Your IP : 3.135.185.78


Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/seo/lib/adv/
Upload File :
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/seo/lib/adv/yandexcampaign.php

<?php
namespace Bitrix\Seo\Adv;

use Bitrix\Main\Entity;
use Bitrix\Main;
use Bitrix\Seo\AdvEntity;
use Bitrix\Seo\Engine;
use Bitrix\Main\Localization\Loc;
use Bitrix\Seo\Service;

Loc::loadMessages(__FILE__);

/**
 * Class YandexCampaignTable
 *
 * Local mirror for Yandex.Direct campaigns
 *
 * Fields:
 * <ul>
 * <li> ID int mandatory
 * <li> ENGINE_ID int mandatory
 * <li> XML_ID string(255) mandatory
 * <li> LAST_UPDATE datetime optional
 * <li> SETTINGS string optional
 * </ul>
 *
 * @package Bitrix\Seo
 *
 * DO NOT WRITE ANYTHING BELOW THIS
 *
 * <<< ORMENTITYANNOTATION
 * @method static EO_YandexCampaign_Query query()
 * @method static EO_YandexCampaign_Result getByPrimary($primary, array $parameters = array())
 * @method static EO_YandexCampaign_Result getById($id)
 * @method static EO_YandexCampaign_Result getList(array $parameters = array())
 * @method static EO_YandexCampaign_Entity getEntity()
 * @method static \Bitrix\Seo\Adv\EO_YandexCampaign createObject($setDefaultValues = true)
 * @method static \Bitrix\Seo\Adv\EO_YandexCampaign_Collection createCollection()
 * @method static \Bitrix\Seo\Adv\EO_YandexCampaign wakeUpObject($row)
 * @method static \Bitrix\Seo\Adv\EO_YandexCampaign_Collection wakeUpCollection($rows)
 */

class YandexCampaignTable extends AdvEntity
{
	const ENGINE = 'yandex_direct';

	const STRATEGY_WEEKLY_BUDGET = 'WeeklyBudget';
	const STRATEGY_WEEKLY_PACKET_OF_CLICKS = 'WeeklyPacketOfClicks';
	const STRATEGY_AVERAGE_CLICK_PRICE = 'AverageClickPrice';

	const MONEY_WARNING_VALUE_DEFAULT = 20;
	const MONEY_WARN_PLACE_INTERVAL_DEFAULT = 30;

	const CACHE_LIFETIME = 3600;

	public static $allowedWarnPlaceIntervalValues = array(15, 30, 60);
	public static $allowedMoneyWarningInterval = array(1, 50);
	public static $supportedStrategy = array(
		"WEEKLY_BUDGET" => self::STRATEGY_WEEKLY_BUDGET,
		"WEEKLY_PACKET_OF_CLICKS" => self::STRATEGY_WEEKLY_PACKET_OF_CLICKS,
		"AVERAGE_CLICK_PRICE" => self::STRATEGY_AVERAGE_CLICK_PRICE,
	);

	public static $strategyConfig = array(
		self::STRATEGY_WEEKLY_BUDGET => array(
			'WeeklySumLimit' => array(
				'type' => 'float',
				'mandatory' => true,
			),
			'MaxPrice' => array(
				'type' => 'float',
				'mandatory' => false,
			),
		),
		self::STRATEGY_WEEKLY_PACKET_OF_CLICKS => array(
			'ClicksPerWeek' => array(
				'type' => 'int',
				'mandatory' => true,
			),
			'MaxPrice' => array(
				'type' => 'float',
				'mandatory' => false,
			),
			'AveragePrice' => array(
				'type' => 'float',
				'mandatory' => false,
			),
		),
		self::STRATEGY_AVERAGE_CLICK_PRICE => array(
			'AveragePrice' => array(
				'type' => 'float',
				'mandatory' => true,
			),
			'WeeklySumLimit' => array(
				'type' => 'float',
				'mandatory' => false,
			),
		),
	);

	private static $engine = null;

	/**
	 * Returns path to the file which contains definition of the class.
	 *
	 * @return string
	 */
	public static function getFilePath()
	{
		return __FILE__;
	}

	/**
	 * Returns DB table name for entity
	 *
	 * @return string
	 */
	public static function getTableName()
	{
		return 'b_seo_adv_campaign';
	}

	/**
	 * Returns link to transport engine object.
	 *
	 * @return Engine\YandexDirect|null
	 */
	public static function getEngine()
	{
		if(!self::$engine)
		{
			self::$engine = new Engine\YandexDirect();
		}
		return self::$engine;
	}

