Passed
Push — v5 ( e348bf...8a8f01 )
by Alexey
06:35
created

CalculatePriceDeliveryCdek   D

Complexity

Total Complexity 58

Size/Duplication

Total Lines 317
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 317
rs 4.8387
c 0
b 0
f 0
wmc 58

17 Methods

Rating   Name   Duplication   Size   Complexity  
A setDateExecute() 0 2 1
A getGoodslist() 0 5 2
A _getSecureAuthPassword() 0 2 1
A addGoodsItemByVolume() 0 11 3
A _getTariffList() 0 5 2
A getResult() 0 2 1
A addTariffPriority() 0 8 3
A setAuth() 0 3 1
A __construct() 0 2 1
A _getRemoteData() 0 16 1
A setTariffId() 0 6 2
A getError() 0 2 1
A setSenderCityId() 0 6 2
A setReceiverCityId() 0 6 2
F calculate() 0 57 29
A addGoodsItemBySize() 0 20 4
A setModeDeliveryId() 0 6 2

How to fix   Complexity   

Complex Class

Complex classes like CalculatePriceDeliveryCdek often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CalculatePriceDeliveryCdek, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Расчёт стоимости доставки СДЭК
4
 * Модуль для интернет-магазинов (ИМ)
5
 *
6
 * @version 1.0
7
 * @since 21.06.2012
8
 * @link http://www.edostavka.ru/integrator/
9
 * @see 3197
10
 * @author Tatyana Shurmeleva
11
 */
