403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/catalog/lib/controller/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/catalog/lib/controller/productproperty.php
<?php

namespace Bitrix\Catalog\Controller;

use Bitrix\Catalog;
use Bitrix\Iblock\PropertyTable;
use Bitrix\Main\Engine\Response\DataType\Page;
use Bitrix\Main\Error;
use Bitrix\Main\Result;
use Bitrix\Main\UI\PageNavigation;

final class ProductProperty extends ProductPropertyBase
{
	use GetAction; // default getAction realization

	private const LIST_NAME = 'PRODUCT_PROPERTIES';

	private string $customUserType = '';

	protected function getServiceListName(): string
	{
		return self::LIST_NAME;
	}

	// region Actions

	/**
	 * @return array
	 */
	public function getFieldsAction(): array
	{
		return [$this->getServiceItemName() => $this->getViewFields()];
	}

	/**
	 * @param PageNavigation $pageNavigation
	 * @param array $select
	 * @param array $filter
	 * @param array $order
	 * @param bool $__calculateTotalCount
	 * @return Page
	 */
	public function listAction(
		PageNavigation $pageNavigation,
		array $select = [],
		array $filter = [],
		array $order = [],
		bool $__calculateTotalCount = true
	): Page
	{
		if (!isset($filter['IBLOCK_ID']))
		{
			$filter['IBLOCK_ID'] = $this->getCatalogIds();
		}
		else
		{
			$iblockId = (int)($filter['IBLOCK_ID']);
			if (!$this->isIblockCatalog($iblockId))
			{
				return new Page($this->getServiceListName(), [], 0);
			}
		}

		return new Page(
			$this->getServiceListName(),
			$this->getList($select, $filter, $order, $pageNavigation),
			$__calculateTotalCount ? $this->count($filter) : 0
		);
	}

	/**
	 * public function getAction
	 * @see GetAction::getAction
	 */

	/**
	 * @param array $fields
	 * @return array|null
	 */
	public function addAction(array $fields): ?array
	{
		if (!$this->isIblockCatalog((int)$fields['IBLOCK_ID']))
		{
			$this->addError(new Error('The specified iblock is not a product catalog'));

			return null;
		}

		$iblockPermissionsCheckResult = $this->checkIblockModifyPermission($fields['IBLOCK_ID']);
		if (!$iblockPermissionsCheckResult->isSuccess())
		{
			$this->addErrors($iblockPermissionsCheckResult->getErrors());

			return null;
		}

		$prepareResult = $this->prepareFieldsForAdd($fields);
		if (!$prepareResult->isSuccess())
		{
			$this->addErrors($prepareResult->getErrors());

			return null;
		}
		$fields = $prepareResult->getData();
		unset($prepareResult);

		$this->processCustomTypesBeforeAdd($fields);

		$property = new \CIBlockProperty();
		$addResult = $property->Add($fields);
		if (!$addResult)
		{
			$error = $property->getLastError();
			if ($error !== '')
			{
				$this->addError(new Error($error));
			}
			else
			{
				$this->addError(new Error('Error adding property'));
			}

			return null;
		}

		$this->processCustomTypesAfterAdd((int)$addResult);

		return [
			$this->getServiceItemName() => $this->get($addResult),
		];
	}

	/**
	 * @param int $id
	 * @param array $fields
	 * @return array|null
	 */
	public function updateAction(int $id, array $fields): ?array
	{
		$existsResult = $this->exists($id);
		if (!$existsResult->isSuccess())
		{
			$this->addErrors($existsResult->getErrors());

			return null;
		}

		$prepareResult = $this->prepareFieldsForUpdate($id, $fields);
		if (!$prepareResult->isSuccess())
		{
			$this->addErrors($prepareResult->getErrors());

			return null;
		}
		$fields = $prepareResult->getData();
		unset($prepareResult);

		$property = new \CIBlockProperty();
		$updateResult = $property->Update($id, $fields);
		if (!$updateResult)
		{
			$error = $property->getLastError();
			if ($error !== '')
			{
				$this->addError(new Error($error));
			}
			else
			{
				$this->addError(new Error('Error updating product property'));
			}

			return null;
		}

		return [
			$this->getServiceItemName() => $this->get($id),
		];
	}