	/**
	 * Makes fields validation and adds new Yandex.Direct campaign.
	 *
	 * @param Entity\Event $event Event data.
	 *
	 * @return Entity\EventResult
	 *
	 * @throws Engine\YandexException
	 * @throws Main\ArgumentException
	 * @throws Main\ArgumentNullException
	 */
	public static function onBeforeAdd(Entity\Event $event)
	{
		$result = new Entity\EventResult();

		$data = $event->getParameter("fields");

		$engine = self::getEngine();

		$ownerInfo = $engine->getCurrentUser();

		if(!static::$skipRemoteUpdate)
		{
			$data["SETTINGS"] = self::createParam($engine, $data, $result);
			$data["XML_ID"] = 'Error';
		}
		else
		{
			$data["XML_ID"] = $data["SETTINGS"]["CampaignID"];
		}

		$data["NAME"] = $data["SETTINGS"]["Name"];

		$data["ENGINE_ID"] = $engine->getId();

		$data['OWNER_ID'] = $ownerInfo['id'];
		$data['OWNER_NAME'] = $ownerInfo['login'];

		if(!static::$skipRemoteUpdate && $result->getType() == Entity\EventResult::SUCCESS)
		{
			try
			{
				$data["XML_ID"] = $engine->addCampaign($data["SETTINGS"]);

				$campaignSettings = $engine->getCampaign(array($data['XML_ID']));
				$data['SETTINGS'] = $campaignSettings[0];
			}
			catch(Engine\YandexDirectException $e)
			{
				$result->addError(new Entity\FieldError(
					static::getEntity()->getField('ENGINE_ID'),
					$e->getMessage(),
					$e->getCode()
				));
			}
		}

		$data['LAST_UPDATE'] = new Main\Type\DateTime();
		$data['ACTIVE'] = $data['SETTINGS']['StatusArchive'] == Engine\YandexDirect::BOOL_YES
			? static::INACTIVE
			: static::ACTIVE;

		$result->modifyFields($data);

		return $result;
	}

	/**
	 * Makes fields validation and updates Yandex.Direct campaign.
	 *
	 * @param Entity\Event $event Event data.
	 *
	 * @return Entity\EventResult
	 *
	 * @throws Engine\YandexException
	 * @throws Main\ArgumentException
	 * @throws Main\ArgumentNullException
	 */
	public static function onBeforeUpdate(Entity\Event $event)
	{
		$result = new Entity\EventResult();

		$primary = $event->getParameter("primary");
		$data = $event->getParameter("fields");

		$currentData = static::getByPrimary($primary);
		$currentData = $currentData->fetch();

		if($currentData)
		{
			$engine = self::getEngine();

			if($currentData['ENGINE_ID'] != $engine->getId())
			{
				$result->addError(new Entity\FieldError(
					static::getEntity()->getField('ENGINE_ID'),
					Loc::getMessage("SEO_CAMPAIGN_ERROR_WRONG_ENGINE")
				));
			}

			$ownerInfo = $engine->getCurrentUser();

			if($currentData['OWNER_ID'] != $ownerInfo['id'])
			{
				$result->addError(new Entity\FieldError(
					static::getEntity()->getField('OWNER_ID'),
					Loc::getMessage("SEO_CAMPAIGN_ERROR_WRONG_OWNER")
				));
			}

			$data['OWNER_NAME'] = $ownerInfo['login'];
			$data['XML_ID'] = $currentData['XML_ID'];

			if(!static::$skipRemoteUpdate)
			{
				$data["SETTINGS"] = self::createParam($engine, $data, $result);
			}

			$data["NAME"] = $data['SETTINGS']['Name'];

			if(!static::$skipRemoteUpdate && $result->getType() == Entity\EventResult::SUCCESS)
			{
				try
				{
					$engine->updateCampaign($data["SETTINGS"]);

					$campaignSettings = $engine->getCampaign(array($data['XML_ID']));
					$data['SETTINGS'] = $campaignSettings[0];
				}
				catch(Engine\YandexDirectException $e)
				{
					$result->addError(
						new Entity\FieldError(
							static::getEntity()->getField('ENGINE_ID'),
							$e->getMessage(),
							$e->getCode()
						)
					);
				}
			}

			$data['LAST_UPDATE'] = new Main\Type\DateTime();
			$data['ACTIVE'] = $data['SETTINGS']['StatusArchive'] == Engine\YandexDirect::BOOL_YES
				? static::INACTIVE
				: static::ACTIVE;

			$result->modifyFields($data);
		}

		return $result;
	}

