Your IP : 18.225.57.152
<?php
/**
* Bitrix Framework
* @package bitrix
* @subpackage main
* @copyright 2001-2012 Bitrix
*/
namespace Bitrix\Main\Mail;
use Bitrix\Main;
use Bitrix\Main\Application;
use Bitrix\Main\EventResult;
use Bitrix\Main\Security\Sign\BadSignatureException;
use Bitrix\Main\Security\Sign\Signer;
use Bitrix\Main\SystemException;
/**
* Class Tracking
* @package Bitrix\Main\Mail
*/
class Tracking
{
const SIGN_SALT_ACTION = 'event_mail_tracking';
/**
* Get tag.
*
* @param string $moduleId Module ID.
* @param array $fields Fields.
* @return string
*/
public static function getTag($moduleId, $fields)
{
return $moduleId . "." . base64_encode(json_encode($fields));
}
/**
* Parse tag.
*
* @param string $tag Tag.
* @return array
*/
public static function parseTag($tag)
{
$data = explode(".", $tag);
$moduleId = $data[0];
unset($data[0]);
return array('MODULE_ID' => $moduleId, 'FIELDS' => (array) json_decode(base64_decode(implode('.', $data))));
}
/**
* Get signed tag.
*
* @param string $moduleId Module ID.
* @param array $fields Fields.
* @return string
* @throws \Bitrix\Main\ArgumentTypeException
*/
public static function getSignedTag($moduleId, $fields)
{
$tag = static::getTag($moduleId, $fields);
$signer = new Signer;
return $signer->sign($tag, static::SIGN_SALT_ACTION);
}
/**
* Parse signed tag.
*
* @param string $signedTag Signed tag.
* @return array
* @throws BadSignatureException
* @throws Main\ArgumentTypeException
*/
public static function parseSignedTag($signedTag)
{
$signer = new Signer;
$unsignedTag = $signer->unsign($signedTag, static::SIGN_SALT_ACTION);
return static::parseTag($unsignedTag);
}
/**
* Get read page link
*
* @param string $moduleId Module ID.
* @param array $fields Fields.
* @param string|null $urlPage Url of custom click page.
* @return string
* @throws SystemException
*/
public static function getLinkRead($moduleId, $fields, $urlPage = null)
{
return static::getTaggedLink(
static::getTag($moduleId, $fields),
'read',
$urlPage
);
}
/**
* Get click page link.
*
* @param string $moduleId Module ID.
* @param array $fields Fields.
* @param string|null $urlPage Url of custom click page.
* @return string
* @throws SystemException
*/
public static function getLinkClick($moduleId, $fields, $urlPage = null)
{
return static::getTaggedLink(
static::getTag($moduleId, $fields),
'click',
$urlPage
);
}
/**
* Get link for unsubscribe.
*
* @param string $moduleId Module ID.
* @param array $fields Fields.
* @param string|null $urlPage Url of custom unsubscribe page.
* @return string
* @throws Main\ArgumentTypeException
* @throws SystemException
*/
public static function getLinkUnsub($moduleId, $fields, $urlPage = null)
{
return static::getTaggedLink(
static::getSignedTag($moduleId, $fields),
'unsub',
$urlPage
);
}
/**
* @param $tag
* @param $opCode
* @param null $uri
* @return null|string
* @throws SystemException
*/
protected static function getTaggedLink($tag, $opCode, $uri = null)
{
if(!$uri)
{
$uri = Application::getInstance()->getPersonalRoot();
$uri .= "/tools/track_mail_$opCode.php";
}
$uri = $uri . (strpos($uri, "?") === false ? "?" : "&");
$uri .= 'tag=' . urlencode($tag);
return $uri;
}
/**
* Get sign.
*
* @param string $value Value.
* @return string
* @throws Main\ArgumentTypeException
*/
public static function getSign($value)
{
static $cached = array();
foreach ($cached as $cache)
{
if ($cache[0] == $value)
{
return $cache[1];
}
}
$signer = new Signer;
$sign = $signer->getSignature($value, static::SIGN_SALT_ACTION);
$cached[] = array($value, $sign);
if (count($cached) > 10)
{
array_shift($cached);
}
return $sign;
}
/**
* Verify sign.
*
* @param string $value Value.
* @param string $signature Signature.
* @return bool
*/
public static function validateSign($value, $signature)
{
try
{
$signer = new Signer;
return $signer->validate($value, $signature, static::SIGN_SALT_ACTION);
}
catch (BadSignatureException $exception)
{
return false;
}
}
/**
* Get subscription list.
*
* @param array $data Data.
* @return array|bool
*/
public static function getSubscriptionList($data)
{
$subscription = array();
if(array_key_exists('MODULE_ID', $data))
$filter = array($data['MODULE_ID']);
else
$filter = null;
if(!is_array($data['FIELDS'])) return false;
$event = new Main\Event("main", "OnMailEventSubscriptionList", array($data['FIELDS']), $filter);
$event->send();
foreach ($event->getResults() as $eventResult)
{
if ($eventResult->getType() == EventResult::ERROR)
{
return false;
}
$subscriptionList = $eventResult->getParameters();
if($subscriptionList && is_array($subscriptionList['LIST']))
{
$subscription = array_merge(
$subscription,
array($eventResult->getModuleId() => $subscriptionList['LIST'])
);
}
}
if(array_key_exists('MODULE_ID', $data))
$subscription = $subscription[$data['MODULE_ID']];
return $subscription;
}
/**
* Subscribe.
*
* @param array $data Data.
* @return bool
*/
public static function subscribe($data)
{
if(!is_array($data['FIELDS'])) return false;
$event = new Main\Event("main", "OnMailEventSubscriptionEnable", array($data['FIELDS']), array($data['MODULE_ID']));
$event->send();
foreach ($event->getResults() as $eventResult)
{
if ($eventResult->getType() == EventResult::ERROR)
{
return false;
}
}
return true;
}
/**
* Unsubscribe.
*
* @param array $data Data.
* @return bool
*/
public static function unsubscribe($data)
{
if(!is_array($data['FIELDS'])) return false;
$event = new Main\Event("main", "OnMailEventSubscriptionDisable", array($data['FIELDS']), array($data['MODULE_ID']));
$event->send();
foreach ($event->getResults() as $eventResult)
{
if ($eventResult->getType() == EventResult::ERROR)
{
return false;
}
}
return true;
}
/**
* Click.
*
* @param array $data Data.
* @return bool
*/
public static function click(array $data)
{
if(array_key_exists('MODULE_ID', $data))
$filter = array($data['MODULE_ID']);
else
$filter = null;
$event = new Main\Event("main", "OnMailEventMailClick", array($data['FIELDS']), $filter);
$event->send();
foreach ($event->getResults() as $eventResult)
{
if ($eventResult->getType() == EventResult::ERROR)
{
return false;
}
}
return true;
}
/**
* Track click from request.
*
* @return void
*/
public static function clickFromRequest()
{
$request = Main\Context::getCurrent()->getRequest();
$url = $request->get('url');
$sign = $request->get('sign');
$tag = $request->get('tag');
if ($tag)
{
try
{
$tag = static::parseTag($tag);
$tag['FIELDS']['IP'] = $request->getRemoteAddress();
$tag['FIELDS']['URL'] = $url;
static::click($tag);
}
catch (SystemException $exception)
{
}
}
$skipSecCheck = ($sign && $url && static::validateSign($url, $sign));
$url = $url ?: '/';
LocalRedirect($url, $skipSecCheck);
}
/**
* Track read from request.
*
* @return bool
*/
public static function readFromRequest()
{
$request = Main\Context::getCurrent()->getRequest();
$tag = $request->get('tag');
if (!$tag)
{
return false;
}
try
{
$data = static::parseTag($tag);
$data['FIELDS']['IP'] = $request->getRemoteAddress();
return static::read($data);
}
catch (SystemException $exception)
{
return false;
}
}
/**
* Read.
*
* @param array $data Data.
* @return bool
*/
public static function read(array $data)
{
if(array_key_exists('MODULE_ID', $data))
$filter = array($data['MODULE_ID']);
else
$filter = null;
$event = new Main\Event("main", "OnMailEventMailRead", array($data['FIELDS']), $filter);
$event->send();
foreach ($event->getResults() as $eventResult)
{
if ($eventResult->getType() == EventResult::ERROR)
{
return false;
}
}
return true;
}
}