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/cvetdv.ru/bitrix/modules/yandex.market/lib/catalog/endpoint/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/cvetdv.ru/bitrix/modules/yandex.market/lib/catalog/endpoint/card.php
<?php
namespace Yandex\Market\Catalog\Endpoint;

use Yandex\Market\Api;
use Yandex\Market\Api\Reference\Auth;
use Yandex\Market\Catalog;
use Yandex\Market\Error;
use Yandex\Market\Export\Xml\Listing;
use Yandex\Market\Logger\Trading\Audit;
use Yandex\Market\Reference\Concerns;
use Yandex\Market\Result;
use Yandex\Market\Psr\Log\LoggerInterface;
use Yandex\Market\Type;
use Yandex\Market\Utils;

class Card implements Driver, DriverWithPrepareCategory
{
    use Concerns\HasMessage;
    use Concerns\HasOnce;

    private $businessId;
    private $valueTypeCache;
    private $unitTypeCache;

    public function __construct($businessId)
    {
        $this->businessId = (int)$businessId;
    }

    public function type()
    {
        return Catalog\Glossary::ENDPOINT_CARD;
    }

    public function campaignId()
    {
        return 0;
    }

	public function audit()
	{
		return Audit::CATALOG_CARD;
	}

    public function priority($placementStatus, array $prepared, array $submitted = null)
    {
        if (!PriorityDictionary::wasPublished($placementStatus))
        {
            return PriorityDictionary::CARD_NEW;
        }

        return PriorityDictionary::CARD_PUBLISHED;
    }

    public function limit()
    {
        return 100;
    }

    public function prepareCategory($categoryId, array $bag, Auth $auth, LoggerInterface $logger)
    {
        list($categoryParameters, $error) = $this->categoryParameters($categoryId, $auth, $logger);

        if ($error !== null)
        {
            $result = new Result\Base();
            $result->addError($error);

            return array_fill_keys(array_keys($bag), $result);
        }

        $prepareResults = [];

        foreach ($bag as $sku => $payload)
        {
            list($parameterValues, $errors) = $this->preparePayload($payload, $categoryParameters);

            $skuResult = new Result\Base();

            if (!empty($parameterValues))
            {
	            $skuResult->addWarnings($errors + $this->validatePayload($categoryParameters, $parameterValues));

                $skuResult->setData([
                    'categoryId' => (int)$categoryId,
                    'parameterValues' => $parameterValues,
                ]);
            }
            else if (!empty($errors))
            {
                $skuResult->addErrors($errors);
            }
            else
            {
                $skuResult->addError(new Error\Base(self::getMessage('EMPTY')));
            }

            $prepareResults[$sku] = $skuResult;
        }

        $this->clearOnce('valueType');
        $this->clearOnce('unitType');

        return $prepareResults;
    }

    private function categoryParameters($categoryId, Auth $auth, LoggerInterface $logger)
    {
        try
        {
            $categoryId = (int)$categoryId;

            if ($categoryId <= 0)
            {
                return [ null, new Error\Base(self::getMessage('CATEGORY_ID_EMPTY')) ];
            }

            $request = new Api\Category\Parameters\Request($auth, $logger);
            $request->setCategoryId($categoryId);

            return [ $request->execute()->getCategoryParameters() ];
        }
        catch (Api\Exception\NotFoundException $exception)
        {
            if ($exception->getErrorCode() === Api\Category\Parameters\Request::CATEGORY_NOT_FOUND)
            {
	            return [ null, new Error\Base($exception->getMessage()) ];
            }

            throw $exception;
        }
    }

