Completed
Pull Request — 1.0 (#62)
by Harald
06:06
created

ContentManager::assignStructValues()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 14
ccs 12
cts 12
cp 1
rs 9.2
cc 4
eloc 8
nc 6
nop 2
crap 4
1
<?php
2
3
/*
4
 * This file is part of Transfer.
5
 *
6
 * For the full copyright and license information, please view the LICENSE file located
7
 * in the root directory.
8
 */
9
10
namespace Transfer\EzPlatform\Repository\Manager;
11
12
use eZ\Publish\API\Repository\ContentService;
13
use eZ\Publish\API\Repository\ContentTypeService;
14
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
15
use eZ\Publish\API\Repository\LocationService;
16
use eZ\Publish\API\Repository\Repository;
17
use eZ\Publish\API\Repository\Values\Content\Content;
18
use eZ\Publish\API\Repository\Values\Content\ContentCreateStruct;
19
use eZ\Publish\API\Repository\Values\Content\ContentUpdateStruct;
20
use eZ\Publish\API\Repository\Values\Content\Location;
21
use Psr\Log\LoggerAwareInterface;
22
use Psr\Log\LoggerInterface;
23
use Transfer\Data\ObjectInterface;
24
use Transfer\Data\ValueObject;
25
use Transfer\EzPlatform\Exception\ObjectNotFoundException;
26
use Transfer\EzPlatform\Repository\Values\ContentObject;
27
use Transfer\EzPlatform\Repository\Values\LocationObject;
28
use Transfer\EzPlatform\Exception\UnsupportedObjectOperationException;
29
use Transfer\EzPlatform\Repository\Manager\Type\CreatorInterface;
30
use Transfer\EzPlatform\Repository\Manager\Type\FinderInterface;
31
use Transfer\EzPlatform\Repository\Manager\Type\RemoverInterface;
32
use Transfer\EzPlatform\Repository\Manager\Type\UpdaterInterface;
33
34
/**
35
 * Content manager.
36
 *
37
 * @internal
38
 */
39
class ContentManager implements LoggerAwareInterface, CreatorInterface, UpdaterInterface, RemoverInterface, FinderInterface
40
{
41
    /**
42
     * @var LocationManager
43
     */
44
    private $locationManager;
45
46
    /**
47
     * @var ContentService
48
     */
49
    protected $contentService;
50
51
    /**
52
     * @var ContentTypeService
53
     */
54
    protected $contentTypeService;
55
56
    /**
57
     * @var LocationService
58
     */
59
    protected $locationService;
60
61
    /**
62
     * @var LoggerInterface
63
     */
64
    protected $logger;
65
66
    /**
67
     * @param Repository      $repository
68
     * @param LocationManager $locationManager
69
     */
70 11
    public function __construct(Repository $repository, LocationManager $locationManager)
71
    {
72 11
        $this->locationManager = $locationManager;
73 11
        $this->contentService = $repository->getContentService();
74 11
        $this->contentTypeService = $repository->getContentTypeService();
75 11
        $this->locationService = $repository->getLocationService();
76 11
    }
77
78
    /**
79
     * {@inheritdoc}
80
     */
81 30
    public function setLogger(LoggerInterface $logger)
82
    {
83 30
        $this->logger = $logger;
84 30
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89 23
    public function find(ValueObject $object)
90
    {
91 1
        try {
92 23
            if ($object->getProperty('remote_id')) {
93 23
                $content = $this->contentService->loadContentByRemoteId($object->getProperty('remote_id'));
94 17
            }
95 23
        } catch (NotFoundException $notFoundException) {
96
            // We'll throw our own exception later instead.
97
        }
98
99 23
        if (!isset($content)) {
100 10
            throw new ObjectNotFoundException(Content::class, array('remote_id'));
101
        }
102
103 17
        return $content;
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109 9
    public function create(ObjectInterface $object)
110
    {
111 9
        if (!$object instanceof ContentObject) {
112 1
            throw new UnsupportedObjectOperationException(ContentObject::class, get_class($object));
113
        }
114
115 8
        $createStruct = $this->contentService->newContentCreateStruct(
116 8
            $this->contentTypeService->loadContentTypeByIdentifier($object->getProperty('content_type_identifier')),
117 8
            $object->getProperty('language')
118 8
        );
119
120 8
        $this->mapObjectToCreateStruct($object, $createStruct);
121
122
        /** @var LocationObject[] $locationObjects */
123 8
        $locationObjects = $object->getProperty('parent_locations');
124 8
        $locationCreateStructs = [];
125 8
        if (is_array($locationObjects) && count($locationObjects) > 0) {
126 1
            foreach ($locationObjects as $locationObject) {
127 1
                $locationCreateStruct = $this->locationService->newLocationCreateStruct($locationObject->data['parent_location_id']);
128 1
                $locationObject->getMapper()->getNewLocationCreateStruct($locationCreateStruct);
129 1
                $locationCreateStructs[] = $locationCreateStruct;
130 1
            }
131 1
        }
132
133 8
        $content = $this->contentService->createContent($createStruct, $locationCreateStructs);
134 8
        $this->contentService->publishVersion($content->versionInfo);
135
136 8
        if ($this->logger) {
137 8
            $this->logger->info(sprintf('Published new version of %s', $object->getProperty('name')), array('ContentManager::create'));
138 8
        }
139
140 8
        $object->setProperty('id', $content->contentInfo->id);
141 8
        $object->setProperty('version_info', $content->versionInfo);
142 8
        $object->setProperty('content_info', $content->contentInfo);
143
144 8
        return $object;
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150 17
    public function update(ObjectInterface $object)
151
    {
152 17
        if (!$object instanceof ContentObject) {
153 1
            throw new UnsupportedObjectOperationException(ContentObject::class, get_class($object));
154
        }
155
156 16
        $existingContent = $this->find($object);
157 16
        if (null === $object->getProperty('content_info')) {
158 14
            $object->setProperty('content_info', $existingContent->contentInfo);
159 14
        }
160
161 16
        $contentDraft = $this->contentService->createContentDraft($object->getProperty('content_info'));
162
163 16
        $contentUpdateStruct = $this->contentService->newContentUpdateStruct();
164 17
        $this->mapObjectToUpdateStruct($object, $contentUpdateStruct);
165
166 16
        $contentDraft = $this->contentService->updateContent($contentDraft->versionInfo, $contentUpdateStruct);
167 16
        $content = $this->contentService->publishVersion($contentDraft->versionInfo);
168
169 16
        if ($this->logger) {
170 16
            $this->logger->info(sprintf('Published new version of %s', $object->getProperty('name')), array('ContentManager::update'));
171 16
        }
172
173 16
        $object->setProperty('id', $content->contentInfo->id);
174 16
        $object->setProperty('version_info', $content->versionInfo);
175 16
        $object->setProperty('content_info', $content->contentInfo);
176
177
        // Add/Update/Delete parent locations
178 16
        $this->locationManager->syncronizeLocationsFromContentObject($object);
179
180 16
        return $object;
181
    }
182
183
    /**
184
     * {@inheritdoc}
185
     */
186 21 View Code Duplication
    public function createOrUpdate(ObjectInterface $object)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
187
    {
188 21
        if (!$object instanceof ContentObject) {
189 1
            throw new UnsupportedObjectOperationException(ContentObject::class, get_class($object));
190
        }
191
192
        try {
193 20
            $this->find($object);
194
195 16
            return $this->update($object);
196 8
        } catch (NotFoundException $notFound) {
197 8
            return $this->create($object);
198
        }
199
    }
200
201
    /**
202
     * {@inheritdoc}
203
     */
204 3 View Code Duplication
    public function remove(ObjectInterface $object)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
205
    {
206 3
        if (!$object instanceof ContentObject) {
207 1
            throw new UnsupportedObjectOperationException(ContentObject::class, get_class($object));
208
        }
209
210 3
        try {
211 2
            $content = $this->find($object);
212 1
            $this->contentService->deleteContent($content->contentInfo);
213
214 1
            return true;
215 1
        } catch (NotFoundException $notFound) {
216 1
            return false;
217
        }
218
    }
219
220
    /**
221
     * Assigns a main location ID for a content object.
222
     *
223
     * @param ContentObject $object   Content object
224
     * @param Location      $location Location
225
     *
226
     * @return Content
227
     */
228 3
    public function setMainLocation(ContentObject $object, Location $location)
229
    {
230 3
        $contentMetadataUpdateStruct = $this->contentService->newContentMetadataUpdateStruct();
231
232 3
        $contentMetadataUpdateStruct->mainLocationId = $location->id;
233
234 3
        $object->setProperty('main_location_id', $location->id);
235
236 3
        return $this->contentService->updateContentMetadata($object->getProperty('content_info'), $contentMetadataUpdateStruct);
237
    }
238
239
    /**
240
     * Maps object data to create struct.
241
     *
242
     * @param ContentObject       $object       Content object to map from
243
     * @param ContentCreateStruct $createStruct Content create struct to map to
244
     *
245
     * @throws \InvalidArgumentException
246
     */
247 8
    private function mapObjectToCreateStruct(ContentObject $object, ContentCreateStruct $createStruct)
248
    {
249 8
        if ($object->getProperty('language')) {
250 8
            $createStruct->mainLanguageCode = $object->getProperty('language');
251 8
        }
252
253 8
        if ($object->getProperty('remote_id')) {
254 8
            $createStruct->remoteId = $object->getProperty('remote_id');
255 8
        }
256
257 8
        $this->assignStructValues($object, $createStruct);
258 8
    }
259
260
    /**
261
     * Maps object data to update struct.
262
     *
263
     * @param ContentObject       $object              Content object to map from
264
     * @param ContentUpdateStruct $contentUpdateStruct Content update struct to map to
265
     *
266
     * @throws \InvalidArgumentException
267
     */
268 16
    private function mapObjectToUpdateStruct(ContentObject $object, ContentUpdateStruct $contentUpdateStruct)
269
    {
270 16
        $this->assignStructValues($object, $contentUpdateStruct);
271 16
    }
272
273
    /**
274
     * Copies content object data from a struct.
275
     *
276
     * @param ContentObject $object Content object to get values from
277
     * @param object        $struct Struct to assign values to
278
     */
279 20
    private function assignStructValues(ContentObject $object, $struct)
280
    {
281 20
        foreach ($object->data as $key => $value) {
282 20
            if (is_array($value)) {
283 2
                $value = end($value);
284 2
            }
285 20
            $struct->setField($key, $value);
286 20
        }
287
288 20
        if ($object->getProperty('struct_callback')) {
289 1
            $callback = $object->getProperty('struct_callback');
290 1
            $callback($struct);
291 1
        }
292 20
    }
293
}
294