Your IP : 3.133.116.50


Current Path : /home/bitrix/ext_www/www.piano.royal-thermo.com.ua/bitrix/modules/sender/lib/
Upload File :
Current File : /home/bitrix/ext_www/www.piano.royal-thermo.com.ua/bitrix/modules/sender/lib/posting.php

<?php
/**
 * Bitrix Framework
 * @package bitrix
 * @subpackage sender
 * @copyright 2001-2012 Bitrix
 */
namespace Bitrix\Sender;

use Bitrix\Main\Entity;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Type;

Loc::loadMessages(__FILE__);

class PostingTable extends Entity\DataManager
{
	const STATUS_NEW = 'N';
	const STATUS_PART = 'P';
	const STATUS_SENT = 'S';
	const STATUS_SENT_WITH_ERRORS = 'E';
	const STATUS_ABORT = 'A';

	/**
	 * @return string
	 */
	public static function getTableName()
	{
		return 'b_sender_posting';
	}

	/**
	 * @return array
	 */
	public static function getMap()
	{
		return array(
			'ID' => array(
				'data_type' => 'integer',
				'primary' => true,
				'autocomplete' => true,
			),
			'MAILING_ID' => array(
				'data_type' => 'integer',
				'primary' => true,
				'required' => true,
			),
			'MAILING_CHAIN_ID' => array(
				'data_type' => 'integer',
				'primary' => true,
				'required' => true,
			),
			'DATE_CREATE' => array(
				'data_type' => 'datetime',
				'required' => true,
				'default_value' => new Type\DateTime(),
			),
			'DATE_UPDATE' => array(
				'data_type' => 'datetime',
				'required' => true,
				'default_value' => new Type\DateTime(),
			),
			'STATUS' => array(
				'data_type' => 'string',
				'required' => true,
				'default_value' => static::STATUS_NEW,
			),
			'DATE_SENT' => array(
				'data_type' => 'datetime',
			),
			'COUNT_READ' => array(
				'data_type' => 'integer',
				'default_value' => 0
			),
			'COUNT_CLICK' => array(
				'data_type' => 'integer',
				'default_value' => 0
			),
			'COUNT_UNSUB' => array(
				'data_type' => 'integer',
				'default_value' => 0
			),
			'COUNT_SEND_ALL' => array(
				'data_type' => 'integer',
				'default_value' => 0
			),
			'COUNT_SEND_NONE' => array(
				'data_type' => 'integer',
				'default_value' => 0
			),
			'COUNT_SEND_ERROR' => array(
				'data_type' => 'integer',
				'default_value' => 0
			),
			'COUNT_SEND_SUCCESS' => array(
				'data_type' => 'integer',
				'default_value' => 0
			),
			'COUNT_SEND_DENY' => array(
				'data_type' => 'integer',
				'default_value' => 0
			),
			'MAILING' => array(
				'data_type' => 'Bitrix\Sender\MailingTable',
				'reference' => array('=this.MAILING_ID' => 'ref.ID'),
			),
			'MAILING_CHAIN' => array(
				'data_type' => 'Bitrix\Sender\MailingChainTable',
				'reference' => array('=this.MAILING_CHAIN_ID' => 'ref.ID'),
			),
			'POSTING_RECIPIENT' => array(
				'data_type' => 'Bitrix\Sender\PostingRecipientTable',
				'reference' => array('=this.ID' => 'ref.POSTING_ID'),
			),
			'POSTING_READ' => array(
				'data_type' => 'Bitrix\Sender\PostingReadTable',
				'reference' => array('=this.ID' => 'ref.POSTING_ID'),
			),
			'POSTING_CLICK' => array(
				'data_type' => 'Bitrix\Sender\PostingClickTable',
				'reference' => array('=this.ID' => 'ref.POSTING_ID'),
			),
			'POSTING_UNSUB' => array(
				'data_type' => 'Bitrix\Sender\PostingUnsubTable',
				'reference' => array('=this.ID' => 'ref.POSTING_ID'),
			),
		);
	}