12
13
namespace Ecommerce\Vendor;
14
class CalculatePriceDeliveryCdek {
15
16
    //версия модуля
17
    private $version = "1.0";
18
    //url для получения данных по отправке
19
    private $jsonUrl = 'http://api.cdek.ru/calculator/calculate_price_by_json.php';
20
21
    //авторизация ИМ
22
    private $authLogin;
23
    private $authPassword;
24
25
    //id города-отправителя
26
    private $senderCityId;
27
    //id города-получателя
28
    private $receiverCityId;
29
    //id тарифа
30
    private $tariffId;
31
    //id способа доставки (склад-склад, склад-дверь)
32
    private $modeId;
33
    //массив мест отправления
34
    public $goodsList;
35
    //массив id тарифов
36
    public $tariffList;
37
    //результат расчёта стоимости отправления ИМ
38
    private $result;
39
    //результат в случае ошибочного расчёта
40
    private $error;
41
    //планируемая дата заказа
42
    public $dateExecute;
43
44
    /**
45
     * конструктор
46
     */
47
    public function __construct() {
48
        $this->dateExecute = date('Y-m-d');
49
    }
50
51
    /**
52
     * Установка планируемой даты отправки
53
     *
54
     * @param string $date дата планируемой отправки, например '2012-06-25'
55
     */
56
    public function setDateExecute($date) {
57
        $this->dateExecute = date($date);
58
    }
59
60
    /**
61
     * Авторизация ИМ
62
     *
63
     * @param string $authLogin логин
64
     * @param string $authPassword пароль
65
     */
66
    public function setAuth($authLogin, $authPassword) {
67
        $this->authLogin = $authLogin;
68
        $this->authPassword = $authPassword;
69
    }
70
71
    /**
72
     * Защифрованный пароль для передачи на сервер
73
     *
74
     * @return string
75
     */
76
    private function _getSecureAuthPassword() {
77
        return md5($this->dateExecute . '&' . $this->authPassword);
78
    }
79
80
    /**
81
     * Город-отправитель
82
     *
83
     * @param int $id города
84
     */
85
    public function setSenderCityId($id) {
86
        $id = (int) $id;
87
        if ($id == 0) {
88
            throw new \Exception("Неправильно задан город-отправитель.");
89
        }
90
        $this->senderCityId = $id;
91
    }
92
93
    /**
94
     * Город-получатель
95
     *
96
     * @param int $id города
97
     */
98
    public function setReceiverCityId($id) {
99
        $id = (int) $id;
100
        if ($id == 0) {
101
            throw new \Exception("Неправильно задан город-получатель.");
102
        }
103
        $this->receiverCityId = $id;
104
    }
105
106
    /**
107
     * Устанавливаем тариф
108
     *
109
     * @param int $id тарифа
110
     */
111
    public function setTariffId($id) {
112
        $id = (int) $id;
113
        if ($id == 0) {
114
            throw new \Exception("Неправильно задан тариф.");
115
        }
116
        $this->tariffId = $id;
117
    }
118
119
    /**
120
     * Устанавливаем режим доставки (дверь-дверь=1, дверь-склад=2, склад-дверь=3, склад-склад=4)
121
     *
122
     * @param int $id режим доставки
123
     */
124
    public function setModeDeliveryId($id) {
125
        $id = (int) $id;
126
        if (!in_array($id, array(1, 2, 3, 4))) {
127
            throw new \Exception("Неправильно задан режим доставки.");
128
        }
129
        $this->modeId = $id;
130
    }
131
132
    /**
133
     * Добавление места в отправлении
134
     *
135
     * @param int $weight вес, килограммы
136
     * @param int $length длина, сантиметры
137
     * @param int $width ширина, сантиметры
138
     * @param int $height высота, сантиметры
139
     */
140
    public function addGoodsItemBySize($weight, $length, $width, $height) {
141
        //проверка веса
142
        $weight = (float) $weight;
143
        if ($weight == 0.00) {
144
            throw new \Exception("Неправильно задан вес места № " . (count($this->getGoodslist()) + 1) . ".");
145
        }
146
        //проверка остальных величин
147
        $paramsItem = array("длина" => $length,
148
            "ширина" => $width,
149
            "высота" => $height);
150
        foreach ($paramsItem as $k => $param) {
151
            $param = (int) $param;
152
            if ($param == 0) {
153
                throw new \Exception("Неправильно задан параметр '" . $k . "' места № " . (count($this->getGoodslist()) + 1) . ".");
154
            }
155
        }
156
        $this->goodsList[] = array('weight' => $weight,
157
            'length' => $length,
158
            'width' => $width,
159
            'height' => $height);
160
    }
161
162
    /**
163
     * Добавление места в отправлении по объёму (куб.метры)
164
     *
165
     * @param int $weight вес, килограммы
166
     * @param int $volume объёмный вес, метры кубические (А * В * С)
167
     */
168
    public function addGoodsItemByVolume($weight, $volume) {
169
        $paramsItem = array("вес" => $weight,
170
            "объёмный вес" => $volume);
171
        foreach ($paramsItem as $k => $param) {
172
            $param = (float) $param;
173
            if ($param == 0.00) {
174
                throw new \ption("Неправильно задан параметр '" . $k . "' места № " . (count($this->getGoodslist()) + 1) . ".");
0 ignored issues
show
Bug introduced by
The type ption was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
175
            }
176
        }
177
        $this->goodsList[] = array('weight' => $weight,
178
            'volume' => $volume);
179
    }
180
181
    /**
182
     * Получение массива мест отправления
183
     *
184
     * @return array
185
     */
186
    public function getGoodslist() {
187
        if (!isset($this->goodsList)) {
188
            return NULL;
189
        }
190
        return $this->goodsList;
191
    }
192
193
    /**
194
     * добавление тарифа в список тарифов с приоритетами
195
     *
196
     * @param int $id тариф
197
     * @param int $priority default false приоритет
198
     */
199
    public function addTariffPriority($id, $priority = 0) {
200
        $id = (int) $id;
201
        if ($id == 0) {
202
            throw new \Exception("Неправильно задан id тарифа.");
203
        }
204
        $priority = ($priority > 0) ? $priority : count($this->tariffList) + 1;
205
        $this->tariffList[] = array('priority' => $priority,
206
            'id' => $id);
207
    }
208
209
    /**
210
     * Получение массива заданных тарифов
211
     *
212
     * @return array
213
     */
214
    private function _getTariffList() {
0 ignored issues
show
Unused Code introduced by
The method _getTariffList() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
215
        if (!isset($this->tariffList)) {
216
            return NULL;
217
        }
218
        return $this->tariffList;
219
    }
220
221
    /**
222
     * Выполнение POST-запроса на сервер для получения данных
223
     * по запрашиваемым параметрам.
224
     *
225
     *
226
     */
227
    private function _getRemoteData($data) {
228
        $data_string = json_encode($data);
229
230
        $ch = curl_init();
231
        curl_setopt($ch, CURLOPT_URL, $this->jsonUrl);
232
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
233
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
234
                'Content-Type: application/json')
235
        );
