Skip to content

Commit 2cbbcc1

Browse files
committed
Merge branch 'tryout-phpstan-v1' into v1
2 parents f875a53 + 27c8c97 commit 2cbbcc1

File tree

22 files changed

+797
-606
lines changed

22 files changed

+797
-606
lines changed

Checker/Catalog/Category/UrlKey/DuplicateUrlKey.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Baldwin\UrlDataIntegrityChecker\Checker\Catalog\Category\UrlPath as UrlPathChecker;
88
use Baldwin\UrlDataIntegrityChecker\Util\Stores as StoresUtil;
9+
use Magento\Catalog\Model\Category;
910

1011
class DuplicateUrlKey
1112
{
@@ -15,6 +16,8 @@ class DuplicateUrlKey
1516

1617
private $storesUtil;
1718
private $urlPathChecker;
19+
20+
/** @var array<string, array<Category>> */
1821
private $urlPathsInfo;
1922

2023
public function __construct(
@@ -56,6 +59,8 @@ private function checkForDuplicatedUrlKeyAttributeValues(): array
5659
$categories = $this->urlPathsInfo[$urlPath];
5760

5861
foreach ($categories as $category) {
62+
assert(is_numeric($category->getEntityId()));
63+
5964
$categoriesWithProblems[] = [
6065
'catId' => (int) $category->getEntityId(),
6166
'name' => $category->getName(),

Checker/Catalog/Category/UrlKey/EmptyUrlKey.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ private function getCategoriesWithProblems(int $storeId, CategoryCollection $col
100100
;
101101

102102
if ($isOverridden || $storeId === Store::DEFAULT_STORE_ID) {
103+
assert(is_numeric($category->getEntityId()));
104+
103105
$problems[] = [
104106
'catId' => (int) $category->getEntityId(),
105107
'name' => $category->getName(),

Checker/Catalog/Category/UrlPath.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,16 @@ public function checkForIncorrectUrlPathAttributeValues(): array
6161
$allCategories = $this->getAllVisibleCategoriesWithStoreId($storeId);
6262

6363
foreach ($allCategories as $category) {
64-
$isOverridden = $this->getIsUrlPathOverridden($category, $storeId);
65-
6664
// we don't care about non overwritten values
67-
if (!$isOverridden && $storeId !== Store::DEFAULT_STORE_ID) {
65+
if ($storeId !== Store::DEFAULT_STORE_ID && !$this->getIsUrlPathOverridden($category, $storeId)) {
6866
continue;
6967
}
7068

7169
if (!$this->doesCategoryUrlPathMatchCalculatedUrlPath($category, $storeId)) {
7270
$correctUrlPath = $this->getCalculatedUrlPathForCategory($category, $storeId);
7371

72+
assert(is_numeric($category->getId()));
73+
7474
$problems[] = [
7575
'catId' => (int) $category->getId(),
7676
'name' => $category->getName(),
@@ -150,6 +150,8 @@ public function getCalculatedUrlPathForCategory(Category $category, int $storeId
150150
$this->fetchAllCategoriesWithUrlPathCalculatedByUrlKey();
151151
}
152152

153+
assert(is_numeric($category->getId()));
154+
153155
$categoryId = (int) $category->getId();
154156
$key = $this->getArrayKeyForCategoryAndStoreId($categoryId, $storeId);
155157

@@ -173,6 +175,8 @@ private function fetchAllCategoriesWithUrlPathCalculatedByUrlKey()
173175

174176
$allCategories = $this->getAllVisibleCategoriesWithStoreId($storeId);
175177
foreach ($allCategories as $category) {
178+
assert(is_numeric($category->getId()));
179+
176180
$categoryId = (int) $category->getId();
177181

178182
$path = $category->getPath() ?: '';

Checker/Catalog/Product/UrlKey/DuplicateUrlKey.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66

77
use Baldwin\UrlDataIntegrityChecker\Checker\Catalog\Product\UrlKey as UrlKeyChecker;
88
use Baldwin\UrlDataIntegrityChecker\Console\Progress;
9+
use Baldwin\UrlDataIntegrityChecker\Util\Configuration as ConfigUtil;
910
use Baldwin\UrlDataIntegrityChecker\Util\Stores as StoresUtil;
1011
use Magento\Catalog\Api\Data\ProductInterface;
1112
use Magento\Catalog\Model\Attribute\ScopeOverriddenValueFactory as AttributeScopeOverriddenValueFactory;
1213
use Magento\Catalog\Model\Product as ProductModel;
14+
use Magento\Catalog\Model\Product\Visibility as ProductVisibility;
1315
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
1416
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
1517
use Magento\Store\Model\Store;
@@ -25,19 +27,23 @@ class DuplicateUrlKey
2527
private $progressIndex;
2628
private $productCollectionFactory;
2729
private $attributeScopeOverriddenValueFactory;
30+
/** @var array<string, string> */
2831
private $cachedProductUrlKeyData;
2932
private $cachedProductSkusByIds;
33+
private $configUtil;
3034

3135
public function __construct(
3236
StoresUtil $storesUtil,
3337
Progress $progress,
3438
ProductCollectionFactory $productCollectionFactory,
35-
AttributeScopeOverriddenValueFactory $attributeScopeOverriddenValueFactory
39+
AttributeScopeOverriddenValueFactory $attributeScopeOverriddenValueFactory,
40+
ConfigUtil $configUtil
3641
) {
3742
$this->storesUtil = $storesUtil;
3843
$this->progress = $progress;
3944
$this->productCollectionFactory = $productCollectionFactory;
4045
$this->attributeScopeOverriddenValueFactory = $attributeScopeOverriddenValueFactory;
46+
$this->configUtil = $configUtil;
4147

4248
$this->progressIndex = 0;
4349
$this->cachedProductUrlKeyData = [];
@@ -81,12 +87,15 @@ private function checkForDuplicatedUrlKeyAttributeValues(): array
8187
->addAttributeToSelect(UrlKeyChecker::URL_KEY_ATTRIBUTE)
8288
->addAttributeToFilter(UrlKeyChecker::URL_KEY_ATTRIBUTE, ['notnull' => true], $joinType)
8389
->addAttributeToFilter(UrlKeyChecker::URL_KEY_ATTRIBUTE, ['neq' => ''], $joinType)
84-
// TODO: remove!
85-
// ->addAttributeToFilter('entity_id', [
86-
// 'in' => [147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158],
87-
// ])
8890
;
8991

92+
if ($this->configUtil->getOnlyCheckVisibleProducts()) {
93+
$collection->addAttributeToFilter(
94+
ProductInterface::VISIBILITY,
95+
['neq' => ProductVisibility::VISIBILITY_NOT_VISIBLE]
96+
);
97+
}
98+
9099
if ($this->progressIndex === 0) {
91100
$this->progress->setGuestimatedSize(count($storeIds), $collection->getSize());
92101
}
@@ -112,6 +121,8 @@ private function checkForDuplicatedUrlKeyAttributeValues(): array
112121
private function storeProductUrlKeyData(int $storeId, ProductCollection $collection)
113122
{
114123
foreach ($collection as $product) {
124+
assert(is_numeric($product->getEntityId()));
125+
115126
$productId = $product->getEntityId();
116127
$productSku = $product->getSku();
117128
$productUrlKey = $product->getUrlKey();

Checker/Catalog/Product/UrlKey/EmptyUrlKey.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66

77
use Baldwin\UrlDataIntegrityChecker\Checker\Catalog\Product\UrlKey as UrlKeyChecker;
88
use Baldwin\UrlDataIntegrityChecker\Console\Progress;
9+
use Baldwin\UrlDataIntegrityChecker\Util\Configuration as ConfigUtil;
910
use Baldwin\UrlDataIntegrityChecker\Util\Stores as StoresUtil;
1011
use Magento\Catalog\Api\Data\ProductInterface;
1112
use Magento\Catalog\Model\Attribute\ScopeOverriddenValueFactory as AttributeScopeOverriddenValueFactory;
1213
use Magento\Catalog\Model\Product as ProductModel;
14+
use Magento\Catalog\Model\Product\Visibility as ProductVisibility;
1315
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
1416
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
1517
use Magento\Store\Model\Store;
@@ -23,17 +25,20 @@ class EmptyUrlKey
2325
private $progressIndex;
2426
private $productCollectionFactory;
2527
private $attributeScopeOverriddenValueFactory;
28+
private $configUtil;
2629

2730
public function __construct(
2831
StoresUtil $storesUtil,
2932
Progress $progress,
3033
ProductCollectionFactory $productCollectionFactory,
31-
AttributeScopeOverriddenValueFactory $attributeScopeOverriddenValueFactory
34+
AttributeScopeOverriddenValueFactory $attributeScopeOverriddenValueFactory,
35+
ConfigUtil $configUtil
3236
) {
3337
$this->storesUtil = $storesUtil;
3438
$this->progress = $progress;
3539
$this->productCollectionFactory = $productCollectionFactory;
3640
$this->attributeScopeOverriddenValueFactory = $attributeScopeOverriddenValueFactory;
41+
$this->configUtil = $configUtil;
3742

3843
$this->progressIndex = 0;
3944
}
@@ -84,6 +89,13 @@ private function checkForEmptyUrlKeyAttributeValues(): array
8489
], null, $joinType)
8590
;
8691

92+
if ($this->configUtil->getOnlyCheckVisibleProducts()) {
93+
$collection->addAttributeToFilter(
94+
ProductInterface::VISIBILITY,
95+
['neq' => ProductVisibility::VISIBILITY_NOT_VISIBLE]
96+
);
97+
}
98+
8799
if ($this->progressIndex === 0) {
88100
$this->progress->setGuestimatedSize(count($storeIds), $collection->getSize());
89101
}
@@ -122,6 +134,8 @@ private function getProductsWithProblems(int $storeId, ProductCollection $collec
122134
;
123135

124136
if ($isOverridden || $storeId === Store::DEFAULT_STORE_ID) {
137+
assert(is_numeric($product->getEntityId()));
138+
125139
$problems[] = [
126140
'productId' => (int) $product->getEntityId(),
127141
'sku' => $product->getSku(),

Checker/Catalog/Product/UrlPath.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44

55
namespace Baldwin\UrlDataIntegrityChecker\Checker\Catalog\Product;
66

7+
use Baldwin\UrlDataIntegrityChecker\Util\Configuration as ConfigUtil;
78
use Baldwin\UrlDataIntegrityChecker\Util\Stores as StoresUtil;
89
use Magento\Catalog\Api\Data\ProductInterface;
910
use Magento\Catalog\Model\Attribute\ScopeOverriddenValueFactory as AttributeScopeOverriddenValueFactory;
1011
use Magento\Catalog\Model\Product as ProductModel;
12+
use Magento\Catalog\Model\Product\Visibility as ProductVisibility;
1113
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
1214
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
1315
use Magento\Store\Model\Store;
@@ -23,15 +25,18 @@ class UrlPath
2325
private $storesUtil;
2426
private $productCollectionFactory;
2527
private $attributeScopeOverriddenValueFactory;
28+
private $configUtil;
2629

2730
public function __construct(
2831
StoresUtil $storesUtil,
2932
ProductCollectionFactory $productCollectionFactory,
30-
AttributeScopeOverriddenValueFactory $attributeScopeOverriddenValueFactory
33+
AttributeScopeOverriddenValueFactory $attributeScopeOverriddenValueFactory,
34+
ConfigUtil $configUtil
3135
) {
3236
$this->storesUtil = $storesUtil;
3337
$this->productCollectionFactory = $productCollectionFactory;
3438
$this->attributeScopeOverriddenValueFactory = $attributeScopeOverriddenValueFactory;
39+
$this->configUtil = $configUtil;
3540
}
3641

3742
/**
@@ -64,6 +69,13 @@ private function checkForNonEmptyUrlPathAttributeValues(): array
6469
->addAttributeToFilter(self::URL_PATH_ATTRIBUTE, ['notnull' => true], $joinType)
6570
;
6671

72+
if ($this->configUtil->getOnlyCheckVisibleProducts()) {
73+
$collection->addAttributeToFilter(
74+
ProductInterface::VISIBILITY,
75+
['neq' => ProductVisibility::VISIBILITY_NOT_VISIBLE]
76+
);
77+
}
78+
6779
$productsWithProblems[] = $this->getProductsWithProblems($storeId, $collection);
6880
}
6981

@@ -91,6 +103,8 @@ private function getProductsWithProblems(int $storeId, ProductCollection $collec
91103
;
92104

93105
if ($isOverridden || $storeId === Store::DEFAULT_STORE_ID) {
106+
assert(is_numeric($product->getEntityId()));
107+
94108
$problems[] = [
95109
'productId' => (int) $product->getEntityId(),
96110
'sku' => $product->getSku(),

Cron/ScheduleJob.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ public function schedule(string $jobCode): bool
4242
$schedule
4343
->setJobCode($jobCode)
4444
->setStatus(CronScheduleModel::STATUS_PENDING)
45-
->setCreatedAt(strftime('%Y-%m-%d %H:%M:%S', $createdAtTime) ?: '')
46-
->setScheduledAt(strftime('%Y-%m-%d %H:%M', $scheduledAtTime) ?: '')
45+
->setCreatedAt(date('Y-m-d H:i:s', $createdAtTime) ?: '')
46+
->setScheduledAt(date('Y-m-d H:i', $scheduledAtTime) ?: '')
4747
->save();
4848

4949
return true;

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ check: checkstyle checkquality test
1111
.PHONY: checkstyle
1212
checkstyle:
1313
vendor/bin/php-cs-fixer fix --dry-run --diff --stop-on-violation --allow-risky=yes
14-
vendor/bin/phpcs -s --standard=Magento2 --ignore=./vendor/ .
14+
vendor/bin/phpcs -s --standard=Magento2 --exclude=Magento2.Security.InsecureFunction --ignore=./vendor/ .
1515
vendor/bin/phpcs -s --standard=PHPCompatibility --runtime-set testVersion 7.0- --ignore=./vendor/,./Test/ .
1616
vendor/bin/phpcs -s --standard=PHPCompatibility --runtime-set testVersion 7.1- ./Test/
17-
composer normalize --dry-run
17+
vendor/bin/composer normalize --dry-run
1818

1919
.PHONY: checkquality
2020
checkquality:

Model/ResourceModel/Catalog/Category/UrlKeyCollection.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ public function loadData($printQuery = false, $logQuery = false)
4343
if (!$this->isLoaded()) {
4444
$urlKeys = $this->storage->read(UrlKeyChecker::STORAGE_IDENTIFIER);
4545
foreach ($urlKeys as $urlKey) {
46-
$this->addItem($this->createDataObject($urlKey));
46+
if (is_array($urlKey)) {
47+
$this->addItem($this->createDataObject($urlKey));
48+
}
4749
}
4850

4951
foreach ($this->_orders as $field => $direction) {
@@ -83,6 +85,7 @@ public function createDataObject(array $arguments = []): DataObject
8385
{
8486
$arguments['hash'] = sha1(json_encode($arguments) ?: '');
8587

88+
/** @var DataObject */
8689
$obj = $this->_entityFactory->create($this->_itemObjectClass, ['data' => $arguments]);
8790

8891
$attributes = [];

Model/ResourceModel/Catalog/Category/UrlPathCollection.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ public function loadData($printQuery = false, $logQuery = false)
4343
if (!$this->isLoaded()) {
4444
$urlPaths = $this->storage->read(UrlPathChecker::STORAGE_IDENTIFIER);
4545
foreach ($urlPaths as $urlPath) {
46-
$this->addItem($this->createDataObject($urlPath));
46+
if (is_array($urlPath)) {
47+
$this->addItem($this->createDataObject($urlPath));
48+
}
4749
}
4850

4951
foreach ($this->_orders as $field => $direction) {
@@ -83,6 +85,7 @@ public function createDataObject(array $arguments = []): DataObject
8385
{
8486
$arguments['hash'] = sha1(json_encode($arguments) ?: '');
8587

88+
/** @var DataObject */
8689
$obj = $this->_entityFactory->create($this->_itemObjectClass, ['data' => $arguments]);
8790

8891
$attributes = [];

Model/ResourceModel/Catalog/Product/UrlKeyCollection.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ public function loadData($printQuery = false, $logQuery = false)
4343
if (!$this->isLoaded()) {
4444
$urlKeys = $this->storage->read(UrlKeyChecker::STORAGE_IDENTIFIER);
4545
foreach ($urlKeys as $urlKey) {
46-
$this->addItem($this->createDataObject($urlKey));
46+
if (is_array($urlKey)) {
47+
$this->addItem($this->createDataObject($urlKey));
48+
}
4749
}
4850

4951
foreach ($this->_orders as $field => $direction) {
@@ -83,6 +85,7 @@ public function createDataObject(array $arguments = []): DataObject
8385
{
8486
$arguments['hash'] = sha1(json_encode($arguments) ?: '');
8587

88+
/** @var DataObject */
8689
$obj = $this->_entityFactory->create($this->_itemObjectClass, ['data' => $arguments]);
8790

8891
$attributes = [];

Model/ResourceModel/Catalog/Product/UrlPathCollection.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ public function loadData($printQuery = false, $logQuery = false)
4343
if (!$this->isLoaded()) {
4444
$urlPaths = $this->storage->read(UrlPathChecker::STORAGE_IDENTIFIER);
4545
foreach ($urlPaths as $urlPath) {
46-
$this->addItem($this->createDataObject($urlPath));
46+
if (is_array($urlPath)) {
47+
$this->addItem($this->createDataObject($urlPath));
48+
}
4749
}
4850

4951
foreach ($this->_orders as $field => $direction) {
@@ -83,6 +85,7 @@ public function createDataObject(array $arguments = []): DataObject
8385
{
8486
$arguments['hash'] = sha1(json_encode($arguments) ?: '');
8587

88+
/** @var DataObject */
8689
$obj = $this->_entityFactory->create($this->_itemObjectClass, ['data' => $arguments]);
8790

8891
$attributes = [];

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ In the Magento admin, you can find the results in:
6767
The results of the checkers are currently stored by default in the directory `var/tmp` as `.json` files.
6868
But you can change the path in the backend settings under Stores > Configuration > Catalog > Url Data Integrity Checker by entering a relative path starting from the Magento installation directory or an absolute path. The directory you enter there needs to exist before it will work.
6969

70+
You can configure this module to ignore problems with invisible products (via Stores > Configuration > Catalog > Url Data Integrity Checker). Because in recent versions of Magento, url rewrites for invisible products are not being generated, so if there are problems with the `url_path` or `url_key` attributes of such products, they should not cause issues with url rewrites. An additional benefit of this option is that it will use less time and less memory to run the product checkers. This option is disabled by default, so you'll need to enable it.
71+
7072
## Some screenshots
7173

7274
### Example of backend report for product url key problems

Storage/CacheStorage.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ public function read(string $identifier): array
3333
{
3434
$data = $this->cache->load($this->getModuleCacheIdentifier($identifier)) ?: '{}';
3535

36-
return json_decode($data, true);
36+
$data = json_decode($data, true);
37+
38+
if ($data === null || !is_array($data)) {
39+
$data = [];
40+
}
41+
42+
return $data;
3743
}
3844

3945
private function getModuleCacheIdentifier(string $identifier): string

0 commit comments

Comments
 (0)