ContentUploader.php 4.69 KB
Newer Older
Ketan's avatar
Ketan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Magento\Downloadable\Model\File;

use Magento\MediaStorage\Helper\File\Storage;
use Magento\MediaStorage\Helper\File\Storage\Database;
use Magento\MediaStorage\Model\File\Uploader;
use Magento\MediaStorage\Model\File\Validator\NotProtectedExtension;
use Magento\Downloadable\Api\Data\File\ContentInterface;
use Magento\Downloadable\Model\Link as LinkConfig;
use Magento\Downloadable\Model\Sample as SampleConfig;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Filesystem;

class ContentUploader extends Uploader implements \Magento\Downloadable\Api\Data\File\ContentUploaderInterface
{
    /**
     * Default MIME type
     */
    const DEFAULT_MIME_TYPE = 'application/octet-stream';

    /**
     * Filename prefix for temporary files
     *
     * @var string
     */
    protected $filePrefix = 'magento_api';

    /**
     * @var \Magento\Framework\Filesystem\Directory\WriteInterface
     */
    protected $mediaDirectory;

    /**
     * @var \Magento\Framework\Filesystem\Directory\WriteInterface
     */
    protected $systemTmpDirectory;

    /**
     * @var LinkConfig
     */
    protected $linkConfig;

    /**
     * @var SampleConfig
     */
    protected $sampleConfig;

    /**
     * @param Database $coreFileStorageDb
     * @param Storage $coreFileStorage
     * @param NotProtectedExtension $validator
     * @param Filesystem $filesystem
     * @param LinkConfig $linkConfig
     * @param SampleConfig $sampleConfig
     */
    public function __construct(
        Database $coreFileStorageDb,
        Storage $coreFileStorage,
        NotProtectedExtension $validator,
        Filesystem $filesystem,
        LinkConfig $linkConfig,
        SampleConfig $sampleConfig
    ) {
        $this->_validator = $validator;
        $this->_coreFileStorage = $coreFileStorage;
        $this->_coreFileStorageDb = $coreFileStorageDb;
        $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
        $this->systemTmpDirectory = $filesystem->getDirectoryWrite(DirectoryList::SYS_TMP);
        $this->linkConfig = $linkConfig;
        $this->sampleConfig = $sampleConfig;
    }

    /**
     * Decode base64 encoded content and save it in system tmp folder
     *
     * @param ContentInterface $fileContent
     * @return array
     */
    protected function decodeContent(ContentInterface $fileContent)
    {
        $tmpFileName = $this->getTmpFileName();
        $fileSize = $this->systemTmpDirectory->writeFile($tmpFileName, base64_decode($fileContent->getFileData()));

        return [
            'name' => $fileContent->getName(),
            'type' => self::DEFAULT_MIME_TYPE,
            'tmp_name' => $this->systemTmpDirectory->getAbsolutePath($tmpFileName),
            'error' => 0,
            'size' => $fileSize,
        ];
    }

    /**
     * Generate temporary file name
     *
     * @return string
     */
    protected function getTmpFileName()
    {
        return uniqid($this->filePrefix, true);
    }

    /**
     * {@inheritdoc}
     */
    public function upload(ContentInterface $fileContent, $contentType)
    {
        $this->_file = $this->decodeContent($fileContent);
        if (!file_exists($this->_file['tmp_name'])) {
            throw new \InvalidArgumentException('There was an error during file content upload.');
        }
        $this->_fileExists = true;
        $this->_uploadType = self::SINGLE_STYLE;
        $this->setAllowRenameFiles(true);
        $this->setFilesDispersion(true);
        $result = $this->save($this->getDestinationDirectory($contentType));
        unset($result['path']);
        $result['status'] = 'new';
        $result['name'] = substr($result['file'], strrpos($result['file'], '/') + 1);
        return $result;
    }

    /**
     * Retrieve destination directory for given content type
     *
     * @param string $contentType
     * @return string
     * @throws \InvalidArgumentException
     */
    protected function getDestinationDirectory($contentType)
    {
        switch ($contentType) {
            case 'link_file':
                $directory = $this->mediaDirectory->getAbsolutePath($this->linkConfig->getBaseTmpPath());
                break;
            case 'link_sample_file':
                $directory = $this->mediaDirectory->getAbsolutePath($this->linkConfig->getBaseSampleTmpPath());
                break;
            case 'sample':
                $directory = $this->mediaDirectory->getAbsolutePath($this->sampleConfig->getBaseTmpPath());
                break;
            default:
                throw new \InvalidArgumentException('Invalid downloadable file content type.');
        }
        return $directory;
    }
}