123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Customer\Model\Metadata\Form;
- use Magento\Customer\Model\FileProcessor;
- use Magento\Customer\Model\FileProcessorFactory;
- use Magento\Framework\Api\ArrayObjectSearch;
- use Magento\Framework\Api\Data\ImageContentInterface;
- use Magento\Framework\App\Filesystem\DirectoryList;
- use Magento\Framework\App\ObjectManager;
- use Magento\Framework\File\UploaderFactory;
- use Magento\Framework\Filesystem;
- /**
- * Processes files that are save for customer.
- *
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class File extends AbstractData
- {
- /**
- * Validator for check not protected extensions
- *
- * @var \Magento\MediaStorage\Model\File\Validator\NotProtectedExtension
- */
- protected $_validatorNotProtectedExtensions;
- /**
- * Core data
- *
- * @var \Magento\Framework\Url\EncoderInterface
- */
- protected $urlEncoder;
- /**
- * @var \Magento\MediaStorage\Model\File\Validator\NotProtectedExtension
- */
- protected $_fileValidator;
- /**
- * @var Filesystem
- */
- protected $_fileSystem;
- /**
- * @var UploaderFactory
- */
- private $uploaderFactory;
- /**
- * @var FileProcessor
- */
- protected $fileProcessor;
- /**
- * @var FileProcessorFactory
- * @deprecated 101.0.0
- */
- protected $fileProcessorFactory;
- /**
- * Constructor
- *
- * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
- * @param \Psr\Log\LoggerInterface $logger
- * @param \Magento\Customer\Api\Data\AttributeMetadataInterface $attribute
- * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
- * @param string|array $value
- * @param string $entityTypeCode
- * @param bool $isAjax
- * @param \Magento\Framework\Url\EncoderInterface $urlEncoder
- * @param \Magento\MediaStorage\Model\File\Validator\NotProtectedExtension $fileValidator
- * @param Filesystem $fileSystem
- * @param UploaderFactory $uploaderFactory
- * @param \Magento\Customer\Model\FileProcessorFactory|null $fileProcessorFactory
- * @SuppressWarnings(PHPMD.ExcessiveParameterList)
- */
- public function __construct(
- \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
- \Psr\Log\LoggerInterface $logger,
- \Magento\Customer\Api\Data\AttributeMetadataInterface $attribute,
- \Magento\Framework\Locale\ResolverInterface $localeResolver,
- $value,
- $entityTypeCode,
- $isAjax,
- \Magento\Framework\Url\EncoderInterface $urlEncoder,
- \Magento\MediaStorage\Model\File\Validator\NotProtectedExtension $fileValidator,
- Filesystem $fileSystem,
- UploaderFactory $uploaderFactory,
- \Magento\Customer\Model\FileProcessorFactory $fileProcessorFactory = null
- ) {
- parent::__construct($localeDate, $logger, $attribute, $localeResolver, $value, $entityTypeCode, $isAjax);
- $this->urlEncoder = $urlEncoder;
- $this->_fileValidator = $fileValidator;
- $this->_fileSystem = $fileSystem;
- $this->uploaderFactory = $uploaderFactory;
- $this->fileProcessorFactory = $fileProcessorFactory ?: ObjectManager::getInstance()
- ->get(\Magento\Customer\Model\FileProcessorFactory::class);
- $this->fileProcessor = $this->fileProcessorFactory->create(['entityTypeCode' => $this->_entityTypeCode]);
- }
- /**
- * @inheritdoc
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- public function extractValue(\Magento\Framework\App\RequestInterface $request)
- {
- $extend = $this->_getRequestValue($request);
- $attrCode = $this->getAttribute()->getAttributeCode();
- if ($this->_requestScope || !isset($_FILES[$attrCode])) {
- $value = [];
- if (strpos($this->_requestScope, '/') !== false) {
- $scopes = explode('/', $this->_requestScope);
- $mainScope = array_shift($scopes);
- } else {
- $mainScope = $this->_requestScope;
- $scopes = [];
- }
- if (!empty($_FILES[$mainScope])) {
- foreach ($_FILES[$mainScope] as $fileKey => $scopeData) {
- foreach ($scopes as $scopeName) {
- if (isset($scopeData[$scopeName])) {
- $scopeData = $scopeData[$scopeName];
- } else {
- $scopeData[$scopeName] = [];
- }
- }
- if (isset($scopeData[$attrCode])) {
- $value[$fileKey] = $scopeData[$attrCode];
- }
- }
- } elseif (isset($extend[0]['file']) && !empty($extend[0]['file'])) {
- /**
- * This case is required by file uploader UI component
- *
- * $extend[0]['file'] - uses for AJAX validation
- * $extend[0] - uses for POST request
- */
- $value = $this->getIsAjaxRequest() ? $extend[0]['file'] : $extend[0];
- } else {
- $value = [];
- }
- } else {
- if (isset($_FILES[$attrCode])) {
- $value = $_FILES[$attrCode];
- } else {
- $value = [];
- }
- }
- if (!empty($extend['delete'])) {
- $value['delete'] = true;
- }
- return $value;
- }
- /**
- * Validate file by attribute validate rules. Returns array of errors.
- *
- * @param array $value
- * @return string[]
- */
- protected function _validateByRules($value)
- {
- $label = $value['name'];
- $rules = $this->getAttribute()->getValidationRules();
- $extension = pathinfo($value['name'], PATHINFO_EXTENSION);
- $fileExtensions = ArrayObjectSearch::getArrayElementByName(
- $rules,
- 'file_extensions'
- );
- if ($fileExtensions !== null) {
- $extensions = explode(',', $fileExtensions);
- $extensions = array_map('trim', $extensions);
- if (!in_array($extension, $extensions)) {
- return [__('"%1" is not a valid file extension.', $extension)];
- }
- }
- /**
- * Check protected file extension
- */
- if (!$this->_fileValidator->isValid($extension)) {
- return $this->_fileValidator->getMessages();
- }
- if (!$this->_isUploadedFile($value['tmp_name'])) {
- return [__('"%1" is not a valid file.', $label)];
- }
- $maxFileSize = ArrayObjectSearch::getArrayElementByName(
- $rules,
- 'max_file_size'
- );
- if ($maxFileSize !== null) {
- $size = $value['size'];
- if ($maxFileSize < $size) {
- return [__('"%1" exceeds the allowed file size.', $label)];
- }
- }
- return [];
- }
- /**
- * Helper function that checks if the file was uploaded.
- *
- * This helper function is needed for testing.
- *
- * @param string $filename
- * @return bool
- */
- protected function _isUploadedFile($filename)
- {
- if (is_uploaded_file($filename)) {
- return true;
- }
- // This case is required for file uploader UI component
- $temporaryFile = FileProcessor::TMP_DIR . '/' . pathinfo($filename)['basename'];
- if ($this->fileProcessor->isExist($temporaryFile)) {
- return true;
- }
- return false;
- }
- /**
- * @inheritdoc
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- */
- public function validateValue($value)
- {
- if ($this->getIsAjaxRequest()) {
- return true;
- }
- $errors = [];
- $attribute = $this->getAttribute();
- $label = $attribute->getStoreLabel();
- $toDelete = !empty($value['delete']) ? true : false;
- $toUpload = !empty($value['tmp_name']) ? true : false;
- if (!$toUpload && !$toDelete && $this->_value) {
- return true;
- }
- if (!$attribute->isRequired() && !$toUpload) {
- return true;
- }
- if ($attribute->isRequired() && !$toUpload) {
- $errors[] = __('"%1" is a required value.', $label);
- }
- if ($toUpload) {
- $errors = array_merge($errors, $this->_validateByRules($value));
- }
- if (count($errors) == 0) {
- return true;
- }
- return $errors;
- }
- /**
- * @inheritdoc
- *
- * @return ImageContentInterface|array|string|null
- */
- public function compactValue($value)
- {
- if ($this->getIsAjaxRequest()) {
- return $this;
- }
- // Remove outdated file (in the case of file uploader UI component)
- if (empty($value) && !empty($this->_value)) {
- $this->fileProcessor->removeUploadedFile($this->_value);
- return $value;
- }
- if (isset($value['file']) && !empty($value['file'])) {
- if ($value['file'] == $this->_value) {
- return $this->_value;
- }
- $result = $this->processUiComponentValue($value);
- } else {
- $result = $this->processInputFieldValue($value);
- }
- return $result;
- }
- /**
- * Process file uploader UI component data
- *
- * @param array $value
- * @return string|null
- */
- protected function processUiComponentValue(array $value)
- {
- $result = $this->fileProcessor->moveTemporaryFile($value['file']);
- return $result;
- }
- /**
- * Process input type=file component data
- *
- * @param string $value
- * @return bool|int|string
- */
- protected function processInputFieldValue($value)
- {
- $toDelete = false;
- if ($this->_value) {
- if (!$this->getAttribute()->isRequired()
- && !empty($value['delete'])
- ) {
- $toDelete = true;
- }
- if (!empty($value['tmp_name'])) {
- $toDelete = true;
- }
- }
- $mediaDir = $this->_fileSystem->getDirectoryWrite(DirectoryList::MEDIA);
- $result = $this->_value;
- if ($toDelete) {
- $mediaDir->delete($this->_entityTypeCode . '/' . ltrim($this->_value, '/'));
- $result = '';
- }
- if (!empty($value['tmp_name'])) {
- try {
- $uploader = $this->uploaderFactory->create(['fileId' => $value]);
- $uploader->setFilesDispersion(true);
- $uploader->setFilenamesCaseSensitivity(false);
- $uploader->setAllowRenameFiles(true);
- $uploader->save($mediaDir->getAbsolutePath($this->_entityTypeCode), $value['name']);
- $result = $uploader->getUploadedFileName();
- } catch (\Exception $e) {
- $this->_logger->critical($e);
- }
- }
- return $result;
- }
- /**
- * @inheritdoc
- */
- public function restoreValue($value)
- {
- return $this->_value;
- }
- /**
- * @inheritdoc
- */
- public function outputValue($format = \Magento\Customer\Model\Metadata\ElementFactory::OUTPUT_FORMAT_TEXT)
- {
- $output = '';
- if ($this->_value) {
- switch ($format) {
- case \Magento\Customer\Model\Metadata\ElementFactory::OUTPUT_FORMAT_JSON:
- $output = ['value' => $this->_value, 'url_key' => $this->urlEncoder->encode($this->_value)];
- break;
- }
- }
- return $output;
- }
- /**
- * Get file processor
- *
- * @return FileProcessor
- * @deprecated 100.1.3
- */
- protected function getFileProcessor()
- {
- return $this->fileProcessor;
- }
- }
|