    private function preparePayload(array $payload, Api\Category\Parameters\Model\CategoryParameterCollection $categoryParameters)
    {
        $export = [];
        $errors = [];
        $preparedGroups = empty($payload['parameterValues']) ? [] : Utils\ArrayHelper::groupBy($payload['parameterValues'], 'parameterId');
        $propertyGroups = empty($payload['param']) ? [] : Utils\ArrayHelper::groupBy(array_map(
            static function(array $param) { return $param + [ 'nameKey' => mb_strtolower(trim($param['name'])) ]; },
            $payload['param']
        ), 'nameKey');
        $foundIds = [];
		$foundNames = [];

        /** @var Api\Category\Parameters\Model\CategoryParameter $categoryParameter */
        foreach ($categoryParameters as $categoryParameter)
        {
            $parameterId = $categoryParameter->getId();

            if (isset($foundIds[$parameterId])) { continue; }

	        $name = mb_strtolower(trim($categoryParameter->getName()));
	        $unit = $categoryParameter->getUnit();
			$nameVariants = [
				$name => true,
			];

			if ($unit !== null)
			{
				$defaultUnit = $unit->getDefaultUnit();
				$nameWithUnit = mb_strtolower("{$name}, {$defaultUnit['name']}");
				$nameVariants[$nameWithUnit] = [
					'unitId' => $defaultUnit['id'],
				];
			}

            if (isset($preparedGroups[$parameterId]))
            {
	            $foundIds[$parameterId] = true;
	            $foundNames += $nameVariants;
                array_push($export, ...$preparedGroups[$parameterId]);
                continue;
            }

			$defined = null;
	        $propertyGroup = null;

			foreach ($nameVariants as $nameVariant => $nameDefined)
			{
				if (isset($propertyGroups[$nameVariant]))
				{
					$propertyGroup = $propertyGroups[$nameVariant];
					$defined = $nameDefined !== true ? $nameDefined : null;
					$foundNames[$nameVariant] = true;
					break;
				}
			}

			if ($propertyGroup === null) { continue; }

	        $foundIds[$parameterId] = true;

            foreach ($propertyGroup as $param)
            {
                list($value, $valueError) = $this->paramValue($param, $categoryParameter);

                if ($valueError instanceof Error\Base)
                {
                    $errors[$parameterId] = new Error\Base(sprintf(
						'%s: %s',
						$categoryParameter->getName(),
						$valueError->getMessage()
                    ));
                    continue;
                }

                if ($value === null) { continue; }

	            $unitParent = $this->paramUnitParent($param, $categoryParameter, $categoryParameters);

	            if ($unitParent !== null && !isset($foundIds[$unitParent['parameterId']]))
	            {
		            $export[] = $unitParent;
		            $foundIds[$unitParent['parameterId']] = true;
	            }

	            list($valueId, $valueIdError) = $this->paramValueId($value, $categoryParameter, $categoryParameters, $export);

	            if ($valueIdError instanceof Error\Base)
	            {
		            $errors[$parameterId] = new Error\Base(sprintf(
			            '%s: %s',
			            $categoryParameter->getName(),
			            $valueIdError->getMessage()
		            ));
		            continue;
	            }

	            list($unitId, $unitError) = $this->paramUnit($param, $categoryParameter->getUnit());

	            if ($unitError instanceof Error\Base)
	            {
		            $errors[$parameterId] = new Error\Base(sprintf(
			            '%s: %s (%s)',
			            $categoryParameter->getName(),
			            $valueError->getMessage(),
			            self::getMessage('UNIT_ERROR')
		            ));
		            continue;
	            }

                $exportItem = [
                    'parameterId' => $parameterId,
                    'value' => $value,
                ];

                if ($valueId !== null)
                {
                    $exportItem['valueId'] = $valueId;
                }

                if ($unitId !== null)
                {
                    $exportItem['unitId'] = $unitId;
                }

				if ($defined !== null)
				{
					$exportItem += $defined;
				}

                $export[] = $exportItem;
            }
        }

		$otherId = Api\Category\Parameters\Model\CategoryParameter::ID_OTHER;
		$otherParameter = $categoryParameters->getItemById($otherId);

		if ($otherParameter !== null && !isset($foundIds[$otherId]))
		{
			$otherValue = $this->paramOther(array_diff_key($propertyGroups, $foundNames));

			if ($otherValue !== '' || !empty($export))
			{
				$export[] = [
					'parameterId' => $otherId,
					'value' => $otherValue,
				];
			}
		}

        return [ $export, $errors ];
    }

    private function paramValue(array $param, Api\Category\Parameters\Model\CategoryParameter $categoryParameter)
    {
        if (!isset($param['value']) || Utils\Value::isEmpty($param['value'])) { return [ null, null ]; }

        $valueType = $this->valueType($categoryParameter);
        $sanitized = $valueType->sanitize($param['value']);

		if ($sanitized instanceof Error\Base)
		{
			if (
				$valueType instanceof Type\EnumType
				&& $sanitized->getCode() === Type\EnumType::ERROR_INVALID
				&& $categoryParameter->isAllowCustomValues()
			)
			{
				return [ $param['value'], null ];
			}

			return [ null, $sanitized ];
		}

        return [ $sanitized, null ];
    }

