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

PatchDehydrator::convertEntityToData()   C

Complexity

Conditions 11
Paths 14

Size

Total Lines 52
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 40
CRAP Score 11

Importance

Changes 0
Metric Value
dl 0
loc 52
ccs 40
cts 40
cp 1
rs 5.9999
c 0
b 0
f 0
cc 11
eloc 36
nc 14
nop 1
crap 11

How to fix   Long Method    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 25
    public function __construct(EntityPersister $persister, ApiMetadata $metadata, ApiEntityManager $manager)
27
    {
28 25
        $this->persister = $persister;
29 25
        $this->metadata  = $metadata;
30 25
        $this->manager   = $manager;
31 25
    }
32
33 7
    public function convertEntityToData($entity)
34
    {
35 7
        $entityData = [];
36
37 7
        $discriminatorField = $this->metadata->getDiscriminatorField();
38
39 7
        if (null !== $discriminatorField) {
40 1
            $entityData[$discriminatorField['fieldName']] = $this->metadata->getDiscriminatorValue();
41 1
        }
42
43 7
        foreach ($this->metadata->getReflectionProperties() as $name => $property) {
44 7
            if ($this->metadata->isIdentifier($name) && $this->metadata->isIdentifierRemote()) {
45 7
                continue;
46
            }
47 7
            $apiField = $this->metadata->getApiFieldName($name);
48 7
            $value    = $property->getValue($entity);
49 7
            if (null === $value) {
50 6
                $entityData[$apiField] = $value;
51 6
                continue;
52
            }
53
54 4
            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, $targetMetadata->getFieldOptions($idName));
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 2
                $typeName = $this->metadata->getTypeOfField($name);
76 2
                $type     = $this->manager->getConfiguration()->getTypeRegistry()->get($typeName);
77 2
                $value    = $type->toApiValue($value, $this->metadata->getFieldOptions($name));
78
            }
79
80 4
            $entityData[$apiField] = $value;
81 7
        }
82
83 7
        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