<?php

defined('HOSTCMS') || exit('HostCMS: access denied.');

/**
 * Properties.
 *
 * @package HostCMS 6\Property
 * @version 6.x
 * @author Hostmake LLC
 * @copyright © 2005-2013 ООО "Хостмэйк" (Hostmake LLC), http://www.hostcms.ru
 */
class Property_Model extends Core_Entity
{
	/**
	 * Model name
	 * @var mixed
	 */
	protected $_modelName = 'property';

	/**
	 * Backend property
	 * @var int
	 */
	public $img = 1;

	/**
	 * Belongs to relations
	 * @var array
	 */
	protected $_belongsTo = array(
		'property_dir' => array(),
		'list' => array(),
		'informationsystem' => array(),
		'user' => array()
	);

	/**
	 * One-to-many or many-to-many relations
	 * @var array
	 */
	protected $_hasMany = array(
		'property_value_int' => array(),
		'property_value_float' => array(),
		'property_value_string' => array(),
		'property_value_text' => array(),
		'property_value_datetime' => array(),
		'property_value_file' => array()
	);

	/**
	 * One-to-one relations
	 * @var array
	 */
	protected $_hasOne = array(
		'structure_property' => array(),
		'siteuser_property' => array(),
		'informationsystem_item_property' => array(),
		'informationsystem_group_property' => array(),
		'shop_item_property' => array(),
		'shop_group_property' => array(),
		'shop_order_property' => array()
	);

	/**
	 * Default sorting for models
	 * @var array
	 */
	protected $_sorting = array(
		'properties.sorting' => 'ASC'
	);

	/**
	 * List of preloaded values
	 * @var array
	 */
	protected $_preloadValues = array(
		'list_id' => 0,
		'informationsystem_id' => 0,
		'type' => 0,
		'description' => '',
		'tag_name' => '',
		'image_large_max_width' => 300,
		'image_large_max_height' => 300,
		'image_small_max_width' => 70,
		'image_small_max_height' => 70,
		'default_value' => '',
		'hide_small_image' => 0,
		'sorting' => 0,
		'multiple' => 1
	);

	/**
	 * Constructor.
	 * @param int $id entity ID
	 */
	public function __construct($id = NULL)
	{
		parent::__construct($id);

		if (is_null($id))
		{
			$oUserCurrent = Core_Entity::factory('User', 0)->getCurrent();
			$this->_preloadValues['user_id'] = is_null($oUserCurrent) ? 0 : $oUserCurrent->id;
			$this->_preloadValues['guid'] = Core_Guid::get();
		}
	}

	/**
	 * Get all values for entity
	 * @param int $entityId entity id
	 * @param boolean $bCache cache mode
	 * @return array|NULL
	 */
	public function getValues($entityId, $bCache = TRUE)
	{
		if (is_null($this->type))
		{
			return array();
		}

		// Кэшировать и данные со значениями всех св-в были загружены
		if ($bCache && !is_null($this->_aAllValues))
		{
			if (isset($this->_aAllValues[$entityId]))
			{
				return $this->_aAllValues[$entityId];
			}
			return array();
		}

		return Property_Controller_Value::factory($this->type)
			->setProperty($this)
			->getValues($entityId, $bCache);
	}

	/**
	 * List of values for property
	 * @var array
	 */
	protected $_aAllValues = NULL;

	/**
	 * Load all values for property
	 * @return self
	 */
	public function loadAllValues()
	{
		if (is_null($this->_aAllValues))
		{
			$this->_aAllValues = array();

			$aPropertyValues = Property_Controller_Value::factory($this->type)
				->setProperty($this)
				->getPropertyValueObject()->findAll();

			foreach ($aPropertyValues as $oPropertyValue)
			{
				$this->_aAllValues[$oPropertyValue->entity_id][] = $oPropertyValue;
			}
		}

		return $this;
	}

	/**
	 * Получить значение свойства объекта по идентификатору $valueId в таблице значений
	 * @param $valueId идентифитор в таблице значений
	 * @return mixed object or NULL
	 */
	public function getValueById($valueId)
	{
		return Property_Controller_Value::factory($this->type)
			->setProperty($this)
			->getValueById($valueId);
	}

	/**
	 * Получить значение свойства объекта по значению в таблице значений
	 * @param string $value значение
	 * @param string $condition condition
	 * @return mixed array of objects or NULL
	 */
	public function getValuesByValue($value, $condition = '=')
	{
		return Property_Controller_Value::factory($this->type)
			->setProperty($this)
			->getValuesByValue($value, $condition);
	}