	/**
	 * @param Entity\Event $event
	 * @return Entity\EventResult
	 * @throws \Bitrix\Main\ArgumentException
	 */
	public static function onDelete(Entity\Event $event)
	{
		$result = new Entity\EventResult;
		$data = $event->getParameters();


		$listId = array();
		if(array_key_exists('ID', $data['primary']))
		{
			$listId[] = $data['primary']['ID'];
		}
		else
		{
			$filter = array();
			foreach($data['primary'] as $primKey => $primVal)
				$filter[$primKey] = $primVal;

			$tableDataList = static::getList(array(
				'select' => array('ID'),
				'filter' => $filter
			));
			while($tableData = $tableDataList->fetch())
			{
				$listId[] = $tableData['ID'];
			}

		}

		foreach($listId as $primaryId)
		{
			$primary = array('POSTING_ID' => $primaryId);
			PostingReadTable::delete($primary);
			PostingClickTable::delete($primary);
			PostingUnsubTable::delete($primary);
			PostingRecipientTable::delete($primary);
		}


		return $result;
	}

	/**
	 * @param $ar
	 * @param bool $checkDuplicate
	 */
	public static function addRecipient($ar, $checkDuplicate = false)
	{
		$ar['EMAIL'] = trim(strtolower($ar['EMAIL']));

		if(!$checkDuplicate)
		{
			$needAdd = true;
		}
		else
		{

			if(!PostingRecipientTable::getRowById(array('EMAIL' => $ar['EMAIL'], 'POSTING_ID' => $ar['POSTING_ID'])))
				$needAdd = true;
			else
				$needAdd = false;
		}

		if($needAdd)
			PostingRecipientTable::add($ar);
	}