	/**
	 * @param int $id
	 * @return bool|null
	 */
	public function deleteAction(int $id): ?bool
	{
		$existsResult = $this->exists($id);
		if (!$existsResult->isSuccess())
		{
			$this->addErrors($existsResult->getErrors());

			return null;
		}

		$application = self::getApplication();
		$application->ResetException();

		$deleteResult = \CIBlockProperty::Delete($id);
		if (!$deleteResult)
		{
			$exception = $application->GetException();
			if ($exception)
			{
				$this->addError(new Error($exception->GetString()));
			}
			else
			{
				$this->addError(new Error('Error deleting product property'));
			}

			return null;
		}

		return true;
	}

	// endregion

	/**
	 * @inheritDoc
	 */
	public function getEntityTable()
	{
		return PropertyTable::class;
	}

	/**
	 * @inheritDoc
	 */
	protected function exists($id): Result
	{
		$result = new Result();
		$id = (int)$id;
		if ($id <= 0)
		{
			$result->addError($this->getErrorEntityNotExists());

			return $result;
		}

		$property = PropertyTable::getRow([
			'select' => [
				'ID',
				'IBLOCK_ID',
			],
			'filter' => [
				'=ID' => $id,
			],
			'cache' => [
				'ttl' => 86400,
			],
		]);

		if (!$property)
		{
			$result->addError($this->getErrorEntityNotExists());

			return $result;
		}

		if (!$this->isIblockCatalog((int)$property['IBLOCK_ID']))
		{
			$result->addError($this->getErrorPropertyIblockIsNotCatalog());

			return $result;
		}

		return $result;
	}

	private function processCustomTypesBeforeAdd(array &$fields): void
	{
		$this->customUserType = '';
		if ($this->isPseudoCheckboxPropertyType($fields['PROPERTY_TYPE'], $fields['USER_TYPE']))
		{
			$fields['LIST_TYPE'] = \Bitrix\Iblock\PropertyTable::CHECKBOX;
			$this->customUserType = Enum::PROPERTY_USER_TYPE_BOOL_ENUM;
			unset($fields['USER_TYPE']);
		}
	}

	private function processCustomTypesAfterAdd(int $id): void
	{
		if ($this->customUserType === Enum::PROPERTY_USER_TYPE_BOOL_ENUM)
		{
			\CIBlockPropertyEnum::Add([
				'PROPERTY_ID' => $id,
				'VALUE' => Catalog\RestView\Product::BOOLEAN_VALUE_YES,
			]);
		}
		$this->customUserType = '';
	}

	private function isPseudoCheckboxPropertyType(string $baseType, ?string $userType): bool
	{
		return
			$baseType === PropertyTable::TYPE_LIST
			&& $userType === Enum::PROPERTY_USER_TYPE_BOOL_ENUM
		;
	}

	protected function prepareFieldsForAdd(array $fields): Result
	{
		$result = new Result();

		$propertyTypeDescr = $this->getPropertyTypeDescription($fields);
		if ($propertyTypeDescr === null)
		{
			$result->addError($this->getErrorPropertyInvalidType());

			return $result;
		}

		$property = $propertyTypeDescr['PROPERTY'];
		$fields['PROPERTY_TYPE'] = $propertyTypeDescr['PROPERTY_TYPE'];
		$fields['USER_TYPE'] = $propertyTypeDescr['USER_TYPE'];
		if ($fields['USER_TYPE'] === null)
		{
			$fields['USER_TYPE'] = false; // for \CIBlockProperty - old api use false as null database field value
			$fields['USER_TYPE_SETTINGS'] = false;
		}
		elseif ($property === null)
		{
			$fields['USER_TYPE_SETTINGS'] = false;
		}
		else
		{
			if (empty($fields['USER_TYPE_SETTINGS']))
			{
				$fields['USER_TYPE_SETTINGS'] = false;
			}
			elseif (!is_array($fields['USER_TYPE_SETTINGS']))
			{
				$result->addError($this->getErrorInvalidCustomTypeSettings());

				return $result;
			}
			else
			{
				if (!$this->validateUserSettings($fields['USER_TYPE_SETTINGS']))
				{
					$result->addError($this->getErrorInvalidCustomTypeSettings());

					return $result;
				}
			}
		}

		$result->setData($fields);

		return $result;
	}

