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 ( 1e1cfe...2af5da )
by Steevan
02:22
created

SimpleObjectHydrator::createEntity()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 8
rs 9.4285
cc 1
eloc 5
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
    /**
14
     * @param array $data
15
     * @param array $result
16
     */
17
    protected function hydrateRowData(array $data, array &$result)
18
    {
19
        $arrayData = array();
20
        parent::hydrateRowData($data, $arrayData);
21
22
        $rootAlias = key($this->getPrivatePropertyValue(ArrayHydrator::class, '_rootAliases', $this));
23
        $result[] = $this->doHydrateRowData($this->_rsm->aliasMap[$rootAlias], $arrayData[0]);
24
    }
25
26
    /**
27
     * @param string $className
28
     * @param array $data
29
     * @return object
30
     * @throws \Exception
31
     */
32
    protected function doHydrateRowData($className, array $data)
33
    {
34
        $classMetaData = $this->_em->getClassMetadata($className);
35
        $mappings = $classMetaData->getAssociationMappings();
36
        $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...
37
        $reflection = new \ReflectionObject($entity);
38
39
        foreach ($data as $name => $value) {
40
            if (array_key_exists($name, $mappings)) {
41
                $mapping = $mappings[$name];
42
                switch ($mapping['type']) {
43
                    case ClassMetadata::ONE_TO_ONE:
44
                        $value = $this->hydrateOneToOne($mapping, $value);
45
                        break;
46
                    case ClassMetadata::ONE_TO_MANY:
47
                        $value = $this->hydrateOneToMany($mapping, $value);
48
                        break;
49
                    case ClassMetadata::MANY_TO_ONE:
50
                        $value = $this->hydrateManyToOne($mapping, $value);
51
                        break;
52
                    case ClassMetadata::MANY_TO_MANY:
53
                        $value = $this->hydrateManyToMany($mapping, $value);
54
                        break;
55
                    default:
56
                        throw new \Exception('Unknow mapping type "' . $mapping['type'] . '".');
57
                }
58
            }
59
60
            if (
61
                $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...
62
                && isset($entity->$name) === false
63
            ) {
64
                continue;
65
            }
66
            $property = $reflection->getProperty($name);
67
            $isAccessible = $property->isPublic() === false;
68
            $property->setAccessible(true);
69
            $property->setValue($entity, $value);
70
            $property->setAccessible($isAccessible);
71
        }
72
73
        return $entity;
74
    }
75
76
    /**
77
     * @param ClassMetadata $classMetaData
78
     * @param array $data
79
     * @return mixed
80
     * @throws \Exception
81
     */
82
    protected function createEntity(ClassMetadata $classMetaData, array $data)
83
    {
84
        $className = $this->getEntityClassName($classMetaData, $data);
85
        $reflection = new \ReflectionClass($className);
86
        $entity = $reflection->newInstanceWithoutConstructor();
87
88
        return $entity;
89
    }
90
91
    /**
92
     * @param ClassMetadata $classMetaData
93
     * @param array $data
94
     * @return string
95
     * @throws \Exception
96
     */
97
    protected function getEntityClassName(ClassMetadata $classMetaData, array $data)
98
    {
99
        switch ($classMetaData->inheritanceType) {
100
            case ClassMetadata::INHERITANCE_TYPE_NONE:
101
                $return = $classMetaData->name;
102
                break;
103
            case ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE:
104
                if (array_key_exists($classMetaData->discriminatorColumn['name'], $data) === false) {
105
                    $exception = 'Discriminator column "' . $classMetaData->discriminatorColumn['name'] . '" ';
106
                    $exception .= 'for "' . $classMetaData->name . '" does not exists in $data.';
107
                    throw new \Exception($exception);
108
                }
109
                $discriminator = $data[$classMetaData->discriminatorColumn['name']];
110
                $return = $classMetaData->discriminatorMap[$discriminator];
111
                break;
112
            default:
113
                throw new \Exception('Unknow inheritance type "' . $classMetaData->inheritanceType . '".');
114
        }
115
116
        return $return;
117
    }
118
119
    /**
120
     * @param array $mapping
121
     * @param array $data
122
     * @return ArrayCollection
123
     */
124
    protected function hydrateOneToOne(array $mapping, $data)
125
    {
126
        return $this->doHydrateRowData($mapping['targetEntity'], $data);
127
    }
128
129
    /**
130
     * @param array $mapping
131
     * @param array $data
132
     * @return ArrayCollection
133
     */
134 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...
135
    {
136
        $entities = [];
137
        foreach ($data as $linkedData) {
138
            $entities[] = $this->doHydrateRowData($mapping['targetEntity'], $linkedData);
139
        }
140
141
        return new ArrayCollection($entities);
142
    }
143
144
    /**
145
     * @param array $mapping
146
     * @param array $data
147
     * @return ArrayCollection
148
     */
149
    protected function hydrateManyToOne(array $mapping, $data)
150
    {
151
        return $this->doHydrateRowData($mapping['targetEntity'], $data);
152
    }
153
154
    /**
155
     * @param array $mapping
156
     * @param array $data
157
     * @return ArrayCollection
158
     */
159 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...
160
    {
161
        $entities = [];
162
        foreach ($data as $linkedData) {
163
            $entities[] = $this->doHydrateRowData($mapping['targetEntity'], $linkedData);
164
        }
165
166
        return new ArrayCollection($entities);
167
    }
168
169
    /**
170
     * @param string $className
171
     * @param string $property
172
     * @param object $object
173
     * @return mixed
174
     */
175
    protected function getPrivatePropertyValue($className, $property, $object)
176
    {
177
        $reflection = new \ReflectionProperty($className, $property);
178
        $accessible = $reflection->isPublic();
179
        $reflection->setAccessible(true);
180
        $value = $reflection->getValue($object);
181
        $reflection->setAccessible($accessible === false);
182
183
        return $value;
184
    }
185
}
186