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/vkapi.market/lib/export/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/vkapi.market/lib/export/photo.php
<?php

namespace VKapi\Market\Export;

use Bitrix\Main\Entity;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\ORM\Query\Query;
use VKapi\Market\Error;
use VKapi\Market\Exception\BaseException;
\Bitrix\Main\Localization\Loc::loadMessages(__FILE__);
/**
 * ����� �� ����� � ������� �������� ������� � ���������
 * ���������� � ����� ������ �������� �������� � �������
 * 
 * ���
 * + ID int(11) NOT NULL AUTO_INCREMENT,
 * + FILE_ID int(11) NOT NULL,
 * + GROUP_ID int(11) NOT NULL,
 * + PHOTO_ID int(11) NOT NULL,
 * + MAIN tinyint(1) NOT NULL DEFAULT '0',
 * + PID int(11) NOT NULL,
 * + HASH varchar(255) NOT NULL,
 * + WM_HASH varchar(255) DEFAULT NULL,
 * ������
 * + PRIMARY KEY (`ID`),
 * + KEY `ix_gid_eid` (`FILE_ID`, `GROUP_ID`, `MAIN`, `PID`) USING BTREE ,
 * + KEY `ix_fid_git_m` (`GROUP_ID`,`FILE_ID`,`PID`) USING BTREE,
 * + KEY `ix_photo_group` (`PHOTO_ID`,`GROUP_ID`) USING BTREE
 * @package VKapi\Market\Export
 */
class PhotoTable extends \Bitrix\Main\Entity\DataManager
{
    public static function getFilePath()
    {
        return __FILE__;
    }
    public static function getTableName()
    {
        return 'vkapi_market_export_photo_list';
    }
    public static function getMap()
    {
        return [
            new \Bitrix\Main\Entity\IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
            // ������������� ����� � ���������, ����� ������������ �����
            new \Bitrix\Main\Entity\IntegerField('GROUP_ID', ['required' => true]),
            ///������������� ����� � ��������
            new \Bitrix\Main\Entity\IntegerField('FILE_ID', ['required' => true]),
            //������������� �������� � ���������
            new \Bitrix\Main\Entity\IntegerField('PHOTO_ID', ['required' => false]),
            //������������� ������, �������� ����������� ��������
            new \Bitrix\Main\Entity\IntegerField('PID', ['required' => false, 'default' => null]),
            //������������� �����
            new \Bitrix\Main\Entity\IntegerField('OID', ['required' => false, 'default' => null]),
            // ������ �������� ������
            new \Bitrix\Main\Entity\IntegerField('MAIN', ['default' => 0, 'required' => false]),
            //��� ��������, �� ����� �������� � ����� ����  ��� � ���������
            new \Bitrix\Main\Entity\StringField('HASH', ['default' => '']),
            // ���  ������� �����, �� ����� �������� � ����� �������� ���������� �������� ������� �����
            new \Bitrix\Main\Entity\StringField('WM_HASH', []),
            new \Bitrix\Main\Entity\ExpressionField('CNT', 'COUNT(ID)'),
        ];
    }
    /**
 * �������� ��� �������� �������� � ������,
 * ���������� ��� ������ �����
 * 
 * @param $groupId
 * @return \Bitrix\Main\DB\Result
 * @throws \Bitrix\Main\Db\SqlQueryException
 */
    public static function deleteAllByGroupId($groupId)
    {
        $entity = static::getEntity();
        $connection = $entity->getConnection();
        $connection->query(sprintf('DELETE FROM %s WHERE %s', $connection->getSqlHelper()->quote($entity->getDbTableName()), \Bitrix\Main\ORM\Query\Query::buildFilterSql($entity, ['GROUP_ID' => abs(intval($groupId))])));
    }
    /**
 * �������� ������ � ���������� �������� � �� �� �������������� ��������� ����� � ������
 * 
 * @param int $fileId - ������������� ����� ���������
 * @param int $groupId - ������������� ����� � ������ �� ������� ���, ����� �� �� �����, ����� ������� �� ��� �����
 * @throws \Bitrix\Main\Db\SqlQueryException
 */
    public static function deleteByFileId($fileId, $groupId = null)
    {
        $arFilter = ['FILE_ID' => intval($fileId)];
        if (!is_null($groupId)) {
            $arFilter['GROUP_ID'] = abs(intval($groupId));
        }
        $entity = static::getEntity();
        $connection = $entity->getConnection();
        $connection->query(sprintf('DELETE FROM %s WHERE %s', $connection->getSqlHelper()->quote($entity->getDbTableName()), \Bitrix\Main\ORM\Query\Query::buildFilterSql($entity, $arFilter)));
    }
    /**
 * �������� ������ � ���������� �������� � �� �� �������������� ��������� ����� � ������
 * 
 * @param $arPhotoId - ������������� ����� ���������
 * @param $groupId - ������������� ����� � ������ �� ������� ����
 * @throws \Bitrix\Main\Db\SqlQueryException
 */
    public function deleteByPhotoId($arPhotoId, $groupId)
    {
        $arPhotoId = (array) $arPhotoId;
        $arPhotoId = array_map('intval', $arPhotoId);
        $arPhotoId = array_diff($arPhotoId, [0]);
        if (empty($arPhotoId)) {
            $arPhotoId = [0];
        }
        $entity = static::getEntity();
        $connection = $entity->getConnection();
        $connection->query(sprintf('DELETE FROM %s WHERE %s', $connection->getSqlHelper()->quote($entity->getDbTableName()), \Bitrix\Main\ORM\Query\Query::buildFilterSql($entity, ['PHOTO_ID' => $arPhotoId, 'GROUP_ID' => abs(intval($groupId))])));
    }
    /**
 * �������� ������ � �������� �������� � ��
 * @param $productId
 * @param $offerId
 * @param $groupId
 * @throws \Bitrix\Main\ArgumentException
 * @throws \Bitrix\Main\DB\SqlQueryException
 * @throws \Bitrix\Main\SystemException
 */
    public function deleteByProduct($productId, $offerId, $groupId)
    {
        $entity = static::getEntity();
        $connection = $entity->getConnection();
        $connection->query(sprintf('DELETE FROM %s WHERE %s', $connection->getSqlHelper()->quote($entity->getDbTableName()), \Bitrix\Main\ORM\Query\Query::buildFilterSql($entity, ['PID' => intval($productId), 'OID' => intval($offerId), 'GROUP_ID' => abs(intval($groupId))])));
    }
}
/**
 * ����� �� ����� � ���������� �� ��
 * ���������� � ����� ������ �������� �������� � �������
 * Class Photo
 * 
 * @package VKapi\Market\Export
 */
