%PDF- %PDF-
| Direktori : /home/bitrix/www/bitrix/modules/seo/lib/retargeting/internals/ |
| Current File : //home/bitrix/www/bitrix/modules/seo/lib/retargeting/internals/queue.php |
<?php
/**
* Bitrix Framework
* @package bitrix
* @subpackage seo
* @copyright 2001-2013 Bitrix
*/
namespace Bitrix\Seo\Retargeting\Internals;
use Bitrix\Main\Application;
use \Bitrix\Main\Entity;
use \Bitrix\Main\Localization\Loc;
use \Bitrix\Main\Type\DateTime;
use Bitrix\Seo\Retargeting\Service;
Loc::loadMessages(__FILE__);
class QueueTable extends Entity\DataManager
{
const MODULE_ID = 'seo';
const PORTION_QUANTITY = 50;
const ACTION_IMPORT = 'IMP';
const ACTION_IMPORT_AND_AUTO_REMOVE = 'IAR';
const ACTION_REMOVE = 'REM';
const ACTION_AUTO_REMOVE = 'ARM';
protected static $isAgentAdded = array();
public static function getTableName()
{
return 'b_seo_service_rtg_queue';
}
public static function getMap()
{
$fieldsMap = array(
'ID' => array(
'data_type' => 'integer',
'primary' => true,
'autocomplete' => true,
),
'DATE_INSERT' => array(
'data_type' => 'datetime',
'default_value' => new DateTime()
),
'TYPE' => array(
'data_type' => 'string',
'required' => true,
),
'ACCOUNT_ID' => array(
'data_type' => 'string',
),
'AUDIENCE_ID' => array(
'data_type' => 'string',
'required' => true,
),
'CONTACT_TYPE' => array(
'data_type' => 'string',
'required' => true,
),
'VALUE' => array(
'data_type' => 'string',
'required' => true,
),
'ACTION' => array(
'data_type' => 'enum',
'values' => array(
self::ACTION_IMPORT,
self::ACTION_REMOVE,
self::ACTION_IMPORT_AND_AUTO_REMOVE,
self::ACTION_AUTO_REMOVE,
),
'default_value' => self::ACTION_IMPORT_AND_AUTO_REMOVE,
'required' => true,
),
'DATE_AUTO_REMOVE' => array(
'data_type' => 'datetime',
)
);
return $fieldsMap;
}
protected static function processQueueAutoRemoveAgentName()
{
return __CLASS__ . '::processQueueAutoRemoveAgent();';
}
protected static function getProcessQueueAgentName($type)
{
return __CLASS__ . '::processQueueAgent("' . $type . '");';
}
public static function processQueueAutoRemoveAgent()
{
$queueDb = static::getList(array(
'select' => array('ID'),
'filter' => array('=ACTION' => self::ACTION_AUTO_REMOVE),
'limit' => 1
));
if ($queueDb->fetch())
{
$connection = Application::getConnection();
$sql = "UPDATE " . self::getTableName() . " " .
"SET ACTION='" . self::ACTION_REMOVE . "' " .
"WHERE ACTION='" . self::ACTION_AUTO_REMOVE . "' " .
"AND DATE_AUTO_REMOVE <= " . $connection->getSqlHelper()->getCurrentDateTimeFunction();
$connection->query($sql);
if ($connection->getAffectedRowsCount() > 0)
{
$types = Service::getTypes();
foreach ($types as $type)
{
static::addQueueAgent($type);
}
}
return static::processQueueAutoRemoveAgentName();
}
else
{
return '';
}
}
public static function processQueueAgent($type)
{
try
{
$hasQueue = static::processQueue($type);
}
catch(\Exception $e)
{
$hasQueue = false;
}
if (!$hasQueue)
{
return '';
}
else
{
return static::getProcessQueueAgentName($type);
}
}
protected static function processQueue($type)
{
$hasQueue = false;
$queryData = array();
$audience = Service::getAudience($type);
$maxQuantity = $audience->getMaxContactsPerPacket();
$maxQuantity = $maxQuantity > 1000 ? 1000 : $maxQuantity;
$queueDb = static::getList(array(
'filter' => array(
'=TYPE' => $type,
'=ACTION' => array(
self::ACTION_IMPORT,
self::ACTION_REMOVE,
self::ACTION_IMPORT_AND_AUTO_REMOVE,
)
),
'limit' => $maxQuantity
));
while ($queueItem = $queueDb->fetch())
{
$hasQueue = true;
$isRemove = $queueItem['ACTION'] == self::ACTION_REMOVE ? 'Y' : 'N';
$queryId = $queueItem['TYPE'];
$queryId .= '_' . $queueItem['ACCOUNT_ID'];
$queryId .= '_' . $queueItem['AUDIENCE_ID'];
$queryId .= '_' . $isRemove;
if (!isset($queryData[$queryId]))
{
$queryData[$queryId] = array(
'ACCOUNT_ID' => $queueItem['ACCOUNT_ID'],
'AUDIENCE_ID' => $queueItem['AUDIENCE_ID'],
'IS_REMOVE' => $isRemove,
'CONTACTS' => array(),
'DELETE_ID_LIST' => array(),
'AUTO_REMOVE_ID_LIST' => array(),
);
}
$contactType = $queueItem['CONTACT_TYPE'];
if (!isset($queryData[$queryId]['CONTACTS'][$contactType]))
{
$queryData[$queryId]['CONTACTS'][$contactType] = array();
}
$queryData[$queryId]['CONTACTS'][$contactType][] = $queueItem['VALUE'];
if ($queueItem['ACTION'] == self::ACTION_IMPORT_AND_AUTO_REMOVE)
{
$queryData[$queryId]['AUTO_REMOVE_ID_LIST'][] = $queueItem['ID'];
}
else
{
$queryData[$queryId]['DELETE_ID_LIST'][] = $queueItem['ID'];
}
}
foreach ($queryData as $queryId => $query)
{
foreach ($query['CONTACTS'] as $contactType => $contacts)
{
$query['CONTACTS'][$contactType] = array_unique($contacts);
}
$audience->disableQueueMode();
$audience->setAccountId($query['ACCOUNT_ID']);
$contactTypes = $audience->isSupportMultiTypeContacts() ? array('') : array_keys($query['CONTACTS']);
foreach ($contactTypes as $contactType)
{
if ($query['IS_REMOVE'] != 'Y')
{
$audienceImportResult = $audience->addContacts(
$query['AUDIENCE_ID'],
$query['CONTACTS'],
array(
'type' => $contactType
)
);
}
else
{
$audienceImportResult = $audience->deleteContacts(
$query['AUDIENCE_ID'],
$query['CONTACTS'],
array(
'type' => $contactType
)
);
}
if ($audienceImportResult->isSuccess())
{
if (!empty($query['DELETE_ID_LIST']))
{
$portions = self::divideListIntoPortions($query['DELETE_ID_LIST']);
foreach ($portions as $portion)
{
Application::getConnection()->query(
"DELETE FROM " . self::getTableName() . " WHERE ID IN (" . implode(',', $portion) . ")"
);
}
}
if (!empty($query['AUTO_REMOVE_ID_LIST']))
{
$portions = self::divideListIntoPortions($query['AUTO_REMOVE_ID_LIST']);
foreach ($portions as $portion)
{
Application::getConnection()->query(
"UPDATE " . self::getTableName() . " SET ACTION='" . self::ACTION_AUTO_REMOVE . "'" .
"WHERE ID IN (" . implode(',', $portion) . ")"
);
}
static::addQueueAutoRemoveAgent();
}
}
else
{
Application::getConnection()->query(
"DELETE FROM " . self::getTableName() .
" WHERE TYPE = '" . Application::getConnection()->getSqlHelper()->forSql($type) . "'" .
" AND ACTION in ('" . implode("', '", [self::ACTION_IMPORT, self::ACTION_IMPORT_AND_AUTO_REMOVE, self::ACTION_REMOVE]) . "')" .
" AND DATE_INSERT < '" . (new DateTime())->add('-1 day')->format("Y-m-d H:i:s") . "'"
);
}
}
}
return $hasQueue;
}
protected static function divideListIntoPortions($list)
{
$portions = array();
$deleteCount = count($list);
$portionCount = ceil($deleteCount / self::PORTION_QUANTITY);
$deleteNum = 0;
for ($portionNum = 0; $portionNum < $portionCount; $portionNum++)
{
$deleteList = array();
$deletePortionCount = ($portionNum + 1) * self::PORTION_QUANTITY;
for (; $deleteNum < $deletePortionCount; $deleteNum++)
{
if ($deleteNum >= $deleteCount)
{
break;
}
$deleteList[] = (int) $list[$deleteNum];
}
$portions[] = $deleteList;
}
return $portions;
}
protected static function addQueueAutoRemoveAgent()
{
if (isset(static::$isAgentAdded['sys.auto_remove']))
{
return;
}
$agentName = static::processQueueAutoRemoveAgentName();
$agent = new \CAgent();
$agentsDb = $agent->GetList(array("ID" => "DESC"), array(
"MODULE_ID" => self::MODULE_ID,
"NAME" => $agentName,
));
if (!$agentsDb->Fetch())
{
$agent->AddAgent($agentName, self::MODULE_ID, "N", 86400, null, "Y", "");
}
}
protected static function addQueueAgent($type)
{
if (isset(static::$isAgentAdded[$type]))
{
return;
}
$agent = new \CAgent();
if ($type)
{
$agentName = static::getProcessQueueAgentName($type);
$agentsDb = $agent->GetList(array("ID" => "DESC"), array(
"MODULE_ID" => self::MODULE_ID,
"NAME" => $agentName,
));
if (!$agentsDb->Fetch())
{
$agent->AddAgent($agentName, self::MODULE_ID, "N", 300, null, "Y", "");
}
}
static::$isAgentAdded[$type] = true;
}
public static function onAfterAdd(Entity\Event $event)
{
$fields = $event->getParameter('fields');
$type = $fields['TYPE'];
static::addQueueAgent($type);
}
}