JsonApiHydrator   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 2
dl 0
loc 82
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A hydrateProperties() 0 8 3
B hydrateAssociations() 0 26 7
A mapRelationshipsArray() 0 9 2
A getResourceId() 0 8 3
1
<?php
2
namespace pmill\Doctrine\Hydrator;
3
4
/**
5
 * Json API Request Doctrine Hydrator
6
 * @link http://jsonapi.org/format/#document-resource-objects
7
 */
8
class JsonApiHydrator extends ArrayHydrator
9
{
10
    /**
11
     * @param $entity
12
     * @param $data
13
     *
14
     * @return object
15
     */
16
    protected function hydrateProperties($entity, $data)
17
    {
18
        if (isset($data['attributes']) && is_array($data['attributes'])) {
19
            $entity = parent::hydrateProperties($entity, $data['attributes']);
20
        }
21
22
        return $entity;
23
    }
24
25
    /**
26
     * Map JSON API resource relations to doctrine entity.
27
     *
28
     * @param object $entity
29
     * @param array  $data
30
     *
31
     * @return mixed
32
     * @throws \Exception
33
     */
34
    protected function hydrateAssociations($entity, $data)
35
    {
36
        if (isset($data['relationships']) && is_array($data['relationships'])) {
37
            $metadata = $this->entityManager->getClassMetadata(get_class($entity));
38
39
            foreach ($data['relationships'] as $name => $data) {
40
                if (!isset($metadata->associationMappings[$name])) {
0 ignored issues
show
Bug introduced by
Accessing associationMappings on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
41
                    throw new \Exception(sprintf('Relation `%s` association not found', $name));
42
                }
43
44
                $mapping = $metadata->associationMappings[$name];
0 ignored issues
show
Bug introduced by
Accessing associationMappings on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
45
46
                if (is_array($data['data'])) {
47
                    if ($resourceId = $this->getResourceId($data['data'])) {
48
                        $this->hydrateToOneAssociation($entity, $name, $mapping, $resourceId);
49
                    } else {
50
                        $this->hydrateToManyAssociation($entity, $name, $mapping,
51
                            $this->mapRelationshipsArray($data['data'])
52
                        );
53
                    }
54
                }
55
            }
56
        }
57
58
        return $entity;
59
    }
60
61
    /**
62
     * @param array $data
63
     *
64
     * @return array
65
     */
66
    protected function mapRelationshipsArray(array $data)
67
    {
68
        return array_map(
69
            function ($relation) {
70
                return $this->getResourceId($relation) ?: ['attributes' => $relation];
71
            },
72
            $data
73
        );
74
    }
75
76
    /**
77
     * @param array $data
78
     *
79
     * @return int|null
80
     */
81
    protected function getResourceId(array $data)
82
    {
83
        if (isset($data['id']) && isset($data['type'])) {
84
            return $data['id'];
85
        }
86
87
        return null;
88
    }
89
}
90