Your IP : 18.216.234.123


Current Path : /home/bitrix/ext_www/crm.klimatlend.ua/bitrix/modules/tasks/lib/
Upload File :
Current File : /home/bitrix/ext_www/crm.klimatlend.ua/bitrix/modules/tasks/lib/manager.php

<?
/**
 * Bitrix Framework
 * @package bitrix
 * @subpackage sale
 * @copyright 2001-2015 Bitrix
 * 
 * @access private
 *
 * THIS IS AN EXPERIMENTAL CLASS, DONT EXTEND
 *
 * This class should be used in components, inside agent functions, in rest, ajax and more, bringing unification to all places and processes.
 *
 */

namespace Bitrix\Tasks;

use \Bitrix\Main\Localization\Loc;

use \Bitrix\Tasks\Util\Error\Collection;

Loc::loadMessages(__FILE__);

abstract class Manager
{
	const SE_PREFIX = 		'SE_'; // sub-entity prefix
    const ACT_KEY =         'ACTION'; // reserved key to keep allowed action map

	const MODE_ADD = 		0x01;
	const MODE_UPDATE = 	0x02;

	public static function getIsMultiple()
	{
		return false;
	}

	public static function getCode($prefix = false)
	{
		$class = explode('\\', (string) get_called_class());
		if(empty($class) && empty($class[count($class) - 1]))
		{
			throw new \Bitrix\Main\SystemException('Cannot identify sub-entity code');
		}

		return ($prefix ? static::SE_PREFIX : '').ToUpper($class[count($class) - 1]);
	}

	protected static function getTask($userId, $taskId)
	{
		// on the same $userId and $taskId this will return the same task instance from cache
		return \CTaskItem::getInstance($taskId, $userId);
	}

	protected static function ensureHaveErrorCollection(&$parameters)
	{
		if(!is_object($parameters['ERRORS']))
		{
			$parameters['ERRORS'] = new Collection();
		}

		return $parameters['ERRORS'];
	}

	protected static function filterData(array $data, array $fieldMap, Collection $errors)
	{
		// READ, WRITE, SORT, FILTER, DATE

		foreach($data as $field => $value)
		{
			$start = mb_substr($field, 0, 3);
			if($start == 'UF_' || $start == static::SE_PREFIX) // we have no other fields that start from SE_ or UF_, so allow
			{
				continue;
			}

			if(!isset($fieldMap[$field]))
			{
				$errors->add('UNKNOWN_FIELD', 'Unknown field given: "'.$field.'"', Collection::TYPE_FATAL, array('FIELD' => $field));
			}
			elseif(!$fieldMap[$field][1]) // WRITE
			{
				$errors->add('FIELD_NOT_ALLOWED', 'Field is not allowed to write: "'.$field.'"', Collection::TYPE_FATAL, array('FIELD' => $field));
			}
		}

		return $data;
	}

	protected static function makeDeltaSets(array $items, array $currentItemsData)
	{
		$toAdd = array();
		$toUpdate = array();
		$toDelete = array();

		foreach($items as $id => $item)
		{
			if(isset($currentItemsData[$id]))
			{
				if(static::detectItemChanged($currentItemsData[$id], $items[$id]))
				{
					$toUpdate[$id] = true;
				}
			}
			else
			{
				$toAdd[$id] = true;
			}
		}

		foreach($currentItemsData as $id => $item)
		{
			if(!isset($items[$id]))
			{
				$toDelete[$id] = true;
			}
		}

		return array(array_keys($toAdd), array_keys($toUpdate), array_keys($toDelete));
	}

	protected static function detectItemChanged(array $itemThen, array $itemNow)
	{
		$changed = false;
		foreach($itemNow as $fld => $value)
		{
			if(!isset($itemThen[$fld]) || ((string) $itemThen[$fld] != (string) $itemNow[$fld]))
			{
				$changed = true;
				break;
			}
		}

		return $changed;
	}

	// permission check

	protected static function ensureCanUpdate(array $toUpdateItems, array $currentItems, Collection $errors, $itemName = '')
	{
		$inoperable = static::getItemsInoperable($toUpdateItems, $currentItems, array('MODIFY', 'EDIT'));
		if(!empty($inoperable))
		{
			if((string) $itemName == '')
			{
				$itemName = Loc::getMessage('TASKS_MANAGER_TASK_ITEM_NAME');
			}
			$errorMessage = str_replace('#ITEM_NAME#', $itemName, Loc::getMessage('TASKS_MANAGER_TASK_CANT_UPDATE'));

			foreach($inoperable as $itemId)
			{
				$errors->add('UPDATE_PERMISSION_DENIED', str_replace('#ID#', $itemId, $errorMessage), Collection::TYPE_FATAL, array('DATA' => array('ID' => $itemId)));
			}
		}
	}