	/**
	 * Create new value for entity
	 * @param int $entityId entity id
	 * @return Property_Value_Model
	 */
	public function createNewValue($entityId)
	{
		return Property_Controller_Value::factory($this->type)
			->setProperty($this)
			->createNewValue($entityId);
	}

	/**
	 * Get property by guid
	 * @param string $guid guid
	 * @return Property_Model|NULL
	 */
	public function getByGuid($guid)
	{
		$this->queryBuilder()
			->where('guid', '=', $guid)
			->limit(1);

		$aObjects = $this->findAll(FALSE);

		return isset($aObjects[0]) ? $aObjects[0] : NULL;
	}

	/**
	 * Get property by tag name
	 * @param string $tag_name tag name
	 * @return Property_Model|NULL
	 */
	public function getByTagName($tag_name)
	{
		$this->queryBuilder()
			->where('tag_name', '=', $tag_name)
			->limit(1);

		$aObjects = $this->findAll();

		return isset($aObjects[0])
			? $aObjects[0]
			: NULL;
	}

	/**
	 * Delete object from database
	 * @param mixed $primaryKey primary key for deleting object
	 * @return Core_Entity
	 */
	public function delete($primaryKey = NULL)
	{
		if (is_null($primaryKey))
		{
			$primaryKey = $this->getPrimaryKey();
		}

		$this->id = $primaryKey;

		// Relations
		$this->Structure_Property->delete();
		$this->Informationsystem_Item_Property->delete();
		$this->Informationsystem_Group_Property->delete();
		$this->Shop_Item_Property->delete();
		$this->Shop_Group_Property->delete();
		$this->Shop_Order_Property->delete();
		Core::moduleIsActive('siteuser') && $this->Siteuser_Property->delete();

		$this->Property_Value_Ints->deleteAll(FALSE);
		$this->Property_Value_Floats->deleteAll(FALSE);
		$this->Property_Value_Strings->deleteAll(FALSE);
		$this->Property_Value_Texts->deleteAll(FALSE);
		$this->Property_Value_Datetimes->deleteAll(FALSE);
		$this->Property_Value_Files->deleteAll(FALSE);

		return parent::delete($primaryKey);
	}

	/**
	 * Copy property
	 * @param boolean $bCopyRelation Copy related entities
	 * @return Property_Model
	 */
	public function copy($bCopyRelation = TRUE)
	{
		$newObject = clone $this;
		//$newObject->name .= ' [Копия от ' . date('d.m.Y H:i:s') . ']';
		$newObject->save();

		if ($bCopyRelation)
		{
			if (Core::moduleIsActive('structure') && !is_null($this->Structure_Property->id))
			{
				$newObject->add(clone $this->Structure_Property);
			}
			elseif (Core::moduleIsActive('siteuser') && !is_null($this->Siteuser_Property->id))
			{
				$newObject->add(clone $this->Siteuser_Property);
			}
			elseif (Core::moduleIsActive('informationsystem') && !is_null($this->Informationsystem_Item_Property->id))
			{
				$newObject->add(clone $this->Informationsystem_Item_Property);
			}
			elseif (Core::moduleIsActive('informationsystem') && !is_null($this->Informationsystem_Group_Property->id))
			{
				$newObject->add(clone $this->Informationsystem_Group_Property);
			}
			elseif (Core::moduleIsActive('shop') && !is_null($this->Shop_Item_Property->id))
			{
				$newObject->add(clone $this->Shop_Item_Property);
			}
			elseif (Core::moduleIsActive('shop') && !is_null($this->Shop_Group_Property->id))
			{
				$newObject->add(clone $this->Shop_Group_Property);
			}
			elseif (Core::moduleIsActive('shop') && !is_null($this->Shop_Order_Property->id))
			{
				$newObject->add(clone $this->Shop_Order_Property);
			}
		}

		return $newObject;
	}

	/**
	 * Get XML for entity and children entities
	 * @return string
	 * @hostcms-event property_model.onBeforeRedeclaredGetXml
	 */
	public function getXml()
	{
		Core_Event::notify($this->_modelName . '.onBeforeRedeclaredGetXml', $this);

		$this->clearXmlTags();

		// List
		if ($this->type == 3 && $this->list_id != 0 && Core::moduleIsActive('list'))
		{
			$this
				->addEntity($this->List->clearEntities());

			$this->List->addEntities(
				$this->List->List_Items->getAllByActive(1)
			);
		}

		return parent::getXml();
	}
}