Completed
Push — master ( 97e40f...89ec5c )
by André
40:26 queued 12:35
created

UrlAliasHandler::createCustomUrlAlias()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 17

Duplication

Lines 25
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
nc 1
nop 5
dl 25
loc 25
rs 8.8571
c 0
b 0
f 0
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
     * {@inheritdoc}
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-location-path-' . $locationId, 'urlAlias-notFound']);
58
    }
59
60
    /**
61
     * {@inheritdoc}
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-location-path-' . $locationId, 'urlAlias-notFound']);
85
86
        return $urlAlias;
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92
    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-notFound']);
114
115
        return $urlAlias;
116
    }
117
118
    /**
119
     * {@inheritdoc}
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
     * {@inheritdoc}
130
     */
131
    public function listURLAliasesForLocation($locationId, $custom = false)
132
    {
133
        $cacheItem = $this->cache->getItem('ez-urlAlias-location-list-' . $locationId . ($custom ? '-custom' : ''));
134
        if ($cacheItem->isHit()) {
135
            return $cacheItem->get();
136
        }
137
138
        $this->logger->logCall(__METHOD__, array('location' => $locationId, 'custom' => $custom));
139
        $urlAliases = $this->persistenceHandler->urlAliasHandler()->listURLAliasesForLocation($locationId, $custom);
140
141
        $cacheItem->set($urlAliases);
142
        $cacheTags = ['urlAlias-location-' . $locationId];
143
        foreach ($urlAliases as $urlAlias) {
144
            $cacheTags = $this->getCacheTags($urlAlias, $cacheTags);
145
        }
146
        $cacheItem->tag($cacheTags);
147
        $this->cache->save($cacheItem);
148
149
        return $urlAliases;
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155
    public function removeURLAliases(array $urlAliases)
156
    {
157
        $this->logger->logCall(__METHOD__, array('aliases' => $urlAliases));
158
        $return = $this->persistenceHandler->urlAliasHandler()->removeURLAliases($urlAliases);
159
160
        $cacheTags = [];
161
        foreach ($urlAliases as $urlAlias) {
162
            $cacheTags[] = 'urlAlias-' . $urlAlias->id;
163
            if ($urlAlias->type === UrlAlias::LOCATION) {
164
                $cacheTags[] = 'urlAlias-location-' . $urlAlias->destination;
165
                $cacheTags[] = 'urlAlias-location-path-' . $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
     * {@inheritdoc}
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)
195
                ->expiresAfter(30)
196
                ->tag(['urlAlias-notFound']);
197
            $this->cache->save($cacheItem);
198
            throw $e;
199
        }
200
201
        $cacheItem->set($urlAlias);
202
        $cacheItem->tag($this->getCacheTags($urlAlias));
203
        $this->cache->save($cacheItem);
204
205
        return $urlAlias;
206
    }
207
208
    /**
209
     * {@inheritdoc}
210
     */
211
    public function loadUrlAlias($id)
212
    {
213
        $cacheItem = $this->cache->getItem('ez-urlAlias-' . $id);
214
        if ($cacheItem->isHit()) {
215
            return $cacheItem->get();
216
        }
217
218
        $this->logger->logCall(__METHOD__, array('alias' => $id));
219
        $urlAlias = $this->persistenceHandler->urlAliasHandler()->loadUrlAlias($id);
220
221
        $cacheItem->set($urlAlias);
222
        $cacheItem->tag($this->getCacheTags($urlAlias));
223
        $this->cache->save($cacheItem);
224
225
        return $urlAlias;
226
    }
227
228
    /**
229
     * {@inheritdoc}
230
     */
231 View Code Duplication
    public function locationMoved($locationId, $oldParentId, $newParentId)
232
    {
233
        $this->logger->logCall(
234
            __METHOD__,
235
            array(
236
                'location' => $locationId,
237
                'oldParent' => $oldParentId,
238
                'newParent' => $newParentId,
239
            )
240
        );
241
242
        $return = $this->persistenceHandler->urlAliasHandler()->locationMoved($locationId, $oldParentId, $newParentId);
243
244
        $this->cache->invalidateTags(['urlAlias-location-' . $locationId, 'urlAlias-location-path-' . $locationId]);
245
246
        return $return;
247
    }
248
249
    /**
250
     * {@inheritdoc}
251
     */
252 View Code Duplication
    public function locationCopied($locationId, $newLocationId, $newParentId)
253
    {
254
        $this->logger->logCall(
255
            __METHOD__,
256
            array(
257
                'oldLocation' => $locationId,
258
                'newLocation' => $newLocationId,
259
                'newParent' => $newParentId,
260
            )
261
        );
262
263
        $return = $this->persistenceHandler->urlAliasHandler()->locationCopied(
264
            $locationId,
265
            $newLocationId,
266
            $newParentId
267
        );
268
        $this->cache->invalidateTags(['urlAlias-location-' . $locationId, 'urlAlias-location-' . $newLocationId]);
269
270
        return $return;
271
    }
272
273
    /**
274
     * {@inheritdoc}
275
     */
276
    public function locationDeleted($locationId)
277
    {
278
        $this->logger->logCall(__METHOD__, array('location' => $locationId));
279
        $return = $this->persistenceHandler->urlAliasHandler()->locationDeleted($locationId);
280
281
        $this->cache->invalidateTags(['urlAlias-location-' . $locationId, 'urlAlias-location-path-' . $locationId]);
282
283
        return $return;
284
    }
285
286
    /**
287
     * {@inheritdoc}
288
     */
289
    public function locationSwapped($location1Id, $location1ParentId, $location2Id, $location2ParentId)
290
    {
291
        $this->logger->logCall(
292
            __METHOD__,
293
            [
294
                'location1Id' => $location1Id,
295
                'location1ParentId' => $location1ParentId,
296
                'location2Id' => $location2Id,
297
                'location2ParentId' => $location2ParentId,
298
            ]
299
        );
300
301
        $return = $this->persistenceHandler->urlAliasHandler()->locationSwapped(
302
            $location1Id,
303
            $location1ParentId,
304
            $location2Id,
305
            $location2ParentId
306
        );
307
308
        $this->cache->invalidateTags(
309
            [
310
                'urlAlias-location-' . $location1Id,
311
                'urlAlias-location-path-' . $location1Id,
312
                'urlAlias-location-' . $location2Id,
313
                'urlAlias-location-path-' . $location2Id,
314
            ]
315
        );
316
317
        return $return;
318
    }
319
320
    /**
321
     * {@inheritdoc}
322
     */
323
    public function translationRemoved(array $locationIds, $languageCode)
324
    {
325
        $this->logger->logCall(
326
            __METHOD__,
327
            ['locations' => implode(',', $locationIds), 'language' => $languageCode]
328
        );
329
330
        $this->persistenceHandler->urlAliasHandler()->translationRemoved($locationIds, $languageCode);
331
332
        $locationTags = [];
333
        foreach ($locationIds as $locationId) {
334
            $locationTags[] = 'urlAlias-location-' . $locationId;
335
            $locationTags[] = 'urlAlias-location-path-' . $locationId;
336
        }
337
338
        $this->cache->invalidateTags($locationTags);
339
    }
340
341
    /**
342
     * {@inheritdoc}
343
     */
344 View Code Duplication
    public function archiveUrlAliasesForDeletedTranslations($locationId, $parentLocationId, array $languageCodes)
345
    {
346
        $this->logger->logCall(
347
            __METHOD__,
348
            [
349
                'locationId' => $locationId,
350
                'parentLocationId' => $parentLocationId,
351
                'languageCodes' => implode(',', $languageCodes),
352
            ]
353
        );
354
355
        $this->persistenceHandler->urlAliasHandler()->archiveUrlAliasesForDeletedTranslations(
356
            $locationId,
357
            $parentLocationId,
358
            $languageCodes
359
        );
360
361
        $this->cache->invalidateTags(['urlAlias-location-' . $locationId, 'urlAlias-location-path-' . $locationId]);
362
    }
363
364
    /**
365
     * Return relevant UrlAlias and optionally UrlAlias location tags so cache can be purged reliably.
366
     *
367
     * For use when generating cache, not on invalidation.
368
     *
369
     * @param \eZ\Publish\SPI\Persistence\Content\UrlAlias $urlAlias
370
     * @param array $tags Optional, can be used to specify other tags.
371
     *
372
     * @return array
373
     */
374
    private function getCacheTags(UrlAlias $urlAlias, array $tags = [])
375
    {
376
        $tags[] = 'urlAlias-' . $urlAlias->id;
377
378 View Code Duplication
        if ($urlAlias->type === UrlAlias::LOCATION) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
379
            $cacheTags[] = 'urlAlias-location-' . $urlAlias->destination;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$cacheTags was never initialized. Although not strictly required by PHP, it is generally a good practice to add $cacheTags = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
380
            $location = $this->persistenceHandler->locationHandler()->load($urlAlias->destination);
381
            foreach (explode('/', trim($location->pathString, '/')) as $pathId) {
382
                $tags[] = 'urlAlias-location-path-' . $pathId;
383
            }
384
        }
385
386
        return array_unique($tags);
387
    }
388
}
389