Redirect Simple Products to their Configurable Parent with Attributes Pre-selected in Magento 2

|

About two years ago I wrote a tutorial on how to redirect simple products to their configurable parents with pre-selected attributes in Magento 1.9.x. Shortly after that Magento 2 was released and I’ve received some requests on how to do the same in the new version.

In this post I will explain to you how to build a module that will redirect simple products to their configurable parent product with automatically pre-selected configurable attributes.

[Update June 18th, 2020] Due to many comments that the code in this tutorial doesn’t work anymore, I’ve tested it with Magento 2.3.5-p1 and can verify that it still works.

If it doesn’t work, then another module must be messing with your configuration.

Don’t feel like doing the work? Download the extension from Github. Feel free to fork its repository and add your own features!

Building a Basic Magento 2 Module

First we need to create the basic files and folders necessary for the module to be recognized by Magento 2.

  1. Create the file /app/code/DaanvdB/RedirectSimpleProducts/registration.php and add the following snippet of code to it:
    <?php
    \Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'DaanvdB_RedirectSimpleProducts',
    __DIR__
    );
  2. Create the file /app/code/DaanvdB/RedirectSimpleProducts/etc/module.xml and add the following code to it:
    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="DaanvdB_RedirectSimpleProducts" setup_version="1.0.0" />
    </config>
    view raw module.xml hosted with ❤ by GitHub

Run php bin/magento setup:upgrade from your terminal so Magento 2 will update and add your new module to its configuration.

Redirecting Simple Products to their Configurable Parent using an Observer

In order to redirect simple products to their configurable parent, we need to create an observer that hooks into an event which is triggered before the catalog_product_view is requested. The best event for this observer is controller_action_predispatch_catalog_product_view.

First we create our custom Observer-class in /app/code/DaanvdB/RedirectSimpleProducts/Observer/Predispatch.php and add the following code (inspired by StackOverflow):

<?php
namespace DaanvdB\RedirectSimpleProducts\Observer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
class Predispatch implements ObserverInterface {
protected $_redirect;
protected $_productTypeConfigurable;
protected $_productRepository;
protected $_storeManager;
public function __construct (
\Magento\Framework\App\Response\Http $redirect,
\Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $productTypeConfigurable,
\Magento\Catalog\Model\ProductRepository $productRepository,
\Magento\Store\Model\StoreManagerInterface $storeManager
) {
$this->_redirect = $redirect;
$this->_productTypeConfigurable = $productTypeConfigurable;
$this->_productRepository = $productRepository;
$this->_storeManager = $storeManager;
}
public function execute(Observer $observer)
{
$pathInfo = $observer->getEvent()->getRequest()->getPathInfo();
/** If it's not a product view we don't need to do anything. */
if (strpos($pathInfo, 'product') === false) {
return;
}
$request = $observer->getEvent()->getRequest();
$simpleProductId = $request->getParam('id');
if (!$simpleProductId) {
return;
}
$simpleProduct = $this->_productRepository->getById($simpleProductId, false, $this->_storeManager->getStore()->getId());
if (!$simpleProduct || $simpleProduct->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) {
return;
}
$configProductId = $this->_productTypeConfigurable->getParentIdsByChild($simpleProductId);
if (isset($configProductId[0])) {
$configProduct = $this->_productRepository->getById($configProductId[0], false, $this->_storeManager->getStore()->getId());
$configType = $configProduct->getTypeInstance();
$attributes = $configType->getConfigurableAttributesAsArray($configProduct);
$options = [];
foreach ($attributes as $attribute) {
$id = $attribute['attribute_id'];
$value = $simpleProduct->getData($attribute['attribute_code']);
$options[$id] = $value;
}
$options = http_build_query($options);
$hash = $options ? '#' . $options : '';
$configProductUrl = $configProduct->getUrlModel()
->getUrl($configProduct) . $hash;
$this->_redirect->setRedirect($configProductUrl, 301);
}
}
}
view raw Predispatch.php hosted with ❤ by GitHub

The Observer we just created takes care of the entire process:

  1. At first it checks if we’re on a catalog_product_view-page,
  2. Then it checks if the current requests is a simple product,
  3. If so, it finds it’s corresponding configurable parent and loads all available configurable attributes,
  4. Then it takes the values for each configurable attribute from the simple product’s properties and builds an options array with them,
  5. With this array it builds a query using Magento 2’s integrated URL parsing functionality.
  6. The created query is appended to the configurable products’ URL-key and a Redirect is set.

Adding the Observer-class to an event

To trigger our custom Observer when the earlier mentioned event is triggered, we need to create a file called events.xml.

Create the file /app/code/DaanvdB/RedirectSimpleProducts/etc/events.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="controller_action_predispatch_catalog_product_view">
<observer name="daanvdb_redirectsimple_products_observer_predispatch" instance="DaanvdB\RedirectSimpleProducts\Observer\Predispatch"/>
</event>
</config>
view raw events.xml hosted with ❤ by GitHub

The events.xml takes care of triggering our custom observer whenever the controller_action_predispatch_catalog_product_view is called.

That’s it! It is this simple to create a module that redirects simple products to their configurable parent product with pre-selected configurable attributes. Make sure you empty your cache (php bin/magento cache:flush) after you’ve copied the files to your site. Enjoy!

Similar Posts

76 Comments

  1. Does this still work with Magento 2.4.1? I tried the tutorial and created the Module, but my simple Products still generates 404 Errors.

  2. Hi Daan,
    First thank you for this code. I tested and works fine on magento 2.3.6. The only problem that keep me to put it on production website is the next one:
    I need to improve this in order to be able to show reviews from the parent product to all his child.
    Because the way is made now I lose the possibility to show reviews of the simple product in category list.
    Now is impossible to give reviews for simple products and only for his parent.
    Because I use color variation the characteristics of the products are the same so if someone give 5 stars to one color I want to show that review to all the children that share the same parent.
    How can I achieve that, can you help?
    Thanks!

  3. Is the this working working for magento opensource 2.4.2 please? We tried and had a couple of issues.

  4. Hey Daan,
    Nice tutorial!

    I have installed the plugin in Magnto 2.4. It seems like not working. My simple products redirect to it’s unique page still. Not to the parent product.
    No errors in the logs or console.

    Any idea to fix this?

  5. Hi

    I have query here ..?
    Please let me know how to come over this

    EX: One simple product which is assigned to multiple configurable or bundle product ,So in this case i will get two parent product right then i can redirect …?

Leave a Reply

Your email address will not be published. Required fields are marked *