Completed
Push — sf_cache ( 42a66b...517fd0 )
by André
13:24
created

UrlAliasHandler   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 304
Duplicated Lines 39.8 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
dl 121
loc 304
rs 10
c 0
b 0
f 0
wmc 24
lcom 1
cbo 9

12 Methods

Rating   Name   Duplication   Size   Complexity  
A locationCopied() 20 20 1
A locationDeleted() 0 9 1
B publishUrlAliasForLocation() 30 30 1
B createCustomUrlAlias() 25 25 1
B createGlobalUrlAlias() 25 25 1
A listGlobalURLAliases() 0 6 1
A listURLAliasesForLocation() 21 21 4
A removeURLAliases() 0 19 4
B lookup() 0 33 5
A loadUrlAlias() 0 21 3
A locationMoved() 0 17 1
A locationSwapped() 0 23 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/**
4
 * File containing the UrlAlias Handler implementation.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Publish\Core\Persistence\Cache;
10
11
use eZ\Publish\API\Repository\Exceptions\NotFoundException as APINotFoundException;
12
use eZ\Publish\Core\Base\Exceptions\NotFoundException;
13
use eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler as UrlAliasHandlerInterface;
14
use eZ\Publish\SPI\Persistence\Content\UrlAlias;
15
16
/**
17
 * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler
18
 */
