Your IP : 127.0.0.1


Current Path : /home/dev2.destoffenstraat.com/app/Firebear/ImportExport/Model/Import/
Upload File :
Current File : /home/dev2.destoffenstraat.com/app/Firebear/ImportExport/Model/Import/Uploader.php

<?php
declare(strict_types=1);
/**
 * @copyright: Copyright © 2017 Firebear Studio. All rights reserved.
 * @author   : Firebear Studio <fbeardev@gmail.com>
 */

namespace Firebear\ImportExport\Model\Import;

use function array_flip;
use function array_search;
use function class_exists;
use function explode;
use finfo;
use Firebear\ImportExport\Helper\MediaHelper;
use Firebear\ImportExport\Model\Filesystem\File\ReadFactory;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\DriverPool;
use Magento\Framework\HTTP\Client\Curl;
use Magento\Framework\Image\AdapterFactory;
use Magento\MediaStorage\Helper\File\Storage;
use Magento\MediaStorage\Helper\File\Storage\Database;
use Magento\MediaStorage\Model\File\Validator\NotProtectedExtension;
use function pathinfo;
use function strpos;
use Symfony\Component\Console\Output\ConsoleOutput;
use Zend_Uri;

/**
 * Class Uploader
 * @api
 * @since 100.0.2
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 * @package Firebear\ImportExport\Model\Import
 */
