GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 2af5da...2e841b )
by Steevan
02:43
created

SimpleObjectHydrator::hydrateRowData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 7
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
1
<?php
2
3
namespace steevanb\DoctrineReadOnlyHydrator\Hydrator;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\ORM\Internal\Hydration\ArrayHydrator;
7
use Doctrine\ORM\Mapping\ClassMetadata;
8
9
class SimpleObjectHydrator extends ArrayHydrator
10
{
11
    const HYDRATOR_NAME = 'simpleObject';
12
13
    /** @var string */
14
    protected $rootClassName;
15
16
    protected function prepare()
17
    {
18
        parent::prepare();
19
20
        $this->rootClassName = null;
21
    }
22
23
    /**
24
     * @param array $data
25
     * @param array $result
26
     */
27
    protected function hydrateRowData(array $data, array &$result)
28
    {
29
        $arrayData = array();
30
        parent::hydrateRowData($data, $arrayData);
31
32
        $result[] = $this->doHydrateRowData($this->getRootClassName(), $arrayData[0]);
33
    }
34
35
    /**
36
     * @return string
37
     */
38
    protected function getRootclassName()
39
    {
40
        // i don't understand when we can have more than one item in ArrayHydrator::$_rootAliases
41
        // so, i assume first one is the right one
42
        if ($this->rootClassName === null) {
43
            $rootAlias = key($this->getPrivatePropertyValue(ArrayHydrator::class, '_rootAliases', $this));
44
            $this->rootClassName = $this->_rsm->aliasMap[$rootAlias];
45
        }
46
47
        return $this->rootClassName;
48
    }
49
50
    /**
51
     * @param string $className
52
     * @param array $data
53
     * @return object
54
     * @throws \Exception
55
     */
56
    protected function doHydrateRowData($className, array $data)
57
    {
58
        $classMetaData = $this->_em->getClassMetadata($className);
59
        $mappings = $classMetaData->getAssociationMappings();
60
        $entity = $this->createEntity($classMetaData, $data);
0 ignored issues
show
Compatibility introduced by
$classMetaData of type object<Doctrine\Common\P...\Mapping\ClassMetadata> is not a sub-type of object<Doctrine\ORM\Mapping\ClassMetadata>. It seems like you assume a concrete implementation of the interface Doctrine\Common\Persistence\Mapping\ClassMetadata to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
61
        $reflection = new \ReflectionObject($entity);
62
63
        foreach ($data as $name => $value) {
64
            if (array_key_exists($name, $mappings)) {
65
                $mapping = $mappings[$name];
66
                switch ($mapping['type']) {
67
                    case ClassMetadata::ONE_TO_ONE:
68
                        $value = $this->hydrateOneToOne($mapping, $value);
69
                        break;
70
                    case ClassMetadata::ONE_TO_MANY:
71
                        $value = $this->hydrateOneToMany($mapping, $value);
72
                        break;
73
                    case ClassMetadata::MANY_TO_ONE:
74
                        $value = $this->hydrateManyToOne($mapping, $value);
75
                        break;
76
                    case ClassMetadata::MANY_TO_MANY:
77
                        $value = $this->hydrateManyToMany($mapping, $value);
78
                        break;
79
                    default:
80
                        throw new \Exception('Unknow mapping type "' . $mapping['type'] . '".');
81
                }
82
            }
83
84
            if (
85
                $classMetaData->inheritanceType === ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE
0 ignored issues
show
Bug introduced by
Accessing inheritanceType 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...
86
                && isset($entity->$name) === false
87
            ) {
88
                continue;
89
            }
90
            $property = $reflection->getProperty($name);
91
            if ($property->isPublic()) {
92
                $entity->$name = $value;
93
            } else {
94
                $property->setAccessible(true);
95
                $property->setValue($entity, $value);
96
                $property->setAccessible(false);
97
            }
98
        }
99
100
        return $entity;
101
    }
102
103
    /**
104
     * @param ClassMetadata $classMetaData
105
     * @param array $data
106
     * @return mixed
107
     * @throws \Exception
108
     */
109
    protected function createEntity(ClassMetadata $classMetaData, array $data)
110
    {
111
        $className = $this->getEntityClassName($classMetaData, $data);
112
        $reflection = new \ReflectionClass($className);
113
        $entity = $reflection->newInstanceWithoutConstructor();
114
115
        return $entity;
116
    }
117
118
    /**
119
     * @param ClassMetadata $classMetaData
120
     * @param array $data
121
     * @return string
122
     * @throws \Exception
123
     */
124
    protected function getEntityClassName(ClassMetadata $classMetaData, array $data)
125
    {
126
        switch ($classMetaData->inheritanceType) {
127
            case ClassMetadata::INHERITANCE_TYPE_NONE:
128
                $return = $classMetaData->name;
129
                break;
130
            case ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE:
131
                if (array_key_exists($classMetaData->discriminatorColumn['name'], $data) === false) {
132
                    $exception = 'Discriminator column "' . $classMetaData->discriminatorColumn['name'] . '" ';
133
                    $exception .= 'for "' . $classMetaData->name . '" does not exists in $data.';
134
                    throw new \Exception($exception);
135
                }
136
                $discriminator = $data[$classMetaData->discriminatorColumn['name']];
137
                $return = $classMetaData->discriminatorMap[$discriminator];
138
                break;
139
            default:
140
                throw new \Exception('Unknow inheritance type "' . $classMetaData->inheritanceType . '".');
141
        }
142
143
        return $return;
144
    }
145
146
    /**
147
     * @param array $mapping
148
     * @param array $data
149
     * @return ArrayCollection
150
     */
151
    protected function hydrateOneToOne(array $mapping, $data)
152
    {
153
        return $this->doHydrateRowData($mapping['targetEntity'], $data);
154
    }
155
156
    /**
157
     * @param array $mapping
158
     * @param array $data
159
     * @return ArrayCollection
160
     */
161 View Code Duplication
    protected function hydrateOneToMany(array $mapping, $data)
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...
162
    {
163
        $entities = [];
164
        foreach ($data as $linkedData) {
165
            $entities[] = $this->doHydrateRowData($mapping['targetEntity'], $linkedData);
166
        }
167
168
        return new ArrayCollection($entities);
169
    }
170
171
    /**
172
     * @param array $mapping
173
     * @param array $data
174
     * @return ArrayCollection
175
     */
176
    protected function hydrateManyToOne(array $mapping, $data)
177
    {
178
        return $this->doHydrateRowData($mapping['targetEntity'], $data);
179
    }
180
181
    /**
182
     * @param array $mapping
183
     * @param array $data
184
     * @return ArrayCollection
185
     */
186 View Code Duplication
    protected function hydrateManyToMany(array $mapping, $data)
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
        $entities = [];
189
        foreach ($data as $linkedData) {
190
            $entities[] = $this->doHydrateRowData($mapping['targetEntity'], $linkedData);
191
        }
192
193
        return new ArrayCollection($entities);
194
    }
195
196
    /**
197
     * @param string $className
198
     * @param string $property
199
     * @param object $object
200
     * @return mixed
201
     */
202
    protected function getPrivatePropertyValue($className, $property, $object)
203
    {
204
        $reflection = new \ReflectionProperty($className, $property);
205
        $accessible = $reflection->isPublic();
206
        $reflection->setAccessible(true);
207
        $value = $reflection->getValue($object);
208
        $reflection->setAccessible($accessible === false);
209
210
        return $value;
211
    }
212
}
213