Completed
Push — master ( 80688c...179189 )
by dotzero
01:51
created

Listener::listen()   D

Complexity

Conditions 9
Paths 13

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 9.0076

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 32
ccs 21
cts 22
cp 0.9545
rs 4.909
cc 9
eloc 20
nc 13
nop 0
crap 9.0076
1
<?php
2
3
namespace AmoCRM\Webhooks;
4
5
use AmoCRM\Exception;
6
7
/**
8
 * Class Listener
9
 *
10
 * Назначения и вызов callback при уведомлениях.
11
 *
12
 * WebHooks – это уведомление сторонних приложений посредством отправки уведомлений о событиях,
13
 * произошедших в amoCRM. Вы можете настроить HTTP адреса ваших приложений и связанные с ними
14
 * рабочие правила в настройках своего аккаунта, в разделе «API».
15
 *
16
 * @package AmoCRM\Webhooks
17
 * @author dotzero <[email protected]>
18
 * @link http://www.dotzero.ru/
19
 * @link https://github.com/dotzero/amocrm-php
20
 *
21
 * For the full copyright and license information, please view the LICENSE
22
 * file that was distributed with this source code.
23
 */
24
class Listener
25
{
26
    /**
27
     * @var array Список callback функций
28
     */
29
    private $hooks = [];
30
31
    /**
32
     * @var array Список всех доступных событий
33
     */
34
    public $events_list = [
35
        'add_lead', // Добавить сделку
36
        'add_contact', // Добавить контакт
37
        'add_company', // Добавить компанию
38
        'add_customer', // Добавить покупателя
39
        'update_lead', // Изменить сделку
40
        'update_contact', // Изменить контакт
41
        'update_company', // Изменить компанию
42
        'update_customer', // Изменить покупателя
43
        'delete_lead', // Удалить сделку
44
        'delete_contact', // Удалить контакт
45
        'delete_company', // Удалить компанию
46
        'delete_customer', // Удалить покупателя
47
        'status_lead', // Смена статуса сделки
48
        'responsible_lead', // Смена отв-го сделки
49
        'restore_contact', // Восстановить контакт
50
        'restore_company', // Восстановить компанию
51
        'restore_lead', // Восстановить сделку
52
        'note_lead', // Примечание в сделке
53
        'note_contact', // Примечание в контакте
54
        'note_company', // Примечание в компании
55
        'note_customer', // Примечание в покупателе
56
    ];
57
58
    /**
59
     * Добавление события на уведомление в список событий
60
     *
61
     * @param string|array $events Код события или массив событий
62
     * @param callback $callback Callback-функция
63
     * @return $this
64
     * @throws Exception
65
     */
66 13
    public function on($events, $callback)
67
    {
68 13
        if (!is_array($events)) {
69 13
            $events = [$events];
70 13
        }
71
72 13
        if (!is_callable($callback, true)) {
73
            throw new Exception('Callback must be callable');
74
        }
75
76 13
        foreach ($events as $event) {
77 13
            if (!in_array($event, $this->events_list)) {
78
                throw new Exception('Invalid event name');
79
            }
80
81 13
            if (!isset($this->hooks[$event])) {
82 13
                $this->hooks[$event] = [];
83 13
            }
84
85 13
            $this->hooks[$event][] = $callback;
86 13
        }
87
88 13
        return $this;
89
    }
90
91
    /**
92
     * Вызов обработчика уведомлений
93
     *
94
     * @return bool
95
     */
96 13
    public function listen()
0 ignored issues
show
Coding Style introduced by
listen uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
97
    {
98 13
        if (!isset($_POST['account']['subdomain']) || empty($this->hooks)) {
99
            return false;
100
        }
101
102 13
        $post = $_POST;
103 13
        $domain = $post['account']['subdomain'];
104 13
        $id = isset($data['id']) ? $data['id'] : null;
0 ignored issues
show
Bug introduced by
The variable $data seems only to be defined at a later point. As such the call to isset() seems to always evaluate to false.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
105
106 13
        unset($post['account']);
107
108 13
        foreach ($post as $entityName => $entityData) {
109 13
            foreach ($entityData as $actionName => $actionData) {
110 13
                foreach ($actionData as $data) {
111 13
                    $type = $entityName;
112
                    switch ($entityName) {
113 13
                        case 'contacts':
114 8
                            $type = $data['type'];
115 8
                            break;
116 5
                        case 'leads':
117 5
                            $type = 'lead';
118 5
                            break;
119
                    }
120
121 13
                    $this->fireCallback($actionName . '_' . $type, $domain, $id, $data);
122 13
                }
123 13
            }
124 13
        }
125
126 13
        return true;
127
    }
128
129
    /**
130
     * Очистка списка событий
131
     *
132
     * @return $this
133
     */
134 13
    public function clean()
135
    {
136 13
        $this->hooks = [];
137
138 13
        return $this;
139
    }
140
141
    /**
142
     * Вызов Callback-функции на уведомление
143
     *
144
     * @param string $name Код события
145
     * @param string $domain Поддомен amoCRM
146
     * @param int $id Id объекта связаного с уведомленим
147
     * @param array $data Поля возвращаемые уведомлением
148
     */
149 13
    private function fireCallback($name, $domain, $id, $data)
150
    {
151 13
        $callbacks = isset($this->hooks[$name]) ? $this->hooks[$name] : [];
152
153 13
        foreach ($callbacks AS $callback) {
154 13
            call_user_func($callback, $domain, $id, $data);
155 13
        }
156 13
    }
157
}
158