Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
tracking.php
1<?php
9namespace Bitrix\Main\Mail;
10
11use Bitrix\Main;
18
24{
25 const SIGN_SALT_ACTION = 'event_mail_tracking';
26
27 const onRead = 'OnMailEventMailRead';
28 const onClick = 'OnMailEventMailClick';
29 const onUnsubscribe = 'OnMailEventSubscriptionDisable';
30 const onChangeStatus = 'OnMailEventMailChangeStatus';
31 const CUSTOM_SIGNER_KEY = 'signer_sender_mail_key';
32
40 public static function getTag($moduleId, $fields)
41 {
42
43 $moduleId = str_replace(".", "--", $moduleId);
44 return $moduleId . "." . base64_encode(json_encode($fields));
45 }
46
53 public static function parseTag($tag)
54 {
55 $data = explode(".", $tag);
56 $moduleId = str_replace("--", ".", $data[0]);
57 unset($data[0]);
58
59 return array('MODULE_ID' => $moduleId, 'FIELDS' => (array) json_decode(base64_decode(implode('.', $data))));
60 }
61
70 public static function getSignedTag($moduleId, $fields)
71 {
72 $tag = static::getTag($moduleId, $fields);
73 $signer = new Signer;
74 return $signer->sign($tag, static::SIGN_SALT_ACTION);
75 }
76
85 public static function parseSignedTag($signedTag)
86 {
87 try
88 {
89 $signer = new Signer;
90 $unsignedTag = $signer->unsign($signedTag, static::SIGN_SALT_ACTION);
91 return static::parseTag($unsignedTag);
92 }
93 catch (BadSignatureException $e)
94 {
95 }
96
97 $signer->setKey(self::getSignKey());
98 $unsignedTag = $signer->unsign($signedTag, static::SIGN_SALT_ACTION);
99 return static::parseTag($unsignedTag);
100 }
101
111 public static function getLinkRead($moduleId, $fields, $urlPage = null)
112 {
113 return static::getTaggedLink(
114 static::getTag($moduleId, $fields),
115 'read',
116 $urlPage
117 );
118 }
119
129 public static function getLinkClick($moduleId, $fields, $urlPage = null)
130 {
131 return static::getTaggedLink(
132 static::getTag($moduleId, $fields),
133 'click',
134 $urlPage
135 );
136 }
137
148 public static function getLinkUnsub($moduleId, $fields, $urlPage = null)
149 {
150 return static::getTaggedLink(
151 static::getSignedTag($moduleId, $fields),
152 'unsub',
153 $urlPage
154 );
155 }
156
164 protected static function getTaggedLink($tag, $opCode, $uri = null)
165 {
166 if(!$uri)
167 {
168 $uri = Application::getInstance()->getPersonalRoot();
169 $uri .= "/tools/track_mail_$opCode.php";
170 }
171
172 $uri = $uri . (strpos($uri, "?") === false ? "?" : "&");
173 $uri .= 'tag=' . urlencode($tag);
174
175 return $uri;
176 }
177
185 public static function getSign($value)
186 {
187 static $cached = array();
188 foreach ($cached as $cache)
189 {
190 if ($cache[0] == $value)
191 {
192 return $cache[1];
193 }
194 }
195
196 $signer = new Signer;
197 $sign = $signer->getSignature($value, static::SIGN_SALT_ACTION);
198
199 $cached[] = array($value, $sign);
200 if (count($cached) > 10)
201 {
202 array_shift($cached);
203 }
204
205 return $sign;
206 }
207
215 public static function validateSign($value, $signature)
216 {
217 try
218 {
219 $signer = new Signer;
220 $result = $signer->validate($value, $signature, static::SIGN_SALT_ACTION);
221 }
222 catch (BadSignatureException $exception)
223 {
224 $result = false;
225 }
226
227 if(!$result)
228 {
229 return self::validateSignWithStoredKey($value, $signature);
230 }
231
232 return $result;
233 }
234
235 private static function validateSignWithStoredKey($value, $signature)
236 {
237 try
238 {
239 $signer = new Signer;
240 $key = self::getSignKey();
241
242 if (is_string($key))
243 {
244 $signer->setKey($key);
245 }
246
247 return $signer->validate($value, $signature, static::SIGN_SALT_ACTION);
248 }
249 catch (BadSignatureException $exception)
250 {
251 return false;
252 }
253 }
254
255 private static function getSignKey()
256 {
257 $key = Config\Option::get('sender', self::CUSTOM_SIGNER_KEY, null);
258 if (!$key)
259 {
260 $key = Config\Option::get('main', 'signer_default_key', null);
261 if (is_string($key))
262 {
263 Config\Option::set('sender', self::CUSTOM_SIGNER_KEY, $key);
264 }
265 }
266
267 return $key;
268 }
269
276 public static function getSubscriptionList($data)
277 {
278 $subscription = array();
279
280 if(array_key_exists('MODULE_ID', $data))
281 $filter = array($data['MODULE_ID']);
282 else
283 $filter = null;
284
285 if(!is_array($data['FIELDS'])) return false;
286
287 $event = new Main\Event("main", "OnMailEventSubscriptionList", array($data['FIELDS']), $filter);
288 $event->send();
289 foreach ($event->getResults() as $eventResult)
290 {
291 if ($eventResult->getType() == EventResult::ERROR)
292 {
293 return false;
294 }
295
296 $subscriptionList = $eventResult->getParameters();
297 if($subscriptionList && is_array($subscriptionList['LIST']))
298 {
299 $subscription = array_merge(
300 $subscription,
301 array($eventResult->getModuleId() => $subscriptionList['LIST'])
302 );
303 }
304 }
305
306 if (empty($data['MODULE_ID']) || $data['MODULE_ID'] === 'main')
307 {
308 if (empty($subscription['main']))
309 {
310 $subscription['main'] = [];
311 }
312 $subscription['main'] = array_merge(
313 $subscription['main'],
315 );
316 }
317
318 if(array_key_exists('MODULE_ID', $data))
319 $subscription = $subscription[$data['MODULE_ID']];
320
321 return $subscription;
322 }
323
330 public static function subscribe($data)
331 {
332 if(!is_array($data['FIELDS'])) return false;
333
334 $event = new Main\Event("main", "OnMailEventSubscriptionEnable", array($data['FIELDS']), array($data['MODULE_ID']));
335 $event->send();
336 foreach ($event->getResults() as $eventResult)
337 {
338 if ($eventResult->getType() == EventResult::ERROR)
339 {
340 return false;
341 }
342 }
343
344 return true;
345 }
346
353 public static function unsubscribe($data)
354 {
355 if(!is_array($data['FIELDS'])) return false;
356
357 $event = new Main\Event("main", "OnMailEventSubscriptionDisable", array($data['FIELDS']), array($data['MODULE_ID']));
358 $event->send();
359 foreach ($event->getResults() as $eventResult)
360 {
361 if ($eventResult->getType() == EventResult::ERROR)
362 {
363 return false;
364 }
365 }
366
367 if (!empty($data['MODULE_ID']) && $data['MODULE_ID'] === 'main')
368 {
370 }
371
372 return true;
373 }
374
381 public static function click(array $data)
382 {
383 if (Main\Config\Option::get('main', 'track_outgoing_emails_click', 'Y') != 'Y')
384 {
385 return false;
386 }
387
388 if(array_key_exists('MODULE_ID', $data))
389 $filter = array($data['MODULE_ID']);
390 else
391 $filter = null;
392
393 $event = new Main\Event("main", "OnMailEventMailClick", array($data['FIELDS']), $filter);
394 $event->send();
395 foreach ($event->getResults() as $eventResult)
396 {
397 if ($eventResult->getType() == EventResult::ERROR)
398 {
399 return false;
400 }
401 }
402
403 return true;
404 }
405
411 public static function clickFromRequest()
412 {
413 $request = Main\Context::getCurrent()->getRequest();
414 $url = $request->get('url');
415 $sign = $request->get('sign');
416 $tag = $request->get('tag');
417
418 if ($tag)
419 {
420 try
421 {
422 $tag = static::parseTag($tag);
423 $tag['FIELDS']['IP'] = $request->getRemoteAddress();
424 $tag['FIELDS']['URL'] = $url;
425 static::click($tag);
426 }
427 catch (SystemException $exception)
428 {
429
430 }
431 }
432
433 $isValidate = static::validateSign($url, $sign);
434 $skipSecCheck = ($sign && $url && $isValidate);
435 $url = $url ?: '/';
436 if ($isValidate)
437 {
438 LocalRedirect($url, $skipSecCheck);
439 }
440 else
441 {
442 ShowError('Failed to verify the security of the url address');
443 }
444 }
445
451 public static function readFromRequest()
452 {
453 $request = Main\Context::getCurrent()->getRequest();
454 $tag = $request->get('tag');
455 if (!$tag)
456 {
457 return false;
458 }
459
460 try
461 {
462 $data = static::parseTag($tag);
463 $data['FIELDS']['IP'] = $request->getRemoteAddress();
464 return static::read($data);
465 }
466 catch (SystemException $exception)
467 {
468 return false;
469 }
470 }
471
478 public static function read(array $data)
479 {
480 if (Main\Config\Option::get('main', 'track_outgoing_emails_read', 'Y') != 'Y')
481 {
482 return false;
483 }
484
485 if(array_key_exists('MODULE_ID', $data))
486 $filter = array($data['MODULE_ID']);
487 else
488 $filter = null;
489
490 $event = new Main\Event("main", "OnMailEventMailRead", array($data['FIELDS']), $filter);
491 $event->send();
492 foreach ($event->getResults() as $eventResult)
493 {
494 if ($eventResult->getType() == EventResult::ERROR)
495 {
496 return false;
497 }
498 }
499
500 return true;
501 }
502
509 public static function changeStatus(Callback\Result $callbackResult)
510 {
511 if($callbackResult->getModuleId())
512 {
513 $filter = [$callbackResult->getModuleId()];
514 }
515 else
516 {
517 $filter = null;
518 }
519
520 $event = new Main\Event("main", self::onChangeStatus, [$callbackResult], $filter);
521 $event->send();
522 foreach ($event->getResults() as $eventResult)
523 {
524 if ($eventResult->getType() == EventResult::ERROR)
525 {
526 return false;
527 }
528 }
529
530 return true;
531 }
532}
static onMailEventSubscriptionList(array $data)
static onMailEventSubscriptionDisable(array $data)
static subscribe($data)
Definition tracking.php:330
static changeStatus(Callback\Result $callbackResult)
Definition tracking.php:509
static getTag($moduleId, $fields)
Definition tracking.php:40
static getLinkClick($moduleId, $fields, $urlPage=null)
Definition tracking.php:129
static getLinkUnsub($moduleId, $fields, $urlPage=null)
Definition tracking.php:148
static click(array $data)
Definition tracking.php:381
static getSign($value)
Definition tracking.php:185
static getSignedTag($moduleId, $fields)
Definition tracking.php:70
static unsubscribe($data)
Definition tracking.php:353
static getLinkRead($moduleId, $fields, $urlPage=null)
Definition tracking.php:111
static parseSignedTag($signedTag)
Definition tracking.php:85
static getTaggedLink($tag, $opCode, $uri=null)
Definition tracking.php:164
static getSubscriptionList($data)
Definition tracking.php:276
static read(array $data)
Definition tracking.php:478
static validateSign($value, $signature)
Definition tracking.php:215
validate($value, $signature, $salt=null)
Definition signer.php:173
getSignature($value, $salt=null)
Definition signer.php:83
sign($value, $salt=null)
Definition signer.php:111
unsign($signedValue, $salt=null)
Definition signer.php:153