	/**
	 * @param $postingId
	 * @param bool $checkDuplicate
	 * @return bool
	 * @throws \Bitrix\Main\ArgumentException
	 */
	public static function initGroupRecipients($postingId, $checkDuplicate = true)
	{
		$posting = \Bitrix\Sender\PostingTable::getRowById(array('ID' => $postingId));
		if(!$posting)
			return false;

		$checkRecipientDuplicate = $checkDuplicate;
		if(!$checkDuplicate)
		{
			if($posting['STATUS'] == \Bitrix\Sender\PostingTable::STATUS_NEW)
			{
				$primary = array('POSTING_ID' => $postingId);
				\Bitrix\Sender\PostingRecipientTable::delete($primary);
				$checkRecipientDuplicate = false;
			}
		}

		// fetch all unsubscribed emails of current mailing for excluding from recipients
		$emailNotSendList = array();
		$unSubEmailDb = \Bitrix\Sender\MailingSubscriptionTable::getUnSubscriptionList(array(
			'select' => array('EMAIL' => 'CONTACT.EMAIL'),
			'filter' => array('=MAILING_ID' => $posting['MAILING_ID'])
		));
		while($unSubEmail = $unSubEmailDb->fetch())
			$emailNotSendList[] = $unSubEmail['EMAIL'];

		$groupConnectorsDataCount = array();

		$connection = \Bitrix\Main\Application::getConnection();
		$conHelper = $connection->getSqlHelper();
		$statusRecipientNone = \Bitrix\Sender\PostingRecipientTable::SEND_RESULT_NONE;

		// fetch all connectors for getting emails
		$groupConnectorList = array();
		$groupConnectorDb = \Bitrix\Sender\MailingGroupTable::getList(array(
			'select' => array(
				'INCLUDE',
				'CONNECTOR_ENDPOINT' => 'GROUP.GROUP_CONNECTOR.ENDPOINT',
				'GROUP_ID'
			),
			'filter' => array(
				'MAILING_ID' => $posting['MAILING_ID'],
			),
			'order' => array('INCLUDE' => 'DESC', 'GROUP_ID' => 'ASC')
		));
		while($group = $groupConnectorDb->fetch())
		{
			$groupConnectorList[] = $group;
		}

		$groupConnectorList[] = array(
			'INCLUDE' => true,
			'CONNECTOR_ENDPOINT' => array(
				'FIELDS' => array('MAILING_ID' => $posting['MAILING_ID'])
			),
			'GROUP_ID' => null,
			'CONNECTOR' => new \Bitrix\Sender\SenderConnectorSubscriber
		);

		foreach($groupConnectorList as $group)
		{
			$connector = null;
			if(isset($group['CONNECTOR']) && is_object($group['CONNECTOR']))
				$connector = $group['CONNECTOR'];
			elseif(is_array($group['CONNECTOR_ENDPOINT']))
				$connector = \Bitrix\Sender\ConnectorManager::getConnector($group['CONNECTOR_ENDPOINT']);

			if(!$connector)
				continue;

			$connectorDataCount = 0;
			$connector->setFieldValues($group['CONNECTOR_ENDPOINT']['FIELDS']);
			$connectorDataDb = $connector->getResult();
			while(true)
			{
				$emailList = array();
				$connectorDataList = array();

				$maxPart = 200;
				while ($connectorData = $connectorDataDb->fetch())
				{
					// collect connectors counter of addresses
					$connectorDataCount++;

					// exclude unsubscribed addresses
					$connectorData['EMAIL'] = trim(strtolower($connectorData['EMAIL']));
					if (strlen($connectorData['EMAIL']) <= 0 || in_array($connectorData['EMAIL'], $emailNotSendList))
					{
						continue;
					}

					$emailList[] = $connectorData['EMAIL'];
					$connectorDataList[$connectorData['EMAIL']] = $connectorData;

					$maxPart--;
					if($maxPart == 0) break;
				}

				if (empty($emailList)) break;

				foreach($emailList as &$email) $email = $conHelper->forSql($email);
				$emailListString = "'" . implode("', '", $emailList) . "'";

				if ($group['INCLUDE'])
				{
					// add address if not exists
					if($checkRecipientDuplicate)
					{
						$recipientEmailDb = $connection->query("select EMAIL from b_sender_posting_recipient where EMAIL in (".$emailListString.") and POSTING_ID=".intval($postingId));
						while ($recipientEmail = $recipientEmailDb->fetch())
						{
							unset($connectorDataList[$recipientEmail['EMAIL']]);
						}
					}

					if(!empty($connectorDataList))
					{
						$insertDataList = array();
						$insertColumnNamesString = array();
						foreach($connectorDataList as $email => $connectorData)
						{
							$recipientInsert = array(
								'NAME' => "'" . $conHelper->forSql($connectorData['NAME']) . "'",
								'EMAIL' => "'" . $conHelper->forSql($connectorData['EMAIL']) . "'",
								'STATUS' => "'" . $statusRecipientNone . "'",
								'POSTING_ID' => intval($postingId),
								'USER_ID' => "NULL",
								'FIELDS' => "NULL"
							);

							if (array_key_exists('USER_ID', $connectorData) && intval($connectorData['USER_ID']) > 0)
							{
								$recipientInsert['USER_ID'] = intval($connectorData['USER_ID']);
							}

							if (array_key_exists('FIELDS', $connectorData) && count($connectorData['FIELDS']) > 0)
							{
								$recipientInsert['FIELDS'] =  "'" . $conHelper->forSql(serialize($connectorData['FIELDS'])) . "'";
							}

							$insertColumnNamesString = implode(", ", array_keys($recipientInsert));
							$insertColumnValuesString = implode(", ", array_values($recipientInsert));
							$insertDataList[] = $insertColumnValuesString;
						}

						if($insertDataList && $insertColumnNamesString)
						{
							$insertDataListString =  implode('),(', $insertDataList);
							$connection->query("insert into b_sender_posting_recipient(" . $insertColumnNamesString . ") values(" . $insertDataListString . ")");
						}
					}
				}
				else
				{
					// delete address from posting
					$connection->query("delete from b_sender_posting_recipient where EMAIL in (".$emailListString.") and POSTING_ID=".intval($postingId));
				}
			}

			//\Bitrix\Sender\GroupConnectorTable::update(array('ID' => $group['GROUP_CONNECTOR_ID']), array('ADDRESS_COUNT' => $connectorDataCount));
			// collect groups counter of addresses
			if(!empty($group['GROUP_ID']))
			{
				if (array_key_exists($group['GROUP_ID'], $groupConnectorsDataCount))
					$groupConnectorsDataCount[$group['GROUP_ID']] += $connectorDataCount;
				else
					$groupConnectorsDataCount[$group['GROUP_ID']] = $connectorDataCount;
			}

			unset($connector);
		}


		// update group counter of addresses
		foreach($groupConnectorsDataCount as $groupId => $groupDataCount)
		{
			\Bitrix\Sender\GroupTable::update($groupId, array('ADDRESS_COUNT' => $groupDataCount));
		}


		return true;
	}