class Uploader extends \Magento\CatalogImportExport\Model\Import\Uploader
{
    /**
     * Default User Agent chain to prevent 403 forbidden issue
     */
    const DEFAULT_HTTP_USER_AGENT = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)";

    protected $httpScheme = 'http://';
    /**
     * @var MediaHelper
     */
    protected $mediaHelper;

    /**
     * @var Curl
     */
    protected $curl;

    protected $entity;

    /**
     * @var ConsoleOutput
     */
    protected $output;

    /**
     * Uploader constructor.
     *
     * @param Database $coreFileStorageDb
     * @param Storage $coreFileStorage
     * @param AdapterFactory $imageFactory
     * @param NotProtectedExtension $validator
     * @param Filesystem $filesystem
     * @param Filesystem\File\ReadFactory $readFactory
     * @param ReadFactory $fireReadFactory
     * @param MediaHelper $mediaHelper
     * @param Curl $curl
     * @param null $filePath
     *
     * @throws FileSystemException
     * @throws LocalizedException
     */
    public function __construct(
        Database $coreFileStorageDb,
        Storage $coreFileStorage,
        AdapterFactory $imageFactory,
        NotProtectedExtension $validator,
        Filesystem $filesystem,
        Filesystem\File\ReadFactory $readFactory,
        ReadFactory $fireReadFactory,
        MediaHelper $mediaHelper,
        Curl $curl,
        $filePath = null
    ) {
        parent::__construct(
            $coreFileStorageDb,
            $coreFileStorage,
            $imageFactory,
            $validator,
            $filesystem,
            $readFactory,
            $filePath
        );

        $this->_readFactory = $fireReadFactory;
        $this->mediaHelper = $mediaHelper;
        $this->curl = $curl;
    }

    /**
     * @param $entity
     * @return $this
     */
    public function setEntity($entity)
    {
        $this->entity = $entity;
        return $this;
    }

    /**
     * Set TMP file path prefix
     *
     * @param string $path
     * @return bool
     * @throws FileSystemException
     */
    public function setTmpDir($path)
    {
        if (is_string($path)) {
            if (!$this->_directory->isExist($path)) {
                $this->_directory->create($path);
            }
            return parent::setTmpDir($path);
        }
        return false;
    }

    /**
     * @param string $fileName
     * @param bool $renameFileOff
     * @param array $existingUpload
     *
     * @return array
     * @throws FileSystemException
     * @throws LocalizedException
     */
    public function move($fileName, $renameFileOff = false, $existingUpload = [])
    {
        $fileName = trim($fileName);
        if ($this->checkValidUrl($fileName)) {
            if (strpos($fileName, MediaHelper::YOUTUBE) !== false) {
                $fileName = $this->mediaHelper->getYoutubeVideoImage($fileName);
            } elseif (strpos($fileName, MediaHelper::VIMEO) !== false) {
                $fileName = $this->mediaHelper->getVimeoVideoImage($fileName);
            }
        } elseif (strpos($fileName, MediaHelper::YOUTUBE) !== false
            || strpos($fileName, MediaHelper::VIMEO) !== false
        ) {
            $this->entity->addLogWriteln(
                __('Error with downloading image for %1', $fileName),
                $this->getOutput(),
                'error'
            );
            return [];
        }
        $file_info = '';
        $mime_type = $this->getImageMimeType();
        if ($renameFileOff) {
            $this->setAllowRenameFiles(false);
        }
        if (preg_match('/\bhttps?:\/\//i', $fileName, $matches)) {
            if (class_exists(finfo::class)) {
                $file_info = new finfo(FILEINFO_MIME_TYPE);
            }
            $url = str_replace($matches[0], '', $fileName);
            $httpDriver = ($matches[0] === $this->httpScheme) ? DriverPool::HTTP . '://' : DriverPool::HTTPS . '://';
            $urlProp = $this->parseUrl($httpDriver . $url);
            $hostname = $urlProp['host'];
            $path = $urlProp['path'];
            $name = hash('sha256', $fileName);

            $existingUpload = [];
            $existName = $name;
            if (!array_key_exists(pathinfo($existName, PATHINFO_EXTENSION), $this->_allowedMimeTypes)) {
                $existName .= $this->getImageMimeType($mime_type);
            }

            $existFilePath = $this->_directory->getRelativePath($this->getTmpDir() . '/' . $existName);
            if ($this->_directory->isExist($existFilePath)) {
                $destDir = $this->_directory->getAbsolutePath($this->getDestDir());
                $destFile = static::_addDirSeparator(static::getDispersionPath($existName)) . $existName;
                if ($this->_directory->isExist($destDir . $destFile)) {
                    return ['file' => $destFile];
                }
                $this->_setUploadFile($existFilePath);
                return $this->save($destDir);
            }

            if (!$this->isImageQueryString($fileName)) {
                $this->getCurl()
                    ->setOptions(
                        [
                            CURLOPT_RETURNTRANSFER => 1,
                            CURLOPT_BINARYTRANSFER => 1,
                            CURLOPT_FOLLOWLOCATION => 1,
                            CURLOPT_UNRESTRICTED_AUTH => 1,
                        ]
                    );
                $url = $httpDriver . $hostname . $path;
                $newPath = [];
                if (!Zend_Uri::check($url)) {
                    foreach (explode('/', $path) as $p) {
                        $newPath[] = rawurlencode($p);
                    }
                    $path = implode('/', $newPath);
                    $path = str_ireplace(['%C4_', '%C5_'], ['%C4%9F', '%C5%9E'], $path);
                    $url = $this->httpScheme . $hostname . $path;
                }

                if (isset($urlProp['user'], $urlProp['pass'])) {
                    $this->getCurl()
                        ->setOption(
                            CURLOPT_USERPWD,
                            $urlProp['user'] . ':' . $urlProp['pass']
                        );
                }

                $this->getCurl()->get($url);
                $data = $this->getCurl()->getBody();

                if (!getimagesizefromstring($data)) {
                    $this->entity->addLogWriteln(
                        __('Image not found string illegal %1', $url),
                        $this->getOutput(),
                        'error'
                    );
                }
                if ($file_info instanceof finfo) {
                    $mime_type = $file_info->buffer($data);
                }
            } else {
                $options = ['http' => ['user_agent' => self::DEFAULT_HTTP_USER_AGENT]];
                $context = stream_context_create($options);
                $data = $this->_directory->getDriver()->fileGetContents($fileName, null, $context);
                if ($file_info instanceof finfo) {
                    $mime_type = $file_info->buffer($data);
                }
            }

            $tmpDir = $this->_directory->getAbsolutePath($this->getTmpDir());
            $tmpPath = static::_addDirSeparator($tmpDir) . $name;
            $this->_directory->writeFile($tmpPath, $data);

            if (!array_key_exists(pathinfo($name, PATHINFO_EXTENSION), $this->_allowedMimeTypes)) {
                $name .= $this->getImageMimeType($name);
            }

            $fileName = static::_addDirSeparator(static::getDispersionPath($name)) . $name;
            $this->_directory->renameFile($tmpPath, $tmpDir . $fileName);
        }

        $filePath = $this->_directory->getRelativePath($this->getTmpDir() . DIRECTORY_SEPARATOR . $fileName);
        $this->_setUploadFile($filePath);

        if (!isset($name)) {
            $name = $fileName;
        }
        $key = array_search($this->getUploadedFileName(), $existingUpload);
        if ($key !== false) {
            $exp = explode('.', $name);
            $newFileName = $exp[0] . '_' . $key . '.' . $exp[1];
        } else {
            $newFileName = $name;
        }

        $destDir = $this->_directory->getAbsolutePath($this->getDestDir());
        $result = $this->save($destDir, $newFileName);

        unset($result['path']);

        $result['name'] = self::getCorrectFileName($result['name']);
        return $result;
    }

    /**
     * @param $url
     *
     * @return bool
     */
    public function checkValidUrl($url)
    {
        return $this->mediaHelper->checkValidUrl($url);
    }

    /**
     * @param string $mime_type
     *
     * @return string
     */
    private function getImageMimeType($mime_type = 'image/jpeg')
    {
        $fileExtension = array_flip($this->_allowedMimeTypes)[$mime_type] ?? 'jpeg';
        return '.' . $fileExtension;
    }

    /**
     * @param $path
     * @return array|false|int|string|null
     */
    protected function parseUrl($path)
    {
        return parse_url($path);
    }

    /**
     * @param $fileName
     *
     * @return bool
     */
    private function isImageQueryString($fileName)
    {
        return strpos($fileName, '?') !== false;
    }

    /**
     * @return Curl
     */
    public function getCurl()
    {
        return $this->curl;
    }

    /**
     * @return ConsoleOutput
     */
    public function getOutput()
    {
        return $this->output;
    }

    /**
     * @param ConsoleOutput|null $output
     */
    public function setOutput(ConsoleOutput $output = null)
    {
        $this->output = $output;
    }

    /**
     * Create folder
     *
     * @param string $directory
     *
     * @return \Magento\Framework\File\Uploader
     * @throws LocalizedException
     */
    public function createDirectory($directory)
    {
        if (!$directory || !$this->_allowCreateFolders) {
            return $this;
        }

        $directory = (substr($directory, -1) == '/') ? substr($directory, 0, -1) : $directory;

        if (!(is_dir($directory) || mkdir($directory, 0777, true))) {
            throw new LocalizedException(__(
                'Unable to create directory \'%1\'',
                $directory
            ));
        }
        return $this;
    }

    /**
     * @param $directory
     *
     * @return bool
     */
    public function isDirectoryWritable($directory)
    {
        return $this->_directory->isWritable($directory);
    }

    /**
     * @return array
     */
    public function getAllowedFileExtension()
    {
        return array_keys($this->_allowedMimeTypes);
    }

    /**
     * Get dispersion path
     *
     * @param string $fileName
     * @return string
     */
    public static function getDispersionPath($fileName)
    {
        $char = 0;
        $dispersionPath = '';
        while ($char < 2 && $char < strlen($fileName)) {
            if (empty($dispersionPath)) {
                $dispersionPath = '/' . ('.' == $fileName[$char] ? '_' : $fileName[$char]);
            } else {
                $dispersionPath = self::_addDirSeparator($dispersionPath)
                    . ('.' == $fileName[$char] ? '_' : $fileName[$char]);
            }
            $char++;
        }
        return $dispersionPath;
    }
}