Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
message.php
1<?php
3
14
15Loc::loadMessages(__FILE__);
16
18{
19 public const EVENT_MESSAGE_UPDATED = 'messageUpdated';
20
21 protected $id;
22
24 protected $sender;
25
27 protected $type;
29 protected $authorId = 0;
31 protected $from;
33 protected $to;
35 protected $headers = array();
37 protected $body;
38
39 protected $statusId;
40 protected $externalStatus;
41
42 protected ?Error $error = null;
43
44 protected bool $checkRestrictions = false;
45
50 public function __construct(Sender\Base $sender = null)
51 {
52 if ($sender)
53 {
54 $this->setSender($sender);
55 }
56 }
57
58 public static function loadById(int $id): ?Message
59 {
60 $fields = MessageTable::getRowById($id);
61 if (!$fields)
62 {
63 return null;
64 }
65 $instance = new static();
66 $instance->setFields($fields);
67
68 return $instance;
69 }
70
71 public static function loadByExternalId(string $senderId, string $externalId, ?string $from = null): ?Message
72 {
73 $fields = MessageTable::getByExternalId($senderId, $externalId, $from)->fetch();
74 if (!$fields)
75 {
76 return null;
77 }
78 $instance = new static();
79 $instance->setFields($fields);
80
81 return $instance;
82 }
83
89 public static function createFromFields(array $fields, Sender\Base $sender = null): Message
90 {
91 $message = new static($sender);
92 $message->setFields($fields);
93
94 return $message;
95 }
96
97 public static function getFieldsById($messageId)
98 {
99 $iterator = Internal\Entity\MessageTable::getById($messageId);
100 return $iterator->fetch();
101 }
102
108 public function setType(string $type): Message
109 {
111 {
112 throw new ArgumentTypeException('Unsupported message type');
113 }
114
115 $this->type = $type;
116 return $this;
117 }
118
122 public function getType(): string
123 {
124 return $this->type;
125 }
126
127 public function checkFields(): Main\Result
128 {
129 $result = new Main\Result();
130
131 $sender = $this->getSender();
132 $from = $this->getFrom();
133
134 if (!$sender)
135 {
136 $result->addError(new Error(Loc::getMessage('MESSAGESERVICE_MESSAGE_ERROR_SENDER')));
137 }
138 elseif (!$sender->canUse())
139 {
140 $result->addError(new Error(Loc::getMessage('MESSAGESERVICE_MESSAGE_ERROR_SENDER_CAN_USE')));
141 }
142 elseif ($sender->getType() !== $this->getType())
143 {
144 $result->addError(new Error(Loc::getMessage('MESSAGESERVICE_MESSAGE_ERROR_TYPE')));
145 }
146 elseif (!$from || !$sender->isCorrectFrom($from))
147 {
148 $result->addError(new Error(Loc::getMessage('MESSAGESERVICE_MESSAGE_ERROR_FROM')));
149 }
150
151 return $result;
152 }
153
157 public function send(): Main\Result
158 {
159 global $USER;
160
161 $checkResult = $this->checkFields();
162
163 if (!$checkResult->isSuccess())
164 {
165 $result = new AddResult();
166 $result->addErrors($checkResult->getErrors());
167 return $result;
168 }
169
170 if ($this->checkRestrictions)
171 {
172 $restrictionManager = new RestrictionManager($this);
173 if (!$restrictionManager->isCanSendMessage())
174 {
175 return (new Main\Result())->addError(
176 new Error(Loc::getMessage('MESSAGESERVICE_MESSAGE_ERROR_RESTRICTION'))
177 );
178 }
179 }
180
181 $sender = $this->getSender();
182 $headers = $this->getHeaders();
183
184 $result = Internal\Entity\MessageTable::add([
185 'TYPE' => $this->getType(),
186 'SENDER_ID' => $sender->getId(),
187 'AUTHOR_ID' => $this->getAuthorId(),
188 'MESSAGE_FROM' => $this->getFrom(),
189 'MESSAGE_TO' => $this->getTo(),
190 'MESSAGE_HEADERS' => count($headers) > 0 ? $headers : null,
191 'MESSAGE_BODY' => $this->getBody(),
192 'CLUSTER_GROUP' => defined('BX_CLUSTER_GROUP') ? BX_CLUSTER_GROUP : null
193 ]);
194 if ($result->isSuccess())
195 {
196 $this->id = $result->getId();
197 if (Main\Config\Option::get('messageservice', 'event_log_message_send', 'N') === 'Y')
198 {
199 $userId = $USER instanceof \CUser ? $USER->getId() : 0;
200 \CEventLog::Log('INFO', 'MESSAGE_SEND', 'messageservice', $userId, $this->getTo());
201 }
202 }
203
204 return $result;
205 }
206
207 public function sendDirectly(): Result\SendMessage
208 {
209 global $USER;
210
211 $checkResult = $this->checkFields();
212
213 if (!$checkResult->isSuccess())
214 {
215 $result = new Result\SendMessage();
216 return $result->addErrors($checkResult->getErrors());
217 }
218
219 if ($this->checkRestrictions)
220 {
221 $restrictionManager = new RestrictionManager($this);
222 if (!$restrictionManager->isCanSendMessage())
223 {
224 return (new Result\SendMessage)->addError(
225 new Error(Loc::getMessage('MESSAGESERVICE_MESSAGE_ERROR_RESTRICTION'))
226 );
227 }
228 }
229
230 $sender = $this->getSender();
231
232 if (!Sender\Limitation::checkDailyLimit($sender->getId(), $this->getFrom()))
233 {
234 $result = new Result\SendMessage();
235 $result->addError(new Error(Loc::getMessage('MESSAGESERVICE_MESSAGE_ERROR_LIMITATION')));
236 $result->setStatus(MessageStatus::DEFERRED);
237
238 return $result;
239 }
240
241 $headers = $this->getHeaders();
242 $messageFields = [
243 'TYPE' => $this->getType(),
244 'SENDER_ID' => $sender->getId(),
245 'AUTHOR_ID' => $this->getAuthorId(),
246 'MESSAGE_FROM' => $this->getFrom(),
247 'MESSAGE_TO' => $this->getTo(),
248 'MESSAGE_HEADERS' => count($headers) > 0 ? $headers : null,
249 'MESSAGE_BODY' => $this->getBody(),
250 'CLUSTER_GROUP' => defined('BX_CLUSTER_GROUP') ? BX_CLUSTER_GROUP : null
251 ];
252
253 $sender->setSocketTimeout(5);
254 $sender->setStreamTimeout(15);
255
256 $result = $sender->sendMessage($messageFields);
257
258 $messageFields['DATE_EXEC'] = new DateTime();
259 $messageFields['SUCCESS_EXEC'] = $result->isSuccess() ? 'Y' : 'N';
260
261 if ($result->getExternalId() !== null)
262 {
263 $messageFields['EXTERNAL_ID'] = $result->getExternalId();
264 }
265 if ($result->getStatus() !== null)
266 {
267 $messageFields['STATUS_ID'] = $result->getStatus();
268 }
269
270 $addResult = Internal\Entity\MessageTable::add($messageFields);
271 if (!$addResult->isSuccess())
272 {
273 $result->addErrors($addResult->getErrors());
274 $result->setStatus(MessageStatus::ERROR);
275
276 return $result;
277 }
278
279 $this->id = $addResult->getId();
280 $result->setId($this->id);
281
282 if (Main\Config\Option::get('messageservice', 'event_log_message_send', 'N') === 'Y')
283 {
284 $userId = $USER instanceof \CUser ? $USER->getId() : 0;
285 \CEventLog::Log('INFO', 'MESSAGE_SEND', 'messageservice', $userId, $this->getTo());
286 }
287
288 return $result;
289 }
290
294 public function getFrom()
295 {
296 return $this->from;
297 }
298
303 public function setFrom($from): Message
304 {
305 $this->from = (string)$from;
306 return $this;
307 }
308
312 public function getBody()
313 {
314 return $this->body;
315 }
316
321 public function setBody($body): Message
322 {
323 $this->body = (string)$body;
324 return $this;
325 }
326
330 public function getTo()
331 {
332 return $this->to;
333 }
334
339 public function setTo($to): Message
340 {
341 $this->to = (string)$to;
342 return $this;
343 }
344
348 public function getSender(): ?Sender\Base
349 {
350 return $this->sender;
351 }
352
357 public function setSender(Sender\Base $sender)
358 {
359 $this->sender = $sender;
360 return $this;
361 }
362
367 public function setHeaders(array $headers): Message
368 {
369 $this->headers = $headers;
370 return $this;
371 }
372
376 public function getHeaders()
377 {
378 return $this->headers;
379 }
380
385 public function setAuthorId(int $authorId): Message
386 {
387 $this->authorId = $authorId;
388 return $this;
389 }
390
394 public function getAuthorId()
395 {
396 return $this->authorId;
397 }
398
402 public function getError(): ?Error
403 {
404 return $this->error;
405 }
406
411 public function setError(Error $error): self
412 {
413 $this->error = $error;
414
415 return $this;
416 }
417
418 public function getStatusId()
419 {
420 return $this->statusId;
421 }
422
423 public function update(array $fields): bool
424 {
425 $updateResult = MessageTable::update($this->id, $fields);
426 if (!$updateResult->isSuccess())
427 {
428 return false;
429 }
430
431 $this->setFields($fields);
432
433 // events
434 $eventFields = array_merge(['ID' => $this->id], $fields);
435 Main\EventManager::getInstance()->send(new Main\Event(
436 'messageservice',
437 static::EVENT_MESSAGE_UPDATED,
438 $eventFields)
439 );
440 Pull::onMessagesUpdate([$eventFields]);
441
442 return true;
443 }
444
445 public function updateWithSendResult(Result\SendMessage $result, DateTime $nextExec): void
446 {
447 $toUpdate = ['SUCCESS_EXEC' => 'E', 'DATE_EXEC' => new DateTime()];
448 if ($result->isSuccess())
449 {
450 $toUpdate['SUCCESS_EXEC'] = 'Y';
451 if ($result->getExternalId() !== null)
452 {
453 $toUpdate['EXTERNAL_ID'] = $result->getExternalId();
454 }
455 if ($result->getStatus() !== null)
456 {
457 $toUpdate['STATUS_ID'] = $result->getStatus();
458 }
459 }
460 elseif ($result->getStatus() === MessageStatus::DEFERRED)
461 {
462 $toUpdate = array(
463 'SUCCESS_EXEC' => 'N',
464 'NEXT_EXEC' => $nextExec,
465 'STATUS_ID' => MessageStatus::DEFERRED
466 );
467 }
468 else
469 {
470 $toUpdate['STATUS_ID'] = MessageStatus::ERROR;
471 }
472
473 $errors = $result->getErrorMessages();
474 if ($errors)
475 {
476 $toUpdate['EXEC_ERROR'] = implode(PHP_EOL, $errors);
477 }
478
479 $this->update($toUpdate);
480 }
481
482 public function updateStatusByExternalStatus(string $externalStatus): bool
483 {
484
485 $newInternalStatus = $this->sender::resolveStatus($externalStatus);
486
487 $isUpdateSuccess = MessageTable::updateMessageStatuses(
488 $this->id,
489 $newInternalStatus,
491 );
492
493 if (!$isUpdateSuccess)
494 {
495 return false;
496 }
497
498 $this->statusId = $newInternalStatus;
499
500 // events
501 $eventFields = ['ID' => $this->id, 'STATUS_ID' => $this->statusId];
502 Main\EventManager::getInstance()->send(new Main\Event(
503 'messageservice',
504 static::EVENT_MESSAGE_UPDATED,
505 $eventFields)
506 );
507 Pull::onMessagesUpdate([$eventFields]);
508
509 return true;
510 }
511
512 public function updateStatus(int $newStatusId): bool
513 {
514 $updateResult = MessageTable::updateStatusId($this->id, $newStatusId);
515 if (!$updateResult)
516 {
517 return false;
518 }
519
520 $this->statusId = $newStatusId;
521
522 // events
523 $eventFields = ['ID' => $this->id, 'STATUS_ID' => $this->statusId];
524 Main\EventManager::getInstance()->send(new Main\Event(
525 'messageservice',
526 static::EVENT_MESSAGE_UPDATED,
527 $eventFields)
528 );
529 Pull::onMessagesUpdate([$eventFields]);
530
531 return true;
532 }
533
534 private function setFields(array $fields): void
535 {
536 if (!$this->sender && isset($fields['SENDER_ID']))
537 {
538 $sender = Sender\SmsManager::getSenderById($fields['SENDER_ID']);
539 if ($sender)
540 {
541 $this->setSender($sender);
542 }
543 }
544 if (isset($fields['ID']))
545 {
546 $this->id = (int)$fields['ID'];
547 }
548 if (isset($fields['TYPE']))
549 {
550 $this->setType($fields['TYPE']);
551 }
552 if (isset($fields['AUTHOR_ID']))
553 {
554 $this->setAuthorId((int)$fields['AUTHOR_ID']);
555 }
556 if (isset($fields['MESSAGE_FROM']))
557 {
558 $this->setFrom($fields['MESSAGE_FROM']);
559 }
560 if (isset($fields['MESSAGE_TO']))
561 {
562 $this->setTo($fields['MESSAGE_TO']);
563 }
564 if (
565 isset($fields['MESSAGE_TEMPLATE'])
566 && $this->sender->isConfigurable()
567 && $this->sender->isTemplatesBased()
568 )
569 {
570 $fields['MESSAGE_HEADERS'] = is_array($fields['MESSAGE_HEADERS']) ? $fields['MESSAGE_HEADERS'] : [];
571 $fields['MESSAGE_HEADERS']['template'] = $this->sender->prepareTemplate($fields['MESSAGE_TEMPLATE']);
572 }
573 if (isset($fields['MESSAGE_HEADERS']) && is_array($fields['MESSAGE_HEADERS']))
574 {
575 $this->setHeaders($fields['MESSAGE_HEADERS']);
576 }
577 if (isset($fields['MESSAGE_BODY']))
578 {
579 $messageBody = $this->sender
580 ? $this->sender->prepareMessageBodyForSave($fields['MESSAGE_BODY'])
581 : $fields['MESSAGE_BODY']
582 ;
583 $this->setBody($messageBody);
584 }
585 if (isset($fields['STATUS_ID']))
586 {
587 $this->statusId = $fields['STATUS_ID'];
588 }
589 if (isset($fields['EXTERNAL_STATUS']))
590 {
591 $this->externalStatus = $fields['EXTERNAL_STATUS'];
592 }
593 }
594
598 public function setCheckRestrictions(bool $checkRestrictions): void
599 {
600 $this->checkRestrictions = $checkRestrictions;
601 }
602}
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static onMessagesUpdate(array $messages)
Definition pull.php:24
setCheckRestrictions(bool $checkRestrictions)
Definition message.php:598
updateWithSendResult(Result\SendMessage $result, DateTime $nextExec)
Definition message.php:445
__construct(Sender\Base $sender=null)
Definition message.php:50
updateStatus(int $newStatusId)
Definition message.php:512
static loadById(int $id)
Definition message.php:58
static createFromFields(array $fields, Sender\Base $sender=null)
Definition message.php:89
setSender(Sender\Base $sender)
Definition message.php:357
static getFieldsById($messageId)
Definition message.php:97
updateStatusByExternalStatus(string $externalStatus)
Definition message.php:482
setHeaders(array $headers)
Definition message.php:367
static loadByExternalId(string $senderId, string $externalId, ?string $from=null)
Definition message.php:71