diff --git a/Helper/Config.php b/Helper/Config.php
index b0c8826..c3d465c 100644
--- a/Helper/Config.php
+++ b/Helper/Config.php
@@ -4,6 +4,7 @@
*/
declare(strict_types=1);
+
namespace Aligent\PrerenderIo\Helper;
use Magento\Framework\App\Config\ScopeConfigInterface;
@@ -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;
@@ -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
);
}
@@ -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
);
}
diff --git a/Model/Url/GetUrlsForProducts.php b/Model/Url/GetUrlsForProducts.php
index bfec571..31a3969 100644
--- a/Model/Url/GetUrlsForProducts.php
+++ b/Model/Url/GetUrlsForProducts.php
@@ -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;
}
/**
@@ -47,16 +41,6 @@ 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);
@@ -64,17 +48,33 @@ public function execute(array $productIds, int $storeId): array
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;
}
diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml
index e787bef..5f3435e 100644
--- a/etc/adminhtml/system.xml
+++ b/etc/adminhtml/system.xml
@@ -20,6 +20,11 @@
1
+
+
+ Ignore the non-canonical URLs which includes category paths for products.
+ Magento\Config\Model\Config\Source\Yesno
+
diff --git a/etc/config.xml b/etc/config.xml
new file mode 100644
index 0000000..d346dc2
--- /dev/null
+++ b/etc/config.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ 0
+
+
+
+
\ No newline at end of file