	/**
	 * @param $id
	 * @return array
	 * @throws \Bitrix\Main\ArgumentException
	 */
	public static function getRecipientCountByStatus($id)
	{
		$statusList = array();

		$select = array('CNT', 'STATUS');
		$filter = array('POSTING_ID' => $id);
		$postingContactDb = PostingRecipientTable::getList(array(
			'select' => $select,
			'filter' => $filter,
			'runtime' => array(new Entity\ExpressionField('CNT', 'COUNT(*)')),
		));
		while($postingContact = $postingContactDb->fetch())
			$statusList[$postingContact['STATUS']] = intval($postingContact['CNT']);

		return $statusList;
	}

	/**
	 * @param $id
	 * @param string $status
	 * @return int
	 */
	public static function getRecipientCount($id, $status = '')
	{
		$count = 0;

		$ar = static::getRecipientCountByStatus($id);
		if ($status != '')
			$count = (array_key_exists($status, $ar) ? $ar[$status] : 0);
		else
			foreach ($ar as $k => $v) $count += $v;

		return $count;
	}

	/**
	 * Return send status of posting in percents by posting id.
	 *
	 * @param $id
	 * @return int
	 */
	public static function getSendPercent($id)
	{
		$ar = static::getRecipientCountByStatus($id);
		$count = 0;
		foreach ($ar as $k => $v)
		{
			$count += $v;
		}

		$countNew = 0;
		if(isset($ar[PostingRecipientTable::SEND_RESULT_NONE]))
		{
			$countNew = $ar[PostingRecipientTable::SEND_RESULT_NONE];
		}

		if($count > 0 && $countNew > 0)
		{
			return round(($count - $countNew) / $count, 2) * 100;
		}
		else
		{
			return 100;
		}
	}

	/**
	 * @return array
	 */
	public static function getRecipientStatusToPostingFieldMap()
	{
		return array(
			PostingRecipientTable::SEND_RESULT_NONE => 'COUNT_SEND_NONE',
			PostingRecipientTable::SEND_RESULT_ERROR => 'COUNT_SEND_ERROR',
			PostingRecipientTable::SEND_RESULT_SUCCESS => 'COUNT_SEND_SUCCESS',
			PostingRecipientTable::SEND_RESULT_DENY => 'COUNT_SEND_DENY',
		);
	}
}



class PostingReadTable extends Entity\DataManager
{
	/**
	 * @return string
	 */
	public static function getTableName()
	{
		return 'b_sender_posting_read';
	}

	/**
	 * @return array
	 */
	public static function getMap()
	{
		return array(
			'ID' => array(
				'data_type' => 'integer',
				'primary' => true,
				'autocomplete' => true,
			),
			'POSTING_ID' => array(
				'primary' => true,
				'data_type' => 'integer',
			),
			'RECIPIENT_ID' => array(
				'primary' => true,
				'data_type' => 'integer',
			),
			'DATE_INSERT' => array(
				'data_type' => 'datetime',
				'default_value' => new Type\DateTime(),
			),
		);
	}

	/**
	 * Handler of after add event
	 *
	 * @param Entity\Event $event
	 * @return Entity\EventResult
	 */
	public static function onAfterAdd(Entity\Event $event)
	{
		$result = new Entity\EventResult;
		$data = $event->getParameters();
		$data = $data['fields'];

		// update read flag of recipient
		PostingRecipientTable::update(array('ID' => $data['RECIPIENT_ID']), array('IS_READ' => 'Y'));

		// update read counter of posting
		$resultDb = static::getList(array('filter' => array('RECIPIENT_ID' => $data['RECIPIENT_ID'])));
		if($resultDb->getSelectedRowsCount() == 1)
		{
			PostingTable::update(array('ID' => $data['POSTING_ID']), array(
				'COUNT_READ' => new \Bitrix\Main\DB\SqlExpression('?# + 1', 'COUNT_READ')
			));
		}

		return $result;
	}
}


class PostingClickTable extends Entity\DataManager
{
	/**
	 * @return string
	 */
	public static function getTableName()
	{
		return 'b_sender_posting_click';
	}