    private function valueType(Api\Category\Parameters\Model\CategoryParameter $categoryParameter)
    {
        return $this->once('valueType', [ $categoryParameter ], function (Api\Category\Parameters\Model\CategoryParameter $categoryParameter) {
            $parameterType = $categoryParameter->getType();

            if ($parameterType === Api\Category\Parameters\Model\CategoryParameter::TYPE_TEXT)
            {
                return new Type\StringType();
            }

            if ($parameterType === Api\Category\Parameters\Model\CategoryParameter::TYPE_BOOLEAN)
            {
                return new Type\BooleanType();
            }

            if ($parameterType === Api\Category\Parameters\Model\CategoryParameter::TYPE_NUMERIC)
            {
                return new Type\NumberType([
                    Type\NumberType::SETTING_PRECISION => 2,
                ]);
            }

            if ($parameterType === Api\Category\Parameters\Model\CategoryParameter::TYPE_ENUM)
            {
                $values = array_values(array_column((array)$categoryParameter->getValues(), 'value', 'value'));

                return new Type\EnumType(new Listing\Custom($values), [
					'value_synonym' => !$categoryParameter->isAllowCustomValues() || $categoryParameter->isFiltering(),
                ]);
            }

            trigger_error(sprintf('unknown category parameter type %s', $parameterType));

            return new Type\StringType();
        });
    }

    private function paramUnit(array $param, Api\Category\Parameters\Model\Unit $parameterUnit = null)
    {
        if ($parameterUnit === null || !isset($param['unit'])) { return [ null, null ]; }

        $unitType = $this->unitType($parameterUnit);
        $sanitized = $unitType->sanitize($param['unit']);

        if ($sanitized === null) { return [ null, null ]; }
        if ($sanitized instanceof Error\XmlNode) { return [ null, $sanitized ]; }

        $id = array_search($sanitized, $unitType->listing()->values(), true);

        if ($id === false)
        {
            return [ null, new Error\Base(sprintf('cant find unitId %s', $sanitized)) ];
        }

        return [ $id, null ];
    }

    /** @return Type\EnumType */
    private function unitType(Api\Category\Parameters\Model\Unit $unit)
    {
        return $this->once('unitType', [ $unit ], function(Api\Category\Parameters\Model\Unit $unit) {
            $units = $unit->getUnits();
            $names = array_column($units, 'name', 'id');
            $fullNames = array_column($units, 'fullName', 'id');

            return new Type\EnumType(new Listing\Custom($names, $fullNames));
        });
    }

	private function paramUnitParent(
		array $param,
		Api\Category\Parameters\Model\CategoryParameter $categoryParameter,
		Api\Category\Parameters\Model\CategoryParameterCollection $categoryParameters
	)
	{
		if (!isset($param['unit']) || (!is_string($param['unit']))) { return null; }

		$unitValue = mb_strtoupper(trim($param['unit']));

		if ($unitValue === '') { return null; }

		/** @var Api\Category\Parameters\Model\ValueRestriction $valueRestriction */
		foreach ($categoryParameter->getValueRestrictions() as $valueRestriction)
		{
			$restrictionParameter = $categoryParameters->getItemById($valueRestriction->getLimitingParameterId());

			if ($restrictionParameter === null) { continue; }

			foreach ((array)$restrictionParameter->getValues() as $restrictionParameterValue)
			{
				if (mb_strtoupper($restrictionParameterValue['value']) === $unitValue)
				{
					return [
						'parameterId' => $restrictionParameter->getId(),
						'value' => $restrictionParameterValue['value'],
						'valueId' => $restrictionParameterValue['id'],
					];
				}
			}
		}

		return null;
	}

