Completed
Push — master ( 814e9e...2525ff )
by Filipe
03:26
created

EntityMapper::createMultiple()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 8
ccs 0
cts 6
cp 0
rs 9.4285
cc 2
eloc 5
nc 2
nop 1
crap 6
1
<?php
2
3
/**
4
 * This file is part of slick/orm package
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Slick\Orm\Mapper;
11
12
use Slick\Database\Adapter\AdapterInterface;
13
use Slick\Database\RecordList;
14
use Slick\Database\Sql;
15
use Slick\Orm\Descriptor\EntityDescriptorInterface;
16
use Slick\Orm\Descriptor\EntityDescriptorRegistry;
17
use Slick\Orm\Descriptor\Field\FieldDescriptor;
18
use Slick\Orm\Entity\EntityCollection;
19
use Slick\Orm\EntityInterface;
20
use Slick\Orm\EntityMapperInterface;
21
22
/**
23
 * Generic Entity Mapper
24
 *
25
 * @package Slick\Orm\Mapper
26
 * @author  Filipe Silva <[email protected]>
27
 */
28
class EntityMapper implements EntityMapperInterface
29
{
30
    /**
31
     * @var EntityDescriptorInterface
32
     */
33
    protected $descriptor;
34
35
    /**
36
     * @var EntityInterface
37
     */
38
    protected $entity;
39
40
    /**
41
     * @var AdapterInterface
42
     */
43
    protected $adapter;
44
45
    /**
46
     * Saves current entity object to database
47
     *
48
     * Optionally saves only the partial data if $data argument is passed. If
49
     * no data is given al the field properties will be updated.
50
     *
51
     * @param array $data Partial data to save
52
     * @param EntityInterface $entity
53
     *
54
     * @return self|$this|EntityMapperInterface
55
     */
56 4
    public function save(EntityInterface $entity, array $data = [])
57
    {
58 4
        $this->entity = $entity;
59 4
        $query = $this->getUpdateQuery();
60 4
        $query->set($this->getData())
61 4
            ->execute();
62 4
        return $this;
63
    }
64
65
    /**
66
     * Get entity descriptor
67
     *
68
     * @return EntityDescriptorInterface
69
     */
70 4
    public function getDescriptor()
71
    {
72 4
        if (null == $this->descriptor) {
73 4
            $this->setDescriptor(
74 4
                EntityDescriptorRegistry::getInstance()
75 4
                    ->getDescriptorFor(get_class($this->entity))
76 2
            );
77 2
        }
78 4
        return $this->descriptor;
79
    }
80
81
    /**
82
     * Set entity descriptor
83
     *
84
     * @param EntityDescriptorInterface $descriptor
85
     *
86
     * @return $this|self|EntityMapper
87
     */
88 4
    public function setDescriptor($descriptor)
89
    {
90 4
        $this->descriptor = $descriptor;
91 4
        return $this;
92
    }
93
94
    /**
95
     * Sets the adapter for this mapper
96
     *
97
     * @param AdapterInterface $adapter
98
     *
99
     * @return self|$this|EntityMapper
100
     */
101 8
    public function setAdapter(AdapterInterface $adapter)
102
    {
103 8
        $this->adapter = $adapter;
104 8
        return $this;
105
    }
106
107
    /**
108
     * Retrieves the current adapter
109
     *
110
     * @return AdapterInterface
111
     */
112 4
    public function getAdapter()
113
    {
114 4
        return $this->adapter;
115
    }
116
117
    /**
118
     * Creates the insert/update query for current entity state
119
     *
120
     * @return Sql\Insert|Sql\Update
121
     */
122 4
    protected function getUpdateQuery()
123
    {
124 4
        $primaryKey = $this->getDescriptor()->getPrimaryKey()->getName();
125 4
        $table = $this->getDescriptor()->getTableName();
126 4
        $sql = Sql::createSql($this->getAdapter());
127 4
        $query = (null === $this->entity->{$primaryKey})
128 3
            ? $sql->insert($table)
129 3
            : $this->setUpdateCriteria(
130 3
                $sql->update($table),
131 1
                $primaryKey,
132
                $table
133 2
            );
134 4
        return $query;
135
    }
136
137
    /**
138
     * Adds the update criteria for an update query
139
     *
140
     * @param Sql\Update $query
141
     * @param string $primaryKey
142
     * @param string $table
143
     *
144
     * @return Sql\Update
145
     */
146 2
    protected function setUpdateCriteria(
147
        Sql\Update $query, $primaryKey, $table
148
    ) {
149 2
        $key = "{$table}.{$primaryKey} = :id";
150 2
        $query->where([$key => [':id' => $this->entity->{$primaryKey}]]);
0 ignored issues
show
Documentation introduced by
array($key => array(':id...entity->{$primaryKey})) is of type array<?,array<string,?,{":id":"?"}>>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
151 2
        return $query;
152
    }
153
154
    /**
155
     * Gets data to be used in queries
156
     *
157
     * @return array
158
     */
159 4
    protected function getData()
160
    {
161 4
        $data = [];
162 4
        $fields = $this->getDescriptor()->getFields();
163
        /** @var FieldDescriptor $field */
164 4
        foreach ($fields as $field) {
165 4
            $data[$field->getField()] = $this->entity->{$field->getName()};
166 2
        }
167 4
        return $data;
168
    }
169
170
    /**
171
     * Creates an entity object from provided data
172
     *
173
     * Data can be an array with single row fields or a RecordList from
174
     * a query.
175
     *
176
     * @param array|RecordList $data
177
     *
178
     * @return EntityInterface|EntityMapperInterface[]|EntityCollection
179
     */
180
    public function createFrom($data)
181
    {
182
        if ($data instanceof RecordList) {
183
            return $this->createMultiple($data);
184
        }
185
        return $this->createSingle($data);
186
    }
187
188
    /**
189
     * Creates an entity for provided row array
190
     *
191
     * @param array $source
192
     * @return EntityInterface
193
     */
194
    protected function createSingle(array $source)
195
    {
196
        $data = [];
197
        /** @var FieldDescriptor $field */
198
        foreach ($this->getDescriptor()->getFields() as $field) {
199
            if (array_key_exists($field->getField(), $source)) {
200
                $data[$field->getName()] = $source[$field->getField()];
201
            }
202
        }
203
        $class = $this->getDescriptor()->className();
204
        return new $class($data);
205
    }
206
207
    /**
208
     * Creates an entity collection for provided record list
209
     *
210
     * @param RecordList $source
211
     * @return EntityCollection
212
     */
213
    protected function createMultiple(RecordList $source)
214
    {
215
        $data = [];
216
        foreach ($source as $item) {
217
            $data[] = $this->createSingle($item);
218
        }
219
        return new EntityCollection($data);
220
    }
221
}