Magento 2 : get rewrite product url
Here is the method I used to get the product url.
It is definitely not optimal as I have to load the entire product to get it so very bad in terms of performance.
First you need to inject a Magento\Catalog\Model\ProductRepository
in your constructor:
use Magento\Catalog\Model\ProductRepository;
//...
public function __construct(
ProductRepository $productRepository
) {
$this->_productRepository = $productRepository;
}
Then you load the product based on the product id:
$product = $this->_productRepository->getById($productId);
Finally you can get the URL model to retrieve the rewritten URL:
return $product->getUrlModel()->getUrl($product);
This may not really answer the question but chances are that, if you are missing the URL rewrite, you may be getting your product out of a product collection. And adding URL rewrite info is not automatic as you can see in \Magento\Catalog\Model\ResourceModel\Product\Collection::$_addUrlRewrite
.
The way I managed forcing the addition of URL rewrites is by creating a plugin on the create()
method of \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
. And as soon as your code (or Magento's core code) uses this factory for instanciating a product collection (and it should as of best practices), this plugin forces the \Magento\Catalog\Model\ResourceModel\Product\Collection::$_addUrlRewrite
to true
.
Then, products URL rewrites are successfully added to the products without the need to loop on them and reload them. It thus fixes the perf downside that @Raphael spoke about.
Here is the plugin XML definition (in your di.xml
file):
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Catalog\Model\ResourceModel\Product\CollectionFactory">
<plugin name="your_plugin_unique_nane" type="Your\Plugin\Namespace\Plugin" />
</type>
</config>
And the plugin code:
namespace Your\Plugin\Namespace;
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as CoreCollectionFactory;
class Plugin
{
/**
* @param CoreCollectionFactory $subject
* @param Collection $collection
* @return Collection
*/
public function afterCreate(CoreCollectionFactory $subject, Collection $collection)
{
$collection->addUrlRewrite();
return $collection;
}
}