	private function paramValueId(
		$value,
		Api\Category\Parameters\Model\CategoryParameter $categoryParameter,
		Api\Category\Parameters\Model\CategoryParameterCollection $categoryParameters,
		array $parameterValues
	)
	{
		$valuesDto = $categoryParameter->getValues();

		if ($valuesDto === null) { return [ null, null ]; }

		$matched = array_column(
			array_filter($valuesDto, static function(array $option) use ($value) { return (string)$option['value'] === (string)$value; }),
			'value',
			'id'
		);

		if (empty($matched))
		{
			if ($categoryParameter->isAllowCustomValues()) { return [ null, null ]; }

			$error = new Error\Base(self::getMessage('VALUE_ID_NOT_FOUND', [
				'#VALUE#' => $value,
			]));

			return [ null, $error ];
		}

		$restrictions = $categoryParameter->getValueRestrictions();
		$restricted = $restrictions->getRestricted($parameterValues);

		if ($restricted !== null)
		{
			$matched = array_intersect_key($matched, array_flip($restricted));

			if (empty($matched))
			{
				$error = new Error\Base(self::getMessage('VALUE_ID_RESTRICTED', [
					'#VALUE#' => $value,
					'#RESTRICTED_VALUES#' => implode(', ', array_filter(array_map(static function(Api\Category\Parameters\Model\ValueRestriction $valueRestriction) use ($categoryParameters, $parameterValues) {
						$parameterId = $valueRestriction->getLimitingParameterId();
						$categoryParameter = $categoryParameters->getItemById($parameterId);

						if ($categoryParameter === null) { return null; }

						$selectedValues = array_filter($parameterValues, static function(array $parameterValue) use ($parameterId) {
							return $parameterValue['parameterId'] === $parameterId;
						});

						if (empty($selectedValues)) { return null; }

						return sprintf('%s: %s', $categoryParameter->getName(), implode(', ', array_column($selectedValues, 'value')));
					}, $restrictions->asArray()))),
				]));

				return [ null, $error ];
			}
		}

		if (count($matched) > 1 && $restrictions->count() > 0)
		{
			$error = new Error\Base(self::getMessage('VALUE_ID_FEW_VARIANTS', [
				'#VALUE#' => $value,
				'#RESTRICTED_NAME#' => implode(', ', array_filter(array_map(static function(Api\Category\Parameters\Model\ValueRestriction $valueRestriction) use ($categoryParameters) {
					$parameterId = $valueRestriction->getLimitingParameterId();
					$categoryParameter = $categoryParameters->getItemById($parameterId);

					if ($categoryParameter === null) { return null; }

					return $categoryParameter->getName();
				}, $restrictions->asArray()))),
			]));

			return [ null, $error ];
		}

		reset($matched);

		return [ key($matched), null ];
	}

	private function paramOther(array $paramGroups)
	{
		$rows = [];

		foreach ($paramGroups as $paramGroup)
		{
			$row = '';

			foreach ($paramGroup as $param)
			{
				if (Utils\Value::isEmpty($param['value'])) { continue; }

				if ($row === '')
				{
					$row = $param['name'];
					$row .= !empty($param['unit']) ? ", {$param['unit']}" : '';
					$row .= ': ';
				}
				else
				{
					$row .= ', ';
				}

				$row .= is_array($param['value']) ? implode(', ', $param['value']) : $param['value'];
			}

			$rows[] = $row;
		}

		return implode(PHP_EOL, $rows);
	}

	private function validatePayload(
		Api\Category\Parameters\Model\CategoryParameterCollection $categoryParameters,
		array $parameterValues
	)
	{
		$warnings = [];
		$preparedGroups = Utils\ArrayHelper::groupBy($parameterValues, 'parameterId');

		/** @var Api\Category\Parameters\Model\CategoryParameter $categoryParameter */
		foreach ($categoryParameters as $categoryParameter)
		{
			$parameterId = $categoryParameter->getId();

			if (!isset($preparedGroups[$parameterId]))
			{
				if ($categoryParameter->isRequired())
				{
					$warnings[$parameterId] = new Error\Base(sprintf(
						'%s: %s',
						$categoryParameter->getName(),
						self::getMessage('PARAMETER_REQUIRED')
					));
				}

				continue;
			}

			$valueRestrictions = $categoryParameter->getValueRestrictions();

			if ($valueRestrictions->count() === 0) { continue; }

			foreach ($preparedGroups[$parameterId] as $parameterValue)
			{
				if (!isset($parameterValue['valueId'])) { continue; }

				foreach ($valueRestrictions->getDependsOn($parameterValue['valueId']) as $restrictionParameterId => $restrictionValueIds)
				{
					$restrictionParameter = $categoryParameters->getItemById($restrictionParameterId);

					if ($restrictionParameter === null) { continue; }

					if (!isset($preparedGroups[$restrictionParameterId]))
					{
						$warnings[$restrictionParameterId] = new Error\Base(sprintf(
							'%s: %s',
							$categoryParameter->getName(),
							self::getMessage('RESTRICTED_REQUIRED', [ '#RESTRICTED_NAME#' => $restrictionParameter->getName() ])
						));
						break;
					}

					foreach ($preparedGroups[$restrictionParameterId] as $restrictedValue)
					{
						if (!isset($restrictedValue['valueId']))
						{
							$warnings[$restrictionParameterId] = new Error\Base(sprintf(
								'%s: %s',
								$restrictionParameter->getName(),
								self::getMessage('RESTRICTED_WITHOUT_VALUE_ID')
							));
							break;
						}

						if (!in_array($restrictedValue['valueId'], $restrictionValueIds, true))
						{
							$restrictedAvailable = array_filter((array)$restrictionParameter->getValues(), static function(array $option) use ($restrictionValueIds) {
								return in_array($option['id'], $restrictionValueIds, true);
							});

							$warnings[$parameterId] = new Error\Base(new Error\Base(sprintf(
								'%s: %s',
								$categoryParameter->getName(),
								self::getMessage('RESTRICTED_INVALID_DEPENDENCY', [
									'#PARAMETER_VALUE#' => $parameterValue['value'],
									'#RESTRICTED_NAME#' => $restrictionParameter->getName(),
									'#RESTRICTED_VALUE#' => $restrictedValue['value'],
									'#RESTRICTED_AVAILABLE#' => count($restrictedAvailable) > 10
										? implode(', ', array_column(array_slice($restrictedAvailable, 0, 10), 'value')) . '...'
										: implode(', ', array_column($restrictedAvailable, 'value')),
								])
							)));
							break;
						}
					}
				}
			}
		}

		return $warnings;
	}

