diff --git a/app/code/Magento/Backend/Block/Template.php b/app/code/Magento/Backend/Block/Template.php index 05cb908d0240e..d0f39b54c1492 100644 --- a/app/code/Magento/Backend/Block/Template.php +++ b/app/code/Magento/Backend/Block/Template.php @@ -85,12 +85,22 @@ public function getFormKey() * * @param string $moduleName Full module name * @return boolean - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version - * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @deprecated 100.2.0 Magento does not support disabling/enabling modules output from the Admin Panel since 2.2.0 + * version. Module output can still be enabled/disabled in configuration files. However, this functionality should + * not be used in future development. Module design should explicitly state dependencies to avoid requiring output + * disabling. This functionality will temporarily be kept in Magento core, as there are unresolved modularity + * issues that will be addressed in future releases. */ public function isOutputEnabled($moduleName = null) { - return true; + if ($moduleName === null) { + $moduleName = $this->getModuleName(); + } + + return !$this->_scopeConfig->isSetFlag( + 'advanced/modules_disable_output/' . $moduleName, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); } /** diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Options/AjaxTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Options/AjaxTest.php index 3a7db614e7f68..7f1b4a8ea7ee7 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Options/AjaxTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Options/AjaxTest.php @@ -58,6 +58,12 @@ public function testToHtml() ->getMock(); $eventManager->expects($this->exactly(2))->method('dispatch')->will($this->returnValue(true)); + $scopeConfig = $this->getMockBuilder(\Magento\Framework\App\Config::class) + ->setMethods(['getValue']) + ->disableOriginalConstructor()->getMock(); + $scopeConfig->expects($this->once())->method('getValue')->withAnyParameters() + ->will($this->returnValue(false)); + $product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)->disableOriginalConstructor() ->setMethods(['setStoreId', 'load', 'getId', '__wakeup', '__sleep']) ->getMock(); @@ -90,6 +96,8 @@ public function testToHtml() $this->context->expects($this->once())->method('getEventManager') ->will($this->returnValue($eventManager)); + $this->context->expects($this->once())->method('getScopeConfig') + ->will($this->returnValue($scopeConfig)); $this->context->expects($this->once())->method('getLayout') ->will($this->returnValue($layout)); $this->context->expects($this->once())->method('getRequest') diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/Widget/NewWidgetTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/Widget/NewWidgetTest.php index c629f797bdc3f..9868213967f7f 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/Widget/NewWidgetTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/Widget/NewWidgetTest.php @@ -186,6 +186,8 @@ protected function generalGetProductCollection() { $this->eventManager->expects($this->exactly(2))->method('dispatch') ->will($this->returnValue(true)); + $this->scopeConfig->expects($this->once())->method('getValue')->withAnyParameters() + ->willReturn(false); $this->cacheState->expects($this->atLeastOnce())->method('isEnabled')->withAnyParameters() ->willReturn(false); $this->catalogConfig->expects($this->once())->method('getProductAttributes') diff --git a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php index 9f54bd279d906..108f1b9f4fd8d 100644 --- a/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php +++ b/app/code/Magento/CatalogSearch/Model/Layer/Filter/Price.php @@ -175,6 +175,9 @@ public function getCurrencyRate() */ protected function _renderRangeLabel($fromPrice, $toPrice) { + $fromPrice = empty($fromPrice) ? 0 : $fromPrice * $this->getCurrencyRate(); + $toPrice = empty($toPrice) ? $toPrice : $toPrice * $this->getCurrencyRate(); + $formattedFromPrice = $this->priceCurrency->format($fromPrice); if ($toPrice === '') { return __('%1 and above', $formattedFromPrice); @@ -261,10 +264,7 @@ private function prepareData($key, $count) if ($to == '*') { $to = $this->getTo($to); } - $label = $this->_renderRangeLabel( - empty($from) ? 0 : $from * $this->getCurrencyRate(), - empty($to) ? $to : $to * $this->getCurrencyRate() - ); + $label = $this->_renderRangeLabel($from, $to); $value = $from . '-' . $to . $this->dataProvider->getAdditionalRequestData(); $data = [ diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/PriceTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/PriceTest.php index 9631773cad2c9..abad58a6876d3 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/PriceTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Layer/Filter/PriceTest.php @@ -225,6 +225,7 @@ function ($field) use ($requestVar, $priceId) { ->with('price') ->will($this->returnSelf()); + $this->target->setCurrencyRate(1); $this->target->apply($this->request); } diff --git a/app/code/Magento/Checkout/Test/Unit/Block/Cart/Item/Renderer/ActionsTest.php b/app/code/Magento/Checkout/Test/Unit/Block/Cart/Item/Renderer/ActionsTest.php index eefb256b6238b..bcec37e0c7bf0 100644 --- a/app/code/Magento/Checkout/Test/Unit/Block/Cart/Item/Renderer/ActionsTest.php +++ b/app/code/Magento/Checkout/Test/Unit/Block/Cart/Item/Renderer/ActionsTest.php @@ -68,6 +68,10 @@ public function testToHtml() $childNameTwo = 'child.2'; $childNames = [$childNameOne, $childNameTwo]; + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->willReturn(false); + /** * @var Item|\PHPUnit_Framework_MockObject_MockObject $itemMock */ diff --git a/app/code/Magento/Config/Block/System/Config/Form/Fieldset/Modules/DisableOutput.php b/app/code/Magento/Config/Block/System/Config/Form/Fieldset/Modules/DisableOutput.php index 1f22fb1cf0e69..99fa7b5addee8 100644 --- a/app/code/Magento/Config/Block/System/Config/Form/Fieldset/Modules/DisableOutput.php +++ b/app/code/Magento/Config/Block/System/Config/Form/Fieldset/Modules/DisableOutput.php @@ -10,7 +10,11 @@ * on the store settings page. * * @method \Magento\Config\Block\System\Config\Form getForm() - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 Magento does not support disabling/enabling modules output from the Admin Panel since 2.2.0 + * version. Module output can still be enabled/disabled in configuration files. However, this functionality should + * not be used in future development. Module design should explicitly state dependencies to avoid requiring output + * disabling. This functionality will temporarily be kept in Magento core, as there are unresolved modularity + * issues that will be addressed in future releases. * @api * @since 100.0.2 */ @@ -18,25 +22,25 @@ class DisableOutput extends \Magento\Config\Block\System\Config\Form\Fieldset { /** * @var \Magento\Framework\DataObject - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 */ protected $_dummyElement; /** * @var \Magento\Config\Block\System\Config\Form\Field - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 */ protected $_fieldRenderer; /** * @var array - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 */ protected $_values; /** * @var \Magento\Framework\Module\ModuleListInterface - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 */ protected $_moduleList; @@ -60,7 +64,11 @@ public function __construct( /** * {@inheritdoc} - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 Magento does not support disabling/enabling modules output from the Admin Panel since 2.2.0 + * version. Module output can still be enabled/disabled in configuration files. However, this functionality should + * not be used in future development. Module design should explicitly state dependencies to avoid requiring output + * disabling. This functionality will temporarily be kept in Magento core, as there are unresolved modularity + * issues that will be addressed in future releases. */ public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element) { @@ -89,7 +97,7 @@ public function render(\Magento\Framework\Data\Form\Element\AbstractElement $ele } /** - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 * @return \Magento\Framework\DataObject */ protected function _getDummyElement() @@ -101,7 +109,7 @@ protected function _getDummyElement() } /** - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 * @return \Magento\Config\Block\System\Config\Form\Field */ protected function _getFieldRenderer() @@ -115,7 +123,7 @@ protected function _getFieldRenderer() } /** - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 * @return array */ protected function _getValues() @@ -132,7 +140,7 @@ protected function _getValues() /** * @param \Magento\Framework\Data\Form\Element\Fieldset $fieldset * @param string $moduleName - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 * @return mixed */ protected function _getFieldHtml($fieldset, $moduleName) diff --git a/app/code/Magento/Config/Test/Unit/Block/System/Config/Form/Fieldset/Modules/DisableOutputTest.php b/app/code/Magento/Config/Test/Unit/Block/System/Config/Form/Fieldset/Modules/DisableOutputTest.php index f274e7a1fa428..9d76363213d0b 100644 --- a/app/code/Magento/Config/Test/Unit/Block/System/Config/Form/Fieldset/Modules/DisableOutputTest.php +++ b/app/code/Magento/Config/Test/Unit/Block/System/Config/Form/Fieldset/Modules/DisableOutputTest.php @@ -7,7 +7,6 @@ /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @deprecated because \Magento\Config\Block\System\Config\Form\Fieldset\Modules\DisableOutput is deprecated */ class DisableOutputTest extends \PHPUnit\Framework\TestCase { diff --git a/app/code/Magento/Payment/Test/Unit/Block/Info/SubstitutionTest.php b/app/code/Magento/Payment/Test/Unit/Block/Info/SubstitutionTest.php index 9db5475bd65e4..729da9eb8196d 100644 --- a/app/code/Magento/Payment/Test/Unit/Block/Info/SubstitutionTest.php +++ b/app/code/Magento/Payment/Test/Unit/Block/Info/SubstitutionTest.php @@ -3,6 +3,9 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +// @codingStandardsIgnoreFile + namespace Magento\Payment\Test\Unit\Block\Info; /** @@ -31,23 +34,71 @@ class SubstitutionTest extends \PHPUnit\Framework\TestCase protected function setUp() { $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); - $this->layout = $this->getMockBuilder(\Magento\Framework\View\LayoutInterface::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $eventManager = $this->getMockBuilder(\Magento\Framework\Event\ManagerInterface::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $context = $this->getMockBuilder(\Magento\Framework\View\Element\Template\Context::class) - ->disableOriginalConstructor() - ->setMethods(['getLayout', 'getEventManager', 'getScopeConfig']) - ->getMock(); - $context->expects($this->any()) - ->method('getLayout') - ->willReturn($this->layout); - $context->expects($this->any())->method('getEventManager') - ->willReturn($eventManager); + + $this->layout = $this->getMockBuilder( + \Magento\Framework\View\LayoutInterface::class + )->disableOriginalConstructor()->setMethods( + [] + )->getMock(); + + $eventManager = $this->getMockBuilder( + \Magento\Framework\Event\ManagerInterface::class + )->disableOriginalConstructor()->setMethods( + [] + )->getMock(); + + $scopeConfig = $this->getMockBuilder( + \Magento\Framework\App\Config\ScopeConfigInterface::class + )->disableOriginalConstructor()->setMethods( + [] + )->getMock(); + $scopeConfig->expects( + $this->any() + )->method( + 'getValue' + )->with( + $this->stringContains( + 'advanced/modules_disable_output/' + ), + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + )->will( + $this->returnValue( + false + ) + ); + + $context = $this->getMockBuilder( + \Magento\Framework\View\Element\Template\Context::class + )->disableOriginalConstructor()->setMethods( + ['getLayout', 'getEventManager', 'getScopeConfig'] + )->getMock(); + $context->expects( + $this->any() + )->method( + 'getLayout' + )->will( + $this->returnValue( + $this->layout + ) + ); + $context->expects( + $this->any() + )->method( + 'getEventManager' + )->will( + $this->returnValue( + $eventManager + ) + ); + $context->expects( + $this->any() + )->method( + 'getScopeConfig' + )->will( + $this->returnValue( + $scopeConfig + ) + ); $this->block = $this->objectManager->getObject( \Magento\Payment\Block\Info\Substitution::class, @@ -62,45 +113,52 @@ protected function setUp() public function testBeforeToHtml() { - $abstractBlock = $this->getMockBuilder(\Magento\Framework\View\Element\AbstractBlock::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $childAbstractBlock = clone $abstractBlock; - - $abstractBlock->expects($this->any()) - ->method('getParentBlock') - ->willReturn($childAbstractBlock); - $this->layout->expects($this->any()) - ->method('getParentName') - ->willReturn('parentName'); - $this->layout->expects($this->any()) - ->method('getBlock') - ->willReturn($abstractBlock); - - $infoMock = $this->getMockBuilder(\Magento\Payment\Model\Info::class) - ->disableOriginalConstructor() - ->getMock(); - $methodMock = $this->getMockBuilder(\Magento\Payment\Model\MethodInterface::class) - ->getMockForAbstractClass(); - $infoMock->expects($this->once()) - ->method('getMethodInstance') - ->willReturn($methodMock); + $abstractBlock = $this->getMockBuilder( + \Magento\Framework\View\Element\AbstractBlock::class + )->disableOriginalConstructor()->setMethods( + [] + )->getMock(); + $childAbstractBlock = clone($abstractBlock); + + $abstractBlock->expects($this->any())->method('getParentBlock')->will($this->returnValue($childAbstractBlock)); + $this->layout->expects($this->any())->method('getParentName')->will($this->returnValue('parentName')); + $this->layout->expects($this->any())->method('getBlock')->will($this->returnValue($abstractBlock)); + + $infoMock = $this->getMockBuilder( + \Magento\Payment\Model\Info::class + )->disableOriginalConstructor()->setMethods( + [] + )->getMock(); + $methodMock = $this->getMockBuilder( + \Magento\Payment\Model\MethodInterface::class + )->getMockForAbstractClass(); + $infoMock->expects($this->once())->method('getMethodInstance')->will($this->returnValue($methodMock)); $this->block->setInfo($infoMock); $fakeBlock = new \StdClass(); - $this->layout->expects($this->any()) - ->method('createBlock') - ->with( - \Magento\Framework\View\Element\Template::class, - '', - ['data' => ['method' => $methodMock, 'template' => 'Magento_Payment::info/substitution.phtml']] - )->willReturn($fakeBlock); - - $childAbstractBlock->expects($this->any()) - ->method('setChild') - ->with('order_payment_additional', $fakeBlock); + $this->layout->expects( + $this->any() + )->method( + 'createBlock' + )->with( + \Magento\Framework\View\Element\Template::class, + '', + ['data' => ['method' => $methodMock, 'template' => 'Magento_Payment::info/substitution.phtml']] + )->will( + $this->returnValue( + $fakeBlock + ) + ); + + $childAbstractBlock->expects( + $this->any() + )->method( + 'setChild' + )->with( + 'order_payment_additional', + $fakeBlock + ); $this->block->toHtml(); } diff --git a/app/code/Magento/Paypal/Test/Unit/Block/Billing/AgreementsTest.php b/app/code/Magento/Paypal/Test/Unit/Block/Billing/AgreementsTest.php index 14be9852e41b1..9808126636a4e 100644 --- a/app/code/Magento/Paypal/Test/Unit/Block/Billing/AgreementsTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Block/Billing/AgreementsTest.php @@ -231,6 +231,10 @@ public function testToHtml() ->expects($this->at(1)) ->method('dispatch') ->with('view_block_abstract_to_html_after', ['block' => $this->block, 'transport' => $transport]); + $this->scopeConfig + ->expects($this->once()) + ->method('getValue') + ->willReturn(false); $this->urlBuilder->expects($this->once())->method('getUrl')->with('paypal/billing_agreement/startWizard', []); $this->block->toHtml(); } diff --git a/app/code/Magento/Paypal/Test/Unit/Block/Express/ReviewTest.php b/app/code/Magento/Paypal/Test/Unit/Block/Express/ReviewTest.php index 9d5d636598767..9a7a87b366fcf 100644 --- a/app/code/Magento/Paypal/Test/Unit/Block/Express/ReviewTest.php +++ b/app/code/Magento/Paypal/Test/Unit/Block/Express/ReviewTest.php @@ -3,9 +3,11 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Paypal\Test\Unit\Block\Express; use Magento\Paypal\Block\Express\Review; +use Magento\Quote\Model\Quote\Address\Rate; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -36,6 +38,14 @@ protected function setUp() $layout = $this->createMock(\Magento\Framework\View\LayoutInterface::class); $eventManager = $this->createMock(\Magento\Framework\Event\ManagerInterface::class); + $scopeConfig = $this->createMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); + + $scopeConfig->expects($this->any()) + ->method('getValue') + ->with( + $this->stringContains('advanced/modules_disable_output/'), + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + )->will($this->returnValue(false)); $urlBuilder = $this->createMock(\Magento\Framework\UrlInterface::class); $urlBuilder->expects($this->any())->method('getUrl')->will($this->returnArgument(0)); @@ -50,6 +60,7 @@ protected function setUp() $context->expects($this->any())->method('getLayout')->will($this->returnValue($layout)); $context->expects($this->any())->method('getEventManager')->will($this->returnValue($eventManager)); + $context->expects($this->any())->method('getScopeConfig')->will($this->returnValue($scopeConfig)); $context->expects($this->any())->method('getRequest')->will($this->returnValue($this->request)); $context->expects($this->any())->method('getAssetRepository')->will($this->returnValue($this->assetRepo)); $context->expects($this->any())->method('getUrlBuilder')->will($this->returnValue($urlBuilder)); diff --git a/app/code/Magento/Persistent/Test/Unit/Block/Header/AdditionalTest.php b/app/code/Magento/Persistent/Test/Unit/Block/Header/AdditionalTest.php index a8c4c46829b2a..b88b02ab4cfb5 100644 --- a/app/code/Magento/Persistent/Test/Unit/Block/Header/AdditionalTest.php +++ b/app/code/Magento/Persistent/Test/Unit/Block/Header/AdditionalTest.php @@ -134,7 +134,8 @@ protected function setUp() '', false, true, - true + true, + ['getValue'] ); $this->cacheStateMock = $this->getMockForAbstractClass( \Magento\Framework\App\Cache\StateInterface::class, @@ -251,6 +252,12 @@ public function testToHtml($customerId) $this->eventManagerMock->expects($this->at(1)) ->method('dispatch') ->with('view_block_abstract_to_html_after'); + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with( + 'advanced/modules_disable_output/Magento_Persistent', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + )->willReturn(false); // get cache $this->cacheStateMock->expects($this->at(0)) diff --git a/app/code/Magento/Robots/Test/Unit/Block/DataTest.php b/app/code/Magento/Robots/Test/Unit/Block/DataTest.php index edc701f438a1b..10d2595832a48 100644 --- a/app/code/Magento/Robots/Test/Unit/Block/DataTest.php +++ b/app/code/Magento/Robots/Test/Unit/Block/DataTest.php @@ -32,11 +32,19 @@ class DataTest extends \PHPUnit\Framework\TestCase */ private $eventManagerMock; + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $scopeConfigMock; + protected function setUp() { $this->eventManagerMock = $this->getMockBuilder(\Magento\Framework\Event\ManagerInterface::class) ->getMockForAbstractClass(); + $this->scopeConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class) + ->getMockForAbstractClass(); + $this->context = $this->getMockBuilder(\Magento\Framework\View\Element\Context::class) ->disableOriginalConstructor() ->getMock(); @@ -45,6 +53,10 @@ protected function setUp() ->method('getEventManager') ->willReturn($this->eventManagerMock); + $this->context->expects($this->any()) + ->method('getScopeConfig') + ->willReturn($this->scopeConfigMock); + $this->robots = $this->getMockBuilder(\Magento\Robots\Model\Robots::class) ->disableOriginalConstructor() ->getMock(); @@ -69,6 +81,8 @@ public function testToHtml() $this->initEventManagerMock($data); + $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(false); + $this->robots->expects($this->once()) ->method('getData') ->willReturn($data); diff --git a/app/code/Magento/Sitemap/Test/Unit/Block/RobotsTest.php b/app/code/Magento/Sitemap/Test/Unit/Block/RobotsTest.php index d78f87ad925be..6fcd247ab1f0f 100644 --- a/app/code/Magento/Sitemap/Test/Unit/Block/RobotsTest.php +++ b/app/code/Magento/Sitemap/Test/Unit/Block/RobotsTest.php @@ -40,6 +40,11 @@ class RobotsTest extends \PHPUnit\Framework\TestCase */ private $eventManagerMock; + /** + * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $scopeConfigMock; + /** * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ @@ -50,6 +55,9 @@ protected function setUp() $this->eventManagerMock = $this->getMockBuilder(\Magento\Framework\Event\ManagerInterface::class) ->getMockForAbstractClass(); + $this->scopeConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class) + ->getMockForAbstractClass(); + $this->context = $this->getMockBuilder(\Magento\Framework\View\Element\Context::class) ->disableOriginalConstructor() ->getMock(); @@ -58,6 +66,10 @@ protected function setUp() ->method('getEventManager') ->willReturn($this->eventManagerMock); + $this->context->expects($this->any()) + ->method('getScopeConfig') + ->willReturn($this->scopeConfigMock); + $this->storeResolver = $this->getMockBuilder(\Magento\Store\Model\StoreResolver::class) ->disableOriginalConstructor() ->getMock(); @@ -95,6 +107,7 @@ public function testToHtmlRobotsSubmissionIsDisabled() $expected = ''; $this->initEventManagerMock($expected); + $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(false); $this->storeResolver->expects($this->once()) ->method('getCurrentStoreId') @@ -150,6 +163,7 @@ public function testAfterGetDataRobotsSubmissionIsEnabled() . PHP_EOL; $this->initEventManagerMock($expected); + $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(false); $this->storeResolver->expects($this->once()) ->method('getCurrentStoreId') diff --git a/app/code/Magento/Theme/Api/Data/DesignConfigDataInterface.php b/app/code/Magento/Theme/Api/Data/DesignConfigDataInterface.php index d71ad5a0ce5b8..6ce93a5ea3bee 100644 --- a/app/code/Magento/Theme/Api/Data/DesignConfigDataInterface.php +++ b/app/code/Magento/Theme/Api/Data/DesignConfigDataInterface.php @@ -64,7 +64,7 @@ public function setFieldConfig(array $config); /** * Retrieve existing extension attributes object or create a new one. * - * @return DesignConfigDataExtensionInterface|null + * @return \Magento\Theme\Api\Data\DesignConfigDataExtensionInterface|null * @since 100.1.0 */ public function getExtensionAttributes(); @@ -72,7 +72,7 @@ public function getExtensionAttributes(); /** * Set an extension attributes object. * - * @param DesignConfigDataExtensionInterface $extensionAttributes + * @param \Magento\Theme\Api\Data\DesignConfigDataExtensionInterface $extensionAttributes * @return $this * @since 100.1.0 */ diff --git a/app/code/Magento/Widget/Test/Unit/Block/Adminhtml/Widget/Instance/Edit/Chooser/ContainerTest.php b/app/code/Magento/Widget/Test/Unit/Block/Adminhtml/Widget/Instance/Edit/Chooser/ContainerTest.php index 346d93a9a8536..540bcd1aa43c6 100644 --- a/app/code/Magento/Widget/Test/Unit/Block/Adminhtml/Widget/Instance/Edit/Chooser/ContainerTest.php +++ b/app/code/Magento/Widget/Test/Unit/Block/Adminhtml/Widget/Instance/Edit/Chooser/ContainerTest.php @@ -67,6 +67,7 @@ public function testToHtmlCatalogProductsListGroupedProduct() . ''; $this->eventManagerMock->expects($this->exactly(2))->method('dispatch')->willReturn(true); + $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(false); $this->themeCollectionFactoryMock->expects($this->once()) ->method('create') @@ -153,6 +154,7 @@ public function testToHtmlCatalogCategoryLinkSimpleProduct() . ''; $this->eventManagerMock->expects($this->exactly(2))->method('dispatch')->willReturn(true); + $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(false); $this->themeCollectionFactoryMock->expects($this->once()) ->method('create') @@ -283,6 +285,7 @@ public function testToHtmlCmsStaticBlockAllProductTypes() . ''; $this->eventManagerMock->expects($this->exactly(2))->method('dispatch')->willReturn(true); + $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(false); $this->themeCollectionFactoryMock->expects($this->once()) ->method('create') @@ -400,6 +403,7 @@ public function testToHtmlOrderBySkuAllPages() . 'Sidebar Main'; $this->eventManagerMock->expects($this->exactly(2))->method('dispatch')->willReturn(true); + $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(false); $this->themeCollectionFactoryMock->expects($this->once()) ->method('create') diff --git a/app/code/Magento/Wishlist/Test/Unit/Model/Rss/WishlistTest.php b/app/code/Magento/Wishlist/Test/Unit/Model/Rss/WishlistTest.php index 4124cb1cd3156..98d36dea28a2a 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Model/Rss/WishlistTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Model/Rss/WishlistTest.php @@ -128,6 +128,7 @@ public function testGetRssData() ); $customerServiceMock = $this->createMock(\Magento\Customer\Api\Data\CustomerInterface::class); $wishlistSharingUrl = 'wishlist/shared/index/1'; + $locale = 'en_US'; $productUrl = 'http://product.url/'; $productName = 'Product name'; @@ -151,6 +152,26 @@ public function testGetRssData() $this->urlBuilderMock->expects($this->once()) ->method('getUrl') ->will($this->returnValue($wishlistSharingUrl)); + $this->scopeConfig->expects($this->any()) + ->method('getValue') + ->will( + $this->returnValueMap( + [ + [ + 'advanced/modules_disable_output/Magento_Rss', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + null, + null, + ], + [ + Data::XML_PATH_DEFAULT_LOCALE, + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + null, + $locale + ], + ] + ) + ); $staticArgs = [ 'productName' => $productName, diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/TemplateTest.php b/dev/tests/integration/testsuite/Magento/Backend/Block/TemplateTest.php index 9c19355095264..82503f6456919 100644 --- a/dev/tests/integration/testsuite/Magento/Backend/Block/TemplateTest.php +++ b/dev/tests/integration/testsuite/Magento/Backend/Block/TemplateTest.php @@ -34,4 +34,26 @@ public function testGetFormKey() { $this->assertGreaterThan(15, strlen($this->_block->getFormKey())); } + + /** + * @magentoAppArea adminhtml + * @covers \Magento\Backend\Block\Template::isOutputEnabled + * @magentoConfigFixture current_store advanced/modules_disable_output/dummy 1 + */ + public function testIsOutputEnabledTrue() + { + $this->_block->setData('module_name', 'dummy'); + $this->assertFalse($this->_block->isOutputEnabled('dummy')); + } + + /** + * @magentoAppArea adminhtml + * @covers \Magento\Backend\Block\Template::isOutputEnabled + * @magentoConfigFixture current_store advanced/modules_disable_output/dummy 0 + */ + public function testIsOutputEnabledFalse() + { + $this->_block->setData('module_name', 'dummy'); + $this->assertTrue($this->_block->isOutputEnabled('dummy')); + } } diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php index cd4ee02616b3a..451553113af2c 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php @@ -5,6 +5,8 @@ */ namespace Magento\CatalogSearch\Model\Layer\Filter; +use Magento\TestFramework\Helper\Bootstrap; + /** * Test class for \Magento\CatalogSearch\Model\Layer\Filter\Price. * @@ -19,26 +21,31 @@ class PriceTest extends \PHPUnit\Framework\TestCase */ protected $_model; + /** + * @var \Magento\Framework\ObjectManagerInterface + */ + private $objectManager; + protected function setUp() { - $category = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + $this->objectManager = Bootstrap::getObjectManager(); + $category = $this->objectManager->create( \Magento\Catalog\Model\Category::class ); $category->load(4); - $layer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() - ->get(\Magento\Catalog\Model\Layer\Category::class); + $layer = $this->objectManager->get(\Magento\Catalog\Model\Layer\Category::class); $layer->setCurrentCategory($category); - $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() - ->create(\Magento\CatalogSearch\Model\Layer\Filter\Price::class, ['layer' => $layer]); + $this->_model = $this->objectManager->create( + \Magento\CatalogSearch\Model\Layer\Filter\Price::class, + ['layer' => $layer] + ); } public function testApplyNothing() { $this->assertEmpty($this->_model->getData('price_range')); - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); /** @var $request \Magento\TestFramework\Request */ - $request = $objectManager->get(\Magento\TestFramework\Request::class); + $request = $this->objectManager->get(\Magento\TestFramework\Request::class); $this->_model->apply($request); $this->assertEmpty($this->_model->getData('price_range')); @@ -47,10 +54,8 @@ public function testApplyNothing() public function testApplyInvalid() { $this->assertEmpty($this->_model->getData('price_range')); - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); /** @var $request \Magento\TestFramework\Request */ - $request = $objectManager->get(\Magento\TestFramework\Request::class); + $request = $this->objectManager->get(\Magento\TestFramework\Request::class); $request->setParam('price', 'non-numeric'); $this->_model->apply($request); @@ -62,12 +67,31 @@ public function testApplyInvalid() */ public function testApplyManual() { - /** @var $objectManager \Magento\TestFramework\ObjectManager */ - $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); /** @var $request \Magento\TestFramework\Request */ - $request = $objectManager->get(\Magento\TestFramework\Request::class); + $request = $this->objectManager->get(\Magento\TestFramework\Request::class); + $request->setParam('price', '10-20'); + $this->_model->apply($request); + } + + /** + * Make sure that currency rate is used to calculate label for applied price filter + */ + public function testApplyWithCustomCurrencyRate() + { + /** @var $request \Magento\TestFramework\Request */ + $request = $this->objectManager->get(\Magento\TestFramework\Request::class); + $request->setParam('price', '10-20'); + $this->_model->setCurrencyRate(10); + $this->_model->apply($request); + + $filters = $this->_model->getLayer()->getState()->getFilters(); + $this->assertArrayHasKey(0, $filters); + $this->assertEquals( + '$100.00 - $199.99', + (string)$filters[0]->getLabel() + ); } public function testGetSetCustomerGroupId() diff --git a/lib/internal/Magento/Framework/Module/Manager.php b/lib/internal/Magento/Framework/Module/Manager.php index dc07ec493e8f0..a9a3d2294a90f 100644 --- a/lib/internal/Magento/Framework/Module/Manager.php +++ b/lib/internal/Magento/Framework/Module/Manager.php @@ -3,6 +3,10 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +/** + * Module statuses manager + */ namespace Magento\Framework\Module; /** @@ -16,36 +20,26 @@ class Manager { /** - * The checker of output modules. - * - * @var Output\ConfigInterface the config checker of output modules. - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version. - * The property can be removed in a future major release + * @var Output\ConfigInterface + * @deprecated 100.2.0 */ private $outputConfig; /** - * The list of all modules. - * - * @var ModuleListInterface the list of all modules. + * @var ModuleListInterface */ private $moduleList; /** - * The list of config paths to ignore. - * - * @var array the list of config paths to ignore. - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version. - * The property can be removed in a future major release + * @var array + * @deprecated 100.2.0 */ private $outputConfigPaths; /** - * Constructor. - * - * @param Output\ConfigInterface $outputConfig the checker of output modules - * @param ModuleListInterface $moduleList the list of all modules - * @param array $outputConfigPaths the list of config paths to ignore + * @param Output\ConfigInterface $outputConfig + * @param ModuleListInterface $moduleList + * @param array $outputConfigPaths */ public function __construct( Output\ConfigInterface $outputConfig, @@ -58,11 +52,10 @@ public function __construct( } /** - * Checks whether a module is enabled in the configuration or not. + * Whether a module is enabled in the configuration or not * - * @param string $moduleName the fully-qualified module name - * - * @return boolean true if module is enabled, false otherwise + * @param string $moduleName Fully-qualified module name + * @return boolean */ public function isEnabled($moduleName) { @@ -70,30 +63,39 @@ public function isEnabled($moduleName) } /** - * Checks whether a module output is permitted by the configuration or not. - * - * @param string $moduleName the fully-qualified module name. + * Whether a module output is permitted by the configuration or not * + * @param string $moduleName Fully-qualified module name * @return boolean - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 Magento does not support disabling/enabling modules output from the Admin Panel since 2.2.0 + * version. Module output can still be enabled/disabled in configuration files. However, this functionality should + * not be used in future development. Module design should explicitly state dependencies to avoid requiring output + * disabling. This functionality will temporarily be kept in Magento core, as there are unresolved modularity + * issues that will be addressed in future releases. */ public function isOutputEnabled($moduleName) { - return $this->isEnabled($moduleName); + return $this->isEnabled($moduleName) + && $this->_isCustomOutputConfigEnabled($moduleName) + && !$this->outputConfig->isEnabled($moduleName); } /** - * Checks whether a configuration switch for a module output permits output. + * Whether a configuration switch for a module output permits output or not * * @param string $moduleName Fully-qualified module name - * * @return boolean - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version. - * The method can be removed in a future major release - * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * @deprecated 100.2.0 */ protected function _isCustomOutputConfigEnabled($moduleName) { + if (isset($this->outputConfigPaths[$moduleName])) { + $configPath = $this->outputConfigPaths[$moduleName]; + if (defined($configPath)) { + $configPath = constant($configPath); + } + return $this->outputConfig->isSetFlag($configPath); + } return true; } } diff --git a/lib/internal/Magento/Framework/Module/Output/Config.php b/lib/internal/Magento/Framework/Module/Output/Config.php index 2577ec07422a0..48afc97dc5336 100644 --- a/lib/internal/Magento/Framework/Module/Output/Config.php +++ b/lib/internal/Magento/Framework/Module/Output/Config.php @@ -8,27 +8,29 @@ namespace Magento\Framework\Module\Output; /** - * Checks whether the module is enabled in the configuration. - * - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 Magento does not support disabling/enabling modules output from the Admin Panel since 2.2.0 + * version. Module output can still be enabled/disabled in configuration files. However, this functionality should + * not be used in future development. Module design should explicitly state dependencies to avoid requiring output + * disabling. This functionality will temporarily be kept in Magento core, as there are unresolved modularity + * issues that will be addressed in future releases. */ class Config implements \Magento\Framework\Module\Output\ConfigInterface { /** * XPath in the configuration where module statuses are stored - * @deprecated Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 */ const XML_PATH_MODULE_OUTPUT_STATUS = 'advanced/modules_disable_output/%s'; /** * @var \Magento\Framework\App\Config\ScopeConfigInterface - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 */ protected $_scopeConfig; /** * @var string - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 */ protected $_storeType; @@ -48,23 +50,31 @@ public function __construct( * Whether a module is enabled in the configuration or not * * @param string $moduleName Fully-qualified module name - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 Magento does not support disabling/enabling modules output from the Admin Panel since 2.2.0 + * version. Module output can still be enabled/disabled in configuration files. However, this functionality should + * not be used in future development. Module design should explicitly state dependencies to avoid requiring output + * disabling. This functionality will temporarily be kept in Magento core, as there are unresolved modularity + * issues that will be addressed in future releases. * @return boolean */ public function isEnabled($moduleName) { - return false; + return $this->isSetFlag(sprintf(self::XML_PATH_MODULE_OUTPUT_STATUS, $moduleName)); } /** * Retrieve module enabled specific path * * @param string $path Fully-qualified config path - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 Magento does not support disabling/enabling modules output from the Admin Panel since 2.2.0 + * version. Module output can still be enabled/disabled in configuration files. However, this functionality should + * not be used in future development. Module design should explicitly state dependencies to avoid requiring output + * disabling. This functionality will temporarily be kept in Magento core, as there are unresolved modularity + * issues that will be addressed in future releases. * @return boolean */ public function isSetFlag($path) { - return false; + return $this->_scopeConfig->isSetFlag($path, $this->_storeType); } } diff --git a/lib/internal/Magento/Framework/Module/Output/ConfigInterface.php b/lib/internal/Magento/Framework/Module/Output/ConfigInterface.php index cce4691d041be..6813691b9c906 100644 --- a/lib/internal/Magento/Framework/Module/Output/ConfigInterface.php +++ b/lib/internal/Magento/Framework/Module/Output/ConfigInterface.php @@ -6,9 +6,8 @@ namespace Magento\Framework\Module\Output; /** - * Checks whether the module is enabled in the configuration. - * - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 Magento does not support disabling/enabling modules output from the Admin Panel since 2.2.0 + * version. Module output can still be enabled/disabled in configuration files. */ interface ConfigInterface { @@ -16,7 +15,11 @@ interface ConfigInterface * Whether a module is enabled in the configuration or not * * @param string $moduleName Fully-qualified module name - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 Magento does not support disabling/enabling modules output from the Admin Panel since 2.2.0 + * version. Module output can still be enabled/disabled in configuration files. However, this functionality should + * not be used in future development. Module design should explicitly state dependencies to avoid requiring output + * disabling. This functionality will temporarily be kept in Magento core, as there are unresolved modularity + * issues that will be addressed in future releases. * @return boolean */ public function isEnabled($moduleName); @@ -25,7 +28,11 @@ public function isEnabled($moduleName); * Retrieve module enabled specific path * * @param string $path Fully-qualified config path - * @deprecated 100.2.0 Magento does not support custom disabling/enabling module output since 2.2.0 version + * @deprecated 100.2.0 Magento does not support disabling/enabling modules output from the Admin Panel since 2.2.0 + * version. Module output can still be enabled/disabled in configuration files. However, this functionality should + * not be used in future development. Module design should explicitly state dependencies to avoid requiring output + * disabling. This functionality will temporarily be kept in Magento core, as there are unresolved modularity + * issues that will be addressed in future releases. * @return boolean */ public function isSetFlag($path); diff --git a/lib/internal/Magento/Framework/Module/Test/Unit/ManagerTest.php b/lib/internal/Magento/Framework/Module/Test/Unit/ManagerTest.php index 4e137514e0e2f..44185b52b19a4 100644 --- a/lib/internal/Magento/Framework/Module/Test/Unit/ManagerTest.php +++ b/lib/internal/Magento/Framework/Module/Test/Unit/ManagerTest.php @@ -5,63 +5,109 @@ */ namespace Magento\Framework\Module\Test\Unit; -use Magento\Framework\Module\Manager; -use Magento\Framework\Module\ModuleListInterface; -use Magento\Framework\Module\Output\ConfigInterface; -use \PHPUnit_Framework_MockObject_MockObject as Mock; +use Magento\Framework\Module\Plugin\DbStatusValidator; class ManagerTest extends \PHPUnit\Framework\TestCase { /** * XPath in the configuration of a module output flag - * @deprecated */ const XML_PATH_OUTPUT_ENABLED = 'custom/is_module_output_enabled'; /** - * @var Manager + * @var \Magento\Framework\Module\Manager */ - private $model; + private $_model; /** - * @var ModuleListInterface|Mock + * @var \PHPUnit_Framework_MockObject_MockObject */ - private $moduleList; + private $_moduleList; /** - * @var ConfigInterface|Mock - * @deprecated + * @var \PHPUnit_Framework_MockObject_MockObject */ - private $outputConfig; + private $_outputConfig; /** * @inheritdoc */ protected function setUp() { - $this->moduleList = $this->getMockBuilder(ModuleListInterface::class) - ->getMockForAbstractClass(); - $this->outputConfig = $this->getMockBuilder(ConfigInterface::class) - ->getMockForAbstractClass(); - - $this->model = new Manager( - $this->outputConfig, - $this->moduleList + $this->_moduleList = $this->getMockForAbstractClass(\Magento\Framework\Module\ModuleListInterface::class); + $this->_moduleList->expects($this->any()) + ->method('getOne') + ->will($this->returnValueMap([ + ['Module_One', ['name' => 'One_Module', 'setup_version' => '1']], + ['Module_Two', ['name' => 'Two_Module', 'setup_version' => '2']], + ['Module_Three', ['name' => 'Two_Three']], + ])); + $this->_outputConfig = $this->getMockForAbstractClass(\Magento\Framework\Module\Output\ConfigInterface::class); + $this->_model = new \Magento\Framework\Module\Manager( + $this->_outputConfig, + $this->_moduleList, + [ + 'Module_Two' => self::XML_PATH_OUTPUT_ENABLED, + ] ); } public function testIsEnabled() { - $this->moduleList->expects($this->exactly(2)) - ->method('has') - ->willReturnMap( - [ - ['Module_Exists', true], - ['Module_NotExists', false], - ] - ); + $this->_moduleList->expects($this->exactly(2))->method('has')->will($this->returnValueMap([ + ['Module_Exists', true], + ['Module_NotExists', false], + ])); + $this->assertTrue($this->_model->isEnabled('Module_Exists')); + $this->assertFalse($this->_model->isEnabled('Module_NotExists')); + } + + public function testIsOutputEnabledReturnsFalseForDisabledModule() + { + $this->_outputConfig->expects($this->any())->method('isSetFlag')->will($this->returnValue(true)); + $this->assertFalse($this->_model->isOutputEnabled('Disabled_Module')); + } + + /** + * @param bool $configValue + * @param bool $expectedResult + * @dataProvider isOutputEnabledGenericConfigPathDataProvider + */ + public function testIsOutputEnabledGenericConfigPath($configValue, $expectedResult) + { + $this->_moduleList->expects($this->once())->method('has')->will($this->returnValue(true)); + $this->_outputConfig->expects($this->once()) + ->method('isEnabled') + ->with('Module_One') + ->will($this->returnValue($configValue)); + $this->assertEquals($expectedResult, $this->_model->isOutputEnabled('Module_One')); + } - $this->assertTrue($this->model->isEnabled('Module_Exists')); - $this->assertFalse($this->model->isEnabled('Module_NotExists')); + public function isOutputEnabledGenericConfigPathDataProvider() + { + return ['output disabled' => [true, false], 'output enabled' => [false, true]]; + } + + /** + * @param bool $configValue + * @param bool $expectedResult + * @dataProvider isOutputEnabledCustomConfigPathDataProvider + */ + public function testIsOutputEnabledCustomConfigPath($configValue, $expectedResult) + { + $this->_moduleList->expects($this->once())->method('has')->will($this->returnValue(true)); + $this->_outputConfig->expects($this->at(0)) + ->method('isSetFlag') + ->with(self::XML_PATH_OUTPUT_ENABLED) + ->will($this->returnValue($configValue)); + $this->assertEquals($expectedResult, $this->_model->isOutputEnabled('Module_Two')); + } + + public function isOutputEnabledCustomConfigPathDataProvider() + { + return [ + 'path literal, output disabled' => [false, false], + 'path literal, output enabled' => [true, true], + ]; } } diff --git a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php index e977e8a2da2d5..0ffa9dce7f730 100644 --- a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php +++ b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php @@ -650,7 +650,12 @@ protected function _beforeToHtml() public function toHtml() { $this->_eventManager->dispatch('view_block_abstract_to_html_before', ['block' => $this]); - $this->getModuleName(); + if ($this->_scopeConfig->getValue( + 'advanced/modules_disable_output/' . $this->getModuleName(), + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + )) { + return ''; + } $html = $this->_loadCache(); if ($html === false) { 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 a12d18befa69d..710b42af3e23f 100644 --- a/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php +++ b/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php @@ -3,6 +3,9 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + +// @codingStandardsIgnoreFile + namespace Magento\Framework\View\Test\Unit\Element; use Magento\Framework\View\Element\AbstractBlock; @@ -204,12 +207,13 @@ public function testToHtmlWhenModuleIsDisabled() $moduleName = 'Test'; $this->block->setData('module_name', $moduleName); - $this->eventManagerMock->expects($this->exactly(2)) + $this->eventManagerMock->expects($this->any()) ->method('dispatch') - ->willReturnMap([ - ['view_block_abstract_to_html_before', ['block' => $this->block]], - ['view_block_abstract_to_html_after', ['block' => $this->block]], - ]); + ->with('view_block_abstract_to_html_before', ['block' => $this->block]); + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with('advanced/modules_disable_output/' . $moduleName, \Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ->willReturn(true); $this->assertSame('', $this->block->toHtml()); } @@ -242,6 +246,10 @@ public function testGetCacheLifetimeViaToHtml( $this->eventManagerMock->expects($expectsDispatchEvent) ->method('dispatch'); + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with('advanced/modules_disable_output/' . $moduleName, \Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ->willReturn(false); $this->cacheStateMock->expects($this->any()) ->method('isEnabled') ->with(AbstractBlock::CACHE_GROUP) 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 21cf8797f8340..e2bd543ccc77c 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 @@ -54,8 +54,8 @@ public function __construct( public function doOperation() { $files = $this->configurationScanner->scan('extension_attributes.xml'); - $repositories = $this->serviceDataAttributesScanner->collectEntities($files); - foreach ($repositories as $entityName) { + $entities = $this->serviceDataAttributesScanner->collectEntities($files); + foreach ($entities as $entityName) { class_exists($entityName); } } diff --git a/setup/src/Magento/Setup/Module/Di/Code/Scanner/PhpScanner.php b/setup/src/Magento/Setup/Module/Di/Code/Scanner/PhpScanner.php index 8c1d6565cd668..ab66a63e24498 100644 --- a/setup/src/Magento/Setup/Module/Di/Code/Scanner/PhpScanner.php +++ b/setup/src/Magento/Setup/Module/Di/Code/Scanner/PhpScanner.php @@ -9,6 +9,7 @@ use Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator; use Magento\Framework\ObjectManager\Code\Generator\Factory as FactoryGenerator; use Magento\Setup\Module\Di\Compiler\Log\Log; +use \Magento\Framework\Reflection\TypeProcessor; class PhpScanner implements ScannerInterface { @@ -18,11 +19,21 @@ class PhpScanner implements ScannerInterface protected $_log; /** + * @var TypeProcessor + */ + private $typeProcessor; + + /** + * Initialize dependencies. + * * @param Log $log + * @param TypeProcessor|null $typeProcessor */ - public function __construct(Log $log) + public function __construct(Log $log, TypeProcessor $typeProcessor = null) { $this->_log = $log; + $this->typeProcessor = $typeProcessor + ?: \Magento\Framework\App\ObjectManager::getInstance()->get(TypeProcessor::class); } /** @@ -45,22 +56,9 @@ protected function _findMissingClasses($file, $classReflection, $methodName, $en preg_match('/\[\s\<\w+?>\s([\w\\\\]+)/s', $parameter->__toString(), $matches); if (isset($matches[1]) && substr($matches[1], -strlen($entityType)) == $entityType) { $missingClassName = $matches[1]; - try { - if (class_exists($missingClassName)) { - continue; - } - } catch (\RuntimeException $e) { - } - $sourceClassName = $this->getSourceClassName($missingClassName, $entityType); - if (!class_exists($sourceClassName) && !interface_exists($sourceClassName)) { - $this->_log->add( - Log::CONFIGURATION_ERROR, - $missingClassName, - "Invalid {$entityType} for nonexistent class {$sourceClassName} in file {$file}" - ); - continue; + if ($this->shouldGenerateClass($missingClassName, $entityType, $file)) { + $missingClasses[] = $missingClassName; } - $missingClasses[] = $missingClassName; } } } @@ -137,12 +135,18 @@ protected function _fetchFactories($reflectionClass, $file) */ protected function _fetchMissingExtensionAttributesClasses($reflectionClass, $file) { - $missingExtensionInterfaces = $this->_findMissingClasses( - $file, - $reflectionClass, - 'setExtensionAttributes', - ucfirst(\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator::ENTITY_TYPE) - ); + $missingExtensionInterfaces = []; + $methodName = 'getExtensionAttributes'; + $entityType = ucfirst(\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator::ENTITY_TYPE); + if ($reflectionClass->hasMethod($methodName) && $reflectionClass->isInterface()) { + $returnType = $this->typeProcessor->getGetterReturnType( + (new \Zend\Code\Reflection\ClassReflection($reflectionClass->getName()))->getMethod($methodName) + ); + $missingClassName = $returnType['type']; + if ($this->shouldGenerateClass($missingClassName, $entityType, $file)) { + $missingExtensionInterfaces[] = $missingClassName; + } + } $missingExtensionClasses = []; $missingExtensionFactories = []; foreach ($missingExtensionInterfaces as $missingExtensionInterface) { @@ -244,4 +248,32 @@ protected function _getDeclaredClasses($file) } return array_unique($classes); } + + /** + * Check if specified class is missing and if it can be generated. + * + * @param string $missingClassName + * @param string $entityType + * @param string $file + * @return bool + */ + private function shouldGenerateClass($missingClassName, $entityType, $file) + { + try { + if (class_exists($missingClassName)) { + return false; + } + } catch (\RuntimeException $e) { + } + $sourceClassName = $this->getSourceClassName($missingClassName, $entityType); + if (!class_exists($sourceClassName) && !interface_exists($sourceClassName)) { + $this->_log->add( + Log::CONFIGURATION_ERROR, + $missingClassName, + "Invalid {$entityType} for nonexistent class {$sourceClassName} in file {$file}" + ); + return false; + } + return true; + } } diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Scanner/PhpScannerTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Scanner/PhpScannerTest.php index f2471bd92da06..ca3fe64f6d153 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Scanner/PhpScannerTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/Code/Scanner/PhpScannerTest.php @@ -8,6 +8,9 @@ require_once __DIR__ . '/../../_files/app/code/Magento/SomeModule/Helper/Test.php'; require_once __DIR__ . '/../../_files/app/code/Magento/SomeModule/ElementFactory.php'; require_once __DIR__ . '/../../_files/app/code/Magento/SomeModule/Model/DoubleColon.php'; +require_once __DIR__ . '/../../_files/app/code/Magento/SomeModule/Api/Data/SomeInterface.php'; + +use Magento\Framework\Reflection\TypeProcessor; class PhpScannerTest extends \PHPUnit\Framework\TestCase { @@ -33,18 +36,19 @@ class PhpScannerTest extends \PHPUnit\Framework\TestCase protected function setUp() { - $this->_model = new \Magento\Setup\Module\Di\Code\Scanner\PhpScanner( - $this->_logMock = $this->createMock(\Magento\Setup\Module\Di\Compiler\Log\Log::class) - ); + $this->_logMock = $this->createMock(\Magento\Setup\Module\Di\Compiler\Log\Log::class); + $this->_model = new \Magento\Setup\Module\Di\Code\Scanner\PhpScanner($this->_logMock, new TypeProcessor()); $this->_testDir = str_replace('\\', '/', realpath(__DIR__ . '/../../') . '/_files'); - $this->_testFiles = [ - $this->_testDir . '/app/code/Magento/SomeModule/Helper/Test.php', - $this->_testDir . '/app/code/Magento/SomeModule/Model/DoubleColon.php' - ]; } public function testCollectEntities() { + $this->_testFiles = [ + $this->_testDir . '/app/code/Magento/SomeModule/Helper/Test.php', + $this->_testDir . '/app/code/Magento/SomeModule/Model/DoubleColon.php', + $this->_testDir . '/app/code/Magento/SomeModule/Api/Data/SomeInterface.php' + ]; + $this->_logMock->expects( $this->at(0) )->method( @@ -64,6 +68,9 @@ public function testCollectEntities() 'Invalid Factory declaration for class Magento\SomeModule\Element in file ' . $this->_testFiles[0] ); - $this->assertEquals([], $this->_model->collectEntities($this->_testFiles)); + $this->assertEquals( + ['\Magento\Eav\Api\Data\AttributeExtensionInterface'], + $this->_model->collectEntities($this->_testFiles) + ); } } diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/_files/app/code/Magento/SomeModule/Api/Data/SomeInterface.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/_files/app/code/Magento/SomeModule/Api/Data/SomeInterface.php new file mode 100644 index 0000000000000..0e2cbcfb8d827 --- /dev/null +++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/_files/app/code/Magento/SomeModule/Api/Data/SomeInterface.php @@ -0,0 +1,15 @@ +