	/**
	 * Deletes Yandex.Direct campaign.
	 *
	 * @param Entity\Event $event Event data.
	 *
	 * @return void
	 *
	 * @throws Engine\YandexException
	 * @throws Main\ArgumentException
	 */
	public static function onDelete(Entity\Event $event)
	{
		$primary = $event->getParameter("primary");

		$dbRes = static::getByPrimary($primary);
		$campaign = $dbRes->fetch();

		$engine = self::getEngine();

		if($campaign && $campaign['ENGINE_ID'] == $engine->getId())
		{
			if(!static::$skipRemoteUpdate)
			{
				$engine->deleteCampaign($campaign['XML_ID']);
			}
		}
	}

	/**
	 * Deletes all campaign banners.
	 *
	 * @param Entity\Event $event Event data.
	 *
	 * @return void
	 *
	 * @throws Main\ArgumentException
	 */
	public static function onAfterDelete(Entity\Event $event)
	{
		$primary = $event->getParameter("primary");

		$engine = self::getEngine();

		$dbRes = YandexBannerTable::getList(array(
			'filter' => array(
				'=CAMPAIGN_ID' => $primary,
				'=ENGINE_ID' => $engine->getId(),
			),
			'select' => array('ID')
		));

		YandexBannerTable::setSkipRemoteUpdate(true);
		while($banner = $dbRes->fetch())
		{
			YandexBannerTable::delete($banner['ID']);
		}
		YandexBannerTable::setSkipRemoteUpdate(false);
	}

