diff --git a/app/code/Magento/Backend/App/BackendAppList.php b/app/code/Magento/Backend/App/BackendAppList.php index 224ce9893100c6b416da0362ca9a0e3af569bf1e..afb812b823488b29898a2027afa87b6980d9974c 100644 --- a/app/code/Magento/Backend/App/BackendAppList.php +++ b/app/code/Magento/Backend/App/BackendAppList.php @@ -44,6 +44,7 @@ class BackendAppList if ($appName && isset($this->backendApps[$appName])) { return $this->backendApps[$appName]; } + return null; } /** diff --git a/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Stock.php b/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Stock.php index 0013ba1f17f1bb404640c5da4b3f8ddb2d77d632..86ed5c6a10766bb8a3f475e9b2bf70e0d4c9e279 100644 --- a/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Stock.php +++ b/app/code/Magento/Bundle/Model/ResourceModel/Indexer/Stock.php @@ -59,33 +59,27 @@ class Stock extends \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\ "bo.parent_id = product.$linkField", [] ); - $this->_addWebsiteJoinToSelect($select, false); $status = new \Zend_Db_Expr( 'MAX(' . $connection->getCheckSql('e.required_options = 0', 'i.stock_status', '0') . ')' ); - $select->columns( - 'website_id', - 'cw' - )->join( + $select->join( ['cis' => $this->getTable('cataloginventory_stock')], '', - ['stock_id'] + ['website_id', 'stock_id'] )->joinLeft( ['bs' => $this->getTable('catalog_product_bundle_selection')], 'bs.option_id = bo.option_id', [] )->joinLeft( ['i' => $idxTable], - 'i.product_id = bs.product_id AND i.website_id = cw.website_id AND i.stock_id = cis.stock_id', + 'i.product_id = bs.product_id AND i.website_id = cis.website_id AND i.stock_id = cis.stock_id', [] )->joinLeft( ['e' => $this->getTable('catalog_product_entity')], 'e.entity_id = bs.product_id', [] - )->where( - 'cw.website_id != 0' )->group( - ['product.entity_id', 'cw.website_id', 'cis.stock_id', 'bo.option_id'] + ['product.entity_id', 'cis.website_id', 'cis.stock_id', 'bo.option_id'] )->columns( ['option_id' => 'bo.option_id', 'status' => $status] ); @@ -118,45 +112,19 @@ class Stock extends \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\ protected function _getStockStatusSelect($entityIds = null, $usePrimaryTable = false) { $this->_prepareBundleOptionStockData($entityIds, $usePrimaryTable); - $linkField = $this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField(); $connection = $this->getConnection(); - $select = $connection->select()->from( - ['e' => $this->getTable('catalog_product_entity')], - ['entity_id'] - ); - $this->_addWebsiteJoinToSelect($select, true); - $this->_addProductWebsiteJoinToSelect($select, 'cw.website_id', 'e.entity_id'); - $select->columns( - 'cw.website_id' - )->join( - ['cis' => $this->getTable('cataloginventory_stock')], - '', - ['stock_id'] - )->joinLeft( - ['cisi' => $this->getTable('cataloginventory_stock_item')], - 'cisi.stock_id = cis.stock_id AND cisi.product_id = e.entity_id', - [] + $select = parent::_getStockStatusSelect($entityIds, $usePrimaryTable); + $select->reset( + \Magento\Framework\DB\Select::COLUMNS + )->columns( + ['e.entity_id', 'cis.website_id', 'cis.stock_id'] )->joinLeft( ['o' => $this->_getBundleOptionTable()], - 'o.entity_id = e.entity_id AND o.website_id = cw.website_id AND o.stock_id = cis.stock_id', + 'o.entity_id = e.entity_id AND o.website_id = cis.website_id AND o.stock_id = cis.stock_id', [] )->columns( ['qty' => new \Zend_Db_Expr('0')] - )->where( - 'cw.website_id != 0' - )->where( - 'e.type_id = ?', - $this->getTypeId() - )->group( - ['e.entity_id', 'cw.website_id', 'cis.stock_id'] - ); - - // add limitation of status - $condition = $connection->quoteInto( - '=?', - \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED ); - $this->_addAttributeToSelect($select, 'status', "e.$linkField", 'cs.store_id', $condition); $statusExpr = $this->getStatusExpression($connection); $select->columns( diff --git a/app/code/Magento/Catalog/Observer/AddCatalogToTopmenuItemsObserver.php b/app/code/Magento/Catalog/Plugin/Block/Topmenu.php similarity index 74% rename from app/code/Magento/Catalog/Observer/AddCatalogToTopmenuItemsObserver.php rename to app/code/Magento/Catalog/Plugin/Block/Topmenu.php index 608c7ee74b7cdda6409432f968734f2d1171a088..098b3282a1b107e56703ee4889f9ce005f25d223 100644 --- a/app/code/Magento/Catalog/Observer/AddCatalogToTopmenuItemsObserver.php +++ b/app/code/Magento/Catalog/Plugin/Block/Topmenu.php @@ -3,17 +3,16 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -namespace Magento\Catalog\Observer; +namespace Magento\Catalog\Plugin\Block; use Magento\Catalog\Model\Category; use Magento\Framework\Data\Collection; use Magento\Framework\Data\Tree\Node; -use Magento\Framework\Event\ObserverInterface; /** - * Observer that add Categories Tree to Topmenu + * Plugin for top menu block */ -class AddCatalogToTopmenuItemsObserver implements ObserverInterface +class Topmenu { /** * Catalog category @@ -38,11 +37,11 @@ class AddCatalogToTopmenuItemsObserver implements ObserverInterface private $layerResolver; /** + * Initialize dependencies. + * * @param \Magento\Catalog\Helper\Category $catalogCategory - * @param \Magento\Catalog\Model\Indexer\Category\Flat\State $categoryFlatState * @param \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory * @param \Magento\Store\Model\StoreManagerInterface $storeManager - * @param \Magento\Catalog\Helper\Category $catalogCategory * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver */ public function __construct( @@ -58,26 +57,27 @@ class AddCatalogToTopmenuItemsObserver implements ObserverInterface } /** - * Checking whether the using static urls in WYSIWYG allowed event + * Build category tree for menu block. * - * @param \Magento\Framework\Event\Observer $observer + * @param \Magento\Theme\Block\Html\Topmenu $subject + * @param string $outermostClass + * @param string $childrenWrapClass + * @param int $limit * @return void + * @SuppressWarnings("PMD.UnusedFormalParameter") */ - public function execute(\Magento\Framework\Event\Observer $observer) - { - $block = $observer->getEvent()->getBlock(); - $menuRootNode = $observer->getEvent()->getMenu(); - $block->addIdentity(Category::CACHE_TAG); - + public function beforeGetHtml( + \Magento\Theme\Block\Html\Topmenu $subject, + $outermostClass = '', + $childrenWrapClass = '', + $limit = 0 + ) { $rootId = $this->storeManager->getStore()->getRootCategoryId(); $storeId = $this->storeManager->getStore()->getId(); - /** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */ $collection = $this->getCategoryTree($storeId, $rootId); - $currentCategory = $this->getCurrentCategory(); - - $mapping = [$rootId => $menuRootNode]; // use nodes stack to avoid recursion + $mapping = [$rootId => $subject->getMenu()]; // use nodes stack to avoid recursion foreach ($collection as $category) { if (!isset($mapping[$category->getParentId()])) { continue; @@ -94,8 +94,28 @@ class AddCatalogToTopmenuItemsObserver implements ObserverInterface $parentCategoryNode->addChild($categoryNode); $mapping[$category->getId()] = $categoryNode; //add node in stack + } + } - $block->addIdentity(Category::CACHE_TAG . '_' . $category->getId()); + /** + * Add list of associated identities to the top menu block for caching purposes. + * + * @param \Magento\Theme\Block\Html\Topmenu $subject + * @return void + */ + public function beforeGetIdentities(\Magento\Theme\Block\Html\Topmenu $subject) + { + $subject->addIdentity(Category::CACHE_TAG); + $rootId = $this->storeManager->getStore()->getRootCategoryId(); + $storeId = $this->storeManager->getStore()->getId(); + /** @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */ + $collection = $this->getCategoryTree($storeId, $rootId); + $mapping = [$rootId => $subject->getMenu()]; // use nodes stack to avoid recursion + foreach ($collection as $category) { + if (!isset($mapping[$category->getParentId()])) { + continue; + } + $subject->addIdentity(Category::CACHE_TAG . '_' . $category->getId()); } } diff --git a/app/code/Magento/Catalog/Test/Unit/Observer/AddCatalogToTopmenuItemsObserverTest.php b/app/code/Magento/Catalog/Test/Unit/Plugin/Block/TopmenuTest.php similarity index 81% rename from app/code/Magento/Catalog/Test/Unit/Observer/AddCatalogToTopmenuItemsObserverTest.php rename to app/code/Magento/Catalog/Test/Unit/Plugin/Block/TopmenuTest.php index 393cf8223d2a2d40ed54802515cdc91fa5fc804a..e0fe2deb232f68b989abb72463268d531e5e81cd 100644 --- a/app/code/Magento/Catalog/Test/Unit/Observer/AddCatalogToTopmenuItemsObserverTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Plugin/Block/TopmenuTest.php @@ -6,16 +6,16 @@ // @codingStandardsIgnoreFile -namespace Magento\Catalog\Test\Unit\Observer; +namespace Magento\Catalog\Test\Unit\Plugin\Block; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; -class AddCatalogToTopmenuItemsObserverTest extends \PHPUnit_Framework_TestCase +class TopmenuTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\Catalog\Observer\AddCatalogToTopmenuItemsObserver + * @var \Magento\Catalog\Plugin\Block\Topmenu */ - protected $_observer; + protected $block; /** * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Helper\Category @@ -100,8 +100,8 @@ class AddCatalogToTopmenuItemsObserverTest extends \PHPUnit_Framework_TestCase $collection->expects($this->once())->method('getIterator') ->willReturn(new \ArrayIterator([])); - $this->_observer = (new ObjectManager($this))->getObject( - 'Magento\Catalog\Observer\AddCatalogToTopmenuItemsObserver', + $this->block = (new ObjectManager($this))->getObject( + \Magento\Catalog\Plugin\Block\Topmenu::class, [ 'catalogCategory' => $this->_catalogCategory, 'menuCategoryData' => $this->menuCategoryData, @@ -142,23 +142,11 @@ class AddCatalogToTopmenuItemsObserverTest extends \PHPUnit_Framework_TestCase ); $blockMock = $this->_getCleanMock('\Magento\Theme\Block\Html\Topmenu'); - - $eventMock = $this->getMock('\Magento\Framework\Event', ['getBlock'], [], '', false); - $eventMock->expects($this->once()) - ->method('getBlock') - ->will($this->returnValue($blockMock)); - - $observerMock = $this->getMock('\Magento\Framework\Event\Observer', ['getEvent', 'getMenu'], [], '', false); - $observerMock->expects($this->any()) - ->method('getEvent') - ->will($this->returnValue($eventMock)); - - return $observerMock; + return $blockMock; } public function testAddCatalogToTopMenuItems() { - $observer = $this->_preparationData(); - $this->_observer->execute($observer); + $this->block->beforeGetHtml($this->_preparationData()); } } diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index 19a4f22a3c8e9425d474873f321f08baf062113c..78e46f0c39205ee7172c890739fa60a23946affa 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -46,6 +46,9 @@ <type name="Magento\Customer\Model\ResourceModel\Visitor"> <plugin name="catalogLog" type="Magento\Catalog\Model\Plugin\Log" /> </type> + <type name="Magento\Theme\Block\Html\Topmenu"> + <plugin name="catalogTopmenu" type="Magento\Catalog\Plugin\Block\Topmenu" /> + </type> <type name="Magento\Framework\Mview\View\StateInterface"> <plugin name="setStatusForMview" type="Magento\Catalog\Model\Indexer\Category\Product\Plugin\MviewState" /> </type> diff --git a/app/code/Magento/Catalog/etc/frontend/events.xml b/app/code/Magento/Catalog/etc/frontend/events.xml index afb3c70a14ade23fc8caab37ab4f3b564ae1f917..5ef8c724683141c38d735fcd0e321615d562ce6a 100644 --- a/app/code/Magento/Catalog/etc/frontend/events.xml +++ b/app/code/Magento/Catalog/etc/frontend/events.xml @@ -12,7 +12,4 @@ <event name="customer_logout"> <observer name="catalog" instance="Magento\Catalog\Observer\Compare\BindCustomerLogoutObserver" shared="false" /> </event> - <event name="page_block_html_topmenu_gethtml_before"> - <observer name="catalog_add_topmenu_items" instance="Magento\Catalog\Observer\AddCatalogToTopmenuItemsObserver" /> - </event> </config> diff --git a/app/code/Magento/CatalogInventory/Helper/Stock.php b/app/code/Magento/CatalogInventory/Helper/Stock.php index 599b2d44e2ae38e45e7477a5c45edb426e0a164b..13e311d1fe5aeb4af1282edcf29215fe67570199 100644 --- a/app/code/Magento/CatalogInventory/Helper/Stock.php +++ b/app/code/Magento/CatalogInventory/Helper/Stock.php @@ -12,9 +12,11 @@ use Magento\CatalogInventory\Model\ResourceModel\Stock\StatusFactory; use Magento\CatalogInventory\Model\ResourceModel\Stock\Status; use Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection; use Magento\Catalog\Model\Product; +use Magento\CatalogInventory\Api\StockConfigurationInterface; /** * Class Stock + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Stock { @@ -47,6 +49,11 @@ class Stock */ private $stockRegistryProvider; + /** + * @var StockConfigurationInterface + */ + private $stockConfiguration; + /** * @param StoreManagerInterface $storeManager * @param ScopeConfigInterface $scopeConfig @@ -75,7 +82,7 @@ class Stock public function assignStatusToProduct(Product $product, $status = null) { if ($status === null) { - $websiteId = $product->getStore()->getWebsiteId(); + $websiteId = $this->getStockConfiguration()->getDefaultScopeId(); $stockStatus = $this->stockRegistryProvider->getStockStatus($product->getId(), $websiteId); $status = $stockStatus->getStockStatus(); } @@ -90,7 +97,7 @@ class Stock */ public function addStockStatusToProducts(AbstractCollection $productCollection) { - $websiteId = $this->storeManager->getStore($productCollection->getStoreId())->getWebsiteId(); + $websiteId = $this->getStockConfiguration()->getDefaultScopeId(); foreach ($productCollection as $product) { $productId = $product->getId(); $stockStatus = $this->stockRegistryProvider->getStockStatus($productId, $websiteId); @@ -161,4 +168,18 @@ class Stock } return $this->stockStatusResource; } + + /** + * @return StockConfigurationInterface + * + * @deprecated + */ + private function getStockConfiguration() + { + if ($this->stockConfiguration === null) { + $this->stockConfiguration = \Magento\Framework\App\ObjectManager::getInstance() + ->get('Magento\CatalogInventory\Api\StockConfigurationInterface'); + } + return $this->stockConfiguration; + } } diff --git a/app/code/Magento/CatalogInventory/Model/Config/Backend/Backorders.php b/app/code/Magento/CatalogInventory/Model/Config/Backend/Backorders.php index db78c8e17322bd12129cc488248cd0703bb83781..1915a576939ac0aca869e5072abb3e828820dea6 100644 --- a/app/code/Magento/CatalogInventory/Model/Config/Backend/Backorders.php +++ b/app/code/Magento/CatalogInventory/Model/Config/Backend/Backorders.php @@ -25,7 +25,6 @@ class Backorders extends AbstractValue || $this->getValue() == \Magento\CatalogInventory\Model\Stock::BACKORDERS_NO ) ) { - $this->stockIndex->rebuild(); $this->_stockIndexerProcessor->markIndexerAsInvalid(); } return parent::afterSave(); diff --git a/app/code/Magento/CatalogInventory/Model/Config/Backend/Managestock.php b/app/code/Magento/CatalogInventory/Model/Config/Backend/Managestock.php index 559e6235951dbae06698ce2def0eccbbd5dfd915..6edab6f3d4eb629e2947676c21d07fe827d52cdd 100644 --- a/app/code/Magento/CatalogInventory/Model/Config/Backend/Managestock.php +++ b/app/code/Magento/CatalogInventory/Model/Config/Backend/Managestock.php @@ -20,7 +20,6 @@ class Managestock extends AbstractValue public function afterSave() { if ($this->isValueChanged()) { - $this->stockIndex->rebuild(); $this->_stockIndexerProcessor->markIndexerAsInvalid(); } return parent::afterSave(); diff --git a/app/code/Magento/CatalogInventory/Model/Configuration.php b/app/code/Magento/CatalogInventory/Model/Configuration.php index 445057c4c08d8174768a9237359bdb4f830066cd..d1509eec3d4adce87cfd4b8ecf75f63485bbeff5 100644 --- a/app/code/Magento/CatalogInventory/Model/Configuration.php +++ b/app/code/Magento/CatalogInventory/Model/Configuration.php @@ -148,7 +148,9 @@ class Configuration implements StockConfigurationInterface */ public function getDefaultScopeId() { - return (int) $this->storeManager->getWebsite()->getId(); + // TODO: should be fixed in MAGETWO-46043 + // "0" is id of admin website, which is used in backend during save entity + return 0; } /** diff --git a/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php b/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php index 82e9e1b1c94c607103230917753f0aa1c5afaede..df910254082185145212c325568a971a75a9bd85 100644 --- a/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php +++ b/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php @@ -24,6 +24,7 @@ class AroundProductRepositorySave /** * @var StoreManagerInterface + * @deprecated */ protected $storeManager; @@ -80,7 +81,7 @@ class AroundProductRepositorySave // set fields that the customer should not care about $stockItem->setProductId($product->getId()); - $stockItem->setWebsiteId($this->storeManager->getStore($product->getStoreId())->getWebsiteId()); + $stockItem->setWebsiteId($this->stockConfiguration->getDefaultScopeId()); $this->stockRegistry->updateStockItemBySku($product->getSku(), $stockItem); diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php index 3bb9ef4c4d5c6f847d17365df179f54b0b678752..40245db2f3372234ad18a988140195e88a11b971 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStock.php @@ -9,6 +9,7 @@ namespace Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock; use Magento\Catalog\Model\ResourceModel\Product\Indexer\AbstractIndexer; use Magento\CatalogInventory\Model\Stock; use Magento\Framework\DB\Adapter\AdapterInterface; +use Magento\CatalogInventory\Api\StockConfigurationInterface; /** * CatalogInventory Default Stock Status Indexer Resource Model @@ -42,6 +43,11 @@ class DefaultStock extends AbstractIndexer implements StockInterface */ private $queryProcessorComposite; + /** + * @var StockConfigurationInterface + */ + protected $stockConfiguration; + /** * Class constructor * @@ -176,43 +182,29 @@ class DefaultStock extends AbstractIndexer implements StockInterface */ protected function _getStockStatusSelect($entityIds = null, $usePrimaryTable = false) { - $metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); $connection = $this->getConnection(); $qtyExpr = $connection->getCheckSql('cisi.qty > 0', 'cisi.qty', 0); $select = $connection->select()->from( ['e' => $this->getTable('catalog_product_entity')], ['entity_id'] ); - $this->_addWebsiteJoinToSelect($select, true); - $this->_addProductWebsiteJoinToSelect($select, 'cw.website_id', 'e.entity_id'); - $select->columns('cw.website_id')->join( + $select->join( ['cis' => $this->getTable('cataloginventory_stock')], '', - ['stock_id'] - )->joinLeft( + ['website_id', 'stock_id'] + )->joinInner( ['cisi' => $this->getTable('cataloginventory_stock_item')], 'cisi.stock_id = cis.stock_id AND cisi.product_id = e.entity_id', [] - )->columns(['qty' => new \Zend_Db_Expr('SUM(' . $qtyExpr . ')')]) - ->where('cw.website_id != 0') - ->where('e.type_id = ?', $this->getTypeId()) - ->group(['e.entity_id', 'cw.website_id']); - - // add limitation of status - $condition = $connection->quoteInto( - '=?', - \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED - ); - $this->_addAttributeToSelect( - $select, - 'status', - 'e.' . $metadata->getLinkField(), - 'cs.store_id', - $condition - ); + )->columns( + ['qty' => $qtyExpr] + )->where( + 'cis.website_id = ?', + $this->getStockConfiguration()->getDefaultScopeId() + )->where('e.type_id = ?', $this->getTypeId()) + ->group(['e.entity_id', 'cis.website_id', 'cis.stock_id']); $select->columns(['status' => $this->getStatusExpression($connection, true)]); - if ($entityIds !== null) { $select->where('e.entity_id IN(?)', $entityIds); } @@ -325,6 +317,20 @@ class DefaultStock extends AbstractIndexer implements StockInterface return $statusExpr; } + /** + * @return StockConfigurationInterface + * + * @deprecated + */ + protected function getStockConfiguration() + { + if ($this->stockConfiguration === null) { + $this->stockConfiguration = \Magento\Framework\App\ObjectManager::getInstance() + ->get('Magento\CatalogInventory\Api\StockConfigurationInterface'); + } + return $this->stockConfiguration; + } + /** * @return QueryProcessorComposite */ diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock.php index f4877e6a3de68fd72a6550d1b6bf6c5b611593bb..17a3e0c9a99494de5efdb4f6825c33fae9e41e54 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock.php @@ -75,6 +75,7 @@ class Stock extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb impleme /** * @var StoreManagerInterface + * @deprecated */ protected $storeManager; @@ -189,11 +190,12 @@ class Stock extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb impleme * Set items out of stock basing on their quantities and config settings * * @param string|int $website + * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @return void */ public function updateSetOutOfStock($website = null) { - $websiteId = $this->storeManager->getWebsite($website)->getId(); + $websiteId = $this->stockConfiguration->getDefaultScopeId(); $this->_initConfig(); $connection = $this->getConnection(); $values = ['is_in_stock' => 0, 'stock_status_changed_auto' => 1]; @@ -223,11 +225,12 @@ class Stock extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb impleme * Set items in stock basing on their quantities and config settings * * @param int|string $website + * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @return void */ public function updateSetInStock($website) { - $websiteId = $this->storeManager->getWebsite($website)->getId(); + $websiteId = $this->stockConfiguration->getDefaultScopeId(); $this->_initConfig(); $connection = $this->getConnection(); $values = ['is_in_stock' => 1]; @@ -255,11 +258,12 @@ class Stock extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb impleme * Update items low stock date basing on their quantities and config settings * * @param int|string $website + * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @return void */ public function updateLowStockDate($website) { - $websiteId = $this->storeManager->getWebsite($website)->getId(); + $websiteId = $this->stockConfiguration->getDefaultScopeId(); $this->_initConfig(); $connection = $this->getConnection(); diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item.php index d08bd31df9eeb517f3577ce3aff34de85c42479f..32d21f388f03e30510dfb1179fdf335654b4c0a4 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item.php @@ -57,13 +57,13 @@ class Item extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb * * @param \Magento\CatalogInventory\Api\Data\StockItemInterface $item * @param int $productId - * @param int $websiteId + * @param int $stockId * @return $this */ - public function loadByProductId(\Magento\CatalogInventory\Api\Data\StockItemInterface $item, $productId, $websiteId) + public function loadByProductId(\Magento\CatalogInventory\Api\Data\StockItemInterface $item, $productId, $stockId) { - $select = $this->_getLoadSelect('product_id', $productId, $item)->where('website_id = :website_id'); - $data = $this->getConnection()->fetchRow($select, [':website_id' => $websiteId]); + $select = $this->_getLoadSelect('product_id', $productId, $item)->where('stock_id = :stock_id'); + $data = $this->getConnection()->fetchRow($select, [':stock_id' => $stockId]); if ($data) { $item->setData($data); } else { diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item/StockItemCriteriaMapper.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item/StockItemCriteriaMapper.php index 551f5e0c3b8fffd04eaac0e5c18bd1a1977990d6..d1e038071ecc52a7adf9f5452076e95cd06358e5 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item/StockItemCriteriaMapper.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Item/StockItemCriteriaMapper.php @@ -13,6 +13,7 @@ use Magento\Framework\Data\ObjectFactory; use Magento\Store\Model\StoreManagerInterface; use Psr\Log\LoggerInterface as Logger; use Magento\Framework\Data\Collection\Db\FetchStrategyInterface; +use Magento\CatalogInventory\Api\StockConfigurationInterface; /** * Interface StockItemCriteriaMapper @@ -20,6 +21,17 @@ use Magento\Framework\Data\Collection\Db\FetchStrategyInterface; */ class StockItemCriteriaMapper extends GenericMapper { + /** + * @var StockConfigurationInterface + */ + private $stockConfiguration; + + /** + * @var StoreManagerInterface + * @deprecated + */ + private $storeManager; + /** * @param Logger $logger * @param FetchStrategyInterface $fetchStrategy @@ -107,10 +119,11 @@ class StockItemCriteriaMapper extends GenericMapper /** * @inheritdoc + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function mapStockStatus($storeId = null) { - $websiteId = $this->storeManager->getStore($storeId)->getWebsiteId(); + $websiteId = $this->getStockConfiguration()->getDefaultScopeId(); $this->getSelect()->joinLeft( ['status_table' => $this->getTable('cataloginventory_stock_status')], 'main_table.product_id=status_table.product_id' . @@ -149,4 +162,18 @@ class StockItemCriteriaMapper extends GenericMapper } $this->addFieldToFilter('main_table.qty', [$methods[$comparisonMethod] => $qty]); } + + /** + * @return StockConfigurationInterface + * + * @deprecated + */ + private function getStockConfiguration() + { + if ($this->stockConfiguration === null) { + $this->stockConfiguration = \Magento\Framework\App\ObjectManager::getInstance() + ->get('Magento\CatalogInventory\Api\StockConfigurationInterface'); + } + return $this->stockConfiguration; + } } diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php index 75b325458ccaa2c9c4bfb3c0c16ffc381c7cab90..f7410de156fb42e4549b3d1910d5c5d9d5fb0d27 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Stock/Status.php @@ -6,9 +6,11 @@ namespace Magento\CatalogInventory\Model\ResourceModel\Stock; use Magento\CatalogInventory\Model\Stock; +use Magento\CatalogInventory\Api\StockConfigurationInterface; /** * CatalogInventory Stock Status per website Resource Model + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { @@ -16,6 +18,7 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb * Store model manager * * @var \Magento\Store\Model\StoreManagerInterface + * @deprecated */ protected $_storeManager; @@ -31,6 +34,11 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ protected $eavConfig; + /** + * @var StockConfigurationInterface + */ + private $stockConfiguration; + /** * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param \Magento\Store\Model\StoreManagerInterface $storeManager @@ -190,11 +198,12 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb * * @param \Magento\Framework\DB\Select $select * @param \Magento\Store\Model\Website $website + * @SuppressWarnings(PHPMD.UnusedFormalParameter) * @return Status */ public function addStockStatusToSelect(\Magento\Framework\DB\Select $select, \Magento\Store\Model\Website $website) { - $websiteId = $website->getId(); + $websiteId = $this->getStockConfiguration()->getDefaultScopeId(); $select->joinLeft( ['stock_status' => $this->getMainTable()], 'e.entity_id = stock_status.product_id AND stock_status.website_id=' . $websiteId, @@ -211,7 +220,7 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ public function addStockDataToCollection($collection, $isFilterInStock) { - $websiteId = $this->_storeManager->getStore($collection->getStoreId())->getWebsiteId(); + $websiteId = $this->getStockConfiguration()->getDefaultScopeId(); $joinCondition = $this->getConnection()->quoteInto( 'e.entity_id = stock_status_index.product_id' . ' AND stock_status_index.website_id = ?', $websiteId @@ -245,7 +254,7 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ public function addIsInStockFilterToCollection($collection) { - $websiteId = $this->_storeManager->getStore($collection->getStoreId())->getWebsiteId(); + $websiteId = $this->getStockConfiguration()->getDefaultScopeId(); $joinCondition = $this->getConnection()->quoteInto( 'e.entity_id = stock_status_index.product_id' . ' AND stock_status_index.website_id = ?', $websiteId @@ -325,4 +334,18 @@ class Status extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb } return $statuses; } + + /** + * @return StockConfigurationInterface + * + * @deprecated + */ + private function getStockConfiguration() + { + if ($this->stockConfiguration === null) { + $this->stockConfiguration = \Magento\Framework\App\ObjectManager::getInstance() + ->get('Magento\CatalogInventory\Api\StockConfigurationInterface'); + } + return $this->stockConfiguration; + } } diff --git a/app/code/Magento/CatalogInventory/Model/StockIndex.php b/app/code/Magento/CatalogInventory/Model/StockIndex.php index a30bc203c638f251e167fa5f88eb6d9eaca6ef21..226293c8205e67acd32953463485713d64729128 100644 --- a/app/code/Magento/CatalogInventory/Model/StockIndex.php +++ b/app/code/Magento/CatalogInventory/Model/StockIndex.php @@ -78,6 +78,7 @@ class StockIndex implements StockIndexInterface * * @param int $productId * @param int $scopeId + * @deprecated * @return true * @SuppressWarnings(PHPMD.UnusedLocalVariable) */ @@ -108,6 +109,7 @@ class StockIndex implements StockIndexInterface * * @param int $productId * @param int $websiteId + * @deprecated * @return void */ public function updateProductStockStatus($productId, $websiteId) diff --git a/app/code/Magento/CatalogInventory/Model/StockState.php b/app/code/Magento/CatalogInventory/Model/StockState.php index a5f60dce93ca7b45d3d4c4aa8783df95e72a7d80..0c8b84d473e45a47ab2ceaf69cf5089f5818a9b3 100644 --- a/app/code/Magento/CatalogInventory/Model/StockState.php +++ b/app/code/Magento/CatalogInventory/Model/StockState.php @@ -52,9 +52,9 @@ class StockState implements StockStateInterface */ public function verifyStock($productId, $scopeId = null) { - if ($scopeId === null) { + // if ($scopeId === null) { $scopeId = $this->stockConfiguration->getDefaultScopeId(); - } + // } $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId); return $this->stockStateProvider->verifyStock($stockItem); } @@ -66,9 +66,9 @@ class StockState implements StockStateInterface */ public function verifyNotification($productId, $scopeId = null) { - if ($scopeId === null) { + // if ($scopeId === null) { $scopeId = $this->stockConfiguration->getDefaultScopeId(); - } + // } $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId); return $this->stockStateProvider->verifyNotification($stockItem); } @@ -84,9 +84,9 @@ class StockState implements StockStateInterface */ public function checkQty($productId, $qty, $scopeId = null) { - if ($scopeId === null) { + // if ($scopeId === null) { $scopeId = $this->stockConfiguration->getDefaultScopeId(); - } + // } $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId); return $this->stockStateProvider->checkQty($stockItem, $qty); } @@ -102,9 +102,9 @@ class StockState implements StockStateInterface */ public function suggestQty($productId, $qty, $scopeId = null) { - if ($scopeId === null) { + // if ($scopeId === null) { $scopeId = $this->stockConfiguration->getDefaultScopeId(); - } + // } $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId); return $this->stockStateProvider->suggestQty($stockItem, $qty); } @@ -118,9 +118,9 @@ class StockState implements StockStateInterface */ public function getStockQty($productId, $scopeId = null) { - if ($scopeId === null) { + // if ($scopeId === null) { $scopeId = $this->stockConfiguration->getDefaultScopeId(); - } + // } $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId); return $this->stockStateProvider->getStockQty($stockItem); } @@ -133,9 +133,9 @@ class StockState implements StockStateInterface */ public function checkQtyIncrements($productId, $qty, $websiteId = null) { - if ($websiteId === null) { + // if ($websiteId === null) { $websiteId = $this->stockConfiguration->getDefaultScopeId(); - } + // } $stockItem = $this->stockRegistryProvider->getStockItem($productId, $websiteId); return $this->stockStateProvider->checkQtyIncrements($stockItem, $qty); } @@ -150,9 +150,9 @@ class StockState implements StockStateInterface */ public function checkQuoteItemQty($productId, $itemQty, $qtyToCheck, $origQty, $scopeId = null) { - if ($scopeId === null) { + // if ($scopeId === null) { $scopeId = $this->stockConfiguration->getDefaultScopeId(); - } + // } $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId); return $this->stockStateProvider->checkQuoteItemQty($stockItem, $itemQty, $qtyToCheck, $origQty); } diff --git a/app/code/Magento/CatalogInventory/Observer/SaveInventoryDataObserver.php b/app/code/Magento/CatalogInventory/Observer/SaveInventoryDataObserver.php index d700b296871aa2faf5fcc62a5ef3b6822c2cbe24..72c9b35394717deb7b22b24fa89236d5e559e1bd 100644 --- a/app/code/Magento/CatalogInventory/Observer/SaveInventoryDataObserver.php +++ b/app/code/Magento/CatalogInventory/Observer/SaveInventoryDataObserver.php @@ -17,6 +17,7 @@ class SaveInventoryDataObserver implements ObserverInterface { /** * @var StockIndexInterface + * @deprecated */ protected $stockIndex; @@ -96,14 +97,7 @@ class SaveInventoryDataObserver implements ObserverInterface public function execute(EventObserver $observer) { $product = $observer->getEvent()->getProduct(); - if ($product->getStockData() === null) { - if ($product->getIsChangedWebsites() || $product->dataHasChangedFor('status')) { - $this->stockIndex->rebuild( - $product->getId(), - $product->getStore()->getWebsiteId() - ); - } return $this; } diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Helper/StockTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Helper/StockTest.php index 1f1c7a98f0907a6cea0b863477a6f57af1200f7d..df5ea40e933075bb07dd398ab3514e2cf18960d6 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Helper/StockTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Helper/StockTest.php @@ -37,6 +37,11 @@ class StockTest extends \PHPUnit_Framework_TestCase */ protected $statusFactoryMock; + /** + * @var \Magento\CatalogInventory\Api\StockConfigurationInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $stockConfiguration; + protected function setUp() { $this->stockRegistryProviderMock = $this->getMockBuilder( @@ -55,12 +60,20 @@ class StockTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); + $this->stockConfiguration = $this->getMockBuilder('Magento\CatalogInventory\Api\StockConfigurationInterface') + ->getMock(); $this->stock = new Stock( $this->storeManagerMock, $this->scopeConfigMock, $this->statusFactoryMock, $this->stockRegistryProviderMock ); + + // Todo: \Magento\Framework\TestFramework\Unit\Helper\ObjectManager to do this automatically (MAGETWO-49793) + $reflection = new \ReflectionClass(get_class($this->stock)); + $reflectionProperty = $reflection->getProperty('stockConfiguration'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($this->stock, $this->stockConfiguration); } public function testAssignStatusToProduct() @@ -77,19 +90,12 @@ class StockTest extends \PHPUnit_Framework_TestCase $this->stockRegistryProviderMock->expects($this->any()) ->method('getStockStatus') ->willReturn($stockStatusMock); - $storeMock = $this->getMockBuilder('Magento\Store\Model\Store') - ->disableOriginalConstructor() - ->getMock(); - $storeMock->expects($this->once()) - ->method('getWebsiteId') - ->willReturn($websiteId); + $this->stockConfiguration->expects($this->once())->method('getDefaultScopeId')->willReturn($websiteId); + $productMock = $this->getMockBuilder('Magento\Catalog\Model\Product') ->disableOriginalConstructor() - ->setMethods(['setIsSalable', 'getStore', 'getId']) + ->setMethods(['setIsSalable', 'getId']) ->getMock(); - $productMock->expects($this->any()) - ->method('getStore') - ->willReturn($storeMock); $productMock->expects($this->once()) ->method('setIsSalable') ->with($status); @@ -134,12 +140,6 @@ class StockTest extends \PHPUnit_Framework_TestCase $productCollectionMock->expects($this->any()) ->method('getIterator') ->willReturn($iteratorMock); - $storeMock = $this->getMockBuilder('Magento\Store\Model\Store') - ->disableOriginalConstructor() - ->getMock(); - $this->storeManagerMock->expects($this->once()) - ->method('getStore') - ->willReturn($storeMock); $this->stockRegistryProviderMock->expects($this->once()) ->method('getStockStatus') ->withAnyParameters() diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Config/Backend/ManagestockTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Config/Backend/ManagestockTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b180ba0e035173514ebb444bec4e2c4487567577 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Config/Backend/ManagestockTest.php @@ -0,0 +1,53 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogInventory\Test\Unit\Model\Config\Backend; + +class ManagestockTest extends \PHPUnit_Framework_TestCase +{ + /** @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor|\PHPUnit_Framework_MockObject_MockObject */ + protected $stockIndexerProcessor; + + /** @var \Magento\CatalogInventory\Model\Config\Backend\Managestock */ + protected $model; + + protected function setUp() + { + $this->stockIndexerProcessor = $this->getMockBuilder('Magento\CatalogInventory\Model\Indexer\Stock\Processor') + ->disableOriginalConstructor() + ->getMock(); + $this->model = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject( + 'Magento\CatalogInventory\Model\Config\Backend\Managestock', + [ + 'stockIndexerProcessor' => $this->stockIndexerProcessor, + ] + ); + } + + /** + * Data provider for testSaveAndRebuildIndex + * @return array + */ + public function saveAndRebuildIndexDataProvider() + { + return [ + [1, 1], + [0, 0], + ]; + } + + /** + * @dataProvider saveAndRebuildIndexDataProvider + * + * @param int $newStockValue new value for stock status + * @param int $callCount count matcher + */ + public function testSaveAndRebuildIndex($newStockValue, $callCount) + { + $this->model->setValue($newStockValue); + $this->stockIndexerProcessor->expects($this->exactly($callCount))->method('markIndexerAsInvalid'); + $this->model->afterSave(); + } +} diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/ConfigurationTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/ConfigurationTest.php index 90b05b2d10649ce527debbea0f368d5e385f55bc..a0b2cc7225c9efe60c158b0e71946a22d5cb5512 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/ConfigurationTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/ConfigurationTest.php @@ -61,17 +61,7 @@ class ConfigurationTest extends \PHPUnit_Framework_TestCase public function testGetDefaultWebsiteId() { - $id = 1; - $websiteMock = $this->getMockBuilder('Magento\Store\Model\Website') - ->disableOriginalConstructor() - ->getMock(); - $websiteMock->expects($this->once()) - ->method('getId') - ->willReturn($id); - $this->storeManagerMock->expects($this->once()) - ->method('getWebsite') - ->willReturn($websiteMock); - $this->assertEquals($id, $this->model->getDefaultScopeId()); + $this->assertEquals(0, $this->model->getDefaultScopeId()); } public function testGetIsQtyTypeIds() diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php index 534960b4397833d268c56ab62c9a45d46cc997f9..cb26fda9be79e928dac5585694e71778661bf0f6 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php @@ -154,11 +154,7 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase ->method('getStockItem') ->willReturn(null); - $storeMock = $this->getMockBuilder('\Magento\Store\Model\Store') - ->disableOriginalConstructor()->getMock(); - $storeMock->expects($this->once())->method('getWebsiteId')->willReturn(1); - $this->storeManager->expects($this->once())->method('getStore')->willReturn($storeMock); - + $this->stockConfiguration->expects($this->once())->method('getDefaultScopeId')->willReturn(1); $this->stockRegistry->expects($this->once())->method('getStockItem')->willReturn($this->stockItem); $this->stockRegistry->expects($this->once())->method('updateStockItemBySku'); @@ -180,11 +176,10 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase public function testAroundSave() { $productId = 5494; - $websiteId = 1; $storeId = 2; $sku = 'my product that needs saving'; $defaultScopeId = 100; - $this->stockConfiguration->expects($this->once()) + $this->stockConfiguration->expects($this->exactly(2)) ->method('getDefaultScopeId') ->willReturn($defaultScopeId); $this->stockRegistry->expects($this->once()) @@ -209,17 +204,12 @@ class AroundProductRepositorySaveTest extends \PHPUnit_Framework_TestCase ->method('getStockItem') ->willReturn($storedStockItem); - $storeMock = $this->getMockBuilder('\Magento\Store\Model\Store') - ->disableOriginalConstructor()->getMock(); - $storeMock->expects($this->once())->method('getWebsiteId')->willReturn($websiteId); - $this->storeManager->expects($this->once())->method('getStore')->with($storeId)->willReturn($storeMock); - $this->product->expects(($this->exactly(2)))->method('getId')->willReturn($productId); $this->product->expects(($this->atLeastOnce()))->method('getStoreId')->willReturn($storeId); $this->product->expects($this->atLeastOnce())->method('getSku')->willReturn($sku); $this->stockItem->expects($this->once())->method('setProductId')->with($productId); - $this->stockItem->expects($this->once())->method('setWebsiteId')->with($websiteId); + $this->stockItem->expects($this->once())->method('setWebsiteId')->with($defaultScopeId); $this->stockRegistry->expects($this->once()) ->method('updateStockItemBySku') diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Observer/SaveInventoryDataObserverTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Observer/SaveInventoryDataObserverTest.php deleted file mode 100644 index 1b8347539485d11ff30b22ea3803201cf08004f2..0000000000000000000000000000000000000000 --- a/app/code/Magento/CatalogInventory/Test/Unit/Observer/SaveInventoryDataObserverTest.php +++ /dev/null @@ -1,95 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\CatalogInventory\Test\Unit\Observer; - -use Magento\CatalogInventory\Observer\SaveInventoryDataObserver; - -class SaveInventoryDataObserverTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var SaveInventoryDataObserver - */ - protected $observer; - - /** - * @var \Magento\CatalogInventory\Api\StockIndexInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $stockIndex; - - /** - * @var \Magento\Framework\Event|\PHPUnit_Framework_MockObject_MockObject - */ - protected $event; - - /** - * @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject - */ - protected $eventObserver; - - protected function setUp() - { - $this->stockIndex = $this->getMockForAbstractClass( - 'Magento\CatalogInventory\Api\StockIndexInterface', - ['rebuild'], - '', - false - ); - - $this->event = $this->getMockBuilder('Magento\Framework\Event') - ->disableOriginalConstructor() - ->setMethods(['getProduct']) - ->getMock(); - - $this->eventObserver = $this->getMockBuilder('Magento\Framework\Event\Observer') - ->disableOriginalConstructor() - ->setMethods(['getEvent']) - ->getMock(); - - $this->eventObserver->expects($this->atLeastOnce()) - ->method('getEvent') - ->will($this->returnValue($this->event)); - - $this->observer = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))->getObject( - 'Magento\CatalogInventory\Observer\SaveInventoryDataObserver', - [ - 'stockIndex' => $this->stockIndex, - ] - ); - } - - public function testSaveInventoryData() - { - $productId = 4; - $websiteId = 5; - $stockData = null; - $websitesChanged = true; - $statusChanged = true; - - $store = $this->getMock('Magento\Store\Model\Store', ['getWebsiteId'], [], '', false); - $store->expects($this->once())->method('getWebsiteId')->will($this->returnValue($websiteId)); - - $product = $this->getMock( - 'Magento\Catalog\Model\Product', - ['getStockData', 'getIsChangedWebsites', 'dataHasChangedFor', 'getId', 'getStore'], - [], - '', - false - ); - $product->expects($this->once())->method('getStockData')->will($this->returnValue($stockData)); - $product->expects($this->any())->method('getIsChangedWebsites')->will($this->returnValue($websitesChanged)); - $product->expects($this->any())->method('dataHasChangedFor')->will($this->returnValue($statusChanged)); - $product->expects($this->once())->method('getId')->will($this->returnValue($productId)); - $product->expects($this->once())->method('getStore')->will($this->returnValue($store)); - - $this->stockIndex->expects($this->once())->method('rebuild')->will($this->returnValue(true)); - - $this->event->expects($this->once()) - ->method('getProduct') - ->will($this->returnValue($product)); - - $this->observer->execute($this->eventObserver); - } -} diff --git a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php index 72134fb16912939f5a80e42e8803fd7120e6f3a5..31ce6d550b116455052cf674e99155db3e3f7af2 100644 --- a/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php +++ b/app/code/Magento/CatalogSearch/Model/Search/IndexBuilder.php @@ -6,20 +6,18 @@ namespace Magento\CatalogSearch\Model\Search; -use Magento\CatalogSearch\Model\Search\TableMapper; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Framework\App\ResourceConnection; use Magento\Framework\DB\Select; use Magento\Framework\Search\Adapter\Mysql\ConditionManager; use Magento\Framework\Search\Adapter\Mysql\IndexBuilderInterface; use Magento\Framework\Search\Request\Dimension; -use Magento\Framework\Search\Request\Filter\BoolExpression; -use Magento\Framework\Search\Request\FilterInterface; -use Magento\Framework\Search\Request\QueryInterface as RequestQueryInterface; use Magento\Framework\Search\RequestInterface; use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver; use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; +use Magento\CatalogInventory\Api\StockConfigurationInterface; +use Magento\CatalogInventory\Model\Stock; use Magento\Framework\App\ScopeResolverInterface; /** @@ -40,6 +38,7 @@ class IndexBuilder implements IndexBuilderInterface /** * @var StoreManagerInterface + * @deprecated */ private $storeManager; @@ -63,6 +62,11 @@ class IndexBuilder implements IndexBuilderInterface */ private $dimensionScopeResolver; + /** + * @var StockConfigurationInterface + */ + private $stockConfiguration; + /** * @param \Magento\Framework\App\ResourceConnection $resource * @param ScopeConfigInterface $config @@ -124,16 +128,30 @@ class IndexBuilder implements IndexBuilderInterface 'search_index.entity_id = stock_index.product_id' . $this->resource->getConnection()->quoteInto( ' AND stock_index.website_id = ?', - $this->storeManager->getWebsite()->getId() + $this->getStockConfiguration()->getDefaultScopeId() ), [] ); - $select->where('stock_index.stock_status = ?', 1); + $select->where('stock_index.stock_status = ?', Stock::DEFAULT_STOCK_ID); } return $select; } + /** + * @return StockConfigurationInterface + * + * @deprecated + */ + private function getStockConfiguration() + { + if ($this->stockConfiguration === null) { + $this->stockConfiguration = \Magento\Framework\App\ObjectManager::getInstance() + ->get('Magento\CatalogInventory\Api\StockConfigurationInterface'); + } + return $this->stockConfiguration; + } + /** * Add filtering by dimensions * diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php index 73dfd3867b0dcaf870794e6195d508309f440600..32176594936b2d996b1e14c758cf0671c76a73f5 100644 --- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php +++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/IndexBuilderTest.php @@ -40,6 +40,9 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Search\Model\IndexScopeResolver|\PHPUnit_Framework_MockObject_MockObject */ private $resource; + /** @var \Magento\CatalogInventory\Api\StockConfigurationInterface|MockObject */ + private $stockConfiguration; + /** * @var \Magento\CatalogSearch\Model\Search\IndexBuilder */ @@ -55,6 +58,10 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase */ private $scopeInterface; + /** + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @return void + */ protected function setUp() { $this->select = $this->getMockBuilder('\Magento\Framework\DB\Select') @@ -139,6 +146,9 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase '', false ); + $this->stockConfiguration = $this + ->getMockBuilder('\Magento\CatalogInventory\Api\StockConfigurationInterface') + ->getMock(); $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->target = $objectManagerHelper->getObject( @@ -153,6 +163,12 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase 'dimensionScopeResolver' => $this->dimensionScopeResolver ] ); + + // Todo: \Magento\Framework\TestFramework\Unit\Helper\ObjectManager to do this automatically (MAGETWO-49793) + $reflection = new \ReflectionClass(get_class($this->target)); + $reflectionProperty = $reflection->getProperty('stockConfiguration'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($this->target, $this->stockConfiguration); } public function testBuildWithOutOfStock() @@ -198,15 +214,13 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase $this->mockBuild($index, $tableSuffix, false); + $this->stockConfiguration->expects($this->once())->method('getDefaultScopeId')->willReturn(1); $this->config->expects($this->once()) ->method('isSetFlag') ->with('cataloginventory/options/show_out_of_stock') ->will($this->returnValue(false)); $this->connection->expects($this->once())->method('quoteInto') ->with(' AND stock_index.website_id = ?', 1)->willReturn(' AND stock_index.website_id = 1'); - $website = $this->getMockBuilder('Magento\Store\Model\Website')->disableOriginalConstructor()->getMock(); - $website->expects($this->once())->method('getId')->willReturn(1); - $this->storeManager->expects($this->once())->method('getWebsite')->willReturn($website); $this->select->expects($this->at(2)) ->method('where') ->with('(someName=someValue)') diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json index 709009300b724a41dbca6c80773684af9c15e91e..860d5080b9bdffd0282c5b989c8373b886d498af 100644 --- a/app/code/Magento/CatalogSearch/composer.json +++ b/app/code/Magento/CatalogSearch/composer.json @@ -11,6 +11,7 @@ "magento/module-eav": "100.0.*", "magento/module-backend": "100.0.*", "magento/module-theme": "100.0.*", + "magento/module-catalog-inventory": "100.0.*", "magento/framework": "100.0.*" }, "type": "magento2-module", diff --git a/app/code/Magento/CatalogWidget/Model/Rule/Condition/Combine.php b/app/code/Magento/CatalogWidget/Model/Rule/Condition/Combine.php index 386e77580fa4abab025f3119b056f08b2be88084..6f2cd40e97f7ad19fb5cd217881403a11a594268 100644 --- a/app/code/Magento/CatalogWidget/Model/Rule/Condition/Combine.php +++ b/app/code/Magento/CatalogWidget/Model/Rule/Condition/Combine.php @@ -71,7 +71,9 @@ class Combine extends \Magento\Rule\Model\Condition\Combine */ public function collectValidatedAttributes($productCollection) { + $alias = array_keys($productCollection->getSelect()->getPart('from'))[0]; foreach ($this->getConditions() as $condition) { + $condition->setData('attribute', $alias . '.' . $condition->getData('attribute')); $condition->addToCollection($productCollection); } return $this; diff --git a/app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/CombineTest.php b/app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/CombineTest.php index 34c14626d8bf7423d435c62e952c663a8b52f9ae..b0a3fdab8eb32c6c97ef798a94390f7a942f04a2 100644 --- a/app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/CombineTest.php +++ b/app/code/Magento/CatalogWidget/Test/Unit/Model/Rule/Condition/CombineTest.php @@ -73,8 +73,13 @@ class CombineTest extends \PHPUnit_Framework_TestCase public function testCollectValidatedAttributes() { $collection = $this->getMockBuilder('\Magento\Catalog\Model\ResourceModel\Product\Collection') - ->disableOriginalConstructor() + ->disableOriginalConstructor()->setMethods(['getSelect']) + ->getMock(); + $select = $this->getMockBuilder('\Magento\Framework\DB\Select') + ->disableOriginalConstructor()->setMethods(['getPart']) ->getMock(); + $select->expects($this->any())->method('getPart')->with('from')->willReturn(['alias_table' => 'table_name']); + $collection->expects($this->any())->method('getSelect')->willReturn($select); $condition = $this->getMockBuilder('Magento\CatalogWidget\Model\Rule\Condition\Combine') ->disableOriginalConstructor()->setMethods(['addToCollection']) ->getMock(); diff --git a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Indexer/Stock/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Indexer/Stock/Configurable.php index 551df288ebcb03e2941a618ec28e667265b0af99..6f2b989e5e9bfaa9fa91643b1958be6a99c0fdc1 100644 --- a/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Indexer/Stock/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/ResourceModel/Indexer/Stock/Configurable.php @@ -28,19 +28,11 @@ class Configurable extends \Magento\CatalogInventory\Model\ResourceModel\Indexer $metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); $connection = $this->getConnection(); $idxTable = $usePrimaryTable ? $this->getMainTable() : $this->getIdxTable(); - $select = $connection->select()->from(['e' => $this->getTable('catalog_product_entity')], ['entity_id']); - $this->_addWebsiteJoinToSelect($select, true); - $this->_addProductWebsiteJoinToSelect($select, 'cw.website_id', 'e.entity_id'); - $select->columns( - 'cw.website_id' - )->join( - ['cis' => $this->getTable('cataloginventory_stock')], - '', - ['stock_id'] - )->joinLeft( - ['cisi' => $this->getTable('cataloginventory_stock_item')], - 'cisi.stock_id = cis.stock_id AND cisi.product_id = e.entity_id', - [] + $select = parent::_getStockStatusSelect($entityIds, $usePrimaryTable); + $select->reset( + \Magento\Framework\DB\Select::COLUMNS + )->columns( + ['e.entity_id', 'cis.website_id', 'cis.stock_id'] )->joinLeft( ['l' => $this->getTable('catalog_product_super_link')], 'l.parent_id = e.' . $metadata->getLinkField(), @@ -51,24 +43,14 @@ class Configurable extends \Magento\CatalogInventory\Model\ResourceModel\Indexer [] )->joinLeft( ['i' => $idxTable], - 'i.product_id = l.product_id AND cw.website_id = i.website_id AND cis.stock_id = i.stock_id', + 'i.product_id = l.product_id AND cis.website_id = i.website_id AND cis.stock_id = i.stock_id', [] )->columns( ['qty' => new \Zend_Db_Expr('0')] - )->where( - 'cw.website_id != 0' - )->where( - 'e.type_id = ?', - $this->getTypeId() - )->group( - ['e.entity_id', 'cw.website_id', 'cis.stock_id'] ); - $psExpr = $this->_addAttributeToSelect($select, 'status', 'e.' . $metadata->getLinkField(), 'cs.store_id'); - $psCond = $connection->quoteInto($psExpr . '=?', ProductStatus::STATUS_ENABLED); - $statusExpr = $this->getStatusExpression($connection); - $optExpr = $connection->getCheckSql("{$psCond} AND le.required_options = 0", 'i.stock_status', 0); + $optExpr = $connection->getCheckSql("le.required_options = 0", 'i.stock_status', 0); $stockStatusExpr = $connection->getLeastSql(["MAX({$optExpr})", "MIN({$statusExpr})"]); $select->columns(['status' => $stockStatusExpr]); diff --git a/app/code/Magento/GroupedProduct/Model/ResourceModel/Indexer/Stock/Grouped.php b/app/code/Magento/GroupedProduct/Model/ResourceModel/Indexer/Stock/Grouped.php index 9587a195b5e7c67d06f8a76b89d6957b5d62c403..8a3f0f1d0e900a5f4d3283076bb6ed8831c9f47a 100644 --- a/app/code/Magento/GroupedProduct/Model/ResourceModel/Indexer/Stock/Grouped.php +++ b/app/code/Magento/GroupedProduct/Model/ResourceModel/Indexer/Stock/Grouped.php @@ -26,23 +26,12 @@ class Grouped extends \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stoc { $connection = $this->getConnection(); $idxTable = $usePrimaryTable ? $this->getMainTable() : $this->getIdxTable(); - $select = $connection->select()->from( - ['e' => $this->getTable('catalog_product_entity')], - ['entity_id'] - ); - $this->_addWebsiteJoinToSelect($select, true); - $this->_addProductWebsiteJoinToSelect($select, 'cw.website_id', 'e.entity_id'); $metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); - $select->columns( - 'cw.website_id' - )->join( - ['cis' => $this->getTable('cataloginventory_stock')], - '', - ['stock_id'] - )->joinLeft( - ['cisi' => $this->getTable('cataloginventory_stock_item')], - 'cisi.stock_id = cis.stock_id AND cisi.product_id = e.entity_id', - [] + $select = parent::_getStockStatusSelect($entityIds, $usePrimaryTable); + $select->reset( + \Magento\Framework\DB\Select::COLUMNS + )->columns( + ['e.entity_id', 'cis.website_id', 'cis.stock_id'] )->joinLeft( ['l' => $this->getTable('catalog_product_link')], 'e.' . $metadata->getLinkField() . ' = l.product_id AND l.link_type_id=' . @@ -54,31 +43,15 @@ class Grouped extends \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stoc [] )->joinLeft( ['i' => $idxTable], - 'i.product_id = l.linked_product_id AND cw.website_id = i.website_id AND cis.stock_id = i.stock_id', + 'i.product_id = l.linked_product_id AND cis.website_id = i.website_id AND cis.stock_id = i.stock_id', [] )->columns( ['qty' => new \Zend_Db_Expr('0')] - )->where( - 'cw.website_id != 0' - )->where( - 'e.type_id = ?', - $this->getTypeId() - )->group( - ['e.entity_id', 'cw.website_id', 'cis.stock_id'] - ); - - // add limitation of status - $productStatusExpr = $this->_addAttributeToSelect( - $select, - 'status', - 'e.' . $metadata->getLinkField(), - 'cs.store_id' ); - $productStatusCond = $connection->quoteInto($productStatusExpr . '=?', ProductStatus::STATUS_ENABLED); $statusExpression = $this->getStatusExpression($connection); - $optExpr = $connection->getCheckSql("{$productStatusCond} AND le.required_options = 0", 'i.stock_status', 0); + $optExpr = $connection->getCheckSql("le.required_options = 0", 'i.stock_status', 0); $stockStatusExpr = $connection->getLeastSql(["MAX({$optExpr})", "MIN({$statusExpression})"]); $select->columns(['status' => $stockStatusExpr]); diff --git a/app/code/Magento/Theme/Block/Html/Topmenu.php b/app/code/Magento/Theme/Block/Html/Topmenu.php index d0205f51453bc4d003e6347af7b5754ac40d6d4c..52a4714fea8db053b49790a548538644866744cc 100644 --- a/app/code/Magento/Theme/Block/Html/Topmenu.php +++ b/app/code/Magento/Theme/Block/Html/Topmenu.php @@ -330,7 +330,9 @@ class Topmenu extends Template implements IdentityInterface */ public function addIdentity($identity) { - $this->identities[] = $identity; + if (!in_array($identity, $this->identities)) { + $this->identities[] = $identity; + } } /** @@ -364,4 +366,14 @@ class Topmenu extends Template implements IdentityInterface { return array_merge(parent::getCacheTags(), $this->getIdentities()); } + + /** + * Get menu object. + * + * @return Node + */ + public function getMenu() + { + return $this->_menu; + } } diff --git a/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php b/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php index d5c0bcc678f6a4af813fe88d6f2419f9561a5134..038f5cdcfc444802259049eac10e371fba17edec 100644 --- a/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php +++ b/app/code/Magento/Webapi/Model/Soap/Wsdl/Generator.php @@ -12,6 +12,7 @@ use Magento\Webapi\Model\Soap\Wsdl; use Magento\Webapi\Model\Soap\WsdlFactory; use Magento\Framework\Webapi\Authorization; use Magento\Webapi\Model\ServiceMetadata; +use Magento\Framework\Exception\AuthorizationException; /** * WSDL generator. @@ -364,4 +365,21 @@ class Generator extends AbstractSchemaGenerator { return $this->serviceMetadata->getServiceMetadata($serviceName); } + + /** + * {@inheritdoc} + */ + protected function getAllowedServicesMetadata($requestedServices) + { + $allowedServicesMetadata = parent::getAllowedServicesMetadata($requestedServices); + if (!$allowedServicesMetadata) { + throw new AuthorizationException( + __( + AuthorizationException::NOT_AUTHORIZED, + ['resources' => implode(', ', $requestedServices)] + ) + ); + } + return $allowedServicesMetadata; + } } diff --git a/composer.json b/composer.json index 73115b15a9f32a8af1a49a14a7658cd5daf9804c..3734cdd372bba9951c78de4769fa6773429b1290 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "zendframework/zend-http": "~2.4.6", "magento/zendframework1": "1.12.16", "colinmollenhour/credis": "1.6", - "colinmollenhour/php-redis-session-abstract": "1.0", + "colinmollenhour/php-redis-session-abstract": "1.1", "composer/composer": "1.0.0-beta1", "monolog/monolog": "1.16.0", "oyejorge/less.php": "1.7.0.3", diff --git a/composer.lock b/composer.lock index 4aaae63b403d43bf5ce7a75886dc6c8cedb6adb0..2f0873b997487361830407de6878ee657eab5928 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "d81a16c234a62403d9b5b06057393d9d", - "content-hash": "cd415001aebab7eb87bb62e2223509fc", + "hash": "666640f73320778f40be99a86695ef1c", + "content-hash": "1a3c1d3316e4448159bbcc436015ad2b", "packages": [ { "name": "braintree/braintree_php", @@ -95,16 +95,16 @@ }, { "name": "colinmollenhour/php-redis-session-abstract", - "version": "v1.0", + "version": "v1.1", "source": { "type": "git", "url": "https://github.com/colinmollenhour/php-redis-session-abstract.git", - "reference": "1308ddc08e2adbe303f7f8b8ead9beb5f2f2adf9" + "reference": "95330b7f29663dab81f53d1a438e4d927b6c5f66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/colinmollenhour/php-redis-session-abstract/zipball/1308ddc08e2adbe303f7f8b8ead9beb5f2f2adf9", - "reference": "1308ddc08e2adbe303f7f8b8ead9beb5f2f2adf9", + "url": "https://api.github.com/repos/colinmollenhour/php-redis-session-abstract/zipball/95330b7f29663dab81f53d1a438e4d927b6c5f66", + "reference": "95330b7f29663dab81f53d1a438e4d927b6c5f66", "shasum": "" }, "require": { @@ -129,7 +129,7 @@ ], "description": "A Redis-based session handler with optimistic locking", "homepage": "https://github.com/colinmollenhour/php-redis-session-abstract", - "time": "2016-01-14 16:04:27" + "time": "2016-02-03 18:13:49" }, { "name": "composer/composer", @@ -208,16 +208,16 @@ }, { "name": "composer/semver", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "df4463baa9f44fe6cf0a6da4fde2934d4c0a2747" + "reference": "84c47f3d8901440403217afc120683c7385aecb8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/df4463baa9f44fe6cf0a6da4fde2934d4c0a2747", - "reference": "df4463baa9f44fe6cf0a6da4fde2934d4c0a2747", + "url": "https://api.github.com/repos/composer/semver/zipball/84c47f3d8901440403217afc120683c7385aecb8", + "reference": "84c47f3d8901440403217afc120683c7385aecb8", "shasum": "" }, "require": { @@ -266,28 +266,28 @@ "validation", "versioning" ], - "time": "2016-02-25 22:23:39" + "time": "2016-03-30 13:16:03" }, { "name": "composer/spdx-licenses", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "9e1c3926bb0842812967213d7c92827bc5883671" + "reference": "547659c3cacd3ccfe1b4714c2ff88cafc6b6793b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/9e1c3926bb0842812967213d7c92827bc5883671", - "reference": "9e1c3926bb0842812967213d7c92827bc5883671", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/547659c3cacd3ccfe1b4714c2ff88cafc6b6793b", + "reference": "547659c3cacd3ccfe1b4714c2ff88cafc6b6793b", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": "^5.3.2 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.5", - "phpunit/phpunit-mock-objects": "~2.3" + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" }, "type": "library", "extra": { @@ -327,7 +327,7 @@ "spdx", "validator" ], - "time": "2015-10-05 11:27:42" + "time": "2016-03-25 10:57:10" }, { "name": "justinrainbow/json-schema", @@ -1181,16 +1181,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3" + "reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/78c468665c9568c3faaa9c416a7134308f2d85c3", - "reference": "78c468665c9568c3faaa9c416a7134308f2d85c3", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/47d2d8cade9b1c3987573d2943bb9352536cdb87", + "reference": "47d2d8cade9b1c3987573d2943bb9352536cdb87", "shasum": "" }, "require": { @@ -1237,20 +1237,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-01-27 05:14:19" + "time": "2016-03-07 14:04:32" }, { "name": "symfony/filesystem", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "65cb36b6539b1d446527d60457248f30d045464d" + "reference": "f08ffdf229252cd2745558cb2112df43903bcae4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/65cb36b6539b1d446527d60457248f30d045464d", - "reference": "65cb36b6539b1d446527d60457248f30d045464d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/f08ffdf229252cd2745558cb2112df43903bcae4", + "reference": "f08ffdf229252cd2745558cb2112df43903bcae4", "shasum": "" }, "require": { @@ -1286,20 +1286,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-02-22 15:02:30" + "time": "2016-03-27 10:20:16" }, { "name": "symfony/finder", - "version": "v3.0.3", + "version": "v3.0.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723" + "reference": "c54e407b35bc098916704e9fd090da21da4c4f52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/623bda0abd9aa29e529c8e9c08b3b84171914723", - "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723", + "url": "https://api.github.com/repos/symfony/finder/zipball/c54e407b35bc098916704e9fd090da21da4c4f52", + "reference": "c54e407b35bc098916704e9fd090da21da4c4f52", "shasum": "" }, "require": { @@ -1335,20 +1335,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-01-27 05:14:46" + "time": "2016-03-10 11:13:05" }, { "name": "symfony/process", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe" + "reference": "fb467471952ef5cf8497c029980e556b47545333" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe", - "reference": "7dedd5b60550f33dca16dd7e94ef8aca8b67bbfe", + "url": "https://api.github.com/repos/symfony/process/zipball/fb467471952ef5cf8497c029980e556b47545333", + "reference": "fb467471952ef5cf8497c029980e556b47545333", "shasum": "" }, "require": { @@ -1384,7 +1384,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-02-02 13:33:15" + "time": "2016-03-23 13:11:46" }, { "name": "tedivm/jshrink", @@ -4112,16 +4112,16 @@ }, { "name": "symfony/config", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "0f8f94e6a32b5c480024eed5fa5cbd2790d0ad19" + "reference": "5273f4724dc5288fe7a33cb08077ab9852621f2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/0f8f94e6a32b5c480024eed5fa5cbd2790d0ad19", - "reference": "0f8f94e6a32b5c480024eed5fa5cbd2790d0ad19", + "url": "https://api.github.com/repos/symfony/config/zipball/5273f4724dc5288fe7a33cb08077ab9852621f2c", + "reference": "5273f4724dc5288fe7a33cb08077ab9852621f2c", "shasum": "" }, "require": { @@ -4161,20 +4161,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-02-22 16:12:45" + "time": "2016-03-04 07:54:35" }, { "name": "symfony/dependency-injection", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "62251761a7615435b22ccf562384c588b431be44" + "reference": "f7b4a498e679fa440b16facb934680a1527ed48c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/62251761a7615435b22ccf562384c588b431be44", - "reference": "62251761a7615435b22ccf562384c588b431be44", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f7b4a498e679fa440b16facb934680a1527ed48c", + "reference": "f7b4a498e679fa440b16facb934680a1527ed48c", "shasum": "" }, "require": { @@ -4223,20 +4223,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2016-02-28 16:34:46" + "time": "2016-03-21 07:27:21" }, { "name": "symfony/stopwatch", - "version": "v3.0.3", + "version": "v3.0.4", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "4a204804952ff267ace88cf499e0b4bb302a475e" + "reference": "6015187088421e9499d8f8316bdb396f8b806c06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/4a204804952ff267ace88cf499e0b4bb302a475e", - "reference": "4a204804952ff267ace88cf499e0b4bb302a475e", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6015187088421e9499d8f8316bdb396f8b806c06", + "reference": "6015187088421e9499d8f8316bdb396f8b806c06", "shasum": "" }, "require": { @@ -4272,20 +4272,20 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com", - "time": "2016-01-03 15:35:16" + "time": "2016-03-04 07:55:57" }, { "name": "symfony/yaml", - "version": "v2.8.3", + "version": "v2.8.4", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995" + "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/2a4ee40acb880c56f29fb1b8886e7ffe94f3b995", - "reference": "2a4ee40acb880c56f29fb1b8886e7ffe94f3b995", + "url": "https://api.github.com/repos/symfony/yaml/zipball/584e52cb8f788a887553ba82db6caacb1d6260bb", + "reference": "584e52cb8f788a887553ba82db6caacb1d6260bb", "shasum": "" }, "require": { @@ -4321,7 +4321,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-02-23 07:41:20" + "time": "2016-03-04 07:54:35" }, { "name": "theseer/fdomdocument", diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/BaseService.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/BaseService.php index eff0dbba735f6295e4084f10bb8228f56ee04539..88d4e559e16d52967f1d452bfd95791765cd1255 100644 --- a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/BaseService.php +++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/BaseService.php @@ -25,7 +25,7 @@ abstract class BaseService extends \Magento\TestFramework\TestCase\WebapiAbstrac $this->_assertSoapException( $serviceInfo, $requestData, - 'SOAP-ERROR: Parsing WSDL: Couldn\'t bind to service' + 'Consumer is not authorized to access %resources' ); } elseif (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) { $this->_assertRestUnauthorizedException($serviceInfo, $requestData); @@ -111,7 +111,7 @@ abstract class BaseService extends \Magento\TestFramework\TestCase\WebapiAbstrac } if ($expectedMessage) { - $this->assertEquals($expectedMessage, $e->getMessage()); + $this->assertContains($expectedMessage, $e->getMessage()); } } } diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SoapErrorHandlingTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SoapErrorHandlingTest.php index c7ef1d00e02fad6a9311240065b3c32a247e2065..8cd95ef23a47e75b7915e7c114c1968833d81125 100644 --- a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SoapErrorHandlingTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SoapErrorHandlingTest.php @@ -110,8 +110,8 @@ class SoapErrorHandlingTest extends \Magento\TestFramework\TestCase\WebapiAbstra } catch (\SoapFault $e) { $this->checkSoapFault( $e, - 'SOAP-ERROR: Parsing WSDL: Couldn\'t bind to service', - 'WSDL' + 'Consumer is not authorized to access %resources', + 'env:Sender' ); } } diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php index 2593e9d12f5f94c4e18f12e3f9720747994e1b56..9afdb1f26067a769726fd4d44f235d3c5958ba48 100644 --- a/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php +++ b/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php @@ -65,6 +65,16 @@ class WsdlGenerationFromDataObjectTest extends \Magento\TestFramework\TestCase\W $this->_checkFaultsDeclaration($wsdlContent); } + public function testNoAuthorizedServices() + { + $wsdlUrl = $this->_getBaseWsdlUrl() . 'testModule5AllSoapAndRestV2'; + $connection = curl_init($wsdlUrl); + curl_setopt($connection, CURLOPT_RETURNTRANSFER, 1); + $responseContent = curl_exec($connection); + $this->assertEquals(curl_getinfo($connection, CURLINFO_HTTP_CODE), 401); + $this->assertContains("Consumer is not authorized to access %resources", $responseContent); + } + public function testInvalidWsdlUrlNoServices() { $responseContent = $this->_getWsdlContent($this->_getBaseWsdlUrl()); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/_files/products_advanced.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/_files/products_advanced.php index 8146a04b34398a758c815c787feb9cfe047c786d..2ae37ed9b71946b9924064a3cd1fa0a30e6b3c88 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/_files/products_advanced.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/Price/_files/products_advanced.php @@ -80,6 +80,11 @@ foreach ($prices as $price) { 'simple-' . $productId )->setPrice( $price + )->setStockData( + [ + 'qty' => 100, + 'is_in_stock' => 1, + ] )->setWeight( 18 )->setCategoryIds( diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual.php index 4992805824538bc35ec803abea5056b6456bb134..7ec85f110a5b58bc9c721593e50e2c6fb4fbb682 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual.php @@ -16,4 +16,9 @@ $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_VIRTUAL) ->setTaxClassId(0) ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) - ->save(); + ->setStockData( + [ + 'qty' => 100, + 'is_in_stock' => 1, + ] + )->save(); diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php deleted file mode 100644 index 12aae4429203d85c9095ba607dfe25f620852353..0000000000000000000000000000000000000000 --- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php +++ /dev/null @@ -1,71 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\CatalogInventory\Model\Config\Backend; - -use Magento\TestFramework\Helper\Bootstrap as Bootstrap; - -/** - * Class ManagestockTest - */ -class ManagestockTest extends \PHPUnit_Framework_TestCase -{ - /** - * Data provider for testSaveAndRebuildIndex - * @return array - */ - public function saveAndRebuildIndexDataProvider() - { - return [ - [1, 1], - [0, 0], - ]; - } - - /** - * Test rebuild stock indexer on stock status config save - * - * @dataProvider saveAndRebuildIndexDataProvider - * - * @magentoAppIsolation enabled - * @magentoDbIsolation enabled - * @magentoConfigFixture default/cataloginventory/item_options/manage_stock 0 - * - * @param int $newStockValue new value for stock status - * @param int $callCount count matcher - */ - public function testSaveAndRebuildIndex($newStockValue, $callCount) - { - /** @var \Magento\CatalogInventory\Model\StockIndex */ - $stockManagement = $this->getMock( - '\Magento\CatalogInventory\Model\StockIndex', - ['rebuild'], - [], - '', - false - ); - - $stockManagement->expects($this->exactly($callCount)) - ->method('rebuild'); - - $manageStock = new Managestock( - Bootstrap::getObjectManager()->get('Magento\Framework\Model\Context'), - Bootstrap::getObjectManager()->get('Magento\Framework\Registry'), - Bootstrap::getObjectManager()->get('Magento\Framework\App\Config\ScopeConfigInterface'), - Bootstrap::getObjectManager()->get('Magento\Framework\App\Cache\TypeListInterface'), - $stockManagement, - Bootstrap::getObjectManager()->get('Magento\CatalogInventory\Model\Indexer\Stock\Processor'), - Bootstrap::getObjectManager()->get('Magento\Config\Model\ResourceModel\Config') - ); - - $manageStock->setPath('cataloginventory/item_options/manage_stock'); - $manageStock->setScope('default'); - $manageStock->setScopeId(0); - $manageStock->setValue($newStockValue); - - // assert - $manageStock->save(); - } -} diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStockTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStockTest.php index 8fbcad5267cf774401910a63b7dcf7b2c8bcd427..02ddb8e23b9924bc2acd357831724196ae1fbcf8 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStockTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/ResourceModel/Indexer/Stock/DefaultStockTest.php @@ -17,12 +17,19 @@ class DefaultStockTest extends \PHPUnit_Framework_TestCase */ private $indexer; + /** + * @var \Magento\CatalogInventory\Api\StockConfigurationInterface + */ + private $stockConfiguration; + protected function setUp() { $this->indexer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\DefaultStock::class ); - + $this->stockConfiguration = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( + \Magento\CatalogInventory\Api\StockConfigurationInterface::class + ); } /** @@ -53,7 +60,7 @@ class DefaultStockTest extends \PHPUnit_Framework_TestCase ); $criteria = $criteriaFactory->create(); $criteria->setProductsFilter([$product->getId()]); - $criteria->addFilter('website', 'website_id', $testWebsite->getId()); + $criteria->addFilter('website', 'website_id', $this->stockConfiguration->getDefaultScopeId()); $items = $stockStatusRepository->getList($criteria)->getItems(); $this->assertEquals($product->getId(), $items[$product->getId()]->getProductId()); } diff --git a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php index 7ccfba9b3c1b7cf743cfeb30512ffc11902ddf80..4c15a2a9e08877c2b3516ad86f5458df7ed5acd3 100644 --- a/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php +++ b/dev/tests/integration/testsuite/Magento/Downloadable/_files/product_downloadable.php @@ -17,7 +17,13 @@ $product ->setPrice(10) ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) - ->setLinksPurchasedSeparately(true); + ->setLinksPurchasedSeparately(true) + ->setStockData( + [ + 'qty' => 100, + 'is_in_stock' => 1, + ] + ); /** * @var \Magento\Downloadable\Api\Data\LinkInterfaceFactory $linkFactory diff --git a/dev/tests/integration/testsuite/Magento/Paypal/_files/quote_payment_express.php b/dev/tests/integration/testsuite/Magento/Paypal/_files/quote_payment_express.php index c94078c41d741682c467819a704610ec5cdad799..8fb3c96eae0b5993b4ec93b3eac13cfccb2de97e 100644 --- a/dev/tests/integration/testsuite/Magento/Paypal/_files/quote_payment_express.php +++ b/dev/tests/integration/testsuite/Magento/Paypal/_files/quote_payment_express.php @@ -28,7 +28,12 @@ $product->setTypeId('simple') ->setPrice(10) ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) - ->save(); + ->setStockData( + [ + 'qty' => 100, + 'is_in_stock' => 1, + ] + )->save(); $product->load(1); $billingData = [ diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/quote.php b/dev/tests/integration/testsuite/Magento/Sales/_files/quote.php index 2304dcdc21399e3dbe7936c83fc880ab06b38139..95f387213d16ccb97ffb4d41321cd2aa941f8fef 100644 --- a/dev/tests/integration/testsuite/Magento/Sales/_files/quote.php +++ b/dev/tests/integration/testsuite/Magento/Sales/_files/quote.php @@ -17,7 +17,12 @@ $product->setTypeId('simple') ->setMetaDescription('meta description') ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) - ->save(); + ->setStockData( + [ + 'qty' => 100, + 'is_in_stock' => 1, + ] + )->save(); $productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() ->create('Magento\Catalog\Api\ProductRepositoryInterface'); diff --git a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php index d4dce686583b060b6e98a8335bf96d9c04608598..1a23e2974f568d90c33d49067cc228f8666d6705 100644 --- a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php +++ b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php @@ -5,9 +5,14 @@ */ namespace Magento\Framework\Session\SaveHandler\Redis; +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Store\Model\ScopeInterface as StoreScopeInterface; use Magento\Framework\App\DeploymentConfig; use Magento\Framework\App\State; +/** + * Redis session save handler + */ class Config implements \Cm\RedisSession\Handler\ConfigInterface { /** @@ -95,6 +100,21 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface */ const PARAM_BREAK_AFTER = 'session/redis/break_after'; + /** + * Cookie lifetime config path + */ + const XML_PATH_COOKIE_LIFETIME = 'web/cookie/cookie_lifetime'; + + /** + * Admin session lifetime config path + */ + const XML_PATH_ADMIN_SESSION_LIFETIME = 'admin/security/session_lifetime'; + + /** + * Session max lifetime + */ + const SESSION_MAX_LIFETIME = 31536000; + /** * Deployment config * @@ -102,14 +122,24 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface */ private $deploymentConfig; + /** + * @var ScopeConfigInterface + */ + private $scopeConfig; + /** * @param DeploymentConfig $deploymentConfig * @param State $appState + * @param ScopeConfigInterface $scopeConfig */ - public function __construct(DeploymentConfig $deploymentConfig, State $appState) - { + public function __construct( + DeploymentConfig $deploymentConfig, + State $appState, + ScopeConfigInterface $scopeConfig + ) { $this->deploymentConfig = $deploymentConfig; $this->appState = $appState; + $this->scopeConfig = $scopeConfig; } /** @@ -197,7 +227,7 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface */ public function getMaxLifetime() { - return $this->deploymentConfig->get(self::PARAM_MAX_LIFETIME); + return self::SESSION_MAX_LIFETIME; } /** @@ -247,4 +277,15 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface { return $this->deploymentConfig->get(self::PARAM_BREAK_AFTER . '_' . $this->appState->getAreaCode()); } + + /** + * {@inheritdoc} + */ + public function getLifetime() + { + if ($this->appState->getAreaCode() == \Magento\Framework\App\Area::AREA_ADMINHTML) { + return (int)$this->scopeConfig->getValue(self::XML_PATH_ADMIN_SESSION_LIFETIME); + } + return (int)$this->scopeConfig->getValue(self::XML_PATH_COOKIE_LIFETIME, StoreScopeInterface::SCOPE_STORE); + } } diff --git a/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php b/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php index f34ef8b756d3343620ce736529a089032ca0a403..c66c31d2fcdff67dcf11b21f35cb3a26c45950db 100644 --- a/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php +++ b/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php @@ -5,35 +5,44 @@ */ namespace Magento\Framework\Session\Test\Unit\SaveHandler\Redis; +use Magento\Store\Model\ScopeInterface; use Magento\Framework\Session\SaveHandler\Redis\Config; class ConfigTest extends \PHPUnit_Framework_TestCase { /** - * @var \Magento\Framework\App\DeploymentConfig + * @var \Magento\Framework\App\DeploymentConfig|\PHPUnit_Framework_MockObject_MockObject */ - protected $deploymentConfig; + private $deploymentConfigMock; /** - * @var \Magento\Framework\App\State + * @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject */ - protected $appState; + private $appStateMock; /** - * @var \Magento\Framework\Session\SaveHandler\Redis\Config + * @var \Magento\Framework\App\Config|\PHPUnit_Framework_MockObject_MockObject */ - protected $config; + private $scopeConfigMock; + + /** + * @var Config + */ + private $config; public function setUp() { - $this->deploymentConfig = $this->getMock('Magento\Framework\App\DeploymentConfig', [], [], '', false); - $this->appState = $this->getMock('Magento\Framework\App\State', [], [], '', false); + $this->deploymentConfigMock = $this->getMock(\Magento\Framework\App\DeploymentConfig::class, [], [], '', false); + $this->appStateMock = $this->getMock(\Magento\Framework\App\State::class, [], [], '', false); + $this->scopeConfigMock = $this->getMock(\Magento\Framework\App\Config::class, [], [], '', false); + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); $this->config = $objectManager->getObject( - 'Magento\Framework\Session\SaveHandler\Redis\Config', + Config::class, [ - 'deploymentConfig' => $this->deploymentConfig, - 'appState' => $this->appState + 'deploymentConfig' => $this->deploymentConfigMock, + 'appState' => $this->appStateMock, + 'scopeConfig' => $this->scopeConfigMock ] ); } @@ -41,7 +50,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetLogLevel() { $expected = 2; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_LOG_LEVEL) ->willReturn($expected); @@ -51,7 +60,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetHost() { $expected = '127.0.0.1'; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_HOST) ->willReturn($expected); @@ -61,7 +70,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetPort() { $expected = 1234; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_PORT) ->willReturn($expected); @@ -71,7 +80,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetDatabase() { $expected = 2; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_DATABASE) ->willReturn($expected); @@ -81,7 +90,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetPassword() { $expected = 'password'; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_PASSWORD) ->willReturn($expected); @@ -91,7 +100,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetTimeout() { $expected = 10; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_TIMEOUT) ->willReturn($expected); @@ -101,7 +110,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetPersistentIdentifier() { $expected = 'sess01'; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_PERSISTENT_IDENTIFIER) ->willReturn($expected); @@ -111,7 +120,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetCompressionThreshold() { $expected = 2; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_COMPRESSION_THRESHOLD) ->willReturn($expected); @@ -121,7 +130,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetCompressionLibrary() { $expected = 'gzip'; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_COMPRESSION_LIBRARY) ->willReturn($expected); @@ -131,7 +140,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetMaxConcurrency() { $expected = 6; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_MAX_CONCURRENCY) ->willReturn($expected); @@ -140,18 +149,13 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetMaxLifetime() { - $expected = 30; - $this->deploymentConfig->expects($this->once()) - ->method('get') - ->with(Config::PARAM_MAX_LIFETIME) - ->willReturn($expected); - $this->assertEquals($this->config->getMaxLifetime(), $expected); + $this->assertEquals($this->config->getMaxLifetime(), Config::SESSION_MAX_LIFETIME); } public function testGetMinLifetime() { $expected = 30; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_MIN_LIFETIME) ->willReturn($expected); @@ -161,7 +165,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetDisableLocking() { $expected = false; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_DISABLE_LOCKING) ->willReturn($expected); @@ -171,7 +175,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetBotLifetime() { $expected = 30; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_BOT_LIFETIME) ->willReturn($expected); @@ -181,7 +185,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetBotFirstLifetime() { $expected = 30; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_BOT_FIRST_LIFETIME) ->willReturn($expected); @@ -191,7 +195,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase public function testGetFirstLifetime() { $expected = 30; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_FIRST_LIFETIME) ->willReturn($expected); @@ -202,13 +206,44 @@ class ConfigTest extends \PHPUnit_Framework_TestCase { $areaCode = 'frontend'; $breakAfter = 5; - $this->deploymentConfig->expects($this->once()) + $this->deploymentConfigMock->expects($this->once()) ->method('get') ->with(Config::PARAM_BREAK_AFTER . '_' . $areaCode) ->willReturn($breakAfter); - $this->appState->expects($this->once()) + $this->appStateMock->expects($this->once()) ->method('getAreaCode') ->willReturn($areaCode); $this->assertEquals($this->config->getBreakAfter(), $breakAfter); } + + public function testGetLifetimeAdmin() + { + $areaCode = 'adminhtml'; + $expectedLifetime = 123; + $this->appStateMock->expects($this->once()) + ->method('getAreaCode') + ->willReturn($areaCode); + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with(Config::XML_PATH_ADMIN_SESSION_LIFETIME) + ->willReturn($expectedLifetime); + $this->assertEquals($this->config->getLifetime(), $expectedLifetime); + } + + public function testGetLifetimeFrontend() + { + $areaCode = 'frontend'; + $expectedLifetime = 234; + $this->appStateMock->expects($this->once()) + ->method('getAreaCode') + ->willReturn($areaCode); + $this->scopeConfigMock->expects($this->once()) + ->method('getValue') + ->with( + Config::XML_PATH_COOKIE_LIFETIME, + ScopeInterface::SCOPE_STORE + ) + ->willReturn($expectedLifetime); + $this->assertEquals($this->config->getLifetime(), $expectedLifetime); + } } diff --git a/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php b/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php index bad169e114754ee24dd850c636b2f27b3e9e76d0..ee5a42069fb0cca56c7bac2065ec7f3ac6607182 100644 --- a/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php +++ b/setup/src/Magento/Setup/Module/Di/Code/Reader/ClassesScanner.php @@ -6,7 +6,7 @@ namespace Magento\Setup\Module\Di\Code\Reader; use Magento\Framework\Exception\FileSystemException; -use Zend\Code\Scanner\FileScanner; +use Magento\Setup\Module\Di\Code\Reader\FileScanner; class ClassesScanner implements ClassesScannerInterface { diff --git a/setup/src/Magento/Setup/Module/Di/Code/Reader/FileScanner.php b/setup/src/Magento/Setup/Module/Di/Code/Reader/FileScanner.php new file mode 100644 index 0000000000000000000000000000000000000000..5293b782064242a571cb7580835abb6586d2a454 --- /dev/null +++ b/setup/src/Magento/Setup/Module/Di/Code/Reader/FileScanner.php @@ -0,0 +1,367 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +// @codingStandardsIgnoreFile + +namespace Magento\Setup\Module\Di\Code\Reader; + +/** + * @SuppressWarnings(PHPMD) + */ +class FileScanner extends \Zend\Code\Scanner\FileScanner +{ + /** + * @var int + */ + private $tokenType; + + /** + * {@inheritdoc} + */ + protected function scan() + { + if ($this->isScanned) { + return; + } + + if (!$this->tokens) { + throw new \Zend\Code\Exception\RuntimeException('No tokens were provided'); + } + + /** + * Define PHP 5.4 'trait' token constant. + */ + if (!defined('T_TRAIT')) { + define('T_TRAIT', 42001); + } + + /** + * Variables & Setup + */ + + $tokens = &$this->tokens; // localize + $infos = &$this->infos; // localize + $tokenIndex = null; + $token = null; + $this->tokenType = null; + $tokenContent = null; + $tokenLine = null; + $namespace = null; + $docCommentIndex = false; + $infoIndex = 0; + + /* + * MACRO creation + */ + $MACRO_TOKEN_ADVANCE = function () use (&$tokens, &$tokenIndex, &$token, &$tokenContent, &$tokenLine) { + $tokenIndex = ($tokenIndex === null) ? 0 : $tokenIndex + 1; + if (!isset($tokens[$tokenIndex])) { + $token = false; + $tokenContent = false; + $this->tokenType = false; + $tokenLine = false; + + return false; + } + if (is_string($tokens[$tokenIndex]) && $tokens[$tokenIndex] === '"') { + do { + $tokenIndex++; + } while (!(is_string($tokens[$tokenIndex]) && $tokens[$tokenIndex] === '"')); + } + $token = $tokens[$tokenIndex]; + if (is_array($token)) { + list($this->tokenType, $tokenContent, $tokenLine) = $token; + } else { + $this->tokenType = null; + $tokenContent = $token; + } + + return $tokenIndex; + }; + $MACRO_TOKEN_LOGICAL_START_INDEX = function () use (&$tokenIndex, &$docCommentIndex) { + return ($docCommentIndex === false) ? $tokenIndex : $docCommentIndex; + }; + $MACRO_DOC_COMMENT_START = function () use (&$tokenIndex, &$docCommentIndex) { + $docCommentIndex = $tokenIndex; + + return $docCommentIndex; + }; + $MACRO_DOC_COMMENT_VALIDATE = function () use (&$docCommentIndex) { + static $validTrailingTokens = null; + if ($validTrailingTokens === null) { + $validTrailingTokens = array(T_WHITESPACE, T_FINAL, T_ABSTRACT, T_INTERFACE, T_CLASS, T_FUNCTION); + } + if ($docCommentIndex !== false && !in_array($this->tokenType, $validTrailingTokens)) { + $docCommentIndex = false; + } + + return $docCommentIndex; + }; + $MACRO_INFO_ADVANCE = function () use (&$infoIndex, &$infos, &$tokenIndex, &$tokenLine) { + $infos[$infoIndex]['tokenEnd'] = $tokenIndex; + $infos[$infoIndex]['lineEnd'] = $tokenLine; + $infoIndex++; + + return $infoIndex; + }; + + /** + * START FINITE STATE MACHINE FOR SCANNING TOKENS + */ + + // Initialize token + $MACRO_TOKEN_ADVANCE(); + + SCANNER_TOP: + + if ($token === false) { + goto SCANNER_END; + } + + // Validate current doc comment index + $MACRO_DOC_COMMENT_VALIDATE(); + + switch ($this->tokenType) { + + case T_DOC_COMMENT: + + $MACRO_DOC_COMMENT_START(); + goto SCANNER_CONTINUE; + //goto no break needed + + case T_NAMESPACE: + + $infos[$infoIndex] = array( + 'type' => 'namespace', + 'tokenStart' => $MACRO_TOKEN_LOGICAL_START_INDEX(), + 'tokenEnd' => null, + 'lineStart' => $token[2], + 'lineEnd' => null, + 'namespace' => null, + ); + + // start processing with next token + if ($MACRO_TOKEN_ADVANCE() === false) { + goto SCANNER_END; + } + + SCANNER_NAMESPACE_TOP: + + if ($this->tokenType === null && $tokenContent === ';' || $tokenContent === '{') { + goto SCANNER_NAMESPACE_END; + } + + if ($this->tokenType === T_WHITESPACE) { + goto SCANNER_NAMESPACE_CONTINUE; + } + + if ($this->tokenType === T_NS_SEPARATOR || $this->tokenType === T_STRING) { + $infos[$infoIndex]['namespace'] .= $tokenContent; + } + + SCANNER_NAMESPACE_CONTINUE: + + if ($MACRO_TOKEN_ADVANCE() === false) { + goto SCANNER_END; + } + goto SCANNER_NAMESPACE_TOP; + + SCANNER_NAMESPACE_END: + + $namespace = $infos[$infoIndex]['namespace']; + + $MACRO_INFO_ADVANCE(); + goto SCANNER_CONTINUE; + //goto no break needed + + case T_USE: + + $infos[$infoIndex] = array( + 'type' => 'use', + 'tokenStart' => $MACRO_TOKEN_LOGICAL_START_INDEX(), + 'tokenEnd' => null, + 'lineStart' => $tokens[$tokenIndex][2], + 'lineEnd' => null, + 'namespace' => $namespace, + 'statements' => array(0 => array('use' => null, + 'as' => null)), + ); + + $useStatementIndex = 0; + $useAsContext = false; + + // start processing with next token + if ($MACRO_TOKEN_ADVANCE() === false) { + goto SCANNER_END; + } + + SCANNER_USE_TOP: + + if ($this->tokenType === null) { + if ($tokenContent === ';') { + goto SCANNER_USE_END; + } elseif ($tokenContent === ',') { + $useAsContext = false; + $useStatementIndex++; + $infos[$infoIndex]['statements'][$useStatementIndex] = array('use' => null, + 'as' => null); + } + } + + // ANALYZE + if ($this->tokenType !== null) { + if ($this->tokenType == T_AS) { + $useAsContext = true; + goto SCANNER_USE_CONTINUE; + } + + if ($this->tokenType == T_NS_SEPARATOR || $this->tokenType == T_STRING) { + if ($useAsContext == false) { + $infos[$infoIndex]['statements'][$useStatementIndex]['use'] .= $tokenContent; + } else { + $infos[$infoIndex]['statements'][$useStatementIndex]['as'] = $tokenContent; + } + } + } + + SCANNER_USE_CONTINUE: + + if ($MACRO_TOKEN_ADVANCE() === false) { + goto SCANNER_END; + } + goto SCANNER_USE_TOP; + + SCANNER_USE_END: + + $MACRO_INFO_ADVANCE(); + goto SCANNER_CONTINUE; + //goto no break needed + + case T_INCLUDE: + case T_INCLUDE_ONCE: + case T_REQUIRE: + case T_REQUIRE_ONCE: + + // Static for performance + static $includeTypes = array( + T_INCLUDE => 'include', + T_INCLUDE_ONCE => 'include_once', + T_REQUIRE => 'require', + T_REQUIRE_ONCE => 'require_once' + ); + + $infos[$infoIndex] = array( + 'type' => 'include', + 'tokenStart' => $MACRO_TOKEN_LOGICAL_START_INDEX(), + 'tokenEnd' => null, + 'lineStart' => $tokens[$tokenIndex][2], + 'lineEnd' => null, + 'includeType' => $includeTypes[$tokens[$tokenIndex][0]], + 'path' => '', + ); + + // start processing with next token + if ($MACRO_TOKEN_ADVANCE() === false) { + goto SCANNER_END; + } + + SCANNER_INCLUDE_TOP: + + if ($this->tokenType === null && $tokenContent === ';') { + goto SCANNER_INCLUDE_END; + } + + $infos[$infoIndex]['path'] .= $tokenContent; + + SCANNER_INCLUDE_CONTINUE: + + if ($MACRO_TOKEN_ADVANCE() === false) { + goto SCANNER_END; + } + goto SCANNER_INCLUDE_TOP; + + SCANNER_INCLUDE_END: + + $MACRO_INFO_ADVANCE(); + goto SCANNER_CONTINUE; + //goto no break needed + + case T_FUNCTION: + case T_FINAL: + case T_ABSTRACT: + case T_CLASS: + case T_INTERFACE: + case T_TRAIT: + + $infos[$infoIndex] = array( + 'type' => ($this->tokenType === T_FUNCTION) ? 'function' : 'class', + 'tokenStart' => $MACRO_TOKEN_LOGICAL_START_INDEX(), + 'tokenEnd' => null, + 'lineStart' => $tokens[$tokenIndex][2], + 'lineEnd' => null, + 'namespace' => $namespace, + 'uses' => $this->getUsesNoScan($namespace), + 'name' => null, + 'shortName' => null, + ); + + $classBraceCount = 0; + + // start processing with current token + + SCANNER_CLASS_TOP: + + // process the name + if ($infos[$infoIndex]['shortName'] == '' + && (($this->tokenType === T_CLASS || $this->tokenType === T_INTERFACE || $this->tokenType === T_TRAIT) && $infos[$infoIndex]['type'] === 'class' + || ($this->tokenType === T_FUNCTION && $infos[$infoIndex]['type'] === 'function')) + ) { + $infos[$infoIndex]['shortName'] = $tokens[$tokenIndex + 2][1]; + $infos[$infoIndex]['name'] = (($namespace !== null) ? $namespace . '\\' : '') . $infos[$infoIndex]['shortName']; + } + + if ($this->tokenType === null) { + if ($tokenContent == '{') { + $classBraceCount++; + } + if ($tokenContent == '}') { + $classBraceCount--; + if ($classBraceCount === 0) { + goto SCANNER_CLASS_END; + } + } + } + + SCANNER_CLASS_CONTINUE: + + if ($MACRO_TOKEN_ADVANCE() === false) { + goto SCANNER_END; + } + goto SCANNER_CLASS_TOP; + + SCANNER_CLASS_END: + + $MACRO_INFO_ADVANCE(); + goto SCANNER_CONTINUE; + + } + + SCANNER_CONTINUE: + + if ($MACRO_TOKEN_ADVANCE() === false) { + goto SCANNER_END; + } + goto SCANNER_TOP; + + SCANNER_END: + + /** + * END FINITE STATE MACHINE FOR SCANNING TOKENS + */ + + $this->isScanned = true; + } +} \ No newline at end of file diff --git a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php index 135e03ae69b800d593bf6c0592f7454c7b9f1da2..2d98bc58f789ad4b8476fa057e615c27d7093253 100644 --- a/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php +++ b/setup/src/Magento/Setup/Mvc/Bootstrap/InitParamListener.php @@ -123,16 +123,20 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface /** @var \Magento\Framework\App\State $adminAppState */ $adminAppState = $objectManager->get('Magento\Framework\App\State'); $adminAppState->setAreaCode(\Magento\Framework\App\Area::AREA_ADMIN); + /** @var \Magento\Backend\Model\Session\AdminConfig $sessionConfig */ + $sessionConfig = $objectManager->get(\Magento\Backend\Model\Session\AdminConfig::class); + $cookiePath = $this->getSetupCookiePath($objectManager); + $sessionConfig->setCookiePath($cookiePath); /** @var \Magento\Backend\Model\Auth\Session $adminSession */ $adminSession = $objectManager->create( \Magento\Backend\Model\Auth\Session::class, [ - 'sessionConfig' => $objectManager->get(\Magento\Backend\Model\Session\AdminConfig::class), + 'sessionConfig' => $sessionConfig, 'appState' => $adminAppState ] ); if (!$objectManager->get(\Magento\Backend\Model\Auth::class)->isLoggedIn()) { - $adminSession->expireSessionCookie(); + $adminSession->destroy(); $response = $event->getResponse(); $response->getHeaders()->addHeaderLine('Location', 'index.php/session/unlogin'); $response->setStatusCode(302); @@ -145,6 +149,25 @@ class InitParamListener implements ListenerAggregateInterface, FactoryInterface return false; } + /** + * Get cookie path + * + * @param \Magento\Framework\ObjectManagerInterface $objectManager + * @return string + */ + private function getSetupCookiePath(\Magento\Framework\ObjectManagerInterface $objectManager) + { + /** @var \Magento\Backend\App\BackendAppList $backendAppList */ + $backendAppList = $objectManager->get(\Magento\Backend\App\BackendAppList::class); + $backendApp = $backendAppList->getBackendApp('setup'); + /** @var \Magento\Backend\Model\UrlFactory $backendUrlFactory */ + $backendUrlFactory = $objectManager->get(\Magento\Backend\Model\UrlFactory::class); + $baseUrl = parse_url($backendUrlFactory->create()->getBaseUrl(), PHP_URL_PATH); + $baseUrl = \Magento\Framework\App\Request\Http::getUrlNoScript($baseUrl); + $cookiePath = $baseUrl . $backendApp->getCookiePath(); + return $cookiePath; + } + /** * {@inheritdoc} */