	/**
	 * @return array
	 */
	public static function getMap()
	{
		return array(
			'ID' => array(
				'data_type' => 'integer',
				'primary' => true,
				'autocomplete' => true,
			),
			'POSTING_ID' => array(
				'primary' => true,
				'data_type' => 'integer',
			),
			'RECIPIENT_ID' => array(
				'primary' => true,
				'data_type' => 'integer',
			),
			'DATE_INSERT' => array(
				'data_type' => 'datetime',
				'default_value' => new Type\DateTime(),
			),
			'URL' => array(
				'data_type' => 'string',
			),
			'POSTING' => array(
				'data_type' => 'Bitrix\Sender\PostingTable',
				'reference' => array('=this.POSTING_ID' => 'ref.ID'),
			),
		);
	}

	/**
	 * Handler of after add event
	 *
	 * @param Entity\Event $event
	 * @return Entity\EventResult
	 */
	public static function onAfterAdd(Entity\Event $event)
	{
		$result = new Entity\EventResult;
		$data = $event->getParameters();
		$data = $data['fields'];

		// update click flag of recipient
		PostingRecipientTable::update(array('ID' => $data['RECIPIENT_ID']), array('IS_CLICK' => 'Y'));

		// update click counter of posting
		$resultDb = static::getList(array('filter' => array('RECIPIENT_ID' => $data['RECIPIENT_ID'])));
		if($resultDb->getSelectedRowsCount() == 1)
		{
			PostingTable::update(array('ID' => $data['POSTING_ID']), array(
				'COUNT_CLICK' => new \Bitrix\Main\DB\SqlExpression('?# + 1', 'COUNT_CLICK')
			));
		}

		return $result;
	}
}

class PostingUnsubTable extends Entity\DataManager
{
	/**
	 * @return string
	 */
	public static function getTableName()
	{
		return 'b_sender_posting_unsub';
	}

	/**
	 * @return array
	 */
	public static function getMap()
	{
		return array(
			'ID' => array(
				'data_type' => 'integer',
				'primary' => true,
				'autocomplete' => true,
			),
			'POSTING_ID' => array(
				'primary' => true,
				'data_type' => 'integer',
			),
			'RECIPIENT_ID' => array(
				'primary' => true,
				'data_type' => 'integer',
			),
			'DATE_INSERT' => array(
				'data_type' => 'datetime',
				'default_value' => new Type\DateTime(),
			),
			'POSTING' => array(
				'data_type' => 'Bitrix\Sender\PostingTable',
				'reference' => array('=this.POSTING_ID' => 'ref.ID'),
			),
			'POSTING_RECIPIENT' => array(
				'data_type' => 'Bitrix\Sender\PostingRecipientTable',
				'reference' => array('=this.RECIPIENT_ID' => 'ref.ID'),
			),
		);
	}

	/**
	 * Handler of after add event
	 *
	 * @param Entity\Event $event
	 * @return Entity\EventResult
	 */
	public static function onAfterAdd(Entity\Event $event)
	{
		$result = new Entity\EventResult;
		$data = $event->getParameters();
		$data = $data['fields'];

		// update unsub flag of recipient
		PostingRecipientTable::update(array('ID' => $data['RECIPIENT_ID']), array('IS_UNSUB' => 'Y'));

		// update unsub counter of posting
		$resultDb = static::getList(array('filter' => array('RECIPIENT_ID' => $data['RECIPIENT_ID'])));
		if($resultDb->getSelectedRowsCount() == 1)
		{
			PostingTable::update(array('ID' => $data['POSTING_ID']), array(
				'COUNT_UNSUB' => new \Bitrix\Main\DB\SqlExpression('?# + 1', 'COUNT_UNSUB')
			));
		}

		return $result;
	}
}

class PostingRecipientTable extends Entity\DataManager
{
	const SEND_RESULT_NONE = 'Y';
	const SEND_RESULT_SUCCESS = 'N';
	const SEND_RESULT_ERROR = 'E';
	const SEND_RESULT_WAIT = 'W';
	const SEND_RESULT_DENY = 'D';

	protected static $personalizeList = null;
	/**
	 * @return string
	 */
	public static function getTableName()
	{
		return 'b_sender_posting_recipient';
	}

