Completed
Push — EZP-31644 ( 2e0a1e...93bb44 )
by
unknown
19:12
created

ContentHandler   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 361
Duplicated Lines 13.57 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 0
Metric Value
dl 49
loc 361
rs 9.6
c 0
b 0
f 0
wmc 35
lcom 1
cbo 13

24 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 7 1
A createDraftFromVersion() 0 6 1
A load() 0 13 4
A loadContentList() 0 5 1
A loadContentInfo() 11 11 2
A loadContentInfoList() 0 5 1
A loadContentInfoByRemoteId() 11 11 2
A loadDraftsForUser() 0 6 1
A copy() 10 10 1
A setStatus() 0 17 2
A updateMetadata() 0 19 2
A updateContent() 0 11 1
A deleteContent() 0 29 3
A deleteVersion() 0 13 1
A listVersions() 0 6 1
A addRelation() 0 6 1
A removeRelation() 0 5 1
A loadRelations() 13 13 1
A loadReverseRelations() 0 6 1
A publish() 0 20 1
A removeTranslationFromContent() 0 4 1
A deleteTranslationFromDraft() 0 17 1
A loadVersionInfo() 4 11 3
A deleteTranslationFromContent() 0 15 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 ContentHandler 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\Values\Content\Relation as APIRelation;
12
use eZ\Publish\SPI\Persistence\Content\Handler as ContentHandlerInterface;
13
use eZ\Publish\SPI\Persistence\Content;
14
use eZ\Publish\SPI\Persistence\Content\VersionInfo;
15
use eZ\Publish\SPI\Persistence\Content\CreateStruct;
16
use eZ\Publish\SPI\Persistence\Content\UpdateStruct;
17
use eZ\Publish\SPI\Persistence\Content\MetadataUpdateStruct;
18
use eZ\Publish\SPI\Persistence\Content\Relation\CreateStruct as RelationCreateStruct;
19
20
/**
21
 * @see \eZ\Publish\SPI\Persistence\Content\Handler
22
 */