	/**
	 * Checks campaign data before sending it to Yandex
	 *
	 * $data array format:
	 *
	 * <ul>
	 * <li>ID
	 * <li>XML_ID
	 * <li>NAME
	 * <li>SETTINGS<ul>
	 *    <li>FIO
	 *    <li>StartDate
	 *    <li>Strategy<ul>
	 *        <li>StrategyName
	 *        <li>MaxPrice
	 *        <li>AveragePrice
	 *        <li>WeeklySumLimit
	 *        <li>ClicksPerWeek
	 *    </ul>
	 *    <li>EmailNotification<ul>
	 *        <li>Email
	 *        <li>WarnPlaceInterval
	 *        <li>MoneyWarningValue
	 *    </ul>
	 *  </ul>
	 * </ul>
	 *
	 * @param Engine\YandexDirect $engine Engine object.
	 * @param array $data Campaign data.
	 * @param Entity\EventResult $result Event result object.
	 *
	 * @return array
	 * @see http://api.yandex.ru/direct/doc/reference/CreateOrUpdateCampaign.xml
	 */
	protected static function createParam(Engine\YandexDirect $engine, array $data, Entity\EventResult $result)
	{
		$settings = $engine->getSettings();

		$campaignParam = array(
			"Login" => $settings["AUTH_USER"]["login"],
		);

		$newCampaign = true;

		if(!empty($data["XML_ID"]))
		{
			$newCampaign = false;
			$campaignParam["CampaignID"] = $data["XML_ID"];
		}

		if($newCampaign || isset($data['SETTINGS']["Name"]))
		{
			$campaignParam["Name"] = trim($data['SETTINGS']["Name"]);
			if($campaignParam["Name"] == '')
			{
				$result->addError(new Entity\FieldError(
					static::getEntity()->getField('NAME'),
					Loc::getMessage('SEO_CAMPAIGN_ERROR_NO_NAME')
				));
			}
		}

		if($newCampaign || isset($data["SETTINGS"]["FIO"]))
		{
			$campaignParam["FIO"] = trim($data["SETTINGS"]["FIO"]);

			if($campaignParam["FIO"] == '')
			{
				$result->addError(new Entity\FieldError(
					static::getEntity()->getField('SETTINGS'),
					Loc::getMessage('SEO_CAMPAIGN_ERROR_NO_FIO')
				));
			}
		}

		if(is_array($data["SETTINGS"]) && array_key_exists("StartDate", $data["SETTINGS"]))
		{
			if(is_a($data["SETTINGS"]["StartDate"], "Bitrix\\Main\\Type\\Date"))
			{
				$campaignParam["StartDate"] = $data["SETTINGS"]["StartDate"]->convertFormatToPhp("Y-m-d");
			}
			elseif(is_string($data["SETTINGS"]["StartDate"]))
			{
				if(preg_match("/^\\d{4}-\\d{2}-\\d{2}$/", $data["SETTINGS"]["StartDate"]))
				{
					$campaignParam["StartDate"] = $data["SETTINGS"]["StartDate"];
				}
				else
				{
					$ts = MakeTimeStamp($data["SETTINGS"]["StartDate"], FORMAT_DATE);
					if($ts > 0)
					{
						$campaignParam["StartDate"] = date('Y-m-d', $ts);
					}
				}
			}

			if(!$campaignParam["StartDate"])
			{
				$result->addError(new Entity\FieldError(
					static::getEntity()->getField('SETTINGS'),
					Loc::getMessage('SEO_CAMPAIGN_ERROR_NO_START_DATE')
				));
			}
		}

		if($newCampaign || isset($data["SETTINGS"]["Strategy"]))
		{
			if(
				empty($data["SETTINGS"]["Strategy"])
				|| !is_array($data["SETTINGS"]["Strategy"])
				|| empty($data["SETTINGS"]["Strategy"]["StrategyName"])
			)
			{
				$result->addError(new Entity\FieldError(
					static::getEntity()->getField('SETTINGS'),
					Loc::getMessage('SEO_CAMPAIGN_ERROR_NO_STRATEGY')
				));
			}

			if(array_key_exists($data["SETTINGS"]["Strategy"]["StrategyName"], self::$strategyConfig))
			{
				$strategy = $data["SETTINGS"]["Strategy"]["StrategyName"];
				$config = self::$strategyConfig[$strategy];

				$campaignParam["Strategy"] = array(
					"StrategyName" => $strategy,
				);

				foreach($data["SETTINGS"]["Strategy"] as $param => $value)
				{
					if($param !== "StrategyName")
					{
						if(array_key_exists($param, $config))
						{
							$campaignParam["Strategy"][$param] = $value;
						}
						else
						{
							$result->addError(new Entity\FieldError(
								static::getEntity()->getField('SETTINGS'),
								Loc::getMessage(
									'SEO_CAMPAIGN_ERROR_STRATEGY_PARAM_NOT_SUPPORTED',
									array(
										'#PARAM#' => $param,
										'#STRATEGY#' => $strategy,
									)
								)
							));
						}
					}
				}

				foreach($config as $key => $def)
				{
					if($def['mandatory'] || isset($campaignParam["Strategy"][$key]))
					{
						switch($def['type'])
						{
							case 'int':
								$campaignParam["Strategy"][$key] = intval($campaignParam["Strategy"][$key]);
							break;
							case 'float':
								$campaignParam["Strategy"][$key] = doubleval($campaignParam["Strategy"][$key]);
							break;
						}

						if(!$def['mandatory'] && empty($campaignParam["Strategy"][$key]))
						{
							unset($campaignParam["Strategy"][$key]);
						}
					}

					if($def['mandatory'] && empty($campaignParam["Strategy"][$key]))
					{
						$result->addError(new Entity\FieldError(
							static::getEntity()->getField('SETTINGS'),
							Loc::getMessage(
								'SEO_CAMPAIGN_ERROR_STRATEGY_PARAM_MANDATORY',
								array(
									'#PARAM#' => Loc::getMessage('SEO_CAMPAIGN_STRATEGY_PARAM_'.ToUpper($key)),
									'#STRATEGY#' => Loc::getMessage('SEO_CAMPAIGN_STRATEGY_'.$strategy),
								)
							)
						));
					}
				}
			}
			else
			{
				$result->addError(new Entity\FieldError(
					static::getEntity()->getField('SETTINGS'),
					Loc::getMessage(
						'SEO_CAMPAIGN_ERROR_STRATEGY_NOT_SUPPORTED',
						array(
							'#STRATEGY#' => $data["SETTINGS"]["Strategy"]["StrategyName"],
						)
					)
				));
			}
		}

		if($newCampaign || !empty($data["SETTINGS"]["EmailNotification"]))
		{
			if(
				empty($data["SETTINGS"]["EmailNotification"])
				|| !is_array($data["SETTINGS"]["EmailNotification"])
				|| !check_email($data["SETTINGS"]["EmailNotification"]['Email'])
			)
			{
				$result->addError(new Entity\FieldError(
					static::getEntity()->getField('SETTINGS'),
					Loc::getMessage('SEO_CAMPAIGN_ERROR_WRONG_EMAIL')
				));
			}

			$campaignParam["EmailNotification"] = array(
				"Email" => trim($data["SETTINGS"]["EmailNotification"]['Email']),
				"WarnPlaceInterval" => intval($data["SETTINGS"]["EmailNotification"]['WarnPlaceInterval']),
				"MoneyWarningValue" => intval($data["SETTINGS"]["EmailNotification"]['MoneyWarningValue']),
				"SendWarn" => intval($data["SETTINGS"]["EmailNotification"]['SendWarn']),
			);

			if($campaignParam["EmailNotification"]['SendWarn'] === true
				|| $campaignParam["EmailNotification"]['SendWarn'] === 1
				|| $campaignParam["EmailNotification"]['SendWarn'] === 'Y'
			)
			{
				$campaignParam["EmailNotification"]['SendWarn'] = Engine\YandexDirect::BOOL_YES;
			}

			if(
				$campaignParam["EmailNotification"]['SendWarn'] === false
				|| $campaignParam["EmailNotification"]['SendWarn'] === 0
				|| $campaignParam["EmailNotification"]['SendWarn'] === 'N'
			)
			{
				$campaignParam["EmailNotification"]['SendWarn'] = Engine\YandexDirect::BOOL_NO;
			}

			if(!in_array($campaignParam["EmailNotification"]["WarnPlaceInterval"], self::$allowedWarnPlaceIntervalValues))
			{
				if($campaignParam["EmailNotification"]['SendWarn'] == Engine\YandexDirect::BOOL_YES)
				{
					$result->addError(new Entity\FieldError(
						static::getEntity()->getField('SETTINGS'),
						Loc::getMessage(
							'SEO_CAMPAIGN_ERROR_WRONG_INTERVAL',
							array('#VALUES#' => implode(
								',', self::$allowedWarnPlaceIntervalValues
							))
						)
					));
				}
				else
				{
					$campaignParam["EmailNotification"]["WarnPlaceInterval"] = self::MONEY_WARN_PLACE_INTERVAL_DEFAULT;
				}
			}

			if(
				$campaignParam["EmailNotification"]["MoneyWarningValue"] < self::$allowedMoneyWarningInterval[0]
				|| $campaignParam["EmailNotification"]["MoneyWarningValue"] > self::$allowedMoneyWarningInterval[1]
			)
			{
				$result->addError(new Entity\FieldError(
					static::getEntity()->getField('SETTINGS'),
					Loc::getMessage(
						'SEO_CAMPAIGN_ERROR_WRONG_WARNING',
						array(
							'#MIN#' => self::$allowedMoneyWarningInterval[0],
							'#MAX#' => self::$allowedMoneyWarningInterval[1],
						)
					)
				));
			}
		}

		if($newCampaign || isset($data["SETTINGS"]["MinusKeywords"]))
		{
			if(!is_array($data["SETTINGS"]["MinusKeywords"]))
			{
				if($data["SETTINGS"]["MinusKeywords"] <> '')
				{
					$data["SETTINGS"]["MinusKeywords"] = array();
				}
				else
				{
					$data["SETTINGS"]["MinusKeywords"] = array($data["SETTINGS"]["MinusKeywords"]);
				}
			}

			$campaignParam["MinusKeywords"] = $data["SETTINGS"]["MinusKeywords"];
		}

		if(!$newCampaign && $result->getType() == Entity\EventResult::SUCCESS)
		{
			try
			{
				$yandexCampaignParam = $engine->getCampaign($data["XML_ID"]);

				if(!is_array($yandexCampaignParam) || count($yandexCampaignParam) <= 0)
				{
					$result->addError(new Entity\FieldError(
						static::getEntity()->getField('XML_ID'),
						Loc::getMessage(
							'SEO_CAMPAIGN_ERROR_CAMPAIGN_NOT_FOUND',
							array('#ID#' => $data["XML_ID"])
						)
					));
				}
				else
				{
					$campaignParam = array_replace_recursive($yandexCampaignParam[0], $campaignParam);
				}
			}
			catch(Engine\YandexDirectException $e)
			{
				$result->addError(
					new Entity\FieldError(
						static::getEntity()->getField('ENGINE_ID'),
						$e->getMessage(),
						$e->getCode()
					)
				);
			}
		}

		return $campaignParam;
	}
}