Skip to content

Commit

Permalink
Merge pull request #13 from aligent/fix/non-canonical-product-urls-re…
Browse files Browse the repository at this point in the history
…caching

fix for non-canonical URL being sent for product recaching
  • Loading branch information
quangdo-aligent authored Jan 8, 2024
2 parents 959f78f + f2c024b commit 6ba80fb
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 35 deletions.
21 changes: 19 additions & 2 deletions Helper/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

declare(strict_types=1);

namespace Aligent\PrerenderIo\Helper;

use Magento\Framework\App\Config\ScopeConfigInterface;
Expand All @@ -13,6 +14,7 @@ class Config
{
private const XML_PATH_RECACHE_ENABLED = 'system/prerender_io/enabled';
private const XML_PATH_PRERENDER_TOKEN = 'system/prerender_io/token';
private const XML_PATH_PRERENDER_USE_PRODUCT_CANONICAL_URL = 'system/prerender_io/use_product_canonical_url';

/** @var ScopeConfigInterface */
private ScopeConfigInterface $scopeConfig;
Expand All @@ -36,7 +38,7 @@ public function isRecacheEnabled(?int $storeId = null): bool
{
return $this->scopeConfig->isSetFlag(
self::XML_PATH_RECACHE_ENABLED,
ScopeInterface::SCOPE_STORE,
ScopeInterface::SCOPE_STORES,
$storeId
);
}
Expand All @@ -51,7 +53,22 @@ public function getToken(?int $storeId = null): ?string
{
return $this->scopeConfig->getValue(
self::XML_PATH_PRERENDER_TOKEN,
ScopeInterface::SCOPE_STORE,
ScopeInterface::SCOPE_STORES,
$storeId
);
}

/**
* Return if product canonical url configuration is enabled or not
*
* @param int|null $storeId
* @return string|null
*/
public function isUseProductCanonicalUrlEnabled(?int $storeId = null): bool
{
return $this->scopeConfig->isSetFlag(
self::XML_PATH_PRERENDER_USE_PRODUCT_CANONICAL_URL,
ScopeInterface::SCOPE_STORES,
$storeId
);
}
Expand Down
66 changes: 33 additions & 33 deletions Model/Url/GetUrlsForProducts.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,32 @@
*/

declare(strict_types=1);

namespace Aligent\PrerenderIo\Model\Url;

use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Aligent\PrerenderIo\Helper\Config;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Model\App\Emulation;
use Magento\Store\Model\Store;
use Magento\Store\Model\StoreManagerInterface;
use Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;

class GetUrlsForProducts
{
/** @var CollectionFactory */
private CollectionFactory $productCollectionFactory;
/** @var StoreManagerInterface */
private StoreManagerInterface $storeManager;
/** @var Emulation */
private Emulation $emulation;

/**
*
* @param CollectionFactory $productCollectionFactory
* @param StoreManagerInterface $storeManager
* @param Emulation $emulation
* @param UrlFinderInterface $urlFinder
* @param Config $prerenderConfigHelper
*/
public function __construct(
CollectionFactory $productCollectionFactory,
StoreManagerInterface $storeManager,
Emulation $emulation
private readonly StoreManagerInterface $storeManager,
private readonly Emulation $emulation,
private readonly UrlFinderInterface $urlFinder,
private readonly Config $prerenderConfigHelper
) {
$this->productCollectionFactory = $productCollectionFactory;
$this->storeManager = $storeManager;
$this->emulation = $emulation;
}

/**
Expand All @@ -47,34 +41,40 @@ public function __construct(
*/
public function execute(array $productIds, int $storeId): array
{
$productCollection = $this->productCollectionFactory->create();
// do not ignore out of stock products
$productCollection->setFlag('has_stock_status_filter', true);
// if array of product ids is empty, just load all products
if (!empty($productIds)) {
$productCollection->addIdFilter($productIds);
}
$productCollection->setStoreId($storeId);
$productCollection->addUrlRewrite();

try {
/** @var Store $store */
$store = $this->storeManager->getStore($storeId);
} catch (NoSuchEntityException $e) {
return [];
}

$useProductCanonical = $this->prerenderConfigHelper->isUseProductCanonicalUrlEnabled($storeId);

$findByData = [
UrlRewrite::ENTITY_TYPE => Rewrite::ENTITY_TYPE_PRODUCT,
UrlRewrite::STORE_ID => $storeId,
UrlRewrite::ENTITY_ID => $productIds
];

$urlRewrites = $this->urlFinder->findAllByData($findByData);

$this->emulation->startEnvironmentEmulation($storeId);
$urls = [];
/** @var Product $product */
foreach ($productCollection as $product) {
$urlPath = $product->getData('request_path');
if (empty($urlPath)) {

foreach ($urlRewrites as $urlRewrite) {
if (empty($urlRewrite->getRequestPath())) {
continue;
}

// Ignore the product URL with category path.
if ($useProductCanonical && $urlRewrite->getMetadata()) {
continue;
}
try {
// remove trailing slashes from urls
$urls[] = rtrim($store->getUrl($urlPath), '/');
// Generate direct URL to avoid Magento stopping at the 4th level onwards
$url = $store->getUrl('', ['_direct' => $urlRewrite->getRequestPath()]);
// Remove trailing slashes from urls
$urls[] = rtrim($url, '/');
} catch (NoSuchEntityException $e) {
continue;
}
Expand Down
5 changes: 5 additions & 0 deletions etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
<field id="enabled">1</field>
</depends>
</field>
<field id="use_product_canonical_url" translate="label comment" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Use Canonical URL For Products</label>
<comment>Ignore the non-canonical URLs which includes category paths for products.</comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
</group>
</section>
</system>
Expand Down
11 changes: 11 additions & 0 deletions etc/config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<system>
<prerender_io>
<use_product_canonical_url>0</use_product_canonical_url>
</prerender_io>
</system>
</default>
</config>

0 comments on commit 6ba80fb

Please sign in to comment.