	protected function prepareFieldsForUpdate(int $id, array $fields): Result
	{
		$result = new Result();

		$propertyTypeExists = array_key_exists('PROPERTY_TYPE', $fields);
		$userTypeExists = array_key_exists('USER_TYPE', $fields);
		$userTypeSettingsExists = array_key_exists('USER_TYPE_SETTINGS', $fields);

		if (
			$propertyTypeExists
			|| $userTypeExists
			|| $userTypeSettingsExists
		)
		{
			$compiledPropertyType = $fields;
			if (
				!$propertyTypeExists
				|| !$userTypeExists
			)
			{
				$row = $this->getPropertyById($id);
				if ($row === null)
				{
					$result->addError($this->getErrorEntityNotExists());

					return $result;
				}

				$compiledPropertyType = [
					'PROPERTY_TYPE' => $fields['PROPERTY_TYPE'] ?? $row['PROPERTY_TYPE'],
					'USER_TYPE' => $fields['USER_TYPE'] ?? $row['USER_TYPE'],
				];
				unset($row);
			}

			$propertyTypeDescr = $this->getPropertyTypeDescription($compiledPropertyType);
			if ($propertyTypeDescr === null)
			{
				$result->addError($this->getErrorPropertyInvalidType());

				return $result;
			}

			$property = $propertyTypeDescr['PROPERTY'];
			$fields['PROPERTY_TYPE'] = $propertyTypeDescr['PROPERTY_TYPE'];
			$fields['USER_TYPE'] = $propertyTypeDescr['USER_TYPE'];

			if ($fields['USER_TYPE'] === null)
			{
				$fields['USER_TYPE'] = false; // for \CIBlockProperty - old api use false as null database field value
				$fields['USER_TYPE_SETTINGS'] = false;
			}
			elseif ($property === null)
			{
				$fields['USER_TYPE_SETTINGS'] = false;
			}
			elseif ($userTypeSettingsExists)
			{
				if (empty($fields['USER_TYPE_SETTINGS']))
				{
					$fields['USER_TYPE_SETTINGS'] = false;
				}
				elseif (!is_array($fields['USER_TYPE_SETTINGS']))
				{
					$result->addError($this->getErrorInvalidCustomTypeSettings());

					return $result;
				}
				else
				{
					if (!$this->validateUserSettings($fields['USER_TYPE_SETTINGS']))
					{
						$result->addError($this->getErrorInvalidCustomTypeSettings());

						return $result;
					}
				}
			}
		}

		$result->setData($fields);

		return $result;
	}

	protected function getPropertyTypeDescription(array $fields): ?array
	{
		$baseTypeList = [
			PropertyTable::TYPE_NUMBER => true,
			PropertyTable::TYPE_STRING => true,
			PropertyTable::TYPE_LIST => true,
			PropertyTable::TYPE_FILE => true,
			PropertyTable::TYPE_ELEMENT => true,
			PropertyTable::TYPE_SECTION => true,
		];

		$baseType = $fields['PROPERTY_TYPE'] ?? null;
		if (!is_string($baseType))
		{
			return null;
		}
		if (!isset($baseTypeList[$baseType]))
		{
			return null;
		}

		$userType = $fields['USER_TYPE'] ?? null;
		if ($userType === '' || $userType === false)
		{
			$userType = null;
		}
		if (!is_string($userType) && $userType !== null)
		{
			return null;
		}

		$property = null;
		if (
			$userType !== null
			&& !$this->isPseudoCheckboxPropertyType($baseType, $userType)
		)
		{
			$property = \CIBlockProperty::GetUserType($userType);
			if (!$property)
			{
				return null;
			}

			if ($property['PROPERTY_TYPE'] !== $baseType)
			{
				return null;
			}
		}

		return [
			'PROPERTY_TYPE' => $baseType,
			'USER_TYPE' => $userType,
			'PROPERTY' => $property,
		];
	}

	protected function validateUserSettings(array $row): bool
	{
		if (empty($row))
		{
			return true;
		}

		$result = true;
		foreach ($row as $field)
		{
			if (is_array($field))
			{
				if (!$this->validateUserSettings($field))
				{
					$result = false;
					break;
				}
			}
			elseif (!is_scalar($field) && $field !== null)
			{
				$result = false;
				break;
			}
		}

		return $result;
	}

	protected function getErrorInvalidCustomTypeSettings(): Error
	{
		return new Error('Invalid custom property type settings specified');
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit