urlEncoder = $urlEncoder; $this->_fileValidator = $fileValidator; $this->_directory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); } /** * Extract data from request and return value * * @param RequestInterface $request * @return array|string|bool * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function extractValue(RequestInterface $request) { if ($this->getIsAjaxRequest()) { return false; } $extend = $this->_getRequestValue($request); $attrCode = $this->getAttribute()->getAttributeCode(); if ($this->_requestScope) { $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]; } } } 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 and return array of errors * * @param array $value * @return string[] */ protected function _validateByRules($value) { $label = $this->getAttribute()->getStoreLabel(); $rules = $this->getAttribute()->getValidateRules(); $extension = pathinfo($value['name'], PATHINFO_EXTENSION); if (!empty($rules['file_extensions'])) { $extensions = explode(',', $rules['file_extensions']); $extensions = array_map('trim', $extensions); if (!in_array($extension, $extensions)) { return [__('"%1" is not a valid file extension.', $label)]; } } /** * Check protected file extension */ if (!$this->_fileValidator->isValid($extension)) { return $this->_fileValidator->getMessages(); } if (empty($value['tmp_name'])) { return [__('"%1" is not a valid file.', $label)]; } if (!empty($rules['max_file_size'])) { $size = $value['size']; if ($rules['max_file_size'] < $size) { return [__('"%1" exceeds the allowed file size.', $label)]; } } return []; } /** * Validate data * * @param array|string $value * @return bool * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) */ public function validateValue($value) { if ($this->getIsAjaxRequest()) { return true; } $fileData = $value; if (is_string($value) && !empty($value)) { $dir = $this->_directory->getAbsolutePath($this->getAttribute()->getEntityType()->getEntityTypeCode()); $fileData = [ 'size' => filesize($dir . $value), 'name' => $value, 'tmp_name' => $dir . $value ]; } $errors = []; $attribute = $this->getAttribute(); $toDelete = !empty($value['delete']) ? true : false; $toUpload = !empty($value['tmp_name']) || is_string($value) && !empty($value) ? true : false; if (!$toUpload && !$toDelete && $this->getEntity()->getData($attribute->getAttributeCode())) { return true; } if (!$attribute->getIsRequired() && !$toUpload) { return true; } if ($attribute->getIsRequired() && !$toUpload) { $label = __($attribute->getStoreLabel()); $errors[] = __('"%1" is a required value.', $label); } if ($toUpload) { $errors = array_merge($errors, $this->_validateByRules($fileData)); } if (count($errors) == 0) { return true; } elseif (is_string($value) && !empty($value)) { $this->_directory->delete($dir . $value); } return $errors; } /** * Export attribute value to entity model * * @param array|string $value * @return $this * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function compactValue($value) { if ($this->getIsAjaxRequest()) { return $this; } $attribute = $this->getAttribute(); $original = $this->getEntity()->getData($attribute->getAttributeCode()); $toDelete = false; if ($original) { if (!$attribute->getIsRequired() && !empty($value['delete'])) { $toDelete = true; } if (!empty($value['tmp_name'])) { $toDelete = true; } } $destinationFolder = $attribute->getEntityType()->getEntityTypeCode(); // unlink entity file if ($toDelete) { $this->getEntity()->setData($attribute->getAttributeCode(), ''); $file = $destinationFolder . $original; if ($this->_directory->isExist($file)) { $this->_directory->delete($file); } } if (!empty($value['tmp_name'])) { try { $uploader = new \Magento\Framework\File\Uploader($value); $uploader->setFilesDispersion(true); $uploader->setFilenamesCaseSensitivity(false); $uploader->setAllowRenameFiles(true); $uploader->save($this->_directory->getAbsolutePath($destinationFolder), $value['name']); $fileName = $uploader->getUploadedFileName(); $this->getEntity()->setData($attribute->getAttributeCode(), $fileName); } catch (\Exception $e) { $this->_logger->critical($e); } } return $this; } /** * Restore attribute value from SESSION to entity model * * @param array|string $value * @return $this * * @codeCoverageIgnore * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function restoreValue($value) { return $this; } /** * Return formatted attribute value from entity model * * @param string $format * @return string|array */ public function outputValue($format = \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_TEXT) { $output = ''; $value = $this->getEntity()->getData($this->getAttribute()->getAttributeCode()); if ($value) { switch ($format) { case \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_JSON: $output = ['value' => $value, 'url_key' => $this->urlEncoder->encode($value)]; break; } } return $output; } }