diff --git a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php index c1fbd62d212129341ce19c777d4c84033c6e2c9b..b884e625c1a7a91e302773fb520a8778182958a9 100644 --- a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php +++ b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php @@ -185,63 +185,67 @@ class Storage extends \Magento\Framework\Object } /** - * Return one-level child directories for specified path + * Create sub directories if DB storage is used * - * @param string $path Parent directory path - * @return \Magento\Framework\Data\Collection\Filesystem - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) + * @param string $path + * @return void */ - public function getDirsCollection($path) + protected function createSubDirectories($path) { if ($this->_coreFileStorageDb->checkDbUsage()) { /** @var \Magento\MediaStorage\Model\File\Storage\Directory\Database $subDirectories */ $subDirectories = $this->_directoryDatabaseFactory->create(); - $subDirectories->getSubdirectories($path); - foreach ($subDirectories as $directory) { + $directories = $subDirectories->getSubdirectories($path); + foreach ($directories as $directory) { $fullPath = rtrim($path, '/') . '/' . $directory['name']; $this->_directory->create($fullPath); } } + } + /** + * Prepare and get conditions for exclude directories + * + * @return array + */ + protected function getConditionsForExcludeDirs() + { $conditions = ['reg_exp' => [], 'plain' => []]; if ($this->_dirs['exclude']) { foreach ($this->_dirs['exclude'] as $dir) { - $conditions[$dir->getAttribute('regexp') ? 'reg_exp' : 'plain'][$dir] = true; + $conditions[!empty($dir['regexp']) ? 'reg_exp' : 'plain'][$dir['name']] = true; } } // "include" section takes precedence and can revoke directory exclusion if ($this->_dirs['include']) { foreach ($this->_dirs['include'] as $dir) { - unset($conditions['regexp'][(string)$dir], $conditions['plain'][$dir]); + unset($conditions['reg_exp'][$dir['name']], $conditions['plain'][$dir['name']]); } } + return $conditions; + } + + /** + * Remove excluded directories from collection + * + * @param \Magento\Framework\Data\Collection\Filesystem $collection + * @param array $conditions + * @return \Magento\Framework\Data\Collection\Filesystem + */ + protected function removeItemFromCollection($collection, $conditions) + { $regExp = $conditions['reg_exp'] ? '~' . implode('|', array_keys($conditions['reg_exp'])) . '~i' : null; - $collection = $this->getCollection( - $path - )->setCollectDirs( - true - )->setCollectFiles( - false - )->setCollectRecursively( - false - ); $storageRootLength = strlen($this->_cmsWysiwygImages->getStorageRoot()); foreach ($collection as $key => $value) { $rootChildParts = explode('/', substr($value->getFilename(), $storageRootLength)); - if (array_key_exists( - $rootChildParts[0], - $conditions['plain'] - ) || $regExp && preg_match( - $regExp, - $value->getFilename() - ) - ) { + if (array_key_exists($rootChildParts[1], $conditions['plain']) + || ($regExp && preg_match($regExp, $value->getFilename()))) { + $collection->removeItemByKey($key); } } @@ -249,6 +253,26 @@ class Storage extends \Magento\Framework\Object return $collection; } + /** + * Return one-level child directories for specified path + * + * @param string $path Parent directory path + * @return \Magento\Framework\Data\Collection\Filesystem + */ + public function getDirsCollection($path) + { + $this->createSubDirectories($path); + + $collection = $this->getCollection($path) + ->setCollectDirs(true) + ->setCollectFiles(false) + ->setCollectRecursively(false); + + $conditions = $this->getConditionsForExcludeDirs(); + + return $this->removeItemFromCollection($collection, $conditions); + } + /** * Return files * diff --git a/app/code/Magento/Cms/Setup/InstallData.php b/app/code/Magento/Cms/Setup/InstallData.php index 726a8e45f01a369bf28833a02bd972ce67b5a857..e73fe3d3e6c0d2e498c6cf07bb6f8c4789987d90 100644 --- a/app/code/Magento/Cms/Setup/InstallData.php +++ b/app/code/Magento/Cms/Setup/InstallData.php @@ -111,13 +111,12 @@ class InstallData implements InstallDataInterface </span> </div> <p> - This privacy policy sets out how {{config path="general/store_information/name"}} uses and protects any - information that you give {{config path="general/store_information/name"}} when you use this website. - {{config path="general/store_information/name"}} is committed to ensuring that your privacy is protected. - Should we ask you to provide certain information by which you can be identified when using this website, - then you can be assured that it will only be used in accordance with this privacy statement. - {{config path="general/store_information/name"}} may change this policy from time to time by updating this page. - You should check this page from time to time to ensure that you are happy with any changes. + This privacy policy sets out how this website (hereafter "the Store") uses and protects any information that + you give the Store while using this website. The Store is committed to ensuring that your privacy is protected. + Should we ask you to provide certain information by which you can be identified when using this website, then + you can be assured that it will only be used in accordance with this privacy statement. The Store may change + this policy from time to time by updating this page. You should check this page from time to time to ensure + that you are happy with any changes. </p> <h2>What we collect</h2> <p>We may collect the following information:</p> @@ -191,8 +190,7 @@ class InstallData implements InstallDataInterface </li> <li> if you have previously agreed to us using your personal information for direct marketing purposes, - you may change your mind at any time by writing to or emailing us at - {{config path="trans_email/ident_general/email"}} + you may change your mind at any time by letting us know using our Contact Us information </li> </ul> <p> @@ -202,8 +200,8 @@ class InstallData implements InstallDataInterface </p> <p> You may request details of personal information which we hold about you under the Data Protection Act 1998. - A small fee will be payable. If you would like a copy of the information held on you please write to - {{config path="general/store_information/address"}}. + A small fee will be payable. If you would like a copy of the information held on you please email us this + request using our Contact Us information. </p> <p> If you believe that any information we are holding on you is incorrect or incomplete, diff --git a/app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php b/app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php index a24fae248edabe1f9b89dbe38fff026f542fc29a..f2a23dc16b8c25819223f1a0073a5e9bc8894369 100644 --- a/app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php +++ b/app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php @@ -1,14 +1,17 @@ <?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ namespace Magento\Cms\Test\Unit\Model\Wysiwyg\Images; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Cms\Model\Wysiwyg\Images\Storage\Collection as StorageCollection; /** - * Copyright © 2015 Magento. All rights reserved. - * See COPYING.txt for license details. - * * @SuppressWarnings(PHPMD.LongVariable) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) */ class StorageTest extends \PHPUnit_Framework_TestCase { @@ -22,72 +25,87 @@ class StorageTest extends \PHPUnit_Framework_TestCase /** * @var \Magento\Cms\Model\Wysiwyg\Images\Storage */ - protected $_model = null; + protected $imagesStorage; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_filesystemMock; + protected $filesystemMock; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_adapterFactoryMock; + protected $adapterFactoryMock; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_imageHelperMock; + protected $imageHelperMock; /** * @var array() */ - protected $_resizeParameters; + protected $resizeParameters; /** * @var \Magento\Cms\Model\Wysiwyg\Images\Storage\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $_storageCollectionFactoryMock; + protected $storageCollectionFactoryMock; + + /** + * @var \Magento\MediaStorage\Model\File\Storage\FileFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $storageFileFactoryMock; /** - * @var \Magento\MediaStorage\Model\File\Storage\FileFactory|PHPUnit_Framework_MockObject_MockObject + * @var \Magento\MediaStorage\Model\File\Storage\DatabaseFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $_storageFileFactoryMock; + protected $storageDatabaseFactoryMock; /** - * @var \Magento\MediaStorage\Model\File\Storage\DatabaseFactory|PHPUnit_Framework_MockObject_MockObject + * @var \Magento\MediaStorage\Model\File\Storage\Directory\DatabaseFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $_storageDatabaseFactoryMock; + protected $directoryDatabaseFactoryMock; /** - * @var \Magento\MediaStorage\Model\File\Storage\Directory\DatabaseFactory|PHPUnit_Framework_MockObject_MockObject + * @var \Magento\MediaStorage\Model\File\Storage\Directory\Database|\PHPUnit_Framework_MockObject_MockObject */ - protected $_directoryDatabaseFactoryMock; + protected $directoryCollectionMock; /** - * @var \Magento\MediaStorage\Model\File\UploaderFactory|PHPUnit_Framework_MockObject_MockObject + * @var \Magento\MediaStorage\Model\File\UploaderFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $_uploaderFactoryMock; + protected $uploaderFactoryMock; /** * @var \Magento\Backend\Model\Session|\PHPUnit_Framework_MockObject_MockObject */ - protected $_sessionMock; + protected $sessionMock; /** * @var \Magento\Backend\Model\Url|\PHPUnit_Framework_MockObject_MockObject */ - protected $_backendUrlMock; + protected $backendUrlMock; /** * @var \Magento\Framework\Filesystem\Directory\Write|\PHPUnit_Framework_MockObject_MockObject */ - protected $_directoryMock; + protected $directoryMock; /** * @var \Magento\Framework\Filesystem\DriverInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $_driverMock; + protected $driverMock; + + /** + * @var \Magento\MediaStorage\Helper\File\Storage\Database|\PHPUnit_Framework_MockObject_MockObject + */ + protected $coreFileStorageMock; + + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager|\PHPUnit_Framework_MockObject_MockObject + */ + protected $objectManagerHelper; /** * @return void @@ -95,8 +113,8 @@ class StorageTest extends \PHPUnit_Framework_TestCase */ protected function setUp() { - $this->_filesystemMock = $this->getMock('Magento\Framework\Filesystem', [], [], '', false); - $this->_driverMock = $this->getMockForAbstractClass( + $this->filesystemMock = $this->getMock('Magento\Framework\Filesystem', [], [], '', false); + $this->driverMock = $this->getMockForAbstractClass( 'Magento\Framework\Filesystem\DriverInterface', [], '', @@ -105,55 +123,55 @@ class StorageTest extends \PHPUnit_Framework_TestCase true, ['getRealPath'] ); - $this->_driverMock->expects($this->any())->method('getRealPath')->will($this->returnArgument(0)); + $this->driverMock->expects($this->any())->method('getRealPath')->will($this->returnArgument(0)); - $this->_directoryMock = $this->getMock( + $this->directoryMock = $this->getMock( 'Magento\Framework\Filesystem\Directory\Write', - ['delete', 'getDriver'], + ['delete', 'getDriver', 'create'], [], '', false ); - $this->_directoryMock->expects( + $this->directoryMock->expects( $this->any() )->method( 'getDriver' )->will( - $this->returnValue($this->_driverMock) + $this->returnValue($this->driverMock) ); - $this->_filesystemMock = $this->getMock( + $this->filesystemMock = $this->getMock( 'Magento\Framework\Filesystem', ['getDirectoryWrite'], [], '', false ); - $this->_filesystemMock->expects( + $this->filesystemMock->expects( $this->any() )->method( 'getDirectoryWrite' )->with( DirectoryList::MEDIA )->will( - $this->returnValue($this->_directoryMock) + $this->returnValue($this->directoryMock) ); - $this->_adapterFactoryMock = $this->getMock( + $this->adapterFactoryMock = $this->getMock( 'Magento\Framework\Image\AdapterFactory', [], [], '', false ); - $this->_imageHelperMock = $this->getMock( + $this->imageHelperMock = $this->getMock( 'Magento\Cms\Helper\Wysiwyg\Images', ['getStorageRoot'], [], '', false ); - $this->_imageHelperMock->expects( + $this->imageHelperMock->expects( $this->any() )->method( 'getStorageRoot' @@ -161,65 +179,76 @@ class StorageTest extends \PHPUnit_Framework_TestCase $this->returnValue(self::STORAGE_ROOT_DIR) ); - $this->_resizeParameters = ['width' => 100, 'height' => 50]; + $this->resizeParameters = ['width' => 100, 'height' => 50]; - $this->_storageCollectionFactoryMock = $this->getMock( + $this->storageCollectionFactoryMock = $this->getMock( 'Magento\Cms\Model\Wysiwyg\Images\Storage\CollectionFactory', ['create'], [], '', false ); - $this->_storageFileFactoryMock = $this->getMock( + $this->storageFileFactoryMock = $this->getMock( 'Magento\MediaStorage\Model\File\Storage\FileFactory', [], [], '', false ); - $this->_storageDatabaseFactoryMock = $this->getMock( + $this->storageDatabaseFactoryMock = $this->getMock( 'Magento\MediaStorage\Model\File\Storage\DatabaseFactory', [], [], '', false ); - $this->_directoryDatabaseFactoryMock = $this->getMock( + $this->directoryDatabaseFactoryMock = $this->getMock( 'Magento\MediaStorage\Model\File\Storage\Directory\DatabaseFactory', + ['create'], + [], + '', + false + ); + $this->directoryCollectionMock = $this->getMock( + 'Magento\MediaStorage\Model\File\Storage\Directory\Database', [], [], '', false ); - $this->_uploaderFactoryMock = $this->getMockBuilder('Magento\MediaStorage\Model\File\UploaderFactory') + + $this->uploaderFactoryMock = $this->getMockBuilder('Magento\MediaStorage\Model\File\UploaderFactory') + ->disableOriginalConstructor() + ->getMock(); + $this->sessionMock = $this->getMock('Magento\Backend\Model\Session', [], [], '', false); + $this->backendUrlMock = $this->getMock('Magento\Backend\Model\Url', [], [], '', false); + + $this->coreFileStorageMock = $this->getMockBuilder('Magento\MediaStorage\Helper\File\Storage\Database') ->disableOriginalConstructor() ->getMock(); - $this->_sessionMock = $this->getMock('Magento\Backend\Model\Session', [], [], '', false); - $this->_backendUrlMock = $this->getMock('Magento\Backend\Model\Url', [], [], '', false); - $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->_model = $objectManagerHelper->getObject( + $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + + $this->imagesStorage = $this->objectManagerHelper->getObject( 'Magento\Cms\Model\Wysiwyg\Images\Storage', [ - 'session' => $this->_sessionMock, - 'backendUrl' => $this->_backendUrlMock, - 'cmsWysiwygImages' => $this->_imageHelperMock, - 'coreFileStorageDb' => $this->getMock( - 'Magento\MediaStorage\Helper\File\Storage\Database', - [], - [], - '', - false - ), - 'filesystem' => $this->_filesystemMock, - 'imageFactory' => $this->_adapterFactoryMock, + 'session' => $this->sessionMock, + 'backendUrl' => $this->backendUrlMock, + 'cmsWysiwygImages' => $this->imageHelperMock, + 'coreFileStorageDb' => $this->coreFileStorageMock, + 'filesystem' => $this->filesystemMock, + 'imageFactory' => $this->adapterFactoryMock, 'assetRepo' => $this->getMock('Magento\Framework\View\Asset\Repository', [], [], '', false), - 'storageCollectionFactory' => $this->_storageCollectionFactoryMock, - 'storageFileFactory' => $this->_storageFileFactoryMock, - 'storageDatabaseFactory' => $this->_storageDatabaseFactoryMock, - 'directoryDatabaseFactory' => $this->_directoryDatabaseFactoryMock, - 'uploaderFactory' => $this->_uploaderFactoryMock, - 'resizeParameters' => $this->_resizeParameters + 'storageCollectionFactory' => $this->storageCollectionFactoryMock, + 'storageFileFactory' => $this->storageFileFactoryMock, + 'storageDatabaseFactory' => $this->storageDatabaseFactoryMock, + 'directoryDatabaseFactory' => $this->directoryDatabaseFactoryMock, + 'uploaderFactory' => $this->uploaderFactoryMock, + 'resizeParameters' => $this->resizeParameters, + 'dirs' => [ + 'exclude' => [], + 'include' => [] + ] ] ); } @@ -229,7 +258,7 @@ class StorageTest extends \PHPUnit_Framework_TestCase */ public function testGetResizeWidth() { - $this->assertEquals(100, $this->_model->getResizeWidth()); + $this->assertEquals(100, $this->imagesStorage->getResizeWidth()); } /** @@ -237,7 +266,7 @@ class StorageTest extends \PHPUnit_Framework_TestCase */ public function testGetResizeHeight() { - $this->assertEquals(50, $this->_model->getResizeHeight()); + $this->assertEquals(50, $this->imagesStorage->getResizeHeight()); } /** @@ -249,7 +278,7 @@ class StorageTest extends \PHPUnit_Framework_TestCase '\Magento\Framework\Exception\LocalizedException', sprintf('Directory %s is not under storage root path.', self::INVALID_DIRECTORY_OVER_ROOT) ); - $this->_model->deleteDirectory(self::INVALID_DIRECTORY_OVER_ROOT); + $this->imagesStorage->deleteDirectory(self::INVALID_DIRECTORY_OVER_ROOT); } /** @@ -261,6 +290,167 @@ class StorageTest extends \PHPUnit_Framework_TestCase '\Magento\Framework\Exception\LocalizedException', sprintf('We can\'t delete root directory %s right now.', self::STORAGE_ROOT_DIR) ); - $this->_model->deleteDirectory(self::STORAGE_ROOT_DIR); + $this->imagesStorage->deleteDirectory(self::STORAGE_ROOT_DIR); + } + + public function testGetDirsCollectionCreateSubDirectories() + { + $directoryName = 'test1'; + + $this->coreFileStorageMock->expects($this->once()) + ->method('checkDbUsage') + ->willReturn(true); + + $this->directoryCollectionMock->expects($this->once()) + ->method('getSubdirectories') + ->with(self::STORAGE_ROOT_DIR) + ->willReturn([['name' => $directoryName]]); + + $this->directoryDatabaseFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($this->directoryCollectionMock); + + $this->directoryMock->expects($this->once()) + ->method('create') + ->with(rtrim(self::STORAGE_ROOT_DIR, '/') . '/' . $directoryName); + + $this->generalTestGetDirsCollection(self::STORAGE_ROOT_DIR); + } + + /** + * @param array $exclude + * @param array $include + * @param array $fileNames + * @param array $expectedRemoveKeys + * @dataProvider dirsCollectionDataProvider + */ + public function testGetDirsCollection($exclude, $include, $fileNames, $expectedRemoveKeys) + { + $this->imagesStorage = $this->objectManagerHelper->getObject( + 'Magento\Cms\Model\Wysiwyg\Images\Storage', + [ + 'session' => $this->sessionMock, + 'backendUrl' => $this->backendUrlMock, + 'cmsWysiwygImages' => $this->imageHelperMock, + 'coreFileStorageDb' => $this->coreFileStorageMock, + 'filesystem' => $this->filesystemMock, + 'imageFactory' => $this->adapterFactoryMock, + 'assetRepo' => $this->getMock('Magento\Framework\View\Asset\Repository', [], [], '', false), + 'storageCollectionFactory' => $this->storageCollectionFactoryMock, + 'storageFileFactory' => $this->storageFileFactoryMock, + 'storageDatabaseFactory' => $this->storageDatabaseFactoryMock, + 'directoryDatabaseFactory' => $this->directoryDatabaseFactoryMock, + 'uploaderFactory' => $this->uploaderFactoryMock, + 'resizeParameters' => $this->resizeParameters, + 'dirs' => [ + 'exclude' => $exclude, + 'include' => $include + ] + ] + ); + + $collection = []; + foreach ($fileNames as $filename) { + /** @var \Magento\Framework\Object|\PHPUnit_Framework_MockObject_MockObject $objectMock */ + $objectMock = $this->getMock('Magento\Framework\Object', ['getFilename'], [], '', false); + $objectMock->expects($this->any()) + ->method('getFilename') + ->willReturn(self::STORAGE_ROOT_DIR . $filename); + $collection[] = $objectMock; + } + + $this->generalTestGetDirsCollection(self::STORAGE_ROOT_DIR, $collection, $expectedRemoveKeys); + } + + /** + * @return array + */ + public function dirsCollectionDataProvider() + { + return [ + [ + 'exclude' => [ + ['name' => 'dress'] + ], + 'include' => [], + 'filenames' => [], + 'expectRemoveKeys' => [] + ], + [ + 'exclude' => [], + 'include' => [], + 'filenames' => [ + '/dress', + ], + 'expectRemoveKeys' => [] + ], + [ + 'exclude' => [ + ['name' => 'dress'] + ], + 'include' => [], + 'filenames' => [ + '/collection', + ], + 'expectRemoveKeys' => [] + ], + [ + 'exclude' => [ + ['name' => 'gear', 'regexp' => 1], + ['name' => 'home', 'regexp' => 1], + ['name' => 'collection'], + ['name' => 'dress'] + ], + 'include' => [ + ['name' => 'home', 'regexp' => 1], + ['name' => 'collection'] + ], + 'filenames' => [ + '/dress', + '/collection', + '/gear' + ], + 'expectRemoveKeys' => [[0], [2]] + ] + ]; + } + + /** + * General conditions for testGetDirsCollection tests + * + * @param string $path + * @param array $collectionArray + * @param array $expectedRemoveKeys + */ + protected function generalTestGetDirsCollection($path, $collectionArray = [], $expectedRemoveKeys = []) + { + /** @var StorageCollection|\PHPUnit_Framework_MockObject_MockObject $storageCollectionMock */ + $storageCollectionMock = $this->getMockBuilder('Magento\Cms\Model\Wysiwyg\Images\Storage\Collection') + ->disableOriginalConstructor() + ->getMock(); + $storageCollectionMock->expects($this->once()) + ->method('setCollectDirs') + ->with(true) + ->willReturnSelf(); + $storageCollectionMock->expects($this->once()) + ->method('setCollectFiles') + ->with(false) + ->willReturnSelf(); + $storageCollectionMock->expects($this->once()) + ->method('setCollectRecursively') + ->with(false) + ->willReturnSelf(); + $storageCollectionMock->expects($this->once()) + ->method('getIterator') + ->willReturn(new \ArrayIterator($collectionArray)); + $storageCollectionInvMock = $storageCollectionMock->expects($this->exactly(sizeof($expectedRemoveKeys))) + ->method('removeItemByKey'); + call_user_func_array([$storageCollectionInvMock, 'withConsecutive'], $expectedRemoveKeys); + + $this->storageCollectionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($storageCollectionMock); + + $this->imagesStorage->getDirsCollection($path); } } diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php index c28a8d4d07093cbd44506b57a0688615e18e78fe..b5b914db4cf5b1aa9d3756f2bbfa33784b71fb53 100644 --- a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php +++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php @@ -26,6 +26,11 @@ class PageActions extends Column /** @var UrlInterface */ protected $urlBuilder; + /** + * @var string + */ + private $editUrl; + /** * @param ContextInterface $context * @param UiComponentFactory $uiComponentFactory @@ -33,6 +38,7 @@ class PageActions extends Column * @param UrlInterface $urlBuilder * @param array $components * @param array $data + * @param string $editUrl */ public function __construct( ContextInterface $context, @@ -40,10 +46,12 @@ class PageActions extends Column UrlBuilder $actionUrlBuilder, UrlInterface $urlBuilder, array $components = [], - array $data = [] + array $data = [], + $editUrl = self::CMS_URL_PATH_EDIT ) { $this->urlBuilder = $urlBuilder; $this->actionUrlBuilder = $actionUrlBuilder; + $this->editUrl = $editUrl; parent::__construct($context, $uiComponentFactory, $components, $data); } @@ -60,7 +68,7 @@ class PageActions extends Column $name = $this->getData('name'); if (isset($item['page_id'])) { $item[$name]['edit'] = [ - 'href' => $this->urlBuilder->getUrl(self::CMS_URL_PATH_EDIT, ['page_id' => $item['page_id']]), + 'href' => $this->urlBuilder->getUrl($this->editUrl, ['page_id' => $item['page_id']]), 'label' => __('Edit') ]; $item[$name]['delete'] = [ diff --git a/app/code/Magento/Payment/Model/Method/Adapter.php b/app/code/Magento/Payment/Model/Method/Adapter.php index 314a03d51550fedde3cd9b9e8c795eb25b4f5061..ac3a5c96e630aca09b3891f13fe04286473bb932 100644 --- a/app/code/Magento/Payment/Model/Method/Adapter.php +++ b/app/code/Magento/Payment/Model/Method/Adapter.php @@ -366,6 +366,7 @@ class Adapter implements MethodInterface $payment, ['amount' => $amount] ); + return $this; } @@ -379,6 +380,7 @@ class Adapter implements MethodInterface $payment, ['amount' => $amount] ); + return $this; } @@ -406,6 +408,7 @@ class Adapter implements MethodInterface $payment, ['amount' => $amount] ); + return $this; } @@ -418,6 +421,7 @@ class Adapter implements MethodInterface 'cancel', $payment ); + return $this; } @@ -430,6 +434,7 @@ class Adapter implements MethodInterface 'void', $payment ); + return $this; } @@ -442,6 +447,7 @@ class Adapter implements MethodInterface 'accept_payment', $payment ); + return $this; } @@ -454,7 +460,8 @@ class Adapter implements MethodInterface 'deny_payment', $payment ); - return false; + + return $this; } /** diff --git a/app/code/Magento/Sales/Model/Order/Payment.php b/app/code/Magento/Sales/Model/Order/Payment.php index 39d7be3556d6d73df4d19894f8316db94c3f9fab..ef13f325fcec26516c4900af9a524b49cfc32490 100755 --- a/app/code/Magento/Sales/Model/Order/Payment.php +++ b/app/code/Magento/Sales/Model/Order/Payment.php @@ -1020,9 +1020,15 @@ class Payment extends Info implements OrderPaymentInterface { $transactionId = $isOnline ? $this->getLastTransId() : $this->getTransactionId(); - $result = $isOnline ? - $this->getMethodInstance()->setStore($this->getOrder()->getStoreId())->denyPayment($this) : - (bool)$this->getNotificationResult(); + if ($isOnline) { + /** @var \Magento\Payment\Model\Method\AbstractMethod $method */ + $method = $this->getMethodInstance(); + $method->setStore($this->getOrder()->getStoreId()); + + $result = $method->denyPayment($this); + } else { + $result = (bool)$this->getNotificationResult(); + } if ($result) { $invoice = $this->_getInvoiceForTransactionId($transactionId); diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php old mode 100644 new mode 100755 index ed0bab0aec2ea260f851808fcdaee177d67d4d60..2f28cf9818308b3e176783004e84ad1b91bd8a83 --- a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php +++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php @@ -1,6 +1,5 @@ <?php /** - * * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ @@ -8,102 +7,149 @@ namespace Magento\Sitemap\Controller\Adminhtml\Sitemap; use Magento\Backend\App\Action; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Controller; class Save extends \Magento\Sitemap\Controller\Adminhtml\Sitemap { /** - * Save action + * Validate path for generation * - * @return void - * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @param array $data + * @return bool + * @throws \Exception */ - public function execute() + protected function validatePath(array $data) { - // check if data sent - $data = $this->getRequest()->getPostValue(); - if ($data) { - // init model and set data - /** @var \Magento\Sitemap\Model\Sitemap $model */ - $model = $this->_objectManager->create('Magento\Sitemap\Model\Sitemap'); - - //validate path to generate - if (!empty($data['sitemap_filename']) && !empty($data['sitemap_path'])) { - $data['sitemap_path'] = '/' . ltrim($data['sitemap_path'], '/'); - $path = rtrim($data['sitemap_path'], '\\/') . '/' . $data['sitemap_filename']; - /** @var $validator \Magento\MediaStorage\Model\File\Validator\AvailablePath */ - $validator = $this->_objectManager->create('Magento\MediaStorage\Model\File\Validator\AvailablePath'); - /** @var $helper \Magento\Sitemap\Helper\Data */ - $helper = $this->_objectManager->get('Magento\Sitemap\Helper\Data'); - $validator->setPaths($helper->getValidPaths()); - if (!$validator->isValid($path)) { - foreach ($validator->getMessages() as $message) { - $this->messageManager->addError($message); - } - // save data in session - $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data); - // redirect to edit form - $this->_redirect( - 'adminhtml/*/edit', - ['sitemap_id' => $this->getRequest()->getParam('sitemap_id')] - ); - return; + if (!empty($data['sitemap_filename']) && !empty($data['sitemap_path'])) { + $data['sitemap_path'] = '/' . ltrim($data['sitemap_path'], '/'); + $path = rtrim($data['sitemap_path'], '\\/') . '/' . $data['sitemap_filename']; + /** @var $validator \Magento\MediaStorage\Model\File\Validator\AvailablePath */ + $validator = $this->_objectManager->create('Magento\MediaStorage\Model\File\Validator\AvailablePath'); + /** @var $helper \Magento\Sitemap\Helper\Data */ + $helper = $this->_objectManager->get('Magento\Sitemap\Helper\Data'); + $validator->setPaths($helper->getValidPaths()); + if (!$validator->isValid($path)) { + foreach ($validator->getMessages() as $message) { + $this->messageManager->addError($message); } + // save data in session + $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data); + // redirect to edit form + return false; } + } + return true; + } - /** @var \Magento\Framework\Filesystem\Directory\Write $directory */ - $directory = $this->_objectManager->get( - 'Magento\Framework\Filesystem' - )->getDirectoryWrite( - DirectoryList::ROOT - ); + /** + * Clear sitemap + * + * @param \Magento\Sitemap\Model\Sitemap $model + * @return void + */ + protected function clearSiteMap(\Magento\Sitemap\Model\Sitemap $model) + { + /** @var \Magento\Framework\Filesystem\Directory\Write $directory */ + $directory = $this->_objectManager->get('Magento\Framework\Filesystem') + ->getDirectoryWrite(DirectoryList::ROOT); - if ($this->getRequest()->getParam('sitemap_id')) { - $model->load($this->getRequest()->getParam('sitemap_id')); - $fileName = $model->getSitemapFilename(); + if ($this->getRequest()->getParam('sitemap_id')) { + $model->load($this->getRequest()->getParam('sitemap_id')); + $fileName = $model->getSitemapFilename(); - $path = $model->getSitemapPath() . '/' . $fileName; - if ($fileName && $directory->isFile($path)) { - $directory->delete($path); - } + $path = $model->getSitemapPath() . '/' . $fileName; + if ($fileName && $directory->isFile($path)) { + $directory->delete($path); } + } + } - $model->setData($data); + /** + * Save data + * + * @param array $data + * @return string|bool + */ + protected function saveData($data) + { + // init model and set data + /** @var \Magento\Sitemap\Model\Sitemap $model */ + $model = $this->_objectManager->create('Magento\Sitemap\Model\Sitemap'); + $this->clearSiteMap($model); + $model->setData($data); - // try to save it - try { - // save the data - $model->save(); - // display success message - $this->messageManager->addSuccess(__('You saved the sitemap.')); - // clear previously saved data from session - $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false); + // try to save it + try { + // save the data + $model->save(); + // display success message + $this->messageManager->addSuccess(__('You saved the sitemap.')); + // clear previously saved data from session + $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false); + return $model->getId(); + } catch (\Exception $e) { + // display error message + $this->messageManager->addError($e->getMessage()); + // save data in session + $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data); + } + return false; + } - // check if 'Save and Continue' - if ($this->getRequest()->getParam('back')) { - $this->_redirect('adminhtml/*/edit', ['sitemap_id' => $model->getId()]); - return; - } - // go to grid or forward to generate action - if ($this->getRequest()->getParam('generate')) { - $this->getRequest()->setParam('sitemap_id', $model->getId()); - $this->_forward('generate'); - return; - } - $this->_redirect('adminhtml/*/'); - return; - } catch (\Exception $e) { - // display error message - $this->messageManager->addError($e->getMessage()); - // save data in session - $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data); - // redirect to edit form - $this->_redirect( + /** + * Get result after saving data + * + * @param string|bool $id + * @return \Magento\Framework\Controller\ResultInterface + */ + protected function getResult($id) + { + /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ + $resultRedirect = $this->resultFactory->create(Controller\ResultFactory::TYPE_REDIRECT); + if ($id) { + // check if 'Save and Continue' + if ($this->getRequest()->getParam('back')) { + $resultRedirect->setPath('adminhtml/*/edit', ['sitemap_id' => $id]); + return $resultRedirect; + } + // go to grid or forward to generate action + if ($this->getRequest()->getParam('generate')) { + $this->getRequest()->setParam('sitemap_id', $id); + return $this->resultFactory->create(Controller\ResultFactory::TYPE_FORWARD) + ->forward('generate'); + } + $resultRedirect->setPath('adminhtml/*/'); + return $resultRedirect; + } + $resultRedirect->setPath( + 'adminhtml/*/edit', + ['sitemap_id' => $this->getRequest()->getParam('sitemap_id')] + ); + return $resultRedirect; + } + + /** + * Save action + * + * @return \Magento\Backend\Model\View\Result\Redirect + */ + public function execute() + { + // check if data sent + $data = $this->getRequest()->getPostValue(); + /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */ + $resultRedirect = $this->resultFactory->create(Controller\ResultFactory::TYPE_REDIRECT); + if ($data) { + if (!$this->validatePath($data)) { + $resultRedirect->setPath( 'adminhtml/*/edit', ['sitemap_id' => $this->getRequest()->getParam('sitemap_id')] ); - return; + return $resultRedirect; } + return $this->getResult($this->saveData($data)); } - $this->_redirect('adminhtml/*/'); + $resultRedirect->setPath('adminhtml/*/'); + return $resultRedirect; } } diff --git a/app/code/Magento/Sitemap/Test/Unit/Controller/Adminhtml/Sitemap/SaveTest.php b/app/code/Magento/Sitemap/Test/Unit/Controller/Adminhtml/Sitemap/SaveTest.php new file mode 100755 index 0000000000000000000000000000000000000000..e067bf2059814fdeadbd0719adda36117dfcdac0 --- /dev/null +++ b/app/code/Magento/Sitemap/Test/Unit/Controller/Adminhtml/Sitemap/SaveTest.php @@ -0,0 +1,171 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Sitemap\Test\Unit\Controller\Adminhtml\Sitemap; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\Controller\ResultFactory; + +class SaveTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Sitemap\Controller\Adminhtml\Sitemap\Save + */ + protected $saveController; + + /** + * @var \Magento\Backend\App\Action\Context + */ + protected $context; + + /** + * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + */ + protected $objectManagerHelper; + + /** + * @var \Magento\Framework\HTTP\PhpEnvironment\Request|\PHPUnit_Framework_MockObject_MockObject + */ + protected $requestMock; + + /** + * @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $resultFactoryMock; + + /** + * @var \Magento\Backend\Model\View\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject + */ + protected $resultRedirectMock; + + /** + * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $objectManagerMock; + + /** + * @var \Magento\Framework\Message\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $messageManagerMock; + + protected function setUp() + { + $this->requestMock = $this->getMockBuilder('Magento\Framework\App\RequestInterface') + ->disableOriginalConstructor() + ->setMethods(['getPostValue']) + ->getMockForAbstractClass(); + $this->resultRedirectMock = $this->getMockBuilder('Magento\Backend\Model\View\Result\Redirect') + ->disableOriginalConstructor() + ->getMock(); + $this->resultFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\ResultFactory') + ->disableOriginalConstructor() + ->getMock(); + $this->objectManagerMock = $this->getMockBuilder('Magento\Framework\ObjectManagerInterface') + ->getMock(); + $this->messageManagerMock = $this->getMockBuilder('Magento\Framework\Message\ManagerInterface') + ->getMock(); + + $this->resultFactoryMock->expects($this->once()) + ->method('create') + ->with(ResultFactory::TYPE_REDIRECT) + ->willReturn($this->resultRedirectMock); + + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->context = $this->objectManagerHelper->getObject( + 'Magento\Backend\App\Action\Context', + [ + 'resultFactory' => $this->resultFactoryMock, + 'request' => $this->requestMock, + 'messageManager' => $this->messageManagerMock, + 'objectManager' => $this->objectManagerMock + ] + ); + $this->saveController = $this->objectManagerHelper->getObject( + 'Magento\Sitemap\Controller\Adminhtml\Sitemap\Save', + [ + 'context' => $this->context + ] + ); + } + + public function testSaveEmptyDataShouldRedirectToDefault() + { + $this->requestMock->expects($this->once()) + ->method('getPostValue') + ->willReturn([]); + $this->resultRedirectMock->expects($this->once()) + ->method('setPath') + ->with('adminhtml/*/') + ->willReturnSelf(); + + $this->assertSame($this->resultRedirectMock, $this->saveController->execute()); + } + + public function testTryToSaveInvalidDataShouldFailWithErrors() + { + $validatorClass = 'Magento\MediaStorage\Model\File\Validator\AvailablePath'; + $helperClass = 'Magento\Sitemap\Helper\Data'; + $validPaths = []; + $messages = ['message1', 'message2']; + $sessionClass = 'Magento\Backend\Model\Session'; + $data = ['sitemap_filename' => 'sitemap_filename', 'sitemap_path' => '/sitemap_path']; + $siteMapId = 1; + + $this->requestMock->expects($this->once()) + ->method('getPostValue') + ->willReturn($data); + $this->requestMock->expects($this->once()) + ->method('getParam') + ->with('sitemap_id') + ->willReturn($siteMapId); + + $validator = $this->getMock($validatorClass, [], [], '', false); + $validator->expects($this->once()) + ->method('setPaths') + ->with($validPaths) + ->willReturnSelf(); + $validator->expects($this->once()) + ->method('isValid') + ->with('/sitemap_path/sitemap_filename') + ->willReturn(false); + $validator->expects($this->once()) + ->method('getMessages') + ->willReturn($messages); + + $helper = $this->getMock($helperClass, [], [], '', false); + $helper->expects($this->once()) + ->method('getValidPaths') + ->willReturn($validPaths); + + $session = $this->getMock($sessionClass, ['setFormData'], [], '', false); + $session->expects($this->once()) + ->method('setFormData') + ->with($data) + ->willReturnSelf(); + + $this->objectManagerMock->expects($this->once()) + ->method('create') + ->with($validatorClass) + ->willReturn($validator); + $this->objectManagerMock->expects($this->any()) + ->method('get') + ->willReturnMap([[$helperClass, $helper], [$sessionClass, $session]]); + + $this->messageManagerMock->expects($this->at(0)) + ->method('addError') + ->withConsecutive( + [$messages[0]], + [$messages[1]] + ) + ->willReturnSelf(); + + $this->resultRedirectMock->expects($this->once()) + ->method('setPath') + ->with('adminhtml/*/edit', ['sitemap_id' => $siteMapId]) + ->willReturnSelf(); + + $this->assertSame($this->resultRedirectMock, $this->saveController->execute()); + } +} diff --git a/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php b/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php index 6893905b14938d6e9f4906cb9c205c8563c43244..cc956ad07c5c55b55fe7a16b4d744bfea3413d18 100644 --- a/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php +++ b/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php @@ -56,4 +56,12 @@ abstract class AbstractAction extends Action implements UiActionInterface { return $this->_request->getParam('component'); } + + /** + * @return bool + */ + protected function _isAllowed() + { + return true; + } } diff --git a/app/code/Magento/Widget/Model/NamespaceResolver.php b/app/code/Magento/Widget/Model/NamespaceResolver.php index f4e035bdea589a6d61f7a5fda4ca643c1e93930f..c458bc795c61f1ad12af243b01de5ce337118292 100644 --- a/app/code/Magento/Widget/Model/NamespaceResolver.php +++ b/app/code/Magento/Widget/Model/NamespaceResolver.php @@ -12,19 +12,19 @@ class NamespaceResolver * * @var array */ - protected $_moduleNamespaces; + protected $moduleNamespaces; /** * @var \Magento\Framework\Module\ModuleListInterface */ - protected $_moduleList; + protected $moduleList; /** * @param \Magento\Framework\Module\ModuleListInterface $moduleList */ public function __construct(\Magento\Framework\Module\ModuleListInterface $moduleList) { - $this->_moduleList = $moduleList; + $this->moduleList = $moduleList; } /** @@ -34,28 +34,15 @@ class NamespaceResolver * @param string $name * @param bool $asFullModuleName * @return string - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) */ public function determineOmittedNamespace($name, $asFullModuleName = false) { - if (null === $this->_moduleNamespaces) { - $this->_moduleNamespaces = []; - foreach ($this->_moduleList->getNames() as $moduleName) { - $module = strtolower($moduleName); - $this->_moduleNamespaces[substr($module, 0, strpos($module, '_'))][$module] = $moduleName; - } - } - - $explodeString = strpos( - $name, - '\\' - ) === false ? '_' : '\\'; - $name = explode($explodeString, strtolower($name)); + $this->prepareModuleNamespaces(); + $name = $this->prepareName($name); $partsNum = count($name); $defaultNamespaceFlag = false; - foreach ($this->_moduleNamespaces as $namespaceName => $namespace) { + foreach ($this->moduleNamespaces as $namespaceName => $namespace) { // assume the namespace is omitted (default namespace only, which comes first) if ($defaultNamespaceFlag === false) { $defaultNamespaceFlag = true; @@ -74,4 +61,32 @@ class NamespaceResolver } return ''; } + + /** + * Prepare module namespaces + * + * @return void + */ + protected function prepareModuleNamespaces() + { + if (null === $this->moduleNamespaces) { + $this->moduleNamespaces = []; + foreach ($this->moduleList->getNames() as $moduleName) { + $module = strtolower($moduleName); + $this->moduleNamespaces[substr($module, 0, strpos($module, '_'))][$module] = $moduleName; + } + } + } + + /** + * Prepare name + * + * @param string $name + * @return array + */ + protected function prepareName($name) + { + $explodeString = strpos($name, '\\') === false ? '_' : '\\'; + return explode($explodeString, strtolower($name)); + } } diff --git a/app/code/Magento/Widget/Model/Widget.php b/app/code/Magento/Widget/Model/Widget.php index 8dcdc466ebb6870ecf20bcbc603c17bece868341..9ac4133834602fec95dbb0415cb2a311c15f15b5 100644 --- a/app/code/Magento/Widget/Model/Widget.php +++ b/app/code/Magento/Widget/Model/Widget.php @@ -3,9 +3,6 @@ * Copyright © 2015 Magento. All rights reserved. * See COPYING.txt for license details. */ - -// @codingStandardsIgnoreFile - namespace Magento\Widget\Model; /** @@ -16,39 +13,37 @@ class Widget /** * @var \Magento\Widget\Model\Config\Data */ - protected $_dataStorage; + protected $dataStorage; /** * @var \Magento\Framework\App\Cache\Type\Config */ - protected $_configCacheType; + protected $configCacheType; /** * @var \Magento\Framework\View\Asset\Repository */ - protected $_assetRepo; + protected $assetRepo; /** * @var \Magento\Framework\View\Asset\Source */ - protected $_assetSource; + protected $assetSource; /** * @var \Magento\Framework\View\FileSystem */ - protected $_viewFileSystem; + protected $viewFileSystem; /** - * Core data - * * @var \Magento\Framework\Escaper */ - protected $_escaper; + protected $escaper; /** * @var array */ - protected $_widgetsArray = []; + protected $widgetsArray = []; /** * @var \Magento\Widget\Helper\Conditions @@ -71,11 +66,11 @@ class Widget \Magento\Framework\View\FileSystem $viewFileSystem, \Magento\Widget\Helper\Conditions $conditionsHelper ) { - $this->_escaper = $escaper; - $this->_dataStorage = $dataStorage; - $this->_assetRepo = $assetRepo; - $this->_assetSource = $assetSource; - $this->_viewFileSystem = $viewFileSystem; + $this->escaper = $escaper; + $this->dataStorage = $dataStorage; + $this->assetRepo = $assetRepo; + $this->assetSource = $assetSource; + $this->viewFileSystem = $viewFileSystem; $this->conditionsHelper = $conditionsHelper; } @@ -118,8 +113,6 @@ class Widget * * @param string $type Widget type * @return \Magento\Framework\Object - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) */ public function getConfigAsObject($type) { @@ -129,54 +122,92 @@ class Widget if ($widget === null) { return $object; } - $widget = $this->_getAsCanonicalArray($widget); + $widget = $this->getAsCanonicalArray($widget); // Save all nodes to object data $object->setType($type); $object->setData($widget); // Correct widget parameters and convert its data to objects + $newParams = $this->prepareWidgetParameters($object); + $object->setData('parameters', $newParams); + + return $object; + } + + /** + * Prepare widget parameters + * + * @param \Magento\Framework\Object $object + * @return array + */ + protected function prepareWidgetParameters(\Magento\Framework\Object $object) + { $params = $object->getData('parameters'); $newParams = []; if (is_array($params)) { $sortOrder = 0; foreach ($params as $key => $data) { if (is_array($data)) { - $data['key'] = $key; - $data['sort_order'] = isset($data['sort_order']) ? (int)$data['sort_order'] : $sortOrder; - - // prepare values (for drop-dawns) specified directly in configuration - $values = []; - if (isset($data['values']) && is_array($data['values'])) { - foreach ($data['values'] as $value) { - if (isset($value['label']) && isset($value['value'])) { - $values[] = $value; - } - } - } - $data['values'] = $values; - - // prepare helper block object - if (isset($data['helper_block'])) { - $helper = new \Magento\Framework\Object(); - if (isset($data['helper_block']['data']) && is_array($data['helper_block']['data'])) { - $helper->addData($data['helper_block']['data']); - } - if (isset($data['helper_block']['type'])) { - $helper->setType($data['helper_block']['type']); - } - $data['helper_block'] = $helper; - } + $data = $this->prepareDropDownValues($data, $key, $sortOrder); + $data = $this->prepareHelperBlock($data); $newParams[$key] = new \Magento\Framework\Object($data); $sortOrder++; } } } - uasort($newParams, [$this, '_sortParameters']); - $object->setData('parameters', $newParams); + uasort($newParams, [$this, 'sortParameters']); - return $object; + return $newParams; + } + + /** + * Prepare drop-down values + * + * @param array $data + * @param string $key + * @param int $sortOrder + * @return array + */ + protected function prepareDropDownValues(array $data, $key, $sortOrder) + { + $data['key'] = $key; + $data['sort_order'] = isset($data['sort_order']) ? (int)$data['sort_order'] : $sortOrder; + + $values = []; + if (isset($data['values']) && is_array($data['values'])) { + foreach ($data['values'] as $value) { + if (isset($value['label']) && isset($value['value'])) { + $values[] = $value; + } + } + } + $data['values'] = $values; + + return $data; + } + + /** + * Prepare helper block + * + * @param array $data + * @return array + */ + protected function prepareHelperBlock(array $data) + { + if (isset($data['helper_block'])) { + $helper = new \Magento\Framework\Object(); + if (isset($data['helper_block']['data']) && is_array($data['helper_block']['data'])) { + $helper->addData($data['helper_block']['data']); + } + if (isset($data['helper_block']['type'])) { + $helper->setType($data['helper_block']['type']); + } + $data['helper_block'] = $helper; + } + + return $data; } /** @@ -188,7 +219,7 @@ class Widget */ public function getWidgets($filters = []) { - $widgets = $this->_dataStorage->get(); + $widgets = $this->dataStorage->get(); $result = $widgets; // filter widgets by params @@ -219,7 +250,7 @@ class Widget */ public function getWidgetsArray($filters = []) { - if (empty($this->_widgetsArray)) { + if (empty($this->widgetsArray)) { $result = []; foreach ($this->getWidgets($filters) as $code => $widget) { $result[$widget['name']] = [ @@ -229,10 +260,10 @@ class Widget 'description' => __((string)$widget['description']), ]; } - usort($result, [$this, "_sortWidgets"]); - $this->_widgetsArray = $result; + usort($result, [$this, "sortWidgets"]); + $this->widgetsArray = $result; } - return $this->_widgetsArray; + return $this->widgetsArray; } /** @@ -274,9 +305,9 @@ class Widget $html = sprintf( '<img id="%s" src="%s" title="%s">', - $this->_idEncode($directive), + $this->idEncode($directive), $this->getPlaceholderImageUrl($type), - $this->_escaper->escapeUrl($directive) + $this->escaper->escapeUrl($directive) ); return $html; } @@ -295,13 +326,13 @@ class Widget $placeholder = (string)$widget['placeholder_image']; } if ($placeholder) { - $asset = $this->_assetRepo->createAsset($placeholder); - $placeholder = $this->_assetSource->getFile($asset); + $asset = $this->assetRepo->createAsset($placeholder); + $placeholder = $this->assetSource->getFile($asset); if ($placeholder) { return $asset->getUrl(); } } - return $this->_assetRepo->getUrl('Magento_Widget::placeholder.gif'); + return $this->assetRepo->getUrl('Magento_Widget::placeholder.gif'); } /** @@ -328,12 +359,12 @@ class Widget } /** - * Remove attributes from widget array so that emulates how \Magento\Framework\Simplexml\Element::asCanonicalArray works + * Remove attributes from widget array and emulate work of \Magento\Framework\Simplexml\Element::asCanonicalArray * * @param array $inputArray * @return array */ - protected function _getAsCanonicalArray($inputArray) + protected function getAsCanonicalArray($inputArray) { if (array_key_exists('@', $inputArray)) { unset($inputArray['@']); @@ -342,7 +373,7 @@ class Widget if (!is_array($value)) { continue; } - $inputArray[$key] = $this->_getAsCanonicalArray($value); + $inputArray[$key] = $this->getAsCanonicalArray($value); } return $inputArray; } @@ -353,7 +384,7 @@ class Widget * @param string $string * @return string */ - protected function _idEncode($string) + protected function idEncode($string) { return strtr(base64_encode($string), '+/=', ':_-'); } @@ -365,7 +396,7 @@ class Widget * @param array $secondElement * @return bool */ - protected function _sortWidgets($firstElement, $secondElement) + protected function sortWidgets($firstElement, $secondElement) { return strcmp($firstElement["name"], $secondElement["name"]); } @@ -377,7 +408,7 @@ class Widget * @param \Magento\Framework\Object $secondElement * @return int */ - protected function _sortParameters($firstElement, $secondElement) + protected function sortParameters($firstElement, $secondElement) { $aOrder = (int)$firstElement->getData('sort_order'); $bOrder = (int)$secondElement->getData('sort_order'); diff --git a/app/code/Magento/Widget/Test/Unit/Model/NamespaceResolverTest.php b/app/code/Magento/Widget/Test/Unit/Model/NamespaceResolverTest.php new file mode 100644 index 0000000000000000000000000000000000000000..1e9552c058be42d307da333719488b3228e9d89a --- /dev/null +++ b/app/code/Magento/Widget/Test/Unit/Model/NamespaceResolverTest.php @@ -0,0 +1,99 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Widget\Test\Unit\Model; + +class NamespaceResolverTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Widget\Model\NamespaceResolver + */ + protected $namespaceResolver; + + /** + * @var \Magento\Framework\Module\ModuleListInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $moduleListMock; + + public function setUp() + { + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->moduleListMock = $this->getMockBuilder('Magento\Framework\Module\ModuleListInterface') + ->getMockForAbstractClass(); + + $this->namespaceResolver = $objectManager->getObject( + 'Magento\Widget\Model\NamespaceResolver', + [ + 'moduleList' => $this->moduleListMock + ] + ); + } + + /** + * @param string $namespace + * @param array $modules + * @param string $expected + * @param bool $asFullModuleName + * + * @dataProvider determineOmittedNamespaceDataProvider + */ + public function testDetermineOmittedNamespace($namespace, $modules, $expected, $asFullModuleName) + { + $this->moduleListMock->expects($this->once()) + ->method('getNames') + ->willReturn($modules); + + $this->assertSame( + $expected, + $this->namespaceResolver->determineOmittedNamespace($namespace, $asFullModuleName) + ); + } + + /** + * @return array + */ + public function determineOmittedNamespaceDataProvider() + { + return[ + [ + 'namespace' => 'Magento\Widget\Test\Unit\Model\NamespaceResolverTest', + 'modules' => ['Magento_Cms', 'Magento_Catalog', 'Magento_Sales', 'Magento_Widget'], + 'expected' => 'Magento_Widget', + 'asFullModuleName' => true + ], + [ + 'namespace' => 'Magento\Widget\Test\Unit\Model\NamespaceResolverTest', + 'modules' => ['Magento_Cms', 'Magento_Catalog', 'Magento_Sales', 'Magento_Widget'], + 'expected' => 'magento_widget', + 'asFullModuleName' => false + ], + [ + 'namespace' => 'Widget\Test\Unit\Model\NamespaceResolverTest', + 'modules' => ['Magento_Cms', 'Magento_Catalog', 'Magento_Sales', 'Magento_Widget'], + 'expected' => 'Magento_Widget', + 'asFullModuleName' => true + + ], + [ + 'namespace' => 'Widget\Test\Unit\Model\NamespaceResolverTest', + 'modules' => ['Magento_Cms', 'Magento_Catalog', 'Magento_Sales', 'Magento_Widget'], + 'expected' => 'widget', + 'asFullModuleName' => false + ], + [ + 'namespace' => 'Unit\Model\NamespaceResolverTest', + 'modules' => ['Magento_Cms', 'Magento_Catalog', 'Magento_Sales', 'Magento_Widget'], + 'expected' => '', + 'asFullModuleName' => true + ], + [ + 'namespace' => 'Unit\Model\NamespaceResolverTest', + 'modules' => ['Magento_Cms', 'Magento_Catalog', 'Magento_Sales', 'Magento_Widget'], + 'expected' => '', + 'asFullModuleName' => false + ], + ]; + } +} diff --git a/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php b/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php index dfbbc341d9b37c7d19b0986251e9a0b2c6f06c37..dffc3bf38ace272348b3a86e027f18fd526b83d4 100644 --- a/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php +++ b/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php @@ -8,33 +8,34 @@ namespace Magento\Widget\Test\Unit\Model; class WidgetTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\Widget\Model\Config\Data|PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Widget\Model\Config\Data|\PHPUnit_Framework_MockObject_MockObject */ - protected $_storage; + protected $dataStorageMock; /** * @var \Magento\Widget\Model\Widget */ - protected $_model; + protected $widget; public function setUp() { - $this->_storage = $this->getMockBuilder( - 'Magento\Widget\Model\Config\Data' - )->disableOriginalConstructor()->getMock(); + $this->dataStorageMock = $this->getMockBuilder('Magento\Widget\Model\Config\Data') + ->disableOriginalConstructor() + ->getMock(); $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $objectManagerHelper->getObject('Magento\Widget\Model\Widget', ['dataStorage' => $this->_storage]); - $this->_model = $objectManagerHelper->getObject( + $this->widget = $objectManagerHelper->getObject( 'Magento\Widget\Model\Widget', - ['dataStorage' => $this->_storage] + ['dataStorage' => $this->dataStorageMock] ); } public function testGetWidgets() { $expected = ['val1', 'val2']; - $this->_storage->expects($this->once())->method('get')->will($this->returnValue($expected)); - $result = $this->_model->getWidgets(); + $this->dataStorageMock->expects($this->once()) + ->method('get') + ->willReturn($expected); + $result = $this->widget->getWidgets(); $this->assertEquals($expected, $result); } @@ -42,8 +43,10 @@ class WidgetTest extends \PHPUnit_Framework_TestCase { $configFile = __DIR__ . '/_files/mappedConfigArrayAll.php'; $widgets = include $configFile; - $this->_storage->expects($this->once())->method('get')->will($this->returnValue($widgets)); - $result = $this->_model->getWidgets(['name' => 'CMS Page Link', 'description' => 'Link to a CMS Page']); + $this->dataStorageMock->expects($this->once()) + ->method('get') + ->willReturn($widgets); + $result = $this->widget->getWidgets(['name' => 'CMS Page Link', 'description' => 'Link to a CMS Page']); $configFileOne = __DIR__ . '/_files/mappedConfigArray1.php'; $expected = ['cms_page_link' => include $configFileOne]; $this->assertEquals($expected, $result); @@ -53,8 +56,10 @@ class WidgetTest extends \PHPUnit_Framework_TestCase { $configFile = __DIR__ . '/_files/mappedConfigArrayAll.php'; $widgets = include $configFile; - $this->_storage->expects($this->once())->method('get')->will($this->returnValue($widgets)); - $result = $this->_model->getWidgets(['name' => 'unknown', 'description' => 'unknown']); + $this->dataStorageMock->expects($this->once()) + ->method('get') + ->willReturn($widgets); + $result = $this->widget->getWidgets(['name' => 'unknown', 'description' => 'unknown']); $expected = []; $this->assertEquals($expected, $result); } @@ -63,16 +68,63 @@ class WidgetTest extends \PHPUnit_Framework_TestCase { $widgetOne = ['@' => ['type' => 'type1']]; $widgets = ['widget1' => $widgetOne]; - $this->_storage->expects($this->any())->method('get')->will($this->returnValue($widgets)); - $this->assertEquals($widgetOne, $this->_model->getWidgetByClassType('type1')); - $this->assertNull($this->_model->getWidgetByClassType('type2')); + $this->dataStorageMock->expects($this->any()) + ->method('get') + ->willReturn($widgets); + $this->assertEquals($widgetOne, $this->widget->getWidgetByClassType('type1')); + $this->assertNull($this->widget->getWidgetByClassType('type2')); } public function testGetWidgetDeclarationTypeWithBackslashes() { $this->assertContains( 'Magento\\\\Widget\\\\Backslashed\\\\ClassName', - $this->_model->getWidgetDeclaration('Magento\Widget\Backslashed\ClassName') + $this->widget->getWidgetDeclaration('Magento\Widget\Backslashed\ClassName') ); } + + public function testGetConfigAsObject() + { + $configFile = __DIR__ . '/_files/mappedConfigArrayAll.php'; + $widgets = include $configFile; + $this->dataStorageMock->expects($this->once()) + ->method('get') + ->willReturn($widgets); + + $resultObject = $this->widget->getConfigAsObject('Magento\Cms\Block\Widget\Page\Link'); + $this->assertInstanceOf('Magento\Framework\Object', $resultObject); + + $this->assertSame('CMS Page Link', $resultObject->getName()); + $this->assertSame('Link to a CMS Page', $resultObject->getDescription()); + $this->assertSame('1', $resultObject->getIsEmailCompatible()); + $this->assertSame('Magento_Cms::images/widget_page_link.png', $resultObject->getPlaceholderImage()); + + $resultParameters = $resultObject->getParameters(); + $this->assertInstanceOf('Magento\Framework\Object', $resultParameters['page_id' ]); + $this->assertInstanceOf('Magento\Framework\Object', $resultParameters['anchor_text']); + $this->assertInstanceOf('Magento\Framework\Object', $resultParameters['template']); + + $supportedContainersExpected = [ + '0' => [ + 'container_name' => 'left', + 'template' => ['default' => 'default', 'names_only' => 'link_inline'], + ], + '1' => [ + 'container_name' => 'content', + 'template' => ['grid' => 'default', 'list' => 'list'] + ], + ]; + $this->assertSame($supportedContainersExpected, $resultObject->getSupportedContainers()); + } + + public function testGetConfigAsObjectWidgetNoFound() + { + $this->dataStorageMock->expects($this->once()) + ->method('get') + ->willReturn([]); + + $resultObject = $this->widget->getConfigAsObject('Magento\Cms\Block\Widget\Page\Link'); + $this->assertInstanceOf('Magento\Framework\Object', $resultObject); + $this->assertSame([], $resultObject->getData()); + } } diff --git a/lib/internal/Magento/Framework/Cache/Core.php b/lib/internal/Magento/Framework/Cache/Core.php index 3fde67c05b317fff0db72f189f16e4a82b211821..6ed73bd93a2e1b28a1437b7ab9833a53fa8c5704 100644 --- a/lib/internal/Magento/Framework/Cache/Core.php +++ b/lib/internal/Magento/Framework/Cache/Core.php @@ -29,6 +29,7 @@ class Core extends \Zend_Cache_Core protected function _id($cacheId) { if ($cacheId !== null) { + $cacheId = str_replace('.', '__', $cacheId); //reduce collision chances $cacheId = preg_replace('/([^a-zA-Z0-9_]{1,1})/', '_', $cacheId); if (isset($this->_options['cache_id_prefix'])) { $cacheId = $this->_options['cache_id_prefix'] . $cacheId;