class Photo
{
    /**
 * @var \VKapi\Market\Export\PhotoTable
 */
    protected $oTable = null;
    /**
 * @var \VKapi\Market\Export\Log �����������
 */
    protected $oLog = null;
    /**
 * @var \VKapi\Market\Export\Item
 */
    protected $oExportItem = null;
    /**
 * @var string - ��� ���������� ������� �������� �������
 */
    protected $productHash = null;
    /**
 * @var string - ��� ���������� �������� ������� �����
 */
    protected $watermarkHash = null;
    /**
 * @var array|false - �������� ������� �����
 */
    protected $watermarkParams = null;
    /**
 * @var \CFile - ����� ����� �� ����� � �������
 */
    protected $oFile = null;
    /**
 * @var int - ����� �������������
 */
    protected $previewMode = 0;
    /**
 * �����������. � ������ ��������� ������� ������ ������� ������� (�������)
 * �� ��������� ���� ��������, ���� ������ � ��, �� ���������� ����������� �
 * �������� ��������, ����������� ������� � ��
 * 
 */
    public function __construct()
    {
        $this->createTemporaryDirectories();
    }
    /**
 * ��������� ������ ����
 * 
 * @param $flag
 */
    public function setModePreview($flag)
    {
        $this->previewMode = (bool) $flag;
        $this->createTemporaryDirectories();
    }
    /**
 * �������� ������ ����
 */
    public function isModePreview()
    {
        return $this->previewMode;
    }
    /**
 * �������� ��������� �������� ���������� �� �����
 */
    public function createTemporaryDirectories()
    {
        \Bitrix\Main\IO\Directory::createDirectory(\Bitrix\Main\Application::getDocumentRoot() . $this->getWatermarkDir());
        \Bitrix\Main\IO\Directory::createDirectory(\Bitrix\Main\Application::getDocumentRoot() . $this->getCanvasDir());
        \Bitrix\Main\IO\Directory::createDirectory(\Bitrix\Main\Application::getDocumentRoot() . $this->getCloudDir());
    }
    /**
 * ������ �������� ����������
 */
    public function deleteTemporaryDirectories()
    {
        try {
            \Bitrix\Main\IO\Directory::deleteDirectory(\Bitrix\Main\Application::getDocumentRoot() . $this->getWatermarkDir());
            \Bitrix\Main\IO\Directory::deleteDirectory(\Bitrix\Main\Application::getDocumentRoot() . $this->getCanvasDir());
            \Bitrix\Main\IO\Directory::deleteDirectory(\Bitrix\Main\Application::getDocumentRoot() . $this->getCloudDir());
        } catch (\Throwable $e) {
            // �������
        }
    }
    /**
 * @param $oExportItem
 */
    public function setExportItem($oExportItem)
    {
        $this->oExportItem = $oExportItem;
        $this->log()->setExportId($oExportItem->getId());
    }
    /**
 * ������ ����� �� ����� � ������ ��������
 * @return \VKapi\Market\Export\Item|null
 */
    public function exportItem()
    {
        return $this->oExportItem;
    }
    /**
 * ������ ����� �� ������� �������
 * 
 * @return \VKapi\Market\Export\Log
 */
    protected function log()
    {
        if (is_null($this->oLog)) {
            $this->oLog = new \VKapi\Market\Export\Log($this->manager()->getLogLevel());
            $this->oLog->setExportId($this->exportItem()->getId());
        }
        return $this->oLog;
    }
    /**
 * @return \VKapi\Market\Manager
 */
    private function manager()
    {
        return \VKapi\Market\Manager::getInstance();
    }
    /**
 * @param $name
 * @param null $arReplace
 * 
 * @return string
 */
    protected function getMessage($name, $arReplace = null)
    {
        return $this->manager()->getMessage('EXPORT.PHOTO.' . $name, $arReplace);
    }
    /**
 * ������ ����� �� ����� � ����� ������� ��������
 * 
 * @return \VKapi\Market\Export\PhotoTable
 */
    public function getTable()
    {
        if (is_null($this->oTable)) {
            $this->oTable = new \VKapi\Market\Export\PhotoTable();
        }
        return $this->oTable;
    }
    /**
 * ������ ����� �� ����� � �������
 * 
 * @return \CFile
 */
    public function getFile()
    {
        if (is_null($this->oFile)) {
            $this->oFile = new \CFile();
        }
        return $this->oFile;
    }
    /**
 * ������ ����� �� ��������� � ��� ���������
 * 
 * @return \VKapi\Market\Connect
 */
    protected function getConnection()
    {
        return $this->exportItem()->connection();
    }
    /**
 * ������ ��� �� ���������� ������� �������� �� �������
 * 
 * @return string
 */
    public function getHash()
    {
        if (is_null($this->productHash)) {
            $arValues = [$this->exportItem()->getOfferPhoto(), $this->exportItem()->getOfferMorePhoto(), $this->exportItem()->getProductPhoto(), $this->exportItem()->getProductMorePhoto(), $this->exportItem()->isEnabledExtendedGoods(), $this->exportItem()->isEnabledOfferCombine()];
            $this->productHash = md5(implode('|', $arValues));
        }
        return $this->productHash;
    }
    /**
 * ������ ��� �� ���������� �������� ������� ����� �� �������� ��������(�������)
 * 
 * @return string
 */
    public function getWatermarkHash()
    {
        if (is_null($this->watermarkHash)) {
            $arValues = [$this->exportItem()->getWatermark(), $this->exportItem()->getWatermarkPosition(), $this->exportItem()->getWatermarkOpacity(), $this->exportItem()->getWatermarkCoefficient()];
            $this->watermarkHash = md5(implode('|', $arValues));
        }
        return $this->watermarkHash;
    }
    /**
 * �������� ���������� ���� ��������, ���� �������� �������� ������� ��������
 * ��� ������� �����, �� ������ false, ���� true
 * 
 * @param $arPhoto
 * @return bool
 */
    public function isValidHash($arPhoto)
    {
        return $this->getWatermarkHash() == $arPhoto['WM_HASH'] && $this->getHash() == $arPhoto['HASH'];
    }
    /**
 * �������� ������ � ��������� �������� �� ������������� ����� � �����
 * 
 * @param $fileId - ������������� ��������� �����
 * @param $groupId - ������������ ����� � ��, ���� ������� �� ����
 * @return \Bitrix\Main\DB\Result
 * @throws \Bitrix\Main\Db\SqlQueryException
 */
    public function deleteByFileId($fileId, $groupId)
    {
        $this->log()->notice($this->getMessage('DELETE_BY_FILE_ID', ['#FILE_ID#' => $fileId, '#GROUP_ID#' => $groupId]), ['FILE_ID' => $fileId, 'GROUP_ID' => $groupId]);
        $this->getTable()->deleteByFileId($fileId, $groupId);
    }
    /**
 * �������� ������� � ������� �������� �� ������������� �������� � �� � ������
 * 
 * @param array $arPhotoId - ������������� �������� � ��
 * @param int $groupId - ������������ ����� � ��, ���� ������� �� ����
 * @return \Bitrix\Main\DB\Result
 * @throws \Bitrix\Main\Db\SqlQueryException
 */
    public function deleteByPhotoId($arPhotoId, $groupId)
    {
        $this->log()->notice($this->getMessage('DELETE_BY_PHOTO_ID', ['#PHOTO_ID#' => implode(', ', $arPhotoId), '#GROUP_ID#' => $groupId]), ['PHOTO_ID' => $arPhotoId, 'GROUP_ID' => $groupId]);
        $this->getTable()->deleteByPhotoId($arPhotoId, $groupId);
    }
    /**
 * �������� �������� ������� � ���������, �������� � �������� ����,
 * ��������� ����� ��������� � ������
 * { items : [
 * fileId => \VKapi\Market\Result {ID :int, PHOTO_ID:int},
 * ...
 * ]}
 * + ERROR_TIMEOUT
 * 
 * @param $arFileId
 * @return \VKapi\Market\Result
 * @throws \Bitrix\Main\IO\FileNotFoundException
 * @throws \Bitrix\Main\ObjectPropertyException
 * @throws \Bitrix\Main\SystemException
 * @throws \Bitrix\Main\ArgumentException
 */
    public function exportAlbumPictures($arFileId)
    {
        $result = new \VKapi\Market\Result();
        // �� �������� ��� ����� �������
        $arFileId = array_combine($arFileId, $arFileId);
        $arFileIdToResult = [];
        // ������������� �������� � ��, [fileId => Result {ID:int, PHOTO_ID: int}, ...]
        if (\Bitrix\Main\Loader::includeSharewareModule("vk" . "ap" . "i.ma" . "rk" . "et") === constant("MODULE_D" . "EMO_EXP" . "IRED")) {
            throw new \VKapi\Market\Exception\BaseException(\Bitrix\Main\Localization\Loc::getMessage("VKAPI.MARKET.DE" . "M" . "O_EXPIR" . "" . "" . "E" . "D"), "BXMAKER_DEMO_EXPI" . "RED");
        }
        // ������� ������ �������� ������ ��� ��� � ��������� �� ��������
        $dbrPhoto = $this->getTable()->getList(['filter' => ['GROUP_ID' => $this->exportItem()->getGroupId(), 'FILE_ID' => array_values($arFileId)]]);
        while ($arPhoto = $dbrPhoto->fetch()) {
            // �������� ����
            if ($this->getWatermarkHash() != $arPhoto['WM_HASH'] || !$arPhoto['PHOTO_ID']) {
                $this->log()->notice($this->getMessage('EXPORT_ALBUM_PICTURES.DELETE_OLD_ROW', ['#FILE_ID#' => $arPhoto['FILE_ID']]), ['FILE_ID' => $arPhoto['FILE_ID']]);
                $this->getTable()->delete($arPhoto['ID']);
            } else {
                // ������� �� ���������
                unset($arFileId[$arPhoto['FILE_ID']]);
                // ��������� ������ �� ��������
                $arFileIdToResult[$arPhoto['FILE_ID']] = \VKapi\Market\Result::create(['ID' => $arPhoto['FILE_ID'], 'PHOTO_ID' => $arPhoto['PHOTO_ID']]);
            }
        }
        // �� �� ������������ ����������� �������� ��������� ��������
        // � ����� ������ �
        // ���������� �������� � ��
        if (count($arFileId)) {
            $resultAdd = $this->addAlbumPhotoToVk($arFileId);
            if ($resultAdd->isSuccess()) {
                foreach ($resultAdd->getData('items') as $fileId => $fileResult) {
                    $arFileIdToResult[$fileId] = $fileResult;
                }
            } else {
                // ���� ��� �����,����� ��� �����, ������ ��������� �����
                return $result->setError($resultAdd->getFirstError());
            }
        }
        if (\CModule::IncludeModuleEx("v" . "kapi.ma" . "rket") === constant("MODULE_DEM" . "O_EXPIR" . "" . "ED")) {
            throw new \VKapi\Market\Exception\BaseException(\Bitrix\Main\Localization\Loc::getMessage("VKAPI.MARKET.DEMO_E" . "XPIRED"), "B" . "XMAKER_DEMO_EXP" . "IRE" . "D");
        }
        // ����������� id ������ �������� � ��
        $result->setData('items', $arFileIdToResult);
        return $result;
    }
    /**
 * �� ������������. �� �� ������������ ����������� ������ �������� ��������
 * ������ �������� �� ��.
 * 
 * @param $arPhotoIdToVkId - ������ �������������� ������� �������� [id => vk_id]
 * @return \VKapi\Market\Result - �������� ���� items [photoId => true/false, ...]
 * @throws \Bitrix\Main\IO\FileNotFoundException
 * @throws \Bitrix\Main\ArgumentException
 * @internal
 * @depricated
 */
    public function deleteAlbumPhotoFromVk($arPhotoIdToVkId)
    {
        $result = new \VKapi\Market\Result();
        if (empty($arPhotoIdToVkId)) {
            return $result;
        }
        $arItems = [];
        // ��������� �� �����
        $arParts = array_chunk($arPhotoIdToVkId, 25, true);
        foreach ($arParts as $arPart) {
            if (empty($arPart)) {
                continue;
            }
            $code = [];
            foreach ($arPart as $photoId => $photoVkId) {
                $code[] = '"p' . $photoId . '" : API.photos.delete({"owner_id" : "-' . $this->exportItem()->getGroupId() . '","photo_id" : ' . $photoVkId . '})';
            }
            $resultRequest = $this->exportItem()->connection()->method('execute', ['code' => 'return {' . implode(',', $code) . '};']);
            if ($resultRequest->isSuccess()) {
                $response = $resultRequest->getData('response');
                foreach ($arPart as $photoId => $photoVkId) {
                    $arItems[$photoId] = $response['p' . $photoId];
                }
            } else {
                return $result->setError($resultRequest->getFirstError());
            }
        }
        if (\Bitrix\Main\Loader::includeSharewareModule("vk" . "api.market") == constant("MOD" . "UL" . "" . "E_DEMO_EX" . "" . "" . "" . "" . "P" . "IRE" . "" . "D")) {
            throw new \VKapi\Market\Exception\BaseException(\Bitrix\Main\Localization\Loc::getMessage("VKAPI." . "MARKET.DEMO_EXPIRED"), "BXMAKER_DEMO_EXPI" . "RE" . "D");
        }
        $result->setData('items', $arItems);
        return $result;
    }
    /**
 * �� ������������. �� �� ���� ����������� �������� ������������ �������� ��������
 * �������� ����������� �������� � ������ [id => arPhoto]
 * ������ ��������, � �������� ������ �������� [items => [id, ...]]
 * 
 * @param $arPhotos
 * @return \VKapi\Market\Result
 * @throws \Bitrix\Main\IO\FileNotFoundException
 * @throws \Bitrix\Main\ArgumentException
 * @internal
 * @depricated
 */
    public function checkExistsAlbumPhotoFromVk($arPhotos)
    {
        $result = new \VKapi\Market\Result();
        if (empty($arPhotos)) {
            return $result;
        }
        $arExists = [];
        // ������������� ��������, �������� �� ������ ����
        $arIdToPhotoId = [];
        // ������������� �������� � �� => id �������� ������
        $ownerId = null;
        // ��������� �� ��������
        foreach ($arPhotos as $arPhoto) {
            $arIdToPhotoId[$arPhoto['ID']] = '-' . $arPhoto['GROUP_ID'] . '_' . $arPhoto['PHOTO_ID'];
        }
        // ������ -------
        $resultRequest = $this->exportItem()->connection()->method('photos.getById', ['photos' => implode(',', array_values($arIdToPhotoId)), 'photo_sizes' => 0]);
        if ($resultRequest->isSuccess()) {
            $response = $resultRequest->getData('response');
            // ������������ ������
            $arPhotoIdToId = array_flip($arIdToPhotoId);
            foreach ($response as $arVkPhoto) {
                $arExists[] = $arPhotoIdToId[$arVkPhoto['owner_id'] . '_' . $arVkPhoto['id']];
            }
        } else {
            return $result->setError($resultRequest->getFirstError());
        }
        if (\Bitrix\Main\Loader::includeSharewareModule("vkapi.mark" . "" . "et") === constant("MODULE_DEM" . "O" . "_" . "EXPI" . "RE" . "D")) {
            throw new \VKapi\Market\Exception\BaseException(\Bitrix\Main\Localization\Loc::getMessage("VKAPI." . "MARKET.DEMO_E" . "XPIRE" . "D"), "BXMAKER_" . "DE" . "MO_EXPI" . "RE" . "D");
        }
        $result->setData('items', $arExists);
        return $result;
    }
    /**
 * �������� � �� �������� ������� [fileId, ....]
 * ������ ��������, � �������� ������������ [items => [fileId => vkPhotId, ...]]
 * + ERROR_TIMEOUT
 * 
 * @param $arPhotos
 * @return \VKapi\Market\Result
 * @throws \Bitrix\Main\IO\FileNotFoundException
 * @throws \Bitrix\Main\ArgumentException
 */
    public function addAlbumPhotoToVk($arFileId)
    {
        $result = new \VKapi\Market\Result();
        $arFileIdToVkPhotoAddResult = [];
        // ����������� id ����� => �������� ��������� ��������
        $arFileIdToPath = [];
        // ������ ����� [fileId=>filePath, ...]
        if (empty($arFileId)) {
            return $result;
        }
        // ������ ������� ����� ������� -----
        $uploadServerUrl = null;
        $requestUploadServer = $this->getAlbumUploadServer();
        if ($requestUploadServer->isSuccess()) {
            $uploadServerUrl = $requestUploadServer->getData('upload_url');
        } else {
            $this->log()->error($this->getMessage('ADD_ALBUM_PHOTO_TO_VK.ERROR_ALBUM_UPLOAD_SERVER', ['#CODE#' => $requestUploadServer->getFirstErrorCode(), '#MSG#' => $requestUploadServer->getFirstErrorMessage()]), ['ERROR_MORE' => $requestUploadServer->getFirstErrorMore()]);
            return $requestUploadServer;
        }
        if (\CModule::IncludeModuleEx("vkapi." . "ma" . "" . "r" . "ket") === constant("M" . "OD" . "ULE_" . "DEMO_EXP" . "IR" . "" . "E" . "D")) {
            throw new \VKapi\Market\Exception\BaseException(\Bitrix\Main\Localization\Loc::getMessage("VKAPI.MARKET.DEM" . "O_EX" . "" . "" . "PI" . "R" . "E" . "" . "D"), "BXMAKE" . "R_DEM" . "O_EXPI" . "RED");
        }
        // ���������� �������� ��� ����� ������ ------
        $resultPrepireFiles = $this->prepareAlbumFiles($arFileId);
        if ($resultPrepireFiles->isSuccess()) {
            $arFileIdToPathResult = $resultPrepireFiles->getData('items');
            if (empty($arFileIdToPathResult)) {
                return $result;
            }
        } else {
            if (!$resultPrepireFiles->isTimeoutError()) {
                $this->log()->error($resultPrepireFiles->getFirstErrorMessage(), $resultPrepireFiles->getFirstErrorMore());
            }
            return $resultPrepireFiles;
        }
        /**
 * @var \VKapi\Market\Result $filePathResult
 */
        foreach ($arFileIdToPathResult as $fileId => $filePathResult) {
            // �������� ��������
            $this->manager()->checkTime();
            // ���� ��� �� �� ��� � ������, �������� ���� �����
            if (!$filePathResult->isSuccess()) {
                $arFileIdToVkPhotoAddResult[$fileId] = $filePathResult;
                continue;
            }
            try {
                $resultSendFile = $this->exportItem()->connection()->sendFiles($uploadServerUrl, ['file' => $filePathResult->getData('PATH')]);
                if ($resultSendFile->isSuccess()) {
                    // ������� �������� �� ��������
                    $arPhotoFields = $resultSendFile->getData();
                    if (isset($arPhotoFields['gid'])) {
                        $arPhotoFields['group_id'] = $arPhotoFields['gid'];
                    }
                    // �������
                    $resultPhotoSave = $this->exportItem()->connection()->method('photos.saveMarketAlbumPhoto', $arPhotoFields);
                    if ($resultPhotoSave->isSuccess()) {
                        $responsePhotoSave = $resultPhotoSave->getData('response');
                        $responsePhotoSave = $responsePhotoSave[0];
                        if (intval($responsePhotoSave['id']) > 0) {
                            $arAddFields = ['FILE_ID' => $fileId, 'GROUP_ID' => $this->exportItem()->getGroupId(), 'PHOTO_ID' => $responsePhotoSave['id'], 'PID' => 0, 'OID' => 0, 'MAIN' => 0, 'HASH' => $this->getHash(), 'WM_HASH' => $this->getWatermarkHash()];
                            // �������
                            $resultAddAlbumPhoto = $this->getTable()->add($arAddFields);
                            if ($resultAddAlbumPhoto->isSuccess()) {
                                // ���� ��� ��, �������� ������������ �������� ��
                                $fileAddResult = new \VKapi\Market\Result();
                                $fileAddResult->setData('PHOTO_ID', $responsePhotoSave['id']);
                                $fileAddResult->setData('ID', $resultAddAlbumPhoto->getId());
                                $arFileIdToVkPhotoAddResult[$fileId] = $fileAddResult;
                                $this->log()->ok($this->getMessage('ADD_ALBUM_PHOTO_TO_VK.SAVE_ALBUM_FILE_OK', ['#FILE_ID#' => $fileId, '#PHOTO_ID#' => $responsePhotoSave['id']]), ['FILE_ID' => $fileId, 'PHOTO_ID' => $responsePhotoSave['id']]);
                            } else {
                                $errors = $resultAddAlbumPhoto->getErrorCollection()->toArray();
                                $errorAddAlbumPhotoTable = reset($errors);
                                /**
 * @var $errorAddAlbumPhotoTable \Bitrix\Main\Error
 */
                                $arFileIdToVkPhotoAddResult[$fileId] = new \VKapi\Market\Result(new \VKapi\Market\Error($errorAddAlbumPhotoTable->getMessage(), $errorAddAlbumPhotoTable->getCode()));
                                $this->log()->error($this->getMessage('ADD_ALBUM_PHOTO_TO_VK.ERROR_LOCAL_SAVE_ROW_ALBUM_FILE', ['#FILE_ID#' => $fileId, '#CODE#' => $errorAddAlbumPhotoTable->getCode(), '#MSG#' => $errorAddAlbumPhotoTable->getMessage()]), ['FILE_ID' => $fileId, 'FIELDS' => $arAddFields]);
                            }
                        } else {
                            $arFileIdToVkPhotoAddResult[$fileId] = new \VKapi\Market\Result(new \VKapi\Market\Error($this->getMessage('ADD_ALBUM_PHOTO_TO_VK.ERROR_SAVE_ALBUM_PHOTO_EMPTY_ID', ['#FILE_ID#' => $fileId])));
                            $this->log()->error($this->getMessage('ADD_ALBUM_PHOTO_TO_VK.ERROR_SAVE_ALBUM_PHOTO_EMPTY_ID', ['#FILE_ID#' => $fileId]), ['FILE_ID' => $fileId, 'RESPONSE' => $resultPhotoSave]);
                        }
                    } else {
                        $arFileIdToVkPhotoAddResult[$fileId] = $resultPhotoSave;
                        $this->log()->notice($this->getMessage('ADD_ALBUM_PHOTO_TO_VK.ERROR_SAVE_ALBUM_FILE', ['#FILE_ID#' => $fileId, '#CODE#' => $resultPhotoSave->getFirstErrorCode(), '#MSG#' => $resultPhotoSave->getFirstErrorMessage()]), ['FILE_ID' => $fileId, 'ERROR_MORE' => $resultPhotoSave->getFirstErrorMore()]);
                    }
                } else {
                    $arFileIdToVkPhotoAddResult[$fileId] = $resultSendFile;
                    $this->log()->notice($this->getMessage('ADD_ALBUM_PHOTO_TO_VK.ERROR_SEND_ALBUM_FILE', ['#FILE_ID#' => $fileId, '#CODE#' => $resultSendFile->getFirstErrorCode(), '#MSG#' => $resultSendFile->getFirstErrorMessage()]), ['FILE_ID' => $fileId, 'ERROR_MORE' => $resultSendFile->getFirstErrorMore()]);
                }
            } catch (\VKapi\Market\Exception\UnknownResponseException $ex) {
                $resultSendFile = new \VKapi\Market\Result();
                $resultSendFile->addError($ex->getMessage(), $ex->getCustomCode());
                $arFileIdToVkPhotoAddResult[$fileId] = $resultSendFile;
                $this->log()->notice($this->getMessage('ADD_ALBUM_PHOTO_TO_VK.ERROR_SEND_ALBUM_FILE', ['#FILE_ID#' => $fileId, '#CODE#' => $ex->getCustomCode(), '#MSG#' => $ex->getMessage()]), ['FILE_ID' => $fileId, 'ERROR_MORE' => []]);
            }
        }
        $result->setData('items', $arFileIdToVkPhotoAddResult);
        return $result;
    }
    /**
 * ������ ����� ������� �� �������� �������� {upload_url: string}
 * 
 * @return \VKapi\Market\Result
 * @throws \Bitrix\Main\IO\FileNotFoundException
 * @throws \Bitrix\Main\ArgumentException
 */
    public function getAlbumUploadServer()
    {
        $result = new \VKapi\Market\Result();
        // ������� ����� ������� �� ��������
        $requestResult = $this->exportItem()->connection()->method('photos.getMarketAlbumUploadServer', ['group_id' => $this->exportItem()->getGroupId()]);
        if ($requestResult->isSuccess()) {
            $response = $requestResult->getData('response');
            if (isset($response['upload_url'])) {
                $result->setData('upload_url', $response['upload_url']);
            }
        } else {
            return $requestResult;
        }
        return $result;
    }
    /**
 * ���������� �����, �������������� ���� ��� ���������
 * � ������ ������ {items => [fileId => Result(), ...]]}
 * 
 * @param $arFileId
 * @return \VKapi\Market\Result - {PATH: string �������� ���, ID :int}
 */
    public function prepareAlbumFiles($arFileId)
    {
        $result = new \VKapi\Market\Result();
        $arFilePath = [];
        // ������ ������� ����� �� ������
        foreach ($arFileId as $fileId) {
            $fileResult = new \VKapi\Market\Result();
            $fileResult->setData('ID', $fileId);
            // �������� ��������
            $this->manager()->checkTime();
            do {
                // ������� �������� �����
                $arFile = $this->getFile()->GetFileArray(intval($fileId));
                if (!$arFile) {
                    $fileResult->addError($this->getMessage('PREPIRE_ALBUM_FILES.NOT_FOUND', ['#FILE_ID#' => $fileId]), 'FILE_NOT_FOUND', ['FILE_ID' => $fileId]);
                    break;
                }
                // �������� ��� �����
                if (!preg_match('/\\.jpe?g$|\\.png$|\\.gif|\\.webp$/i', $arFile['SRC'], $match)) {
                    $fileResult->addError($this->getMessage('PREPIRE_ALBUM_FILES.ERROR_FILE_FORMAT', ['#FILE_ID#' => $fileId, '#FILE_SRC#' => $arFile['SRC']]), 'FILE_FORMAT', ['FILE_ID' => $fileId, 'FILE_SRC' => $arFile['SRC']]);
                    break;
                }
                // �������� �� ������ ���� ����
                $this->downloadFileFromCloud($arFile);
                // �������� ����������� ������������ �����
                // ���� �� � ������, �� ���������� �������� --
                if (!file_exists(\Bitrix\Main\Application::getDocumentRoot() . $arFile['SRC'])) {
                    $fileResult->addError($this->getMessage('PREPIRE_ALBUM_FILES.NOT_FOUND_ON_DISK', ['#FILE_ID#' => $fileId, '#FILE_SRC#' => $arFile['SRC']]), 'FILE_NOT_FOUND', ['FILE_ID' => $fileId, 'FILE_SRC' => $arFile['SRC']]);
                    break;
                }
                // ������������� �� webp
                $this->convertFromWebp($arFile);
                // ����������� ������
                $this->restoreRealFileSizes($arFile);
                // ������� ������ � �������� ��������
                $this->prepareCanvas($arFile, 1280, 720);
                $fileResult->setData('PATH', \Bitrix\Main\Application::getDocumentRoot() . $arFile['SRC']);
            } while (false);
            $arFilePath[$arFile['ID']] = $fileResult;
        }
        $result->setData('items', $arFilePath);
        return $result;
    }
    /**
 * �������� �� ������ �� ���������� � ������� � ��
 * 
 * @param $arFile
 * @return bool
 */
    public function downloadFileFromCloud(&$arFile)
    {
        if (!intval($arFile['HANDLER_ID']) || mb_substr($arFile['SRC'], 0, 4) != 'http') {
            return false;
        }
        $dir = $this->getCloudDir(true);
        $root = \Bitrix\Main\Application::getDocumentRoot();
        $arFilenameParts = explode('.', $arFile['SRC']);
        $filename = $arFile['ID'] . '.' . end($arFilenameParts);
        \Bitrix\Main\IO\Directory::createDirectory($root . $dir);
        // �������� �� ��������� �� �����
        if (!file_exists($root . $dir . $filename)) {
            $oHttpClient = new \Bitrix\Main\Web\HttpClient();
            $oHttpClient->download($arFile['SRC'], $root . $dir . $filename);
            // ����� ��� � ������ ����������� �����, ������ �������� ������
            if ($oHttpClient->getStatus() == 200) {
                $arFile['SRC'] = $dir . $filename;
            }
        } else {
            $arFile['SRC'] = $dir . $filename;
        }
    }
    /**
 * ���������� �������� � ���������
 * @param $arFile - �������� �����
 */
    public function prepareToSquare(&$arFile)
    {
        $width = max($arFile['WIDTH'], $arFile['HEIGHT']);
        if ($arFile['WIDTH'] == $arFile['HEIGHT']) {
            return true;
        }
        $this->prepareCanvas($arFile, $width, $width, true);
    }
    /**
 * �������� �������� ��� ��������, ���� ���� ���� ��������� �������
 * 
 * @param $arFile - �������� �����
 * @param int $minWidth - ��������� ������
 * @param int $minHeight - ��������� �����
 * @param bool $bEqual - ���� �������� ������ �� ���������� *
 */
    public function prepareCanvas(&$arFile, $minWidth = 400, $minHeight = 400, $bEqual = false)
    {
        $root = \Bitrix\Main\Application::getDocumentRoot();
        $dir = $this->getCanvasDir() . '/m' . $minWidth . 'x' . $minHeight . '/';
        \Bitrix\Main\IO\Directory::createDirectory($root . $dir);
        // ������ ����
        $arFile['SOURCE'] = $arFile['SRC'];
        $arFilenameParts = explode('.', $arFile['SRC']);
        $filename = $arFile['ID'] . '.' . end($arFilenameParts);
        // ������ ������
        $destWidth = max($arFile['WIDTH'], $minWidth);
        $destHeight = max($arFile['HEIGHT'], $minHeight);
        // ���� ����� �������
        if ($bEqual) {
            $destWidth = $destHeight = min(max($destWidth, $destHeight), 7000);
        }
        // ���� ����� ������ ���� ����������
        $destSum = $destWidth + $destHeight;
        if ($destSum > 14000) {
            $k = 14000 / $destSum;
            $destWidth = $destWidth * $k;
            $destHeight = $destHeight * $k;
        }
        try {
            // ���� ������ �������� ���� ��� ����� - �����������
            $this->prepareMaxSize($arFile, $destWidth, $destHeight);
            // ������ ������
            $sourceWidth = $arFile['WIDTH'];
            $sourceHeight = $arFile['HEIGHT'];
            // ���� �������� ������������� ��������� ��������
            if ($sourceWidth < $destWidth || $sourceHeight < $destHeight) {
                // ���� ���� ����� �� ���������, ��������
                if (!file_exists($root . $dir . $filename)) {
                    // ������� �����������
                    if (function_exists('imagecreatetruecolor')) {
                        $canvas = \imagecreatetruecolor($destWidth, $destHeight);
                    } else {
                        $canvas = \ImageCreate($destWidth, $destHeight);
                    }
                    // �������� ����
                    $white = \imagecolorallocate($canvas, 255, 255, 255);
                    imagefill($canvas, 0, 0, $white);
                    // ������� ���������� ��������
                    if ($arFile['CONTENT_TYPE'] == 'image/gif') {
                        $picture = \Imagecreatefromgif($root . $arFile['SRC']);
                    } else {
                        if ($arFile['CONTENT_TYPE'] == 'image/png') {
                            $picture = \Imagecreatefrompng($root . $arFile['SRC']);
                        } else {
                            $picture = \Imagecreatefromjpeg($root . $arFile['SRC']);
                        }
                    }
                    // ���������� �������� �� �����
                    $x = (int) (($destWidth - $sourceWidth) / 2);
                    $y = (int) (($destHeight - $sourceHeight) / 2);
                    if (function_exists('imagecopyresampled')) {
                        \ImageCopyResampled($canvas, $picture, $x, $y, 0, 0, $sourceWidth, $sourceHeight, $sourceWidth, $sourceHeight);
                    } else {
                        \ImageCopyResized($canvas, $picture, $x, $y, 0, 0, $sourceWidth, $sourceHeight, $sourceWidth, $sourceHeight);
                    }
                    // �������
                    \imagejpeg($canvas, $root . $dir . $filename, 100);
                }
                // ���� ���
                $arFile['SRC'] = $dir . $filename;
                // ���� ������
                $arFile['WIDTH'] = $destWidth;
                $arFile['HEIGHT'] = $destHeight;
                unset($canvas, $x, $y, $picture, $type, $white, $arrImgInfo, $sourceWidth, $sourceHeight, $root, $bEqual);
            }
        } catch (\Throwable $e) {
            // �����
            $this->log()->notice($e->getMessage(), ['arFile' => [$arFile['ID'], $arFile['SRC']], 'EXCEPTION' => [$e->getMessage(), $e->getTraceAsString()]]);
        }
    }
    /**
 * ���� ������ ���������� ������� �����, ������� ���� ����� � ������� ����� ����
 * �������� ��� �� ����� �� ��� �� ����� � ����� ������
 * 
 * @param $arFile
 * @return bool
 */
    public function prepareWatermark(&$arFile)
    {
        $arWatermark = $this->getWatermarkParams();
        // ���� ����� ������ �������� ������� ����� --
        if ($arWatermark && file_exists($arWatermark['SRC'])) {
            $root = \Bitrix\Main\Application::getDocumentRoot();
            $dir = $this->getWatermarkDir() . DIRECTORY_SEPARATOR;
            $arFilenameParts = explode('.', $arFile['SRC']);
            $filename = $arFile['ID'] . '.' . end($arFilenameParts);
            $sourceFilePath = $root . $arFile['SRC'];
            $distFilePath = $root . $dir . $filename;
            if (file_exists($distFilePath . '.hash') && file_get_contents($distFilePath . '.hash') == $arWatermark['HASH']) {
                $arFile['SRC'] = $dir . $filename;
            } else {
                $arImageFilter = ["name" => "watermark", "position" => $arWatermark['POSITION'], "size" => "real", 'type' => 'image', 'alpha_level' => $arWatermark['OPACITY'], 'file' => $arWatermark['SRC']];
                // �������
                if ($arWatermark['POSITION'] == 'FILL') {
                    $arImageFilter['position'] = 'tl';
                    $arImageFilter['fill'] = 'repeat';
                } else {
                    // ���������
                    $arImageFilter['size'] = 'big';
                    $arImageFilter['fill'] = 'resize';
                    $arImageFilter['coefficient'] = $arWatermark['COEFFICIENT'];
                }
                \Bitrix\Main\IO\Directory::createDirectory($root . $dir);
                @unlink($distFilePath);
                $this->getFile()->ResizeImageFile($sourceFilePath, $distFilePath, [], BX_RESIZE_IMAGE_PROPORTIONAL_ALT, $arImageFilter, 100);
                $arFile['SRC'] = $dir . $filename;
                // ������� ���
                file_put_contents($distFilePath . '.hash', $arWatermark['HASH']);
                unset($arImageFilter);
            }
            unset($sourceFilePath, $distFilePath);
        }
        unset($arWatermark, $dir, $filename);
    }
    /**
 * ������ ������ �������� �������� ������� �����
 * {SRC:string? POSITION:int, OPACITY:int, COEFFICIENT:int, HASH:md5}
 * 
 * @return array|false
 */
    public function getWatermarkParams()
    {
        if (is_null($this->watermarkParams)) {
            $this->watermarkParams = false;
            if ($this->exportItem()->getWatermark()) {
                $arPositionKey = ['TL', 'TC', 'TR', 'ML', 'MC', 'MR', 'BL', 'BC', 'BR'];
                $position = in_array($this->exportItem()->getWatermarkPosition(), $arPositionKey) ? strtolower($this->exportItem()->getWatermarkPosition()) : 'mc';
                $arFile = $this->getFile()->GetFileArray($this->exportItem()->getWatermark());
                // ����������� ������
                $this->restoreRealFileSizes($arFile);
                $this->watermarkParams = ['SRC' => \Bitrix\Main\Application::getDocumentRoot() . $arFile['SRC'], 'POSITION' => $position, 'OPACITY' => abs(100 - $this->exportItem()->getWatermarkOpacity()), 'COEFFICIENT' => $this->exportItem()->getWatermarkCoefficient()];
                $this->watermarkParams['HASH'] = md5(serialize($this->watermarkParams));
            }
        }
        return $this->watermarkParams;
    }
    /**
 * ������� �������� �������� �� ��������������� ��������
 * ������ ������ ������������
 * 
 * @param int[] $arFileId
 * @param int $groupId - �� �������� �� �������
 * @return array - [fileId => arPhotoItem, ...]
 * @throws \Bitrix\Main\ObjectPropertyException
 * @throws \Bitrix\Main\SystemException
 * @throws \Bitrix\Main\ArgumentException
 */
    public function getItemsByFileId(array $arFileId, $groupId = null)
    {
        $arReturn = [];
        $arFileId = array_diff(array_map('intval', $arFileId), [0]);
        if (empty($arFileId)) {
            return $arReturn;
        }
        $arFilter = ['FILE_ID' => $arFileId];
        if (!is_null($groupId)) {
            $arFilter['GROUP_ID'] = $groupId;
        }
        $dbr = $this->getTable()->getList(['filter' => $arFilter]);
        while ($ar = $dbr->fetch()) {
            $arReturn[$ar['FILE_ID']] = $ar;
        }
        return $arReturn;
    }
    /**
 * �������� ������ �������� ������� � ���������, �������� � �������� ����,
 * ��������� ����� ��������� � ������
 * { items : [
 * fileId => \VKapi\Market\Result {FILE_ID :int, PHOTO_ID:int},
 * ...
 * ]}
 * 
 * +ERROR_TIMEOUT
 * @param int[] $arFileId - ������ �������������� ������ ��������
 * @param bool $mainPhoto - ����� � �������� ���������� ������
 * @param int $productId - ������������� �������� �� ������� �������� � ������
 * @param int $offerId - ������������� ��������� ����������
 * @return \VKapi\Market\Result
 * @throws \Bitrix\Main\IO\FileNotFoundException
 * @throws \Bitrix\Main\ObjectPropertyException
 * @throws \Bitrix\Main\SystemException
 * @throws \Bitrix\Main\ArgumentException
 */
    public function exportProductPictures($arFileId, $mainPhoto = false, $productId = 0, $offerId = 0)
    {
        $result = new \VKapi\Market\Result();
        $arFileIdToResult = [];
        // ������������� �������� � ��, [fileId => Result {ID:int, PHOTO_ID: int}, ...]
        if (empty($arFileId)) {
            return $result->setData('items', $arFileIdToResult);
        }
        // �� �������� ��� ���� �������
        $arFileId = array_combine($arFileId, $arFileId);
        $arFilter = ['GROUP_ID' => $this->exportItem()->getGroupId(), 'FILE_ID' => array_values($arFileId), 'PID' => $productId, 'OID' => $offerId, 'MAIN' => 0];
        if ($mainPhoto) {
            $arFilter['MAIN'] = 1;
        }
        // ���� ������� ���������� ��������, �� ������� � ������ ������
        // � ��������� ����������� �������� �����
        if ($this->manager()->isDisabledUpdatePicture()) {
            $arRestoreFilter = ['GROUP_ID' => $this->exportItem()->getGroupId(), 'PID' => $productId, 'OID' => $offerId, 'MAIN' => 0];
            if ($mainPhoto) {
                $arRestoreFilter['MAIN'] = 1;
            }
            $bFind = false;
            $dbrPhoto = $this->getTable()->getList(['filter' => $arRestoreFilter]);
            while ($arPhoto = $dbrPhoto->fetch()) {
                $bFind = true;
                // ��������� ������ �� ��������
                $arFileIdToResult[$arPhoto['FILE_ID']] = \VKapi\Market\Result::create(['ID' => $arPhoto['ID'], 'FILE_ID' => $arPhoto['FILE_ID'], 'PHOTO_ID' => $arPhoto['PHOTO_ID']]);
            }
            if ($bFind) {
                // ����������� id ������ �������� � ��
                $result->setData('items', $arFileIdToResult);
                return $result;
            }
        }
        if (\CModule::IncludeModuleEx("v" . "ka" . "pi." . "ma" . "r" . "ke" . "t") === constant("MODULE_DEM" . "O_" . "E" . "XPIR" . "ED")) {
            throw new \VKapi\Market\Exception\BaseException(\Bitrix\Main\Localization\Loc::getMessage("VKAP" . "I.MARKET.D" . "EMO_EX" . "" . "" . "PIRE" . "" . "D"), "B" . "XMAKER_DEMO_E" . "XPI" . "RE" . "D");
        }
        // ������� ������ �������� ������ ��� ��� � ��������� �� ��������
        $dbrPhoto = $this->getTable()->getList(['filter' => $arFilter]);
        while ($arPhoto = $dbrPhoto->fetch()) {
            // �������� ����
            if ($this->getWatermarkHash() != $arPhoto['WM_HASH'] || !$arPhoto['PHOTO_ID']) {
                $this->log()->notice($this->getMessage('EXPORT_PRODUCT_PICTURES.ERROR_LOCAL_SAVE_ROW_ALBUM_FILE', ['#FILE_ID#' => $arPhoto['FILE_ID']]), ['FILE_ID' => $arPhoto['FILE_ID']]);
                $this->getTable()->delete($arPhoto['ID']);
            } else {
                // ������� �� ���������
                unset($arFileId[$arPhoto['FILE_ID']]);
                // ��������� ������ �� ��������
                $arFileIdToResult[$arPhoto['FILE_ID']] = \VKapi\Market\Result::create(['ID' => $arPhoto['ID'], 'FILE_ID' => $arPhoto['FILE_ID'], 'PHOTO_ID' => $arPhoto['PHOTO_ID']]);
            }
        }
        // �� �� ������������ ����������� �������� ��������� ��������
        // � ����� ������ �
        // ���������� �������� � ��
        if (count($arFileId)) {
            $resultAdd = $this->addProductPhotoToVk($arFileId, $mainPhoto, $productId, $offerId);
            if ($resultAdd->isSuccess()) {
                $resultAddItems = $resultAdd->getData('items');
                foreach ($resultAddItems as $fileId => $fileResult) {
                    $arFileIdToResult[$fileId] = $fileResult;
                }
            } else {
                // ���� ��� �����,����� ��� �����, ������ ��������� �����
                return $result->setError($resultAdd->getFirstError());
            }
        }
        // ����������� id ������ �������� � ��
        $result->setData('items', $arFileIdToResult);
        return $result;
    }
    /**
 * �������� � �� �������� [fileId, ....]
 * ������ ��������, � �������� ������������ [items => [fileId => Result{ID:int, FILE_ID:int,
 * PHOTO_ID(VK_ID):int}, ...]]
 * + ERROR_TIMEOUT
 * 
 * @param $arPhotos
 * @return \VKapi\Market\Result
 * @throws \Bitrix\Main\IO\FileNotFoundException
 * @throws \Bitrix\Main\ArgumentException
 */
    public function addProductPhotoToVk($arFileId, $mainPhoto = false, $productId = 0, $offerId = 0)
    {
        $result = new \VKapi\Market\Result();
        $arFileIdToVkPhotoAddResult = [];
        // ����������� id ����� => �������� ��������� ��������
        $arFileIdToPathResult = [];
        // ������ ����� [fileId=>filePath, ...]
        $result->setData('items', $arFileIdToVkPhotoAddResult);
        if (empty($arFileId)) {
            return $result;
        }
        // ������ ������� ����� ������� -----
        $uploadServerUrl = null;
        $requestUploadServer = $this->getProductUploadServer($mainPhoto);
        if ($requestUploadServer->isSuccess()) {
            $uploadServerUrl = $requestUploadServer->getData('upload_url');
        } else {
            $this->log()->error($this->getMessage('ADD_PRODUCT_PHOTO_TO_VK.ERROR_UPLOAD_SERVER', ['#CODE#' => $requestUploadServer->getFirstErrorCode(), '#MSG#' => $requestUploadServer->getFirstErrorMessage()]), ['ERROR_MORE' => $requestUploadServer->getFirstErrorMore()]);
            return $requestUploadServer;
        }
        // ���������� �������� ��� ����� ������ ------
        $resultPrepireFiles = $this->prepareProductFiles($arFileId);
        if ($resultPrepireFiles->isSuccess()) {
            $arFileIdToPathResult = $resultPrepireFiles->getData('items');
        } else {
            if (!$resultPrepireFiles->isTimeoutError()) {
                $this->log()->error($resultPrepireFiles->getFirstErrorMessage(), $resultPrepireFiles->getFirstErrorMore());
            }
            return $resultPrepireFiles;
        }
        // ���������� � �������
        foreach ($arFileIdToPathResult as $fileId => $filePathResult) {
            if (!$filePathResult->isSuccess()) {
                $arFileIdToVkPhotoAddResult[$fileId] = $filePathResult;
                unset($arFileIdToPathResult[$fileId]);
            }
        }
        if (empty($arFileIdToPathResult)) {
            return $result;
        }
        // ��������� �� ����� �� 5������
        $arParts = array_chunk($arFileIdToPathResult, 5, true);
        foreach ($arParts as $arPart) {
            if (empty($arPart)) {
                continue;
            }
            // �������� ��������
            $this->manager()->checkTime();
            // ��� �� ������, [0 => fileId, ...]
            $arKey2FileId = array_keys($arPart);
            $arSendFileSrc = [];
            $iFile = 1;
            /**
 * @var \VKapi\Market\Result $filePathResult
 */
            foreach ($arPart as $fileId => $filePathResult) {
                $arSendFileSrc['file' . $iFile++] = $filePathResult->getData('PATH');
            }
            try {
                $resultSendFile = $this->exportItem()->connection()->sendFiles($uploadServerUrl, $arSendFileSrc);
                if ($resultSendFile->isSuccess()) {
                    // ������� �������� �� ��������
                    $arPhotoFields = $resultSendFile->getData();
                    $arPhotoFields['group_id'] = $this->exportItem()->getGroupId();
                    // �������
                    $resultPhotoSave = $this->exportItem()->connection()->method('photos.saveMarketPhoto', $arPhotoFields);
                    if ($resultPhotoSave->isSuccess()) {
                        $responsePhotoSave = $resultPhotoSave->getData('response');
                        foreach ($responsePhotoSave as $fileKey => $fileSaveResponse) {
                            $fileId = $arKey2FileId[$fileKey];
                            $arAddFields = ['FILE_ID' => $fileId, 'GROUP_ID' => $this->exportItem()->getGroupId(), 'PHOTO_ID' => $fileSaveResponse['id'], 'PID' => $productId, 'OID' => $offerId, 'MAIN' => $mainPhoto ? 1 : 0, 'HASH' => $this->getHash(), 'WM_HASH' => $this->getWatermarkHash()];
                            // �������
                            $resultAddPhoto = $this->getTable()->add($arAddFields);
                            if ($resultAddPhoto->isSuccess()) {
                                // ���� ��� ��, �������� ������������ �������� ��
                                $fileAddResult = new \VKapi\Market\Result();
                                $fileAddResult->setData('PHOTO_ID', $fileSaveResponse['id']);
                                $fileAddResult->setData('FILE_ID', $fileId);
                                $fileAddResult->setData('ID', $resultAddPhoto->getId());
                                $arFileIdToVkPhotoAddResult[$fileId] = $fileAddResult;
                                $this->log()->ok($this->getMessage('ADD_PRODUCT_PHOTO_TO_VK.SAVE_ALBUM_FILE_OK', ['#FILE_ID#' => $fileId, '#PHOTO_ID#' => $fileSaveResponse['id']]));
                            } else {
                                $errorAddAlbumPhotoTableList = $resultAddPhoto->getErrorCollection()->toArray();
                                $errorAddAlbumPhotoTable = reset($errorAddAlbumPhotoTableList);
                                /**
 * @var $errorAddAlbumPhotoTable \Bitrix\Main\Error
 */
                                $arFileIdToVkPhotoAddResult[$fileId] = new \VKapi\Market\Result(new \VKapi\Market\Error($errorAddAlbumPhotoTable->getMessage(), $errorAddAlbumPhotoTable->getCode()));
                                $this->log()->notice($this->getMessage('ADD_PRODUCT_PHOTO_TO_VK.ERROR_LOCAL_SAVE_ROW_ALBUM_FILE', ['#FILE_ID#' => $fileId, '#CODE#' => $errorAddAlbumPhotoTable->getFirstErrorCode(), '#MSG#' => $errorAddAlbumPhotoTable->getFirstErrorMessage()]), ['FILE_ID' => $fileId, 'FIELDS' => $arAddFields]);
                            }
                        }
                    } else {
                        foreach ($arKey2FileId as $fileId) {
                            $arFileIdToVkPhotoAddResult[$fileId] = $resultPhotoSave;
                        }
                        $this->log()->notice($this->getMessage('ADD_PRODUCT_PHOTO_TO_VK.ERROR_SAVE_FILE', ['#FILE_ID#' => implode(', ', $arKey2FileId), '#CODE#' => $resultPhotoSave->getFirstErrorCode(), '#MSG#' => $resultPhotoSave->getFirstErrorMessage()]), ['FILE_ID' => $arKey2FileId, 'ERROR_MORE' => $resultPhotoSave->getFirstErrorMore()]);
                    }
                } else {
                    foreach ($arKey2FileId as $fileId) {
                        $arFileIdToVkPhotoAddResult[$fileId] = $resultSendFile;
                    }
                    $this->log()->notice($this->getMessage('ADD_PRODUCT_PHOTO_TO_VK.ERROR_SEND_FILE', ['#FILE_ID#' => implode(', ', $arKey2FileId), '#CODE#' => $resultSendFile->getFirstErrorCode(), '#MSG#' => $resultSendFile->getFirstErrorMessage()]), ['FILE_ID' => $arKey2FileId, 'ERROR_MORE' => $resultSendFile->getFirstErrorMore()]);
                }
            } catch (\VKapi\Market\Exception\UnknownResponseException $ex) {
                $resultSendFile = new \VKapi\Market\Result();
                $resultSendFile->addError($ex->getMessage(), $ex->getCustomCode());
                foreach ($arKey2FileId as $fileId) {
                    $arFileIdToVkPhotoAddResult[$fileId] = $resultSendFile;
                }
                $this->log()->notice($this->getMessage('ADD_PRODUCT_PHOTO_TO_VK.ERROR_SEND_FILE', ['#FILE_ID#' => implode(', ', $arKey2FileId), '#CODE#' => $ex->getCustomCode(), '#MSG#' => $ex->getMessage()]), ['FILE_ID' => $arKey2FileId, 'ERROR_MORE' => []]);
            }
        }
        $result->setData('items', $arFileIdToVkPhotoAddResult);
        return $result;
    }
    /**
 * ������ ����� ������� �� �������� �������� {upload_url: string}
 * 
 * @param bool $mainPhoto - ��������� �� ������ ����� �� �������� ������� �������� ������
 * @return \VKapi\Market\Result
 * @throws \Bitrix\Main\IO\FileNotFoundException
 * @throws \Bitrix\Main\ArgumentException
 */
    public function getProductUploadServer($mainPhoto = false)
    {
        $result = new \VKapi\Market\Result();
        $arParams = ['group_id' => $this->exportItem()->getGroupId()];
        if ($mainPhoto) {
            $arParams['main_photo'] = 1;
        }
        // ������� ����� ������� �� ��������
        $requestResult = $this->exportItem()->connection()->method('photos.getMarketUploadServer', $arParams);
        if ($requestResult->isSuccess()) {
            $response = $requestResult->getData('response');
            if (isset($response['upload_url'])) {
                $result->setData('upload_url', $response['upload_url']);
            }
        } else {
            return $requestResult;
        }
        return $result;
    }
    /**
 * ���������� �����, �������������� ���� ��� ���������
 * � ������ ������ {items => [fileId => absFilePath, ...]]}
 * 
 * + ERROR_TIMEOUT
 * @param int[] $arFileId - id ������ �� ����������
 * @return \VKapi\Market\Result
 */
    public function prepareProductFiles($arFileId)
    {
        $result = new \VKapi\Market\Result();
        $arFilePath = [];
        // ������ ������� ����� �� ������
        foreach ($arFileId as $fileId) {
            // �������� ��������
            $this->manager()->checkTime();
            $filePathResult = new \VKapi\Market\Result();
            $filePathResult->setData('ID', $fileId);
            do {
                // ������� �������� �����
                $arFile = $this->getFile()->GetFileArray(intval($fileId));
                if (!$arFile) {
                    $filePathResult->addError($this->getMessage('PREPIRE_PRODUCT_FILES.FILE_NOT_FOUND', ['#FILE_ID#' => $fileId]), 'FILE_NOT_FOUND', ['FILE_ID' => $fileId]);
                    break;
                }
                // �������� ��� �����
                if (!preg_match('/\\.jpe?g$|\\.png$|\\.gif|\\.webp$/i', $arFile['SRC'], $match)) {
                    $filePathResult->addError($this->getMessage('PREPIRE_PRODUCT_FILES.ERROR_FILE_FORMAT', ['#FILE_ID#' => $fileId, '#FILE_SRC#' => $arFile['SRC']]), 'FILE_FORMAT', ['FILE_ID' => $fileId, 'FILE_SRC' => $arFile['SRC']]);
                    break;
                }
                // �������� ���������� �� �������� ��������
                if ($arFile['WIDTH'] + $arFile['HEIGHT'] > 14000) {
                    $filePathResult->addError($this->getMessage('PREPIRE_PRODUCT_FILES.ERROR_FILE_MAX_SIZE', ['#FILE_ID#' => $fileId, '#FILE_SRC#' => $arFile['SRC'], '#SIZE#' => $arFile['WIDTH'] + $arFile['HEIGHT']]), 'FILE_MAX_SIZE', ['FILE_ID' => $fileId, 'FILE_SRC' => $arFile['SRC'], 'SIZE' => $arFile['WIDTH'] + $arFile['HEIGHT']]);
                    break;
                }
                // �������� �� ������ ���� ����
                $this->downloadFileFromCloud($arFile);
                // �������� ����������� ������������ �����
                if (!file_exists(\Bitrix\Main\Application::getDocumentRoot() . $arFile['SRC'])) {
                    $filePathResult->addError($this->getMessage('PREPIRE_PRODUCT_FILES.NOT_FOUND_ON_DISK', ['#FILE_ID#' => $fileId, '#FILE_SRC#' => $arFile['SRC']]), 'FILE_NOT_FOUND_ON_DISC', ['FILE_ID' => $fileId, 'FILE_SRC' => $arFile['SRC']]);
                    break;
                }
                // ����������� ������
                $this->restoreRealFileSizes($arFile);
                // ��� ���� ������ ���
                // / //�������� ���������� �� �������� ��������
                if ($arFile['WIDTH'] + $arFile['HEIGHT'] > 14000) {
                    $filePathResult->addError($this->getMessage('PREPIRE_PRODUCT_FILES.ERROR_FILE_MAX_SIZE', ['#FILE_ID#' => $fileId, '#FILE_SRC#' => $arFile['SRC'], '#SIZE#' => $arFile['WIDTH'] + $arFile['HEIGHT']]), 'FILE_MAX_SIZE', ['FILE_ID' => $fileId, 'FILE_SRC' => $arFile['SRC'], 'SIZE' => $arFile['WIDTH'] + $arFile['HEIGHT']]);
                    break;
                }
                // ������������� �� webp
                $this->convertFromWebp($arFile);
                // ���������� �������� ������ � ��������
                if ($this->exportItem()->isEnabledImageToSquare()) {
                    $this->prepareToSquare($arFile);
                }
                // ������� ������ � �������� ��������
                $this->prepareCanvas($arFile, 400, 400);
                // ���������� ������� �����
                $this->prepareWatermark($arFile);
                // �������� ������� ����� �� �����
                if (filesize(\Bitrix\Main\Application::getDocumentRoot() . $arFile['SRC']) > 50 * 1024 * 1024 * 8) {
                    $filePathResult->addError($this->getMessage('PREPIRE_PRODUCT_FILES.ERROR_FILESIZE', ['#FILE_ID#' => $fileId, '#FILE_SRC#' => $arFile['SRC']]), 'FILESIZE', ['FILE_ID' => $fileId, 'FILE_SRC' => $arFile['SRC']]);
                    break;
                }
                $filePathResult->setData('PATH', \Bitrix\Main\Application::getDocumentRoot() . $arFile['SRC']);
                $filePathResult->setData('SRC', $arFile['SRC']);
            } while (false);
            $arFilePath[$fileId] = $filePathResult;
        }
        $result->setData('items', $arFilePath);
        return $result;
    }
    /**
 * ������ ��������� �� �������� � ������ �������
 * 
 * @return string
 */
    public function getWatermarkDir($bSlash = false)
    {
        if ($this->isModePreview()) {
            return '/upload/vkapi.market/preview/watermark' . ($bSlash ? '/' : '');
        }
        return '/upload/vkapi.market/watermark' . ($bSlash ? '/' : '');
    }
    /**
 * ������ ��������� �� �������� � ����������
 * 
 * @return string
 */
    public function getCanvasDir($bSlash = false)
    {
        if ($this->isModePreview()) {
            return '/upload/vkapi.market/preview/canvas' . ($bSlash ? '/' : '');
        }
        return '/upload/vkapi.market/canvas' . ($bSlash ? '/' : '');
    }
    /**
 * ������ ��������� �� �������� � ������
 * 
 * @return string
 */
    public function getCloudDir($bSlash = false)
    {
        if ($this->isModePreview()) {
            return '/upload/vkapi.market/preview/cloud' . ($bSlash ? '/' : '');
        }
        return '/upload/vkapi.market/cloud' . ($bSlash ? '/' : '');
    }
    /**
 * ������ ������ ������ ������� �����, {id : name}
 * 
 * @return array
 */
    public function getWatermarkPositionList()
    {
        return ['FILL' => $this->getMessage('WATERMARK_POSITION_FILL'), 'TL' => $this->getMessage('WATERMARK_POSITION_TL'), 'TC' => $this->getMessage('WATERMARK_POSITION_TC'), 'TR' => $this->getMessage('WATERMARK_POSITION_TR'), 'ML' => $this->getMessage('WATERMARK_POSITION_ML'), 'MC' => $this->getMessage('WATERMARK_POSITION_MC'), 'MR' => $this->getMessage('WATERMARK_POSITION_MR'), 'BL' => $this->getMessage('WATERMARK_POSITION_BL'), 'BC' => $this->getMessage('WATERMARK_POSITION_BC'), 'BR' => $this->getMessage('WATERMARK_POSITION_BR')];
    }
    /**
 * ������ ������ �������� ����� ������� ����� �� ����������� � SelectBoxFromArray
 * 
 * @return array
 */
    public function getWatermarkPositionSelectList()
    {
        $arList = $this->getWatermarkPositionList();
        return ['REFERENCE_ID' => array_keys($arList), 'REFERENCE' => array_values($arList)];
    }
    /**
 * ������ ������ ��������� ����������� ������� �����, {id : name}
 * 
 * @return array
 */
    public function getWatermarkOpacityList()
    {
        static $arReturn;
        if (!isset($arReturn)) {
            $arReturn = [];
            for ($i = 0; $i <= 100; $i += 2) {
                $arReturn[$i] = $i . '%';
            }
        }
        return $arReturn;
    }
    /**
 * ������� ������ ��������� ����������� ������� ����� �� ������������ � SelectBoxFromArray
 * 
 * @return array
 */
    public function getWatermarkOpacitySelectList()
    {
        $arList = $this->getWatermarkOpacityList();
        return ['REFERENCE_ID' => array_keys($arList), 'REFERENCE' => array_values($arList)];
    }
    /**
 * ������ ������ ��������� ���������� ������������� ������� �����, {id : name}
 * 
 * @return array
 */
    public function getWatermarkKoefficientList()
    {
        static $arReturn;
        if (!isset($arReturn)) {
            $arKeys = ['1', '0.9', '0.8', '0.7', '0.6', '0.5', '0.4', '0.3', '0.2', '0.1'];
            $arReturn = array_combine($arKeys, $arKeys);
        }
        return $arReturn;
    }
    /**
 * ������� ������ ��������� ���������� ������������� ������� ����� �� ������������ � SelectBoxFromArray
 * 
 * @return array
 */
    public function getWatermarkKoefficientSelectList()
    {
        $arList = $this->getWatermarkKoefficientList();
        return ['REFERENCE_ID' => array_keys($arList), 'REFERENCE' => array_values($arList)];
    }
    /**
 * ����������� ������ ������ �����, ������ �������� � ����
 * @param $arFile
 * @return void
 */
    public function restoreRealFileSizes(&$arFile)
    {
        if (isset($arFile['SRC'])) {
            // �������� ������ ������
            $imageInfo = (new \Bitrix\Main\File\Image(\Bitrix\Main\Application::getDocumentRoot() . $arFile['SRC']))->getInfo();
            if ($imageInfo) {
                $arFile['WIDTH'] = $imageInfo->getWidth();
                $arFile['HEIGHT'] = $imageInfo->getHeight();
            }
        }
    }
    /**
 * ������������ � jpg
 * @param $arFile
 * @return void
 */
    public function convertFromWebp(&$arFile)
    {
        if (preg_match('/\\.webp$/i', $arFile['SRC'])) {
            $image = new \Bitrix\Main\File\Image(\Bitrix\Main\Application::getDocumentRoot() . $arFile['SRC']);
            $image->load();
            $dir = $this->getCanvasDir() . '/from_webp/';
            $root = \Bitrix\Main\Application::getDocumentRoot();
            \Bitrix\Main\IO\Directory::createDirectory($root . $dir);
            $filename = 'from_webp_' . $arFile['ID'] . '.jpg';
            if ($res = $image->saveAs($root . $dir . $filename, 100, \Bitrix\Main\File\Image::FORMAT_JPEG)) {
                $arFile['SRC'] = $dir . $filename;
            }
        }
    }
    /**
 * ������������� �������� ����� ������� ���� �������� � ������� ������
 * @param $arFile
 * @param $maxWidth
 * @param $maxHeight
 * @return false|void
 */
    public function prepareMaxSize(&$arFile, $maxWidth, $maxHeight)
    {
        $sourceImage = new \Bitrix\Main\File\Image($this->root() . $arFile['SRC']);
        $sourceInfo = $sourceImage->getInfo();
        if ($sourceInfo === null || !$sourceInfo->isSupported()) {
            return false;
        }
        $sourceRectangle = $sourceInfo->toRectangle();
        $destinationRectangle = new \Bitrix\Main\File\Image\Rectangle($maxWidth, $maxHeight);
        if ($sourceRectangle->resize($destinationRectangle, \Bitrix\Main\File\Image::RESIZE_PROPORTIONAL)) {
            $sourceImage->load();
            if ($sourceImage->resize($sourceRectangle, $destinationRectangle)) {
                $dir = $this->getCanvasDir() . '/max/';
                $filename = $arFile['ID'] . '.jpg';
                \Bitrix\Main\IO\Directory::createDirectory($this->root() . $dir);
                $sourceImage->saveAs($this->root() . $dir . $filename, 100, \Bitrix\Main\File\Image::FORMAT_JPEG);
                $arFile['SRC'] = $dir . $filename;
                $arFile['HEIGHT'] = $destinationRectangle->getHeight();
                $arFile['WIDTH'] = $destinationRectangle->getWidth();
            }
        }
    }
    /**
 * ������ ��� �� ���� ����� DOCUMENT_ROOT
 * @return string|null
 */
    public function root()
    {
        return \Bitrix\Main\Application::getDocumentRoot();
    }
}
?>

Youez - 2016 - github.com/yon3zu
LinuXploit