diff --git a/app/code/Magento/Config/Model/Config/Backend/File.php b/app/code/Magento/Config/Model/Config/Backend/File.php index f12d7bfdcec8ce5a935329730c33df742c015e18..809014f11f46f0109fe1476108642539b7e8f387 100644 --- a/app/code/Magento/Config/Model/Config/Backend/File.php +++ b/app/code/Magento/Config/Model/Config/Backend/File.php @@ -179,7 +179,6 @@ class File extends \Magento\Framework\App\Config\Value protected function _getUploadDir() { $fieldConfig = $this->getFieldConfig(); - /* @var $fieldConfig \Magento\Framework\Simplexml\Element */ if (!array_key_exists('upload_dir', $fieldConfig)) { throw new \Magento\Framework\Exception\LocalizedException( @@ -189,13 +188,15 @@ class File extends \Magento\Framework\App\Config\Value if (is_array($fieldConfig['upload_dir'])) { $uploadDir = $fieldConfig['upload_dir']['value']; - if (array_key_exists('scope_info', $fieldConfig['upload_dir']) && $fieldConfig['upload_dir']['scope_info'] + if ( + array_key_exists('scope_info', $fieldConfig['upload_dir']) + && $fieldConfig['upload_dir']['scope_info'] ) { $uploadDir = $this->_appendScopeInfo($uploadDir); } if (array_key_exists('config', $fieldConfig['upload_dir'])) { - $uploadDir = $this->_mediaDirectory->getAbsolutePath($uploadDir); + $uploadDir = $this->getUploadDirPath($uploadDir); } } else { $uploadDir = (string)$fieldConfig['upload_dir']; @@ -204,6 +205,17 @@ class File extends \Magento\Framework\App\Config\Value return $uploadDir; } + /** + * Retrieve upload directory path + * + * @param string $uploadDir + * @return string + */ + protected function getUploadDirPath($uploadDir) + { + return $this->_mediaDirectory->getAbsolutePath($uploadDir); + } + /** * Prepend path with scope info * diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php index 3449bb7ad104c07fa4ad5f8516043b0b3d77aa42..0bf781111fa104259dd5d69aef5c39f2ca3bab53 100644 --- a/app/code/Magento/Sales/Model/AdminOrder/Create.php +++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php @@ -1560,11 +1560,13 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ { $customer = $this->getQuote()->getCustomer(); $form = $this->_createCustomerForm($customer); + $customerData = $this->customerMapper->toFlatArray($customer); // emulate request $request = $form->prepareRequest($accountData); $data = $form->extractData($request); $data = $form->restoreData($data); + $data = array_merge($customerData, array_filter($data)); $customer = $this->customerFactory->create(); $this->dataObjectHelper->populateWithArray( $customer, @@ -1574,7 +1576,6 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\ $this->getQuote()->updateCustomerData($customer); $data = []; - $customerData = $this->customerMapper->toFlatArray($customer); foreach ($form->getAttributes() as $attribute) { $code = sprintf('customer_%s', $attribute->getAttributeCode()); $data[$code] = isset($customerData[$attribute->getAttributeCode()]) diff --git a/app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php b/app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php index 6c02813d2cdf8f5876caf08d6f20700e183250bf..1f684b00b075d1249ef7ea4e70a5ae8a3e06e15e 100644 --- a/app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php +++ b/app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php @@ -13,6 +13,7 @@ use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHe /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) */ class CreateTest extends \PHPUnit_Framework_TestCase { @@ -76,6 +77,11 @@ class CreateTest extends \PHPUnit_Framework_TestCase */ protected $accountManagementMock; + /** + * @var \Magento\Framework\Api\DataObjectHelper|\PHPUnit_Framework_MockObject_MockObject + */ + protected $dataObjectHelper; + /** * @var \PHPUnit_Framework_MockObject_MockObject */ @@ -171,6 +177,9 @@ class CreateTest extends \PHPUnit_Framework_TestCase '', false ); + $this->dataObjectHelper = $this->getMockBuilder('Magento\Framework\Api\DataObjectHelper') + ->disableOriginalConstructor() + ->getMock(); $objectManagerHelper = new ObjectManagerHelper($this); $this->adminOrderCreate = $objectManagerHelper->getObject( @@ -195,6 +204,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase 'customerMapper' => $this->customerMapper, 'objectFactory' => $this->objectFactory, 'accountManagement' => $this->accountManagementMock, + 'dataObjectHelper' => $this->dataObjectHelper, ] ); } @@ -242,8 +252,11 @@ class CreateTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue($this->getMock('Magento\Framework\App\RequestInterface'))); $customerMock = $this->getMock('Magento\Customer\Api\Data\CustomerInterface', [], [], '', false); - $this->customerMapper->expects($this->any())->method('toFlatArray') - ->will($this->returnValue(['email' => 'user@example.com', 'group_id' => 1])); + $this->customerMapper->expects($this->atLeastOnce()) + ->method('toFlatArray') + ->willReturn(['email' => 'user@example.com', 'group_id' => 1, 'gender' => 1]); + + $quoteMock = $this->getMock('Magento\Quote\Model\Quote', [], [], '', false); $quoteMock->expects($this->any())->method('getCustomer')->will($this->returnValue($customerMock)); $quoteMock->expects($this->once()) @@ -255,6 +268,13 @@ class CreateTest extends \PHPUnit_Framework_TestCase 'customer_tax_class_id' => $taxClassId ] ); + $this->dataObjectHelper->expects($this->once()) + ->method('populateWithArray') + ->with( + $customerMock, + ['email' => 'user@example.com', 'group_id' => 1, 'gender' => 1], + '\Magento\Customer\Api\Data\CustomerInterface' + ); $this->formFactoryMock->expects($this->any())->method('create')->will($this->returnValue($customerFormMock)); $this->sessionQuoteMock->expects($this->any())->method('getQuote')->will($this->returnValue($quoteMock)); diff --git a/app/code/Magento/Theme/Controller/Adminhtml/Design/Config/FileUploader/Save.php b/app/code/Magento/Theme/Controller/Adminhtml/Design/Config/FileUploader/Save.php index a9595a01207c085460a0ce9d68eb5d4c474ff624..23eb7590ca604a6b3ecdfdedfab810bc77f31d7f 100644 --- a/app/code/Magento/Theme/Controller/Adminhtml/Design/Config/FileUploader/Save.php +++ b/app/code/Magento/Theme/Controller/Adminhtml/Design/Config/FileUploader/Save.php @@ -8,25 +8,25 @@ namespace Magento\Theme\Controller\Adminhtml\Design\Config\FileUploader; use Magento\Backend\App\Action; use Magento\Backend\App\Action\Context; use Magento\Framework\Controller\ResultFactory; -use Magento\Theme\Model\Design\Config\FileUploader\ImageProcessor; +use Magento\Theme\Model\Design\Config\FileUploader\FileProcessor; class Save extends Action { /** - * @var ImageProcessor + * @var FileProcessor */ - protected $imageProcessor; + protected $fileProcessor; /** * @param Context $context - * @param ImageProcessor $imageProcessor + * @param FileProcessor $fileProcessor */ public function __construct( Context $context, - ImageProcessor $imageProcessor + FileProcessor $fileProcessor ) { parent::__construct($context); - $this->imageProcessor = $imageProcessor; + $this->fileProcessor = $fileProcessor; } /** @@ -34,7 +34,7 @@ class Save extends Action */ public function execute() { - $result = $this->imageProcessor->saveToTmp(key($_FILES)); + $result = $this->fileProcessor->saveToTmp(key($_FILES)); return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result); } } diff --git a/app/code/Magento/Theme/Model/Design/Backend/Favicon.php b/app/code/Magento/Theme/Model/Design/Backend/Favicon.php index 46496287caf88a2c2d76fbfaf931642b75932801..ebab873f99f60a9f4d77f688f25861213151ed63 100644 --- a/app/code/Magento/Theme/Model/Design/Backend/Favicon.php +++ b/app/code/Magento/Theme/Model/Design/Backend/Favicon.php @@ -5,12 +5,36 @@ */ namespace Magento\Theme\Model\Design\Backend; +use Magento\Framework\Filesystem; + class Favicon extends Image { /** - * @var string + * The tail part of directory path for uploading + * + */ + const UPLOAD_DIR = 'favicon'; + + /** + * Return path to directory for upload file + * + * @return string + * @throw \Magento\Framework\Exception\LocalizedException + */ + protected function _getUploadDir() + { + return $this->_mediaDirectory->getRelativePath($this->_appendScopeInfo(self::UPLOAD_DIR)); + } + + /** + * Makes a decision about whether to add info about the scope. + * + * @return boolean */ - protected $uploadDir = 'favicon'; + protected function _addWhetherScopeInfo() + { + return true; + } /** * Getter for allowed extensions of uploaded files. diff --git a/app/code/Magento/Theme/Model/Design/Backend/File.php b/app/code/Magento/Theme/Model/Design/Backend/File.php new file mode 100644 index 0000000000000000000000000000000000000000..e788c6892f4c89e20f89b454f7a6061f30d08b0b --- /dev/null +++ b/app/code/Magento/Theme/Model/Design/Backend/File.php @@ -0,0 +1,195 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Theme\Model\Design\Backend; + +use Magento\Config\Model\Config\Backend\File\RequestData\RequestDataInterface; +use Magento\Config\Model\Config\Backend\File as BackendFile; +use Magento\Framework\App\Cache\TypeListInterface; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\Data\Collection\AbstractDb; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Filesystem; +use Magento\Framework\Model\Context; +use Magento\Framework\Model\ResourceModel\AbstractResource; +use Magento\Framework\Registry; +use Magento\Framework\UrlInterface; +use Magento\MediaStorage\Model\File\UploaderFactory; +use Magento\Theme\Model\Design\Config\FileUploader\FileProcessor; + +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class File extends BackendFile +{ + /** + * @var UrlInterface + */ + protected $urlBuilder; + + /** + * @param Context $context + * @param Registry $registry + * @param ScopeConfigInterface $config + * @param TypeListInterface $cacheTypeList + * @param UploaderFactory $uploaderFactory + * @param RequestDataInterface $requestData + * @param Filesystem $filesystem + * @param UrlInterface $urlBuilder + * @param AbstractResource|null $resource + * @param AbstractDb|null $resourceCollection + * @param array $data + * @SuppressWarnings(PHPMD.ExcessiveParameterList) + */ + public function __construct( + Context $context, + Registry $registry, + ScopeConfigInterface $config, + TypeListInterface $cacheTypeList, + UploaderFactory $uploaderFactory, + RequestDataInterface $requestData, + Filesystem $filesystem, + UrlInterface $urlBuilder, + AbstractResource $resource = null, + AbstractDb $resourceCollection = null, + array $data = [] + ) { + parent::__construct( + $context, + $registry, + $config, + $cacheTypeList, + $uploaderFactory, + $requestData, + $filesystem, + $resource, + $resourceCollection, + $data + ); + $this->urlBuilder = $urlBuilder; + } + + /** + * Save uploaded file and remote temporary file before saving config value + * + * @return $this + * @throws LocalizedException + */ + public function beforeSave() + { + $values = $this->getValue(); + $value = reset($values) ?: []; + if (!isset($value['file'])) { + throw new LocalizedException( + __('%1 does not contain field \'file\'', $this->getData('field_config/field')) + ); + } + if (isset($value['exists'])) { + $this->setValue($value['file']); + return $this; + } + $filename = $value['file']; + $result = $this->_mediaDirectory->copyFile( + $this->getTmpMediaPath($filename), + $this->_getUploadDir() . '/' . $filename + ); + if ($result) { + $this->_mediaDirectory->delete($this->getTmpMediaPath($filename)); + if ($this->_addWhetherScopeInfo()) { + $filename = $this->_prependScopeInfo($filename); + } + $this->setValue($filename); + } else { + $this->unsValue(); + } + + return $this; + } + + /** + * @return array + */ + public function afterLoad() + { + $value = $this->getValue(); + if ($value && !is_array($value)) { + $fileName = $this->_getUploadDir() . '/' . basename($value); + $fileInfo = null; + if ($this->_mediaDirectory->isExist($fileName)) { + $stat = $this->_mediaDirectory->stat($fileName); + $url = $this->getStoreMediaUrl($value); + $fileInfo = [ + [ + 'url' => $url, + 'file' => $value, + 'size' => is_array($stat) ? $stat['size'] : 0, + 'exists' => true + ] + ]; + } + $this->setValue($fileInfo); + } + return $this; + } + + /** + * Getter for allowed extensions of uploaded files + * + * @return array + */ + public function getAllowedExtensions() + { + return []; + } + + /** + * Retrieve upload directory path + * + * @param string $uploadDir + * @return string + */ + protected function getUploadDirPath($uploadDir) + { + return $this->_mediaDirectory->getRelativePath($uploadDir); + } + + /** + * @return array + */ + public function getValue() + { + return $this->getData('value') ?: []; + } + + /** + * Retrieve store media url + * + * @param string $fileName + * @return mixed + */ + protected function getStoreMediaUrl($fileName) + { + $fieldConfig = $this->getFieldConfig(); + $baseUrl = ''; + $urlType = ['_type' => UrlInterface::URL_TYPE_MEDIA]; + if (isset($fieldConfig['base_url'])) { + $baseUrl = $fieldConfig['base_url']; + $urlType = ['_type' => empty($baseUrl['type']) ? 'link' : (string)$baseUrl['type']]; + $baseUrl = $baseUrl['value'] . '/'; + } + return $this->urlBuilder->getBaseUrl($urlType) . $baseUrl . $fileName; + } + + /** + * Retrieve temp media path + * + * @param string $filename + * @return string + */ + protected function getTmpMediaPath($filename) + { + return 'tmp/' . FileProcessor::FILE_DIR . '/' . $filename; + } +} diff --git a/app/code/Magento/Theme/Model/Design/Backend/Image.php b/app/code/Magento/Theme/Model/Design/Backend/Image.php index 8f7dbbca100d4588aaae35e6cb1361ff4fccfcaf..f9e80b921fd1391edba904002b1aff06eb3a8fae 100644 --- a/app/code/Magento/Theme/Model/Design/Backend/Image.php +++ b/app/code/Magento/Theme/Model/Design/Backend/Image.php @@ -5,129 +5,8 @@ */ namespace Magento\Theme\Model\Design\Backend; -use Magento\Config\Model\Config\Backend\File\RequestData\RequestDataInterface; -use \Magento\Config\Model\Config\Backend\File as File; -use Magento\Framework\App\Cache\TypeListInterface; -use Magento\Framework\App\Config\ScopeConfigInterface; -use Magento\Framework\Data\Collection\AbstractDb; -use Magento\Framework\Exception\LocalizedException; -use Magento\Framework\Filesystem; -use Magento\Framework\Model\Context; -use Magento\Framework\Model\ResourceModel\AbstractResource; -use Magento\Framework\Registry; -use Magento\MediaStorage\Model\File\UploaderFactory; -use Magento\Theme\Model\Design\Config\FileUploader\Config; - class Image extends File { - /** - * @var string - */ - protected $uploadDir = 'image'; - - /** - * @var Config - */ - protected $imageConfig; - - /** - * @param Context $context - * @param Registry $registry - * @param ScopeConfigInterface $config - * @param TypeListInterface $cacheTypeList - * @param UploaderFactory $uploaderFactory - * @param RequestDataInterface $requestData - * @param Filesystem $filesystem - * @param Config $imageConfig - * @param AbstractResource|null $resource - * @param AbstractDb|null $resourceCollection - * @param array $data - * @SuppressWarnings(PHPMD.ExcessiveParameterList) - */ - public function __construct( - Context $context, - Registry $registry, - ScopeConfigInterface $config, - TypeListInterface $cacheTypeList, - UploaderFactory $uploaderFactory, - RequestDataInterface $requestData, - Filesystem $filesystem, - Config $imageConfig, - AbstractResource $resource = null, - AbstractDb $resourceCollection = null, - array $data = [] - ) { - parent::__construct( - $context, - $registry, - $config, - $cacheTypeList, - $uploaderFactory, - $requestData, - $filesystem, - $resource, - $resourceCollection, - $data - ); - $this->imageConfig = $imageConfig; - } - - /** - * Save uploaded file and remote temporary file before saving config value - * - * @return $this - * @throws LocalizedException - */ - public function beforeSave() - { - $values = $this->getValue(); - $value = reset($values) ?: []; - if (!isset($value['file'])) { - throw new LocalizedException( - __('%1 does not contain field \'file\'', $this->getData('field_config/field')) - ); - } - if (isset($value['exists'])) { - $this->setValue($value['file']); - return $this; - } - $filename = $value['file']; - $result = $this->_mediaDirectory->copyFile( - $this->imageConfig->getTmpMediaPath($filename), - $this->_appendScopeInfo($this->uploadDir) . '/' . $filename - ); - if ($result) { - $this->_mediaDirectory->delete($this->imageConfig->getTmpMediaPath($filename)); - $filename = $this->_prependScopeInfo($filename); - $this->setValue($filename); - } else { - $this->unsValue(); - } - - return $this; - } - - /** - * @return array - */ - public function afterLoad() - { - $value = $this->getValue(); - if ($value && !is_array($value)) { - $fileName = '/' . $this->uploadDir . '/' . $value; - $stat = $this->_mediaDirectory->stat($fileName); - $this->setValue([ - [ - 'url' => $this->imageConfig->getStoreMediaUrl() . $fileName, - 'file' => $value, - 'size' => is_array($stat) ? $stat['size'] : 0, - 'exists' => true - ] - ]); - } - return $this; - } - /** * Getter for allowed extensions of uploaded files * @@ -137,12 +16,4 @@ class Image extends File { return ['jpg', 'jpeg', 'gif', 'png']; } - - /** - * @return array - */ - public function getValue() - { - return $this->getData('value') ?: []; - } } diff --git a/app/code/Magento/Theme/Model/Design/Backend/Logo.php b/app/code/Magento/Theme/Model/Design/Backend/Logo.php index b658bfefa312d3c4484b148b9bf94c30f2b33305..78bc7603492aba395fbd7bce9493ce21cf2ee1e1 100644 --- a/app/code/Magento/Theme/Model/Design/Backend/Logo.php +++ b/app/code/Magento/Theme/Model/Design/Backend/Logo.php @@ -8,9 +8,31 @@ namespace Magento\Theme\Model\Design\Backend; class Logo extends Image { /** - * @var string + * The tail part of directory path for uploading + * */ - protected $uploadDir = 'logo'; + const UPLOAD_DIR = 'logo'; + + /** + * Return path to directory for upload file + * + * @return string + * @throw \Magento\Framework\Exception\LocalizedException + */ + protected function _getUploadDir() + { + return $this->_mediaDirectory->getRelativePath($this->_appendScopeInfo(self::UPLOAD_DIR)); + } + + /** + * Makes a decision about whether to add info about the scope. + * + * @return boolean + */ + protected function _addWhetherScopeInfo() + { + return true; + } /** * Getter for allowed extensions of uploaded files. diff --git a/app/code/Magento/Theme/Model/Design/Config/FileUploader/Config.php b/app/code/Magento/Theme/Model/Design/Config/FileUploader/Config.php deleted file mode 100644 index 3d3e29e39d2bcb7e932688d8d2470978df67d0e5..0000000000000000000000000000000000000000 --- a/app/code/Magento/Theme/Model/Design/Config/FileUploader/Config.php +++ /dev/null @@ -1,147 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\Theme\Model\Design\Config\FileUploader; - -use Magento\Framework\App\Helper\AbstractHelper; -use Magento\Framework\App\Helper\Context; -use Magento\Framework\Filesystem\Directory\WriteInterface; -use Magento\Framework\UrlInterface; -use Magento\Store\Model\StoreManagerInterface; -use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\Filesystem; - -class Config extends AbstractHelper -{ - /** - * @var StoreManagerInterface - */ - protected $storeManager; - - /** - * Media Directory object (writable). - * - * @var WriteInterface - */ - protected $mediaDirectory; - - /** - * @var string - */ - protected $imageDir; - - /** - * @param Context $context - * @param StoreManagerInterface $storeManager - * @param Filesystem $filesystem - * @param string $imageDir - */ - public function __construct( - Context $context, - StoreManagerInterface $storeManager, - Filesystem $filesystem, - $imageDir = 'design/image' - ) { - parent::__construct($context); - $this->storeManager = $storeManager; - $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); - $this->imageDir = $imageDir; - } - - /** - * Retrieve absolute temp media path - * - * @return string - */ - public function getAbsoluteTmpMediaPath() - { - return $this->mediaDirectory->getAbsolutePath($this->getBaseTmpMediaPath()); - } - - /** - * Retrieve base temp media url - * - * @return string - */ - public function getBaseTmpMediaUrl() - { - return $this->getStoreMediaUrl() . 'tmp/' . $this->imageDir; - } - - /** - * Retrieve temp media url - * - * @param string $file - * @return string - */ - public function getTmpMediaUrl($file) - { - return $this->getBaseTmpMediaUrl() . '/' . $this->prepareFile($file); - } - - /** - * Retrieve store media url - * - * @return mixed - */ - public function getStoreMediaUrl() - { - return $this->storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA); - } - - /** - * Retrieve base media url - * - * @return string - */ - public function getBaseMediaUrl() - { - return $this->getStoreMediaUrl() . $this->imageDir; - } - - /** - * Retrieve media url - * - * @param string $file - * @return string - */ - public function getMediaUrl($file) - { - return $this->getBaseMediaUrl() . '/' . $this->prepareFile($file); - } - - /** - * Filesystem directory path of temporary images - * relatively to media folder - * - * @return string - */ - public function getBaseTmpMediaPath() - { - return 'tmp/' . $this->imageDir; - } - - /** - * Retrieve temp media path - * - * @param string $filename - * @return string - */ - public function getTmpMediaPath($filename) - { - return $this->getBaseTmpMediaPath() . '/' . $filename; - } - - /** - * Prepare file - * - * @param string $file - * @return string - */ - protected function prepareFile($file) - { - return ltrim(str_replace('\\', '/', $file), '/'); - } -} diff --git a/app/code/Magento/Theme/Model/Design/Config/FileUploader/ImageProcessor.php b/app/code/Magento/Theme/Model/Design/Config/FileUploader/FileProcessor.php similarity index 58% rename from app/code/Magento/Theme/Model/Design/Config/FileUploader/ImageProcessor.php rename to app/code/Magento/Theme/Model/Design/Config/FileUploader/FileProcessor.php index f8eaa277b157469ef1a95f0f189b5a34d3dceb05..5a132b0250079123694a23addaea3935d53cb685 100644 --- a/app/code/Magento/Theme/Model/Design/Config/FileUploader/ImageProcessor.php +++ b/app/code/Magento/Theme/Model/Design/Config/FileUploader/FileProcessor.php @@ -6,23 +6,26 @@ namespace Magento\Theme\Model\Design\Config\FileUploader; use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Filesystem; use Magento\MediaStorage\Model\File\UploaderFactory; -use Magento\Theme\Model\Design\Backend\Image; +use Magento\Theme\Model\Design\Backend\File; use Magento\Theme\Model\Design\BackendModelFactory; use Magento\Theme\Model\Design\Config\MetadataProvider; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Filesystem\Directory\WriteInterface; +use Magento\Framework\UrlInterface; +use Magento\Store\Model\StoreManagerInterface; -class ImageProcessor +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ +class FileProcessor { /** * @var UploaderFactory */ protected $uploaderFactory; - /** - * @var Config - */ - protected $imageConfig; - /** * @var BackendModelFactory */ @@ -33,22 +36,42 @@ class ImageProcessor */ protected $metadataProvider; + /** + * Media Directory object (writable). + * + * @var WriteInterface + */ + protected $mediaDirectory; + + /** + * @var StoreManagerInterface + */ + protected $storeManager; + + /** + * @var string + */ + const FILE_DIR = 'design/file'; + /** * @param UploaderFactory $uploaderFactory - * @param Config $imageConfig * @param BackendModelFactory $backendModelFactory * @param MetadataProvider $metadataProvider + * @param Filesystem $filesystem + * @param StoreManagerInterface $storeManager */ public function __construct( UploaderFactory $uploaderFactory, - Config $imageConfig, BackendModelFactory $backendModelFactory, - MetadataProvider $metadataProvider + MetadataProvider $metadataProvider, + Filesystem $filesystem, + StoreManagerInterface $storeManager ) { $this->uploaderFactory = $uploaderFactory; - $this->imageConfig = $imageConfig; $this->backendModelFactory = $backendModelFactory; $this->metadataProvider = $metadataProvider; + $this->storeManager = $storeManager; + $this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); } /** @@ -61,14 +84,47 @@ class ImageProcessor public function saveToTmp($fileId) { try { - $result = $this->save($fileId, $this->imageConfig->getAbsoluteTmpMediaPath()); - $result['url'] = $this->imageConfig->getTmpMediaUrl($result['file']); + $result = $this->save($fileId, $this->getAbsoluteTmpMediaPath()); + $result['url'] = $this->getTmpMediaUrl($result['file']); } catch (\Exception $e) { $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()]; } return $result; } + /** + * Retrieve temp media url + * + * @param string $file + * @return string + */ + protected function getTmpMediaUrl($file) + { + return $this->storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA) + . 'tmp/' . self::FILE_DIR . '/' . $this->prepareFile($file); + } + + /** + * Prepare file + * + * @param string $file + * @return string + */ + protected function prepareFile($file) + { + return ltrim(str_replace('\\', '/', $file), '/'); + } + + /** + * Retrieve absolute temp media path + * + * @return string + */ + protected function getAbsoluteTmpMediaPath() + { + return $this->mediaDirectory->getAbsolutePath('tmp/' . self::FILE_DIR); + } + /** * Save image * @@ -80,7 +136,7 @@ class ImageProcessor protected function save($fileId, $destination) { $result = ['file' => '', 'size' => '']; - /** @var Image $backendModel */ + /** @var File $backendModel */ $backendModel = $this->getBackendModel($fileId); $uploader = $this->uploaderFactory->create(['fileId' => $fileId]); $uploader->setAllowRenameFiles(true); @@ -94,7 +150,7 @@ class ImageProcessor * Retrieve backend model by field code * * @param string $code - * @return Image + * @return File * @throws LocalizedException */ protected function getBackendModel($code) diff --git a/app/code/Magento/Theme/Model/Design/Config/Storage.php b/app/code/Magento/Theme/Model/Design/Config/Storage.php index aa518a085a54805556110be7cb96d1eb16e11e35..5e47d1aefe4e0255174833e55e6f8e77b0bd73aa 100644 --- a/app/code/Magento/Theme/Model/Design/Config/Storage.php +++ b/app/code/Magento/Theme/Model/Design/Config/Storage.php @@ -77,7 +77,9 @@ class Storage foreach ($fieldsData as &$fieldData) { $value = $this->valueProcessor->process( $this->scopeConfig->getValue($fieldData->getPath(), $scope, $scopeId), - $fieldData->getPath() + $scope, + $scopeId, + $fieldData->getFieldConfig() ); if ($value !== null) { $fieldData->setValue($value); @@ -113,7 +115,7 @@ class Storage $fieldData->getValue(), $designConfig->getScope(), $designConfig->getScopeId(), - $fieldData->getFieldConfig()['path'] + $fieldData->getFieldConfig() ) ) { $saveTransaction->addObject($backendModel); diff --git a/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php b/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php index a65c566a61b3461a0f90b405baff1010b1a0d505..0a1c61f75644f02d64c5b40197735b715f71afb5 100644 --- a/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php +++ b/app/code/Magento/Theme/Model/Design/Config/ValueChecker.php @@ -47,21 +47,25 @@ class ValueChecker * @param string $value * @param string $scope * @param int $scopeId - * @param string $path + * @param array $fieldConfig * @return bool */ - public function isDifferentFromDefault($value, $scope, $scopeId, $path) + public function isDifferentFromDefault($value, $scope, $scopeId, array $fieldConfig) { list($scope, $scopeId) = $this->fallbackResolver->getFallbackScope($scope, $scopeId); if ($scope) { return !$this->isEqual( $this->valueProcessor->process( $value, - $path + $scope, + $scopeId, + $fieldConfig ), $this->valueProcessor->process( - $this->appConfig->getValue($path, $scope, $scopeId), - $path + $this->appConfig->getValue($fieldConfig['path'], $scope, $scopeId), + $scope, + $scopeId, + $fieldConfig ) ); } diff --git a/app/code/Magento/Theme/Model/Design/Config/ValueProcessor.php b/app/code/Magento/Theme/Model/Design/Config/ValueProcessor.php index 7ce660f625f09e4e3426eba6a52e810d9336355c..ed3ae3809fdbe1c67e638673ce571ea8c219039e 100644 --- a/app/code/Magento/Theme/Model/Design/Config/ValueProcessor.php +++ b/app/code/Magento/Theme/Model/Design/Config/ValueProcessor.php @@ -27,12 +27,22 @@ class ValueProcessor * Process value * * @param string $value - * @param string $path + * @param string $scope + * @param string $scopeId + * @param array $fieldConfig * @return mixed */ - public function process($value, $path) + public function process($value, $scope, $scopeId, array $fieldConfig) { - $backendModel = $this->backendModelFactory->createByPath($path, ['value' => $value]); + $backendModel = $this->backendModelFactory->createByPath( + $fieldConfig['path'], + [ + 'value' => $value, + 'field_config' => $fieldConfig, + 'scope' => $scope, + 'scope_id' => $scopeId + ] + ); $backendModel->afterLoad(); return $backendModel->getValue(); } diff --git a/app/code/Magento/Theme/Model/ResourceModel/Design/Config/Collection.php b/app/code/Magento/Theme/Model/ResourceModel/Design/Config/Collection.php index 0bd41722b9cfa37635ef6e52c0b52a02c3c091a8..eeb73108d96e844f2366fedfaa34ca1d5bbe691d 100644 --- a/app/code/Magento/Theme/Model/ResourceModel/Design/Config/Collection.php +++ b/app/code/Magento/Theme/Model/ResourceModel/Design/Config/Collection.php @@ -73,7 +73,15 @@ class Collection extends ConfigCollection protected function _afterLoad() { foreach ($this->_items as $item) { - $item->setData('value', $this->valueProcessor->process($item->getData('value'), $item->getData('path'))); + $item->setData( + 'value', + $this->valueProcessor->process( + $item->getData('value'), + $this->getData('scope'), + $this->getData('scope_id'), + $item->getData('path') + ) + ); } parent::_afterLoad(); } diff --git a/app/code/Magento/Theme/Model/ResourceModel/Design/Config/Scope/Collection.php b/app/code/Magento/Theme/Model/ResourceModel/Design/Config/Scope/Collection.php index 9196d6d55644bb7d5b740b01f70384ec8676f229..7c1b50024ba6ecc85b9ffcccabe9c202cdfa2828 100644 --- a/app/code/Magento/Theme/Model/ResourceModel/Design/Config/Scope/Collection.php +++ b/app/code/Magento/Theme/Model/ResourceModel/Design/Config/Scope/Collection.php @@ -101,7 +101,9 @@ class Collection extends \Magento\Framework\Data\Collection if (isset($itemData['use_in_grid']) && (boolean)$itemData['use_in_grid']) { $result[$itemName] = $this->valueProcessor->process( $this->appConfig->getValue($itemData['path'], $scope, $scopeId), - $itemData['path'] + $scope, + $scopeId, + $itemData ); } } diff --git a/app/code/Magento/Theme/Model/Theme/Plugin/Registration.php b/app/code/Magento/Theme/Model/Theme/Plugin/Registration.php index 487670e88a0e6a44ddf9c385d1c91487966a03f7..e17581cb283d90db59983b7c80412124ce6de245 100644 --- a/app/code/Magento/Theme/Model/Theme/Plugin/Registration.php +++ b/app/code/Magento/Theme/Model/Theme/Plugin/Registration.php @@ -86,23 +86,25 @@ class Registration */ protected function updateThemeData() { - $themesData = $this->themeCollection->loadData(); - /** @var \Magento\Theme\Model\Theme $themeData */ - foreach ($themesData as $themeData) { - if ($themeData->getParentTheme()) { - $parentTheme = $this->themeLoader->getThemeByFullPath( - $themeData->getParentTheme()->getFullPath() + $themesFromConfig = $this->themeCollection->loadData(); + /** @var \Magento\Theme\Model\Theme $themeFromConfig */ + foreach ($themesFromConfig as $themeFromConfig) { + /** @var \Magento\Theme\Model\Theme $themeFromDb */ + $themeFromDb = $this->themeLoader->getThemeByFullPath( + $themeFromConfig->getArea() + . Theme::THEME_PATH_SEPARATOR + . $themeFromConfig->getThemePath() + ); + + if ($themeFromConfig->getParentTheme()) { + $parentThemeFromDb = $this->themeLoader->getThemeByFullPath( + $themeFromConfig->getParentTheme()->getFullPath() ); - $themeData->setParentId($parentTheme->getId()); + $themeFromDb->setParentId($parentThemeFromDb->getId()); } - /** @var \Magento\Theme\Model\Theme $theme */ - $theme = $this->themeLoader->getThemeByFullPath( - $themeData->getArea() - . Theme::THEME_PATH_SEPARATOR - . $themeData->getThemePath() - ); - $theme->addData($themeData->toArray())->save(); + $themeFromDb->setThemeTitle($themeFromConfig->getThemeTitle()); + $themeFromDb->save(); } } } diff --git a/app/code/Magento/Theme/Test/Unit/Controller/Adminhtml/Design/Config/FileUploader/SaveTest.php b/app/code/Magento/Theme/Test/Unit/Controller/Adminhtml/Design/Config/FileUploader/SaveTest.php index c155934c9f579e2138bd34f1ac006424f1b12891..011f89b342bc775759f2eaf0b40b34f4b0ca6699 100644 --- a/app/code/Magento/Theme/Test/Unit/Controller/Adminhtml/Design/Config/FileUploader/SaveTest.php +++ b/app/code/Magento/Theme/Test/Unit/Controller/Adminhtml/Design/Config/FileUploader/SaveTest.php @@ -19,8 +19,8 @@ class SaveTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Framework\Controller\ResultInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $resultPage; - /** @var \Magento\Theme\Model\Design\Config\FileUploader\ImageProcessor|\PHPUnit_Framework_MockObject_MockObject */ - protected $imageProcessor; + /** @var \Magento\Theme\Model\Design\Config\FileUploader\FileProcessor|\PHPUnit_Framework_MockObject_MockObject */ + protected $fileProcessor; /** @var Save */ protected $controller; @@ -36,14 +36,14 @@ class SaveTest extends \PHPUnit_Framework_TestCase $this->resultPage = $this->getMockBuilder('Magento\Framework\Controller\ResultInterface') ->setMethods(['setData']) ->getMockForAbstractClass(); - $this->imageProcessor = $this->getMockBuilder('Magento\Theme\Model\Design\Config\FileUploader\ImageProcessor') + $this->fileProcessor = $this->getMockBuilder('Magento\Theme\Model\Design\Config\FileUploader\FileProcessor') ->disableOriginalConstructor() ->getMock(); $this->context->expects($this->once()) ->method('getResultFactory') ->willReturn($this->resultFactory); - $this->controller = new Save($this->context, $this->imageProcessor); + $this->controller = new Save($this->context, $this->fileProcessor); } public function testExecute() @@ -55,7 +55,7 @@ class SaveTest extends \PHPUnit_Framework_TestCase ]; $resultJson = '{"file": "", "url": ""}'; - $this->imageProcessor->expects($this->once()) + $this->fileProcessor->expects($this->once()) ->method('saveToTmp') ->with('test_key') ->willReturn($result); diff --git a/app/code/Magento/Theme/Test/Unit/Model/Design/Backend/ImageTest.php b/app/code/Magento/Theme/Test/Unit/Model/Design/Backend/FileTest.php similarity index 59% rename from app/code/Magento/Theme/Test/Unit/Model/Design/Backend/ImageTest.php rename to app/code/Magento/Theme/Test/Unit/Model/Design/Backend/FileTest.php index ce2a8c47419e79487940f5b79451fe2287e833b0..c67540e10d4368ea942db0942ddd1f215db15b15 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/Design/Backend/ImageTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/Design/Backend/FileTest.php @@ -5,20 +5,20 @@ */ namespace Magento\Theme\Test\Unit\Model\Design\Backend; -use Magento\Theme\Model\Design\Backend\Image; +use Magento\Framework\UrlInterface; +use Magento\Theme\Model\Design\Backend\File; use Magento\Framework\App\Filesystem\DirectoryList; -class ImageTest extends \PHPUnit_Framework_TestCase +class FileTest extends \PHPUnit_Framework_TestCase { - /** @var \Magento\Framework\Filesystem\Directory\WriteInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $mediaDirectory; - /** @var \Magento\Theme\Model\Design\Config\FileUploader\Config|\PHPUnit_Framework_MockObject_MockObject */ - protected $imageConfig; + /** @var UrlInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $urlBuilder; - /** @var Image */ - protected $imageBackend; + /** @var File */ + protected $fileBackend; public function setUp() { @@ -30,19 +30,20 @@ class ImageTest extends \PHPUnit_Framework_TestCase $requestData = $this->getMockObjectForAbstractClass( 'Magento\Config\Model\Config\Backend\File\RequestData\RequestDataInterface' ); - $filesystem = $this->getMockObject('Magento\Framework\Filesystem'); - $this->imageConfig = $this->getMockObject('Magento\Theme\Model\Design\Config\FileUploader\Config'); - - $this->mediaDirectory = $this->getMockObjectForAbstractClass( - 'Magento\Framework\Filesystem\Directory\WriteInterface' - ); + $filesystem = $this->getMockBuilder('Magento\Framework\Filesystem') + ->disableOriginalConstructor() + ->getMock(); + $this->mediaDirectory = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\WriteInterface') + ->getMockForAbstractClass(); $filesystem->expects($this->once()) ->method('getDirectoryWrite') ->with(DirectoryList::MEDIA) ->willReturn($this->mediaDirectory); + $this->urlBuilder = $this->getMockBuilder('Magento\Framework\UrlInterface') + ->getMockForAbstractClass(); - $this->imageBackend = new Image( + $this->fileBackend = new File( $context, $registry, $config, @@ -50,13 +51,13 @@ class ImageTest extends \PHPUnit_Framework_TestCase $uploaderFactory, $requestData, $filesystem, - $this->imageConfig + $this->urlBuilder ); } public function tearDown() { - unset($this->imageBackend); + unset($this->fileBackend); } /** @@ -86,36 +87,59 @@ class ImageTest extends \PHPUnit_Framework_TestCase public function testAfterLoad() { - $value = 'store/1/filename.jpg'; - $this->imageBackend->setValue($value); + $value = 'filename.jpg'; + $this->fileBackend->setValue($value); + $this->fileBackend->setFieldConfig( + [ + 'upload_dir' => [ + 'value' => 'value', + 'config' => 'system/filesystem/media', + ], + 'base_url' => [ + 'type' => 'media', + 'value' => 'design/file' + ], + ] + ); + + $this->mediaDirectory->expects($this->once()) + ->method('isExist') + ->with('value/' . $value) + ->willReturn(true); + $this->urlBuilder->expects($this->once()) + ->method('getBaseUrl') + ->with(['_type' => UrlInterface::URL_TYPE_MEDIA]) + ->willReturn('http://magento2.com/pub/media/'); + $this->mediaDirectory->expects($this->once()) + ->method('getRelativePath') + ->with('value') + ->willReturn('value'); $this->mediaDirectory->expects($this->once()) ->method('stat') - ->with('/image/' . $value) + ->with('value/' . $value) ->willReturn(['size' => 234234]); - $this->imageConfig->expects($this->once()) - ->method('getStoreMediaUrl') - ->willReturn('http://magento2.com/pub/media'); - $this->imageBackend->afterLoad(); + + $this->fileBackend->afterLoad(); $this->assertEquals( [ [ - 'url' => 'http://magento2.com/pub/media/image/' . $value, + 'url' => 'http://magento2.com/pub/media/design/file/' . $value, 'file' => $value, 'size' => 234234, 'exists' => true, ] ], - $this->imageBackend->getValue() + $this->fileBackend->getValue() ); } public function testBeforeSave() { $value = 'filename.jpg'; - $tmpMediaPath = 'tmp/image/' . $value; - $this->imageBackend->setScope('store'); - $this->imageBackend->setScopeId(1); - $this->imageBackend->setValue( + $tmpMediaPath = 'tmp/design/file/' . $value; + $this->fileBackend->setScope('store'); + $this->fileBackend->setScopeId(1); + $this->fileBackend->setValue( [ [ 'url' => 'http://magento2.com/pub/media/tmp/image/' . $value, @@ -124,24 +148,25 @@ class ImageTest extends \PHPUnit_Framework_TestCase ] ] ); - $this->imageConfig->expects($this->exactly(2)) - ->method('getTmpMediaPath') - ->with($value) - ->willReturn($tmpMediaPath); + $this->fileBackend->setFieldConfig( + [ + 'upload_dir' => [ + 'value' => 'value', + 'config' => 'system/filesystem/media', + ], + ] + ); $this->mediaDirectory->expects($this->once()) ->method('copyFile') - ->with( - $tmpMediaPath, - 'image/store/1/' . $value - ) + ->with($tmpMediaPath, '/' . $value) ->willReturn(true); $this->mediaDirectory->expects($this->once()) ->method('delete') ->with($tmpMediaPath); - $this->imageBackend->beforeSave(); - $this->assertEquals('store/1/filename.jpg', $this->imageBackend->getValue()); + $this->fileBackend->beforeSave(); + $this->assertEquals('filename.jpg', $this->fileBackend->getValue()); } /** @@ -150,7 +175,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase */ public function testBeforeSaveWithoutFile() { - $this->imageBackend->setData( + $this->fileBackend->setData( [ 'value' => [ 'test' => '' @@ -160,13 +185,13 @@ class ImageTest extends \PHPUnit_Framework_TestCase ], ] ); - $this->imageBackend->beforeSave(); + $this->fileBackend->beforeSave(); } public function testBeforeSaveWithExistingFile() { $value = 'filename.jpg'; - $this->imageBackend->setValue( + $this->fileBackend->setValue( [ [ 'url' => 'http://magento2.com/pub/media/tmp/image/' . $value, @@ -176,10 +201,10 @@ class ImageTest extends \PHPUnit_Framework_TestCase ] ] ); - $this->imageBackend->beforeSave(); + $this->fileBackend->beforeSave(); $this->assertEquals( $value, - $this->imageBackend->getValue() + $this->fileBackend->getValue() ); } } diff --git a/app/code/Magento/Theme/Test/Unit/Model/Design/Config/FileUploader/ImageProcessorTest.php b/app/code/Magento/Theme/Test/Unit/Model/Design/Config/FileUploader/FileProcessorTest.php similarity index 61% rename from app/code/Magento/Theme/Test/Unit/Model/Design/Config/FileUploader/ImageProcessorTest.php rename to app/code/Magento/Theme/Test/Unit/Model/Design/Config/FileUploader/FileProcessorTest.php index 4449104fdd76148cf97de19a831df4808e474a5e..ceda9e18effa1d80bc1beaaa523b0347f5268544 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/Design/Config/FileUploader/ImageProcessorTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/Design/Config/FileUploader/FileProcessorTest.php @@ -5,9 +5,11 @@ */ namespace Magento\Theme\Test\Unit\Model\Design\Config\FileUploader; -use Magento\Theme\Model\Design\Config\FileUploader\ImageProcessor; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\UrlInterface; +use Magento\Theme\Model\Design\Config\FileUploader\FileProcessor; -class ImageProcessorTest extends \PHPUnit_Framework_TestCase +class FileProcessorTest extends \PHPUnit_Framework_TestCase { /** @var \Magento\MediaStorage\Model\File\UploaderFactory|\PHPUnit_Framework_MockObject_MockObject */ protected $uploaderFactory; @@ -15,20 +17,26 @@ class ImageProcessorTest extends \PHPUnit_Framework_TestCase /** @var \Magento\MediaStorage\Model\File\Uploader|\PHPUnit_Framework_MockObject_MockObject */ protected $uploader; - /** @var \Magento\Theme\Model\Design\Config\FileUploader\Config|\PHPUnit_Framework_MockObject_MockObject */ - protected $imageConfig; - /** @var \Magento\Theme\Model\Design\BackendModelFactory|\PHPUnit_Framework_MockObject_MockObject */ protected $backendModelFactory; - /** @var \Magento\Theme\Model\Design\Backend\Image|\PHPUnit_Framework_MockObject_MockObject */ + /** @var \Magento\Theme\Model\Design\Backend\File|\PHPUnit_Framework_MockObject_MockObject */ protected $backendModel; /** @var \Magento\Theme\Model\Design\Config\MetadataProvider|\PHPUnit_Framework_MockObject_MockObject */ protected $metadataProvider; - /** @var ImageProcessor */ - protected $imageProcessor; + /** @var \Magento\Framework\Filesystem\Directory\WriteInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $directoryWrite; + + /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $storeManager; + + /** @var \Magento\Store\Api\Data\StoreInterface|\PHPUnit_Framework_MockObject_MockObject */ + protected $store; + + /** @var FileProcessor */ + protected $fileProcessor; public function setUp() { @@ -39,23 +47,36 @@ class ImageProcessorTest extends \PHPUnit_Framework_TestCase $this->uploader = $this->getMockBuilder('Magento\MediaStorage\Model\File\Uploader') ->disableOriginalConstructor() ->getMock(); - $this->imageConfig = $this->getMockBuilder('Magento\Theme\Model\Design\Config\FileUploader\Config') - ->disableOriginalConstructor() - ->getMock(); $this->backendModelFactory = $this->getMockBuilder('Magento\Theme\Model\Design\BackendModelFactory') ->disableOriginalConstructor() ->getMock(); - $this->backendModel = $this->getMockBuilder('Magento\Theme\Model\Design\Backend\Image') + $this->backendModel = $this->getMockBuilder('Magento\Theme\Model\Design\Backend\File') ->disableOriginalConstructor() ->getMock(); $this->metadataProvider = $this->getMockBuilder('Magento\Theme\Model\Design\Config\MetadataProvider') ->disableOriginalConstructor() ->getMock(); - $this->imageProcessor = new ImageProcessor( + $filesystem = $this->getMockBuilder('Magento\Framework\Filesystem') + ->disableOriginalConstructor() + ->getMock(); + $this->directoryWrite = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\WriteInterface') + ->getMockForAbstractClass(); + $filesystem->expects($this->once()) + ->method('getDirectoryWrite') + ->with(DirectoryList::MEDIA) + ->willReturn($this->directoryWrite); + $this->storeManager = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface') + ->getMockForAbstractClass(); + $this->store = $this->getMockBuilder('Magento\Store\Api\Data\StoreInterface') + ->setMethods(['getBaseUrl']) + ->getMockForAbstractClass(); + + $this->fileProcessor = new FileProcessor( $this->uploaderFactory, - $this->imageConfig, $this->backendModelFactory, - $this->metadataProvider + $this->metadataProvider, + $filesystem, + $this->storeManager ); } @@ -66,9 +87,20 @@ class ImageProcessorTest extends \PHPUnit_Framework_TestCase $metadata = [ $fieldCode => [ 'path' => $path, - 'backend_model' => 'Magento\Theme\Model\Design\Backend\Image' + 'backend_model' => 'Magento\Theme\Model\Design\Backend\File' ], ]; + $this->storeManager->expects($this->once()) + ->method('getStore') + ->willReturn($this->store); + $this->store->expects($this->once()) + ->method('getBaseUrl') + ->with(UrlInterface::URL_TYPE_MEDIA) + ->willReturn('http://magento2.com/pub/media/'); + $this->directoryWrite->expects($this->once()) + ->method('getAbsolutePath') + ->with('tmp/' . FileProcessor::FILE_DIR) + ->willReturn('absolute/path/to/tmp/media'); $this->metadataProvider->expects($this->once()) ->method('get') @@ -97,25 +129,17 @@ class ImageProcessorTest extends \PHPUnit_Framework_TestCase $this->uploader->expects($this->once()) ->method('addValidateCallback') ->with('size', $this->backendModel, 'validateMaxSize'); - $this->imageConfig - ->expects($this->once()) - ->method('getAbsoluteTmpMediaPath') - ->willReturn('absolute/path/to/tmp/media'); $this->uploader->expects($this->once()) ->method('save') ->with('absolute/path/to/tmp/media') ->willReturn(['file' => 'file.jpg', 'size' => '234234']); - $this->imageConfig->expects($this->once()) - ->method('getTmpMediaUrl') - ->with('file.jpg') - ->willReturn('http://magento2.com/pub/media/tmp/file.jpg'); $this->assertEquals( [ 'file' => 'file.jpg', 'size' => '234234', - 'url' => 'http://magento2.com/pub/media/tmp/file.jpg' + 'url' => 'http://magento2.com/pub/media/tmp/' . FileProcessor::FILE_DIR . '/file.jpg' ], - $this->imageProcessor->saveToTmp($fieldCode) + $this->fileProcessor->saveToTmp($fieldCode) ); } } diff --git a/app/code/Magento/Theme/Test/Unit/Model/Design/Config/StorageTest.php b/app/code/Magento/Theme/Test/Unit/Model/Design/Config/StorageTest.php index 77c1b2b7ca81161e98fdcc62185f65c4192fadf8..58d993cf20cfdc1c2bc71ab51d745a8fb6685e3d 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/Design/Config/StorageTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/Design/Config/StorageTest.php @@ -145,7 +145,7 @@ class StorageTest extends \PHPUnit_Framework_TestCase ->willReturn($this->backendModelMock); $this->valueCheckerMock->expects($this->once()) ->method('isDifferentFromDefault') - ->with('value', $scope, $scopeId, 'design/head/default_title') + ->with('value', $scope, $scopeId, ['path' => 'design/head/default_title']) ->willReturn(true); $this->transactionMock->expects($this->once()) ->method('addObject') @@ -175,13 +175,16 @@ class StorageTest extends \PHPUnit_Framework_TestCase $this->designConfigData->expects($this->atLeastOnce()) ->method('getPath') ->willReturn('path'); + $this->designConfigData->expects($this->atLeastOnce()) + ->method('getFieldConfig') + ->willReturn(['path' => 'path']); $this->scopeConfig->expects($this->once()) ->method('getValue') ->with('path', $scope, $scopeId) ->willReturn('value'); $this->valueProcessor->expects($this->once()) ->method('process') - ->with('value', 'path') + ->with('value', 'website', 1, ['path' => 'path']) ->willReturnArgument(0); $this->designConfigData->expects($this->once()) ->method('setValue') diff --git a/app/code/Magento/Theme/Test/Unit/Model/Design/Config/ValueCheckerTest.php b/app/code/Magento/Theme/Test/Unit/Model/Design/Config/ValueCheckerTest.php index 35afbdfc4660630cc121f9d8b32f088909b7e418..2a41342a855c67d60959705609329b1e3918be4e 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/Design/Config/ValueCheckerTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/Design/Config/ValueCheckerTest.php @@ -53,7 +53,7 @@ class ValueCheckerTest extends \PHPUnit_Framework_TestCase 'value', 'default', 0, - 'design/head/default_title' + ['path' => 'design/head/default_title'] ) ); } @@ -77,7 +77,7 @@ class ValueCheckerTest extends \PHPUnit_Framework_TestCase 'value', 'website', 1, - 'design/head/default_title' + ['path' => 'design/head/default_title'] ) ); } @@ -111,7 +111,7 @@ class ValueCheckerTest extends \PHPUnit_Framework_TestCase ], 'website', 1, - $path + ['path' => $path] ) ); } diff --git a/app/code/Magento/Theme/Test/Unit/Model/Design/Config/ValueProcessorTest.php b/app/code/Magento/Theme/Test/Unit/Model/Design/Config/ValueProcessorTest.php index ac8097a28fa271f0589bdee59bb912732e5d34d3..03eaca7853a52163544c8987ab6aa13c14b06df8 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/Design/Config/ValueProcessorTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/Design/Config/ValueProcessorTest.php @@ -35,16 +35,26 @@ class ValueProcessorTest extends \PHPUnit_Framework_TestCase { $path = 'design/head/logo'; $value = 'path/to/logo'; + $scope = 'websites'; + $scopeId = 1; $this->backendModelFactory->expects($this->once()) ->method('createByPath') - ->with($path, ['value' => $value]) + ->with( + $path, + [ + 'value' => $value, + 'field_config' => ['path' => $path], + 'scope' => $scope, + 'scope_id' => $scopeId + ] + ) ->willReturn($this->backendModel); $this->backendModel->expects($this->once()) ->method('afterLoad'); $this->backendModel->expects($this->once()) ->method('getValue') ->willReturn($value); - $this->assertEquals($value, $this->valueProcessor->process($value, $path)); + $this->assertEquals($value, $this->valueProcessor->process($value, $scope, $scopeId, ['path' => $path])); } } diff --git a/app/code/Magento/Theme/Test/Unit/Model/ResourceModel/Design/Config/Scope/CollectionTest.php b/app/code/Magento/Theme/Test/Unit/Model/ResourceModel/Design/Config/Scope/CollectionTest.php index 45a812039df8b20b1e76118d279ba528f1a1a74e..378016bb7e140104c579a2124a9bd098c292fb8f 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/ResourceModel/Design/Config/Scope/CollectionTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/ResourceModel/Design/Config/Scope/CollectionTest.php @@ -113,9 +113,9 @@ class CollectionTest extends \PHPUnit_Framework_TestCase $this->valueProcessor->expects($this->atLeastOnce()) ->method('process') ->withConsecutive( - ['DefaultValue', 'second/field/path'], - ['WebsiteValue', 'second/field/path'], - ['WebsiteValue', 'second/field/path'] + ['DefaultValue', 'default', null, ['path' => 'second/field/path', 'use_in_grid' => 1]], + ['WebsiteValue', 'website', 1, ['path' => 'second/field/path', 'use_in_grid' => 1]], + ['WebsiteValue', 'store', 1, ['path' => 'second/field/path', 'use_in_grid' => 1]] ) ->willReturnOnConsecutiveCalls( 'DefaultValue', diff --git a/app/code/Magento/Theme/Test/Unit/Model/Theme/Plugin/RegistrationTest.php b/app/code/Magento/Theme/Test/Unit/Model/Theme/Plugin/RegistrationTest.php index 4ec24f3eea6a614374030630734222e51172e97c..53a569f01b72a29c1b989162e41d0e18b228b628 100644 --- a/app/code/Magento/Theme/Test/Unit/Model/Theme/Plugin/RegistrationTest.php +++ b/app/code/Magento/Theme/Test/Unit/Model/Theme/Plugin/RegistrationTest.php @@ -53,61 +53,109 @@ class RegistrationTest extends \PHPUnit_Framework_TestCase ); } - public function testBeforeDispatch() - { - $theme = $this->getMock( - 'Magento\Theme\Model\Theme', - [ - 'setParentId', + /** + * @param bool $hasParentTheme + * @dataProvider dataProviderBeforeDispatch + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function testBeforeDispatch( + $hasParentTheme + ) { + $themeId = 1; + $themeTitle = 'Theme title'; + + $themeFromConfigMock = $this->getMockBuilder('Magento\Theme\Model\Theme') + ->disableOriginalConstructor() + ->setMethods([ 'getArea', 'getThemePath', 'getParentTheme', - 'getId', - 'getFullPath', - 'toArray', - 'addData', + 'getThemeTitle', + ]) + ->getMock(); + + $themeFromDbMock = $this->getMockBuilder('Magento\Theme\Model\Theme') + ->disableOriginalConstructor() + ->setMethods([ + 'setParentId', + 'setThemeTitle', 'save', - ], - [], - '', - false - ); - $this->appState->expects($this->once())->method('getMode')->willReturn('default'); - $this->themeRegistration->expects($this->once())->method('register'); - $this->themeCollection->expects($this->once())->method('loadData')->willReturn([$theme]); - $theme->expects($this->once())->method('getArea')->willReturn('frontend'); - $theme->expects($this->once())->method('getThemePath')->willReturn('Magento/luma'); - $theme->expects($this->exactly(2))->method('getParentTheme')->willReturnSelf(); - $theme->expects($this->once())->method('getId')->willReturn(1); - $theme->expects($this->once())->method('getFullPath')->willReturn('frontend/Magento/blank'); - $theme->expects($this->once())->method('setParentId')->with(1); - $this->themeLoader->expects($this->exactly(2)) + ]) + ->getMock(); + + $parentThemeFromDbMock = $this->getMockBuilder('Magento\Theme\Model\Theme') + ->disableOriginalConstructor() + ->getMock(); + + $parentThemeFromConfigMock = $this->getMockBuilder('Magento\Theme\Model\Theme') + ->disableOriginalConstructor() + ->getMock(); + + $this->appState->expects($this->once()) + ->method('getMode') + ->willReturn('default'); + + $this->themeRegistration->expects($this->once()) + ->method('register'); + + $this->themeCollection->expects($this->once()) + ->method('loadData') + ->willReturn([$themeFromConfigMock]); + + $this->themeLoader->expects($hasParentTheme ? $this->exactly(2) : $this->once()) ->method('getThemeByFullPath') - ->withConsecutive( - ['frontend/Magento/blank'], - ['frontend/Magento/luma'] - ) - ->will($this->onConsecutiveCalls( - $theme, - $theme - )); - $theme->expects($this->once()) - ->method('toArray') - ->willReturn([ - 'title' => 'Magento Luma' + ->willReturnMap([ + ['frontend/Magento/blank', $parentThemeFromDbMock], + ['frontend/Magento/luma', $themeFromDbMock], ]); - $theme->expects($this->once()) - ->method('addData') - ->with([ - 'title' => 'Magento Luma' - ]) + + $themeFromConfigMock->expects($this->once()) + ->method('getArea') + ->willReturn('frontend'); + $themeFromConfigMock->expects($this->once()) + ->method('getThemePath') + ->willReturn('Magento/luma'); + $themeFromConfigMock->expects($hasParentTheme ? $this->exactly(2) : $this->once()) + ->method('getParentTheme') + ->willReturn($hasParentTheme ? $parentThemeFromConfigMock : null); + $themeFromConfigMock->expects($this->once()) + ->method('getThemeTitle') + ->willReturn($themeTitle); + + $parentThemeFromDbMock->expects($hasParentTheme ? $this->once() : $this->never()) + ->method('getId') + ->willReturn($themeId); + + $parentThemeFromConfigMock->expects($hasParentTheme ? $this->once() : $this->never()) + ->method('getFullPath') + ->willReturn('frontend/Magento/blank'); + + $themeFromDbMock->expects($hasParentTheme ? $this->once() : $this->never()) + ->method('setParentId') + ->with($themeId) + ->willReturnSelf(); + $themeFromDbMock->expects($this->once()) + ->method('setThemeTitle') + ->with($themeTitle) + ->willReturnSelf(); + $themeFromDbMock->expects($this->once()) + ->method('save') ->willReturnSelf(); - $theme->expects($this->once()) - ->method('save'); $this->plugin->beforeDispatch($this->abstractAction, $this->request); } + /** + * @return array + */ + public function dataProviderBeforeDispatch() + { + return [ + [true], + [false], + ]; + } + public function testBeforeDispatchWithProductionMode() { $this->appState->expects($this->once())->method('getMode')->willReturn('production'); diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/insert-form.js b/app/code/Magento/Ui/view/base/web/js/form/components/insert-form.js index 790ce2a8cc4d950cc85652c685175eb7a55be07f..75234253c12d4362484b92e3a21a8fd2b3eef824 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/insert-form.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/insert-form.js @@ -89,7 +89,7 @@ define([ /** @inheritdoc*/ destroyInserted: function () { - if (this.isRendered) { + if (this.isRendered && this.externalForm()) { this.externalForm().delegate('destroy'); this.removeActions(); this.responseStatus(undefined); diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/insert-listing.js b/app/code/Magento/Ui/view/base/web/js/form/components/insert-listing.js index f77dcbb71af6855396f3e50c36579ea42600bcf7..eab8b0b8ff3537a6f2c0ec30dd0015bb02feabac 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/insert-listing.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/insert-listing.js @@ -77,7 +77,7 @@ define([ /** @inheritdoc */ destroyInserted: function () { - if (this.isRendered) { + if (this.isRendered && this.externalListing()) { this.externalListing().destroy(); }