magento2: Product duplication of imported products "fails" due to url rewrites

Preconditions

  1. Magento 2.4-develop

Steps to reproduce

  1. Save and duplicate product A, creating a duplicate product B image

  2. Edit product B, change the URL Key under “Search Engine Optimization” while leaving “Create Permanent Redirect for old URL” checked and save the product image image

  3. Open product A

  4. Save and duplicate product A again in an attempt to create product C

Expected result

  1. A workflow that lets me duplicate the product by e.g. changing the URL Key.

Actual result

  1. Warning The value specified in the URL Key field would generate a URL that already exists. image
  2. Products don’t have url key product-a-1 but product A cannot be duplicated again image

Original descirption

Preconditions

  1. Environment
  • php7.0 7.0.25-1+ubuntu16.04.1+deb.sury.org+1
  • mysql-server-5.7 5.7.20-0ubuntu0.16.04.1
  • magento 2.2.1 with (some) data imported from m1.6.2 (with earlier m2 version)
  1. Some categories of which some are imported from m1.6.2 (with earlier m2 version)
  2. URLRewrites for these products and categories

Steps to reproduce

  1. Open an old product, click on “Save and duplicate”

Expected result

  1. A workflow that lets me duplicate the product by e.g. changing the URL Key.

Actual result

I see a warning

The value specified in the URL Key field would generate a URL that already exists.

To resolve this conflict, you can either change the value of the URL Key field (located in the Search Engine Optimization section) to a unique value, or change the Request Path fields in all locations listed below:

- PRODURLKEY.html
- CATURLKEY/SUBCATURLKEY/PRODURLKEY.html
[... modified for readability ...]
You saved the product.

The product is then not duplicated.

I assume the error/warning message changed in Magento 2.2.1 (might have been “URL key for specified store already exists.” before). There is a variety of other issues, none of which addresses the implications of this usecase (extremely inconvient product duplication workflow).

Also, the solution proposed by the warning (changing the URL Key and hitting “Save and duplicate”) does not work.

I think it might have something to do with the attributes (url_key, url_path) being assigned to different stores (store_id).

I understand that developers favor NOT to use magento1-stlye and just append something to the url_key to prevent duplicates to avoid what some user called a SEO-mess. However, it should be easy to duplicate a given product (and e.g. manually assign a new url-key).

I will update this issue with a list of related issues as they cross my way.

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 12
  • Comments: 28 (2 by maintainers)

Most upvoted comments

@luckyduck Here’s my solution: app/code/<VENDOR>/<MODULE>/CatalogUrlRewrite/Model/ProductUrlPathGenerator.php:

namespace <VENDOR>\<MODULE>\CatalogUrlRewrite\Model;

class ProductUrlPathGenerator extends \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator
{
    /**
     * Ignore attribute url_path. Always use url_key instead.
     *
     * @inheritdoc
     */
    public function getUrlPath($product, $category = null)
    {
        $path = $product->getUrlKey()
            ? $this->prepareProductUrlKey($product)
            : $this->prepareProductDefaultUrlKey($product);
        return $category === null
            ? $path
            : $this->categoryUrlPathGenerator->getUrlPath($category) . '/' . $path;
    }
}

Tie this in with app/code/<VENDOR>/<MODULE>/etc/di.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator"
                type="<VENDOR>\<MODULE>\CatalogUrlRewrite\Model\ProductUrlPathGenerator" />
</config>

Hope this helps.

@chattertech Yes, indeed. You will need more files to have a complete module. I’ll attach a full one here. You need to extract the zip to app/code or upload the content there, respectively. It includes the needed subfolders. You should delete the files and folders that you created, though. UrlPathFix.zip

@magento-engcom-team Any updates or fixes on this issue?

@intelsteel Well, mine is. 😃

It looks like this has something to do with the combo of the way that \Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator::getUrlPath() first looks for a url_path, then falls back to a url_key:

public function getUrlPath($product, $category = null)
    {
        $path = $product->getData('url_path');
        if ($path === null) {
            $path = $product->getUrlKey()
                ? $this->prepareProductUrlKey($product)
                : $this->prepareProductDefaultUrlKey($product);
        }
        return $category === null
            ? $path
            : $this->categoryUrlPathGenerator->getUrlPath($category) . '/' . $path;
    }

And the product copier function (\Magento\Catalog\Model\Product\Copier::copy()) only updates the url_key on duplication, leaving the url_path in tact from the old product:

public function copy(\Magento\Catalog\Model\Product $product)
    {
        .
        .
        .
        $isDuplicateSaved = false;
        do {
            $urlKey = $duplicate->getUrlKey();
            $urlKey = preg_match('/(.*)-(\d+)$/', $urlKey, $matches)
                ? $matches[1] . '-' . ($matches[2] + 1)
                : $urlKey . '-1';
            $duplicate->setUrlKey($urlKey);
            try {
                $duplicate->save();
                $isDuplicateSaved = true;
            } catch (\Magento\Framework\Exception\AlreadyExistsException $e) {
            }
        } while (!$isDuplicateSaved);
        .
        .
        .
        return $duplicate;
    }

I was able to force the url_path to reset on duplication, however this isn’t a complete fix because I’m unable to update the URL key on the duplicated product after that, and the url_path in the database for the new product is still the original product’s url_path.

Just a start, hope this helps the Magento team diagnose this issue.