%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/bitrix/www/bitrix/modules/lists/classes/general/
Upload File :
Create Path :
Current File : //home/bitrix/www/bitrix/modules/lists/classes/general/listfield.php

<?
IncludeModuleLangFile(__FILE__);

use Bitrix\Main\ArgumentException;
use Bitrix\Main\NotSupportedException;

abstract class CListField
{
	/** @var int */
	protected $_iblock_id;
	/** @var  string */
	protected $_field_id;
	/** @var  string */
	protected $_label;
	/** @var CListFieldType */
	protected $_type;
	/** @var int */
	protected $_sort;

	private static $prop_cache = array();

	public function __construct($iblock_id, $field_id, $label, $sort)
	{
		global $DB;

		$this->_iblock_id = intval($iblock_id);
		$this->_field_id = $field_id;
		$this->_label = $label;
		$this->_sort = intval($sort);

		if($this->_iblock_id > 0 && strlen($this->_field_id))
		{
			$arField = $this->_read_from_cache($this->_field_id);
			if(!$arField)
			{
				$DB->Add("b_lists_field", array(
					"ID" => 1, //This makes Oracle version happy
					"IBLOCK_ID" => $this->_iblock_id,
					"FIELD_ID" => $this->_field_id,
					"SORT" => $this->_sort,
					"NAME" => $this->_label,
				));
				$this->_clear_cache();
			}
			elseif(
				$arField["SORT"] != $this->_sort
				|| $arField["NAME"] != $this->_label
			)
			{
				$DB->Query("
					UPDATE b_lists_field
					SET SORT = ".$this->_sort."
					,NAME = '".$DB->ForSQL($this->_label)."'
					WHERE IBLOCK_ID = ".$this->_iblock_id."
					AND FIELD_ID = '".$DB->ForSQL($this->_field_id)."'
				", false, "File: ".__FILE__."<br>Line: ".__LINE__);
				$this->_clear_cache();
			}
		}
	}

	private function _read_from_cache($field_id)
	{
		global $DB;

		if($this->_iblock_id > 0 && !isset(self::$prop_cache[$this->_iblock_id]))
		{
			$rsFields = $DB->Query("
				SELECT * FROM b_lists_field
				WHERE IBLOCK_ID = ".$this->_iblock_id."
			", false, "File: ".__FILE__."<br>Line: ".__LINE__);

			self::$prop_cache[$this->_iblock_id] = array();
			while($arField = $rsFields->Fetch())
				self::$prop_cache[$this->_iblock_id][$arField["FIELD_ID"]] = $arField;
		}

		if(isset(self::$prop_cache[$this->_iblock_id][$field_id]))
			return self::$prop_cache[$this->_iblock_id][$field_id];
		else
			return false;
	}

	private function _clear_cache()
	{
		if(isset(self::$prop_cache[$this->_iblock_id]))
			unset(self::$prop_cache[$this->_iblock_id]);
	}

	public function GetID()
	{
		return $this->_field_id;
	}

	public function GetLabel()
	{
		return $this->_label;
	}

	public function GetTypeID()
	{
		return $this->_type->GetID();
	}

	public function IsReadOnly()
	{
		return $this->_type->IsReadonly();
	}

	public function GetSort()
	{
		return $this->_sort;
	}

	public function GetSettingsDefaults()
	{
		switch($this->_field_id)
		{
		case "PREVIEW_TEXT":
			return array(
				"USE_EDITOR" => "N",
				"WIDTH" => "40",
				"HEIGHT" => "3",
			);
		default:
			return false;
		}
	}

	public function GetSettings()
	{
		$arField = $this->_read_from_cache($this->_field_id);
		if($arField)
		{
			$res = unserialize($arField["SETTINGS"]);
			if(is_array($res))
				return $res;
		}
		return $this->GetSettingsDefaults();
	}

	public function SetSettings($arSettings)
	{
		global $DB;

		$arStore = false;
		switch($this->_field_id)
		{
			case "PREVIEW_TEXT":
				if(preg_match('/\s*(\d+)\s*(px|%|)/', $arSettings["WIDTH"], $match) && ($match[1] > 0))
					$width = $match[1].$match[2];
				else
					$width = "40";

				if(preg_match('/\s*(\d+)\s*(px|%|)/', $arSettings["HEIGHT"], $match) && ($match[1] > 0))
					$height = $match[1].$match[2];
				else
					$height = "3";

				$arStore = array(
					"USE_EDITOR" => $arSettings["USE_EDITOR"]=="Y"? "Y": "N",
					"WIDTH" => $width,
					"HEIGHT" => $height,
					"SHOW_ADD_FORM" => $arSettings["SHOW_ADD_FORM"],
					"SHOW_EDIT_FORM" => $arSettings["SHOW_EDIT_FORM"],
					"ADD_READ_ONLY_FIELD" => $arSettings["ADD_READ_ONLY_FIELD"],
					"EDIT_READ_ONLY_FIELD" => $arSettings["EDIT_READ_ONLY_FIELD"],
					"SHOW_FIELD_PREVIEW" => $arSettings["SHOW_FIELD_PREVIEW"]
				);
				break;
			default:
				$arStore = $arSettings;
		}

		$arFields = array();
		if(is_array($arStore))
			$arFields["SETTINGS"] = serialize($arStore);
		else
			$arFields["SETTINGS"] = false;

		$strUpdate = $DB->PrepareUpdate("b_lists_field", $arFields);
		if($strUpdate!="")
		{
			$strSql = "
				UPDATE b_lists_field
				SET ".$strUpdate."
				WHERE IBLOCK_ID = ".$this->_iblock_id."
				AND FIELD_ID = '".$DB->ForSQL($this->_field_id)."'
			";
			$arBinds = array(
				"SETTINGS" => $arFields["SETTINGS"],
			);
			$DB->QueryBind($strSql, $arBinds);

			$this->_clear_cache();
		}
	}

	abstract public function IsRequired();
	abstract public function IsMultiple();
	abstract public function GetDefaultValue();
	abstract public function SetSort($sort);
	abstract public function GetArray();

	public function Delete()
	{
		global $DB;
		$DB->Query("
			DELETE FROM b_lists_field
			WHERE IBLOCK_ID = ".$this->_iblock_id."
			AND FIELD_ID = '".$DB->ForSQL($this->_field_id)."'
		", false, "File: ".__FILE__."<br>Line: ".__LINE__);
	}

	abstract public function Update($arFields);
	static public function Add($iblock_id, $arFields)
	{
	}
}

class CListElementField extends CListField
{
	private $_iblock_field;

	public function __construct($iblock_id, $field_id, $label, $sort)
	{
		parent::__construct($iblock_id, $field_id, $label, $sort);

		$this->_type = CListFieldTypeList::GetByID($field_id);

		if($this->_iblock_id > 0)
			$arIBlockFields = CIBlock::GetArrayByID($this->_iblock_id, "FIELDS");
		else
			$arIBlockFields = CIBlock::GetFieldsDefaults();

		$this->_iblock_field = $arIBlockFields[$field_id];
	}

	public function IsRequired()
	{
		return $this->_iblock_field["IS_REQUIRED"] == "Y";
	}

	public function IsMultiple()
	{
		return false;
	}

	public function GetDefaultValue()
	{
		return $this->_iblock_field["DEFAULT_VALUE"];
	}

	public function SetSort($sort)
	{
		$this->_sort = intval($sort);
	}

	//This is only backward compatibility method
	public function GetArray()
	{
		return array(
			"FIELD_ID" => $this->_field_id,
			"SORT" => $this->_sort,
			"NAME" => $this->_label,
			"IS_REQUIRED" => $this->_iblock_field["IS_REQUIRED"],
			"MULTIPLE" => "N",
			"DEFAULT_VALUE" => $this->_iblock_field["DEFAULT_VALUE"],
			"TYPE" => $this->GetTypeID(),
			"PROPERTY_TYPE" => false,
			"PROPERTY_USER_TYPE" => false,
			"SETTINGS" => $this->GetSettings(),
		);
	}

	public function Delete()
	{
		/** @global CStackCacheManager $stackCacheManager */
		global $stackCacheManager;
		if($this->_iblock_field["IS_REQUIRED"] == "Y")
		{
			if($this->_iblock_id > 0)
			{
				$arIBlockFields = CIBlock::GetArrayByID($this->_iblock_id, "FIELDS");
				$arIBlockFields[$this->_field_id]["IS_REQUIRED"] = "N";
				CIBlock::SetFields($this->_iblock_id, $arIBlockFields);
				$stackCacheManager->Clear("b_iblock");
			}
			$this->_iblock_field["IS_REQUIRED"] = "N";
		}

		parent::Delete();
		return true;
	}

	public function Update($arFields)
	{
		/** @global CStackCacheManager $stackCacheManager */
		global $stackCacheManager;
		if(isset($arFields["TYPE"]))
			$newType = $arFields["TYPE"];
		else
			$newType = $this->GetTypeID();

		if($this->_iblock_id > 0 && CListFieldTypeList::IsField($newType))
		{
			$arIBlockFields = CIBlock::GetArrayByID($this->_iblock_id, "FIELDS");
			$arIBlockFields[$newType] = $arFields;
			CIBlock::SetFields($this->_iblock_id, $arIBlockFields);
			$stackCacheManager->Clear("b_iblock");

			if($newType != $this->GetTypeID())
				$this->Delete();

			return new CListElementField($this->_iblock_id, $newType, $arFields["NAME"], $arFields["SORT"]);
		}

		return null;
	}

	static public function Add($iblock_id, $arFields)
	{
		/** @global CStackCacheManager $stackCacheManager */
		global $stackCacheManager;
		if($iblock_id > 0)
		{
			$arIBlockFields = CIBlock::GetArrayByID($iblock_id, "FIELDS");
			$arIBlockFields[$arFields["TYPE"]] = $arFields;
			CIBlock::SetFields($iblock_id, $arIBlockFields);
			$stackCacheManager->Clear("b_iblock");
		}
		return new CListElementField($iblock_id, $arFields["TYPE"], $arFields["NAME"], $arFields["SORT"]);
	}
}

class CListPropertyField extends CListField
{
	private $_property = false;
	private static $prop_cache = array();

	public function __construct($iblock_id, $field_id, $label, $sort)
	{
		parent::__construct($iblock_id, $field_id, $label, $sort);

		if(preg_match("/^PROPERTY_(\\d+)$/", $field_id, $match))
		{
			$this->_property = $this->getPropertyArrayFromCache($match[1]);
		}

		if ($this->_property)
		{
			if($this->_property["USER_TYPE"])
				$this->_type = CListFieldTypeList::GetByID($this->_property["PROPERTY_TYPE"].":".$this->_property["USER_TYPE"]);
			else
				$this->_type = CListFieldTypeList::GetByID($this->_property["PROPERTY_TYPE"]);
		}

		if(!is_object($this->_type))
			$this->_type = CListFieldTypeList::GetByID("S");
	}

	private function getPropertyArrayFromCache($id)
	{
		//Cache iblock metadata in order to reduce queries
		if(!array_key_exists($this->_iblock_id, self::$prop_cache))
		{
			self::$prop_cache[$this->_iblock_id] = array();

			$rsProperties = CIBlockProperty::GetList(array(), array(
				"IBLOCK_ID" => $this->_iblock_id,
				"CHECK_PERMISSIONS" => "N",
				"ACTIVE" => "Y",
			));
			while($arProperty = $rsProperties->Fetch())
				self::$prop_cache[$this->_iblock_id][$arProperty["ID"]] = $arProperty;
		}
		return self::$prop_cache[$this->_iblock_id][$id];
	}

	private static function resetPropertyArrayCache()
	{
		self::$prop_cache = array();
	}

	public function IsRequired()
	{
		return is_array($this->_property) && $this->_property["IS_REQUIRED"] == "Y";
	}

	public function IsMultiple()
	{
		return is_array($this->_property) && $this->_property["MULTIPLE"] == "Y";
	}

	public function GetDefaultValue()
	{
		return is_array($this->_property) && $this->_property["DEFAULT_VALUE"];
	}

	public function SetSort($sort)
	{
		if(is_array($this->_property))
		{
			$old_sort = intval($this->_property["SORT"]);
			$new_sort = intval($sort);

			if($old_sort != $new_sort)
			{
				$this->_property["SORT"] = $new_sort;
				$obProperty = new CIBlockProperty;
				$obProperty->Update($this->_property["ID"], $this->_property);
				$this->_sort = $new_sort;
			}
		}
	}

	//This is only backward compatibility method
	public function GetArray()
	{
		if(is_array($this->_property))
		{
			return array(
				"FIELD_ID" => $this->_field_id,
				"SORT" => $this->_sort,
				"NAME" => $this->_property["NAME"],
				"IS_REQUIRED" => $this->_property["IS_REQUIRED"],
				"MULTIPLE" => $this->_property["MULTIPLE"],
				"DEFAULT_VALUE" => $this->_property["DEFAULT_VALUE"],
				"TYPE" => $this->GetTypeID(),
				"PROPERTY_TYPE" => $this->_property["PROPERTY_TYPE"],
				"PROPERTY_USER_TYPE" => $this->_property["USER_TYPE"]? CIBlockProperty::GetUserType($this->_property["USER_TYPE"]): false,
				"CODE" => $this->_property["CODE"],
				"ID" => $this->_property["ID"],
				"LINK_IBLOCK_ID" => $this->_property["LINK_IBLOCK_ID"],
				"ROW_COUNT" =>  $this->_property["ROW_COUNT"],
				"COL_COUNT" =>  $this->_property["COL_COUNT"],
				"USER_TYPE_SETTINGS" => $this->_property["USER_TYPE_SETTINGS"],
				"SETTINGS" => $this->GetSettings(),
			);
		}
		else
		{
			return false;
		}
	}

	public function Delete()
	{
		if(is_array($this->_property))
		{
			$obProperty = new CIBlockProperty;
			if($obProperty->Delete($this->_property["ID"]))
			{
				$this->resetPropertyArrayCache();
				$this->_property = false;
			}
		}

		parent::Delete();
		return true;
	}

	private static function generatePropertyCode($name, $code, $iblockId, $propertyId = 0)
	{
		if(empty($code))
		{
			$code = CUtil::translit($name, LANGUAGE_ID, array("change_case" => "U"));
		}

		$object = CIBlockProperty::getList(array(), array("IBLOCK_ID" => $iblockId));
		while($property = $object->fetch())
		{
			if($property["CODE"] == $code && $property["ID"] != $propertyId)
			{
				$code = $code.'_'.CLists::generateMnemonicCode();
				break;
			}
		}

		return $code;
	}

	public function Update($arFields)
	{
		if(isset($arFields["TYPE"]))
			$newType = $arFields["TYPE"];
		else
			$newType = $this->GetTypeID();

		if(is_array($this->_property) && !CListFieldTypeList::IsField($newType))
		{
			if (self::existPropertyCode($this->_iblock_id, $arFields["CODE"], $this->_property["ID"]))
			{
				throw new NotSupportedException(GetMessage("LIST_PROPERTY_FIELD_DUPLICATE_CODE"));
			}

			foreach($this->GetArray() as $id => $val)
				if(array_key_exists($id, $arFields) && $id != "IBLOCK_ID")
					$this->_property[$id] = $arFields[$id];

			if(strpos($newType, ":")!==false)
				list($this->_property["PROPERTY_TYPE"], $this->_property["USER_TYPE"]) = explode(":", $newType);
			else
			{
				$this->_property["PROPERTY_TYPE"] = $newType;
				$this->_property["USER_TYPE"] = "";
			}

			$this->_property["CHECK_PERMISSIONS"] = "N";
			$this->_property["ACTIVE"] = "Y";

			$obProperty = new CIBlockProperty;
			if($obProperty->Update($this->_property["ID"], $this->_property))
			{
				self::resetPropertyArrayCache();

				if($this->_property["PROPERTY_TYPE"] == "L" && is_array($arFields["LIST"]))
					CList::UpdatePropertyList($this->_property["ID"], $arFields["LIST"]);

				return new CListPropertyField($this->_property["IBLOCK_ID"], "PROPERTY_".$this->_property["ID"], $arFields["NAME"], $arFields["SORT"]);
			}
			elseif (!empty($obProperty->LAST_ERROR))
			{
				throw new ArgumentException($obProperty->LAST_ERROR);
			}
		}

		return null;
	}

	static public function Add($iblock_id, $arFields)
	{
		if($iblock_id > 0)
		{
			if (self::existPropertyCode($iblock_id, $arFields["CODE"]))
			{
				throw new NotSupportedException(GetMessage("LIST_PROPERTY_FIELD_DUPLICATE_CODE"));
			}
			$property_id = intval($arFields["ID"]);
			if($property_id > 0)
			{
				return new CListPropertyField($iblock_id, "PROPERTY_".$property_id, $arFields["NAME"], $arFields["SORT"]);
			}
			else
			{
				$arFields["IBLOCK_ID"] = $iblock_id;
				if(strpos($arFields["TYPE"], ":")!==false)
					list($arFields["PROPERTY_TYPE"], $arFields["USER_TYPE"]) = explode(":", $arFields["TYPE"]);
				else
					$arFields["PROPERTY_TYPE"] = $arFields["TYPE"];
				$arFields["MULTIPLE_CNT"] = 1;
				$arFields["CHECK_PERMISSIONS"] = "N";

				$obProperty = new CIBlockProperty;
				$res = $obProperty->Add($arFields);
				if (!empty($obProperty->LAST_ERROR))
				{
					throw new ArgumentException($obProperty->LAST_ERROR);
				}
				if($res)
				{
					self::resetPropertyArrayCache();

					if($arFields["PROPERTY_TYPE"] == "L" && is_array($arFields["LIST"]))
						CList::UpdatePropertyList($res, $arFields["LIST"]);

					return new CListPropertyField($iblock_id, "PROPERTY_".$res, $arFields["NAME"], $arFields["SORT"]);
				}
			}
		}
		return null;
	}

	private static function existPropertyCode($iblockId, $code, $propertyId = 0)
	{
		$iblockId = intval($iblockId);
		if (!$iblockId)
		{
			throw new ArgumentException("Required parameter \"iblockId\" is missing.");
		}
		if (empty($code))
		{
			return false;
		}

		$queryObject = \CIBlockProperty::getList(array(), array("IBLOCK_ID" => $iblockId, "CODE" => $code));
		$property = $queryObject->fetch();

		if (!empty($property) && is_array($property))
		{
			return $property["ID"] != $propertyId;
		}
		else
		{
			return false;
		}
	}
}
?>

Zerion Mini Shell 1.0