236
        curl_setopt($ch, CURLOPT_POST, 1);
237
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
238
239
        $result = curl_exec($ch);
240
        curl_close($ch);
241
242
        return json_decode($result, true);
243
    }
244
245
    /**
246
     * Расчет стоимости доставки
247
     *
248
     * @return bool
249
     */
250
    public function calculate() {
251
        //формируем массив для отправки curl-post-запроса
252
        //передаём только явно заданные параметры, установленные ИМ
253
        //всю проверку и обработку будем делать на стороне сервера
254
        $data = array();
255
        //получение всех свойств текущего объекта не работает, т.к. у нас свойства private
256
        //поэтому определим массив $data явно
257
        //проверяем на установленную переменную и не-NULL-значение
258
259
        //версия модуля
260
        isset($this->version) ? $data['version'] = $this->version : '';
261
        //дата планируемой доставки, если не установлено, берётся сегодняшний день
262
        $data['dateExecute'] = $this->dateExecute;
263
        //авторизация: логин
264
        isset($this->authLogin) ? $data['authLogin'] = $this->authLogin : '';
265
        //авторизация: пароль
266
        isset($this->authPassword) ? $data['secure'] = $this->_getSecureAuthPassword() : '';
267
        //город-отправитель
268
        isset($this->senderCityId) ? $data['senderCityId'] = $this->senderCityId : '';
269
        //город-получатель
270
        isset($this->receiverCityId) ? $data['receiverCityId'] = $this->receiverCityId : '';
271
        //выбранный тариф
272
        isset($this->tariffId) ? $data['tariffId'] = $this->tariffId : '';
273
        //список тарифов с приоритетами
274
        (isset($this->tariffList)) ? $data['tariffList'] = $this->tariffList : '';
275
        //режим доставки
276
        isset($this->modeId) ? $data['modeId'] = $this->modeId : '';
277
278
        //список мест
279
        if (isset($this->goodsList)) {
280
            foreach ($this->goodsList as $idGoods => $goods) {
281
                $data['goods'][$idGoods] = array();
282
                //вес
283
                (isset($goods['weight']) && $goods['weight'] <> '' && $goods['weight'] > 0.00) ? $data['goods'][$idGoods]['weight'] = $goods['weight'] : '';
284
                //длина
285
                (isset($goods['length']) && $goods['length'] <> '' && $goods['length'] > 0) ? $data['goods'][$idGoods]['length'] = $goods['length'] : '';
286
                //ширина
287
                (isset($goods['width']) && $goods['width'] <> '' && $goods['width'] > 0) ? $data['goods'][$idGoods]['width'] = $goods['width'] : '';
288
                //высота
289
                (isset($goods['height']) && $goods['height'] <> '' && $goods['height'] > 0) ? $data['goods'][$idGoods]['height'] = $goods['height'] : '';
290
                //объемный вес (куб.м)
291
                (isset($goods['volume']) && $goods['volume'] <> '' && $goods['volume'] > 0.00) ? $data['goods'][$idGoods]['volume'] = $goods['volume'] : '';
292
293
            }
294
        }
295
        //проверка на подключние библиотеки curl
296
        if (!extension_loaded('curl')) {
297
            throw new \Exception("Не подключена библиотека CURL");
298
        }
299
        $response = $this->_getRemoteData($data);
300
301
        if (isset($response['result']) && !empty($response['result'])) {
302
            $this->result = $response;
303
            return true;
304
        } else {
305
            $this->error = $response;
306
            return false;
307
        }
308
309
        //return (isset($response['result']) && (!empty($response['result']))) ? true : false;
0 ignored issues
show
Unused Code Comprehensibility introduced by
79% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
310
        //результат
311
        //$result = ($this->getResponse());
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
312
        //return $result;
313
    }
314
315
    /**
316
     * Получить результаты подсчета
317
     *
318
     * @return array
319
     */
320
    public function getResult() {
321
        return $this->result;
322
    }
323
324
    /**
325
     * получить код и текст ошибки
326
     *
327
     * @return object
328
     */
329
    public function getError() {
330
        return $this->error;
331
    }
332
333
}
334
335
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...