Your IP : 3.147.44.255


Current Path : /home/bitrix/ext_www/klimatlend.ua/bitrix/modules/conversion/lib/
Upload File :
Current File : /home/bitrix/ext_www/klimatlend.ua/bitrix/modules/conversion/lib/context.php

<?php

namespace Bitrix\Conversion;

use Bitrix\Main\DB;
use Bitrix\Main\Type\Date;
use Bitrix\Main\SystemException;
use Bitrix\Main\ArgumentTypeException;

/** @internal */
class Context
{
	const EMPTY_CONTEXT_ID = 0; // Context with no attributes.

	protected $id = null;
	protected $attributes = array();

	/** Add value to counter. If counter not exists set counter to value. Save to database.
	 * @param Date      $day   - counter date
	 * @param string    $name  - counter name
	 * @param int|float $value - number to add
	 * @throws ArgumentTypeException
	 * @throws SystemException
	 */
	public function addCounter(Date $day, $name, $value)
	{
		if (! is_string($name))
			throw new ArgumentTypeException('name', 'string');

		if (! is_numeric($value))
			throw new ArgumentTypeException('value', 'numeric');

		if (($id = $this->id) === null)
			throw new SystemException('Cannot add counter without context!');

		// save to database

		$primary = array(
			'DAY'        => $day,
			'CONTEXT_ID' => $id,
			'NAME'       => $name
		);

		$data = array('VALUE' => new DB\SqlExpression('?# + ?f', 'VALUE', $value));

		$result = Internals\ContextCounterDayTable::update($primary, $data);

		if ($result->getAffectedRowsCount() === 0)
		{
			try
			{
				$result = Internals\ContextCounterDayTable::add($primary + array('VALUE' => $value));
			}
			catch (DB\SqlQueryException $e)
			{
				$result = Internals\ContextCounterDayTable::update($primary, $data);
			}
		}

		$result->isSuccess(); // TODO isSuccess
	}

	/** Set attribute with value.
	 * @param string                $name  - attribute name
	 * @param string|int|float|null $value - attribute value
	 * @throws ArgumentTypeException
	 * @throws SystemException
	 */
	public function setAttribute($name, $value = null)
	{
		if (! is_string($name))
			throw new ArgumentTypeException('name', 'string');

		if (! (is_scalar($value) || is_null($value)))
			throw new ArgumentTypeException('name', 'scalar');

		if ($this->id !== null)
			throw new SystemException('Cannot set attribute for existent context!');

		$this->attributes[$name.':'.$value] = array('NAME' => $name, 'VALUE' => $value);
	}

	/** Save context & attributes to database */
	protected function save()
	{
		if (($id =& $this->id) !== null)
			throw new SystemException('Cannot save existent context!');

		// save to database

		$id = self::EMPTY_CONTEXT_ID;

		if ($attributes = $this->attributes)
		{
			$snapshot = self::getSnapshot($attributes);

			$query = array(
				'limit'  => 1,
				'select' => array('ID'),
				'filter' => array('=SNAPSHOT' => $snapshot),
			);

			if ($row = Internals\ContextTable::getList($query)->fetch())
			{
				$id = (int) $row['ID'];
			}
			else
			{
				try
				{
					$result = Internals\ContextTable::add(array('SNAPSHOT' => $snapshot));

					if ($result->isSuccess())
					{
						$id = $result->getId();

						foreach ($attributes as $attribute)
						{
							// TODO resetContext if not success and return null!!!
							$result = Internals\ContextAttributeTable::add(array(
								'CONTEXT_ID' => $id,
								'NAME'       => $attribute['NAME'],
								'VALUE'      => $attribute['VALUE'],
							));
						}
					}
					else
					{
						throw new DB\SqlQueryException();
					}
				}
				catch (DB\SqlQueryException $e)
				{
					if ($row = Internals\ContextTable::getList($query)->fetch())
					{
						$id = (int) $row['ID'];
					}
				}
			}
		}
	}

	private static function getSnapshot(array $attributes)
	{
		$keys = array_keys($attributes);
		sort($keys);

		$str1 = implode(';', $keys);
		$str2 = strrev($str1);

		return md5($str1).md5($str2);
	}
}