Completed
Push — master ( 2e5aab...1fffaf )
by Denis
03:46
created

Model::set()   C

Complexity

Conditions 8
Paths 6

Size

Total Lines 22
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 8.0291

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 12
cts 13
cp 0.9231
rs 6.6037
c 0
b 0
f 0
cc 8
eloc 11
nc 6
nop 2
crap 8.0291
1
<?php
2
/**
3
 * Class Model
4
 *
5
 * @author       Denis Shestakov <[email protected]>
6
 * @copyright    Copyright (c) 2017, Lan Publishing
7
 * @license      MIT
8
 */
9
10
namespace Lan\Ebs\Sdk\Classes;
11
12
use Exception;
13
use Lan\Ebs\Sdk\Client;
14
use Lan\Ebs\Sdk\Common;
15
16
/**
17
 *  Абстрактный класс моделей
18
 *
19
 * @package      Lan\Ebs
20
 * @subpackage   Sdk
21
 * @category     Classes
22
 */
23
abstract class Model implements Common
24
{
25
    const MESSAGE_ID_REQUIRED = 'Id is required';
26
    const MESSAGE_ID_CAN_NOT_CHANGED = 'Id can not be changed';
27
28
    /**
29
     * Инстанс клиента API
30
     *
31
     * @var Client
32
     */
33
    private $client;
34
35
    /**
36
     * Имена полей, подлежаших получению через API
37
     *
38
     * @var array
39
     */
40
    private $fields = [];
41
42
    /**
43
     * Данные модели
44
     *
45
     * @var array
46
     */
47
    private $data = [];
48
49
    /**
50
     * Идентификатор модели
51
     *
52
     * @var null
53
     */
54
    private $id = null;
55
56
    /**
57
     * Статус последнего обращения по API
58
     *
59
     * @var int
60
     */
61
    private $lastStatus = 0;
62
63
    /**
64
     * Конструктор модели
65
     *
66
     * @param Client $client Инстанс клиента
67
     * @param array $fields Поля для выборки
68
     *
69
     * Пример:
70
     * ```php
71
     *      $token = '7c0c2193d27108a509abd8ea84a8750c82b3a520'; // токен для тестового подписчика
72
     *
73
     *      $client = new Client($token); // инициализация клиента
74
     *
75
     *      $book = new Book($client, []); // инициализация модели книг
76
     * ```
77
     *
78
     * @throws Exception
79
     *
80
     * @see Article::__construct
81
     * @see Book::__construct
82
     * @see Issue::__construct
83
     * @see Journal::__construct
84
     * @see User::__construct
85
     */
86 10
    public function __construct(Client $client, array $fields)
87
    {
88 10
        if (!$client) {
89
            throw new Exception('Клиент не инициализирован');
90
        }
91
92 10
        if (!is_array($fields)) {
93
            throw new Exception('Fields for model of collection mast be array');
94
        }
95
96 10
        $this->client = $client;
97 10
        $this->fields = $fields;
98 10
    }
99
100
    /**
101
     * Загружаемые поля модели
102
     *
103
     * Те поля модели, которые будут получены по API
104
     *
105
     * @return array
106
     */
107
    public function getFields()
108
    {
109
        return $this->fields;
110
    }
111
112
    /**
113
     * Добавление новой записи по API
114
     *
115
     * @param array $data Устанавливаемые данные модели
116
     *
117
     * @return $this
118
     *
119
     * @throws Exception
120
     */
121 1
    public function post(array $data)
122
    {
123 1
        $response = $this->getClient()->getResponse($this->getUrl(__FUNCTION__), $data);
124
125 1
        $this->set($response['data'], $response['status']);
126
127 1
        return $this;
128
    }
129
130
    /**
131
     * Получение инстанса клиента
132
     *
133
     * @return Client
134
     */
135 5
    protected function getClient()
136
    {
137 5
        return $this->client;
138
    }
139
140
    /**
141
     * Установка данных модели
142
     *
143
     * @param  array $data Данные модели
144
     * @param  int $status Статус полученных данных
145
     *
146
     * @return $this
147
     *
148
     * @throws Exception
149
     */
150 10
    public function set(array $data, $status = null)
151
    {
152 10
        if (empty($data['id']) && empty($this->getId())) {
153 2
            throw new Exception(Model::MESSAGE_ID_REQUIRED);
154
        }
155
156 8
        if (!empty($data['id']) && !empty($this->getId()) && $data['id'] != $this->getId()) {
157
            throw new Exception(Model::MESSAGE_ID_CAN_NOT_CHANGED);
158
        }
159
160 8
        if (!empty($data['id'])) {
161 8
            $this->setId($data['id']);
162 8
        }
163
164 8
        $this->data = array_merge((array)$this->data, $data);
165
166 8
        if ($status) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $status of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
167 5
            $this->lastStatus = $status;
168 5
        }
169
170 8
        return $this;
171
    }
