Completed
Push — master ( 9301ed...f1e463 )
by André
94:57 queued 80:46
created

Mapper   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 492
Duplicated Lines 5.89 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 0
Metric Value
dl 29
loc 492
rs 8.3396
c 0
b 0
f 0
wmc 44
lcom 1
cbo 13

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A extractRelationsFromRows() 0 13 3
A extractRelationFromRow() 0 16 2
A createRelationFromCreateStruct() 0 12 1
B createContentInfoFromCreateStruct() 0 24 3
B createVersionInfoFromCreateStruct() 5 24 3
A createVersionInfoForContent() 0 16 2
A convertToStorageValue() 0 13 1
C extractContentFromRows() 8 54 10
A extractContentInfoFromRow() 0 19 2
A extractContentInfoFromRows() 0 9 2
A extractVersionInfoFromRow() 0 16 1
B extractVersionInfoListFromRows() 0 29 4
A extractLanguageCodesFromMask() 16 16 3
A extractFieldFromRow() 0 13 1
B extractFieldValueFromRow() 0 24 3
A createCreateStructFromContent() 0 22 2

How to fix   Duplicated Code    Complexity   

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Mapper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Mapper, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * File containing the Mapper class.
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\Legacy\Content;
10
11
use eZ\Publish\SPI\Persistence\Content;
12
use eZ\Publish\SPI\Persistence\Content\CreateStruct;
13
use eZ\Publish\SPI\Persistence\Content\Field;
14
use eZ\Publish\SPI\Persistence\Content\FieldValue;
15
use eZ\Publish\SPI\Persistence\Content\Relation;
16
use eZ\Publish\SPI\Persistence\Content\Relation\CreateStruct as RelationCreateStruct;
17
use eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry as Registry;
18
use eZ\Publish\SPI\Persistence\Content\Language\Handler as LanguageHandler;
19
use eZ\Publish\SPI\Persistence\Content\ContentInfo;
20
use eZ\Publish\SPI\Persistence\Content\VersionInfo;
21
22
/**
23
 * Mapper for Content Handler.
24
 *
25
 * Performs mapping of Content objects.
26
 */