	/**
	 * @return array
	 */
	public static function getMap()
	{
		return array(
			'ID' => array(
				'data_type' => 'integer',
				'primary' => true,
				'autocomplete' => true,
			),
			'POSTING_ID' => array(
				'primary' => true,
				'data_type' => 'integer',
			),
			'STATUS' => array(
				'data_type' => 'string',
				'primary' => true,
				'required' => true,
				'default_value' => static::SEND_RESULT_NONE,
			),
			'DATE_SENT' => array(
				'data_type' => 'datetime',
			),

			'DATE_DENY' => array(
				'data_type' => 'datetime',
			),
			'NAME' => array(
				'data_type' => 'string',
			),
			'EMAIL' => array(
				'data_type' => 'string',
				'primary' => true,
				'required' => true,
			),
			'PHONE' => array(
				'data_type' => 'string',
				//'required' => true,
			),
			'USER_ID' => array(
				'data_type' => 'integer',
			),
			'FIELDS' => array(
				'data_type' => 'text',
				'serialized' => true,
			),
			'ROOT_ID' => array(
				'data_type' => 'integer',
			),
			'IS_READ' => array(
				'data_type' => 'string',
			),
			'IS_CLICK' => array(
				'data_type' => 'string',
			),
			'IS_UNSUB' => array(
				'data_type' => 'string',
			),
			'POSTING' => array(
				'data_type' => 'Bitrix\Sender\PostingTable',
				'reference' => array('=this.POSTING_ID' => 'ref.ID'),
			),
			'POSTING_READ' => array(
				'data_type' => 'Bitrix\Sender\PostingReadTable',
				'reference' => array('=this.ID' => 'ref.RECIPIENT_ID'),
			),
			'POSTING_CLICK' => array(
				'data_type' => 'Bitrix\Sender\PostingClickTable',
				'reference' => array('=this.ID' => 'ref.RECIPIENT_ID'),
			),
			'POSTING_UNSUB' => array(
				'data_type' => 'Bitrix\Sender\PostingUnsubTable',
				'reference' => array('=this.ID' => 'ref.RECIPIENT_ID'),
			),
		);
	}

	public static function setPersonalizeList(array $personalizeList = null)
	{
		static::$personalizeList = $personalizeList;
	}

	/**
	 * @return array
	 */
	public static function getPersonalizeList()
	{
		return array_merge(
			array(
				array(
					'CODE' => 'NAME',
					'NAME' => Loc::getMessage("SENDER_POSTING_PERSONALIZE_FIELD_NAME"),
					'DESC' => Loc::getMessage("SENDER_POSTING_PERSONALIZE_FIELD_NAME_DESC"),
				),
				array(
					'CODE' => 'USER_ID',
					'NAME' => Loc::getMessage("SENDER_POSTING_PERSONALIZE_FIELD_USER_ID"),
					'DESC' => Loc::getMessage("SENDER_POSTING_PERSONALIZE_FIELD_USER_ID_DESC"),
				),
				array(
					'CODE' => 'SITE_NAME',
					'NAME' => Loc::getMessage("SENDER_POSTING_PERSONALIZE_FIELD_SITE_NAME"),
					'DESC' => Loc::getMessage("SENDER_POSTING_PERSONALIZE_FIELD_SITE_NAME_DESC"),
				),
				array(
					'CODE' => 'EMAIL_TO',
					'NAME' => Loc::getMessage("SENDER_POSTING_PERSONALIZE_FIELD_EMAIL"),
					'DESC' => Loc::getMessage("SENDER_POSTING_PERSONALIZE_FIELD_EMAIL_DESC"),
				),
				array(
					'CODE' => 'SENDER_CHAIN_CODE',
					'NAME' => Loc::getMessage("SENDER_POSTING_PERSONALIZE_FIELD_SENDER_CHAIN_ID"),
					'DESC' => Loc::getMessage("SENDER_POSTING_PERSONALIZE_FIELD_SENDER_CHAIN_ID_DESC"),
				),
			),
			(static::$personalizeList ? static::$personalizeList : array())
		);
	}

	/**
	 * @return array
	 */
	public static function getStatusList()
	{
		return array(
			self::SEND_RESULT_NONE => Loc::getMessage('SENDER_POSTING_RECIPIENT_STATUS_N'),
			self::SEND_RESULT_SUCCESS => Loc::getMessage('SENDER_POSTING_RECIPIENT_STATUS_S'),
			self::SEND_RESULT_ERROR => Loc::getMessage('SENDER_POSTING_RECIPIENT_STATUS_E')
		);
	}
}