172
173
    /**
174
     * Получение идентификатора модели
175
     *
176
     * @return int
177
     */
178 10
    public function getId()
179
    {
180 10
        return $this->id;
181
    }
182
183
    /**
184
     * Установка идентификатора модели
185
     *
186
     * @param int $id Идентификатор модели
187
     *
188
     * @return int
189
     *
190
     * @throws Exception
191
     */
192 8
    public function setId($id)
193
    {
194 8
        return $this->id = $id;
0 ignored issues
show
Documentation Bug introduced by
It seems like $id of type integer is incompatible with the declared type null of property $id.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
195
    }
196
197
    /**
198
     * Обновление записи по API
199
     *
200
     * @param array $data Обновляемые данные
201
     *
202
     * @return $this
203
     *
204
     * @throws Exception
205
     */
206 1
    public function put(array $data)
207
    {
208 1
        $this->set($data);
209
210 1
        $response = $this->getClient()->getResponse($this->getUrl(__FUNCTION__, [$this->getId()]), $data);
211
212 1
        $this->set($response['data'], $response['status']);
213
214 1
        return $this;
215
    }
216
217
    /**
218
     * Удаление модели
219
     *
220
     * @param int $id Идентификатор модели
221
     *
222
     * @return $this
223
     *
224
     * @throws Exception
225
     */
226 1
    public function delete($id = null)
227
    {
228 1
        if (empty($this->getId())) {
229
            $this->set(['id' => $id]);
230
        }
231
232 1
        $response = $this->getClient()->getResponse($this->getUrl(__FUNCTION__, [$this->getId()]));
233
234 1
        $this->set($response['data'], $response['status']);
235
236 1
        return $this;
237
    }
238
239
    /**
240
     * Магический Get
241
     *
242
     * @param mixed $name Имя поля
243
     *
244
     * @return mixed
245
     *
246
     * @throws Exception
247
     */
248 4
    public function __get($name)
249
    {
250 4
        $data = $this->get();
251
252 4
        if (!array_key_exists($name, $data)) {
253
            throw new Exception('Поле ' . $name . ' не указано при создвнии объекта модели ' . get_class($this) . ' (см. 2-й аргумент)');
254
        }
255
256 4
        return $data[$name];
257
    }
258
259
    /**
260
     * Получение метаданных по идентификатору модели
261
     *
262
     * @param int $id Идентификатор модели
263
     *
264
     * @return array
265
     *
266
     * @throws Exception
267
     */
268 5
    public function get($id = null)
269
    {
270 5
        if ($id === null && $this->getId() !== null) {
271 4
            return $this->data;
272
        }
273
274 3
        if (!$id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $id of type integer|null is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
275 2
            throw new Exception(Model::MESSAGE_ID_REQUIRED);
276
        }
277
278 3
        $this->setId($id);
279
280 3
        $params = $this->fields ? ['fields' => implode(',', $this->fields)] : [];
281
282 3
        $response = $this->getClient()->getResponse($this->getUrl(__FUNCTION__, [$this->getId()]), $params);
283
284 2
        $this->set($response['data'], $response['status']);
285
286 2
        return $this->data;
287
    }
288
}