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/components/bitrix/catalog.store.entity.details/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/components/bitrix/catalog.store.entity.details/class.php
<?php

use Bitrix\Catalog\Access\AccessController;
use Bitrix\Catalog\Access\ActionDictionary;
use Bitrix\Catalog\StoreTable;
use Bitrix\Catalog\v2\Integration\UI\EntityEditor\StoreProvider;
use Bitrix\Main\Engine\Contract\Controllerable;
use Bitrix\Main\Error;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Loader;
use Bitrix\Main\Result;
use Bitrix\Main\UI\FileInputUtility;

if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true)
{
	die();
}

Loader::requireModule('catalog');

/**
 * Store view and edit form component.
 *
 * Params:
 * - ID - id entity (if new record can be empty or `0`);
 * - PATH_TO_DETAIL - URL template for detail page (variable with id must be named `#ID#`);
 */
class CatalogStoreEntityDetails extends CBitrixComponent implements Controllerable
{
	private int $entityId;
	private ?array $entityFields;
	private AccessController $accessController;

	private function init(): void
	{
		$this->entityId = (int)($this->arParams['ID'] ?? 0);
		$this->accessController = AccessController::getCurrent();
	}

	/**
	 * @inheritDoc
	 *
	 * @param array $arParams
	 *
	 * @return void
	 */
	public function onPrepareComponentParams($arParams)
	{
		$arParams['USER_FIELD_CREATE_PAGE_URL'] ??= null;

		return $arParams;
	}

	/**
	 * Is new entity.
	 *
	 * @return bool
	 */
	private function isNew(): bool
	{
		return !$this->entityId;
	}

	/**
	 * @inheritDoc
	 */
	public function executeComponent()
	{
		$this->init();

		if (!$this->loadEntity())
		{
			$this->includeComponentTemplate();

			return;
		}

		if (!$this->checkAccess())
		{
			$this->includeComponentTemplate();

			return;
		}

		$this->initForm();
		$this->includeComponentTemplate();
	}

	/**
	 * Init `arResult` form values.
	 *
	 * @return void
	 */
	private function initForm(): void
	{
		$provider = $this->getEditorProvider();

		$this->arResult['FORM'] = $provider->getFields();
		$this->arResult['FORM']['ENABLE_CONFIGURATION_UPDATE'] = ! $provider->isReadOnly();
	}

	/**
	 * Form fields provider.
	 *
	 * @return StoreProvider
	 */
	private function getEditorProvider(): StoreProvider
	{
		return new StoreProvider(
			$this->entityFields ?? [],
			$this->arParams['USER_FIELD_CREATE_PAGE_URL']
		);
	}

	/**
	 * Load entity if exists.
	 *
	 * @return bool
	 */
	private function loadEntity(): bool
	{
		if ($this->isNew())
		{
			return true;
		}

		$entity = StoreTable::getRowById($this->entityId);
		if (!$entity)
		{
			$this->arResult['ERROR']['TITLE'] = Loc::getMessage('CATALOG_STORE_DETAIL_NOT_FOUND_ERROR');
			$this->arResult['ERROR']['DESCRIPTION'] = '';

			return false;
		}

		$this->entityFields = $entity;

		return true;
	}

	/**
	 * Checks access and add errors.
	 *
	 * @return bool
	 */
	private function checkAccess(): bool
	{
		$can =
			$this->entityId > 0
			? (
				(
					(int)$this->entityFields['USER_ID'] === $this->accessController->getUser()->getUserId()
					&& $this->accessController->check(ActionDictionary::ACTION_STORE_MODIFY)
				)
				|| $this->accessController->checkByValue(ActionDictionary::ACTION_STORE_VIEW, (string)$this->entityId)
			)
			: $this->accessController->check(ActionDictionary::ACTION_STORE_MODIFY)
		;

		if (!$can)
		{
			$this->arResult['ERROR']['TITLE'] = Loc::getMessage('CATALOG_STORE_DETAIL_ACCESS_DENIED_ERROR');

			return false;
		}

		return true;
	}

	/**
	 * @inheritDoc
	 */
	public function configureActions()
	{
		return [];
	}

