From e725aee8878caff2f806f03ead52e835828b6f9e Mon Sep 17 00:00:00 2001 From: Serhiy Shkolyarenko Date: Thu, 17 Dec 2015 17:54:26 +0200 Subject: [PATCH 001/128] MAGETWO-46968: Upgrade data issues fixed upgrade script (cherry picked from commit d145602) --- .../Magento/Customer/Setup/UpgradeData.php | 91 ++++++++++--------- 1 file changed, 46 insertions(+), 45 deletions(-) diff --git a/app/code/Magento/Customer/Setup/UpgradeData.php b/app/code/Magento/Customer/Setup/UpgradeData.php index 1f4da520fd0b2..5a0bdb4b42dee 100644 --- a/app/code/Magento/Customer/Setup/UpgradeData.php +++ b/app/code/Magento/Customer/Setup/UpgradeData.php @@ -60,6 +60,52 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface /** @var CustomerSetup $customerSetup */ $customerSetup = $this->customerSetupFactory->create(['setup' => $setup]); + if (version_compare($context->getVersion(), '2.0.6', '<')) { + $customerSetup->updateEntityType( + \Magento\Customer\Model\Customer::ENTITY, + 'entity_model', + 'Magento\Customer\Model\ResourceModel\Customer' + ); + $customerSetup->updateEntityType( + \Magento\Customer\Model\Customer::ENTITY, + 'increment_model', + 'Magento\Eav\Model\Entity\Increment\NumericValue' + ); + $customerSetup->updateEntityType( + \Magento\Customer\Model\Customer::ENTITY, + 'entity_attribute_collection', + 'Magento\Customer\Model\ResourceModel\Attribute\Collection' + ); + $customerSetup->updateEntityType( + 'customer_address', + 'entity_model', + 'Magento\Customer\Model\ResourceModel\Address' + ); + $customerSetup->updateEntityType( + 'customer_address', + 'entity_attribute_collection', + 'Magento\Customer\Model\ResourceModel\Address\Attribute\Collection' + ); + $customerSetup->updateAttribute( + 'customer_address', + 'country_id', + 'source_model', + 'Magento\Customer\Model\ResourceModel\Address\Attribute\Source\Country' + ); + $customerSetup->updateAttribute( + 'customer_address', + 'region', + 'backend_model', + 'Magento\Customer\Model\ResourceModel\Address\Attribute\Backend\Region' + ); + $customerSetup->updateAttribute( + 'customer_address', + 'region_id', + 'source_model', + 'Magento\Customer\Model\ResourceModel\Address\Attribute\Source\Region' + ); + } + if (version_compare($context->getVersion(), '2.0.1', '<')) { $entityAttributes = [ 'customer' => [ @@ -240,51 +286,6 @@ public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface ]; $this->upgradeAttributes($entityAttributes, $customerSetup); } - if (version_compare($context->getVersion(), '2.0.6', '<')) { - $customerSetup->updateEntityType( - \Magento\Customer\Model\Customer::ENTITY, - 'entity_model', - 'Magento\Customer\Model\ResourceModel\Customer' - ); - $customerSetup->updateEntityType( - \Magento\Customer\Model\Customer::ENTITY, - 'increment_model', - 'Magento\Eav\Model\Entity\Increment\NumericValue' - ); - $customerSetup->updateEntityType( - \Magento\Customer\Model\Customer::ENTITY, - 'entity_attribute_collection', - 'Magento\Customer\Model\ResourceModel\Attribute\Collection' - ); - $customerSetup->updateEntityType( - 'customer_address', - 'entity_model', - 'Magento\Customer\Model\ResourceModel\Address' - ); - $customerSetup->updateEntityType( - 'customer_address', - 'entity_attribute_collection', - 'Magento\Customer\Model\ResourceModel\Address\Attribute\Collection' - ); - $customerSetup->updateAttribute( - 'customer_address', - 'country_id', - 'source_model', - 'Magento\Customer\Model\ResourceModel\Address\Attribute\Source\Country' - ); - $customerSetup->updateAttribute( - 'customer_address', - 'region', - 'backend_model', - 'Magento\Customer\Model\ResourceModel\Address\Attribute\Backend\Region' - ); - $customerSetup->updateAttribute( - 'customer_address', - 'region_id', - 'source_model', - 'Magento\Customer\Model\ResourceModel\Address\Attribute\Source\Region' - ); - } if (version_compare($context->getVersion(), '2.0.6', '<')) { $setup->getConnection()->delete( From b113d789e778ab050fa2b308178ee6a0457e8a4e Mon Sep 17 00:00:00 2001 From: Daniel Fahlke Date: Sat, 7 Nov 2015 23:23:26 +0200 Subject: [PATCH 002/128] dont crash CustomerSetupUpgrade on users without password there may be modules or setups, which work with users not having a password at all (cherry picked from commit 539b80f) --- app/code/Magento/Customer/Setup/UpgradeData.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/code/Magento/Customer/Setup/UpgradeData.php b/app/code/Magento/Customer/Setup/UpgradeData.php index 5a0bdb4b42dee..d19765b99a43b 100644 --- a/app/code/Magento/Customer/Setup/UpgradeData.php +++ b/app/code/Magento/Customer/Setup/UpgradeData.php @@ -333,6 +333,9 @@ private function upgradeHash($setup) $customers = $setup->getConnection()->fetchAll($select); foreach ($customers as $customer) { + if ($customer['password_hash'] === null) { + continue; + } list($hash, $salt) = explode(Encryptor::DELIMITER, $customer['password_hash']); $newHash = $customer['password_hash']; From 2d69a657140d13e790b9280ad6a5730a60c8fdb3 Mon Sep 17 00:00:00 2001 From: Ivan Gavryshko Date: Tue, 1 Dec 2015 14:39:24 -0600 Subject: [PATCH 003/128] MAGETWO-45743: Investigate L2 test failure in testGetPackagesForUpdate test file - fixed integration test (avoid to call real composer repo) --- .../Setup/Model/UpdatePackagesCacheTest.php | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php b/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php index 939054260269b..2d82fb6e7eb42 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php @@ -6,11 +6,10 @@ namespace Magento\Setup\Model; -use Magento\Framework\App\Filesystem\DirectoryList; use Magento\TestFramework\Helper\Bootstrap; use Magento\Framework\Composer\ComposerJsonFinder; use Magento\Framework\Composer\MagentoComposerApplicationFactory; -use Magento\Framework\Stdlib\DateTime\DateTime; +use Magento\Setup\Model\UpdatePackagesCache; /** * Tests Magento\Framework\ComposerInformation @@ -88,19 +87,19 @@ public function testGetPackagesForUpdate() ->method('get') ->willReturn($this->objectManager); - /** @var \Magento\Setup\Model\UpdatePackagesCache $updatePackagesCache */ - $updatePackagesCache = $this->objectManager->create( - 'Magento\Setup\Model\UpdatePackagesCache', - [ - 'applicationFactory' => new MagentoComposerApplicationFactory( - $this->composerJsonFinder, - $this->directoryList - ), - 'filesystem' => $this->filesystem, - 'composerInformation' => $this->composerInformation, - 'objectManagerProvider' => $objectManagerProvider, + /** @var UpdatePackagesCache $updatePackagesCache|\PHPUnit_Framework_MockObject_MockObject */ + $updatePackagesCache = $this->getMock('Magento\Setup\Model\UpdatePackagesCache', [], [], '', false); + + $packages = [ + 'packages' => [ + $packageName => [ + 'latestVersion' => '100.0.0' + ] ] - ); + ]; + + $updatePackagesCache->expects($this->once())->method('syncPackagesForUpdate')->willReturn(true); + $updatePackagesCache->expects($this->once())->method('getPackagesForUpdate')->willReturn($packages); $requiredPackages = $this->composerInformation->getInstalledMagentoPackages(); $this->assertArrayHasKey($packageName, $requiredPackages); From bc582f91631eef9ad8e5c2e70f0860c6885e1774 Mon Sep 17 00:00:00 2001 From: Ivan Gavryshko Date: Fri, 4 Dec 2015 11:09:06 -0600 Subject: [PATCH 004/128] MAGETWO-45743: Investigate L2 test failure in testGetPackagesForUpdate test file - change according to CR --- .../testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php b/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php index 2d82fb6e7eb42..690f7e6a4dbd2 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php @@ -93,7 +93,7 @@ public function testGetPackagesForUpdate() $packages = [ 'packages' => [ $packageName => [ - 'latestVersion' => '100.0.0' + 'latestVersion' => '1000.100.200' ] ] ]; From 2e90ff8ac21a6e3f50073cc58900030bd3f4df9a Mon Sep 17 00:00:00 2001 From: Dale Sikkema Date: Fri, 8 Jan 2016 12:30:23 -0600 Subject: [PATCH 005/128] MAGETWO-47009: Github #2674 Plugins/Interceptors Don't Work with Early Stage Single Instance Objects in Developer Mode - 2.0.1 release --- .../ObjectManager/Environment/Developer.php | 5 ++ .../Environment/DeveloperTest.php | 58 +++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/lib/internal/Magento/Framework/App/ObjectManager/Environment/Developer.php b/lib/internal/Magento/Framework/App/ObjectManager/Environment/Developer.php index 09d25c7de4d1b..df2a6ceee56e0 100644 --- a/lib/internal/Magento/Framework/App/ObjectManager/Environment/Developer.php +++ b/lib/internal/Magento/Framework/App/ObjectManager/Environment/Developer.php @@ -62,6 +62,7 @@ public function getObjectManagerConfigLoader() */ public function configureObjectManager(ConfigInterface $diConfig, &$sharedInstances) { + $originalSharedInstances = $sharedInstances; $objectManager = ObjectManager::getInstance(); $sharedInstances['Magento\Framework\ObjectManager\ConfigLoaderInterface'] = $objectManager ->get('Magento\Framework\App\ObjectManager\ConfigLoader'); @@ -80,5 +81,9 @@ public function configureObjectManager(ConfigInterface $diConfig, &$sharedInstan $diConfig->setInterceptionConfig( $objectManager->get('Magento\Framework\Interception\Config\Config') ); + /** Reset the shared instances once interception config is set so classes can be intercepted if necessary */ + $sharedInstances = $originalSharedInstances; + $sharedInstances['Magento\Framework\ObjectManager\ConfigLoaderInterface'] = $objectManager + ->get('Magento\Framework\App\ObjectManager\ConfigLoader'); } } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/ObjectManager/Environment/DeveloperTest.php b/lib/internal/Magento/Framework/App/Test/Unit/ObjectManager/Environment/DeveloperTest.php index c86318181a2c0..6e7ddc94f3d26 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/ObjectManager/Environment/DeveloperTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/ObjectManager/Environment/DeveloperTest.php @@ -5,6 +5,7 @@ */ namespace Magento\Framework\App\Test\Unit\ObjectManager\Environment; +use Magento\Framework\App\ObjectManager; use Magento\Framework\App\ObjectManager\Environment\Developer; class DeveloperTest extends \PHPUnit_Framework_TestCase @@ -29,4 +30,61 @@ public function testGetObjectManagerConfigLoader() { $this->assertNull($this->_developer->getObjectManagerConfigLoader()); } + + public function testConfigureObjectManager() + { + try { + $origObjectManager = ObjectManager::getInstance(); + } catch (\Exception $e) { + $origObjectManager = null; + } + + + $objectManagerMock = $this->getMockBuilder('Magento\Framework\App\ObjectManager') + ->disableOriginalConstructor() + ->getMock(); + ObjectManager::setInstance($objectManagerMock); + $diConfigMock = $this->getMockBuilder('\Magento\Framework\Interception\ObjectManager\ConfigInterface') + ->disableOriginalConstructor() + ->getMock(); + + $configLoaderMock = $this->getMockBuilder('Magento\Framework\App\ObjectManager\ConfigLoader') + ->disableOriginalConstructor() + ->getMock(); + $configLoaderMock->expects($this->any())->method('load')->willReturn([]); + $omReturnMap = [ + ['Magento\Framework\App\ObjectManager\ConfigLoader', $configLoaderMock], + [ + 'Magento\Framework\Config\ScopeInterface', + $this->getMockBuilder('Magento\Framework\Config\ScopeInterface') + ->disableOriginalConstructor() + ->getMock() + ], + [ + 'Magento\Framework\App\ObjectManager\ConfigCache', + $this->getMockBuilder('Magento\Framework\App\ObjectManager\ConfigCache') + ->disableOriginalConstructor() + ->getMock() + ], + [ + 'Magento\Framework\Interception\Config\Config', + $this->getMockBuilder('Magento\Framework\Interception\Config\Config') + ->disableOriginalConstructor() + ->getMock() + ] + ]; + $objectManagerMock->expects($this->any())->method('get')->willReturnMap($omReturnMap); + + $sharedInstances = ['class_name' => 'shared_object']; + $this->_developer->configureObjectManager($diConfigMock, $sharedInstances); + + $expectedSharedInstances = [ + 'class_name' => 'shared_object', + 'Magento\Framework\ObjectManager\ConfigLoaderInterface' => $configLoaderMock + ]; + $this->assertSame($expectedSharedInstances, $sharedInstances); + if (isset($origObjectManager)) { + ObjectManager::setInstance($origObjectManager); + } + } } From 23746e5fa1f7deb3a4a8643beb317603cf3b0bd0 Mon Sep 17 00:00:00 2001 From: Dale Sikkema Date: Fri, 8 Jan 2016 12:34:07 -0600 Subject: [PATCH 006/128] MAGETWO-47375: Unnecessary MessageBox plugin duplicating Message logic - 2.0.1 release --- .../Model/App/FrontController/MessageBox.php | 100 ------------ .../App/FrontController/MessageBoxTest.php | 148 ------------------ .../Magento/PageCache/etc/frontend/di.xml | 1 - .../view/frontend/web/js/page-cache.js | 26 +-- .../PageCache/frontend/js/page-cache.test.js | 58 ------- 5 files changed, 1 insertion(+), 332 deletions(-) delete mode 100644 app/code/Magento/PageCache/Model/App/FrontController/MessageBox.php delete mode 100644 app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/MessageBoxTest.php diff --git a/app/code/Magento/PageCache/Model/App/FrontController/MessageBox.php b/app/code/Magento/PageCache/Model/App/FrontController/MessageBox.php deleted file mode 100644 index 38d2e63c6e2fb..0000000000000 --- a/app/code/Magento/PageCache/Model/App/FrontController/MessageBox.php +++ /dev/null @@ -1,100 +0,0 @@ -cookieManager = $cookieManager; - $this->cookieMetadataFactory = $cookieMetadataFactory; - $this->request = $request; - $this->config = $config; - $this->messageManager = $messageManager; - } - - /** - * Set Cookie for msg box when it displays first - * - * @param FrontController $subject - * @param \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface $result - * - * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function afterDispatch(FrontController $subject, $result) - { - if ($this->request->isPost() && $this->messageManager->hasMessages()) { - $publicCookieMetadata = $this->cookieMetadataFactory->createPublicCookieMetadata() - ->setDuration(self::COOKIE_PERIOD) - ->setPath('/') - ->setHttpOnly(false); - $this->cookieManager->setPublicCookie(self::COOKIE_NAME, 1, $publicCookieMetadata); - } - return $result; - } -} diff --git a/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/MessageBoxTest.php b/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/MessageBoxTest.php deleted file mode 100644 index cec6b6f530382..0000000000000 --- a/app/code/Magento/PageCache/Test/Unit/Model/App/FrontController/MessageBoxTest.php +++ /dev/null @@ -1,148 +0,0 @@ -cookieManagerMock = $this->getMock('Magento\Framework\Stdlib\CookieManagerInterface'); - $this->cookieMetadataFactoryMock = $this->getMockBuilder( - 'Magento\Framework\Stdlib\Cookie\CookieMetadataFactory' - )->disableOriginalConstructor() - ->getMock(); - $this->publicCookieMetadataMock = $this->getMockBuilder( - 'Magento\Framework\Stdlib\Cookie\PublicCookieMetadata' - )->disableOriginalConstructor() - ->getMock(); - $this->requestMock = $this->getMockBuilder('Magento\Framework\App\Request\Http') - ->disableOriginalConstructor() - ->getMock(); - $this->messageManagerMock = $this->getMockBuilder('Magento\Framework\Message\Manager') - ->disableOriginalConstructor() - ->getMock(); - - $this->msgBox = (new ObjectManager($this))->getObject( - 'Magento\PageCache\Model\App\FrontController\MessageBox', - [ - 'cookieManager' => $this->cookieManagerMock, - 'cookieMetadataFactory' => $this->cookieMetadataFactoryMock, - 'request' => $this->requestMock, - 'messageManager' => $this->messageManagerMock, - ] - ); - - $this->objectMock = $this->getMock('Magento\Framework\App\FrontController', [], [], '', false); - $this->responseMock = $this->getMock('Magento\Framework\App\ResponseInterface', [], [], '', false); - } - - /** - * @param bool $isPost - * @param int $numOfCalls - * @dataProvider afterDispatchTestDataProvider - */ - public function testAfterDispatch($isPost, $numOfCalls) - { - $this->messageManagerMock->expects($this->exactly($numOfCalls)) - ->method('hasMessages') - ->will($this->returnValue(true)); - $this->requestMock->expects($this->once()) - ->method('isPost') - ->will($this->returnValue($isPost)); - $this->cookieMetadataFactoryMock->expects($this->exactly($numOfCalls)) - ->method('createPublicCookieMetadata') - ->will($this->returnValue($this->publicCookieMetadataMock)); - $this->publicCookieMetadataMock->expects(($this->exactly($numOfCalls))) - ->method('setDuration') - ->with(MessageBox::COOKIE_PERIOD) - ->will($this->returnValue($this->publicCookieMetadataMock)); - $this->publicCookieMetadataMock->expects(($this->exactly($numOfCalls))) - ->method('setPath') - ->with('/') - ->will($this->returnValue($this->publicCookieMetadataMock)); - $this->publicCookieMetadataMock->expects(($this->exactly($numOfCalls))) - ->method('setHttpOnly') - ->with(false) - ->will($this->returnValue($this->publicCookieMetadataMock)); - $this->cookieManagerMock->expects($this->exactly($numOfCalls)) - ->method('setPublicCookie') - ->with( - MessageBox::COOKIE_NAME, - 1, - $this->publicCookieMetadataMock - ); - $this->assertSame($this->responseMock, $this->msgBox->afterDispatch($this->objectMock, $this->responseMock)); - } - - /** - * Data provider - * - * @return array - */ - public function afterDispatchTestDataProvider() - { - return [ - [true, 1], - [false, 0], - ]; - } -} diff --git a/app/code/Magento/PageCache/etc/frontend/di.xml b/app/code/Magento/PageCache/etc/frontend/di.xml index 658dce3f72ed6..1d57d767e9904 100644 --- a/app/code/Magento/PageCache/etc/frontend/di.xml +++ b/app/code/Magento/PageCache/etc/frontend/di.xml @@ -9,7 +9,6 @@ - diff --git a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js index 162a8412aeda8..26f394b98dd07 100644 --- a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js +++ b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js @@ -51,28 +51,6 @@ define([ return elements; }; - /** - * MsgBox Widget checks if message box is displayed and sets cookie - */ - $.widget('mage.msgBox', { - options: { - msgBoxCookieName: 'message_box_display', - msgBoxSelector: '.main div.messages' - }, - - /** - * Creates widget 'mage.msgBox' - * @private - */ - _create: function () { - if ($.mage.cookies.get(this.options.msgBoxCookieName)) { - $.mage.cookies.clear(this.options.msgBoxCookieName); - } else { - $(this.options.msgBoxSelector).hide(); - } - } - }); - /** * FormKey Widget - this widget is generating from key, saves it to cookie and */ @@ -272,14 +250,12 @@ define([ domReady(function () { $('body') - .msgBox() .formKey(); }); return { 'pageCache': $.mage.pageCache, - 'formKey': $.mage.formKey, - 'msgBox': $.mage.msgBox + 'formKey': $.mage.formKey }; /** diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/PageCache/frontend/js/page-cache.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/PageCache/frontend/js/page-cache.test.js index 1f7a247a2faf1..8df486f29c6fb 100644 --- a/dev/tests/js/jasmine/tests/app/code/Magento/PageCache/frontend/js/page-cache.test.js +++ b/dev/tests/js/jasmine/tests/app/code/Magento/PageCache/frontend/js/page-cache.test.js @@ -64,64 +64,6 @@ define([ }); }); - describe('Testing msgBox Widget', function () { - var wdContainer, - msgCookieName, - msgContainer; - - beforeEach(function () { - wdContainer = $('
'); - msgContainer = $('
'); - msgCookieName = 'FAKE_COOKIE'; - }); - - afterEach(function () { - $(wdContainer).remove(); - $(msgContainer).remove(); - }); - - it('widget extends jQuery object', function () { - expect($.fn.msgBox).toBeDefined(); - }); - - it('widget gets options', function () { - wdContainer.msgBox({ - 'msgBoxCookieName': msgCookieName - }); - expect(wdContainer.msgBox('option', 'msgBoxCookieName')).toBe('FAKE_COOKIE'); - }); - - it('widget disables cookie if it exist', function () { - spyOn($.mage.cookies, 'get').and.returnValue('FAKE_MAGE_COOKIE'); - spyOn($.mage.cookies, 'clear'); - - wdContainer.msgBox({ - 'msgBoxSelector': msgContainer - }); - - expect($.mage.cookies.get).toHaveBeenCalled(); - expect($.mage.cookies.clear).toHaveBeenCalled(); - }); - - it('widget disables messageBox if cookie not exist', function () { - spyOn($.mage.cookies, 'get'); - - wdContainer.msgBox({ - 'msgBoxSelector': msgContainer - }); - - expect($.mage.cookies.get).toHaveBeenCalled(); - expect(msgContainer.is(':hidden')).toBeTruthy(); - }); - - it('widget exist on load on body', function (done) { - $(function () { - expect($('body').data('mageMsgBox')).toBeDefined(); - done(); - }); - }); - }); - describe('Testing FormKey Widget', function () { var wdContainer, msgCookieName, From b6c44fc9cd5ef1381d31f42e53c36f4fa4fdd652 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko Date: Mon, 11 Jan 2016 16:54:46 -0600 Subject: [PATCH 007/128] MAGETWO-47377: Unnecessary StoreCookie plugin is executed on each request --- app/code/Magento/Store/Model/Plugin/StoreCookie.php | 7 ++----- app/code/Magento/Store/Model/StoreResolver.php | 5 +++++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/Store/Model/Plugin/StoreCookie.php b/app/code/Magento/Store/Model/Plugin/StoreCookie.php index cb4ec64e03a2f..498faf02000ca 100644 --- a/app/code/Magento/Store/Model/Plugin/StoreCookie.php +++ b/app/code/Magento/Store/Model/Plugin/StoreCookie.php @@ -52,14 +52,12 @@ public function __construct( * Delete cookie "store" if the store (a value in the cookie) does not exist or is inactive * * @param \Magento\Framework\App\FrontController $subject - * @param callable $proceed * @param \Magento\Framework\App\RequestInterface $request - * @return mixed + * @return void * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - public function aroundDispatch( + public function beforeDispatch( \Magento\Framework\App\FrontController $subject, - \Closure $proceed, \Magento\Framework\App\RequestInterface $request ) { $defaultStore = $this->storeManager->getDefaultStoreView(); @@ -75,6 +73,5 @@ public function aroundDispatch( $this->storeCookieManager->deleteStoreCookie($defaultStore); } } - return $proceed($request); } } diff --git a/app/code/Magento/Store/Model/StoreResolver.php b/app/code/Magento/Store/Model/StoreResolver.php index f609e271ffd6c..b87a5aabf6f71 100644 --- a/app/code/Magento/Store/Model/StoreResolver.php +++ b/app/code/Magento/Store/Model/StoreResolver.php @@ -45,6 +45,11 @@ class StoreResolver implements \Magento\Store\Api\StoreResolverInterface */ protected $scopeCode; + /* + * @var \Magento\Framework\App\RequestInterface + */ + protected $request; + /** * @param \Magento\Store\Api\StoreRepositoryInterface $storeRepository * @param StoreCookieManagerInterface $storeCookieManager From ae5d328e2ebd44cfb3a83b19fbe8ed5206716671 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko Date: Mon, 11 Jan 2016 17:08:20 -0600 Subject: [PATCH 008/128] MAGETWO-47377: Unnecessary StoreCookie plugin is executed on each request --- app/code/Magento/Store/Model/Plugin/StoreCookie.php | 7 +++---- app/code/Magento/Store/etc/di.xml | 5 +++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Store/Model/Plugin/StoreCookie.php b/app/code/Magento/Store/Model/Plugin/StoreCookie.php index 498faf02000ca..b42e645799867 100644 --- a/app/code/Magento/Store/Model/Plugin/StoreCookie.php +++ b/app/code/Magento/Store/Model/Plugin/StoreCookie.php @@ -60,17 +60,16 @@ public function beforeDispatch( \Magento\Framework\App\FrontController $subject, \Magento\Framework\App\RequestInterface $request ) { - $defaultStore = $this->storeManager->getDefaultStoreView(); $storeCodeFromCookie = $this->storeCookieManager->getStoreCodeFromCookie(); if ($storeCodeFromCookie) { try { $this->storeRepository->getActiveStoreByCode($storeCodeFromCookie); } catch (StoreIsInactiveException $e) { - $this->storeCookieManager->deleteStoreCookie($defaultStore); + $this->storeCookieManager->deleteStoreCookie($this->storeManager->getDefaultStoreView()); } catch (NoSuchEntityException $e) { - $this->storeCookieManager->deleteStoreCookie($defaultStore); + $this->storeCookieManager->deleteStoreCookie($this->storeManager->getDefaultStoreView()); } catch (InvalidArgumentException $e) { - $this->storeCookieManager->deleteStoreCookie($defaultStore); + $this->storeCookieManager->deleteStoreCookie($this->storeManager->getDefaultStoreView()); } } } diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml index e0371cb29ff30..66db600c32d29 100644 --- a/app/code/Magento/Store/etc/di.xml +++ b/app/code/Magento/Store/etc/di.xml @@ -281,6 +281,11 @@ + + + Magento\Store\Model\StoreManagerInterface\Proxy + + Magento\Framework\App\Cache\Type\Config From 1a13f4d8d6b70237a425fab50f98fb6fe2a10ec7 Mon Sep 17 00:00:00 2001 From: Joan He Date: Tue, 12 Jan 2016 13:10:58 -0600 Subject: [PATCH 009/128] MAGETWO-47639: [Github] Not all files are pre-compiled #2888 - Fixed single tenant compiler --- app/code/Magento/Cron/etc/di.xml | 8 ++ .../Framework/Config/Reader/Filesystem.php | 10 ++ .../Console/Command/DiCompileCommand.php | 13 +-- .../Di/App/Task/Operation/ProxyGenerator.php | 31 ++----- .../Task/Operation/RepositoryGenerator.php | 31 ++----- .../ServiceDataAttributesGenerator.php | 33 +++---- .../Di/Code/Scanner/ConfigurationScanner.php | 48 ++++++++++ .../Module/Di/App/Task/ProxyGeneratorTest.php | 81 +++++----------- .../Di/App/Task/RepositoryGeneratorTest.php | 93 +++++++------------ .../ServiceDataAttributesGeneratorTest.php | 90 ++++++------------ .../Code/Scanner/ConfigurationScannerTest.php | 64 +++++++++++++ 11 files changed, 251 insertions(+), 251 deletions(-) create mode 100644 setup/src/Magento/Setup/Module/Di/Code/Scanner/ConfigurationScanner.php create mode 100644 setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Scanner/ConfigurationScannerTest.php diff --git a/app/code/Magento/Cron/etc/di.xml b/app/code/Magento/Cron/etc/di.xml index ae600be3c5c8a..db9161d26099f 100644 --- a/app/code/Magento/Cron/etc/di.xml +++ b/app/code/Magento/Cron/etc/di.xml @@ -36,4 +36,12 @@ + + + + + + + + diff --git a/lib/internal/Magento/Framework/Config/Reader/Filesystem.php b/lib/internal/Magento/Framework/Config/Reader/Filesystem.php index bbe3544318f84..e1b271f9bd0f1 100644 --- a/lib/internal/Magento/Framework/Config/Reader/Filesystem.php +++ b/lib/internal/Magento/Framework/Config/Reader/Filesystem.php @@ -67,6 +67,16 @@ class Filesystem implements \Magento\Framework\Config\ReaderInterface */ protected $validationState; + /** + * @var string + */ + protected $_defaultScope; + + /** + * @var string + */ + protected $_schemaFile; + /** * Constructor * diff --git a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php index 8843fb66c2111..963ae19576ac1 100644 --- a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php +++ b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php @@ -299,20 +299,11 @@ private function getOperationsConfiguration( } $operations = [ - OperationFactory::PROXY_GENERATOR => [ - 'paths' => $compiledPathsList['application'], - 'filePatterns' => ['di' => '/\/etc\/([a-zA-Z_]*\/di|di)\.xml$/'], - 'excludePatterns' => $excludePatterns, - ], + OperationFactory::PROXY_GENERATOR => [], OperationFactory::REPOSITORY_GENERATOR => [ 'paths' => $compiledPathsList['application'], - 'filePatterns' => ['di' => '/\/etc\/([a-zA-Z_]*\/di|di)\.xml$/'], - 'excludePatterns' => $excludePatterns, - ], - OperationFactory::DATA_ATTRIBUTES_GENERATOR => [ - 'paths' => $compiledPathsList['application'], - 'filePatterns' => $dataAttributesIncludePattern ], + OperationFactory::DATA_ATTRIBUTES_GENERATOR => [], OperationFactory::APPLICATION_CODE_GENERATOR => [ 'paths' => [ $compiledPathsList['application'], diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ProxyGenerator.php b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ProxyGenerator.php index ebfec0635b8bb..f5c79fec02f2e 100644 --- a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ProxyGenerator.php +++ b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ProxyGenerator.php @@ -11,11 +11,6 @@ class ProxyGenerator implements OperationInterface { - /** - * @var Scanner\DirectoryScanner - */ - private $directoryScanner; - /** * @var Scanner\XmlScanner */ @@ -27,18 +22,23 @@ class ProxyGenerator implements OperationInterface private $data; /** - * @param Scanner\DirectoryScanner $directoryScanner + * @var Scanner\ConfigurationScanner + */ + private $configurationScanner; + + /** * @param Scanner\XmlScanner $proxyScanner + * @param Scanner\ConfigurationScanner $configurationScanner * @param array $data */ public function __construct( - Scanner\DirectoryScanner $directoryScanner, Scanner\XmlScanner $proxyScanner, + \Magento\Setup\Module\Di\Code\Scanner\ConfigurationScanner $configurationScanner, $data = [] ) { - $this->directoryScanner = $directoryScanner; $this->proxyScanner = $proxyScanner; $this->data = $data; + $this->configurationScanner = $configurationScanner; } /** @@ -48,19 +48,8 @@ public function __construct( */ public function doOperation() { - if (array_diff(array_keys($this->data), ['filePatterns', 'paths', 'excludePatterns']) - !== array_diff(['filePatterns', 'paths', 'excludePatterns'], array_keys($this->data))) { - return; - } - - $files = []; - foreach ($this->data['paths'] as $path) { - $files = array_merge_recursive( - $files, - $this->directoryScanner->scan($path, $this->data['filePatterns'], $this->data['excludePatterns']) - ); - } - $proxies = $this->proxyScanner->collectEntities($files['di']); + $files = $this->configurationScanner->scan('di.xml'); + $proxies = $this->proxyScanner->collectEntities($files); foreach ($proxies as $entityName) { class_exists($entityName); } diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/RepositoryGenerator.php b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/RepositoryGenerator.php index 60d1159661528..2f51b34a11187 100644 --- a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/RepositoryGenerator.php +++ b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/RepositoryGenerator.php @@ -12,11 +12,6 @@ class RepositoryGenerator implements OperationInterface { - /** - * @var Scanner\DirectoryScanner - */ - private $directoryScanner; - /** * @var Scanner\RepositoryScanner */ @@ -33,21 +28,26 @@ class RepositoryGenerator implements OperationInterface private $classesScanner; /** - * @param Scanner\DirectoryScanner $directoryScanner + * @var Scanner\ConfigurationScanner + */ + private $configurationScanner; + + /** * @param ClassesScanner $classesScanner * @param Scanner\RepositoryScanner $repositoryScanner + * @param Scanner\ConfigurationScanner $configurationScanner * @param array $data */ public function __construct( - Scanner\DirectoryScanner $directoryScanner, ClassesScanner $classesScanner, Scanner\RepositoryScanner $repositoryScanner, + \Magento\Setup\Module\Di\Code\Scanner\ConfigurationScanner $configurationScanner, $data = [] ) { - $this->directoryScanner = $directoryScanner; $this->repositoryScanner = $repositoryScanner; $this->data = $data; $this->classesScanner = $classesScanner; + $this->configurationScanner = $configurationScanner; } /** @@ -57,23 +57,12 @@ public function __construct( */ public function doOperation() { - if (array_diff(array_keys($this->data), ['filePatterns', 'paths', 'excludePatterns']) - !== array_diff(['filePatterns', 'paths', 'excludePatterns'], array_keys($this->data))) { - return; - } - foreach ($this->data['paths'] as $path) { $this->classesScanner->getList($path); } $this->repositoryScanner->setUseAutoload(false); - $files = []; - foreach ($this->data['paths'] as $path) { - $files = array_merge_recursive( - $files, - $this->directoryScanner->scan($path, $this->data['filePatterns'], $this->data['excludePatterns']) - ); - } - $repositories = $this->repositoryScanner->collectEntities($files['di']); + $files = $this->configurationScanner->scan('di.xml'); + $repositories = $this->repositoryScanner->collectEntities($files); foreach ($repositories as $entityName) { class_exists($entityName); } diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ServiceDataAttributesGenerator.php b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ServiceDataAttributesGenerator.php index 0a28df86d27fc..2f80abd296d06 100644 --- a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ServiceDataAttributesGenerator.php +++ b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ServiceDataAttributesGenerator.php @@ -16,11 +16,6 @@ */ class ServiceDataAttributesGenerator implements OperationInterface { - /** - * @var Scanner\DirectoryScanner - */ - private $directoryScanner; - /** * @var Scanner\ServiceDataAttributesScanner */ @@ -32,18 +27,23 @@ class ServiceDataAttributesGenerator implements OperationInterface private $data; /** - * @param Scanner\DirectoryScanner $directoryScanner - * @param Scanner\ServiceDataAttributesScanner $repositoryScanner + * @var Scanner\ConfigurationScanner + */ + private $configurationScanner; + + /** + * @param Scanner\ServiceDataAttributesScanner $serviceDataAttributesScanner + * @param Scanner\ConfigurationScanner $configurationScanner * @param array $data */ public function __construct( - Scanner\DirectoryScanner $directoryScanner, - Scanner\ServiceDataAttributesScanner $repositoryScanner, + Scanner\ServiceDataAttributesScanner $serviceDataAttributesScanner, + \Magento\Setup\Module\Di\Code\Scanner\ConfigurationScanner $configurationScanner, $data = [] ) { - $this->directoryScanner = $directoryScanner; - $this->serviceDataAttributesScanner = $repositoryScanner; + $this->serviceDataAttributesScanner = $serviceDataAttributesScanner; $this->data = $data; + $this->configurationScanner = $configurationScanner; } /** @@ -53,15 +53,8 @@ public function __construct( */ public function doOperation() { - if (array_diff(array_keys($this->data), ['filePatterns', 'paths']) - !== array_diff(['filePatterns', 'paths'], array_keys($this->data))) { - return; - } - $files = []; - foreach ($this->data['paths'] as $path) { - $files = array_merge_recursive($files, $this->directoryScanner->scan($path, $this->data['filePatterns'])); - } - $repositories = $this->serviceDataAttributesScanner->collectEntities($files['extension_attributes']); + $files = $this->configurationScanner->scan('extension_attributes.xml'); + $repositories = $this->serviceDataAttributesScanner->collectEntities($files); foreach ($repositories as $entityName) { class_exists($entityName); } diff --git a/setup/src/Magento/Setup/Module/Di/Code/Scanner/ConfigurationScanner.php b/setup/src/Magento/Setup/Module/Di/Code/Scanner/ConfigurationScanner.php new file mode 100644 index 0000000000000..90aed20512528 --- /dev/null +++ b/setup/src/Magento/Setup/Module/Di/Code/Scanner/ConfigurationScanner.php @@ -0,0 +1,48 @@ +fileResolver = $fileResolver; + $this->areaList = $areaList; + } + + /** + * Scan configuration files + * + * @param string $fileName + * + * @return array array of paths to the configuration files + */ + public function scan($fileName) + { + $files = []; + $areaCodes = array_merge( + ['primary', Area::AREA_GLOBAL], + $this->areaList->getCodes() + ); + foreach ($areaCodes as $area) { + $files = array_merge_recursive( + $files, + $this->fileResolver->get($fileName, $area)->toArray() + ); + } + return array_keys($files); + } +} diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ProxyGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ProxyGeneratorTest.php index c721973f615ef..ac0ecfc74dbf7 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ProxyGeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ProxyGeneratorTest.php @@ -13,83 +13,52 @@ class ProxyGeneratorTest extends \PHPUnit_Framework_TestCase { /** - * @var Scanner\DirectoryScanner | \PHPUnit_Framework_MockObject_MockObject + * @var Scanner\XmlScanner | \PHPUnit_Framework_MockObject_MockObject */ - private $directoryScannerMock; + private $proxyScannerMock; /** - * @var Scanner\XmlScanner | \PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Setup\Module\Di\Code\Scanner\ConfigurationScanner | \PHPUnit_Framework_MockObject_MockObject */ - private $proxyScannerMock; + private $configurationScannerMock; + + /** + * @var \Magento\Setup\Module\Di\App\Task\Operation\ProxyGenerator + */ + private $model; protected function setUp() { - $this->directoryScannerMock = $this->getMockBuilder('Magento\Setup\Module\Di\Code\Scanner\DirectoryScanner') + $this->proxyScannerMock = $this->getMockBuilder('Magento\Setup\Module\Di\Code\Scanner\XmlScanner') ->disableOriginalConstructor() ->getMock(); - $this->proxyScannerMock = $this->getMockBuilder('Magento\Setup\Module\Di\Code\Scanner\XmlScanner') + + $this->configurationScannerMock = $this->getMockBuilder('Magento\Setup\Module\Di\Code\Scanner\ConfigurationScanner') ->disableOriginalConstructor() ->getMock(); - } - /** - * @param array $data - * - * @dataProvider doOperationWrongDataDataProvider - */ - public function testDoOperationWrongData($data) - { - $model = new ProxyGenerator( - $this->directoryScannerMock, - $this->proxyScannerMock, - $data + $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\Setup\Module\Di\App\Task\Operation\ProxyGenerator', + [ + 'proxyScanner' => $this->proxyScannerMock, + 'configurationScanner' => $this->configurationScannerMock, + ] ); - - $this->directoryScannerMock->expects($this->never()) - ->method('scan'); - $this->proxyScannerMock->expects($this->never()) - ->method('collectEntities'); - - $this->assertEmpty($model->doOperation()); - } - - /** - * @return array - */ - public function doOperationWrongDataDataProvider() - { - return [ - [[]], - [['filePatterns' => ['php' => '*.php']]], - [['path' => 'path']], - ]; } public function testDoOperation() { - $data = [ - 'paths' => ['path/to/app'], - 'filePatterns' => ['di' => 'di.xml'], - 'excludePatterns' => ['/\/Test\//'], - ]; - $files = ['di' => []]; - $model = new ProxyGenerator( - $this->directoryScannerMock, - $this->proxyScannerMock, - $data - ); - - $this->directoryScannerMock->expects($this->once()) + $files = ['file1', 'file2']; + $this->configurationScannerMock->expects($this->once()) ->method('scan') - ->with( - $data['paths'][0], - $data['filePatterns'] - )->willReturn($files); + ->with('di.xml') + ->willReturn($files); $this->proxyScannerMock->expects($this->once()) ->method('collectEntities') - ->with($files['di']) + ->with($files) ->willReturn([]); - $this->assertEmpty($model->doOperation()); + $this->model->doOperation(); } } diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/RepositoryGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/RepositoryGeneratorTest.php index 626ccfbe71346..cf8ab935db943 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/RepositoryGeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/RepositoryGeneratorTest.php @@ -12,11 +12,6 @@ class RepositoryGeneratorTest extends \PHPUnit_Framework_TestCase { - /** - * @var Scanner\DirectoryScanner | \PHPUnit_Framework_MockObject_MockObject - */ - private $directoryScannerMock; - /** * @var Scanner\RepositoryScanner | \PHPUnit_Framework_MockObject_MockObject */ @@ -27,81 +22,59 @@ class RepositoryGeneratorTest extends \PHPUnit_Framework_TestCase */ private $classesScannerMock; + + /** + * @var \Magento\Setup\Module\Di\Code\Scanner\ConfigurationScanner | \PHPUnit_Framework_MockObject_MockObject + */ + private $configurationScannerMock; + + /** + * @var \Magento\Setup\Module\Di\App\Task\Operation\RepositoryGenerator + */ + private $model; + protected function setUp() { - $this->directoryScannerMock = $this->getMockBuilder('Magento\Setup\Module\Di\Code\Scanner\DirectoryScanner') - ->setMethods([]) - ->disableOriginalConstructor() - ->getMock(); $this->repositoryScannerMock = $this->getMockBuilder('Magento\Setup\Module\Di\Code\Scanner\RepositoryScanner') - ->setMethods([]) ->disableOriginalConstructor() ->getMock(); $this->classesScannerMock = $this->getMockBuilder('Magento\Setup\Module\Di\Code\Reader\ClassesScanner') - ->setMethods([]) ->disableOriginalConstructor() ->getMock(); - } - - /** - * @dataProvider wrongDataDataProvider - */ - public function testDoOperationEmptyData($wrongData) - { - $model = new RepositoryGenerator( - $this->directoryScannerMock, - $this->classesScannerMock, - $this->repositoryScannerMock, - $wrongData + $this->configurationScannerMock = $this->getMockBuilder( + 'Magento\Setup\Module\Di\Code\Scanner\ConfigurationScanner' + )->disableOriginalConstructor() + ->getMock(); + $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\Setup\Module\Di\App\Task\Operation\RepositoryGenerator', + [ + 'repositoryScanner' => $this->repositoryScannerMock, + 'classesScanner' => $this->classesScannerMock, + 'configurationScanner' => $this->configurationScannerMock, + 'data' => ['paths' => ['path/to/app']] + ] ); - - $this->assertNull($model->doOperation()); - } - - /** - * @return array - */ - public function wrongDataDataProvider() - { - return [ - [[]], - [['filePatterns' => ['php' => '*.php']]], - [['path' => 'path']] - ]; } - public function testDoOperationEmptyRepositories() + public function testDoOperation() { - $data = [ - 'paths' => ['path/to/app'], - 'filePatterns' => ['di' => 'di.xml'], - 'excludePatterns' => ['/\/Test\//'], - ]; - $files = ['di' => []]; - $model = new RepositoryGenerator( - $this->directoryScannerMock, - $this->classesScannerMock, - $this->repositoryScannerMock, - $data - ); - $this->classesScannerMock->expects($this->once()) ->method('getList') - ->with($data['paths'][0]); - $this->directoryScannerMock->expects($this->once()) - ->method('scan') - ->with( - $data['paths'][0], - $data['filePatterns'] - )->willReturn($files); + ->with('path/to/app'); $this->repositoryScannerMock->expects($this->once()) ->method('setUseAutoload') ->with(false); + $files = ['file1', 'file2']; + $this->configurationScannerMock->expects($this->once()) + ->method('scan') + ->with('di.xml') + ->willReturn($files); $this->repositoryScannerMock->expects($this->once()) ->method('collectEntities') - ->with($files['di']) + ->with($files) ->willReturn([]); - $this->assertEmpty($model->doOperation()); + $this->model->doOperation(); } } diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ServiceDataAttributesGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ServiceDataAttributesGeneratorTest.php index b1b01608ea21d..3d97c1083927f 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ServiceDataAttributesGeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ServiceDataAttributesGeneratorTest.php @@ -6,7 +6,6 @@ namespace Magento\Setup\Test\Unit\Module\Di\App\Task; -use Magento\Setup\Module\Di\App\Task\Operation\ServiceDataAttributesGenerator; use Magento\Setup\Module\Di\Code\Scanner; /** @@ -15,85 +14,52 @@ class ServiceDataAttributesGeneratorTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\Setup\Module\Di\Code\Scanner\DirectoryScanner|\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Setup\Module\Di\Code\Scanner\ConfigurationScanner | \PHPUnit_Framework_MockObject_MockObject */ - private $directoryScannerMock; - + private $configurationScannerMock; + /** * @var \Magento\Setup\Module\Di\Code\Scanner\ServiceDataAttributesScanner|\PHPUnit_Framework_MockObject_MockObject */ private $serviceDataAttributesScannerMock; - protected function setUp() - { - $this->directoryScannerMock = $this->getMock( - 'Magento\Setup\Module\Di\Code\Scanner\DirectoryScanner', - [], - [], - '', - false - ); - $this->serviceDataAttributesScannerMock = $this->getMock( - 'Magento\Setup\Module\Di\Code\Scanner\ServiceDataAttributesScanner', - [], - [], - '', - false - ); - } - /** - * @param $data array - * @dataProvider doOperationDataProvider + * @var \Magento\Setup\Module\Di\App\Task\Operation\ServiceDataAttributesGenerator */ - public function testDoOperationEmptyData($data) - { - $model = new ServiceDataAttributesGenerator( - $this->directoryScannerMock, - $this->serviceDataAttributesScannerMock, - $data - ); - $this->directoryScannerMock->expects($this->never())->method('scan'); + private $model; - $model->doOperation(); - } - - /** - * @return array - */ - public function doOperationDataProvider() + protected function setUp() { - return [ - [[]], - [['filePatterns' => ['php' => '*.php']]], - [['path' => 'path']] - ]; + $this->configurationScannerMock = $this->getMockBuilder( + 'Magento\Setup\Module\Di\Code\Scanner\ConfigurationScanner' + )->disableOriginalConstructor() + ->getMock(); + $this->serviceDataAttributesScannerMock = $this->getMockBuilder( + 'Magento\Setup\Module\Di\Code\Scanner\ServiceDataAttributesScanner' + )->disableOriginalConstructor() + ->getMock(); + $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\Setup\Module\Di\App\Task\Operation\ServiceDataAttributesGenerator', + [ + 'serviceDataAttributesScanner' => $this->serviceDataAttributesScannerMock, + 'configurationScanner' => $this->configurationScannerMock, + ] + ); } public function testDoOperation() { - $data = [ - 'paths' => ['path/to/app'], - 'filePatterns' => ['di' => 'di.xml'], - ]; - $files = ['extension_attributes' => []]; - $model = new ServiceDataAttributesGenerator( - $this->directoryScannerMock, - $this->serviceDataAttributesScannerMock, - $data - ); - - $this->directoryScannerMock->expects($this->once()) + $files = ['file1', 'file2']; + $this->configurationScannerMock->expects($this->once()) ->method('scan') - ->with( - $data['paths'][0], - $data['filePatterns'] - )->willReturn($files); + ->with('extension_attributes.xml') + ->willReturn($files); $this->serviceDataAttributesScannerMock->expects($this->once()) ->method('collectEntities') - ->with($files['extension_attributes']) + ->with($files) ->willReturn([]); - $model->doOperation(); + $this->model->doOperation(); } } diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Scanner/ConfigurationScannerTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Scanner/ConfigurationScannerTest.php new file mode 100644 index 0000000000000..32e0398890464 --- /dev/null +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Scanner/ConfigurationScannerTest.php @@ -0,0 +1,64 @@ +fileResolverMock = $this->getMockBuilder('Magento\Framework\App\Config\FileResolver') + ->disableOriginalConstructor() + ->getMock(); + + $this->areaListMock = $this->getMockBuilder('Magento\Framework\App\AreaList') + ->disableOriginalConstructor() + ->getMock(); + + $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->model = $objectManagerHelper->getObject( + 'Magento\Setup\Module\Di\Code\Scanner\ConfigurationScanner', + [ + 'fileResolver' => $this->fileResolverMock, + 'areaList' => $this->areaListMock, + ] + ); + } + + public function testScan() + { + $codes = ['code1', 'code2']; + $iteratorMock = $this->getMockBuilder('Magento\Framework\Config\FileIterator') + ->disableOriginalConstructor() + ->getMock(); + $this->areaListMock->expects($this->once()) + ->method('getCodes') + ->willReturn($codes); + $counts = count($codes) + 2; + $this->fileResolverMock->expects($this->exactly($counts)) + ->method('get') + ->willReturn($iteratorMock); + $files = ['file1' => 'onefile', 'file2' => 'anotherfile']; + $iteratorMock->expects($this->exactly($counts)) + ->method('toArray') + ->willReturn($files); + $this->assertEquals(array_keys($files), $this->model->scan('di.xml')); + } +} From d5331e2dc88de4ed04c3094a92ea05af26c83b58 Mon Sep 17 00:00:00 2001 From: Joan He Date: Tue, 12 Jan 2016 13:28:59 -0600 Subject: [PATCH 010/128] MAGETWO-47639: [Github] Not all files are pre-compiled #2888 - Fixed multi-tenant compiler --- .../Setup/Console/Command/DiCompileMultiTenantCommand.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/src/Magento/Setup/Console/Command/DiCompileMultiTenantCommand.php b/setup/src/Magento/Setup/Console/Command/DiCompileMultiTenantCommand.php index ea56ed13dbd4d..0958daf9ac20b 100644 --- a/setup/src/Magento/Setup/Console/Command/DiCompileMultiTenantCommand.php +++ b/setup/src/Magento/Setup/Console/Command/DiCompileMultiTenantCommand.php @@ -260,6 +260,9 @@ public function generateCode($generationDir, $fileExcludePatterns, $input) $directoryScanner->scan($codeScanDir, $filePatterns, $fileExcludePatterns) ); } + $this->files['di'][] = $this->directoryList->getPath( + \Magento\Framework\App\Filesystem\DirectoryList::CONFIG + ) . '/di.xml'; $this->files['additional'] = [$input->getOption(self::INPUT_KEY_EXTRA_CLASSES_FILE)]; $repositoryScanner = new Scanner\RepositoryScanner(); $repositories = $repositoryScanner->collectEntities($this->files['di']); From 03f59fda9e6f902e25bfcfd9fdfc538dee8d8f56 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko Date: Tue, 12 Jan 2016 14:04:41 -0600 Subject: [PATCH 011/128] MAGETWO-47679: Remi PHP 7.0.1 failure on L1 segmentation fault on SOAP / REST --- .../CatalogSearch/Model/Indexer/Fulltext.php | 17 +++++++++-------- .../Model/Indexer/Fulltext/Action/Full.php | 13 ++++++++----- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php index c59954933ce39..bad9d312c3235 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php @@ -89,10 +89,11 @@ public function execute($ids) foreach ($storeIds as $storeId) { $dimension = $this->dimensionFactory->create(['name' => 'scope', 'value' => $storeId]); $saveHandler->deleteIndex([$dimension], new \ArrayObject($ids)); - $saveHandler->saveIndex( - [$dimension], - $this->fullAction->rebuildStoreIndex($storeId, $ids) - ); + $products = $this->fullAction->rebuildStoreIndex($storeId, $ids); + foreach ($products as $product) { + $saveHandler->saveIndex([$dimension], $product); + } + } } @@ -111,10 +112,10 @@ public function executeFull() foreach ($storeIds as $storeId) { $dimension = $this->dimensionFactory->create(['name' => 'scope', 'value' => $storeId]); $saveHandler->cleanIndex([$dimension]); - $saveHandler->saveIndex( - [$dimension], - $this->fullAction->rebuildStoreIndex($storeId) - ); + $products = $this->fullAction->rebuildStoreIndex($storeId); + foreach ($products as $product) { + $saveHandler->saveIndex([$dimension], $product); + } } $this->fulltextResource->resetSearchResults(); $this->searchRequestConfig->reset(); diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php index 4c0f94351f51d..803c3f61f7abf 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php @@ -248,10 +248,11 @@ protected function rebuildIndex($productIds = null) foreach ($storeIds as $storeId) { $dimension = $this->dimensionFactory->create(['name' => self::SCOPE_FIELD_NAME, 'value' => $storeId]); $this->indexHandler->deleteIndex([$dimension], $this->getIterator($productIds)); - $this->indexHandler->saveIndex( - [$dimension], - $this->rebuildStoreIndex($storeId, $productIds) - ); + $products = $this->rebuildStoreIndex($storeId, $productIds); + foreach ($products as $product) { + $this->indexHandler->saveIndex([$dimension], $product); + } + } $this->fulltextResource->resetSearchResults(); $this->searchRequestConfig->reset(); @@ -287,6 +288,7 @@ protected function getProductIdsFromParents(array $entityIds) */ public function rebuildStoreIndex($storeId, $productIds = null) { + $output = []; if ($productIds !== null) { $productIds = array_unique(array_merge($productIds, $this->getProductIdsFromParents($productIds))); } @@ -373,9 +375,10 @@ public function rebuildStoreIndex($storeId, $productIds = null) $index = $this->prepareProductIndex($productIndex, $productData, $storeId); - yield $productData['entity_id'] => $index; + $output[] = new \ArrayObject([$productData['entity_id'] => $index]); } } + return $output; } /** From d568485961fac75e97dbbfb9fef61478c448ea03 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko Date: Tue, 12 Jan 2016 17:04:22 -0600 Subject: [PATCH 012/128] MAGETWO-47679: Remi PHP 7.0.1 failure on L1 segmentation fault on SOAP / REST --- .../Test/Unit/Model/CartItemProcessorTest.php | 22 +++++++- .../Test/Unit/Model/Indexer/FulltextTest.php | 24 ++++++--- .../Unit/Model/Queue/TransportBuilderTest.php | 53 ++++++++++++++++++- 3 files changed, 88 insertions(+), 11 deletions(-) diff --git a/app/code/Magento/Bundle/Test/Unit/Model/CartItemProcessorTest.php b/app/code/Magento/Bundle/Test/Unit/Model/CartItemProcessorTest.php index 02be067f9e68a..03e1646cca386 100644 --- a/app/code/Magento/Bundle/Test/Unit/Model/CartItemProcessorTest.php +++ b/app/code/Magento/Bundle/Test/Unit/Model/CartItemProcessorTest.php @@ -79,7 +79,16 @@ public function testConvertToBuyRequest() $dataObjectMock = $this->getMock('\Magento\Framework\DataObject'); $optionExtensionMock = $this->getMock( '\Magento\Quote\Api\Data\ProductOptionExtensionInterface', - ['getBundleOptions'], + [ + 'getBundleOptions', + 'getCustomOptions', + 'setCustomOptions', + 'setBundleOptions', + 'getDownloadableOption', + 'setDownloadableOption', + 'getConfigurableItemOptions', + 'setConfigurableItemOptions' + ], [], '', false @@ -128,7 +137,16 @@ public function testProcessProductOptions() $productOptionMock = $this->getMock('\Magento\Quote\Model\Quote\ProductOption', [], [], '', false); $optionExtensionMock = $this->getMock( '\Magento\Quote\Api\Data\ProductOptionExtensionInterface', - ['setBundleOptions'], + [ + 'getBundleOptions', + 'getCustomOptions', + 'setCustomOptions', + 'setBundleOptions', + 'getDownloadableOption', + 'setDownloadableOption', + 'getConfigurableItemOptions', + 'setConfigurableItemOptions' + ], [], '', false diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/FulltextTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/FulltextTest.php index 1118c81f3fa87..54e654c91cf41 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/FulltextTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/FulltextTest.php @@ -120,8 +120,10 @@ public function testExecute() $indexData = new \ArrayObject([]); $this->storeManager->expects($this->once())->method('getStores')->willReturn($stores); $this->saveHandler->expects($this->exactly(count($stores)))->method('deleteIndex'); - $this->saveHandler->expects($this->exactly(count($stores)))->method('saveIndex'); - $this->fullAction->expects($this->exactly(count($stores)))->method('rebuildStoreIndex')->willReturn($indexData); + $this->saveHandler->expects($this->exactly(4))->method('saveIndex'); + $this->fullAction->expects($this->exactly(2)) + ->method('rebuildStoreIndex') + ->willReturn([$indexData, $indexData]); $this->model->execute($ids); } @@ -132,8 +134,10 @@ public function testExecuteFull() $indexData = new \ArrayObject([]); $this->storeManager->expects($this->once())->method('getStores')->willReturn($stores); $this->saveHandler->expects($this->exactly(count($stores)))->method('cleanIndex'); - $this->saveHandler->expects($this->exactly(count($stores)))->method('saveIndex'); - $this->fullAction->expects($this->exactly(count($stores)))->method('rebuildStoreIndex')->willReturn($indexData); + $this->saveHandler->expects($this->exactly(4))->method('saveIndex'); + $this->fullAction->expects($this->exactly(2)) + ->method('rebuildStoreIndex') + ->willReturn([$indexData, $indexData]); $this->fulltextResource->expects($this->once())->method('resetSearchResults'); $this->searchRequestConfig->expects($this->once())->method('reset'); @@ -147,8 +151,10 @@ public function testExecuteList() $indexData = new \ArrayObject([]); $this->storeManager->expects($this->once())->method('getStores')->willReturn($stores); $this->saveHandler->expects($this->exactly(count($stores)))->method('deleteIndex'); - $this->saveHandler->expects($this->exactly(count($stores)))->method('saveIndex'); - $this->fullAction->expects($this->exactly(count($stores)))->method('rebuildStoreIndex')->willReturn($indexData); + $this->saveHandler->expects($this->exactly(4))->method('saveIndex'); + $this->fullAction->expects($this->exactly(2)) + ->method('rebuildStoreIndex') + ->willReturn([$indexData, $indexData]); $this->model->executeList($ids); } @@ -160,8 +166,10 @@ public function testExecuteRow() $indexData = new \ArrayObject([]); $this->storeManager->expects($this->once())->method('getStores')->willReturn($stores); $this->saveHandler->expects($this->exactly(count($stores)))->method('deleteIndex'); - $this->saveHandler->expects($this->exactly(count($stores)))->method('saveIndex'); - $this->fullAction->expects($this->exactly(count($stores)))->method('rebuildStoreIndex')->willReturn($indexData); + $this->saveHandler->expects($this->exactly(4))->method('saveIndex'); + $this->fullAction->expects($this->exactly(2)) + ->method('rebuildStoreIndex') + ->willReturn([$indexData, $indexData]); $this->model->executeRow($id); } diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/Queue/TransportBuilderTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/Queue/TransportBuilderTest.php index d9e904b7000cf..a498d464eaf94 100644 --- a/app/code/Magento/Newsletter/Test/Unit/Model/Queue/TransportBuilderTest.php +++ b/app/code/Magento/Newsletter/Test/Unit/Model/Queue/TransportBuilderTest.php @@ -8,7 +8,7 @@ use Magento\Framework\App\TemplateTypesInterface; use Magento\Framework\Mail\MessageInterface; -class TransportBuilderTest extends \Magento\Framework\Mail\Test\Unit\Template\TransportBuilderTest +class TransportBuilderTest extends \PHPUnit_Framework_TestCase { /** * @var string @@ -20,6 +20,57 @@ class TransportBuilderTest extends \Magento\Framework\Mail\Test\Unit\Template\Tr */ protected $builder; + /** + * @var \Magento\Framework\Mail\Template\FactoryInterface | \PHPUnit_Framework_MockObject_MockObject + */ + protected $templateFactoryMock; + + /** + * @var \Magento\Framework\Mail\Message | \PHPUnit_Framework_MockObject_MockObject + */ + protected $messageMock; + + /** + * @var \Magento\Framework\ObjectManagerInterface | \PHPUnit_Framework_MockObject_MockObject + */ + protected $objectManagerMock; + + /** + * @var \Magento\Framework\Mail\Template\SenderResolverInterface | \PHPUnit_Framework_MockObject_MockObject + */ + protected $senderResolverMock; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $mailTransportFactoryMock; + + /** + * @return void + */ + public function setUp() + { + $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->templateFactoryMock = $this->getMock('Magento\Framework\Mail\Template\FactoryInterface'); + $this->messageMock = $this->getMock('Magento\Framework\Mail\Message'); + $this->objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface'); + $this->senderResolverMock = $this->getMock('Magento\Framework\Mail\Template\SenderResolverInterface'); + $this->mailTransportFactoryMock = $this->getMockBuilder('Magento\Framework\Mail\TransportInterfaceFactory') + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->builder = $objectManagerHelper->getObject( + $this->builderClassName, + [ + 'templateFactory' => $this->templateFactoryMock, + 'message' => $this->messageMock, + 'objectManager' => $this->objectManagerMock, + 'senderResolver' => $this->senderResolverMock, + 'mailTransportFactory' => $this->mailTransportFactoryMock + ] + ); + } + /** * @param int $templateType * @param string $messageType From 9cf7b1a50d42bcfeeee571a9e008568f499ebd28 Mon Sep 17 00:00:00 2001 From: Igor Melnikov Date: Tue, 12 Jan 2016 18:18:16 -0600 Subject: [PATCH 013/128] MAGETWO-47679: Remi PHP 7.0.1 failure on L1 segmentation fault on SOAP / REST Removing yield for compatibility with PHP 7 --- .../Magento/Framework/Indexer/SaveHandler/Batch.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php b/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php index 5f432356d3d1b..4c20ad939f995 100644 --- a/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php +++ b/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php @@ -17,16 +17,20 @@ public function getItems(\Traversable $documents, $size) $i = 0; $batch = []; + if (iterator_count($documents) == 0) { + return [$batch]; + } + foreach ($documents as $documentName => $documentValue) { $batch[$documentName] = $documentValue; if ($i++ >= $size) { - yield $batch; + return [$batch]; $i = 0; $batch = []; } } if (count($batch) > 0) { - yield $batch; + return [$batch]; } } } From 30aaa1145a1d1abe61c52eb1efd2c8df1497a638 Mon Sep 17 00:00:00 2001 From: Igor Melnikov Date: Tue, 12 Jan 2016 18:49:08 -0600 Subject: [PATCH 014/128] MAGETWO-47679: Remi PHP 7.0.1 failure on L1 segmentation fault on SOAP / REST Removing yield for compatibility with PHP 7 --- .../Magento/Framework/Indexer/SaveHandler/Batch.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php b/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php index 4c20ad939f995..8601cf6709b2b 100644 --- a/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php +++ b/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php @@ -14,13 +14,12 @@ class Batch */ public function getItems(\Traversable $documents, $size) { + if (count($documents) == 0) { + return []; + } + $i = 0; $batch = []; - - if (iterator_count($documents) == 0) { - return [$batch]; - } - foreach ($documents as $documentName => $documentValue) { $batch[$documentName] = $documentValue; if ($i++ >= $size) { From 446e17b8c99b920f411b878af130d155cd3d8256 Mon Sep 17 00:00:00 2001 From: Igor Melnikov Date: Tue, 12 Jan 2016 18:57:05 -0600 Subject: [PATCH 015/128] MAGETWO-47679: Remi PHP 7.0.1 failure on L1 segmentation fault on SOAP / REST Removing yield for compatibility with PHP 7 --- lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php b/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php index 8601cf6709b2b..0c8aa4c27ce20 100644 --- a/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php +++ b/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php @@ -10,14 +10,14 @@ class Batch /** * @param \Traversable $documents * @param int $size - * @return \Generator + * @return array */ public function getItems(\Traversable $documents, $size) { if (count($documents) == 0) { return []; } - + $i = 0; $batch = []; foreach ($documents as $documentName => $documentValue) { From 1c12fa2696f6ac9334074bc534d6f1681fe71494 Mon Sep 17 00:00:00 2001 From: Alexander Paliarush Date: Wed, 13 Jan 2016 16:34:38 +0200 Subject: [PATCH 016/128] MAGETWO-47583: checkAdminPasswordChange is NOT throwing exception when previous password is used --- .../Magento/User/Model/ResourceModel/User.php | 4 +- app/code/Magento/User/Model/User.php | 35 ++++- .../CheckAdminPasswordChangeObserver.php | 82 ------------ .../Backend/TrackAdminNewPasswordObserver.php | 4 +- .../Magento/User/Test/Unit/Model/UserTest.php | 100 ++++++++++++++ .../CheckAdminPasswordChangeObserverTest.php | 126 ------------------ .../TrackAdminNewPasswordObserverTest.php | 4 +- .../Magento/User/etc/adminhtml/events.xml | 3 - .../Test/Legacy/_files/obsolete_classes.php | 1 + 9 files changed, 138 insertions(+), 221 deletions(-) delete mode 100644 app/code/Magento/User/Observer/Backend/CheckAdminPasswordChangeObserver.php delete mode 100644 app/code/Magento/User/Test/Unit/Observer/Backend/CheckAdminPasswordChangeObserverTest.php diff --git a/app/code/Magento/User/Model/ResourceModel/User.php b/app/code/Magento/User/Model/ResourceModel/User.php index 1c87be70f24ef..6f782c75f3108 100644 --- a/app/code/Magento/User/Model/ResourceModel/User.php +++ b/app/code/Magento/User/Model/ResourceModel/User.php @@ -539,7 +539,7 @@ public function getOldPasswords($user, $retainLimit = 4) $userId = (int)$user->getId(); $table = $this->getTable('admin_passwords'); - // purge expired passwords, except that should retain + // purge expired passwords, except those which should be retained $retainPasswordIds = $this->getConnection()->fetchCol( $this->getConnection() ->select() @@ -556,7 +556,7 @@ public function getOldPasswords($user, $retainLimit = 4) } $this->getConnection()->delete($table, $where); - // now get all remained passwords + // get all remaining passwords return $this->getConnection()->fetchCol( $this->getConnection() ->select() diff --git a/app/code/Magento/User/Model/User.php b/app/code/Magento/User/Model/User.php index b9573b4f76e30..c5d38e8b98e25 100644 --- a/app/code/Magento/User/Model/User.php +++ b/app/code/Magento/User/Model/User.php @@ -256,9 +256,9 @@ protected function _getValidationRulesBeforeSave() } /** - * Validate customer attribute values. - * For existing customer password + confirmation will be validated only when password is set - * (i.e. its change is requested) + * Validate admin user data. + * + * Existing user password confirmation will be validated only when password is set * * @return bool|string[] */ @@ -272,8 +272,35 @@ public function validate() return $validator->getMessages(); } - return true; + return $this->validatePasswordChange(); + } + + /** + * Make sure admin password was changed. + * + * New password is compared to at least 4 previous passwords to prevent setting them again + * + * @return bool|string[] + */ + protected function validatePasswordChange() + { + $password = $this->getPassword(); + if ($password && !$this->getForceNewPassword() && $this->getId()) { + $errorMessage = __('Sorry, but this password has already been used. Please create another.'); + // Check if password is equal to the current one + if ($this->_encryptor->isValidHash($password, $this->getOrigData('password'))) { + return [$errorMessage]; + } + // Check whether password was used before + $passwordHash = $this->_encryptor->getHash($password, false); + foreach ($this->getResource()->getOldPasswords($this) as $oldPasswordHash) { + if ($passwordHash === $oldPasswordHash) { + return [$errorMessage]; + } + } + } + return true; } /** diff --git a/app/code/Magento/User/Observer/Backend/CheckAdminPasswordChangeObserver.php b/app/code/Magento/User/Observer/Backend/CheckAdminPasswordChangeObserver.php deleted file mode 100644 index 3bf06a441e248..0000000000000 --- a/app/code/Magento/User/Observer/Backend/CheckAdminPasswordChangeObserver.php +++ /dev/null @@ -1,82 +0,0 @@ -userResource = $userResource; - $this->encryptor = $encryptor; - } - - /** - * Harden admin password change. - * - * New password must be minimum 7 chars length and include alphanumeric characters - * The password is compared to at least last 4 previous passwords to prevent setting them again - * - * @param EventObserver $observer - * @return void - * @throws \Magento\Framework\Exception\LocalizedException - */ - public function execute(EventObserver $observer) - { - /* @var $user \Magento\User\Model\User */ - $user = $observer->getEvent()->getObject(); - - if ($user->getNewPassword()) { - $password = $user->getNewPassword(); - } else { - $password = $user->getPassword(); - } - - if ($password && !$user->getForceNewPassword() && $user->getId()) { - if ($this->encryptor->isValidHash($password, $user->getOrigData('password'))) { - throw new \Magento\Framework\Exception\LocalizedException( - __('Sorry, but this password has already been used. Please create another.') - ); - } - - // check whether password was used before - $passwordHash = $this->encryptor->getHash($password, false); - foreach ($this->userResource->getOldPasswords($user) as $oldPasswordHash) { - if ($passwordHash === $oldPasswordHash) { - throw new \Magento\Framework\Exception\LocalizedException( - __('Sorry, but this password has already been used. Please create another.') - ); - } - } - } - } -} diff --git a/app/code/Magento/User/Observer/Backend/TrackAdminNewPasswordObserver.php b/app/code/Magento/User/Observer/Backend/TrackAdminNewPasswordObserver.php index 790d78301f058..0f33107ac0173 100644 --- a/app/code/Magento/User/Observer/Backend/TrackAdminNewPasswordObserver.php +++ b/app/code/Magento/User/Observer/Backend/TrackAdminNewPasswordObserver.php @@ -71,7 +71,7 @@ public function __construct( } /** - * Save new admin password + * Save current admin password to prevent its usage when changed in the future. * * @param EventObserver $observer * @return void @@ -81,7 +81,7 @@ public function execute(EventObserver $observer) /* @var $user \Magento\User\Model\User */ $user = $observer->getEvent()->getObject(); if ($user->getId()) { - $password = $user->getNewPassword(); + $password = $user->getCurrentPassword(); $passwordLifetime = $this->observerConfig->getAdminPasswordLifetime(); if ($passwordLifetime && $password && !$user->getForceNewPassword()) { $passwordHash = $this->encryptor->getHash($password, false); diff --git a/app/code/Magento/User/Test/Unit/Model/UserTest.php b/app/code/Magento/User/Test/Unit/Model/UserTest.php index ed495d41e369d..d2f89414527de 100644 --- a/app/code/Magento/User/Test/Unit/Model/UserTest.php +++ b/app/code/Magento/User/Test/Unit/Model/UserTest.php @@ -610,4 +610,104 @@ public function testIsResetPasswordLinkTokenExpiredIsNotExpiredToken() $this->userDataMock->expects($this->once())->method('getResetPasswordLinkExpirationPeriod')->willReturn(1); $this->assertFalse($this->model->isResetPasswordLinkTokenExpired()); } + + public function testCheckPasswordChangeEqualToCurrent() + { + /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */ + $validatorMock = $this->getMockBuilder('Magento\Framework\Validator\DataObject') + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock); + $this->validationRulesMock->expects($this->once()) + ->method('addUserInfoRules') + ->with($validatorMock); + $validatorMock->expects($this->once())->method('isValid')->willReturn(true); + + $newPassword = "NEWmYn3wpassw0rd"; + $oldPassword = "OLDmYn3wpassw0rd"; + $this->model->setPassword($newPassword) + ->setId(1) + ->setOrigData('password', $oldPassword); + $this->encryptorMock->expects($this->once()) + ->method('isValidHash') + ->with($newPassword, $oldPassword) + ->willReturn(true); + $result = $this->model->validate(); + $this->assertInternalType('array', $result); + $this->assertCount(1, $result); + $this->assertContains("Sorry, but this password has already been used.", (string)$result[0]); + } + + public function testCheckPasswordChangeEqualToPrevious() + { + /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */ + $validatorMock = $this->getMockBuilder('Magento\Framework\Validator\DataObject') + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock); + $this->validationRulesMock->expects($this->once()) + ->method('addUserInfoRules') + ->with($validatorMock); + $validatorMock->expects($this->once())->method('isValid')->willReturn(true); + + $newPassword = "NEWmYn3wpassw0rd"; + $newPasswordHash = "new password hash"; + $oldPassword = "OLDmYn3wpassw0rd"; + $this->model->setPassword($newPassword) + ->setId(1) + ->setOrigData('password', $oldPassword); + $this->encryptorMock->expects($this->once()) + ->method('isValidHash') + ->with($newPassword, $oldPassword) + ->willReturn(false); + + $this->encryptorMock->expects($this->once()) + ->method('getHash') + ->with($newPassword, false) + ->willReturn($newPasswordHash); + + $this->resourceMock->expects($this->once())->method('getOldPasswords')->willReturn(['hash1', $newPasswordHash]); + + $result = $this->model->validate(); + $this->assertInternalType('array', $result); + $this->assertCount(1, $result); + $this->assertContains("Sorry, but this password has already been used.", (string)$result[0]); + } + + public function testCheckPasswordChangeValid() + { + /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */ + $validatorMock = $this->getMockBuilder('Magento\Framework\Validator\DataObject') + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); + $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock); + $this->validationRulesMock->expects($this->once()) + ->method('addUserInfoRules') + ->with($validatorMock); + $validatorMock->expects($this->once())->method('isValid')->willReturn(true); + + $newPassword = "NEWmYn3wpassw0rd"; + $newPasswordHash = "new password hash"; + $oldPassword = "OLDmYn3wpassw0rd"; + $this->model->setPassword($newPassword) + ->setId(1) + ->setOrigData('password', $oldPassword); + $this->encryptorMock->expects($this->once()) + ->method('isValidHash') + ->with($newPassword, $oldPassword) + ->willReturn(false); + + $this->encryptorMock->expects($this->once()) + ->method('getHash') + ->with($newPassword, false) + ->willReturn($newPasswordHash); + + $this->resourceMock->expects($this->once())->method('getOldPasswords')->willReturn(['hash1', 'hash2']); + + $result = $this->model->validate(); + $this->assertTrue($result); + } } diff --git a/app/code/Magento/User/Test/Unit/Observer/Backend/CheckAdminPasswordChangeObserverTest.php b/app/code/Magento/User/Test/Unit/Observer/Backend/CheckAdminPasswordChangeObserverTest.php deleted file mode 100644 index a4b9b37edbfa8..0000000000000 --- a/app/code/Magento/User/Test/Unit/Observer/Backend/CheckAdminPasswordChangeObserverTest.php +++ /dev/null @@ -1,126 +0,0 @@ -userMock = $this->getMockBuilder('Magento\User\Model\ResourceModel\User') - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $this->encryptorMock = $this->getMockBuilder('\Magento\Framework\Encryption\EncryptorInterface') - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $this->eventManagerMock = $this->getMockBuilder('Magento\Framework\Event\ManagerInterface') - ->disableOriginalConstructor() - ->setMethods([]) - ->getMockForAbstractClass(); - - $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - - $this->model = $helper->getObject( - '\Magento\User\Observer\Backend\CheckAdminPasswordChangeObserver', - [ - 'userResource' => $this->userMock, - 'encryptor' => $this->encryptorMock, - ] - ); - } - - public function testCheckAdminPasswordChange() - { - $newPW = "mYn3wpassw0rd"; - $uid = 123; - /** @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject $eventObserverMock */ - $eventObserverMock = $this->getMockBuilder('Magento\Framework\Event\Observer') - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - /** @var \Magento\Framework\Event|\PHPUnit_Framework_MockObject_MockObject */ - $eventMock = $this->getMockBuilder('Magento\Framework\Event') - ->disableOriginalConstructor() - ->setMethods(['getObject']) - ->getMock(); - - /** @var \Magento\User\Model\User|\PHPUnit_Framework_MockObject_MockObject $userMock */ - $userMock = $this->getMockBuilder('Magento\User\Model\User') - ->disableOriginalConstructor() - ->setMethods(['getId', 'getNewPassword', 'getForceNewPassword']) - ->getMock(); - - $eventObserverMock->expects($this->once())->method('getEvent')->willReturn($eventMock); - $eventMock->expects($this->once())->method('getObject')->willReturn($userMock); - $userMock->expects($this->atLeastOnce())->method('getNewPassword')->willReturn($newPW); - $userMock->expects($this->once())->method('getForceNewPassword')->willReturn(false); - $userMock->expects($this->once())->method('getId')->willReturn($uid); - $this->encryptorMock->expects($this->once())->method('isValidHash')->willReturn(false); - $this->encryptorMock->expects($this->once())->method('getHash')->willReturn(md5($newPW)); - $this->userMock->method('getOldPasswords')->willReturn([md5('pw1'), md5('pw2')]); - - $this->model->execute($eventObserverMock); - } - - public function testCheckAdminPasswordChangeThrowsLocalizedExp() - { - $newPW = "mYn3wpassw0rd"; - $uid = 123; - /** @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject $eventObserverMock */ - $eventObserverMock = $this->getMockBuilder('Magento\Framework\Event\Observer') - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - /** @var \Magento\Framework\Event|\PHPUnit_Framework_MockObject_MockObject */ - $eventMock = $this->getMockBuilder('Magento\Framework\Event') - ->disableOriginalConstructor() - ->setMethods(['getObject']) - ->getMock(); - - /** @var \Magento\User\Model\User|\PHPUnit_Framework_MockObject_MockObject $userMock */ - $userMock = $this->getMockBuilder('Magento\User\Model\User') - ->disableOriginalConstructor() - ->setMethods(['getId', 'getNewPassword', 'getForceNewPassword']) - ->getMock(); - - $eventObserverMock->expects($this->once())->method('getEvent')->willReturn($eventMock); - $eventMock->expects($this->once())->method('getObject')->willReturn($userMock); - $userMock->expects($this->atLeastOnce())->method('getNewPassword')->willReturn($newPW); - $userMock->expects($this->once())->method('getForceNewPassword')->willReturn(false); - $userMock->expects($this->once())->method('getId')->willReturn($uid); - $this->encryptorMock->expects($this->once())->method('isValidHash')->willReturn(true); - $this->userMock->method('getOldPasswords')->willReturn([md5('pw1'), md5('pw2')]); - - try { - $this->model->execute($eventObserverMock); - } catch (\Magento\Framework\Exception\LocalizedException $expected) { - return; - } - $this->fail('An expected exception has not been raised.'); - } -} diff --git a/app/code/Magento/User/Test/Unit/Observer/Backend/TrackAdminNewPasswordObserverTest.php b/app/code/Magento/User/Test/Unit/Observer/Backend/TrackAdminNewPasswordObserverTest.php index eb1b930771dd3..d6dc5ddde8dc6 100644 --- a/app/code/Magento/User/Test/Unit/Observer/Backend/TrackAdminNewPasswordObserverTest.php +++ b/app/code/Magento/User/Test/Unit/Observer/Backend/TrackAdminNewPasswordObserverTest.php @@ -108,13 +108,13 @@ public function testTrackAdminPassword() /** @var \Magento\User\Model\User|\PHPUnit_Framework_MockObject_MockObject $userMock */ $userMock = $this->getMockBuilder('Magento\User\Model\User') ->disableOriginalConstructor() - ->setMethods(['getId', 'getNewPassword', 'getForceNewPassword']) + ->setMethods(['getId', 'getCurrentPassword', 'getForceNewPassword']) ->getMock(); $eventObserverMock->expects($this->once())->method('getEvent')->willReturn($eventMock); $eventMock->expects($this->once())->method('getObject')->willReturn($userMock); $userMock->expects($this->once())->method('getId')->willReturn($uid); - $userMock->expects($this->once())->method('getNewPassword')->willReturn($newPW); + $userMock->expects($this->once())->method('getCurrentPassword')->willReturn($newPW); $this->configInterfaceMock ->expects($this->atLeastOnce()) ->method('getValue') diff --git a/app/code/Magento/User/etc/adminhtml/events.xml b/app/code/Magento/User/etc/adminhtml/events.xml index 1bcdab99c7667..469c19b9c1b25 100755 --- a/app/code/Magento/User/etc/adminhtml/events.xml +++ b/app/code/Magento/User/etc/adminhtml/events.xml @@ -12,9 +12,6 @@ - - - diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php index a03cced85cf25..6a88c679b8f1d 100755 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php @@ -3878,6 +3878,7 @@ 'Magento\Framework\Component\ComponentRegistrar' ], ['Magento\Framework\App\Router\ActionList\Reader'], + ['Magento\User\Observer\Backend\CheckAdminPasswordChangeObserver'], ['Magento\Framework\View\File\AbstractCollector'], ['Magento\Tools\Migration\Acl\FileManager'], ['Magento\Tools\Migration\Acl\Formatter'], From 7f7634a809577f992be2a84be77455a74131c4b2 Mon Sep 17 00:00:00 2001 From: Joan He Date: Wed, 13 Jan 2016 08:48:58 -0600 Subject: [PATCH 017/128] MAGETWO-47639: [Github] Not all files are pre-compiled #2888 - Fixed static test failures --- .../Setup/Console/Command/DiCompileCommand.php | 12 ++---------- .../Unit/Module/Di/App/Task/ProxyGeneratorTest.php | 5 +++-- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php index 963ae19576ac1..b9dbc3aebbda2 100644 --- a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php +++ b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php @@ -161,15 +161,9 @@ protected function execute(InputInterface $input, OutputInterface $output) 'application' => $excludedModulePaths, 'framework' => $excludedLibraryPaths ]; - $dataAttributesIncludePattern = [ - 'extension_attributes' => '/\/etc\/([a-zA-Z_]*\/extension_attributes|extension_attributes)\.xml$/' - ]; $this->configureObjectManager($output); - $operations = $this->getOperationsConfiguration( - $compiledPathsList, - $dataAttributesIncludePattern - ); + $operations = $this->getOperationsConfiguration($compiledPathsList); try { $this->cleanupFilesystem( @@ -286,12 +280,10 @@ private function configureObjectManager(OutputInterface $output) * Returns operations configuration * * @param array $compiledPathsList - * @param array $dataAttributesIncludePattern * @return array */ private function getOperationsConfiguration( - array $compiledPathsList, - array $dataAttributesIncludePattern + array $compiledPathsList ) { $excludePatterns = []; foreach ($this->excludedPathsList as $excludedPaths) { diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ProxyGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ProxyGeneratorTest.php index ac0ecfc74dbf7..1a1382b87a65d 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ProxyGeneratorTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/App/Task/ProxyGeneratorTest.php @@ -33,8 +33,9 @@ protected function setUp() ->disableOriginalConstructor() ->getMock(); - $this->configurationScannerMock = $this->getMockBuilder('Magento\Setup\Module\Di\Code\Scanner\ConfigurationScanner') - ->disableOriginalConstructor() + $this->configurationScannerMock = $this->getMockBuilder( + 'Magento\Setup\Module\Di\Code\Scanner\ConfigurationScanner' + )->disableOriginalConstructor() ->getMock(); $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); From 18e4fadddae03530e2cbe61b9f668b09a3d8eb49 Mon Sep 17 00:00:00 2001 From: Igor Melnikov Date: Wed, 13 Jan 2016 09:46:42 -0600 Subject: [PATCH 018/128] MAGETWO-47679: Remi PHP 7.0.1 failure on L1 segmentation fault on SOAP / REST Removing yield for compatibility with PHP 7 --- .../Magento/Framework/Indexer/SaveHandler/Batch.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php b/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php index 0c8aa4c27ce20..d58cb71d65cef 100644 --- a/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php +++ b/lib/internal/Magento/Framework/Indexer/SaveHandler/Batch.php @@ -19,17 +19,18 @@ public function getItems(\Traversable $documents, $size) } $i = 0; - $batch = []; + $batch = $items = []; foreach ($documents as $documentName => $documentValue) { $batch[$documentName] = $documentValue; if ($i++ >= $size) { - return [$batch]; + $items[] = $batch; $i = 0; $batch = []; } } if (count($batch) > 0) { - return [$batch]; + $items[] = $batch; } + return $items; } } From 3c5617e1f96f83b8f33bbaa4b5cc5d3951a6ef1d Mon Sep 17 00:00:00 2001 From: Joan He Date: Wed, 13 Jan 2016 09:26:54 -0600 Subject: [PATCH 019/128] MAGETWO-47639: [Github] Not all files are pre-compiled #2888 - Fixed integration tests --- app/code/Magento/Cron/etc/di.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/code/Magento/Cron/etc/di.xml b/app/code/Magento/Cron/etc/di.xml index db9161d26099f..0b78824ef4807 100644 --- a/app/code/Magento/Cron/etc/di.xml +++ b/app/code/Magento/Cron/etc/di.xml @@ -39,8 +39,7 @@ - - + From 0de4f9c9788a75b9e5070477167fb87c7a8c0703 Mon Sep 17 00:00:00 2001 From: Eddie Lau Date: Mon, 21 Dec 2015 11:38:48 -0600 Subject: [PATCH 020/128] MAGETWO-47005: bin/magento setup:upgrade doesn't clean DB_PDO_MYSQL_DDL cache - fixed Db Adapter class to use correct cache frontend class --- .../App/ResourceConnection/ConnectionFactory.php | 6 +++--- .../ResourceConnection/ConnectionFactoryTest.php | 13 ++----------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/lib/internal/Magento/Framework/App/ResourceConnection/ConnectionFactory.php b/lib/internal/Magento/Framework/App/ResourceConnection/ConnectionFactory.php index 7924f4babdac9..f054c815916c2 100644 --- a/lib/internal/Magento/Framework/App/ResourceConnection/ConnectionFactory.php +++ b/lib/internal/Magento/Framework/App/ResourceConnection/ConnectionFactory.php @@ -22,9 +22,9 @@ class ConnectionFactory extends ModelConnectionFactory public function create(array $connectionConfig) { $connection = parent::create($connectionConfig); - /** @var \Magento\Framework\App\Cache\Type\FrontendPool $pool */ - $pool = $this->objectManager->get(\Magento\Framework\App\Cache\Type\FrontendPool::class); - $connection->setCacheAdapter($pool->get(DdlCache::TYPE_IDENTIFIER)); + /** @var \Magento\Framework\DB\Adapter\DdlCache $ddlCache */ + $ddlCache = $this->objectManager->get(\Magento\Framework\DB\Adapter\DdlCache::class); + $connection->setCacheAdapter($ddlCache); return $connection; } } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/ResourceConnection/ConnectionFactoryTest.php b/lib/internal/Magento/Framework/App/Test/Unit/ResourceConnection/ConnectionFactoryTest.php index 8a1b7296bbff1..77e6c428ae9b2 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/ResourceConnection/ConnectionFactoryTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/ResourceConnection/ConnectionFactoryTest.php @@ -5,8 +5,6 @@ */ namespace Magento\Framework\App\Test\Unit\ResourceConnection; -use Magento\Framework\DB\Adapter\DdlCache; - class ConnectionFactoryTest extends \PHPUnit_Framework_TestCase { /** @@ -38,7 +36,7 @@ protected function setUp() public function testCreate() { - $cacheAdapterMock = $this->getMockBuilder('Magento\Framework\Cache\FrontendInterface') + $cacheAdapterMock = $this->getMockBuilder('Magento\Framework\DB\Adapter\DdlCache') ->disableOriginalConstructor() ->getMock(); $loggerMock = $this->getMockBuilder('Magento\Framework\DB\LoggerInterface') @@ -63,19 +61,12 @@ public function testCreate() ->method('create') ->with('Magento\Framework\App\ResourceConnection\ConnectionAdapterInterface') ->will($this->returnValue($connectionAdapterMock)); - $poolMock = $this->getMockBuilder('Magento\Framework\App\Cache\Type\FrontendPool') - ->disableOriginalConstructor() - ->getMock(); - $poolMock->expects($this->once()) - ->method('get') - ->with(DdlCache::TYPE_IDENTIFIER) - ->will($this->returnValue($cacheAdapterMock)); $this->objectManagerMock->expects($this->any()) ->method('get') ->will($this->returnValueMap( [ ['Magento\Framework\DB\LoggerInterface', $loggerMock], - ['Magento\Framework\App\Cache\Type\FrontendPool', $poolMock], + ['Magento\Framework\DB\Adapter\DdlCache', $cacheAdapterMock], ] )); $this->assertSame($connectionMock, $this->model->create(['active' => true])); From 07c2ae029955bc2606bf159b4c2adf68459fa04a Mon Sep 17 00:00:00 2001 From: Maddy Chellathurai Date: Mon, 28 Dec 2015 23:18:09 -0600 Subject: [PATCH 021/128] MAGETWO-47301: PHP7 Integration test failed - syntax error, unexpected 'Gateway' (T_STRING) - adding escape for quotes --- setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php b/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php index 55d060c895f8c..80e66ce6e15e0 100644 --- a/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php +++ b/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php @@ -270,7 +270,7 @@ private function getCompiledString($string) { $encloseQuote = $this->getQuote() == Phrase::QUOTE_DOUBLE ? Phrase::QUOTE_DOUBLE : Phrase::QUOTE_SINGLE; - $evalString = 'return ' . $encloseQuote . $string . $encloseQuote . ';'; + $evalString = 'return ' . $encloseQuote . addslashes($string) . $encloseQuote . ';'; $result = @eval($evalString); return is_string($result) ? $result : $string; } From f800142938ee35a06f465712444b6a707d41dda1 Mon Sep 17 00:00:00 2001 From: Maddy Chellathurai Date: Thu, 7 Jan 2016 11:27:21 -0600 Subject: [PATCH 022/128] MAGETWO-47301: PHP7 Integration test failed - syntax error, unexpected 'Gateway' (T_STRING) - fixed incorrect usage of Phrase. - Fixed Phrase to use double quotes and not excape those within strings. --- .../Test/Unit/Model/DirectpostTest.php | 2 +- .../Model/Config/Backend/Image/Adapter.php | 2 +- .../Model/Config/Compiler/IncludeElement.php | 2 +- .../Cookie/Model/Config/Backend/Domain.php | 2 +- .../Cookie/Model/Config/Backend/Lifetime.php | 2 +- .../Entity/Attribute/AbstractAttribute.php | 2 +- .../Magento/Email/Model/Template/Filter.php | 2 +- app/code/Magento/Ui/Component/Form/Field.php | 2 +- app/code/Magento/Ui/Component/Layout/Tabs.php | 6 +-- .../Setup/Module/I18n/Dictionary/Phrase.php | 54 ++----------------- 10 files changed, 15 insertions(+), 61 deletions(-) diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php index 3726d4e5108ae..925dd324a9e8f 100644 --- a/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php +++ b/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php @@ -331,7 +331,7 @@ public function testCheckResponseCodeFailure($responseCode) $this->dataHelperMock->expects($this->any()) ->method('wrapGatewayError') ->with($reasonText) - ->willReturn(__('Gateway error: ' . $reasonText)); + ->willReturn(__('Gateway error: %1', $reasonText)); $this->directpost->checkResponseCode(); } diff --git a/app/code/Magento/Config/Model/Config/Backend/Image/Adapter.php b/app/code/Magento/Config/Model/Config/Backend/Image/Adapter.php index 23e65a6e1d11c..be7c4739b53f2 100644 --- a/app/code/Magento/Config/Model/Config/Backend/Image/Adapter.php +++ b/app/code/Magento/Config/Model/Config/Backend/Image/Adapter.php @@ -53,7 +53,7 @@ public function beforeSave() try { $this->_imageFactory->create($this->getValue()); } catch (\Exception $e) { - $message = __('The specified image adapter cannot be used because of: ' . $e->getMessage()); + $message = __('The specified image adapter cannot be used because of: %1', $e->getMessage()); throw new \Magento\Framework\Exception\LocalizedException($message); } diff --git a/app/code/Magento/Config/Model/Config/Compiler/IncludeElement.php b/app/code/Magento/Config/Model/Config/Compiler/IncludeElement.php index 941cdc8529a1b..977cd035a1c04 100644 --- a/app/code/Magento/Config/Model/Config/Compiler/IncludeElement.php +++ b/app/code/Magento/Config/Model/Config/Compiler/IncludeElement.php @@ -112,6 +112,6 @@ protected function getContent($includePath) return $directoryRead->readFile($path); } - throw new LocalizedException(__('The file "' . $path . '" does not exist')); + throw new LocalizedException(__('The file "%1" does not exist', $path)); } } diff --git a/app/code/Magento/Cookie/Model/Config/Backend/Domain.php b/app/code/Magento/Cookie/Model/Config/Backend/Domain.php index 2f84b6d2fd067..1aeefdf6f7310 100644 --- a/app/code/Magento/Cookie/Model/Config/Backend/Domain.php +++ b/app/code/Magento/Cookie/Model/Config/Backend/Domain.php @@ -50,7 +50,7 @@ public function beforeSave() // Empty value is treated valid and will be handled when read the value out if (!empty($value) && !$this->configValidator->isValid($value)) { - $msg = __('Invalid domain name: ' . join('; ', $this->configValidator->getMessages())); + $msg = __('Invalid domain name: %1', join('; ', $this->configValidator->getMessages())); throw new \Magento\Framework\Exception\LocalizedException($msg); } } diff --git a/app/code/Magento/Cookie/Model/Config/Backend/Lifetime.php b/app/code/Magento/Cookie/Model/Config/Backend/Lifetime.php index 9d650159e4501..c7f418f92152e 100644 --- a/app/code/Magento/Cookie/Model/Config/Backend/Lifetime.php +++ b/app/code/Magento/Cookie/Model/Config/Backend/Lifetime.php @@ -49,7 +49,7 @@ public function beforeSave() $value = $this->getValue(); if (!empty($value) && !$this->configValidator->isValid($value)) { - $msg = __('Invalid cookie lifetime: ' . join('; ', $this->configValidator->getMessages())); + $msg = __('Invalid cookie lifetime: %1', join('; ', $this->configValidator->getMessages())); throw new \Magento\Framework\Exception\LocalizedException($msg); } return parent::beforeSave(); diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php b/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php index b77183b6c05f3..d09156a107ebb 100644 --- a/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php +++ b/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php @@ -497,7 +497,7 @@ public function getBackend() } $backend = $this->_universalFactory->create($this->getBackendModel()); if (!$backend) { - throw new LocalizedException(__('Invalid backend model specified: ' . $this->getBackendModel())); + throw new LocalizedException(__('Invalid backend model specified: %1', $this->getBackendModel())); } $this->_backend = $backend->setAttribute($this); } diff --git a/app/code/Magento/Email/Model/Template/Filter.php b/app/code/Magento/Email/Model/Template/Filter.php index 645c2d7aff607..7d285c36ee96d 100644 --- a/app/code/Magento/Email/Model/Template/Filter.php +++ b/app/code/Magento/Email/Model/Template/Filter.php @@ -920,7 +920,7 @@ public function applyInlineCss($html) !== false ) { throw new \Magento\Framework\Exception\MailException( - __('
' . PHP_EOL . $cssToInline . PHP_EOL . '
') + __('
 %1 
', PHP_EOL . $cssToInline . PHP_EOL) ); } diff --git a/app/code/Magento/Ui/Component/Form/Field.php b/app/code/Magento/Ui/Component/Form/Field.php index d2ff377ae5bd4..79b93d95764dc 100644 --- a/app/code/Magento/Ui/Component/Form/Field.php +++ b/app/code/Magento/Ui/Component/Form/Field.php @@ -71,7 +71,7 @@ public function prepare() $formElement = $this->getData('config/formElement'); if (null === $formElement) { throw new LocalizedException(__( - 'The configuration parameter "formElement" is a required for "' . $this->getName() . '" field.' + 'The configuration parameter "formElement" is a required for "%1" field', $this->getName() )); } // Create of wrapped component diff --git a/app/code/Magento/Ui/Component/Layout/Tabs.php b/app/code/Magento/Ui/Component/Layout/Tabs.php index 34021f0d8782d..1a48b532ed9c6 100644 --- a/app/code/Magento/Ui/Component/Layout/Tabs.php +++ b/app/code/Magento/Ui/Component/Layout/Tabs.php @@ -137,8 +137,8 @@ protected function addChildren(array &$topNode, UiComponentInterface $component, 'type' => 'collection', 'config' => [ 'active' => 1, - 'removeLabel' => __('Remove ' . $label), - 'addLabel' => __('Add New ' . $label), + 'removeLabel' => __('Remove %1', $label), + 'addLabel' => __('Add New %1', $label), 'removeMessage' => $childComponent->getData('config/removeMessage'), 'itemTemplate' => 'item_template', ], @@ -148,7 +148,7 @@ protected function addChildren(array &$topNode, UiComponentInterface $component, 'component' => 'Magento_Ui/js/form/components/collection/item', 'childType' => 'group', 'config' => [ - 'label' => __('New ' . $label), + 'label' => __('New %1', $label), ], 'children' => $childrenStructure ] diff --git a/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php b/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php index 80e66ce6e15e0..b59f47a35efe2 100644 --- a/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php +++ b/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php @@ -10,20 +10,6 @@ */ class Phrase { - /** - * Single quote that enclose the phrase - * - * @var string - */ - const QUOTE_SINGLE = "'"; - - /** - * Double quote that enclose the phrase - * - * @var string - */ - const QUOTE_DOUBLE = '"'; - /** * Phrase * @@ -52,13 +38,6 @@ class Phrase */ private $_contextValue = []; - /** - * Quote type that enclose the phrase, single or double - * - * @var string - */ - private $_quote; - /** * Phrase construct * @@ -68,13 +47,12 @@ class Phrase * @param string|array|null $contextValue * @param string|null $quote */ - public function __construct($phrase, $translation, $contextType = null, $contextValue = null, $quote = null) + public function __construct($phrase, $translation, $contextType = null, $contextValue = null) { $this->setPhrase($phrase); $this->setTranslation($translation); $this->setContextType($contextType); $this->setContextValue($contextValue); - $this->setQuote($quote); } /** @@ -93,7 +71,7 @@ public function setPhrase($phrase) } /** - * Get quote type + * Get phrase * * @return string */ @@ -102,29 +80,6 @@ public function getPhrase() return $this->_phrase; } - /** - * Set quote type - * - * @param string $quote - * @return void - */ - public function setQuote($quote) - { - if (in_array($quote, [self::QUOTE_SINGLE, self::QUOTE_DOUBLE])) { - $this->_quote = $quote; - } - } - - /** - * Get phrase - * - * @return string - */ - public function getQuote() - { - return $this->_quote; - } - /** * Set translation * @@ -268,9 +223,8 @@ public function getCompiledTranslation() */ private function getCompiledString($string) { - $encloseQuote = $this->getQuote() == Phrase::QUOTE_DOUBLE ? Phrase::QUOTE_DOUBLE : Phrase::QUOTE_SINGLE; - - $evalString = 'return ' . $encloseQuote . addslashes($string) . $encloseQuote . ';'; + $string = str_replace('$' , '\\$', $string); + $evalString = 'return "' . str_replace('"', '\\"', $string) . '";'; $result = @eval($evalString); return is_string($result) ? $result : $string; } From 15657f07be889163842af97fa1fb2c8709020bd3 Mon Sep 17 00:00:00 2001 From: Maddy Chellathurai Date: Thu, 7 Jan 2016 11:56:11 -0600 Subject: [PATCH 023/128] MAGETWO-47301: PHP7 Integration test failed - syntax error, unexpected 'Gateway' (T_STRING) - fixed static failures --- app/code/Magento/Ui/Component/Form/Field.php | 3 ++- app/code/Magento/Ui/Component/Layout/Tabs.php | 1 + .../Setup/Module/I18n/Dictionary/Phrase.php | 16 +++++++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Ui/Component/Form/Field.php b/app/code/Magento/Ui/Component/Form/Field.php index 79b93d95764dc..af329180a826c 100644 --- a/app/code/Magento/Ui/Component/Form/Field.php +++ b/app/code/Magento/Ui/Component/Form/Field.php @@ -71,7 +71,8 @@ public function prepare() $formElement = $this->getData('config/formElement'); if (null === $formElement) { throw new LocalizedException(__( - 'The configuration parameter "formElement" is a required for "%1" field', $this->getName() + 'The configuration parameter "formElement" is a required for "%1" field', + $this->getName() )); } // Create of wrapped component diff --git a/app/code/Magento/Ui/Component/Layout/Tabs.php b/app/code/Magento/Ui/Component/Layout/Tabs.php index 1a48b532ed9c6..66ff8693add39 100644 --- a/app/code/Magento/Ui/Component/Layout/Tabs.php +++ b/app/code/Magento/Ui/Component/Layout/Tabs.php @@ -96,6 +96,7 @@ public function build(UiComponentInterface $component) * @param string $componentType * @return void * @throws \Magento\Framework\Exception\LocalizedException + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ protected function addChildren(array &$topNode, UiComponentInterface $component, $componentType) { diff --git a/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php b/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php index b59f47a35efe2..5f0be3fa2c0f4 100644 --- a/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php +++ b/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php @@ -10,6 +10,20 @@ */ class Phrase { + /** + * Single quote that enclose the phrase + * + * @var string + */ + const QUOTE_SINGLE = "'"; + + /** + * Double quote that enclose the phrase + * + * @var string + */ + const QUOTE_DOUBLE = '"'; + /** * Phrase * @@ -223,7 +237,7 @@ public function getCompiledTranslation() */ private function getCompiledString($string) { - $string = str_replace('$' , '\\$', $string); + $string = str_replace('$', '\\$', $string); $evalString = 'return "' . str_replace('"', '\\"', $string) . '";'; $result = @eval($evalString); return is_string($result) ? $result : $string; From 7fa32e3335b7d8bd2cb25b40cc4bc9d8d7ba8281 Mon Sep 17 00:00:00 2001 From: Maddy Chellathurai Date: Thu, 7 Jan 2016 13:37:21 -0600 Subject: [PATCH 024/128] MAGETWO-47301: PHP7 Integration test failed - syntax error, unexpected 'Gateway' (T_STRING) - reverting removal of quote from phrase - fix for integration tests - adding escapes when quotes are not closed --- .../PageCache/etc/adminhtml/system.xml | 2 +- app/code/Magento/Weee/Model/Tax.php | 5 ++- .../Setup/Module/I18n/Dictionary/Phrase.php | 41 +++++++++++++++++-- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/app/code/Magento/PageCache/etc/adminhtml/system.xml b/app/code/Magento/PageCache/etc/adminhtml/system.xml index b6c79ee8c853f..fe6b8c6f85b14 100644 --- a/app/code/Magento/PageCache/etc/adminhtml/system.xml +++ b/app/code/Magento/PageCache/etc/adminhtml/system.xml @@ -18,7 +18,7 @@ - IPs access list separated with ',' that can purge Varnish configuration for config file generation. + IPs access list separated with \',\' that can purge Varnish configuration for config file generation. If field is empty default value localhost will be saved. Magento\PageCache\Model\System\Config\Backend\Varnish diff --git a/app/code/Magento/Weee/Model/Tax.php b/app/code/Magento/Weee/Model/Tax.php index b1293159031e9..1319ac01af822 100644 --- a/app/code/Magento/Weee/Model/Tax.php +++ b/app/code/Magento/Weee/Model/Tax.php @@ -344,7 +344,10 @@ public function getProductWeeeAttributes( } $one = new \Magento\Framework\DataObject(); - $one->setName(__($attribute['label_value'] ? $attribute['label_value'] : $attribute['frontend_label'])) + $one->setName( + __($attribute['label_value']) ? + __($attribute['label_value']) : __($attribute['frontend_label']) + ) ->setAmount($amount) ->setTaxAmount($taxAmount) ->setAmountExclTax($amountExclTax) diff --git a/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php b/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php index 5f0be3fa2c0f4..11f2a6b9f4ea6 100644 --- a/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php +++ b/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php @@ -52,6 +52,13 @@ class Phrase */ private $_contextValue = []; + /** + * Quote type that enclose the phrase, single or double + * + * @var string + */ + private $_quote; + /** * Phrase construct * @@ -61,12 +68,36 @@ class Phrase * @param string|array|null $contextValue * @param string|null $quote */ - public function __construct($phrase, $translation, $contextType = null, $contextValue = null) + public function __construct($phrase, $translation, $contextType = null, $contextValue = null, $quote = null) { $this->setPhrase($phrase); $this->setTranslation($translation); $this->setContextType($contextType); $this->setContextValue($contextValue); + $this->setQuote($quote); + } + + /** + * Set quote type + * + * @param string $quote + * @return void + */ + public function setQuote($quote) + { + if (in_array($quote, [self::QUOTE_SINGLE, self::QUOTE_DOUBLE])) { + $this->_quote = $quote; + } + } + + /** + * Get phrase + * + * @return string + */ + public function getQuote() + { + return $this->_quote; } /** @@ -237,8 +268,12 @@ public function getCompiledTranslation() */ private function getCompiledString($string) { - $string = str_replace('$', '\\$', $string); - $evalString = 'return "' . str_replace('"', '\\"', $string) . '";'; + $encloseQuote = $this->getQuote() == Phrase::QUOTE_DOUBLE ? Phrase::QUOTE_DOUBLE : Phrase::QUOTE_SINGLE; + preg_match_all('/(? Date: Thu, 7 Jan 2016 13:51:54 -0600 Subject: [PATCH 025/128] MAGETWO-47301: PHP7 Integration test failed - syntax error, unexpected 'Gateway' (T_STRING) - phpcs fix --- app/code/Magento/Weee/Model/Tax.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Weee/Model/Tax.php b/app/code/Magento/Weee/Model/Tax.php index 1319ac01af822..d3de2f754ca00 100644 --- a/app/code/Magento/Weee/Model/Tax.php +++ b/app/code/Magento/Weee/Model/Tax.php @@ -345,9 +345,8 @@ public function getProductWeeeAttributes( $one = new \Magento\Framework\DataObject(); $one->setName( - __($attribute['label_value']) ? - __($attribute['label_value']) : __($attribute['frontend_label']) - ) + __($attribute['label_value']) ? __($attribute['label_value']) : __($attribute['frontend_label']) + ) ->setAmount($amount) ->setTaxAmount($taxAmount) ->setAmountExclTax($amountExclTax) From 02e93555b46cb8e4715cf3ba95ba50fc2fe87e2c Mon Sep 17 00:00:00 2001 From: Maddy Chellathurai Date: Thu, 7 Jan 2016 13:53:47 -0600 Subject: [PATCH 026/128] MAGETWO-47301: PHP7 Integration test failed - syntax error, unexpected 'Gateway' (T_STRING) - phpcs fix --- .../Setup/Module/I18n/Dictionary/Phrase.php | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php b/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php index 11f2a6b9f4ea6..97a6e4afd78d9 100644 --- a/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php +++ b/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php @@ -78,16 +78,18 @@ public function __construct($phrase, $translation, $contextType = null, $context } /** - * Set quote type + * Set phrase * - * @param string $quote + * @param string $phrase * @return void + * @throws \DomainException */ - public function setQuote($quote) + public function setPhrase($phrase) { - if (in_array($quote, [self::QUOTE_SINGLE, self::QUOTE_DOUBLE])) { - $this->_quote = $quote; + if (!$phrase) { + throw new \DomainException('Missed phrase'); } + $this->_phrase = $phrase; } /** @@ -95,34 +97,32 @@ public function setQuote($quote) * * @return string */ - public function getQuote() + public function getPhrase() { - return $this->_quote; + return $this->_phrase; } /** - * Set phrase + * Set quote type * - * @param string $phrase + * @param string $quote * @return void - * @throws \DomainException */ - public function setPhrase($phrase) + public function setQuote($quote) { - if (!$phrase) { - throw new \DomainException('Missed phrase'); + if (in_array($quote, [self::QUOTE_SINGLE, self::QUOTE_DOUBLE])) { + $this->_quote = $quote; } - $this->_phrase = $phrase; } /** - * Get phrase + * Get quote type * * @return string */ - public function getPhrase() + public function getQuote() { - return $this->_phrase; + return $this->_quote; } /** From 899c7e225ddd8e6a93e0b1380d499b1bbdcd03e4 Mon Sep 17 00:00:00 2001 From: Maddy Chellathurai Date: Fri, 8 Jan 2016 14:22:08 -0600 Subject: [PATCH 027/128] MAGETWO-47301: PHP7 Integration test failed - syntax error, unexpected 'Gateway' (T_STRING) - fixing in translation file. --- app/code/Magento/Backend/i18n/en_US.csv | 2 +- app/code/Magento/Eav/i18n/en_US.csv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Backend/i18n/en_US.csv b/app/code/Magento/Backend/i18n/en_US.csv index 6e16f6a6e7ec6..0c5586948801f 100644 --- a/app/code/Magento/Backend/i18n/en_US.csv +++ b/app/code/Magento/Backend/i18n/en_US.csv @@ -306,7 +306,7 @@ YTD,YTD "Maximum sender name length is 255. Please correct your settings.","Maximum sender name length is 255. Please correct your settings." "The file you're uploading exceeds the server size limit of %1 kilobytes.","The file you're uploading exceeds the server size limit of %1 kilobytes." "The base directory to upload file is not specified.","The base directory to upload file is not specified." -"The specified image adapter cannot be used because of: ","The specified image adapter cannot be used because of: " +"The specified image adapter cannot be used because of: %1","The specified image adapter cannot be used because of: %1" "Default scope","Default scope" "Base currency","Base currency" "Display default currency","Display default currency" diff --git a/app/code/Magento/Eav/i18n/en_US.csv b/app/code/Magento/Eav/i18n/en_US.csv index 37bc177bd3572..df3f5cced4c3a 100644 --- a/app/code/Magento/Eav/i18n/en_US.csv +++ b/app/code/Magento/Eav/i18n/en_US.csv @@ -71,7 +71,7 @@ Letters,Letters "Invalid default decimal value","Invalid default decimal value" "Invalid default date","Invalid default date" "Invalid entity supplied","Invalid entity supplied" -"Invalid backend model specified: ","Invalid backend model specified: " +"Invalid backend model specified: %1","Invalid backend model specified: %1" "Source model ""%1"" not found for attribute ""%2""","Source model ""%1"" not found for attribute ""%2""" "The value of attribute ""%1"" must be unique","The value of attribute ""%1"" must be unique" "Invalid date","Invalid date" From 6dd421fae13b6cbb36407b5e336ec7aa42d3e5dd Mon Sep 17 00:00:00 2001 From: Maddy Chellathurai Date: Fri, 8 Jan 2016 14:27:33 -0600 Subject: [PATCH 028/128] MAGETWO-47301: PHP7 Integration test failed - syntax error, unexpected 'Gateway' (T_STRING) - added missed period --- app/code/Magento/Ui/Component/Form/Field.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Ui/Component/Form/Field.php b/app/code/Magento/Ui/Component/Form/Field.php index af329180a826c..c79b162b8cab0 100644 --- a/app/code/Magento/Ui/Component/Form/Field.php +++ b/app/code/Magento/Ui/Component/Form/Field.php @@ -71,7 +71,7 @@ public function prepare() $formElement = $this->getData('config/formElement'); if (null === $formElement) { throw new LocalizedException(__( - 'The configuration parameter "formElement" is a required for "%1" field', + 'The configuration parameter "formElement" is a required for "%1" field.', $this->getName() )); } From 503059d189bcb52a1b2dccce83a0b0662a839fd4 Mon Sep 17 00:00:00 2001 From: Maddy Chellathurai Date: Fri, 8 Jan 2016 15:30:16 -0600 Subject: [PATCH 029/128] MAGETWO-47301: PHP7 Integration test failed - syntax error, unexpected 'Gateway' (T_STRING) - splitting i18n and attr to be like other usages. --- .../Checkout/view/frontend/web/template/billing-address.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html index 3c87e88b6ad65..9efc76a8ee05a 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html @@ -6,7 +6,7 @@ -->
- +
From 28d9a3a7b2031408c293206997c90667abeaf4b4 Mon Sep 17 00:00:00 2001 From: Maddy Chellathurai Date: Mon, 11 Jan 2016 12:07:24 -0600 Subject: [PATCH 030/128] MAGETWO-47301: PHP7 Integration test failed - syntax error, unexpected 'Gateway' (T_STRING) - Adding comment as per CR. --- setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php b/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php index 97a6e4afd78d9..582ca2fcc2919 100644 --- a/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php +++ b/setup/src/Magento/Setup/Module/I18n/Dictionary/Phrase.php @@ -269,6 +269,7 @@ public function getCompiledTranslation() private function getCompiledString($string) { $encloseQuote = $this->getQuote() == Phrase::QUOTE_DOUBLE ? Phrase::QUOTE_DOUBLE : Phrase::QUOTE_SINGLE; + //find all occurrences of ' and ", with no \ before it. preg_match_all('/(? Date: Tue, 12 Jan 2016 14:45:39 -0600 Subject: [PATCH 031/128] MAGETWO-45688: Reflected XSS in Cookie HTTP header - Provided fix to add server side encoding of form_key --- lib/internal/Magento/Framework/Data/Form/FormKey.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Data/Form/FormKey.php b/lib/internal/Magento/Framework/Data/Form/FormKey.php index 6a5485d7bb4f2..6b493d84816a7 100644 --- a/lib/internal/Magento/Framework/Data/Form/FormKey.php +++ b/lib/internal/Magento/Framework/Data/Form/FormKey.php @@ -22,16 +22,24 @@ class FormKey */ protected $session; + /** + * @var \Zend\Escaper\Escaper + */ + protected $escaper; + /** * @param \Magento\Framework\Math\Random $mathRandom * @param \Magento\Framework\Session\SessionManagerInterface $session + * @param \Zend\Escaper\Escaper $escaper */ public function __construct( \Magento\Framework\Math\Random $mathRandom, - \Magento\Framework\Session\SessionManagerInterface $session + \Magento\Framework\Session\SessionManagerInterface $session, + \Zend\Escaper\Escaper $escaper ) { $this->mathRandom = $mathRandom; $this->session = $session; + $this->escaper = $escaper; } /** @@ -44,7 +52,7 @@ public function getFormKey() if (!$this->isPresent()) { $this->set($this->mathRandom->getRandomString(16)); } - return $this->session->getData(self::FORM_KEY); + return $this->escaper->escapeHtmlAttr($this->session->getData(self::FORM_KEY)); } /** From bad65b873f5095bc68395e8fb1f39997da69f482 Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko Date: Wed, 13 Jan 2016 17:38:32 -0600 Subject: [PATCH 032/128] MAGETWO-47679: Remi PHP 7.0.1 failure on L1 segmentation fault on SOAP / REST --- .../Product/Attribute/Collection.php | 1 + .../CatalogSearch/Model/Indexer/Fulltext.php | 12 +- .../Indexer/Fulltext/Action/ClassTen.php | 823 ++++++++++++++++++ .../Model/Indexer/Fulltext/Action/Full.php | 127 ++- .../Indexer/Fulltext/Action/IndexIterator.php | 187 ++++ 5 files changed, 1067 insertions(+), 83 deletions(-) create mode 100644 app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/ClassTen.php create mode 100644 app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/IndexIterator.php diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Collection.php index 3f396b654f281..29c78ea2ff152 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Attribute/Collection.php @@ -39,6 +39,7 @@ public function __construct( ) { $this->_eavEntityFactory = $eavEntityFactory; parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $eavConfig, $connection, $resource); + $a = 10; } /** diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php index bad9d312c3235..c6c8cad564234 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php @@ -89,11 +89,7 @@ public function execute($ids) foreach ($storeIds as $storeId) { $dimension = $this->dimensionFactory->create(['name' => 'scope', 'value' => $storeId]); $saveHandler->deleteIndex([$dimension], new \ArrayObject($ids)); - $products = $this->fullAction->rebuildStoreIndex($storeId, $ids); - foreach ($products as $product) { - $saveHandler->saveIndex([$dimension], $product); - } - + $saveHandler->saveIndex([$dimension], $this->fullAction->rebuildStoreIndex($storeId, $ids)); } } @@ -112,10 +108,8 @@ public function executeFull() foreach ($storeIds as $storeId) { $dimension = $this->dimensionFactory->create(['name' => 'scope', 'value' => $storeId]); $saveHandler->cleanIndex([$dimension]); - $products = $this->fullAction->rebuildStoreIndex($storeId); - foreach ($products as $product) { - $saveHandler->saveIndex([$dimension], $product); - } + $saveHandler->saveIndex([$dimension], $this->fullAction->rebuildStoreIndex($storeId)); + } $this->fulltextResource->resetSearchResults(); $this->searchRequestConfig->reset(); diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/ClassTen.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/ClassTen.php new file mode 100644 index 0000000000000..cb62bb4765342 --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/ClassTen.php @@ -0,0 +1,823 @@ +resource = $resource; + $this->connection = $resource->getConnection(); + $this->catalogProductType = $catalogProductType; + $this->eavConfig = $eavConfig; + $this->searchRequestConfig = $searchRequestConfig; + $this->catalogProductStatus = $catalogProductStatus; + $this->productAttributeCollectionFactory = $prodAttributeCollectionFactory; + $this->eventManager = $eventManager; + $this->scopeConfig = $scopeConfig; + $this->storeManager = $storeManager; + $this->engine = $engineProvider->get(); + $configData = $indexerConfig->getIndexer(Fulltext::INDEXER_ID); + $this->indexHandler = $indexHandlerFactory->create(['data' => $configData]); + $this->dateTime = $dateTime; + $this->localeResolver = $localeResolver; + $this->localeDate = $localeDate; + $this->fulltextResource = $fulltextResource; + $this->dimensionFactory = $dimensionFactory; + } + + /** + * Return validated table name + * + * @param string|string[] $table + * @return string + */ + public function getTable($table) + { + return $this->resource->getTableName($table); + } + + /** + * Regenerate search index for all stores + * + * @param int|array|null $productIds + * @return void + */ + public function rebuildIndex($productIds = null) + { + $storeIds = array_keys($this->storeManager->getStores()); + foreach ($storeIds as $storeId) { + $dimension = $this->dimensionFactory->create(['name' => self::SCOPE_FIELD_NAME, 'value' => $storeId]); + $this->indexHandler->deleteIndex([$dimension], $this->getIterator($productIds)); + $products = $this->rebuildStoreIndex($storeId, $productIds); + foreach ($products as $product) { + $this->indexHandler->saveIndex([$dimension], $product); + } + + } + $this->fulltextResource->resetSearchResults(); + $this->searchRequestConfig->reset(); + } + + /** + * Get parents IDs of product IDs to be re-indexed + * + * @param int[] $entityIds + * @return int[] + */ + public function getProductIdsFromParents(array $entityIds) + { + return $this->connection + ->select() + ->from($this->getTable('catalog_product_relation'), 'parent_id') + ->distinct(true) + ->where('child_id IN (?)', $entityIds) + ->where('parent_id NOT IN (?)', $entityIds) + ->query() + ->fetchAll(\Zend_Db::FETCH_COLUMN); + } + + /** + * Regenerate search index for specific store + * + * @param int $storeId Store View Id + * @param int|array $productIds Product Entity Id + * @return \Generator + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function rebuildStoreIndex($storeId, $productIds = null) + { + $output = []; + if ($productIds !== null) { + $productIds = array_unique(array_merge($productIds, $this->getProductIdsFromParents($productIds))); + } + // prepare searchable attributes + $staticFields = []; + foreach ($this->getSearchableAttributes('static') as $attribute) { + $staticFields[] = $attribute->getAttributeCode(); + } + $dynamicFields = [ + 'int' => array_keys($this->getSearchableAttributes('int')), + 'varchar' => array_keys($this->getSearchableAttributes('varchar')), + 'text' => array_keys($this->getSearchableAttributes('text')), + 'decimal' => array_keys($this->getSearchableAttributes('decimal')), + 'datetime' => array_keys($this->getSearchableAttributes('datetime')), + ]; + + // status and visibility filter + $visibility = $this->getSearchableAttribute('visibility'); + $status = $this->getSearchableAttribute('status'); + $statusIds = $this->catalogProductStatus->getVisibleStatusIds(); + $allowedVisibility = $this->engine->getAllowedVisibility(); + + return $this->getIndexIterator( + $storeId, + $productIds, + $staticFields, + $dynamicFields, + $visibility, + $allowedVisibility, + $status, + $statusIds + ); + } + + /** + * Retrieve searchable products per store + * + * @param int $storeId + * @param array $staticFields + * @param array|int $productIds + * @param int $lastProductId + * @param int $limit + * @return array + */ + public function getSearchableProducts( + $storeId, + array $staticFields, + $productIds = null, + $lastProductId = 0, + $limit = 100 + ) { + $websiteId = $this->storeManager->getStore($storeId)->getWebsiteId(); + $select = $this->connection->select() + ->useStraightJoin(true) + ->from( + ['e' => $this->getTable('catalog_product_entity')], + array_merge(['entity_id', 'type_id'], $staticFields) + ) + ->join( + ['website' => $this->getTable('catalog_product_website')], + $this->connection->quoteInto('website.product_id = e.entity_id AND website.website_id = ?', $websiteId), + [] + ); + + if ($productIds !== null) { + $select->where('e.entity_id IN (?)', $productIds); + } + + $select->where('e.entity_id > ?', $lastProductId)->limit($limit)->order('e.entity_id'); + + $result = $this->connection->fetchAll($select); + + return $result; + } + + /** + * Clean search index data for store + * + * @param int $storeId + * @return void + */ + public function cleanIndex($storeId) + { + $dimension = $this->dimensionFactory->create(['name' => self::SCOPE_FIELD_NAME, 'value' => $storeId]); + $this->indexHandler->cleanIndex([$dimension]); + } + + /** + * Delete search index data for store + * + * @param int $storeId Store View Id + * @param array $productIds Product Entity Id + * @return void + */ + public function deleteIndex($storeId = null, $productIds = null) + { + $dimension = $this->dimensionFactory->create(['name' => self::SCOPE_FIELD_NAME, 'value' => $storeId]); + $this->indexHandler->deleteIndex([$dimension], $this->getIterator($productIds)); + } + + /** + * Retrieve EAV Config Singleton + * + * @return \Magento\Eav\Model\Config + */ + public function getEavConfig() + { + return $this->eavConfig; + } + + /** + * Retrieve searchable attributes + * + * @param string $backendType + * @return \Magento\Eav\Model\Entity\Attribute[] + */ + public function getSearchableAttributes($backendType = null) + { + if (null === $this->searchableAttributes) { + $this->searchableAttributes = []; + + $productAttributes = $this->productAttributeCollectionFactory->create(); + $productAttributes->addToIndexFilter(true); + + /** @var \Magento\Eav\Model\Entity\Attribute[] $attributes */ + $attributes = $productAttributes->getItems(); + + $this->eventManager->dispatch( + 'catelogsearch_searchable_attributes_load_after', + ['engine' => $this->engine, 'attributes' => $attributes] + ); + + $entity = $this->getEavConfig()->getEntityType(\Magento\Catalog\Model\Product::ENTITY)->getEntity(); + + foreach ($attributes as $attribute) { + $attribute->setEntity($entity); + } + + $this->searchableAttributes = $attributes; + } + + if ($backendType !== null) { + $attributes = []; + foreach ($this->searchableAttributes as $attributeId => $attribute) { + if ($attribute->getBackendType() == $backendType) { + $attributes[$attributeId] = $attribute; + } + } + + return $attributes; + } + + return $this->searchableAttributes; + } + + /** + * Retrieve searchable attribute by Id or code + * + * @param int|string $attribute + * @return \Magento\Eav\Model\Entity\Attribute + */ + public function getSearchableAttribute($attribute) + { + $attributes = $this->getSearchableAttributes(); + if (is_numeric($attribute)) { + if (isset($attributes[$attribute])) { + return $attributes[$attribute]; + } + } elseif (is_string($attribute)) { + foreach ($attributes as $attributeModel) { + if ($attributeModel->getAttributeCode() == $attribute) { + return $attributeModel; + } + } + } + + return $this->getEavConfig()->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attribute); + } + + /** + * Returns expression for field unification + * + * @param string $field + * @param string $backendType + * @return \Zend_Db_Expr + */ + public function unifyField($field, $backendType = 'varchar') + { + if ($backendType == 'datetime') { + $expr = $this->connection->getDateFormatSql($field, '%Y-%m-%d %H:%i:%s'); + } else { + $expr = $field; + } + return $expr; + } + + /** + * Load product(s) attributes + * + * @param int $storeId + * @param array $productIds + * @param array $attributeTypes + * @return array + */ + public function getProductAttributes($storeId, array $productIds, array $attributeTypes) + { + $result = []; + $selects = []; + $ifStoreValue = $this->connection->getCheckSql('t_store.value_id > 0', 't_store.value', 't_default.value'); + foreach ($attributeTypes as $backendType => $attributeIds) { + if ($attributeIds) { + $tableName = $this->getTable('catalog_product_entity_' . $backendType); + $selects[] = $this->connection->select()->from( + ['t_default' => $tableName], + ['entity_id', 'attribute_id'] + )->joinLeft( + ['t_store' => $tableName], + $this->connection->quoteInto( + 't_default.entity_id=t_store.entity_id' . + ' AND t_default.attribute_id=t_store.attribute_id' . + ' AND t_store.store_id = ?', + $storeId + ), + ['value' => $this->unifyField($ifStoreValue, $backendType)] + )->where( + 't_default.store_id = ?', + 0 + )->where( + 't_default.attribute_id IN (?)', + $attributeIds + )->where( + 't_default.entity_id IN (?)', + $productIds + ); + } + } + + if ($selects) { + $select = $this->connection->select()->union($selects, \Magento\Framework\DB\Select::SQL_UNION_ALL); + $query = $this->connection->query($select); + while ($row = $query->fetch()) { + $result[$row['entity_id']][$row['attribute_id']] = $row['value']; + } + } + + return $result; + } + + /** + * Retrieve Product Type Instance + * + * @param string $typeId + * @return \Magento\Catalog\Model\Product\Type\AbstractType + */ + public function getProductTypeInstance($typeId) + { + if (!isset($this->productTypes[$typeId])) { + $productEmulator = $this->getProductEmulator($typeId); + + $this->productTypes[$typeId] = $this->catalogProductType->factory($productEmulator); + } + return $this->productTypes[$typeId]; + } + + /** + * Return all product children ids + * + * @param int $productId Product Entity Id + * @param string $typeId Super Product Link Type + * @return array|null + */ + public function getProductChildIds($productId, $typeId) + { + $typeInstance = $this->getProductTypeInstance($typeId); + $relation = $typeInstance->isComposite( + $this->getProductEmulator($typeId) + ) ? $typeInstance->getRelationInfo() : false; + + if ($relation && $relation->getTable() && $relation->getParentFieldName() && $relation->getChildFieldName()) { + $select = $this->connection->select()->from( + ['main' => $this->getTable($relation->getTable())], + [$relation->getChildFieldName()] + )->where( + $relation->getParentFieldName() . ' = ?', + $productId + ); + if ($relation->getWhere() !== null) { + $select->where($relation->getWhere()); + } + return $this->connection->fetchCol($select); + } + + return null; + } + + /** + * Retrieve Product Emulator (Magento Object) + * + * @param string $typeId + * @return \Magento\Framework\DataObject + */ + public function getProductEmulator($typeId) + { + if (!isset($this->productEmulators[$typeId])) { + $productEmulator = new \Magento\Framework\DataObject(); + $productEmulator->setTypeId($typeId); + $this->productEmulators[$typeId] = $productEmulator; + } + return $this->productEmulators[$typeId]; + } + + /** + * Prepare Fulltext index value for product + * + * @param array $indexData + * @param array $productData + * @param int $storeId + * @return string + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + public function prepareProductIndex($indexData, $productData, $storeId) + { + $index = []; + + foreach ($this->getSearchableAttributes('static') as $attribute) { + $attributeCode = $attribute->getAttributeCode(); + + if (isset($productData[$attributeCode])) { + + if ('store_id' === $attributeCode) { + continue; + } + + $value = $this->getAttributeValue($attribute->getId(), $productData[$attributeCode], $storeId); + if ($value) { + if (isset($index[$attribute->getId()])) { + if (!is_array($index[$attribute->getId()])) { + $index[$attribute->getId()] = [$index[$attribute->getId()]]; + } + $index[$attribute->getId()][] = $value; + } else { + $index[$attribute->getId()] = $value; + } + } + } + } + + foreach ($indexData as $entityId => $attributeData) { + foreach ($attributeData as $attributeId => $attributeValue) { + $value = $this->getAttributeValue($attributeId, $attributeValue, $storeId); + if (!empty($value)) { + if (isset($index[$attributeId])) { + $index[$attributeId][$entityId] = $value; + } else { + $index[$attributeId] = [$entityId => $value]; + } + } + } + } + + $product = $this->getProductEmulator( + $productData['type_id'] + )->setId( + $productData['entity_id'] + )->setStoreId( + $storeId + ); + $typeInstance = $this->getProductTypeInstance($productData['type_id']); + $data = $typeInstance->getSearchableData($product); + if ($data) { + $index['options'] = $data; + } + + return $this->engine->prepareEntityIndex($index, $this->separator); + } + + /** + * Retrieve attribute source value for search + * + * @param int $attributeId + * @param mixed $valueId + * @param int $storeId + * @return mixed + */ + public function getAttributeValue($attributeId, $valueId, $storeId) + { + $attribute = $this->getSearchableAttribute($attributeId); + $value = $this->engine->processAttributeValue($attribute, $valueId); + + if (false !== $value + && $attribute->getIsSearchable() + && $attribute->usesSource() + && $this->engine->allowAdvancedIndex() + ) { + $attribute->setStoreId($storeId); + + $valueText = (array) $attribute->getSource()->getIndexOptionText($valueId); + + $pieces = array_filter(array_merge([$value], $valueText)); + + $value = implode($this->separator, $pieces); + } + + $value = preg_replace('/\\s+/siu', ' ', trim(strip_tags($value))); + + return $value; + } + + /** + * Retrieve Date value for store + * + * @param int $storeId + * @param string $date + * @return string|null + */ + public function getStoreDate($storeId, $date = null) + { + if (!isset($this->dates[$storeId])) { + $timezone = $this->scopeConfig->getValue( + $this->localeDate->getDefaultTimezonePath(), + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $storeId + ); + + $this->localeResolver->emulate($storeId); + + $dateObj = new \DateTime(); + $dateObj->setTimezone(new \DateTimeZone($timezone)); + $this->dates[$storeId] = $dateObj; + + $this->localeResolver->revert(); + } + + if (!$this->dateTime->isEmptyDate($date)) { + /** @var \DateTime $dateObj */ + $dateObj = $this->dates[$storeId]; + return $this->localeDate->formatDateTime($dateObj, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::NONE); + } + + return null; + } + + /** + * Get iterator + * + * @param array $data + * @return \Generator + */ + public function getIterator(array $data) + { + foreach ($data as $key => $value) { + yield $key => $value; + } + } + + /** + * @param $storeId + * @param $productIds + * @param $staticFields + * @param $dynamicFields + * @param $visibility + * @param $allowedVisibility + * @param $status + * @param $statusIds + * @param $output + * @return \Iterator + */ + public function getIndexIterator( + $storeId, + $productIds, + $staticFields, + $dynamicFields, + $visibility, + $allowedVisibility, + $status, + $statusIds + ) { + $lastProductId = 0; + while (true) { + $products = $this->getSearchableProducts($storeId, $staticFields, $productIds, $lastProductId); + if (!$products) { + break; + } + + $productAttributes = []; + $productRelations = []; + foreach ($products as $productData) { + $lastProductId = $productData['entity_id']; + $productAttributes[$productData['entity_id']] = $productData['entity_id']; + $productChildren = $this->getProductChildIds($productData['entity_id'], $productData['type_id']); + $productRelations[$productData['entity_id']] = $productChildren; + if ($productChildren) { + foreach ($productChildren as $productChildId) { + $productAttributes[$productChildId] = $productChildId; + } + } + } + + $productAttributes = $this->getProductAttributes($storeId, $productAttributes, $dynamicFields); + foreach ($products as $productData) { + if (!isset($productAttributes[$productData['entity_id']])) { + continue; + } + + $productAttr = $productAttributes[$productData['entity_id']]; + if (!isset($productAttr[$visibility->getId()]) + || !in_array($productAttr[$visibility->getId()], $allowedVisibility) + ) { + continue; + } + if (!isset($productAttr[$status->getId()]) + || !in_array($productAttr[$status->getId()], $statusIds) + ) { + continue; + } + + $productIndex = [$productData['entity_id'] => $productAttr]; + + $hasChildren = false; + $productChildren = $productRelations[$productData['entity_id']]; + if ($productChildren) { + foreach ($productChildren as $productChildId) { + if (isset($productAttributes[$productChildId])) { + $productChildAttr = $productAttributes[$productChildId]; + if (!isset($productChildAttr[$status->getId()]) + || !in_array($productChildAttr[$status->getId()], $statusIds) + ) { + continue; + } + + $hasChildren = true; + $productIndex[$productChildId] = $productChildAttr; + } + } + } + if ($productChildren !== null && !$hasChildren) { + continue; + } + + $index = $this->prepareProductIndex($productIndex, $productData, $storeId); + + yield [$productData['entity_id'] => $index]; + } + } + } +} diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php index 803c3f61f7abf..9ea927eeec4df 100644 --- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/Full.php @@ -151,6 +151,11 @@ class Full */ protected $connection; + /** + * @var \Magento\CatalogSearch\Model\Indexer\Fulltext\Action\IndexIteratorFactory + */ + private $iteratorFactory; + /** * @param ResourceConnection $resource * @param \Magento\Catalog\Model\Product\Type $catalogProductType @@ -188,7 +193,8 @@ public function __construct( \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\CatalogSearch\Model\ResourceModel\Fulltext $fulltextResource, \Magento\Framework\Search\Request\DimensionFactory $dimensionFactory, - \Magento\Framework\Indexer\ConfigInterface $indexerConfig + \Magento\Framework\Indexer\ConfigInterface $indexerConfig, + \Magento\CatalogSearch\Model\Indexer\Fulltext\Action\IndexIteratorFactory $classTenFactory ) { $this->resource = $resource; $this->connection = $resource->getConnection(); @@ -208,6 +214,7 @@ public function __construct( $this->localeDate = $localeDate; $this->fulltextResource = $fulltextResource; $this->dimensionFactory = $dimensionFactory; + $this->iteratorFactory = $classTenFactory; } /** @@ -248,11 +255,7 @@ protected function rebuildIndex($productIds = null) foreach ($storeIds as $storeId) { $dimension = $this->dimensionFactory->create(['name' => self::SCOPE_FIELD_NAME, 'value' => $storeId]); $this->indexHandler->deleteIndex([$dimension], $this->getIterator($productIds)); - $products = $this->rebuildStoreIndex($storeId, $productIds); - foreach ($products as $product) { - $this->indexHandler->saveIndex([$dimension], $product); - } - + $this->indexHandler->saveIndex([$dimension], $this->rebuildStoreIndex($storeId, $productIds)); } $this->fulltextResource->resetSearchResults(); $this->searchRequestConfig->reset(); @@ -311,74 +314,16 @@ public function rebuildStoreIndex($storeId, $productIds = null) $statusIds = $this->catalogProductStatus->getVisibleStatusIds(); $allowedVisibility = $this->engine->getAllowedVisibility(); - $lastProductId = 0; - while (true) { - $products = $this->getSearchableProducts($storeId, $staticFields, $productIds, $lastProductId); - if (!$products) { - break; - } - - $productAttributes = []; - $productRelations = []; - foreach ($products as $productData) { - $lastProductId = $productData['entity_id']; - $productAttributes[$productData['entity_id']] = $productData['entity_id']; - $productChildren = $this->getProductChildIds($productData['entity_id'], $productData['type_id']); - $productRelations[$productData['entity_id']] = $productChildren; - if ($productChildren) { - foreach ($productChildren as $productChildId) { - $productAttributes[$productChildId] = $productChildId; - } - } - } - - $productAttributes = $this->getProductAttributes($storeId, $productAttributes, $dynamicFields); - foreach ($products as $productData) { - if (!isset($productAttributes[$productData['entity_id']])) { - continue; - } - - $productAttr = $productAttributes[$productData['entity_id']]; - if (!isset($productAttr[$visibility->getId()]) - || !in_array($productAttr[$visibility->getId()], $allowedVisibility) - ) { - continue; - } - if (!isset($productAttr[$status->getId()]) - || !in_array($productAttr[$status->getId()], $statusIds) - ) { - continue; - } - - $productIndex = [$productData['entity_id'] => $productAttr]; - - $hasChildren = false; - $productChildren = $productRelations[$productData['entity_id']]; - if ($productChildren) { - foreach ($productChildren as $productChildId) { - if (isset($productAttributes[$productChildId])) { - $productChildAttr = $productAttributes[$productChildId]; - if (!isset($productChildAttr[$status->getId()]) - || !in_array($productChildAttr[$status->getId()], $statusIds) - ) { - continue; - } - - $hasChildren = true; - $productIndex[$productChildId] = $productChildAttr; - } - } - } - if ($productChildren !== null && !$hasChildren) { - continue; - } - - $index = $this->prepareProductIndex($productIndex, $productData, $storeId); - - $output[] = new \ArrayObject([$productData['entity_id'] => $index]); - } - } - return $output; + return $this->getIndexIterator( + $storeId, + $productIds, + $staticFields, + $dynamicFields, + $visibility, + $allowedVisibility, + $status, + $statusIds + ); } /** @@ -802,4 +747,38 @@ protected function getIterator(array $data) yield $key => $value; } } + + /** + * @param $storeId + * @param $productIds + * @param $staticFields + * @param $dynamicFields + * @param $visibility + * @param $allowedVisibility + * @param $status + * @param $statusIds + * @param $output + * @return \Iterator + */ + protected function getIndexIterator( + $storeId, + $productIds, + $staticFields, + $dynamicFields, + $visibility, + $allowedVisibility, + $status, + $statusIds + ) { + return $this->iteratorFactory->create([ + 'storeId' => $storeId, + 'productIds' => $productIds, + 'staticFields' => $staticFields, + 'dynamicFields' => $dynamicFields, + 'visibility' => $visibility, + 'allowedVisibility' => $allowedVisibility, + 'status' => $status, + 'statusIds' => $statusIds + ]); + } } diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/IndexIterator.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/IndexIterator.php new file mode 100644 index 0000000000000..3bedb665a9b5f --- /dev/null +++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext/Action/IndexIterator.php @@ -0,0 +1,187 @@ +dataProvider = $dataProvider; + $this->storeId = $storeId; + $this->staticFields = $staticFields; + $this->productIds = $productIds; + $this->dynamicFields = $dynamicFields; + $this->visibility = $visibility; + $this->allowedVisibility = $allowedVisibility; + $this->status = $status; + $this->statusIds = $statusIds; + } + + + /** + * @inheritDoc + */ + public function current() + { + return $this->current; + } + + /** + * @inheritDoc + */ + public function next() + { + \next($this->products); + if (\key($this->products) === null) { + //check if storage has more items to process + $this->products = $this->dataProvider->getSearchableProducts( + $this->storeId, + $this->staticFields, + $this->productIds, + $this->lastProductId + ); + + if(!count($this->products)) { + $this->isValid = false; + return; + } + + + $productAttributes = []; + $this->productRelations = []; + foreach ($this->products as $productData) { + $this->lastProductId = $productData['entity_id']; + $productAttributes[$productData['entity_id']] = $productData['entity_id']; + $productChildren = $this->dataProvider->getProductChildIds($productData['entity_id'], $productData['type_id']); + $this->productRelations[$productData['entity_id']] = $productChildren; + if ($productChildren) { + foreach ($productChildren as $productChildId) { + $productAttributes[$productChildId] = $productChildId; + } + } + } + + $this->productAttributes = $this->dataProvider->getProductAttributes($this->storeId, $productAttributes, $this->dynamicFields); + } + + $productData = \current($this->products); + + if (!isset($this->productAttributes[$productData['entity_id']])) { + $this->next(); + } + + $productAttr = $this->productAttributes[$productData['entity_id']]; + if (!isset($productAttr[$this->visibility->getId()]) + || !in_array($productAttr[$this->visibility->getId()], $this->allowedVisibility) + ) { + $this->next(); + } + if (!isset($productAttr[$this->status->getId()]) + || !in_array($productAttr[$this->status->getId()], $this->statusIds) + ) { + $this->next(); + } + + $productIndex = [$productData['entity_id'] => $productAttr]; + + $hasChildren = false; + $productChildren = $this->productRelations[$productData['entity_id']]; + if ($productChildren) { + foreach ($productChildren as $productChildId) { + if (isset($productAttributes[$productChildId])) { + $productChildAttr = $productAttributes[$productChildId]; + if (!isset($productChildAttr[$this->status->getId()]) + || !in_array($productChildAttr[$this->status->getId()], $this->statusIds) + ) { + continue; + } + + $hasChildren = true; + $productIndex[$productChildId] = $productChildAttr; + } + } + } + if ($productChildren !== null && !$hasChildren) { + $this->next(); + } + + $index = $this->dataProvider->prepareProductIndex($productIndex, $productData, $this->storeId); + + $this->current = $index; + $this->key = $productData['entity_id']; + } + + /** + * @inheritDoc + */ + public function key() + { + return $this->key; + } + + /** + * @inheritDoc + */ + public function valid() + { + return $this->isValid; + } + + /** + * @inheritDoc + */ + public function rewind() + { + $this->lastProductId = 0; + $this->key = null; + $this->current = null; + unset($this->products); + $this->products = []; + $this->next(); + } +} \ No newline at end of file From 0753caf18fb24eb2f96ae0a945b4288dfffb757f Mon Sep 17 00:00:00 2001 From: Oleksii Korshenko Date: Wed, 13 Jan 2016 17:51:05 -0600 Subject: [PATCH 033/128] MAGETWO-47679: Remi PHP 7.0.1 failure on L1 segmentation fault on SOAP / REST --- .../Test/Unit/Model/Indexer/FulltextTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/FulltextTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/FulltextTest.php index 54e654c91cf41..962bc1f6d7c61 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/FulltextTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/FulltextTest.php @@ -120,10 +120,10 @@ public function testExecute() $indexData = new \ArrayObject([]); $this->storeManager->expects($this->once())->method('getStores')->willReturn($stores); $this->saveHandler->expects($this->exactly(count($stores)))->method('deleteIndex'); - $this->saveHandler->expects($this->exactly(4))->method('saveIndex'); + $this->saveHandler->expects($this->exactly(2))->method('saveIndex'); $this->fullAction->expects($this->exactly(2)) ->method('rebuildStoreIndex') - ->willReturn([$indexData, $indexData]); + ->willReturn(new \ArrayObject([$indexData, $indexData])); $this->model->execute($ids); } @@ -134,10 +134,10 @@ public function testExecuteFull() $indexData = new \ArrayObject([]); $this->storeManager->expects($this->once())->method('getStores')->willReturn($stores); $this->saveHandler->expects($this->exactly(count($stores)))->method('cleanIndex'); - $this->saveHandler->expects($this->exactly(4))->method('saveIndex'); + $this->saveHandler->expects($this->exactly(2))->method('saveIndex'); $this->fullAction->expects($this->exactly(2)) ->method('rebuildStoreIndex') - ->willReturn([$indexData, $indexData]); + ->willReturn(new \ArrayObject([$indexData, $indexData])); $this->fulltextResource->expects($this->once())->method('resetSearchResults'); $this->searchRequestConfig->expects($this->once())->method('reset'); @@ -151,10 +151,10 @@ public function testExecuteList() $indexData = new \ArrayObject([]); $this->storeManager->expects($this->once())->method('getStores')->willReturn($stores); $this->saveHandler->expects($this->exactly(count($stores)))->method('deleteIndex'); - $this->saveHandler->expects($this->exactly(4))->method('saveIndex'); + $this->saveHandler->expects($this->exactly(2))->method('saveIndex'); $this->fullAction->expects($this->exactly(2)) ->method('rebuildStoreIndex') - ->willReturn([$indexData, $indexData]); + ->willReturn(new \ArrayObject([$indexData, $indexData])); $this->model->executeList($ids); } @@ -166,10 +166,10 @@ public function testExecuteRow() $indexData = new \ArrayObject([]); $this->storeManager->expects($this->once())->method('getStores')->willReturn($stores); $this->saveHandler->expects($this->exactly(count($stores)))->method('deleteIndex'); - $this->saveHandler->expects($this->exactly(4))->method('saveIndex'); + $this->saveHandler->expects($this->exactly(2))->method('saveIndex'); $this->fullAction->expects($this->exactly(2)) ->method('rebuildStoreIndex') - ->willReturn([$indexData, $indexData]); + ->willReturn(new \ArrayObject([$indexData, $indexData])); $this->model->executeRow($id); } From 36bff7af50b3f2b8594f5c3d5e5ccf8c6906d5d3 Mon Sep 17 00:00:00 2001 From: Yaroslav Onischenko Date: Thu, 14 Jan 2016 10:56:13 +0200 Subject: [PATCH 034/128] MAGETWO-47082: Category creation from product page fails if google experiments enabled --- .../adminhtml/web/js/new-category-dialog.js | 44 +++++++++--- .../AddGoogleExperimentFieldsObserver.php | 72 +++++++++++++++++++ .../Magento/GoogleOptimizer/etc/events.xml | 3 + .../AddGoogleExperimentFieldsObserverTest.php | 67 +++++++++++++++++ 4 files changed, 175 insertions(+), 11 deletions(-) create mode 100644 app/code/Magento/GoogleOptimizer/Observer/Block/Category/AddGoogleExperimentFieldsObserver.php create mode 100644 dev/tests/integration/testsuite/Magento/GoogleOptimizer/Observer/Block/Category/AddGoogleExperimentFieldsObserverTest.php diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/new-category-dialog.js b/app/code/Magento/Catalog/view/adminhtml/web/js/new-category-dialog.js index 44f3371cf9371..7bc01bfccb8ea 100644 --- a/app/code/Magento/Catalog/view/adminhtml/web/js/new-category-dialog.js +++ b/app/code/Magento/Catalog/view/adminhtml/web/js/new-category-dialog.js @@ -83,20 +83,42 @@ define([ var thisButton = $(e.currentTarget); thisButton.prop('disabled', true); + + var postData = { + general: { + name: $('#new_category_name').val(), + is_active: 1, + include_in_menu: 1 + }, + parent: $('#new_category_parent').val(), + use_config: ['available_sort_by', 'default_sort_by'], + form_key: FORM_KEY, + return_session_messages_only: 1 + }; + + var fields = {}; + + $.each($(newCategoryForm).serializeArray(), function(_, field) { + if ( + field.name && + field.name != 'new_category_name' && + field.name != 'new_category_parent' + ) { + if (fields.hasOwnProperty(field.name)) { + fields[field.name] = $.makeArray(fields[field.name]); + fields[field.name].push(field.value); + } + else { + fields[field.name] = field.value; + } + } + }); + $.extend(postData, fields); + $.ajax({ type: 'POST', url: widget.options.saveCategoryUrl, - data: { - general: { - name: $('#new_category_name').val(), - is_active: 1, - include_in_menu: 1 - }, - parent: $('#new_category_parent').val(), - use_config: ['available_sort_by', 'default_sort_by'], - form_key: FORM_KEY, - return_session_messages_only: 1 - }, + data: postData, dataType: 'json', context: $('body') }).success(function (data) { diff --git a/app/code/Magento/GoogleOptimizer/Observer/Block/Category/AddGoogleExperimentFieldsObserver.php b/app/code/Magento/GoogleOptimizer/Observer/Block/Category/AddGoogleExperimentFieldsObserver.php new file mode 100644 index 0000000000000..fe6fc525e044f --- /dev/null +++ b/app/code/Magento/GoogleOptimizer/Observer/Block/Category/AddGoogleExperimentFieldsObserver.php @@ -0,0 +1,72 @@ +dataHelper = $dataHelper; + } + + /** + * Adds Google Experiment fields to category creation form on product edit page + * + * @param EventObserver $observer + * @return void + */ + public function execute(EventObserver $observer) + { + if ($this->dataHelper->isGoogleExperimentActive()) { + $block = $observer->getEvent()->getBlock(); + if ($block->getForm() && $block->getForm()->getId() == 'new_category_form') { + $fieldset = $block->getForm()->getElement('new_category_form_fieldset'); + $fieldset->addField( + 'experiment_script', + 'textarea', + [ + 'name' => 'google_experiment[experiment_script]', + 'label' => __('Experiment Code'), + 'value' => '', + 'class' => 'textarea googleoptimizer', + 'required' => false, + 'note' => __('Experiment code should be added to the original page only.') + ] + ); + + $fieldset->addField( + 'code_id', + 'hidden', + [ + 'name' => 'google_experiment[code_id]', + 'value' => '', + 'required' => false + ] + ); + } + } + } +} diff --git a/app/code/Magento/GoogleOptimizer/etc/events.xml b/app/code/Magento/GoogleOptimizer/etc/events.xml index bb71f28673684..3595289a987aa 100644 --- a/app/code/Magento/GoogleOptimizer/etc/events.xml +++ b/app/code/Magento/GoogleOptimizer/etc/events.xml @@ -27,4 +27,7 @@ + + + diff --git a/dev/tests/integration/testsuite/Magento/GoogleOptimizer/Observer/Block/Category/AddGoogleExperimentFieldsObserverTest.php b/dev/tests/integration/testsuite/Magento/GoogleOptimizer/Observer/Block/Category/AddGoogleExperimentFieldsObserverTest.php new file mode 100644 index 0000000000000..319d9909682f5 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/GoogleOptimizer/Observer/Block/Category/AddGoogleExperimentFieldsObserverTest.php @@ -0,0 +1,67 @@ +objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->config = $this->objectManager->create( + 'Magento\Config\Model\ResourceModel\Config' + ); + $this->config->saveConfig('google/analytics/active', 1, 'default', 0); + $this->config->saveConfig('google/analytics/type', 'universal', 'default', 0); + $this->config->saveConfig('google/analytics/experiments', 1, 'default', 0); + $this->config->saveConfig('google/analytics/account', 1234567890, 'default', 0); + $this->resetConfig(); + } + + /** + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled + */ + public function testExecute() + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + /** @var \Magento\Catalog\Block\Adminhtml\Product\Edit\NewCategory $newCategoryForm */ + $newCategoryForm = $objectManager->get('Magento\Catalog\Block\Adminhtml\Product\Edit\NewCategory'); + $html = $newCategoryForm->toHtml(); + $this->assertContains('name="google_experiment[code_id]"', $html); + $this->assertContains('name="google_experiment[experiment_script]"', $html); + } + + protected function tearDown() + { + $this->config->deleteConfig('google/analytics/active', 'default', 0); + $this->config->deleteConfig('google/analytics/type', 'default', 0); + $this->config->deleteConfig('google/analytics/experiments', 'default', 0); + $this->config->deleteConfig('google/analytics/account', 'default', 0); + $this->resetConfig(); + } + + /** + * Clear config cache + */ + protected function resetConfig() + { + $this->objectManager->get('Magento\Framework\App\Config\ReinitableConfigInterface')->reinit(); + } +} From e7abf62dfd7daf4fb0baad4ee516b24e029c7382 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov Date: Thu, 14 Jan 2016 11:15:04 +0200 Subject: [PATCH 035/128] MAGETWO-46478: Frontend CAPTCHA Bypass --- .../Framework/Event/Config/Converter.php | 2 +- .../Magento/Framework/Event/Manager.php | 20 ++---- .../Event/Test/Unit/Config/ConverterTest.php | 33 +++++---- .../Test/Unit/Config/_files/event_config.php | 3 + .../Test/Unit/Config/_files/event_config.xml | 3 + .../Framework/Event/Test/Unit/ManagerTest.php | 71 ++++++++++--------- 6 files changed, 73 insertions(+), 59 deletions(-) diff --git a/lib/internal/Magento/Framework/Event/Config/Converter.php b/lib/internal/Magento/Framework/Event/Config/Converter.php index c06372a5c0732..f979ccedb1a36 100644 --- a/lib/internal/Magento/Framework/Event/Config/Converter.php +++ b/lib/internal/Magento/Framework/Event/Config/Converter.php @@ -38,7 +38,7 @@ public function convert($source) $config['name'] = $observerNameNode->nodeValue; $eventObservers[$observerNameNode->nodeValue] = $config; } - $output[$eventName] = $eventObservers; + $output[mb_strtolower($eventName)] = $eventObservers; } return $output; } diff --git a/lib/internal/Magento/Framework/Event/Manager.php b/lib/internal/Magento/Framework/Event/Manager.php index 7f6916ddf1dc3..237cd1586577d 100644 --- a/lib/internal/Magento/Framework/Event/Manager.php +++ b/lib/internal/Magento/Framework/Event/Manager.php @@ -10,26 +10,19 @@ class Manager implements ManagerInterface { - /** - * Events cache - * - * @var array - */ - protected $_events = []; - /** * Event invoker * * @var InvokerInterface */ - protected $_invoker; + protected $invoker; /** * Event config * * @var ConfigInterface */ - protected $_eventConfig; + protected $eventConfig; /** * @param InvokerInterface $invoker @@ -37,8 +30,8 @@ class Manager implements ManagerInterface */ public function __construct(InvokerInterface $invoker, ConfigInterface $eventConfig) { - $this->_invoker = $invoker; - $this->_eventConfig = $eventConfig; + $this->invoker = $invoker; + $this->eventConfig = $eventConfig; } /** @@ -53,8 +46,9 @@ public function __construct(InvokerInterface $invoker, ConfigInterface $eventCon */ public function dispatch($eventName, array $data = []) { + $eventName = mb_strtolower($eventName); \Magento\Framework\Profiler::start('EVENT:' . $eventName, ['group' => 'EVENT', 'name' => $eventName]); - foreach ($this->_eventConfig->getObservers($eventName) as $observerConfig) { + foreach ($this->eventConfig->getObservers($eventName) as $observerConfig) { $event = new \Magento\Framework\Event($data); $event->setName($eventName); @@ -62,7 +56,7 @@ public function dispatch($eventName, array $data = []) $wrapper->setData(array_merge(['event' => $event], $data)); \Magento\Framework\Profiler::start('OBSERVER:' . $observerConfig['name']); - $this->_invoker->dispatch($observerConfig, $wrapper); + $this->invoker->dispatch($observerConfig, $wrapper); \Magento\Framework\Profiler::stop('OBSERVER:' . $observerConfig['name']); } \Magento\Framework\Profiler::stop('EVENT:' . $eventName); diff --git a/lib/internal/Magento/Framework/Event/Test/Unit/Config/ConverterTest.php b/lib/internal/Magento/Framework/Event/Test/Unit/Config/ConverterTest.php index e0c9593e5cf21..91bade40692c8 100644 --- a/lib/internal/Magento/Framework/Event/Test/Unit/Config/ConverterTest.php +++ b/lib/internal/Magento/Framework/Event/Test/Unit/Config/ConverterTest.php @@ -5,35 +5,44 @@ */ namespace Magento\Framework\Event\Test\Unit\Config; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\Event\Config\Converter; + class ConverterTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\Framework\Event\Config\Converter + * @var Converter */ - protected $_model; + protected $model; /** * @var string */ - protected $_filePath; + protected $filePath; /** * @var \DOMDocument */ - protected $_source; + protected $source; + + /** + * @var ObjectManagerHelper + */ + protected $objectManagerHelper; protected function setUp() { - $this->_filePath = __DIR__ . '/_files/'; - $this->_source = new \DOMDocument(); - $this->_model = new \Magento\Framework\Event\Config\Converter(); + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->filePath = __DIR__ . '/_files/'; + $this->source = new \DOMDocument(); + $this->model = $this->objectManagerHelper->getObject(Converter::class); } public function testConvert() { - $this->_source->loadXML(file_get_contents($this->_filePath . 'event_config.xml')); - $convertedFile = include $this->_filePath . 'event_config.php'; - $this->assertEquals($convertedFile, $this->_model->convert($this->_source)); + $this->source->loadXML(file_get_contents($this->filePath . 'event_config.xml')); + $convertedFile = include $this->filePath . 'event_config.php'; + $this->assertEquals($convertedFile, $this->model->convert($this->source)); } /** @@ -42,7 +51,7 @@ public function testConvert() */ public function testConvertThrowsExceptionWhenDomIsInvalid() { - $this->_source->loadXML(file_get_contents($this->_filePath . 'event_invalid_config.xml')); - $this->_model->convert($this->_source); + $this->source->loadXML(file_get_contents($this->filePath . 'event_invalid_config.xml')); + $this->model->convert($this->source); } } diff --git a/lib/internal/Magento/Framework/Event/Test/Unit/Config/_files/event_config.php b/lib/internal/Magento/Framework/Event/Test/Unit/Config/_files/event_config.php index 141b0b4b927db..88d9961b928d2 100644 --- a/lib/internal/Magento/Framework/Event/Test/Unit/Config/_files/event_config.php +++ b/lib/internal/Magento/Framework/Event/Test/Unit/Config/_files/event_config.php @@ -15,5 +15,8 @@ 'shared' => false, 'name' => 'observer_2', ], + ], + 'some_eventname' => [ + 'observer_3' => ['instance' => 'instance_3', 'name' => 'observer_3'], ] ]; diff --git a/lib/internal/Magento/Framework/Event/Test/Unit/Config/_files/event_config.xml b/lib/internal/Magento/Framework/Event/Test/Unit/Config/_files/event_config.xml index 87dcbc0d45972..228fa6b5251b8 100644 --- a/lib/internal/Magento/Framework/Event/Test/Unit/Config/_files/event_config.xml +++ b/lib/internal/Magento/Framework/Event/Test/Unit/Config/_files/event_config.xml @@ -13,4 +13,7 @@ + + + \ No newline at end of file diff --git a/lib/internal/Magento/Framework/Event/Test/Unit/ManagerTest.php b/lib/internal/Magento/Framework/Event/Test/Unit/ManagerTest.php index 6c519bc6fbbe3..43f79df53c2d9 100644 --- a/lib/internal/Magento/Framework/Event/Test/Unit/ManagerTest.php +++ b/lib/internal/Magento/Framework/Event/Test/Unit/ManagerTest.php @@ -5,6 +5,11 @@ */ namespace Magento\Framework\Event\Test\Unit; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; +use Magento\Framework\Event\InvokerInterface; +use Magento\Framework\Event\ConfigInterface; +use Magento\Framework\Event\Manager as EventManager; + /** * Class ManagerTest * @@ -15,74 +20,74 @@ class ManagerTest extends \PHPUnit_Framework_TestCase /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_invoker; + protected $invokerMock; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_eventFactory; + protected $eventFactory; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_event; + protected $event; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_wrapperFactory; + protected $wrapperFactory; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_observer; + protected $observer; /** * @var \PHPUnit_Framework_MockObject_MockObject */ - protected $_eventConfigMock; + protected $eventConfigMock; /** * @var \Magento\Framework\Event\Manager */ - protected $_eventManager; + protected $eventManager; + + /** + * @var ObjectManagerHelper + */ + protected $objectManagerHelper; protected function setUp() { - $this->_invoker = $this->getMock('Magento\Framework\Event\InvokerInterface'); - $this->_eventConfigMock = $this->getMock('Magento\Framework\Event\ConfigInterface'); + $this->objectManagerHelper = new ObjectManagerHelper($this); + $this->invokerMock = $this->getMock(InvokerInterface::class); + $this->eventConfigMock = $this->getMock(ConfigInterface::class); - $this->_eventManager = new \Magento\Framework\Event\Manager($this->_invoker, $this->_eventConfigMock); + $this->eventManager = $this->objectManagerHelper->getObject( + EventManager::class, + [ + 'invoker' => $this->invokerMock, + 'eventConfig' => $this->eventConfigMock + ] + ); } public function testDispatch() { - $this->_eventConfigMock->expects( - $this->once() - )->method( - 'getObservers' - )->with( - 'some_event' - )->will( - $this->returnValue( - ['observer' => ['instance' => 'class', 'method' => 'method', 'name' => 'observer']] - ) - ); - $this->_eventManager->dispatch('some_event', ['123']); + $this->eventConfigMock->expects($this->once()) + ->method('getObservers') + ->with('some_eventname') + ->willReturn(['observer' => ['instance' => 'class', 'method' => 'method', 'name' => 'observer']]); + $this->eventManager->dispatch('some_eventName', ['123']); } public function testDispatchWithEmptyEventObservers() { - $this->_eventConfigMock->expects( - $this->once() - )->method( - 'getObservers' - )->with( - 'some_event' - )->will( - $this->returnValue([]) - ); - $this->_invoker->expects($this->never())->method('dispatch'); - $this->_eventManager->dispatch('some_event'); + $this->eventConfigMock->expects($this->once()) + ->method('getObservers') + ->with('some_event') + ->willReturn([]); + $this->invokerMock->expects($this->never())->method('dispatch'); + $this->eventManager->dispatch('some_event'); } } From 50ebc969fb24939af22466e08390ff38411dc275 Mon Sep 17 00:00:00 2001 From: Alexander Paliarush Date: Thu, 14 Jan 2016 11:15:45 +0200 Subject: [PATCH 036/128] MAGETWO-46853: Magento - Malicious Filter --- .../Magento/Framework/Filter/Input/MaliciousCode.php | 6 +++++- .../Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php b/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php index 72d30d3373709..9de7bfe1ba66f 100644 --- a/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php +++ b/lib/internal/Magento/Framework/Filter/Input/MaliciousCode.php @@ -44,7 +44,11 @@ class MaliciousCode implements \Zend_Filter_Interface */ public function filter($value) { - return preg_replace($this->_expressions, '', $value); + $replaced = 0; + do { + $value = preg_replace($this->_expressions, '', $value, -1, $replaced); + } while ($replaced !== 0); + return $value; } /** diff --git a/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php b/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php index dfe0a755397cc..5c6e4be9d8364 100644 --- a/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php +++ b/lib/internal/Magento/Framework/Filter/Test/Unit/Input/MaliciousCodeTest.php @@ -101,6 +101,10 @@ public function filterDataProvider() 'Base64' => [ 'Embedded Image', 'Embedded Image', + ], + 'Nested malicious tags' => [ + 'pt>alert(1);pt>', + 'alert(1);', ] ]; } From 2c7cd74324e2ca59fad3ed1d8b41a5ae5eb64c29 Mon Sep 17 00:00:00 2001 From: Bohdan Korablov Date: Thu, 14 Jan 2016 11:19:17 +0200 Subject: [PATCH 037/128] MAGETWO-46855: Block Cache Exploit --- .../View/Element/AbstractBlockTest.php | 4 +- .../Framework/View/Element/AbstractBlock.php | 9 +- .../Test/Unit/Element/AbstractBlockTest.php | 96 +++++++++++++------ 3 files changed, 76 insertions(+), 33 deletions(-) diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/Element/AbstractBlockTest.php b/dev/tests/integration/testsuite/Magento/Framework/View/Element/AbstractBlockTest.php index ef1ea1fd983ee..fb4873b17fd95 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/View/Element/AbstractBlockTest.php +++ b/dev/tests/integration/testsuite/Magento/Framework/View/Element/AbstractBlockTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Framework\View\Element; +use Magento\Framework\View\Element\AbstractBlock; + /** * @magentoAppIsolation enabled */ @@ -556,7 +558,7 @@ public function testGetCacheKey() $this->assertNotEquals($name, $key); $block->setCacheKey('key'); - $this->assertEquals('key', $block->getCacheKey()); + $this->assertEquals(AbstractBlock::CACHE_KEY_PREFIX . 'key', $block->getCacheKey()); } /** diff --git a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php index 0d965a9906061..bfed571826a80 100644 --- a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php +++ b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php @@ -24,6 +24,11 @@ abstract class AbstractBlock extends \Magento\Framework\DataObject implements Bl */ const CACHE_GROUP = \Magento\Framework\App\Cache\Type\Block::TYPE_IDENTIFIER; + /** + * Prefix for cache key of block + */ + const CACHE_KEY_PREFIX = 'BLOCK_'; + /** * Design * @@ -958,7 +963,7 @@ public function getCacheKeyInfo() public function getCacheKey() { if ($this->hasData('cache_key')) { - return $this->getData('cache_key'); + return static::CACHE_KEY_PREFIX . $this->getData('cache_key'); } /** * don't prevent recalculation by saving generated cache key @@ -970,7 +975,7 @@ public function getCacheKey() // ignore array keys $key = implode('|', $key); $key = sha1($key); - return $key; + return static::CACHE_KEY_PREFIX . $key; } /** diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php index f187f63c647f0..802a37b1690a3 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php @@ -8,8 +8,30 @@ namespace Magento\Framework\View\Test\Unit\Element; +use Magento\Framework\View\Element\AbstractBlock; +use Magento\Framework\View\Element\Context; +use Magento\Framework\Config\View; +use Magento\Framework\View\ConfigInterface; + class AbstractBlockTest extends \PHPUnit_Framework_TestCase { + /** + * @var AbstractBlock + */ + protected $block; + + /** + * @return void + */ + protected function setUp() + { + $contextMock = $this->getMock(Context::class, [], [], '', false); + $this->block = $this->getMockForAbstractClass( + AbstractBlock::class, + ['context' => $contextMock] + ); + } + /** * @param string $expectedResult * @param string $nameInLayout @@ -18,11 +40,8 @@ class AbstractBlockTest extends \PHPUnit_Framework_TestCase */ public function testGetUiId($expectedResult, $nameInLayout, $methodArguments) { - /** @var $block \Magento\Framework\View\Element\AbstractBlock|\PHPUnit_Framework_MockObject_MockObject */ - $block = $this->getMockForAbstractClass('Magento\Framework\View\Element\AbstractBlock', [], '', false); - $block->setNameInLayout($nameInLayout); - - $this->assertEquals($expectedResult, call_user_func_array([$block, 'getUiId'], $methodArguments)); + $this->block->setNameInLayout($nameInLayout); + $this->assertEquals($expectedResult, call_user_func_array([$this->block, 'getUiId'], $methodArguments)); } /** @@ -57,46 +76,63 @@ public function getUiIdDataProvider() ]; } + /** + * @return void + */ public function testGetVar() { - $this->markTestIncomplete('MAGETWO-11727'); - $config = $this->getMock('Magento\Framework\Config\View', ['getVarValue'], [], '', false); + $config = $this->getMock(View::class, ['getVarValue'], [], '', false); $module = uniqid(); - $config->expects( - $this->at(0) - )->method( - 'getVarValue' - )->with( - 'Magento_Theme', - 'v1' - )->will( - $this->returnValue('one') - ); - $config->expects($this->at(1))->method('getVarValue')->with($module, 'v2')->will($this->returnValue('two')); - $configManager = $this->getMock('Magento\Framework\View\ConfigInterface', [], [], '', false); - $configManager->expects($this->exactly(2))->method('getViewConfig')->will($this->returnValue($config)); + $config->expects($this->any()) + ->method('getVarValue') + ->willReturnMap([ + ['Magento_Theme', 'v1', 'one'], + [$module, 'v2', 'two'] + ]); + + $configManager = $this->getMock(ConfigInterface::class, [], [], '', false); + $configManager->expects($this->exactly(2))->method('getViewConfig')->willReturn($config); - /** @var $block \Magento\Framework\View\Element\AbstractBlock|\PHPUnit_Framework_MockObject_MockObject */ + /** @var $block AbstractBlock|\PHPUnit_Framework_MockObject_MockObject */ $params = ['viewConfig' => $configManager]; $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $block = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\AbstractBlock', - $helper->getConstructArguments('Magento\Framework\View\Element\AbstractBlock', $params), - uniqid('Magento\\Theme\\Block\\AbstractBlock\\') + AbstractBlock::class, + $helper->getConstructArguments(AbstractBlock::class, $params) ); + $block->setData('module_name', 'Magento_Theme'); $this->assertEquals('one', $block->getVar('v1')); $this->assertEquals('two', $block->getVar('v2', $module)); } + /** + * @return void + */ public function testIsScopePrivate() { - $contextMock = $this->getMock('Magento\Framework\View\Element\Context', [], [], '', false); - $block = $this->getMockForAbstractClass( - 'Magento\Framework\View\Element\AbstractBlock', - ['context' => $contextMock] - ); - $this->assertEquals(false, $block->isScopePrivate()); + $this->assertFalse($this->block->isScopePrivate()); + } + + /** + * @return void + */ + public function testGetCacheKey() + { + $cacheKey = 'testKey'; + $this->block->setData('cache_key', $cacheKey); + $this->assertEquals(AbstractBlock::CACHE_KEY_PREFIX . $cacheKey, $this->block->getCacheKey()); + } + + /** + * @return void + */ + public function testGetCacheKeyByName() + { + $nameInLayout = 'testBlock'; + $this->block->setNameInLayout($nameInLayout); + $cacheKey = sha1($nameInLayout); + $this->assertEquals(AbstractBlock::CACHE_KEY_PREFIX . $cacheKey, $this->block->getCacheKey()); } } From 25b8622f1475081d11cc271a03228430466da991 Mon Sep 17 00:00:00 2001 From: Alexander Paliarush Date: Thu, 14 Jan 2016 13:27:27 +0200 Subject: [PATCH 038/128] MAGETWO-47377: Unnecessary StoreCookie plugin is executed on each request --- .../Unit/Model/Plugin/StoreCookieTest.php | 39 +++++-------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/app/code/Magento/Store/Test/Unit/Model/Plugin/StoreCookieTest.php b/app/code/Magento/Store/Test/Unit/Model/Plugin/StoreCookieTest.php index 3b2197494bef8..43a471fba9ffc 100644 --- a/app/code/Magento/Store/Test/Unit/Model/Plugin/StoreCookieTest.php +++ b/app/code/Magento/Store/Test/Unit/Model/Plugin/StoreCookieTest.php @@ -37,11 +37,6 @@ class StoreCookieTest extends \PHPUnit_Framework_TestCase */ protected $storeMock; - /** - * @var \Closure - */ - protected $closureMock; - /** * @var \Magento\Framework\App\FrontController|\PHPUnit_Framework_MockObject_MockObject */ @@ -77,10 +72,6 @@ public function setUp() ->setMethods([]) ->getMock(); - $this->closureMock = function () { - return 'ExpectedValue'; - }; - $this->subjectMock = $this->getMockBuilder('Magento\Framework\App\FrontController') ->disableOriginalConstructor() ->setMethods([]) @@ -106,7 +97,7 @@ public function setUp() ); } - public function testAroundDispatchNoSuchEntity() + public function testBeforeDispatchNoSuchEntity() { $storeCode = 'store'; $this->storeManagerMock->expects($this->once())->method('getDefaultStoreView')->willReturn($this->storeMock); @@ -115,13 +106,10 @@ public function testAroundDispatchNoSuchEntity() ->method('getActiveStoreByCode') ->willThrowException(new NoSuchEntityException); $this->storeCookieManagerMock->expects($this->once())->method('deleteStoreCookie')->with($this->storeMock); - $this->assertEquals( - 'ExpectedValue', - $this->plugin->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock) - ); + $this->plugin->beforeDispatch($this->subjectMock, $this->requestMock); } - public function testAroundDispatchStoreIsInactive() + public function testBeforeDispatchStoreIsInactive() { $storeCode = 'store'; $this->storeManagerMock->expects($this->once())->method('getDefaultStoreView')->willReturn($this->storeMock); @@ -130,13 +118,10 @@ public function testAroundDispatchStoreIsInactive() ->method('getActiveStoreByCode') ->willThrowException(new StoreIsInactiveException); $this->storeCookieManagerMock->expects($this->once())->method('deleteStoreCookie')->with($this->storeMock); - $this->assertEquals( - 'ExpectedValue', - $this->plugin->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock) - ); + $this->plugin->beforeDispatch($this->subjectMock, $this->requestMock); } - public function testAroundDispatchInvalidArgument() + public function testBeforeDispatchInvalidArgument() { $storeCode = 'store'; $this->storeManagerMock->expects($this->once())->method('getDefaultStoreView')->willReturn($this->storeMock); @@ -145,22 +130,16 @@ public function testAroundDispatchInvalidArgument() ->method('getActiveStoreByCode') ->willThrowException(new InvalidArgumentException); $this->storeCookieManagerMock->expects($this->once())->method('deleteStoreCookie')->with($this->storeMock); - $this->assertEquals( - 'ExpectedValue', - $this->plugin->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock) - ); + $this->plugin->beforeDispatch($this->subjectMock, $this->requestMock); } - public function testAroundDispatchNoStoreCookie() + public function testBeforeDispatchNoStoreCookie() { $storeCode = null; - $this->storeManagerMock->expects($this->once())->method('getDefaultStoreView')->willReturn($this->storeMock); $this->storeCookieManagerMock->expects($this->once())->method('getStoreCodeFromCookie')->willReturn($storeCode); + $this->storeManagerMock->expects($this->never())->method('getDefaultStoreView')->willReturn($this->storeMock); $this->storeRepositoryMock->expects($this->never())->method('getActiveStoreByCode'); $this->storeCookieManagerMock->expects($this->never())->method('deleteStoreCookie')->with($this->storeMock); - $this->assertEquals( - 'ExpectedValue', - $this->plugin->aroundDispatch($this->subjectMock, $this->closureMock, $this->requestMock) - ); + $this->plugin->beforeDispatch($this->subjectMock, $this->requestMock); } } From 00a7f515cf9c759ab8c1427eae78119ca15c6a53 Mon Sep 17 00:00:00 2001 From: Leonid Poluyanov Date: Tue, 17 Nov 2015 11:53:53 +0200 Subject: [PATCH 039/128] MAGETWO-45652: Can't Deploy Sample Data After "composer create-project" --- .../SampleData/Console/Command/SampleDataDeployCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/code/Magento/SampleData/Console/Command/SampleDataDeployCommand.php b/app/code/Magento/SampleData/Console/Command/SampleDataDeployCommand.php index 8b3ca20ca09c9..6a8ada8a43693 100644 --- a/app/code/Magento/SampleData/Console/Command/SampleDataDeployCommand.php +++ b/app/code/Magento/SampleData/Console/Command/SampleDataDeployCommand.php @@ -80,7 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $sampleDataPackages = $this->sampleDataDependency->getSampleDataPackages(); if (!empty($sampleDataPackages)) { $baseDir = $this->filesystem->getDirectoryRead(DirectoryList::ROOT)->getAbsolutePath(); - $commonArgs = ['--working-dir' => $baseDir, '--no-interaction' => 1, '--no-progress' => 1]; + $commonArgs = ['--working-dir' => $baseDir, '--no-progress' => 1]; $packages = []; foreach ($sampleDataPackages as $name => $version) { $packages[] = "$name:$version"; From 5a005e4d819c06007b925fa415c7e4afaa4d8b05 Mon Sep 17 00:00:00 2001 From: Sviatoslav Mankivskyi Date: Fri, 27 Nov 2015 11:26:21 +0200 Subject: [PATCH 040/128] MAGETWO-45887: Persistent XSS on Create User Account --- .../Magento/Framework/View/Page/Config/Renderer.php | 2 +- .../Framework/View/Test/Unit/Page/Config/RendererTest.php | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/internal/Magento/Framework/View/Page/Config/Renderer.php b/lib/internal/Magento/Framework/View/Page/Config/Renderer.php index 660d1d9c5aa6b..c117472325c06 100644 --- a/lib/internal/Magento/Framework/View/Page/Config/Renderer.php +++ b/lib/internal/Magento/Framework/View/Page/Config/Renderer.php @@ -106,7 +106,7 @@ public function renderHeadContent() */ public function renderTitle() { - return '' . $this->pageConfig->getTitle()->get() . '' . "\n"; + return '' . $this->escaper->escapeHtml($this->pageConfig->getTitle()->get()) . '' . "\n"; } /** diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/RendererTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/RendererTest.php index 62c52b45cc818..8164bd3bb18a2 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/RendererTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/RendererTest.php @@ -179,11 +179,15 @@ public function testRenderTitle() $this->pageConfigMock->expects($this->any()) ->method('getTitle') - ->will($this->returnValue($this->titleMock)); + ->willReturn($this->titleMock); $this->titleMock->expects($this->once()) ->method('get') - ->will($this->returnValue($title)); + ->willReturn($title); + + $this->escaperMock->expects($this->once()) + ->method('escapeHtml') + ->willReturnArgument(0); $this->assertEquals($expected, $this->renderer->renderTitle()); } From c8da771c01fbb9e0ba01208b540858123c5af01e Mon Sep 17 00:00:00 2001 From: Vitalii Zabaznov Date: Mon, 30 Nov 2015 19:03:06 +0200 Subject: [PATCH 041/128] MAGETWO-45954: Stored XSS through custom options --- .../catalog/product/composite/fieldset/options/type/file.phtml | 2 +- .../frontend/templates/product/view/options/type/file.phtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/composite/fieldset/options/type/file.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/composite/fieldset/options/type/file.phtml index 644226409aa72..0e44b0639f4dd 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/composite/fieldset/options/type/file.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/composite/fieldset/options/type/file.phtml @@ -68,7 +68,7 @@ require(['prototype'], function(){
- getTitle(); ?> + escapeHtml($_fileInfo->getTitle()); ?>   diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/file.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/file.phtml index a7c60b9f3a920..9b9a7e3f998b9 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/file.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/file.phtml @@ -23,7 +23,7 @@
- getTitle(); ?> + escapeHtml($_fileInfo->getTitle()); ?> From 5a666fb9d3a6277c2e8bdf0ec26d05a0b4871f5d Mon Sep 17 00:00:00 2001 From: Vitalii Zabaznov Date: Thu, 3 Dec 2015 13:38:33 +0200 Subject: [PATCH 042/128] MAGETWO-45954: Stored XSS through custom options - fix CS --- .../product/composite/fieldset/options/type/file.phtml | 4 ++-- .../templates/product/view/options/type/file.phtml | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/composite/fieldset/options/type/file.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/composite/fieldset/options/type/file.phtml index 0e44b0639f4dd..861a4e9a0424a 100644 --- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/composite/fieldset/options/type/file.phtml +++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/composite/fieldset/options/type/file.phtml @@ -68,7 +68,7 @@ require(['prototype'], function(){
- escapeHtml($_fileInfo->getTitle()); ?> + escapeHtml($_fileInfo->getTitle()); ?>   @@ -79,7 +79,7 @@ require(['prototype'], function(){
> - /> + /> getFileExtension()): ?> diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/file.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/file.phtml index 9b9a7e3f998b9..7ced840c1060a 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/file.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/options/type/file.phtml @@ -17,14 +17,14 @@ getIsRequire()) ? ' required' : ''; ?>
-