4

I have 3 storeviews in multiple languages (English, Dutch and German). The all have the same categories but the english names must be translated. So i select a storeview in the categorie editor in the backend. But when I rename a category in let's say 'kitchen' to 'Küchen' in german (or to any other name) I get the following error:

"URL key for specified store already exists."

So and i can't change the name to anything whithout getting this error. I tried to manually add a random url key lets say 'foo1234' but still not working. so i changed the category name and url key to random text. but there is no way i get it changed

I have no idea why i keep getting this error.

  • Tried to re-index your database, also clear your Magento Cache? – Khoa TruongDinh Aug 29 '16 at 15:34
  • Thanks for commenting, i've tried that but it doesn't make a difference – Rickert Aug 30 '16 at 6:08
2

I've fixed this issue. And I have 2 solutions for that.

The first one: Clean up your database in table url_rewrite (Change the url_key of all category). You can write UpgradeData script for this solution.

The second one: Remove the duplication data when saving category. This data is throw in method doReplace($urls) in \vendor\magento\module-url-rewrite\Model\Storage\DbStorage.php file.

protected function doReplace($urls)
    {
        foreach ($this->createFilterDataBasedOnUrls($urls) as $type => $urlData) {
            $urlData[UrlRewrite::ENTITY_TYPE] = $type;
            $this->deleteByData($urlData);
        }
        $data = [];
        foreach ($urls as $url) {
            $data[] = $url->toArray();
        }
        $this->insertMultiple($data);
    } 

After debugging, I found out $data variable has a duplicate record. If you want this method to work without any errors. Rewrite this method above to:

protected function doReplace($urls)
{
    foreach ($this->createFilterDataBasedOnUrls($urls) as $type => $urlData) {
        $urlData[UrlRewrite::ENTITY_TYPE] = $type;
        $this->deleteByData($urlData);
    }
    $data = [];
    $storeId_requestPaths = [];
    foreach ($urls as $url) {
        $storeId = $url->getStoreId();
        $requestPath = $url->getRequestPath();
        // Skip if is exist in the database
        $sql = "SELECT * FROM url_rewrite where store_id = $storeId and request_path = '$requestPath'";
        $exists = $this->connection->fetchOne($sql);

        if ($exists) continue;

        $storeId_requestPaths[] = $storeId . '-' . $requestPath;
        $data[] = $url->toArray();
    }

    // Remove duplication data;
    $n = count($storeId_requestPaths);
    for ($i = 0; $i < $n - 1; $i++) {
        for ($j = $i + 1; $j < $n; $j++) {
            if ($storeId_requestPaths[$i] == $storeId_requestPaths[$j]) {
                unset($data[$j]);
            }
        }
    }
    $this->insertMultiple($data);
}

If you want to get more details. Please, read my comment in

https://github.com/magento/magento2/issues/7298

Hope this will help you.

  • Showing error "Something went wrong while saving the category." – Pushpendra Singh Aug 11 '17 at 11:17
  • same error @pushpendra singh did you get the solution? – Jigs Parmar Mar 14 '18 at 5:46
  • Sorry for the late response, in your case it might be some other bugs. You should debug to the save category function and see what is causing the problem. – Toan Tam Mar 21 '18 at 1:53
3

This is an acknowledge issue of Magento 2, it's fixed permanently in 2.2 but it wasn't backported to 2.1. So I will provide you a workaround for it and let see how does it go :)

app/code/Stackoverflow/UrlRewrite/etc/di.xml

<?xml version="1.0"?>
<!--
  ~ Copyright © 2017 Toan Nguyen. All rights reserved.
  ~ See COPYING.txt for license details.
  -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\UrlRewrite\Model\Storage\DbStorage" type="Stackoverflow\UrlRewrite\Model\Storage\DbStorage"/>
</config>

app/code/Stackoverflow/UrlRewrite/Model/Storage/DbStorage.php

<?php
/**
 * Copyright © 2017 Toan Nguyen. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Stackoverflow\UrlRewrite\Model\Storage;

use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
use Magento\UrlRewrite\Service\V1\Data\UrlRewriteFactory;

class DbStorage extends \Magento\UrlRewrite\Model\Storage\DbStorage
{
    /**
     * Save new url rewrites and remove old if exist. Template method
     *
     * @param \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[] $urls
     *
     * @return void
     * @throws \Magento\Framework\Exception\AlreadyExistsException
     */
    protected function doReplace($urls)
    {
        foreach ($this->createFilterDataBasedOnUrls($urls) as $type => $urlData) {
            $urlData[UrlRewrite::ENTITY_TYPE] = $type;
            $this->deleteByData($urlData);
        }
        $data = [];
        foreach ($urls as $url) {
            $urlArray = $url->toArray();
            $urlPath = $urlArray['request_path'];
            $storeId = $urlArray['store_id'];
            $dataKey = $storeId . '..' . $urlPath;
            $data[$dataKey] = $urlArray;
        }

        $this->insertMultiple($data);
    }
}

I tried myself a lot of ways/workaround on GitHub and this one seems fixed the problem permanently. Gods know why...

Hope it helps.

  • It's not true. It still is a bug in 2.2.x – WaPoNe Apr 5 at 10:39
0

As it is reported on github also, check these issues, hope the tricks suggested here, will help you out regarding this issue:-

#1471 #3268 #4487

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.