1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Trello; |
4
|
|
|
|
5
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
6
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcher; |
7
|
|
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
8
|
|
|
use Symfony\Component\HttpFoundation\Request; |
9
|
|
|
use Trello\Exception\InvalidArgumentException; |
10
|
|
|
|
11
|
|
|
class Service extends Manager |
12
|
|
|
{ |
13
|
|
|
/** |
14
|
|
|
* @var EventDispatcherInterface |
15
|
|
|
*/ |
16
|
|
|
protected $dispatcher; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Constructor. |
20
|
|
|
* |
21
|
|
|
* @param ClientInterface $client |
22
|
|
|
* @param EventDispatcherInterface|null $dispatcher |
23
|
|
|
*/ |
24
|
|
|
public function __construct(ClientInterface $client, EventDispatcherInterface $dispatcher = null) |
25
|
|
|
{ |
26
|
|
|
parent::__construct($client); |
27
|
|
|
|
28
|
|
|
$this->dispatcher = $dispatcher ? $dispatcher : new EventDispatcher(); |
29
|
|
|
} |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Get event dispatcher |
33
|
|
|
* |
34
|
|
|
* @return EventDispatcherInterface |
35
|
|
|
*/ |
36
|
|
|
public function getEventDispatcher() |
37
|
|
|
{ |
38
|
|
|
return $this->dispatcher; |
39
|
|
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Attach an event listener |
43
|
|
|
* |
44
|
|
|
* @param string $eventName @see Events for name constants |
45
|
|
|
* @param callable $listener The listener |
46
|
|
|
* @param int $priority The higher this value, the earlier an event |
47
|
|
|
* listener will be triggered in the chain (defaults to 0) |
48
|
|
|
*/ |
49
|
|
|
public function addListener($eventName, $listener, $priority = 0) |
50
|
|
|
{ |
51
|
|
|
$this->dispatcher->addListener($eventName, $listener, $priority); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Attach an event subscriber |
56
|
|
|
* |
57
|
|
|
* @param EventSubscriberInterface $subscriber The subscriber |
58
|
|
|
*/ |
59
|
|
|
public function addEventSubscriber(EventSubscriberInterface $subscriber) |
60
|
|
|
{ |
61
|
|
|
$this->dispatcher->addSubscriber($subscriber); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* Checks whether a given request is a Trello webhook |
66
|
|
|
* |
67
|
|
|
* @param Request $request |
68
|
|
|
* |
69
|
|
|
* @return bool |
70
|
|
|
*/ |
71
|
|
|
public function isTrelloWebhook(Request $request) |
72
|
|
|
{ |
73
|
|
|
if (!$request->getMethod() === 'POST') { |
74
|
|
|
return false; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
if (!$request->headers->has('X-Trello-Webhook')) { |
78
|
|
|
return false; |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
return true; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Checks whether a given request is a Trello webhook |
86
|
|
|
* and raises appropriate events @see Events |
87
|
|
|
* |
88
|
|
|
* @param Request|null $request |
89
|
|
|
*/ |
90
|
|
|
public function handleWebhook(Request $request = null) |
91
|
|
|
{ |
92
|
|
|
if (!$request) { |
93
|
|
|
$request = Request::createFromGlobals(); |
94
|
|
|
$data = json_decode($request->getContent(), true); |
95
|
|
|
$request->request->replace($data); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
if (!$this->isTrelloWebhook($request) || !$action = $request->get('action')) { |
99
|
|
|
return; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
if (!isset($action['type'])) { |
103
|
|
|
throw new InvalidArgumentException('Unable to determine event from request.'); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
if (!isset($action['data'])) { |
107
|
|
|
throw new InvalidArgumentException('Unable to retrieve data from request.'); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
$eventName = $action['type']; |
111
|
|
|
$data = $action['data']; |
112
|
|
|
|
113
|
|
|
switch ($eventName) { |
114
|
|
|
case Events::BOARD_CREATE: |
115
|
|
|
case Events::BOARD_UPDATE: |
116
|
|
|
case Events::BOARD_COPY: |
117
|
|
|
$event = new Event\BoardEvent(); |
118
|
|
|
$event->setBoard($this->getBoard($data['board']['id'])); |
119
|
|
|
break; |
120
|
|
|
case Events::BOARD_MOVE_CARD_FROM: |
121
|
|
|
case Events::BOARD_MOVE_CARD_TO: |
122
|
|
|
$event = new Event\CardMoveEvent(); |
123
|
|
|
$event->setCard($this->getCard($data['card']['id'])); |
124
|
|
|
break; |
125
|
|
|
case Events::BOARD_MOVE_LIST_FROM: |
126
|
|
|
case Events::BOARD_MOVE_LIST_TO: |
127
|
|
|
$event = new Event\ListMoveEvent(); |
128
|
|
|
$event->setList($this->getList($data['list']['id'])); |
129
|
|
|
break; |
130
|
|
|
case Events::BOARD_ADD_MEMBER: |
131
|
|
|
case Events::BOARD_MAKE_ADMIN: |
132
|
|
|
case Events::BOARD_MAKE_NORMAL_MEMBER: |
133
|
|
|
case Events::BOARD_MAKE_OBSERVER: |
134
|
|
|
case Events::BOARD_REMOVE_ADMIN: |
135
|
|
|
case Events::BOARD_DELETE_INVITATION: |
136
|
|
|
case Events::BOARD_UNCONFIRMED_INVITATION: |
137
|
|
|
$event = new Event\BoardMemberEvent(); |
138
|
|
|
$event->setBoard($this->getBoard($data['board']['id'])); |
139
|
|
|
$event->setMember($this->getMember($data['member']['id'])); |
140
|
|
|
break; |
141
|
|
|
case Events::BOARD_ADD_TO_ORGANIZATION: |
142
|
|
|
case Events::BOARD_REMOVE_FROM_ORGANIZATION: |
143
|
|
|
$event = new Event\BoardOrganizationEvent(); |
144
|
|
|
$event->setBoard($this->getBoard($data['board']['id'])); |
145
|
|
|
$event->setOrganization($this->getOrganization($data['organization']['id'])); |
146
|
|
|
break; |
147
|
|
|
case Events::LIST_CREATE: |
148
|
|
|
case Events::LIST_UPDATE: |
149
|
|
|
case Events::LIST_UPDATE_CLOSED: |
150
|
|
|
case Events::LIST_UPDATE_NAME: |
151
|
|
|
$event = new Event\ListEvent(); |
152
|
|
|
$event->setList($this->getList($data['list']['id'])); |
153
|
|
|
break; |
154
|
|
|
case Events::CARD_CREATE: |
155
|
|
|
case Events::CARD_UPDATE: |
156
|
|
|
case Events::CARD_UPDATE_LIST: |
157
|
|
|
case Events::CARD_UPDATE_NAME: |
158
|
|
|
case Events::CARD_UPDATE_DESC: |
159
|
|
|
case Events::CARD_UPDATE_CLOSED: |
160
|
|
|
case Events::CARD_DELETE: |
161
|
|
|
case Events::CARD_EMAIL: |
162
|
|
|
case Events::CARD_ADD_LABEL: |
163
|
|
|
case Events::CARD_REMOVE_LABEL: |
164
|
|
|
$event = new Event\CardEvent(); |
165
|
|
|
$event->setCard($this->getCard($data['card']['id'])); |
166
|
|
|
break; |
167
|
|
|
case Events::CARD_COPY: |
168
|
|
|
$event = new Event\CardCopyEvent(); |
169
|
|
|
$event->setCard($this->getCard($data['card']['id'])); |
170
|
|
|
break; |
171
|
|
|
case Events::CARD_ADD_MEMBER: |
172
|
|
|
case Events::CARD_REMOVE_MEMBER: |
173
|
|
|
$event = new Event\CardMemberEvent(); |
174
|
|
|
$event->setCard($this->getCard($data['card']['id'])); |
175
|
|
|
$event->setMember($this->getMember($data['member']['id'])); |
176
|
|
|
break; |
177
|
|
|
case Events::CARD_COMMENT: |
178
|
|
View Code Duplication |
case Events::CARD_COPY_COMMENT: |
|
|
|
|
179
|
|
|
$event = new Event\CardCommentEvent(); |
180
|
|
|
$event->setCard($this->getCard($data['card']['id'])); |
181
|
|
|
$event->setComment($data['text']); |
182
|
|
|
break; |
183
|
|
|
case Events::CARD_FROM_CHECKITEM: |
184
|
|
|
$event = new Event\CardFromCheckItemEvent(); |
185
|
|
|
$event->setCard($this->getCard($data['card']['id'])); |
186
|
|
|
break; |
187
|
|
|
case Events::CARD_ADD_ATTACHMENT: |
188
|
|
View Code Duplication |
case Events::CARD_DELETE_ATTACHMENT: |
|
|
|
|
189
|
|
|
$event = new Event\CardAttachmentEvent(); |
190
|
|
|
$event->setCard($this->getCard($data['card']['id'])); |
191
|
|
|
$event->setAttachment($data['attachment']); |
192
|
|
|
break; |
193
|
|
|
case Events::CARD_ADD_CHECKLIST: |
194
|
|
|
case Events::CARD_CREATE_CHECKLIST_ITEM: |
195
|
|
View Code Duplication |
case Events::CARD_UPDATE_CHECKLIST_ITEM_STATE: |
|
|
|
|
196
|
|
|
$event = new Event\CardChecklistEvent(); |
197
|
|
|
$event->setCard($this->getCard($data['card']['id'])); |
198
|
|
|
$event->setChecklist($this->getChecklist($data['checklist']['id'])); |
199
|
|
|
break; |
200
|
|
|
case Events::CARD_CREATE_CHECKLIST: |
201
|
|
|
case Events::CARD_UPDATE_CHECKLIST: |
202
|
|
View Code Duplication |
case Events::CARD_REMOVE_CHECKLIST: |
|
|
|
|
203
|
|
|
$event = new Event\CardChecklistEvent(); |
204
|
|
|
$event->setCard($this->getCard($data['cardTarget']['_id'])); |
205
|
|
|
$event->setChecklist($this->getChecklist($data['checklist']['id'])); |
206
|
|
|
break; |
207
|
|
|
case Events::ORGANIZATION_CREATE: |
208
|
|
|
case Events::ORGANIZATION_UPDATE: |
209
|
|
|
$event = new Event\OrganizationEvent(); |
210
|
|
|
$event->setOrganization($this->getOrganization($data['organization']['id'])); |
211
|
|
|
break; |
212
|
|
|
case Events::ORGANIZATION_ADD_MEMBER: |
213
|
|
|
case Events::ORGANIZATION_MAKE_NORMAL_MEMBER: |
214
|
|
|
case Events::ORGANIZATION_REMOVE_ADMIN: |
215
|
|
|
case Events::ORGANIZATION_DELETE_INVITATION: |
216
|
|
|
case Events::ORGANIZATION_UNCONFIRMED_INVITATION: |
217
|
|
|
$event = new Event\OrganizationMemberEvent(); |
218
|
|
|
$event->setOrganization($this->getOrganization($data['organization']['id'])); |
219
|
|
|
$event->setMember($this->getMember($data['member']['id'])); |
220
|
|
|
break; |
221
|
|
|
case Events::MEMBER_JOINED: |
222
|
|
|
case Events::MEMBER_UPDATE: |
223
|
|
|
$event = new Event\MemberEvent(); |
224
|
|
|
$event->setMember($this->getMember($data['member']['id'])); |
225
|
|
|
break; |
226
|
|
|
case Events::POWERUP_ENABLE: |
227
|
|
|
case Events::POWERUP_DISABLE: |
228
|
|
|
$event = new Event\PowerUpEvent(); |
229
|
|
|
$event->setPowerUp($data['powerUp']); |
230
|
|
|
break; |
231
|
|
|
default: |
232
|
|
|
throw new InvalidArgumentException(sprintf( |
233
|
|
|
'Unknown event "%s" occured with following data: "%s".', |
234
|
|
|
$eventName, |
235
|
|
|
serialize($data) |
236
|
|
|
)); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
$event->setRequestData($data); |
240
|
|
|
|
241
|
|
|
$this->dispatcher->dispatch($eventName, $event); |
242
|
|
|
} |
243
|
|
|
} |
244
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.