	protected static function ensureCanDelete(array $toDeleteItems, array $currentItems, Collection $errors, $itemName = '')
	{
		$inoperable = static::getItemsInoperable($toDeleteItems, $currentItems, array('DELETE', 'REMOVE'));
		if(!empty($inoperable))
		{
			if((string) $itemName == '')
			{
				$itemName = Loc::getMessage('TASKS_MANAGER_TASK_ITEM_NAME');
			}
			$errorMessage = str_replace('#ITEM_NAME#', $itemName, Loc::getMessage('TASKS_MANAGER_TASK_CANT_DELETE'));

			foreach($inoperable as $itemId)
			{
				$errors->add('DELETE_PERMISSION_DENIED', str_replace('#ID#', $itemId, $errorMessage), Collection::TYPE_FATAL, array('DATA' => array('ID' => $itemId)));
			}
		}
	}

	protected static function getItemsInoperable(array $toActionItems, array $currentItems, array $actions)
	{
		$inoperable = array();
		foreach($toActionItems as $itemId)
		{
			if(isset($currentItems['DATA'][$itemId]))
			{
				$canDo = false;
				foreach($actions as $action)
				{
					if(static::checkCanDoOnItem($currentItems['CAN'][$itemId], $action))
					{
						$canDo = true;
						break;
					}
				}

				if(!$canDo)
				{
					$inoperable[$itemId] = true;
				}
			}
		}

		return array_keys($inoperable);
	}

	private static function checkCanDoOnItem(array $itemCan, $op)
	{
		if(!is_array($itemCan['ACTION']) || empty($itemCan['ACTION']))
		{
			return true; // no rights declaration, then yes
		}

		if(!isset($itemCan['ACTION'][$op]))
		{
			return false; // declaration array is present, but no such operation, then false
		}

		return !!$itemCan['ACTION'][$op];
	}

	protected static function checkCanReadTaskThrowException($userId, $taskId)
	{
		$task = static::getTask($userId, $taskId);
		if(!$task->checkCanRead(array('CHECK_BY_DATA_FETCH' => true)))
		{
			throw new \Bitrix\Tasks\AccessDeniedException();
		}
	}

	protected static function checkSetPassed(array $set, $mode)
	{
		if($mode == static::MODE_UPDATE)
		{
			return is_array($set); // only is_array(), because empty array is also a legal value
		}
		else
		{
			return is_array($set) && !empty($set); // in "add" mode set should not be empty, or else nothing to do
		}
	}

	protected static function indexItemSets(array $set)
	{
		$indexed = array();
		$i = 0;
		foreach($set as $item)
		{
			if (!is_array($item))
			{
				continue;
			}

			$pIndex = static::extractPrimaryIndex($item);
			if((string) $pIndex == '' || $pIndex == '0')
			{
				$pIndex = 'n'.($i++);
			}

			$indexed[$pIndex] = $item;
		}

		return $indexed;
	}

	protected static function extractPrimaryIndex(array $data)
	{
		return $data['ID'];
	}

	protected static function checkIsSubEntityKey($key)
	{
		$key = trim($key);
		if((string) $key == '')
		{
			return false;
		}

		if(mb_strpos($key, static::SE_PREFIX) === 0)
		{
			$key = mb_substr($key, mb_strlen(static::SE_PREFIX), mb_strlen($key) - mb_strlen(static::SE_PREFIX));
			$legal = array_flip(static::getLegalSubEntities());

			return isset($legal[$key]) ? $key : false;
		}

		return false;
	}

	// default merge function
	public static function mergeData($primary = array(), $secondary = array())
	{
		return $primary; // no merge by default
	}

	// default normalize function
	public static function normalizeData($data)
	{
		if(static::getIsMultiple())
		{
			return \Bitrix\Tasks\Util\Type::normalizeArray($data);
		}

		return $data;
	}

	public static function extractPrimaryIndexes($data)
	{
		$result = array();

		if(static::getIsMultiple())
		{
			if(is_array($data))
			{
				foreach($data as $item)
				{
					$result[] = static::extractPrimaryIndex($item);
				}
			}
		}
		else
		{
			$result[] = static::extractPrimaryIndex($data);
		}

		return $result;
	}

	protected static function getLegalSubEntities()
	{
		return array();
	}

	protected static function stripSubEntityData(array $data)
	{
		foreach($data as $k => $v)
		{
			if(static::checkIsSubEntityKey($k))
			{
				unset($data[$k]);
			}
		}

		return $data;
	}
}