    public function submit(array $payloadBag, Auth $auth, LoggerInterface $logger)
    {
		$offersContent = $this->compileOffersContent($payloadBag);

		$skus = array_keys($payloadBag);
	    $offerResults = array_combine($skus, array_map(static function() { return new Result\Base(); }, $skus));

        $request = new Api\Business\OfferCards\Update\Request($this->businessId, $auth, $logger);
        $request->setOffersContent($offersContent);

        $response = $request->execute();

		$errorOfferIds = $this->fillResponseResult($offerResults, $response->getResults());
	    $repeatOffers = $this->sliceErrorOffers($offersContent, $errorOfferIds);

	    if (!empty($repeatOffers))
	    {
		    $request->setOffersContent($repeatOffers);
		    $response = $request->execute();

		    $this->fillResponseResult($offerResults, $response->getResults());
	    }

		$this->logSubmitted($offerResults, $payloadBag, $logger);

        return $offerResults;
    }

    private function compileOffersContent(array $payloadBag)
    {
        $result = [];

        foreach ($payloadBag as $sku => $payload)
        {
            $result[] = [ 'offerId' => (string)$sku ] + $payload;
        }

        return $result;
    }

    private function fillResponseResult(array $submitResults, Api\Business\OfferCards\Update\OfferResultCollection $offerResultCollection)
    {
	    $errorOfferIds = [];

        /** @var Api\Business\OfferCards\Update\OfferResult $offerResult */
        foreach ($offerResultCollection as $offerResult)
        {
            $offerId = $offerResult->getOfferId();

            if (!isset($submitResults[$offerId])) { continue; }

            /** @var Result\Base $submitResult */
            $submitResult = $submitResults[$offerId];

            /** @var Api\Business\OfferCards\Update\OfferError $error */
            foreach ($offerResult->getErrors() as $error)
            {
	            $errorOfferIds[$offerId] = $offerId;
                $submitResult->addError(new Error\Base($error->errorMessage()));

				if ($error->getType() === Api\Business\OfferCards\Update\OfferError::OFFER_NOT_FOUND)
				{
					$submitResult->setData([ 'REPEAT' => true ]);
				}
            }

			if ($submitResult->hasWarnings()) { continue; }

            /** @var Api\Business\OfferCards\Update\OfferError $error */
            foreach ($offerResult->getWarnings() as $error)
            {
                $submitResult->addWarning(new Error\Base($error->errorMessage()));
            }
        }

		return array_values($errorOfferIds);
    }

	private function sliceErrorOffers(array $offersContent, array $errorOfferIds)
	{
		if (empty($errorOfferIds)) { return null; }

		$errorOfferMap = array_flip($errorOfferIds);

		return array_values(array_filter($offersContent, static function(array $offer) use ($errorOfferMap) {
			return !isset($errorOfferMap[$offer['offerId']]);
		}));
	}

	private function logSubmitted(array $offerResults, array $payloadBag, LoggerInterface $logger)
	{
		foreach ($offerResults as $sku => $offerResult)
		{
			if (!$offerResult->isSuccess()) { continue; }

			$logger->info(self::getMessage('SUBMITTED', [
				'#CATEGORY#' => $payloadBag[$sku]['categoryId'],
				'#PARAMETERS#' => implode(', ', array_column($payloadBag[$sku]['parameterValues'], 'value')),
			]), [
				'ENTITY_TYPE' => Catalog\Glossary::ENTITY_SKU,
				'ENTITY_ID' => $sku,
			]);
		}
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit