Passed
Push — dev_2x ( 241dab...1e248d )
by Adrian
01:59
created

ClassMethodsHydrator::getMapperConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Sirius\Orm\Entity;
5
6
use Sirius\Orm\CastingManager;
7
use Sirius\Orm\Contract\EntityInterface;
8
use Sirius\Orm\Contract\HydratorInterface;
9
use Sirius\Orm\Contract\LazyLoader;
10
use Sirius\Orm\Contract\Relation\ToManyInterface;
11
use Sirius\Orm\Contract\Relation\ToOneInterface;
12
use Sirius\Orm\Helpers\Arr;
13
use Sirius\Orm\Helpers\Str;
14
use Sirius\Orm\Mapper;
15
use Sirius\Orm\MapperConfig;
16
17
class ClassMethodsHydrator implements HydratorInterface
18
{
19
    /**
20
     * @var CastingManager
21
     */
22
    protected $castingManager;
23
24
    /**
25
     * @var Mapper
26
     */
27
    protected $mapper;
28
29
    public function __construct(CastingManager $castingManager)
30
    {
31
        $this->castingManager = $castingManager;
32
    }
33
34
    public function setMapper(Mapper $mapper)
35
    {
36
        $this->mapper = $mapper;
37
    }
38
39
    /**
40
     * @param array $attributes
41
     *
42
     * @return mixed|ClassMethodsEntity
43
     */
44
    public function hydrate(array $attributes = [])
45
    {
46
        $attributes = Arr::renameKeys($attributes, $this->getMapperConfig()->getColumnAttributeMap());
47
        if ($this->castingManager) {
48
            $attributes = $this->castingManager
49
                ->castArray($attributes, $this->getMapperConfig()->getCasts());
50
        }
51
52
        $attributes = $this->compileRelations($attributes);
53
54
        $class = $this->getMapperConfig()->getEntityClass() ?? GenericEntity::class;
55
56
        return new $class($attributes);
57
    }
58
59
    /**
60
     * @param EntityInterface $entity
61
     *
62
     * @return array
63
     */
64
    public function extract(EntityInterface $entity)
65
    {
66
        $data = Arr::renameKeys(
67
            $entity->toArray(),
68
            array_flip($this->getMapperConfig()->getColumnAttributeMap())
69
        );
70
        if ($this->castingManager) {
71
            $data = $this->castingManager
72
                ->castArrayForDb($data, $this->getMapperConfig()->getCasts());
73
        }
74
75
        return Arr::only($data, $this->getMapperConfig()->getColumns());
76
    }
77
78
    /**
79
     * @param $entity
80
     * @param $attribute
81
     *
82
     * @return mixed
83
     */
84
    public function get(EntityInterface $entity, $attribute)
85
    {
86
        $method = Str::methodName($attribute, 'get');
87
88
        return $entity->{$method}();
89
    }
90
91
    /**
92
     * @param $entity
93
     * @param $attribute
94
     * @param $value
95
     *
96
     * @return mixed
97
     */
98
    public function set(EntityInterface $entity, $attribute, $value)
99
    {
100
        if ($value instanceof LazyLoader) {
101
            return $entity->setLazy($attribute, $value);
102
        }
103
104
        $method = Str::methodName($attribute, 'set');
105
106
        return $entity->{$method}($value);
107
    }
108
109
    /**
110
     * @param $entity
111
     *
112
     * @return mixed
113
     */
114
    public function getPk($entity)
115
    {
116
        return $this->get($entity, $this->getMapperConfig()->getPrimaryKey());
117
    }
118
119
    /**
120
     * Set primary key on an entity
121
     *
122
     * @param $entity
123
     * @param $value
124
     *
125
     * @return mixed
126
     */
127
    public function setPk($entity, $value)
128
    {
129
        return $this->set($entity, $this->getMapperConfig()->getPrimaryKey(), $value);
130
    }
131
132
    protected function compileRelations(array $attributes)
133
    {
134
        foreach ($this->mapper->getRelations() as $name) {
135
            $relation = $this->mapper->getRelation($name);
136
            if ($relation instanceof ToOneInterface &&
137
                isset($attributes[$name]) &&
138
                ! is_object($attributes[$name])) {
139
                $attributes[$name] = $relation->getForeignMapper()->newEntity($attributes[$name]);
140
            } elseif ($relation instanceof ToManyInterface &&
141
                      ! $relation instanceof ToOneInterface
142
                      && ( ! isset($attributes[$name]) || is_array($attributes[$name]))) {
143
                /**
144
                 * we also need to check against ToOneInterface because OneToOne relation extends
145
                 * OneToMany which implements ToOneInterface
146
                 * @todo remove this quirk
147
                 */
148
                $attributes[$name] = $relation->getForeignMapper()->newCollection($attributes[$name] ?? []);
149
            }
150
        }
151
152
        return $attributes;
153
    }
154
155
    protected function getMapperConfig(): MapperConfig
156
    {
157
        return $this->mapper->getConfig();
158
    }
159
}
160