23
class ContentHandler extends AbstractHandler implements ContentHandlerInterface
24
{
25
    const ALL_TRANSLATIONS_KEY = '0';
26
    const PUBLISHED_VERSION = 0;
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    public function create(CreateStruct $struct)
32
    {
33
        // Cached on demand when published or loaded
34
        $this->logger->logCall(__METHOD__, ['struct' => $struct]);
35
36
        return $this->persistenceHandler->contentHandler()->create($struct);
37
    }
38
39
    /**
40
     * {@inheritdoc}
41
     */
42
    public function createDraftFromVersion($contentId, $srcVersion, $userId)
43
    {
44
        $this->logger->logCall(__METHOD__, ['content' => $contentId, 'version' => $srcVersion, 'user' => $userId]);
45
46
        return $this->persistenceHandler->contentHandler()->createDraftFromVersion($contentId, $srcVersion, $userId);
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52 View Code Duplication
    public function copy($contentId, $versionNo = null, $newOwnerId = null)
53
    {
54
        $this->logger->logCall(__METHOD__, [
55
            'content' => $contentId,
56
            'version' => $versionNo,
57
            'newOwner' => $newOwnerId,
58
        ]);
59
60
        return $this->persistenceHandler->contentHandler()->copy($contentId, $versionNo, $newOwnerId);
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function load($contentId, $version = null, array $translations = null)
67
    {
68
        $translationsKey = empty($translations) ? self::ALL_TRANSLATIONS_KEY : implode('|', $translations);
69
        $cache = $this->cache->getItem('content', $contentId, $version ?: self::PUBLISHED_VERSION, $translationsKey);
70
        $content = $cache->get();
71
        if ($cache->isMiss()) {
72
            $this->logger->logCall(__METHOD__, ['content' => $contentId, 'version' => $version, 'translations' => $translations]);
73
            $content = $this->persistenceHandler->contentHandler()->load($contentId, $version, $translations);
0 ignored issues
show
Bug introduced by
It seems like $translations defined by parameter $translations on line 66 can also be of type array; however, eZ\Publish\SPI\Persistence\Content\Handler::load() does only seem to accept null|array<integer,string>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
74
            $cache->set($content)->save();
75
        }
76
77
        return $content;
78
    }
79
80
    public function loadContentList(array $contentIds, array $translations = null)
81
    {
82
        // Intentionally not caching until we can handle caching multiple items (see 7.x)
83
        return $this->persistenceHandler->contentHandler()->loadContentList($contentIds, $translations);
0 ignored issues
show
Bug introduced by
It seems like $translations defined by parameter $translations on line 80 can also be of type array; however, eZ\Publish\SPI\Persisten...dler::loadContentList() does only seem to accept null|array<integer,string>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89 View Code Duplication
    public function loadContentInfo($contentId)
90
    {
91
        $cache = $this->cache->getItem('content', 'info', $contentId);
92
        $contentInfo = $cache->get();
93
        if ($cache->isMiss()) {
94
            $this->logger->logCall(__METHOD__, ['content' => $contentId]);
95
            $cache->set($contentInfo = $this->persistenceHandler->contentHandler()->loadContentInfo($contentId))->save();
96
        }
97
98
        return $contentInfo;
99
    }
100
101
    public function loadContentInfoList(array $contentIds)
102
    {
103
        // Intentionally not caching until we can handle caching multiple items (see 7.x)
104
        return $this->persistenceHandler->contentHandler()->loadContentInfoList($contentIds);
105
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110 View Code Duplication
    public function loadContentInfoByRemoteId($remoteId)
111
    {
112
        $cache = $this->cache->getItem('content', 'info', 'remoteId', $remoteId);
113
        $contentInfo = $cache->get();
114
        if ($cache->isMiss()) {
115
            $this->logger->logCall(__METHOD__, ['content' => $remoteId]);
116
            $cache->set($contentInfo = $this->persistenceHandler->contentHandler()->loadContentInfoByRemoteId($remoteId))->save();
117
        }
118
119
        return $contentInfo;
120
    }
121
122
    /**
123
     * {@inheritdoc}
124
     */
125
    public function loadVersionInfo($contentId, $versionNo = null)
126
    {
127
        $cache = $this->cache->getItem('content', 'info', $contentId, 'versioninfo', $versionNo ?: self::PUBLISHED_VERSION);
128
        $versionInfo = $cache->get();
129 View Code Duplication
        if ($cache->isMiss()) {
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...
130
            $this->logger->logCall(__METHOD__, ['content' => $contentId, 'version' => $versionNo]);
131
            $cache->set($versionInfo = $this->persistenceHandler->contentHandler()->loadVersionInfo($contentId, $versionNo))->save();
132
        }
133
134
        return $versionInfo;
135
    }
136
137
    /**
138
     * {@inheritdoc}
139
     */
140
    public function loadDraftsForUser($userId)
141
    {
142
        $this->logger->logCall(__METHOD__, ['user' => $userId]);
143
144
        return $this->persistenceHandler->contentHandler()->loadDraftsForUser($userId);
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150
    public function setStatus($contentId, $status, $version)
151
    {
152
        $this->logger->logCall(__METHOD__, ['content' => $contentId, 'status' => $status, 'version' => $version]);
153
        $return = $this->persistenceHandler->contentHandler()->setStatus($contentId, $status, $version);
154
155
        $this->cache->clear('content', $contentId, $version);
156
        $this->cache->clear('content', $contentId, self::PUBLISHED_VERSION);
157
        if ($status === VersionInfo::STATUS_PUBLISHED) {
158
            $this->cache->clear('content', 'info', $contentId);
159
            $this->cache->clear('content', 'info', 'remoteId');
160
        } else {
161
            $this->cache->clear('content', 'info', $contentId, 'versioninfo', $version);
162
            $this->cache->clear('content', 'info', $contentId, 'versioninfo', self::PUBLISHED_VERSION);
163
        }
164
165
        return $return;
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171
    public function updateMetadata($contentId, MetadataUpdateStruct $struct)
172
    {
173
        $this->logger->logCall(__METHOD__, ['content' => $contentId, 'struct' => $struct]);
174
175
        $contentInfo = $this->persistenceHandler->contentHandler()->updateMetadata($contentId, $struct);
176
177
        $this->cache->clear('content', $contentId, $contentInfo->currentVersionNo);
178
        $this->cache->clear('content', $contentId, self::PUBLISHED_VERSION);
179
        $this->cache->clear('content', 'info', $contentId);
180
181
        if ($struct->remoteId) {
182
            // remote id changed
183
            $this->cache->clear('content', 'info', 'remoteId');
184
        } else {
185
            $this->cache->clear('content', 'info', 'remoteId', $contentInfo->remoteId);
186
        }
187
188
        return $contentInfo;
189
    }
190
191
    /**
192
     * {@inheritdoc}
193
     */
194
    public function updateContent($contentId, $versionNo, UpdateStruct $struct)
195
    {
196
        $this->logger->logCall(__METHOD__, ['content' => $contentId, 'version' => $versionNo, 'struct' => $struct]);
197
        $content = $this->persistenceHandler->contentHandler()->updateContent($contentId, $versionNo, $struct);
198
        $this->cache->clear('content', $contentId, $versionNo);
199
        $this->cache->clear('content', $contentId, self::PUBLISHED_VERSION);
200
        $this->cache->clear('content', 'info', $contentId, 'versioninfo', $versionNo);
201
        $this->cache->clear('content', 'info', $contentId, 'versioninfo', self::PUBLISHED_VERSION);
202
203
        return $content;
204
    }
205
206
    /**
207
     * {@inheritdoc}
208
     */
209
    public function deleteContent($contentId)
210
    {
211
        $this->logger->logCall(__METHOD__, ['content' => $contentId]);
212
213
        // Load locations and reverse field relations first
214
        $locations = $this->persistenceHandler->locationHandler()->loadLocationsByContent($contentId);
215
        $reverseRelations = $this->persistenceHandler->contentHandler()->loadReverseRelations(
216
            $contentId,
217
            APIRelation::FIELD
218
        );
219
220
        $return = $this->persistenceHandler->contentHandler()->deleteContent($contentId);
221
222
        // Clear cache of the reversely related Content after main action has executed
223
        foreach ($reverseRelations as $relation) {
224
            $this->cache->clear('content', $relation->sourceContentId);
225
        }
226
227
        $this->cache->clear('content', $contentId);
228
        $this->cache->clear('content', 'info', $contentId);
229
        $this->cache->clear('content', 'info', 'remoteId');
230
        $this->cache->clear('location', 'subtree');
231
232
        foreach ($locations as $location) {
233
            $this->cache->clear('location', $location->id);
234
        }
235
236
        return $return;
237
    }
238
239
    /**
240
     * {@inheritdoc}
241
     */
242
    public function deleteVersion($contentId, $versionNo)
243
    {
244
        $this->logger->logCall(__METHOD__, ['content' => $contentId, 'version' => $versionNo]);
245
        $return = $this->persistenceHandler->contentHandler()->deleteVersion($contentId, $versionNo);
246
247
        $this->cache->clear('content', $contentId, $versionNo);
248
        $this->cache->clear('content', $contentId, self::PUBLISHED_VERSION);
249
        $this->cache->clear('content', 'info', $contentId);
250
        $this->cache->clear('content', 'info', 'remoteId');
251
        $this->cache->clear('location', 'subtree');
252
253
        return $return;
254
    }
255
256
    /**
257
     * {@inheritdoc}
258
     */
259
    public function listVersions($contentId, $status = null, $limit = -1)
260
    {
261
        $this->logger->logCall(__METHOD__, ['content' => $contentId, 'status' => $status]);
262
263
        return $this->persistenceHandler->contentHandler()->listVersions($contentId, $status, $limit);
264
    }
265
266
    /**
267
     * {@inheritdoc}
268
     */
269
    public function addRelation(RelationCreateStruct $relation)
270
    {
271
        $this->logger->logCall(__METHOD__, ['struct' => $relation]);
272
273
        return $this->persistenceHandler->contentHandler()->addRelation($relation);
274
    }
275
276
    /**
277
     * {@inheritdoc}
278
     */
279
    public function removeRelation($relationId, $type)
280
    {
281
        $this->logger->logCall(__METHOD__, ['relation' => $relationId, 'type' => $type]);
282
        $this->persistenceHandler->contentHandler()->removeRelation($relationId, $type);
283
    }
284
285
    /**
286
     * {@inheritdoc}
287
     */
288 View Code Duplication
    public function loadRelations($sourceContentId, $sourceContentVersionNo = null, $type = null)
289
    {
290
        $this->logger->logCall(
291
            __METHOD__,
292
            [
293
                'content' => $sourceContentId,
294
                'version' => $sourceContentVersionNo,
295
                'type' => $type,
296
            ]
297
        );
298
299
        return $this->persistenceHandler->contentHandler()->loadRelations($sourceContentId, $sourceContentVersionNo, $type);
300
    }
301
302
    /**
303
     * {@inheritdoc}
304
     */
305
    public function loadReverseRelations($destinationContentId, $type = null)
306
    {
307
        $this->logger->logCall(__METHOD__, ['content' => $destinationContentId, 'type' => $type]);
308
309
        return $this->persistenceHandler->contentHandler()->loadReverseRelations($destinationContentId, $type);
310
    }
311
312
    /**
313
     * {@inheritdoc}
314
     */
315
    public function publish($contentId, $versionNo, MetadataUpdateStruct $struct)
316
    {
317
        $this->logger->logCall(__METHOD__, ['content' => $contentId, 'version' => $versionNo, 'struct' => $struct]);
318
        $content = $this->persistenceHandler->contentHandler()->publish($contentId, $versionNo, $struct);
319
320
        $this->cache->clear('content', $contentId);
321
        $this->cache->clear('content', 'info', $contentId);
322
        $this->cache->clear('content', 'info', 'remoteId');
323
        $this->cache->clear('location', 'subtree');
324
325
        // warm up cache
326
        $contentInfo = $content->versionInfo->contentInfo;
327
        $this->cache
328
            ->getItem('content', $contentInfo->id, $content->versionInfo->versionNo, self::ALL_TRANSLATIONS_KEY)
329
            ->set($content)
330
            ->save();
331
        $this->cache->getItem('content', 'info', $contentInfo->id)->set($contentInfo)->save();
332
333
        return $content;
334
    }
335
336
    /**
337
     * {@inheritdoc}
338
     */
339
    public function removeTranslationFromContent($contentId, $languageCode)
340
    {
341
        $this->deleteTranslationFromContent($contentId, $languageCode);
342
    }
343
344
    /**
345
     * {@inheritdoc}
346
     */
347
    public function deleteTranslationFromContent($contentId, $languageCode)
348
    {
349
        $this->logger->logCall(
350
            __METHOD__,
351
            [
352
                'contentId' => $contentId,
353
                'languageCode' => $languageCode,
354
            ]
355
        );
356
357
        $this->persistenceHandler->contentHandler()->deleteTranslationFromContent($contentId, $languageCode);
358
359
        $this->cache->clear('content', $contentId);
360
        $this->cache->clear('content', 'info', $contentId);
361
    }
362
363
    /**
364
     * {@inheritdoc}
365
     */
366
    public function deleteTranslationFromDraft($contentId, $versionNo, $languageCode)
367
    {
368
        $this->logger->logCall(
369
            __METHOD__,
370
            ['content' => $contentId, 'version' => $versionNo, 'languageCode' => $languageCode]
371
        );
372
        $content = $this->persistenceHandler->contentHandler()->deleteTranslationFromDraft(
373
            $contentId,
374
            $versionNo,
375
            $languageCode
376
        );
377
        $this->cache->clear('content', $contentId, $versionNo);
378
        $this->cache->clear('content', $contentId, self::PUBLISHED_VERSION);
379
        $this->cache->clear('content', 'info', $contentId, 'versioninfo', $versionNo);
380
381
        return $content;
382
    }
383
}
384