	/**
	 * Save AJAX action.
	 *
	 * Data loaded from field 'data' of request.
	 *
	 * @return array
	 */
	public function saveAction(): array
	{
		global $APPLICATION;

		/**
		 * @var \CMain $APPLICATION
		 */

		$this->init();

		if (!$this->accessController->check(ActionDictionary::ACTION_STORE_MODIFY))
		{
			return [
				'ERROR' => Loc::getMessage('CATALOG_STORE_DETAIL_ACCESS_DENIED_ERROR'),
			];
		}

		$fields = (array)($this->request->get('data') ?: []);
		$fields = $this->prepareFileFields($fields);
		if (empty($fields))
		{
			return [
				'ERROR' => Loc::getMessage('CATALOG_STORE_DETAIL_EMPTY_REQUEST_ERROR'),
			];
		}

		$result = $this->validateFields($fields);
		if (!$result->isSuccess())
		{
			return [
				'ERROR' => join(', ', $result->getErrorMessages()),
			];
		}

		$id = $this->entityId;
		if ($id > 0)
		{
			if (
				!$this->isUserStoreCreator($id)
				&& !$this->accessController->checkByValue(ActionDictionary::ACTION_STORE_VIEW, (string)$this->entityId)
			)
			{
				return [
					'ERROR' => Loc::getMessage('CATALOG_STORE_DETAIL_ACCESS_DENIED_ERROR'),
				];
			}

			$ret =  CCatalogStore::Update($id, $fields);
			if ($ret === false)
			{
				$ex = $APPLICATION->GetException();
				$error =
					$ex instanceof \CApplicationException
						? $ex->GetString()
						: 'Unknown error'
				;
				$result->addError(new Error($error));
			}
		}
		else
		{
			$id =  CCatalogStore::Add($fields);
			if ($id === false)
			{
				$ex = $APPLICATION->GetException();
				$error =
					$ex instanceof \CApplicationException
						? $ex->GetString()
						: 'Unknown error'
				;
				$result->addError(new Error($error));
			}
		}

		if (!$result->isSuccess())
		{
			return [
				'ERROR' => join(' ', $result->getErrorMessages()),
			];
		}

		$this->saveUserFields($id, $fields);

		return [
			'ENTITY_ID' => $id,
			'REDIRECT_URL' => $this->getDetailsUrl($id),
		];
	}

	/**
	 * Validate fields with editor provider info.
	 *
	 * @param array $fields
	 *
	 * @return Result
	 */
	private function validateFields(array $fields): Result
	{
		$result = new Result();

		$editorFields = $this->getEditorProvider()->getEntityFields();
		foreach ($editorFields as $field)
		{
			$name = $field['name'] ?? null;
			if (!$name)
			{
				continue;
			}

			if (($field['required'] ?? false) && empty($fields[$name]))
			{
				$isSetEmptyField = array_key_exists($name, $fields);
				if ($this->isNew() || $isSetEmptyField)
				{
					$message = Loc::getMessage('CATALOG_STORE_DETAIL_FIELD_REQUIRED_ERROR', [
						'#NAME#' => $field['title'] ?? $name,
					]);
					$result->addError(new Error($message));
				}
			}
		}

		return $result;
	}

	/**
	 * Zeroing fields with files if they are marked for deletion.
	 *
	 * @param array $fields
	 *
	 * @return array
	 */
	private function prepareFileFields(array $fields): array
	{
		$imageFields = [
			'IMAGE_ID',
		];
		foreach ($imageFields as $name)
		{
			$fileId = (int)($fields[$name] ?? 0);
			if ($fileId <= 0)
			{
				continue;
			}

			// mark as deleted
			$delName = "{$name}_del";
			if (
				isset($fields[$delName])
				&& (string)$fields[$name] === (string)$fields[$delName]
			)
			{
				$fields[$name] = null;
				continue;
			}

			// check as real uploaded file
			$uploaderControlId = mb_strtolower($name . '_uploader');
			$checkedFiles = FileInputUtility::instance()->checkFiles(
				$uploaderControlId,
				[$fileId]
			);
			if (empty($checkedFiles))
			{
				unset($fields[$name]);
				continue;
			}

			$fields[$name] = CFile::MakeFileArray($fileId);
		}

		return $fields;
	}

	/**
	 * @inheritDoc
	 */
	protected function listKeysSignedParameters()
	{
		return [
			'ID',
			'PATH_TO_DETAIL',
		];
	}

	/**
	 * Detail URL for store with id.
	 *
	 * @param int $id
	 *
	 * @return string
	 */
	private function getDetailsUrl(int $id): string
	{
		$url = (string)($this->arParams['PATH_TO_DETAIL'] ?? '');

		return str_replace('#ID#', $id, $url);
	}

	/**
	 * Save store user fields.
	 *
	 * @param int $storeId
	 * @param array $fields
	 *
	 * @return void
	 */
	private function saveUserFields(int $storeId, array $fields): void
	{
		$userFields = array_filter($fields, fn($key) => strpos($key, 'UF_') === 0, ARRAY_FILTER_USE_KEY);
		if (empty($userFields))
		{
			return;
		}

		$manager = new CUserTypeManager();
		$manager->Update(StoreTable::getUfId(), $storeId, $userFields);
	}

	private function isUserStoreCreator(int $storeId): bool
	{
		$storeCreatorId = StoreTable::getStoreCreatorId($storeId);
		$currentUserId = $this->accessController->getUser()->getUserId();

		return $storeCreatorId == $currentUserId;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit