Skip to content

Commit

Permalink
Added an option to disable checking for product problems when those p…
Browse files Browse the repository at this point in the history
…roducts are invisible. Fixes baldwin-agency#31
  • Loading branch information
hostep committed Jan 30, 2022
1 parent 1e51191 commit 0f652b8
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 9 deletions.
18 changes: 13 additions & 5 deletions Checker/Catalog/Product/UrlKey/DuplicateUrlKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@

use Baldwin\UrlDataIntegrityChecker\Checker\Catalog\Product\UrlKey as UrlKeyChecker;
use Baldwin\UrlDataIntegrityChecker\Console\Progress;
use Baldwin\UrlDataIntegrityChecker\Util\Configuration as ConfigUtil;
use Baldwin\UrlDataIntegrityChecker\Util\Stores as StoresUtil;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Attribute\ScopeOverriddenValueFactory as AttributeScopeOverriddenValueFactory;
use Magento\Catalog\Model\Product as ProductModel;
use Magento\Catalog\Model\Product\Visibility as ProductVisibility;
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
use Magento\Store\Model\Store;
Expand All @@ -28,17 +30,20 @@ class DuplicateUrlKey
/** @var array<string, string> */
private $cachedProductUrlKeyData;
private $cachedProductSkusByIds;
private $configUtil;

public function __construct(
StoresUtil $storesUtil,
Progress $progress,
ProductCollectionFactory $productCollectionFactory,
AttributeScopeOverriddenValueFactory $attributeScopeOverriddenValueFactory
AttributeScopeOverriddenValueFactory $attributeScopeOverriddenValueFactory,
ConfigUtil $configUtil
) {
$this->storesUtil = $storesUtil;
$this->progress = $progress;
$this->productCollectionFactory = $productCollectionFactory;
$this->attributeScopeOverriddenValueFactory = $attributeScopeOverriddenValueFactory;
$this->configUtil = $configUtil;

$this->progressIndex = 0;
$this->cachedProductUrlKeyData = [];
Expand Down Expand Up @@ -82,12 +87,15 @@ private function checkForDuplicatedUrlKeyAttributeValues(): array
->addAttributeToSelect(UrlKeyChecker::URL_KEY_ATTRIBUTE)
->addAttributeToFilter(UrlKeyChecker::URL_KEY_ATTRIBUTE, ['notnull' => true], $joinType)
->addAttributeToFilter(UrlKeyChecker::URL_KEY_ATTRIBUTE, ['neq' => ''], $joinType)
// TODO: remove!
// ->addAttributeToFilter('entity_id', [
// 'in' => [147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158],
// ])
;

if ($this->configUtil->getOnlyCheckVisibleProducts()) {
$collection->addAttributeToFilter(
ProductInterface::VISIBILITY,
['neq' => ProductVisibility::VISIBILITY_NOT_VISIBLE]
);
}

if ($this->progressIndex === 0) {
$this->progress->setGuestimatedSize(count($storeIds), $collection->getSize());
}
Expand Down
14 changes: 13 additions & 1 deletion Checker/Catalog/Product/UrlKey/EmptyUrlKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@

use Baldwin\UrlDataIntegrityChecker\Checker\Catalog\Product\UrlKey as UrlKeyChecker;
use Baldwin\UrlDataIntegrityChecker\Console\Progress;
use Baldwin\UrlDataIntegrityChecker\Util\Configuration as ConfigUtil;
use Baldwin\UrlDataIntegrityChecker\Util\Stores as StoresUtil;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Attribute\ScopeOverriddenValueFactory as AttributeScopeOverriddenValueFactory;
use Magento\Catalog\Model\Product as ProductModel;
use Magento\Catalog\Model\Product\Visibility as ProductVisibility;
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
use Magento\Store\Model\Store;
Expand All @@ -23,17 +25,20 @@ class EmptyUrlKey
private $progressIndex;
private $productCollectionFactory;
private $attributeScopeOverriddenValueFactory;
private $configUtil;

public function __construct(
StoresUtil $storesUtil,
Progress $progress,
ProductCollectionFactory $productCollectionFactory,
AttributeScopeOverriddenValueFactory $attributeScopeOverriddenValueFactory
AttributeScopeOverriddenValueFactory $attributeScopeOverriddenValueFactory,
ConfigUtil $configUtil
) {
$this->storesUtil = $storesUtil;
$this->progress = $progress;
$this->productCollectionFactory = $productCollectionFactory;
$this->attributeScopeOverriddenValueFactory = $attributeScopeOverriddenValueFactory;
$this->configUtil = $configUtil;

$this->progressIndex = 0;
}
Expand Down Expand Up @@ -84,6 +89,13 @@ private function checkForEmptyUrlKeyAttributeValues(): array
], null, $joinType)
;

if ($this->configUtil->getOnlyCheckVisibleProducts()) {
$collection->addAttributeToFilter(
ProductInterface::VISIBILITY,
['neq' => ProductVisibility::VISIBILITY_NOT_VISIBLE]
);
}

if ($this->progressIndex === 0) {
$this->progress->setGuestimatedSize(count($storeIds), $collection->getSize());
}
Expand Down
14 changes: 13 additions & 1 deletion Checker/Catalog/Product/UrlPath.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

namespace Baldwin\UrlDataIntegrityChecker\Checker\Catalog\Product;

use Baldwin\UrlDataIntegrityChecker\Util\Configuration as ConfigUtil;
use Baldwin\UrlDataIntegrityChecker\Util\Stores as StoresUtil;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Attribute\ScopeOverriddenValueFactory as AttributeScopeOverriddenValueFactory;
use Magento\Catalog\Model\Product as ProductModel;
use Magento\Catalog\Model\Product\Visibility as ProductVisibility;
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
use Magento\Store\Model\Store;
Expand All @@ -23,15 +25,18 @@ class UrlPath
private $storesUtil;
private $productCollectionFactory;
private $attributeScopeOverriddenValueFactory;
private $configUtil;

public function __construct(
StoresUtil $storesUtil,
ProductCollectionFactory $productCollectionFactory,
AttributeScopeOverriddenValueFactory $attributeScopeOverriddenValueFactory
AttributeScopeOverriddenValueFactory $attributeScopeOverriddenValueFactory,
ConfigUtil $configUtil
) {
$this->storesUtil = $storesUtil;
$this->productCollectionFactory = $productCollectionFactory;
$this->attributeScopeOverriddenValueFactory = $attributeScopeOverriddenValueFactory;
$this->configUtil = $configUtil;
}

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

if ($this->configUtil->getOnlyCheckVisibleProducts()) {
$collection->addAttributeToFilter(
ProductInterface::VISIBILITY,
['neq' => ProductVisibility::VISIBILITY_NOT_VISIBLE]
);
}

$productsWithProblems[] = $this->getProductsWithProblems($storeId, $collection);
}

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ In the Magento admin, you can find the results in:
The results of the checkers are currently stored by default in the directory `var/tmp` as `.json` files.
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.

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.

## Some screenshots

### Example of backend report for product url key problems
Expand Down
10 changes: 9 additions & 1 deletion Test/Checker/Catalog/Product/UrlKey/DuplicateUrlKeyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Baldwin\UrlDataIntegrityChecker\Checker\Catalog\Product\UrlKey\DuplicateUrlKey as UrlKeyChecker;
use Baldwin\UrlDataIntegrityChecker\Console\Progress;
use Baldwin\UrlDataIntegrityChecker\Util\Configuration as ConfigUtil;
use Baldwin\UrlDataIntegrityChecker\Util\Stores as StoresUtil;
use Magento\Catalog\Model\Attribute\ScopeOverriddenValue as AttributeScopeOverriddenValue;
use Magento\Catalog\Model\Attribute\ScopeOverriddenValueFactory as AttributeScopeOverriddenValueFactory;
Expand Down Expand Up @@ -119,11 +120,18 @@ function ($productsData) {
->method('create')
->willReturn($attributeScopeOverriddenValueMock);

/** @var ConfigUtil&MockObject */
$configUtilMock = $this
->getMockBuilder(ConfigUtil::class)
->disableOriginalConstructor()
->getMock();

$urlKeyChecker = new UrlKeyChecker(
$storesUtilMock,
$progressMock,
$productCollectionFactoryMock,
$attributeScopeOverriddenValueFactoryMock
$attributeScopeOverriddenValueFactoryMock,
$configUtilMock
);
$results = $urlKeyChecker->execute();

Expand Down
29 changes: 29 additions & 0 deletions Util/Configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Baldwin\UrlDataIntegrityChecker\Util;

use Magento\Framework\App\Config\ScopeConfigInterface;

class Configuration
{
const CONFIG_ONLY_CHECK_VISIBLE_PRODUCTS = 'url_data_integrity_checker/configuration/only_check_visible_products';

private $scopeConfig;

public function __construct(
ScopeConfigInterface $scopeConfig
) {
$this->scopeConfig = $scopeConfig;
}

public function getOnlyCheckVisibleProducts(): bool
{
$configValue = (bool) $this->scopeConfig->getValue(
self::CONFIG_ONLY_CHECK_VISIBLE_PRODUCTS
);

return $configValue;
}
}
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"magento/framework": "^100.1 || ^101.0 || ^102.0 || ^103.0",
"magento/module-backend": "^100.1 || ^101.0 || ^102.0",
"magento/module-catalog": "^101.0 || ^102.0 || ^103.0 || ^104.0",
"magento/module-config": "^100.1 || ^101.0",
"magento/module-cron": "^100.1",
"magento/module-store": "^100.1 || ^101.0",
"magento/module-ui": "^100.1 || ^101.0",
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
<label>Path to store results</label>
<comment>Path where to store json files, can be either an absolute or a relative path</comment>
</field>
<field id="only_check_visible_products" type="select" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0" translate="label">
<label>Don't check for problems with invisible products</label>
<comment>Sometimes you want to focus on products that are visible only, because Magento (at least in recent versions) only generated url rewrites for products that are visible. Be aware, after switching this config setting that you should re-run the checkers.</comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
</group>
</section>
</system>
Expand Down

0 comments on commit 0f652b8

Please sign in to comment.