27
class Mapper
28
{
29
    /**
30
     * FieldValue converter registry.
31
     *
32
     * @var \eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry
33
     */
34
    protected $converterRegistry;
35
36
    /**
37
     * Caching language handler.
38
     *
39
     * @var \eZ\Publish\SPI\Persistence\Content\Language\Handler
40
     */
41
    protected $languageHandler;
42
43
    /**
44
     * Creates a new mapper.
45
     *
46
     * @param \eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\ConverterRegistry $converterRegistry
47
     * @param \eZ\Publish\SPI\Persistence\Content\Language\Handler $languageHandler
48
     */
49
    public function __construct(Registry $converterRegistry, LanguageHandler $languageHandler)
50
    {
51
        $this->converterRegistry = $converterRegistry;
52
        $this->languageHandler = $languageHandler;
53
    }
54
55
    /**
56
     * Creates a Content from the given $struct and $currentVersionNo.
57
     *
58
     * @param \eZ\Publish\SPI\Persistence\Content\CreateStruct $struct
59
     * @param mixed $currentVersionNo
60
     *
61
     * @return \eZ\Publish\SPI\Persistence\Content\ContentInfo
62
     */
63
    private function createContentInfoFromCreateStruct(CreateStruct $struct, $currentVersionNo = 1)
64
    {
65
        $contentInfo = new ContentInfo();
66
67
        $contentInfo->id = null;
68
        $contentInfo->contentTypeId = $struct->typeId;
69
        $contentInfo->sectionId = $struct->sectionId;
70
        $contentInfo->ownerId = $struct->ownerId;
71
        $contentInfo->alwaysAvailable = $struct->alwaysAvailable;
72
        $contentInfo->remoteId = $struct->remoteId;
73
        $contentInfo->mainLanguageCode = $this->languageHandler
74
            ->load(isset($struct->mainLanguageId) ? $struct->mainLanguageId : $struct->initialLanguageId)
75
            ->languageCode;
76
        $contentInfo->name = isset($struct->name[$contentInfo->mainLanguageCode])
77
            ? $struct->name[$contentInfo->mainLanguageCode]
78
            : '';
79
        // For drafts published and modified timestamps should be 0
80
        $contentInfo->publicationDate = 0;
81
        $contentInfo->modificationDate = 0;
82
        $contentInfo->currentVersionNo = $currentVersionNo;
83
        $contentInfo->isPublished = false;
84
85
        return $contentInfo;
86
    }
87
88
    /**
89
     * Creates a new version for the given $struct and $versionNo.
90
     *
91
     * @param \eZ\Publish\SPI\Persistence\Content\CreateStruct $struct
92
     * @param mixed $versionNo
93
     *
94
     * @return \eZ\Publish\SPI\Persistence\Content\VersionInfo
95
     */
96
    public function createVersionInfoFromCreateStruct(CreateStruct $struct, $versionNo)
97
    {
98
        $versionInfo = new VersionInfo();
99
100
        $versionInfo->id = null;
101
        $versionInfo->contentInfo = $this->createContentInfoFromCreateStruct($struct, $versionNo);
102
        $versionInfo->versionNo = $versionNo;
103
        $versionInfo->creatorId = $struct->ownerId;
104
        $versionInfo->status = VersionInfo::STATUS_DRAFT;
105
        $versionInfo->initialLanguageCode = $this->languageHandler->load($struct->initialLanguageId)->languageCode;
106
        $versionInfo->creationDate = $struct->modified;
107
        $versionInfo->modificationDate = $struct->modified;
108
        $versionInfo->names = $struct->name;
109
110
        $languages = [];
111 View Code Duplication
        foreach ($struct->fields as $field) {
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...
112
            if (!isset($languages[$field->languageCode])) {
113
                $languages[$field->languageCode] = true;
114
            }
115
        }
116
        $versionInfo->languageCodes = array_keys($languages);
0 ignored issues
show
Documentation Bug introduced by
It seems like array_keys($languages) of type array<integer,integer|string> is incompatible with the declared type array<integer,string> of property $languageCodes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
117
118
        return $versionInfo;
119
    }
120
121
    /**
122
     * Creates a new version for the given $content.
123
     *
124
     * @param \eZ\Publish\SPI\Persistence\Content $content
125
     * @param mixed $versionNo
126
     * @param mixed $userId
127
     *
128
     * @return \eZ\Publish\SPI\Persistence\Content\VersionInfo
129
     */
130
    public function createVersionInfoForContent(Content $content, $versionNo, $userId)
131
    {
132
        $versionInfo = new VersionInfo();
133
134
        $versionInfo->contentInfo = $content->versionInfo->contentInfo;
135
        $versionInfo->versionNo = $versionNo;
136
        $versionInfo->creatorId = $userId;
137
        $versionInfo->status = VersionInfo::STATUS_DRAFT;
138
        $versionInfo->initialLanguageCode = $content->versionInfo->initialLanguageCode;
139
        $versionInfo->creationDate = time();
140
        $versionInfo->modificationDate = $versionInfo->creationDate;
141
        $versionInfo->names = is_object($content->versionInfo) ? $content->versionInfo->names : array();
142
        $versionInfo->languageCodes = $content->versionInfo->languageCodes;
143
144
        return $versionInfo;
145
    }
146
147
    /**
148
     * Converts value of $field to storage value.
149
     *
150
     * @param \eZ\Publish\SPI\Persistence\Content\Field $field
151
     *
152
     * @return \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldValue
153
     */
154
    public function convertToStorageValue(Field $field)
155
    {
156
        $converter = $this->converterRegistry->getConverter(
157
            $field->type
158
        );
159
        $storageValue = new StorageFieldValue();
160
        $converter->toStorageValue(
161
            $field->value,
162
            $storageValue
163
        );
164
165
        return $storageValue;
166
    }
167
168
    /**
169
     * Extracts Content objects (and nested) from database result $rows.
170
     *
171
     * Expects database rows to be indexed by keys of the format
172
     *
173
     *      "$tableName_$columnName"
174
     *
175
     * @param array $rows
176
     * @param array $nameRows
177
     *
178
     * @return \eZ\Publish\SPI\Persistence\Content[]
179
     */
180
    public function extractContentFromRows(array $rows, array $nameRows)
181
    {
182
        $versionedNameData = array();
183
        foreach ($nameRows as $row) {
184
            $contentId = (int)$row['ezcontentobject_name_contentobject_id'];
185
            $versionNo = (int)$row['ezcontentobject_name_content_version'];
186
            $versionedNameData[$contentId][$versionNo][$row['ezcontentobject_name_content_translation']] = $row['ezcontentobject_name_name'];
187
        }
188
189
        $contentInfos = array();
190
        $versionInfos = array();
191
        $fields = array();
192
193
        foreach ($rows as $row) {
194
            $contentId = (int)$row['ezcontentobject_id'];
195
            if (!isset($contentInfos[$contentId])) {
196
                $contentInfos[$contentId] = $this->extractContentInfoFromRow($row, 'ezcontentobject_');
197
            }
198
            if (!isset($versionInfos[$contentId])) {
199
                $versionInfos[$contentId] = array();
200
            }
201
202
            $versionId = (int)$row['ezcontentobject_version_id'];
203
            if (!isset($versionInfos[$contentId][$versionId])) {
204
                $versionInfos[$contentId][$versionId] = $this->extractVersionInfoFromRow($row);
205
            }
206
207
            $fieldId = (int)$row['ezcontentobject_attribute_id'];
208 View Code Duplication
            if (!isset($fields[$contentId][$versionId][$fieldId])) {
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...
209
                $fields[$contentId][$versionId][$fieldId] = $this->extractFieldFromRow($row);
210
            }
211
        }
212
213
        $results = array();
214
        foreach ($contentInfos as $contentId => $contentInfo) {
215
            foreach ($versionInfos[$contentId] as $versionId => $versionInfo) {
216
                // Fallback to just main language name if versioned name data is missing
217 View Code Duplication
                if (isset($versionedNameData[$contentId][$versionInfo->versionNo])) {
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...
218
                    $names = $versionedNameData[$contentId][$versionInfo->versionNo];
219
                } else {
220
                    $names = [$contentInfo->mainLanguageCode => $contentInfo->name];
221
                }
222
223
                $content = new Content();
224
                $content->versionInfo = $versionInfo;
225
                $content->versionInfo->names = $names;
226
                $content->versionInfo->contentInfo = $contentInfo;
227
                $content->fields = array_values($fields[$contentId][$versionId]);
228
                $results[] = $content;
229
            }
230
        }
231
232
        return $results;
233
    }
234
235
    /**
236
     * Extracts a ContentInfo object from $row.
237
     *
238
     * @param array $row
239
     * @param string $prefix Prefix for row keys, which are initially mapped by ezcontentobject fields
240
     * @param string $treePrefix Prefix for tree row key, which are initially mapped by ezcontentobject_tree_ fields
241
     *
242
     * @return \eZ\Publish\SPI\Persistence\Content\ContentInfo
243
     */
244
    public function extractContentInfoFromRow(array $row, $prefix = '', $treePrefix = 'ezcontentobject_tree_')
245
    {
246
        $contentInfo = new ContentInfo();
247
        $contentInfo->id = (int)$row["{$prefix}id"];
248
        $contentInfo->name = $row["{$prefix}name"];
249
        $contentInfo->contentTypeId = (int)$row["{$prefix}contentclass_id"];
250
        $contentInfo->sectionId = (int)$row["{$prefix}section_id"];
251
        $contentInfo->currentVersionNo = (int)$row["{$prefix}current_version"];
252
        $contentInfo->isPublished = (bool)($row["{$prefix}status"] == ContentInfo::STATUS_PUBLISHED);
253
        $contentInfo->ownerId = (int)$row["{$prefix}owner_id"];
254
        $contentInfo->publicationDate = (int)$row["{$prefix}published"];
255
        $contentInfo->modificationDate = (int)$row["{$prefix}modified"];
256
        $contentInfo->alwaysAvailable = (int)$row["{$prefix}language_mask"] & 1;
0 ignored issues
show
Documentation Bug introduced by
The property $alwaysAvailable was declared of type boolean, but (int) $row["{$prefix}language_mask"] & 1 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
257
        $contentInfo->mainLanguageCode = $this->languageHandler->load($row["{$prefix}initial_language_id"])->languageCode;
258
        $contentInfo->remoteId = $row["{$prefix}remote_id"];
259
        $contentInfo->mainLocationId = ($row["{$treePrefix}main_node_id"] !== null ? (int)$row["{$treePrefix}main_node_id"] : null);
260
261
        return $contentInfo;
262
    }
263
264
    /**
265
     * Extracts ContentInfo objects from $rows.
266
     *
267
     * @param array $rows
268
     * @param string $prefix Prefix for row keys, which are initially mapped by ezcontentobject fields
269
     * @param string $treePrefix Prefix for tree row key, which are initially mapped by ezcontentobject_tree_ fields
270
     *
271
     * @return \eZ\Publish\SPI\Persistence\Content\ContentInfo[]
272
     */
273
    public function extractContentInfoFromRows(array $rows, $prefix = '', $treePrefix = 'ezcontentobject_tree_')
274
    {
275
        $contentInfoObjects = array();
276
        foreach ($rows as $row) {
277
            $contentInfoObjects[] = $this->extractContentInfoFromRow($row, $prefix, $treePrefix);
278
        }
279
280
        return $contentInfoObjects;
281
    }
282
283
    /**
284
     * Extracts a VersionInfo object from $row.
285
     *
286
     * This method will return VersionInfo with incomplete data. It is intended to be used only by
287
     * {@link self::extractContentFromRows} where missing data will be filled in.
288
     *
289
     * @param array $row
290
     * @param array $names
291
     *
292
     * @return \eZ\Publish\SPI\Persistence\Content\VersionInfo
293
     */
294
    private function extractVersionInfoFromRow(array $row, array $names = array())
295
    {
296
        $versionInfo = new VersionInfo();
297
        $versionInfo->id = (int)$row['ezcontentobject_version_id'];
298
        $versionInfo->contentInfo = null;
299
        $versionInfo->versionNo = (int)$row['ezcontentobject_version_version'];
300
        $versionInfo->creatorId = (int)$row['ezcontentobject_version_creator_id'];
301
        $versionInfo->creationDate = (int)$row['ezcontentobject_version_created'];
302
        $versionInfo->modificationDate = (int)$row['ezcontentobject_version_modified'];
303
        $versionInfo->initialLanguageCode = $this->languageHandler->load($row['ezcontentobject_version_initial_language_id'])->languageCode;
304
        $versionInfo->languageCodes = $this->extractLanguageCodesFromMask($row['ezcontentobject_version_language_mask']);
305
        $versionInfo->status = (int)$row['ezcontentobject_version_status'];
306
        $versionInfo->names = $names;
307
308
        return $versionInfo;
309
    }
310
311
    /**
312
     * Extracts a VersionInfo object from $row.
313
     *
314
     * @param array $rows
315
     * @param array $nameRows
316
     *
317
     * @return \eZ\Publish\SPI\Persistence\Content\VersionInfo[]
318
     */
319
    public function extractVersionInfoListFromRows(array $rows, array $nameRows)
320
    {
321
        $nameData = array();
322
        foreach ($nameRows as $row) {
323
            $versionId = $row['ezcontentobject_name_contentobject_id'] . '_' . $row['ezcontentobject_name_content_version'];
324
            $nameData[$versionId][$row['ezcontentobject_name_content_translation']] = $row['ezcontentobject_name_name'];
325
        }
326
327
        $versionInfoList = array();
328
        foreach ($rows as $row) {
329
            $versionId = $row['ezcontentobject_id'] . '_' . $row['ezcontentobject_version_version'];
330
            if (!isset($versionInfoList[$versionId])) {
331
                $versionInfo = new VersionInfo();
332
                $versionInfo->id = (int)$row['ezcontentobject_version_id'];
333
                $versionInfo->contentInfo = $this->extractContentInfoFromRow($row, 'ezcontentobject_');
334
                $versionInfo->versionNo = (int)$row['ezcontentobject_version_version'];
335
                $versionInfo->creatorId = (int)$row['ezcontentobject_version_creator_id'];
336
                $versionInfo->creationDate = (int)$row['ezcontentobject_version_created'];
337
                $versionInfo->modificationDate = (int)$row['ezcontentobject_version_modified'];
338
                $versionInfo->initialLanguageCode = $this->languageHandler->load($row['ezcontentobject_version_initial_language_id'])->languageCode;
339
                $versionInfo->languageCodes = $this->extractLanguageCodesFromMask((int)$row['ezcontentobject_version_language_mask']);
340
                $versionInfo->status = (int)$row['ezcontentobject_version_status'];
341
                $versionInfo->names = $nameData[$versionId];
342
                $versionInfoList[$versionId] = $versionInfo;
343
            }
344
        }
345
346
        return array_values($versionInfoList);
347
    }
348
349
    /**
350
     * @param int $languageMask
351
     *
352
     * @return string[]
353
     */
354 View Code Duplication
    public function extractLanguageCodesFromMask($languageMask)
355
    {
356
        $exp = 2;
357
        $result = [];
358
359
        // Decomposition of $languageMask into its binary components.
360
        while ($exp <= $languageMask) {
361
            if ($languageMask & $exp) {
362
                $result[] = $this->languageHandler->load($exp)->languageCode;
363
            }
364
365
            $exp *= 2;
366
        }
367
368
        return $result;
369
    }
370
371
    /**
372
     * Extracts a Field from $row.
373
     *
374
     * @param array $row
375
     *
376
     * @return Field
377
     */
378
    protected function extractFieldFromRow(array $row)
379
    {
380
        $field = new Field();
381
382
        $field->id = (int)$row['ezcontentobject_attribute_id'];
383
        $field->fieldDefinitionId = (int)$row['ezcontentobject_attribute_contentclassattribute_id'];
384
        $field->type = $row['ezcontentobject_attribute_data_type_string'];
385
        $field->value = $this->extractFieldValueFromRow($row, $field->type);
386
        $field->languageCode = $row['ezcontentobject_attribute_language_code'];
387
        $field->versionNo = (int)$row['ezcontentobject_attribute_version'];
388
389
        return $field;
390
    }
391
392
    /**
393
     * Extracts a FieldValue of $type from $row.
394
     *
395
     * @param array $row
396
     * @param string $type
397
     *
398
     * @return \eZ\Publish\SPI\Persistence\Content\FieldValue
399
     *
400
     * @throws \eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\Converter\Exception\NotFound
401
     *         if the necessary converter for $type could not be found.
402
     */
403
    protected function extractFieldValueFromRow(array $row, $type)
404
    {
405
        $storageValue = new StorageFieldValue();
406
407
        // Nullable field
408
        $storageValue->dataFloat = isset($row['ezcontentobject_attribute_data_float'])
409
            ? (float)$row['ezcontentobject_attribute_data_float']
410
            : null;
411
        // Nullable field
412
        $storageValue->dataInt = isset($row['ezcontentobject_attribute_data_int'])
413
            ? (int)$row['ezcontentobject_attribute_data_int']
414
            : null;
415
        $storageValue->dataText = $row['ezcontentobject_attribute_data_text'];
416
        // Not nullable field
417
        $storageValue->sortKeyInt = (int)$row['ezcontentobject_attribute_sort_key_int'];
418
        $storageValue->sortKeyString = $row['ezcontentobject_attribute_sort_key_string'];
419
420
        $fieldValue = new FieldValue();
421
422
        $converter = $this->converterRegistry->getConverter($type);
423
        $converter->toFieldValue($storageValue, $fieldValue);
424
425
        return $fieldValue;
426
    }
427
428
    /**
429
     * Creates CreateStruct from $content.
430
     *
431
     * @param \eZ\Publish\SPI\Persistence\Content $content
432
     *
433
     * @return \eZ\Publish\SPI\Persistence\Content\CreateStruct
434
     */
435
    public function createCreateStructFromContent(Content $content)
436
    {
437
        $struct = new CreateStruct();
438
        $struct->name = $content->versionInfo->names;
439
        $struct->typeId = $content->versionInfo->contentInfo->contentTypeId;
440
        $struct->sectionId = $content->versionInfo->contentInfo->sectionId;
441
        $struct->ownerId = $content->versionInfo->contentInfo->ownerId;
442
        $struct->locations = array();
443
        $struct->alwaysAvailable = $content->versionInfo->contentInfo->alwaysAvailable;
444
        $struct->remoteId = md5(uniqid(get_class($this), true));
445
        $struct->initialLanguageId = $this->languageHandler->loadByLanguageCode($content->versionInfo->initialLanguageCode)->id;
446
        $struct->mainLanguageId = $this->languageHandler->loadByLanguageCode($content->versionInfo->contentInfo->mainLanguageCode)->id;
447
        $struct->modified = time();
448
449
        foreach ($content->fields as $field) {
450
            $newField = clone $field;
451
            $newField->id = null;
452
            $struct->fields[] = $newField;
453
        }
454
455
        return $struct;
456
    }
457
458
    /**
459
     * Extracts relation objects from $rows.
460
     */
461
    public function extractRelationsFromRows(array $rows)
462
    {
463
        $relations = array();
464
465
        foreach ($rows as $row) {
466
            $id = (int)$row['ezcontentobject_link_id'];
467
            if (!isset($relations[$id])) {
468
                $relations[$id] = $this->extractRelationFromRow($row);
469
            }
470
        }
471
472
        return $relations;
473
    }
474
475
    /**
476
     * Extracts a Relation object from a $row.
477
     *
478
     * @param array $row Associative array representing a relation
479
     *
480
     * @return \eZ\Publish\SPI\Persistence\Content\Relation
481
     */
482
    protected function extractRelationFromRow(array $row)
483
    {
484
        $relation = new Relation();
485
        $relation->id = (int)$row['ezcontentobject_link_id'];
486
        $relation->sourceContentId = (int)$row['ezcontentobject_link_from_contentobject_id'];
487
        $relation->sourceContentVersionNo = (int)$row['ezcontentobject_link_from_contentobject_version'];
488
        $relation->destinationContentId = (int)$row['ezcontentobject_link_to_contentobject_id'];
489
        $relation->type = (int)$row['ezcontentobject_link_relation_type'];
490
491
        $contentClassAttributeId = (int)$row['ezcontentobject_link_contentclassattribute_id'];
492
        if ($contentClassAttributeId > 0) {
493
            $relation->sourceFieldDefinitionId = $contentClassAttributeId;
494
        }
495
496
        return $relation;
497
    }
498
499
    /**
500
     * Creates a Content from the given $struct.
501
     *
502
     * @param \eZ\Publish\SPI\Persistence\Content\Relation\CreateStruct $struct
503
     *
504
     * @return \eZ\Publish\SPI\Persistence\Content\Relation
505
     */
506
    public function createRelationFromCreateStruct(RelationCreateStruct $struct)
507
    {
508
        $relation = new Relation();
509
510
        $relation->destinationContentId = $struct->destinationContentId;
511
        $relation->sourceContentId = $struct->sourceContentId;
512
        $relation->sourceContentVersionNo = $struct->sourceContentVersionNo;
513
        $relation->sourceFieldDefinitionId = $struct->sourceFieldDefinitionId;
514
        $relation->type = $struct->type;
515
516
        return $relation;
517
    }
518
}
519