Completed
Push — EZP-26146-location-swap-urlali... ( 1d10ee...db0b96 )
by
unknown
26:42 queued 07:46
created

UrlAliasHandler::lookup()   C

Complexity

Conditions 7
Paths 22

Size

Total Lines 39
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 26
c 0
b 0
f 0
nc 22
nop 1
dl 0
loc 39
rs 6.7272
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
 * @version //autogentag//
10
 */
11
namespace eZ\Publish\Core\Persistence\Cache;
12
13
use eZ\Publish\API\Repository\Exceptions\NotFoundException as APINotFoundException;
14
use eZ\Publish\Core\Base\Exceptions\NotFoundException;
15
use eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler as UrlAliasHandlerInterface;
16
use eZ\Publish\SPI\Persistence\Content\UrlAlias;
17
18
/**
19
 * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler
20
 */
21
class UrlAliasHandler extends AbstractHandler implements UrlAliasHandlerInterface
22
{
23
    /**
24
     * Constant used for storing not found results for lookup().
25
     */
26
    const NOT_FOUND = 0;
27
28
    /**
29
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::publishUrlAliasForLocation
30
     */
31
    public function publishUrlAliasForLocation(
32
        $locationId,
33
        $parentLocationId,
34
        $name,
35
        $languageCode,
36
        $alwaysAvailable = false,
37
        $updatePathIdentificationString = false
38
    ) {
39
        $this->logger->logCall(
40
            __METHOD__,
41
            array(
42
                'location' => $locationId,
43
                'parent' => $parentLocationId,
44
                'name' => $name,
45
                'language' => $languageCode,
46
                'alwaysAvailable' => $alwaysAvailable,
47
            )
48
        );
49
        $this->clearLocation($locationId);
50
51
        $this->persistenceHandler->urlAliasHandler()->publishUrlAliasForLocation(
52
            $locationId,
53
            $parentLocationId,
54
            $name,
55
            $languageCode,
56
            $alwaysAvailable,
57
            $updatePathIdentificationString
58
        );
59
    }
60
61
    /**
62
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::createCustomUrlAlias
63
     */
64
    public function createCustomUrlAlias($locationId, $path, $forwarding = false, $languageCode = null, $alwaysAvailable = false)
65
    {
66
        $this->logger->logCall(
67
            __METHOD__,
68
            array(
69
                'location' => $locationId,
70
                '$path' => $path,
71
                '$forwarding' => $forwarding,
72
                'language' => $languageCode,
73
                'alwaysAvailable' => $alwaysAvailable,
74
            )
75
        );
76
77
        $urlAlias = $this->persistenceHandler->urlAliasHandler()->createCustomUrlAlias(
78
            $locationId,
79
            $path,
80
            $forwarding,
81
            $languageCode,
82
            $alwaysAvailable
83
        );
84
85
        $this->cache->getItem('urlAlias', $urlAlias->id)->set($urlAlias)->save();
86
        $cache = $this->cache->getItem('urlAlias', 'location', $urlAlias->destination, 'custom');
87
        $urlAliasIds = $cache->get();
88
        if ($cache->isMiss()) {
89
            $urlAliasIds = array();
90
        }
91
92
        $urlAliasIds[] = $urlAlias->id;
93
        $cache->set($urlAliasIds)->save();
94
95
        return $urlAlias;
96
    }
97
98
    /**
99
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::createGlobalUrlAlias
100
     */
101
    public function createGlobalUrlAlias($resource, $path, $forwarding = false, $languageCode = null, $alwaysAvailable = false)
102
    {
103
        $this->logger->logCall(
104
            __METHOD__,
105
            array(
106
                'resource' => $resource,
107
                'path' => $path,
108
                'forwarding' => $forwarding,
109
                'language' => $languageCode,
110
                'alwaysAvailable' => $alwaysAvailable,
111
            )
112
        );
113
114
        $urlAlias = $this->persistenceHandler->urlAliasHandler()->createGlobalUrlAlias(
115
            $resource,
116
            $path,
117
            $forwarding,
118
            $languageCode,
119
            $alwaysAvailable
120
        );
121
122
        $this->cache->getItem('urlAlias', $urlAlias->id)->set($urlAlias)->save();
123
124
        return $urlAlias;
125
    }
126
127
    /**
128
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::listGlobalURLAliases
129
     */
130
    public function listGlobalURLAliases($languageCode = null, $offset = 0, $limit = -1)
131
    {
132
        $this->logger->logCall(__METHOD__, array('language' => $languageCode, 'offset' => $offset, 'limit' => $limit));
133
134
        return $this->persistenceHandler->urlAliasHandler()->listGlobalURLAliases($languageCode, $offset, $limit);
135
    }
136
137
    /**
138
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::listURLAliasesForLocation
139
     */
140 View Code Duplication
    public function listURLAliasesForLocation($locationId, $custom = false)
141
    {
142
        // Look for location to list of url alias id's cache
143
        if ($custom) {
144
            $cache = $this->cache->getItem('urlAlias', 'location', $locationId, 'custom');
145
        } else {
146
            $cache = $this->cache->getItem('urlAlias', 'location', $locationId);
147
        }
148
        $urlAliasIds = $cache->get();
149
        if ($cache->isMiss()) {
150
            $this->logger->logCall(__METHOD__, array('location' => $locationId, 'custom' => $custom));
151
            $urlAliases = $this->persistenceHandler->urlAliasHandler()->listURLAliasesForLocation($locationId, $custom);
152
153
            $urlAliasIds = array();
154
            foreach ($urlAliases as $urlAlias) {
155
                $urlAliasIds[] = $urlAlias->id;
156
            }
157
158
            $cache->set($urlAliasIds)->save();
159
        } else {
160
            // Reuse loadUrlAlias for the url alias object cache
161
            $urlAliases = array();
162
            foreach ($urlAliasIds as $urlAliasId) {
163
                $urlAliases[] = $this->loadUrlAlias($urlAliasId);
164
            }
165
        }
166
167
        return $urlAliases;
168
    }
169
170
    /**
171
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::removeURLAliases
172
     */
173
    public function removeURLAliases(array $urlAliases)
174
    {
175
        $this->logger->logCall(__METHOD__, array('aliases' => $urlAliases));
176
        $return = $this->persistenceHandler->urlAliasHandler()->removeURLAliases($urlAliases);
177
178
        $this->cache->clear('urlAlias', 'url');//TIMBER! (no easy way to do reverse lookup of urls)
179
        foreach ($urlAliases as $urlAlias) {
180
            $this->cache->clear('urlAlias', $urlAlias->id);
181
            if ($urlAlias->type === UrlAlias::LOCATION) {
182
                $this->cache->clear('urlAlias', 'location', $urlAlias->destination);
183
            }
184
            if ($urlAlias->isCustom) {
185
                $this->cache->clear('urlAlias', 'location', $urlAlias->destination, 'custom');
186
            }
187
        }
188
189
        return $return;
190
    }
191
192
    /**
193
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::lookup
194
     */
195
    public function lookup($url)
196
    {
197
        // Look for url to url alias id cache
198
        // Replace slashes by "|" to be sure not to mix cache key combinations in underlying lib.
199
        $cacheKey = $url ?: '/';
200
        $cache = $this->cache->getItem('urlAlias', 'url', $cacheKey);
201
        $urlAliasId = $cache->get();
202
        if ($cache->isMiss()) {
203
            $urlAliasHistoryCache = $this->cache->getItem('urlAlias', 'url', 'history', $cacheKey);
204
            $historyUrlAlias = $urlAliasHistoryCache->get();
205
206
            if (!$urlAliasHistoryCache->isMiss()) {
207
                return $historyUrlAlias;
208
            }
209
210
            // Also cache "not found" as this function is heavliy used and hance should be cached
211
            try {
212
                $this->logger->logCall(__METHOD__, array('url' => $url));
213
                $urlAlias = $this->persistenceHandler->urlAliasHandler()->lookup($url);
214
215
                if ($urlAlias->isHistory) {
216
                    $urlAliasHistoryCache->set($urlAlias)->save();
217
                } else {
218
                    $cache->set($urlAlias->id)->save();
219
                    $urlAliasCache = $this->cache->getItem('urlAlias', $urlAlias->id);
220
                    $urlAliasCache->set($urlAlias)->save();
221
                }
222
            } catch (APINotFoundException $e) {
223
                $cache->set(self::NOT_FOUND)->save();
224
                throw $e;
225
            }
226
        } elseif ($urlAliasId === self::NOT_FOUND) {
227
            throw new NotFoundException('UrlAlias', $url);
228
        } else {
229
            $urlAlias = $this->loadUrlAlias($urlAliasId);
230
        }
231
232
        return $urlAlias;
233
    }
234
235
    /**
236
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::loadUrlAlias
237
     */
238 View Code Duplication
    public function loadUrlAlias($id)
239
    {
240
        // Look for url alias cache
241
        $cache = $this->cache->getItem('urlAlias', $id);
242
        $urlAlias = $cache->get();
243
        if ($cache->isMiss()) {
244
            $this->logger->logCall(__METHOD__, array('alias' => $id));
245
            $urlAlias = $this->persistenceHandler->urlAliasHandler()->loadUrlAlias($id);
246
            $cache->set($urlAlias)->save();
247
        }
248
249
        return $urlAlias;
250
    }
251
252
    /**
253
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::locationMoved
254
     */
255 View Code Duplication
    public function locationMoved($locationId, $oldParentId, $newParentId)
256
    {
257
        $this->logger->logCall(
258
            __METHOD__,
259
            array(
260
                'location' => $locationId,
261
                'oldParent' => $oldParentId,
262
                'newParent' => $newParentId,
263
            )
264
        );
265
266
        $return = $this->persistenceHandler->urlAliasHandler()->locationMoved($locationId, $oldParentId, $newParentId);
267
        $this->cache->clear('urlAlias', 'url');//TIMBER! (Will have to load url aliases for location to be able to clear specific entries)
268
269
        return $return;
270
    }
271
272
    /**
273
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::locationCopied
274
     */
275 View Code Duplication
    public function locationCopied($locationId, $newLocationId, $newParentId)
276
    {
277
        $this->logger->logCall(
278
            __METHOD__,
279
            array(
280
                'oldLocation' => $locationId,
281
                'newLocation' => $newLocationId,
282
                'newParent' => $newParentId,
283
            )
284
        );
285
286
        $return = $this->persistenceHandler->urlAliasHandler()->locationCopied(
287
            $locationId,
288
            $newLocationId,
289
            $newParentId
290
        );
291
        $this->cache->clear('urlAlias', 'url'); // required due to caching not found aliases
292
293
        return $return;
294
    }
295
296
    /**
297
     * @see eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::locationDeleted
298
     */
299
    public function locationDeleted($locationId)
300
    {
301
        $this->logger->logCall(__METHOD__, array('location' => $locationId));
302
        $return = $this->persistenceHandler->urlAliasHandler()->locationDeleted($locationId);
303
304
        $this->clearLocation($locationId);
305
306
        return $return;
307
    }
308
309
    /**
310
     * @param $locationId
311
     */
312
    protected function clearLocation($locationId)
313
    {
314
        $locationCache = $this->cache->getItem('urlAlias', 'location', $locationId);
315
316
        if ($locationCache->isMiss()) {
317
            // we need to clear all if we don't have location id in cache
318
            $this->cache->clear('urlAlias');
319
        } else {
320
            $urlAliasIds = $locationCache->get();
321
            foreach ((array) $urlAliasIds as $urlAliasId) {
322
                $this->cache->clear('urlAlias', $urlAliasId);
323
            }
324
            $this->cache->clear('urlAlias', 'url');
325
            $locationCache->clear();
326
        }
327
    }
328
329
    /**
330
     * @see \eZ\Publish\SPI\Persistence\Content\UrlAlias\Handler::swap
331
     */
332 View Code Duplication
    public function locationSwapped($location1ParentId, $location1Id, $location2ParentId, $location2Id)
333
    {
334
        $this->logger->logCall(
335
            __METHOD__,
336
            [
337
                'location1ParentId' => $location1ParentId,
338
                'location1Id' => $location1Id,
339
                'location2ParentId' => $location2ParentId,
340
                'location2Id' => $location2Id,
341
            ]
342
        );
343
344
        $return = $this->persistenceHandler->urlAliasHandler()->locationSwapped(
345
            $location1ParentId,
346
            $location1Id,
347
            $location2ParentId,
348
            $location2Id
349
        );
350
351
        $this->clearLocation($location1Id);
352
        $this->clearLocation($location2Id);
353
354
        return $return;
355
    }
356
}
357