19
class UrlAliasHandler extends AbstractHandler implements UrlAliasHandlerInterface
20
{
21
    /**
22
     * Constant used for storing not found results for lookup().
23
     */
24
    const NOT_FOUND = 0;
25
26
    /**
27
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::publishUrlAliasForLocation
28
     */
29 View Code Duplication
    public function publishUrlAliasForLocation(
30
        $locationId,
31
        $parentLocationId,
32
        $name,
33
        $languageCode,
34
        $alwaysAvailable = false,
35
        $updatePathIdentificationString = false
36
    ) {
37
        $this->logger->logCall(
38
            __METHOD__,
39
            array(
40
                'location' => $locationId,
41
                'parent' => $parentLocationId,
42
                'name' => $name,
43
                'language' => $languageCode,
44
                'alwaysAvailable' => $alwaysAvailable,
45
            )
46
        );
47
48
        $this->persistenceHandler->urlAliasHandler()->publishUrlAliasForLocation(
49
            $locationId,
50
            $parentLocationId,
51
            $name,
52
            $languageCode,
53
            $alwaysAvailable,
54
            $updatePathIdentificationString
55
        );
56
57
        $this->cache->invalidateTags(['urlAlias-location-'.$locationId, 'urlAlias-notFound']);
58
    }
59
60
    /**
61
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::createCustomUrlAlias
62
     */
63 View Code Duplication
    public function createCustomUrlAlias($locationId, $path, $forwarding = false, $languageCode = null, $alwaysAvailable = false)
64
    {
65
        $this->logger->logCall(
66
            __METHOD__,
67
            array(
68
                'location' => $locationId,
69
                '$path' => $path,
70
                '$forwarding' => $forwarding,
71
                'language' => $languageCode,
72
                'alwaysAvailable' => $alwaysAvailable,
73
            )
74
        );
75
76
        $urlAlias = $this->persistenceHandler->urlAliasHandler()->createCustomUrlAlias(
77
            $locationId,
78
            $path,
79
            $forwarding,
80
            $languageCode,
81
            $alwaysAvailable
82
        );
83
84
        $this->cache->invalidateTags(['urlAlias-location-'.$locationId, 'urlAlias-notFound']);
85
86
        return $urlAlias;
87
    }
88
89
    /**
90
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::createGlobalUrlAlias
91
     */
92 View Code Duplication
    public function createGlobalUrlAlias($resource, $path, $forwarding = false, $languageCode = null, $alwaysAvailable = false)
93
    {
94
        $this->logger->logCall(
95
            __METHOD__,
96
            array(
97
                'resource' => $resource,
98
                'path' => $path,
99
                'forwarding' => $forwarding,
100
                'language' => $languageCode,
101
                'alwaysAvailable' => $alwaysAvailable,
102
            )
103
        );
104
105
        $urlAlias = $this->persistenceHandler->urlAliasHandler()->createGlobalUrlAlias(
106
            $resource,
107
            $path,
108
            $forwarding,
109
            $languageCode,
110
            $alwaysAvailable
111
        );
112
113
        $this->cache->invalidateTags(['urlAlias-global-'.$languageCode, 'urlAlias-notFound']);
114
115
        return $urlAlias;
116
    }
117
118
    /**
119
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::listGlobalURLAliases
120
     */
121
    public function listGlobalURLAliases($languageCode = null, $offset = 0, $limit = -1)
122
    {
123
        $this->logger->logCall(__METHOD__, array('language' => $languageCode, 'offset' => $offset, 'limit' => $limit));
124
125
        return $this->persistenceHandler->urlAliasHandler()->listGlobalURLAliases($languageCode, $offset, $limit);
126
    }
127
128
    /**
129
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::listURLAliasesForLocation
130
     */
131 View Code Duplication
    public function listURLAliasesForLocation($locationId, $custom = false)
132
    {
133
134
        $cacheItem = $this->cache->getItem('ez-urlAlias-location-list-'.$locationId.($custom ? '-custom' : ''));
135
        if ($cacheItem->isHit()) {
136
            return $cacheItem->get();
137
        }
138
139
        $this->logger->logCall(__METHOD__, array('location' => $locationId, 'custom' => $custom));
140
        $urlAliases = $this->persistenceHandler->urlAliasHandler()->listURLAliasesForLocation($locationId, $custom);
141
142
        $cacheItem->set($urlAliases);
143
        $cacheTags = ['urlAlias-location-'.$locationId];
144
        foreach ($urlAliases as $urlAlias) {
145
            $cacheTags[] = 'urlAlias-'.$urlAlias->id;
146
        }
147
        $cacheItem->tag($cacheTags);
148
        $this->cache->save($cacheItem);
149
150
        return $urlAliases;
151
    }
152
153
    /**
154
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::removeURLAliases
155
     */
156
    public function removeURLAliases(array $urlAliases)
157
    {
158
        $this->logger->logCall(__METHOD__, array('aliases' => $urlAliases));
159
        $return = $this->persistenceHandler->urlAliasHandler()->removeURLAliases($urlAliases);
160
161
        $cacheTags = [];
162
        foreach ($urlAliases as $urlAlias) {
163
            $cacheTags[] = 'urlAlias-'.$urlAlias->id;
164
            if ($urlAlias->type === UrlAlias::LOCATION) {
165
                $cacheTags[] = 'urlAlias-location-'.$urlAlias->destination;
166
            }
167
            if ($urlAlias->isCustom) {
168
                $cacheTags[] = 'urlAlias-custom-'.$urlAlias->destination;
169
            }
170
        }
171
        $this->cache->invalidateTags($cacheTags);
172
173
        return $return;
174
    }
175
176
    /**
177
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::lookup
178
     */
179
    public function lookup($url)
180
    {
181
        $cacheItem = $this->cache->getItem('ez-urlAlias-url-'.str_replace('/', '_', $url));
182
        if ($cacheItem->isHit()) {
183
            if (($return = $cacheItem->get()) === self::NOT_FOUND) {
184
                throw new NotFoundException('UrlAlias', $url);
185
            }
186
187
            return $return;
188
        }
189
190
        $this->logger->logCall(__METHOD__, array('url' => $url));
191
        try {
192
            $urlAlias = $this->persistenceHandler->urlAliasHandler()->lookup($url);
193
        } catch (APINotFoundException $e) {
194
            $cacheItem->set(self::NOT_FOUND)
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Psr\Cache\CacheItemInterface as the method tag() does only exist in the following implementations of said interface: Symfony\Component\Cache\CacheItem.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
195
                ->expiresAfter(30)
196
                ->tag(['urlAlias-notFound']);
197
            $this->cache->save($cacheItem);
198
            throw $e;
199
        }
200
201
        $cacheItem->set($urlAlias);
202
        $cachTags = ['urlAlias-'.$urlAlias->id];
203
        if ($urlAlias->type === UrlAlias::LOCATION) {
204
            $cachTags[] = 'urlAlias-location-'.$urlAlias->destination;
205
        }
206
        $cacheItem->tag($cachTags);
207
        $this->cache->save($cacheItem);
208
209
210
        return $urlAlias;
211
    }
212
213
    /**
214
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::loadUrlAlias
215
     */
216
    public function loadUrlAlias($id)
217
    {
218
        $cacheItem = $this->cache->getItem('ez-urlAlias-', $id);
219
        if ($cacheItem->isHit()) {
220
            return $cacheItem->get();
221
        }
222
223
        $this->logger->logCall(__METHOD__, array('alias' => $id));
224
        $urlAlias = $this->persistenceHandler->urlAliasHandler()->loadUrlAlias($id);
225
226
        $cacheItem->set($urlAlias);
227
        if ($urlAlias->type === UrlAlias::LOCATION) {
228
            $cacheItem->tag(['urlAlias-'.$urlAlias->id, 'urlAlias-location-'.$urlAlias->destination]);
229
        } else {
230
            $cacheItem->tag(['urlAlias-'.$urlAlias->id]);
231
        }
232
        $this->cache->save($cacheItem);
233
234
235
        return $urlAlias;
236
    }
237
238
    /**
239
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::locationMoved
240
     */
241
    public function locationMoved($locationId, $oldParentId, $newParentId)
242
    {
243
        $this->logger->logCall(
244
            __METHOD__,
245
            array(
246
                'location' => $locationId,
247
                'oldParent' => $oldParentId,
248
                'newParent' => $newParentId,
249
            )
250
        );
251
252
        $return = $this->persistenceHandler->urlAliasHandler()->locationMoved($locationId, $oldParentId, $newParentId);
253
254
        $this->cache->invalidateTags(['urlAlias-location-'.$locationId]);
255
256
        return $return;
257
    }
258
259
    /**
260
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::locationCopied
261
     */
262 View Code Duplication
    public function locationCopied($locationId, $newLocationId, $newParentId)
263
    {
264
        $this->logger->logCall(
265
            __METHOD__,
266
            array(
267
                'oldLocation' => $locationId,
268
                'newLocation' => $newLocationId,
269
                'newParent' => $newParentId,
270
            )
271
        );
272
273
        $return = $this->persistenceHandler->urlAliasHandler()->locationCopied(
274
            $locationId,
275
            $newLocationId,
276
            $newParentId
277
        );
278
        $this->cache->invalidateTags(['urlAlias-location-'.$locationId, 'urlAlias-location-'.$newLocationId]);
279
280
        return $return;
281
    }
282
283
    /**
284
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::locationDeleted
285
     */
286
    public function locationDeleted($locationId)
287
    {
288
        $this->logger->logCall(__METHOD__, array('location' => $locationId));
289
        $return = $this->persistenceHandler->urlAliasHandler()->locationDeleted($locationId);
290
291
        $this->cache->invalidateTags(['urlAlias-location-'.$locationId]);
292
293
        return $return;
294
    }
295
296
    /**
297
     * @see \eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::swap
298
     */
299
    public function locationSwapped($location1ParentId, $location1Id, $location2ParentId, $location2Id)
300
    {
301
        $this->logger->logCall(
302
            __METHOD__,
303
            [
304
                'location1ParentId' => $location1ParentId,
305
                'location1Id' => $location1Id,
306
                'location2ParentId' => $location2ParentId,
307
                'location2Id' => $location2Id,
308
            ]
309
        );
310
311
        $return = $this->persistenceHandler->urlAliasHandler()->locationSwapped(
312
            $location1ParentId,
313
            $location1Id,
314
            $location2ParentId,
315
            $location2Id
316
        );
317
318
        $this->cache->invalidateTags(['urlAlias-location-'.$location1ParentId, 'urlAlias-location-'.$location2ParentId]);
319
320
        return $return;
321
    }
322
}
323