Passed
Pull Request — master (#14)
by Pavel
03:16
created

PatchDehydrator::prepareUpdateData()   D

Complexity

Conditions 10
Paths 15

Size

Total Lines 39
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 10.2918

Importance

Changes 0
Metric Value
dl 0
loc 39
ccs 24
cts 28
cp 0.8571
rs 4.8196
c 0
b 0
f 0
cc 10
eloc 25
nc 15
nop 1
crap 10.2918

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Bankiru\Api\Doctrine\Dehydration;
4
5
use Bankiru\Api\Doctrine\ApiEntityManager;
6
use Bankiru\Api\Doctrine\Mapping\ApiMetadata;
7
use Bankiru\Api\Doctrine\Persister\EntityPersister;
8
9
/** @internal */
10
final class PatchDehydrator
11
{
12
    /** @var EntityPersister */
13
    private $persister;
14
    /** @var ApiMetadata */
15
    private $metadata;
16
    /** @var ApiEntityManager */
17
    private $manager;
18
19
    /**
20
     * PatchDehydrator constructor.
21
     *
22
     * @param EntityPersister  $persister
23
     * @param ApiMetadata      $metadata
24
     * @param ApiEntityManager $manager
25
     */
26 23
    public function __construct(EntityPersister $persister, ApiMetadata $metadata, ApiEntityManager $manager)
27
    {
28 23
        $this->persister = $persister;
29 23
        $this->metadata  = $metadata;
30 23
        $this->manager   = $manager;
31 23
    }
32
33 6
    public function convertEntityToData($entity)
34
    {
35 6
        $entityData = [];
36
37 6
        $discriminatorField = $this->metadata->getDiscriminatorField();
38
39 6
        if (null !== $discriminatorField) {
40 1
            $entityData[$discriminatorField['fieldName']] = $this->metadata->getDiscriminatorValue();
41 1
        }
42
43 6
        foreach ($this->metadata->getReflectionProperties() as $name => $property) {
44 6
            if ($this->metadata->isIdentifier($name) && $this->metadata->isIdentifierRemote()) {
45 6
                continue;
46
            }
47 6
            $apiField = $this->metadata->getApiFieldName($name);
48 6
            $value    = $property->getValue($entity);
49 6
            if (null === $value) {
50 6
                $entityData[$apiField] = $value;
51 6
                continue;
52
            }
53
54 3
            if ($this->metadata->hasAssociation($name)) {
55 2
                $mapping = $this->metadata->getAssociationMapping($name);
56 2
                if (($mapping['type'] & ApiMetadata::TO_MANY) && !$mapping['isOwningSide']) {
57 2
                    continue;
58
                }
59 2
                $target         = $this->metadata->getAssociationMapping($name)['target'];
60 2
                $targetMetadata = $this->manager->getClassMetadata($target);
61 2
                $value          = $targetMetadata->getIdentifierValues($value);
62 2
                $ids            = [];
63 2
                foreach ($value as $idName => $idValue) {
64 2
                    $typeName        = $targetMetadata->getTypeOfField($idName);
65 2
                    $idApiName       = $targetMetadata->getApiFieldName($idName);
66 2
                    $type            = $this->manager->getConfiguration()->getTypeRegistry()->get($typeName);
67 2
                    $idValue         = $type->toApiValue($idValue);
68 2
                    $ids[$idApiName] = $idValue;
69 2
                }
70 2
                if (!$targetMetadata->isIdentifierComposite()) {
0 ignored issues
show
Bug introduced by
The method isIdentifierComposite() does not exist on Doctrine\Common\Persistence\Mapping\ClassMetadata. Did you maybe mean isIdentifier()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
71 2
                    $ids = array_shift($ids);
72 2
                }
73 2
                $value = $ids;
74 2
            } else {
75 1
                $typeName = $this->metadata->getTypeOfField($name);
76 1
                $type     = $this->manager->getConfiguration()->getTypeRegistry()->get($typeName);
77 1
                $value    = $type->toApiValue($value);
78
            }
79
80 3
            $entityData[$apiField] = $value;
81 6
        }
82
83 6
        return $entityData;
84
    }
85
86
    /**
87
     * Prepares the changeset of an entity for database insertion (UPDATE).
88
     *
89
     * The changeset is obtained from the currently running UnitOfWork.
90
     *
91
     * During this preparation the array that is passed as the second parameter is filled with
92
     * <columnName> => <value> pairs, grouped by table name.
93
     *
94
     * Example:
95
     * <code>
96
     * array(
97
     *    'foo_table' => array('column1' => 'value1', 'column2' => 'value2', ...),
98
     *    'bar_table' => array('columnX' => 'valueX', 'columnY' => 'valueY', ...),
99
     *    ...
100
     * )
101
     * </code>
102
     *
103
     * @param object $entity The entity for which to prepare the data.
104
     *
105
     * @return array The prepared data.
106
     */
107 2
    public function prepareUpdateData($entity)
108
    {
109 2
        $result = [];
110 2
        $uow    = $this->manager->getUnitOfWork();
111 2
        foreach ($uow->getEntityChangeSet($entity) as $field => $change) {
112 2
            $newVal = $change[1];
113 2
            if (!$this->metadata->hasAssociation($field)) {
114
115 1
                $result[$this->metadata->getApiFieldName($field)] = $newVal;
116 1
                continue;
117
            }
118 1
            $assoc = $this->metadata->getAssociationMapping($field);
119
            // Only owning side of x-1 associations can have a FK column.
120 1
            if (!$assoc['isOwningSide'] || !($assoc['type'] & ApiMetadata::TO_ONE)) {
121
                continue;
122
            }
123 1
            if ($newVal !== null) {
124 1
                $oid = spl_object_hash($newVal);
125 1
                if ($this->persister->hasPendingUpdates($oid) || $uow->isScheduledForInsert($newVal)) {
126
                    // The associated entity $newVal is not yet persisted, so we must
127
                    // set $newVal = null, in order to insert a null value and schedule an
128
                    // extra update on the UnitOfWork.
129
                    $uow->scheduleExtraUpdate($entity, [$field => [null, $newVal]]);
130
                    $newVal = null;
131
                }
132 1
            }
133 1
            $newValId = null;
134 1
            if ($newVal !== null) {
135 1
                $newValId = $uow->getEntityIdentifier($newVal);
136 1
            }
137
            $targetClass                                      =
138 1
                $this->manager->getClassMetadata($assoc['target']);
139 1
            $result[$this->metadata->getApiFieldName($field)] = $newValId
140 1
                ? $newValId[$targetClass->getIdentifierFieldNames()[0]]
141 1
                : null;
142 2
        }
143
144 2
        return $result;
145
    }
146
}
147