Skip to content

Commit cb8dfaf

Browse files
committed
Achieve 1.0 milestone
- Add test coverage for loaders - Remove version from composer file - Fix couple of bugs discovered by automated tests
1 parent d34b8c2 commit cb8dfaf

23 files changed

+880
-147
lines changed

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"name": "ecomdev/magento2-product-data-preloader",
3-
"version": "1.0.0",
43
"description": "Magento 2 Product Data Pre-Loader FTW",
54
"type": "magento2-module",
65
"require": {
@@ -13,7 +12,8 @@
1312
"require-dev": {
1413
"phpstan/phpstan": "^0.12.86",
1514
"squizlabs/php_codesniffer": "^3.6.0",
16-
"phpunit/phpunit": "~8.5.15"
15+
"phpunit/phpunit": "~8.5.15",
16+
"ecomdev/magento2-test-essentials": "dev-main"
1717
},
1818
"license": [
1919
"MIT"

phpunit.xml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.5/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
executionOrder="depends,defects"
6+
beStrictAboutOutputDuringTests="true"
7+
beStrictAboutTodoAnnotatedTests="true"
8+
colors="true">
9+
<testsuites>
10+
<testsuite name="default">
11+
<directory suffix="Test.php">tests</directory>
12+
</testsuite>
13+
</testsuites>
14+
15+
<filter>
16+
<whitelist processUncoveredFilesFromWhitelist="true">
17+
<directory suffix=".php">src</directory>
18+
</whitelist>
19+
</filter>
20+
21+
22+
</phpunit>
Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,21 @@
11
<?php
22
/**
33
* Copyright © EcomDev B.V. All rights reserved.
4+
* See LICENSE for license details.
45
*/
56
declare(strict_types=1);
67

78
namespace EcomDev\ProductDataPreLoader\DataService;
89

9-
use Magento\Framework\Exception\LocalizedException;
10-
use Magento\Framework\Exception\NoSuchEntityException;
11-
use Magento\Framework\Session\SessionStartChecker;
12-
use Magento\Customer\Model\Session;
13-
1410
/**
1511
* Customer group provider for dynamic resolution of it
1612
*/
17-
class CustomerGroupProvider
13+
interface CustomerGroupProvider
1814
{
19-
/**
20-
* Customer session instance
21-
*
22-
* @var Session
23-
*/
24-
private $customerSession;
25-
26-
/**
27-
* Session availability checker
28-
*
29-
* @var SessionStartChecker
30-
*/
31-
private $sessionChecker;
32-
33-
/**
34-
* CustomerGroupProvider constructor.
35-
*
36-
* @param Session $customerSession
37-
* @param SessionStartChecker $sessionChecker
38-
*/
39-
public function __construct(Session $customerSession, SessionStartChecker $sessionChecker)
40-
{
41-
$this->customerSession = $customerSession;
42-
$this->sessionChecker = $sessionChecker;
43-
}
44-
4515
/**
4616
* Return current customer group
4717
*
4818
* @return int
4919
*/
50-
public function getCustomerGroupId(): int
51-
{
52-
if ($this->sessionChecker->check()) {
53-
try {
54-
return $this->customerSession->getCustomerGroupId();
55-
} catch (NoSuchEntityException | LocalizedException $e) {
56-
return 0;
57-
}
58-
}
59-
60-
return 0;
61-
}
20+
public function getCustomerGroupId(): int;
6221
}

src/DataService/LoadService.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ public function get(int $productId, string $type): array
9595
*/
9696
public function load(string $type, ScopeFilter $filter, array $products)
9797
{
98+
foreach ($products as $productId => $adapter) {
99+
$this->skuToId[$adapter->getSku()] = $productId;
100+
}
101+
98102
foreach ($this->loaders as $code => $loader) {
99103
if (!$loader->isApplicable($type)) {
100104
continue;
@@ -110,11 +114,6 @@ public function load(string $type, ScopeFilter $filter, array $products)
110114
}
111115

112116
$defaultData = array_fill_keys(array_keys($productsToLoad), []);
113-
114-
foreach ($productsToLoad as $productId => $adapter) {
115-
$this->skuToId[$adapter->getSku()] = $productId;
116-
}
117-
118117
$this->storage[$code] += $loader->load($filter, $productsToLoad) + $defaultData;
119118
}
120119
}

src/DataService/ScopeFilterFactory.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function createFromCart(CartInterface $cart): MagentoScopeFilter
4545
return $this->objectManager->create(MagentoScopeFilter::class, [
4646
'options' => [
4747
'store_id' => $cart->getStoreId(),
48-
'customer_group_id' => $cart->getCustomerIsGuest() ? 0 : $cart->getCustomer()->getGroupId()
48+
'group_id' => $cart->getCustomerIsGuest() ? 0 : $cart->getCustomer()->getGroupId()
4949
]
5050
]);
5151
}
@@ -82,7 +82,7 @@ public function createFromLimitation(int $storeId, ProductLimitation $productLim
8282

8383
if ($productLimitation->isUsingPriceIndex()) {
8484
$options['website_id'] = $productLimitation->getWebsiteId();
85-
$options['customer_group_id'] = $productLimitation->getCustomerGroupId();
85+
$options['group_id'] = $productLimitation->getCustomerGroupId();
8686
}
8787

8888
return $this->objectManager->create(MagentoScopeFilter::class, [
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
/**
3+
* Copyright © EcomDev B.V. All rights reserved.
4+
*/
5+
declare(strict_types=1);
6+
7+
namespace EcomDev\ProductDataPreLoader\DataService;
8+
9+
use Magento\Framework\Exception\LocalizedException;
10+
use Magento\Framework\Exception\NoSuchEntityException;
11+
use Magento\Framework\Session\SessionStartChecker;
12+
use Magento\Customer\Model\Session;
13+
14+
/**
15+
* Customer group provider for dynamic resolution of it
16+
*/
17+
class SessionCustomerGroupProvider implements CustomerGroupProvider
18+
{
19+
/**
20+
* Customer session instance
21+
*
22+
* @var Session
23+
*/
24+
private $customerSession;
25+
26+
/**
27+
* Session availability checker
28+
*
29+
* @var SessionStartChecker
30+
*/
31+
private $sessionChecker;
32+
33+
/**
34+
* CustomerGroupProvider constructor.
35+
*
36+
* @param Session $customerSession
37+
* @param SessionStartChecker $sessionChecker
38+
*/
39+
public function __construct(Session $customerSession, SessionStartChecker $sessionChecker)
40+
{
41+
$this->customerSession = $customerSession;
42+
$this->sessionChecker = $sessionChecker;
43+
}
44+
45+
/**
46+
* Return current customer group
47+
*
48+
* @return int
49+
*/
50+
public function getCustomerGroupId(): int
51+
{
52+
if ($this->sessionChecker->check()) {
53+
try {
54+
return (int)$this->customerSession->getCustomerGroupId();
55+
} catch (NoSuchEntityException | LocalizedException $e) {
56+
return 0;
57+
}
58+
}
59+
60+
return 0;
61+
}
62+
}

src/Observer/ListCollectionAfterLoad.php

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,23 +101,29 @@ public function execute(Observer $observer)
101101
$productInfo[(int)$product->getId()] = $this->adapterFactory->create($product);
102102
}
103103

104-
$type = DataLoader::TYPE_OTHER;
104+
list($type, $scope) = $this->detectScopeFilterAndType($collection);
105+
106+
$this->loadService->load($type, $scope, $productInfo);
107+
}
108+
109+
public function detectScopeFilterAndType(Collection $collection): array
110+
{
111+
if (isset($this->currentScope) && isset($this->currentType)) {
112+
$type = $this->currentType;
113+
$scope = $this->currentScope;
114+
unset($this->currentScope, $this->currentType);
115+
return [$type, $scope];
116+
}
117+
105118
$scope = $this->filterFactory->createFromLimitation(
106119
(int)$collection->getStoreId(),
107120
$collection->getLimitationFilters()
108121
);
109122

110123
if ($collection->getLimitationFilters()->isUsingPriceIndex()) {
111-
$type = DataLoader::TYPE_LIST;
124+
return [DataLoader::TYPE_LIST, $scope];
112125
}
113126

114-
if ($this->currentScope && $this->currentType) {
115-
$type = $this->currentType;
116-
$scope = $this->currentScope;
117-
$this->currentScope = null;
118-
$this->currentType = null;
119-
}
120-
121-
$this->loadService->load($type, $scope, $productInfo);
127+
return [DataLoader::TYPE_OTHER, $scope];
122128
}
123129
}

src/Observer/ProductAfterLoad.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ public function execute(Observer $observer)
7575
/* @var Product $product */
7676
$product = $observer->getData('product');
7777

78-
7978
if (empty($product->getId())) {
8079
return;
8180
}

src/Plugin/FixMissingStoreIdInProductRepository.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99

1010
use Magento\Catalog\Model\ProductRepository;
1111

12+
/**
13+
* Some extensions call product repository within a page without store id
14+
*
15+
* This happens in most cases on product view pages after original repsitory with store id was performed.
16+
* Omitting store_id from a call results in diverging cache key so we walk around it by storing store id for product
17+
* and re-using it when none specified.
18+
*/
1219
class FixMissingStoreIdInProductRepository
1320
{
1421
/**

src/etc/di.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
</arguments>
99
</type>
1010

11-
<type name="EcomDev\ProductDataPreLoader\DataService\CustomerGroupProvider">
11+
<preference for="EcomDev\ProductDataPreLoader\DataService\CustomerGroupProvider" type="EcomDev\ProductDataPreLoader\DataService\SessionCustomerGroupProvider" />
12+
13+
<type name="EcomDev\ProductDataPreLoader\DataService\SessionCustomerGroupProvider">
1214
<arguments>
1315
<argument name="customerSession" xsi:type="object">Magento\Customer\Model\Session\Proxy</argument>
1416
</arguments>

0 commit comments

Comments
 (0)