diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php index 0dc343c88192b43e9f133ee589bfea81e247c018..9b75e6e6e0c325819d09f543cc445ae61eb7fb84 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Aggregation/DataProvider.php @@ -73,7 +73,7 @@ class DataProvider implements DataProviderInterface array $dimensions, Table $entityIdsTable ) { - $currentScope = $dimensions['scope']->getValue(); + $currentScope = $this->scopeResolver->getScope($dimensions['scope']->getValue())->getId(); $attribute = $this->eavConfig->getAttribute(Product::ENTITY, $bucket->getField()); diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php index 5161cc3e31a4d516108d8b46bb62c4f33abe1e5a..e6a6128cdc05866e912d6d0134fb439fbccd2b1a 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php @@ -67,8 +67,7 @@ class DataProvider Table $entityIdsTable ) { if ($bucket->getField() == 'category_ids') { - $currentScope = $dimensions['scope']->getValue(); - $currentScopeId = $this->scopeResolver->getScope($currentScope)->getId(); + $currentScopeId = $this->scopeResolver->getScope($dimensions['scope']->getValue())->getId(); $currentCategory = $this->layer->getCurrentCategory(); $derivedTable = $this->resource->getConnection()->select(); diff --git a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php index 5bec5552e091376ce22351302c615d6acaa7c2fc..72134fb16912939f5a80e42e8803fd7120e6f3a5 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php +++ b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php @@ -20,6 +20,7 @@ use Magento\Framework\Search\RequestInterface; use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver; use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\App\ScopeResolverInterface; /** * Build base Query for Index @@ -57,6 +58,11 @@ class IndexBuilder implements IndexBuilderInterface */ private $tableMapper; + /** + * @var ScopeResolverInterface + */ + private $dimensionScopeResolver; + /** * @param \Magento\Framework\App\ResourceConnection $resource * @param ScopeConfigInterface $config @@ -64,6 +70,7 @@ class IndexBuilder implements IndexBuilderInterface * @param ConditionManager $conditionManager * @param IndexScopeResolver $scopeResolver * @param TableMapper $tableMapper + * @param ScopeResolverInterface $dimensionScopeResolver */ public function __construct( ResourceConnection $resource, @@ -71,7 +78,8 @@ class IndexBuilder implements IndexBuilderInterface StoreManagerInterface $storeManager, ConditionManager $conditionManager, IndexScopeResolver $scopeResolver, - TableMapper $tableMapper + TableMapper $tableMapper, + ScopeResolverInterface $dimensionScopeResolver ) { $this->resource = $resource; $this->config = $config; @@ -79,6 +87,7 @@ class IndexBuilder implements IndexBuilderInterface $this->conditionManager = $conditionManager; $this->scopeResolver = $scopeResolver; $this->tableMapper = $tableMapper; + $this->dimensionScopeResolver = $dimensionScopeResolver; } /** @@ -158,7 +167,7 @@ class IndexBuilder implements IndexBuilderInterface $preparedDimensions[] = $this->conditionManager->generateCondition( $dimension->getName(), '=', - $dimension->getValue() + $this->dimensionScopeResolver->getScope($dimension->getValue())->getId() ); } diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php index 21e466383f9f1030b03da311019c4a6a153ff2e1..73dfd3867b0dcaf870794e6195d508309f440600 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php @@ -6,39 +6,38 @@ namespace Magento\CatalogSearch\Test\Unit\Model\Search; -use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; -use PHPUnit_Framework_MockObject_MockObject as MockObject; - /** * Test for \Magento\CatalogSearch\Model\Search\IndexBuilder + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class IndexBuilderTest extends \PHPUnit_Framework_TestCase { - /** @var \Magento\CatalogSearch\Model\Search\TableMapper|MockObject */ + /** @var \Magento\CatalogSearch\Model\Search\TableMapper|\PHPUnit_Framework_MockObject_MockObject */ private $tableMapper; - /** @var \Magento\Framework\Search\Adapter\Mysql\ConditionManager|MockObject */ + /** @var \Magento\Framework\Search\Adapter\Mysql\ConditionManager|\PHPUnit_Framework_MockObject_MockObject */ private $conditionManager; - /** @var \Magento\Search\Model\IndexScopeResolver|MockObject */ + /** @var \Magento\Search\Model\IndexScopeResolver|\PHPUnit_Framework_MockObject_MockObject */ private $scopeResolver; - /** @var \Magento\Framework\DB\Adapter\AdapterInterface|MockObject */ + /** @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject */ private $connection; - /** @var \Magento\Framework\DB\Select|MockObject */ + /** @var \Magento\Framework\DB\Select|\PHPUnit_Framework_MockObject_MockObject */ private $select; - /** @var \Magento\Framework\App\Config\ScopeConfigInterface|MockObject */ + /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ private $config; - /** @var \Magento\Store\Model\StoreManagerInterface|MockObject */ + /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ private $storeManager; - /** @var \Magento\Framework\Search\RequestInterface|MockObject */ + /** @var \Magento\Framework\Search\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */ private $request; - /** @var \Magento\Search\Model\IndexScopeResolver|MockObject */ + /** @var \Magento\Search\Model\IndexScopeResolver|\PHPUnit_Framework_MockObject_MockObject */ private $resource; /** @@ -46,6 +45,16 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase */ private $target; + /** + * @var \Magento\Framework\App\ScopeResolverInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $dimensionScopeResolver; + + /** + * @var \Magento\Framework\App\ScopeInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $scopeInterface; + protected function setUp() { $this->select = $this->getMockBuilder('\Magento\Framework\DB\Select') @@ -118,8 +127,20 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase ->method('addTables') ->with($this->select, $this->request) ->willReturnArgument(0); + $this->dimensionScopeResolver = $this->getMockForAbstractClass( + '\Magento\Framework\App\ScopeResolverInterface', + [], + '', + false + ); + $this->scopeInterface = $this->getMockForAbstractClass( + '\Magento\Framework\App\ScopeInterface', + [], + '', + false + ); - $objectManagerHelper = new ObjectManagerHelper($this); + $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->target = $objectManagerHelper->getObject( 'Magento\CatalogSearch\Model\Search\IndexBuilder', [ @@ -129,6 +150,7 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase 'conditionManager' => $this->conditionManager, 'scopeResolver' => $this->scopeResolver, 'tableMapper' => $this->tableMapper, + 'dimensionScopeResolver' => $this->dimensionScopeResolver ] ); } @@ -167,6 +189,12 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase $this->request->expects($this->exactly(2)) ->method('getDimensions') ->willReturn($dimensions); + $this->dimensionScopeResolver->expects($this->once()) + ->method('getScope') + ->willReturn($this->scopeInterface); + $this->scopeInterface->expects($this->once()) + ->method('getId') + ->willReturn('someValue'); $this->mockBuild($index, $tableSuffix, false); @@ -270,7 +298,7 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase /** * @param $name * @param $value - * @return MockObject + * @return \PHPUnit_Framework_MockObject_MockObject */ private function createDimension($name, $value) { diff --git a/app/code/Magento/CatalogUrlRewrite/etc/setup/events.xml b/app/code/Magento/CatalogUrlRewrite/etc/setup/events.xml deleted file mode 100644 index e880a73ed296d5edc907b483235aa254f4ac628e..0000000000000000000000000000000000000000 --- a/app/code/Magento/CatalogUrlRewrite/etc/setup/events.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> - <event name="catalog_product_save_after"> - <observer name="process_url_rewrite_saving" instance="\Magento\CatalogUrlRewrite\Observer\ProductProcessUrlRewriteSavingObserver"/> - </event> -</config> diff --git a/app/code/Magento/CmsUrlRewrite/etc/adminhtml/events.xml b/app/code/Magento/CmsUrlRewrite/etc/events.xml similarity index 100% rename from app/code/Magento/CmsUrlRewrite/etc/adminhtml/events.xml rename to app/code/Magento/CmsUrlRewrite/etc/events.xml diff --git a/app/code/Magento/CmsUrlRewrite/etc/setup/events.xml b/app/code/Magento/CmsUrlRewrite/etc/setup/events.xml deleted file mode 100644 index 79798b599e2942ed6994b1c0e00b51d39de7e6bd..0000000000000000000000000000000000000000 --- a/app/code/Magento/CmsUrlRewrite/etc/setup/events.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0"?> -<!-- -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ ---> -<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> - <event name="cms_page_save_after"> - <observer name="process_url_rewrite_saving" instance="Magento\CmsUrlRewrite\Observer\ProcessUrlRewriteSavingObserver" /> - </event> -</config> diff --git a/lib/internal/Magento/Framework/Filesystem/Filter/ExcludeFilter.php b/lib/internal/Magento/Framework/Filesystem/Filter/ExcludeFilter.php new file mode 100644 index 0000000000000000000000000000000000000000..a00bf449718ab3f148d039e810c1a863cf89a7b2 --- /dev/null +++ b/lib/internal/Magento/Framework/Filesystem/Filter/ExcludeFilter.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\Filesystem\Filter; + +/** + * Filters Iterator to exclude specified files + */ +class ExcludeFilter extends \FilterIterator +{ + /** + * Array that is used for filtering + * + * @var array + */ + protected $_filters; + + /** + * Constructor + * + * @param \Iterator $iterator + * @param array $filters list of files to skip + */ + public function __construct(\Iterator $iterator, array $filters) + { + parent::__construct($iterator); + $this->_filters = $filters; + } + + /** + * Check whether the current element of the iterator is acceptable + * + * @return bool + */ + public function accept() + { + $current = str_replace('\\', '/', $this->current()->__toString()); + $currentFilename = str_replace('\\', '/', $this->current()->getFilename()); + + if ($currentFilename == '.' || $currentFilename == '..') { + return false; + } + + foreach ($this->_filters as $filter) { + $filter = str_replace('\\', '/', $filter); + if (false !== strpos($current, $filter)) { + return false; + } + } + + return true; + } +} diff --git a/lib/internal/Magento/Framework/Filesystem/Test/Unit/File/ExcludeFilterTest.php b/lib/internal/Magento/Framework/Filesystem/Test/Unit/File/ExcludeFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..bca9b5b66768591238324b4262fe8471374d47e3 --- /dev/null +++ b/lib/internal/Magento/Framework/Filesystem/Test/Unit/File/ExcludeFilterTest.php @@ -0,0 +1,57 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Framework\Filesystem\Test\Unit\File; + +use \Magento\Framework\Filesystem\Filter\ExcludeFilter; + +/** + * Class ExcludeFilterTest + */ +class ExcludeFilterTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Iterator + */ + protected $iterator; + + protected function setUp() + { + $this->iterator = $this->getFilesIterator(); + } + + public function testExclusion() + { + $iterator = new ExcludeFilter( + $this->iterator, + [ + BP . '/var/session/' + ] + ); + + foreach ($iterator as $i) { + $result[] = $i; + } + + $this->assertTrue(!in_array(BP . '/var/session/', $result), 'Filtered path should not be in array'); + } + + private function getFilesIterator () + { + $files = [ + BP . '/var/', + BP . '/var/session/', + BP . '/var/cache/' + ]; + + foreach ($files as $file) { + $item = $this->getMockBuilder('SplFileInfoClass')->setMethods(['__toString', 'getFilename'])->getMock(); + $item->expects($this->any())->method('__toString')->willReturn($file); + $item->expects($this->any())->method('getFilename')->willReturn('notDots'); + yield $item; + } + } +} diff --git a/lib/internal/Magento/Framework/Module/DependencyChecker.php b/lib/internal/Magento/Framework/Module/DependencyChecker.php index 1149d2f35bcdbbf723ca939bd93635ba81c31edc..92adbd6fbb7bfdff02ce8ace917c063e8010236d 100644 --- a/lib/internal/Magento/Framework/Module/DependencyChecker.php +++ b/lib/internal/Magento/Framework/Module/DependencyChecker.php @@ -50,7 +50,6 @@ class DependencyChecker $this->enabledModuleList = $list->getNames(); $this->fullModuleList = $loader->load(); $this->packageInfo = $packageInfoFactory->create(); - $this->graph = $this->createGraph(); } /** @@ -93,6 +92,7 @@ class DependencyChecker */ private function checkDependencyGraph($isEnable, $moduleNames, $enabledModules) { + $this->graph = $this->createGraph(); $dependenciesMissingAll = []; $graphMode = $isEnable ? Graph::DIRECTIONAL : Graph::INVERSE; foreach ($moduleNames as $moduleName) { diff --git a/lib/internal/Magento/Framework/Search/Search.php b/lib/internal/Magento/Framework/Search/Search.php index 718357d4c29ca237ebaa0772f0dadc1dbbbe197a..3bd25d6dec9c3b905cab4b03dcb684f6b64c1941 100644 --- a/lib/internal/Magento/Framework/Search/Search.php +++ b/lib/internal/Magento/Framework/Search/Search.php @@ -57,7 +57,7 @@ class Search implements SearchInterface { $this->requestBuilder->setRequestName($searchCriteria->getRequestName()); - $scope = $this->scopeResolver->getScope(); + $scope = $this->scopeResolver->getScope()->getId(); $this->requestBuilder->bindDimension('scope', $scope); foreach ($searchCriteria->getFilterGroups() as $filterGroup) { diff --git a/lib/internal/Magento/Framework/Search/Test/Unit/SearchTest.php b/lib/internal/Magento/Framework/Search/Test/Unit/SearchTest.php index bb4f56445c862182dcc703e5e3258dc2b8abf6c9..0fbf9215f63e7c424714b8073cc3c9b6a793fc11 100644 --- a/lib/internal/Magento/Framework/Search/Test/Unit/SearchTest.php +++ b/lib/internal/Magento/Framework/Search/Test/Unit/SearchTest.php @@ -65,10 +65,14 @@ class SearchTest extends \PHPUnit_Framework_TestCase public function testSearch() { $requestName = 'requestName'; - $scope = 333; + $scopeId = 333; $filterField = 'filterField'; $filterValue = 'filterValue'; + $scope = $this->getMockBuilder('Magento\Framework\App\ScopeInterface') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $filter = $this->getMockBuilder('Magento\Framework\Api\Filter') ->disableOriginalConstructor() ->getMock(); @@ -113,7 +117,7 @@ class SearchTest extends \PHPUnit_Framework_TestCase ->with($requestName); $this->requestBuilder->expects($this->once()) ->method('bindDimension') - ->with('scope', $scope); + ->with('scope', $scopeId); $this->requestBuilder->expects($this->any()) ->method('bind'); $this->requestBuilder->expects($this->once()) @@ -134,6 +138,10 @@ class SearchTest extends \PHPUnit_Framework_TestCase ->method('getScope') ->willReturn($scope); + $scope->expects($this->once()) + ->method('getId') + ->willReturn($scopeId); + $searchResult = $this->model->search($searchCriteria); $this->assertInstanceOf('Magento\Framework\Api\Search\SearchResultInterface', $searchResult); diff --git a/lib/internal/Magento/Framework/Setup/FilePermissions.php b/lib/internal/Magento/Framework/Setup/FilePermissions.php index e70e583c27114c0071fe16d85b7cccb1f05324aa..df65ae89296fc685d3fa240720a6ea3463307670 100644 --- a/lib/internal/Magento/Framework/Setup/FilePermissions.php +++ b/lib/internal/Magento/Framework/Setup/FilePermissions.php @@ -8,8 +8,10 @@ namespace Magento\Framework\Setup; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Backup\Filesystem\Iterator\Filter; +use Magento\Framework\Filesystem\Filter\ExcludeFilter; use Magento\Framework\Filesystem; use Magento\Framework\Filesystem\Driver\File; +use Magento\Framework\OsInfo; class FilePermissions { @@ -63,19 +65,27 @@ class FilePermissions */ protected $nonWritablePathsInDirectories = []; + /** + * @var \Magento\Framework\OsInfo + */ + protected $osInfo; + /** * @param Filesystem $filesystem * @param DirectoryList $directoryList * @param File $driverFile + * @param OsInfo $osInfo */ public function __construct( Filesystem $filesystem, DirectoryList $directoryList, - File $driverFile + File $driverFile, + OsInfo $osInfo ) { $this->filesystem = $filesystem; $this->directoryList = $directoryList; $this->driverFile = $driverFile; + $this->osInfo = $osInfo; } /** @@ -152,10 +162,18 @@ class FilePermissions ); $noWritableFilesFolders = [ $this->directoryList->getPath(DirectoryList::GENERATION) . '/', - $this->directoryList->getPath(DirectoryList::DI) .'/' + $this->directoryList->getPath(DirectoryList::DI) . '/', ]; $directoryIterator = new Filter($directoryIterator, $noWritableFilesFolders); + + $directoryIterator = new ExcludeFilter( + $directoryIterator, + [ + $this->directoryList->getPath(DirectoryList::SESSION) . '/', + ] + ); + $foundNonWritable = false; try { @@ -224,10 +242,7 @@ class FilePermissions array_unshift($dirs, $varGenerationDir); foreach ($dirs as $dir) { - if (!is_dir($dir) - || !is_readable($dir) - || !is_executable($dir) - ) { + if (!$this->directoryPermissionForCLIUserValid($dir)) { return false; } } @@ -293,4 +308,16 @@ class FilePermissions $current = $this->getApplicationCurrentNonWritableDirectories(); return array_diff($required, $current); } + + /** + * Checks if directory has permissions needed for CLI user (valid directory, readable, and executable.) + * Ignores executable permission for Windows. + * + * @param string $dir + * @return bool + */ + private function directoryPermissionForCLIUserValid($dir) + { + return (is_dir($dir) && is_readable($dir) && (is_executable($dir) || $this->osInfo->isWindows())); + } } diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php index 29869b89be72a9f4b194fff100f18b8272b80e13..3788a1ede33cfef1b935159fa8c74eeac7d8fadb 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php @@ -8,7 +8,6 @@ namespace Magento\Framework\Setup\Test\Unit; use \Magento\Framework\Setup\FilePermissions; use Magento\Framework\App\Filesystem\DirectoryList; -use Magento\Framework\Filesystem\Driver\File; class FilePermissionsTest extends \PHPUnit_Framework_TestCase { @@ -32,6 +31,11 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase */ private $driverFileMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\OsInfo + */ + private $osInfoMock; + /** * @var FilePermissions */ @@ -42,6 +46,7 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase $this->directoryWriteMock = $this->getMock('Magento\Framework\Filesystem\Directory\Write', [], [], '', false); $this->filesystemMock = $this->getMock('Magento\Framework\Filesystem', [], [], '', false); $this->driverFileMock = $this->getMock('Magento\Framework\Filesystem\Driver\File', [], [], '', false); + $this->osInfoMock = $this->getMock('Magento\Framework\OsInfo', [], [], '', false); $this->filesystemMock ->expects($this->any()) @@ -52,7 +57,8 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase $this->filePermissions = new FilePermissions( $this->filesystemMock, $this->directoryListMock, - $this->driverFileMock + $this->driverFileMock, + $this->osInfoMock ); } @@ -206,6 +212,55 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase ]; } + /** + * Directories have executable permission, not Windows + */ + public function testCheckDirectoryPermissionForCLIUser() + { + $this->directoryListMock->expects($this->once())->method('getPath')->willReturn('/var/generation'); + $this->driverFileMock->expects($this->once()) + ->method('readDirectory') + ->willReturn(['/var/generation/Composer', '/var/gen/Magento']); + // Should never check for OS if executable + $this->osInfoMock->expects($this->never())->method('isWindows'); + $this->assertTrue($this->filePermissions->checkDirectoryPermissionForCLIUser()); + } + + /** + * Directories do not have executable permissions, is Windows + */ + public function testCheckDirectoryPermissionForCLIUserWin() + { + $this->directoryListMock->expects($this->once())->method('getPath')->willReturn('/var/generationNotExec'); + $this->driverFileMock->expects($this->once()) + ->method('readDirectory') + ->willReturn(['/var/generation/ComposerNotExec', '/var/generation/MagentoNotExec']); + // Contains a 'NotExec', so is_executable will return false, isWindows should be called once for each + // directory (including parent) and return true + $this->osInfoMock->expects($this->exactly(3))->method('isWindows')->willReturn(true); + $this->assertTrue($this->filePermissions->checkDirectoryPermissionForCLIUser()); + } + + /** + * One directory does not have executable permission, is not Windows + */ + public function testCheckDirectoryPermissionForCLIUserNotExecutable() + { + $this->directoryListMock->expects($this->once())->method('getPath')->willReturn('/var/generation'); + $this->driverFileMock->expects($this->once()) + ->method('readDirectory') + ->willReturn(['/var/generation/ComposerNotExec', '/var/gen/Magento']); + // Contains a 'NotExec', so is_executable will return false, isWindows should be called and return false + $this->osInfoMock->expects($this->once())->method('isWindows')->willReturn(false); + $this->assertFalse($this->filePermissions->checkDirectoryPermissionForCLIUser()); + } + + /* + * exec directory, unix + * non-exec directory, windows + * non-exec directory, unix + */ + public function setUpDirectoryListInstallation() { $this->directoryListMock @@ -285,3 +340,46 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue(false)); } } + +namespace Magento\Framework\Setup; + +/** + * Overriding the built-in PHP function is_dir, always returns true, + * allows unit test of this code without having to setup special directories. + * + * @param string $filename + * @return true + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ +function is_dir($filename) +{ + return true; +} + +/** + * Overriding the built-in PHP function is_readable, always returns true, + * allows unit test of this code without having to setup special directories. + * + * @param string $filename + * @return true + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ +function is_readable($filename) +{ + return true; +} + +/** + * Overriding the built-in PHP function is_executable, will return false if directory name contains 'NotExec' + * Allows unit test of this code without having to setup a special directory with non-executable permission. + * + * @param string $filename + * @return bool + */ +function is_executable($filename) +{ + if (strpos($filename, 'NotExec') !== false) { + return false; + } + return true; +} diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php index d2c37704e42055d304f03f20c2462e0cc54a3da3..595f34a03d05396bd300be86d66b0b6a75aecf8f 100644 --- a/setup/src/Magento/Setup/Model/Installer.php +++ b/setup/src/Magento/Setup/Model/Installer.php @@ -825,7 +825,7 @@ class Installer $this->log->log("Module '{$moduleName}':"); $modulePostUpdater = $this->getSchemaDataHandler($moduleName, $handlerType); if ($modulePostUpdater) { - $this->log->logInline('Running ' + str_replace('-', ' ', $handlerType) + '...'); + $this->log->logInline('Running ' . str_replace('-', ' ', $handlerType) . '...'); $modulePostUpdater->install($setup, $moduleContextList[$moduleName]); } $this->logProgress();