Magento 2: Как сгенерировать URL-ключ продукта при создании продукта из Rest API?


Я создаю продукт в magento usign Rest API. Используя следующий формат:

{
"product": {
"name": "Product Name",
"sku": "product_name_1498227094",
"attribute_set_id": "18",
"status": 1,
"visibility": 4,
"type_id": "simple",
"price": 0,
"weight": 0,
"product_links": [],
"options": [],
"tier_prices": [],
"custom_attributes": [
  {
    "attribute_code": "description",
    "value": "Product About content"
  },
  {
    "attribute_code": "short_description",
    "value": "Product Mini content"
  },
  {
    "attribute_code": "meta_title",
    "value": "Product Name"
  },
  {
    "attribute_code": "meta_keyword",
    "value": "Product Name"
  },
  {
    "attribute_code": "meta_description",
    "value": "Product Name"
  }
]
},
"saveOptions": true
}

Его продукт создается впервые. Но если я снова использую те же данные для создания продукта. Я получаю следующую ошибку:

[message] => URL key for specified store already exists.

Как вы можете проверить, я не передаю url_key в массив custom_attributes.

{
  "attribute_code": "url_key",
  "value": "10090-white-xl"
}

Вот мой вопрос: Не создает ли magento2 уникальный URL-ключ автоматически? Как мы можем сгенерировать уникальный URL-ключ в magento2 с учетом SEO?

Author: Pankaj Pareek, 2017-06-23

5 answers

Я создал пользовательский код, чтобы проверить, существует ли URL-ключ или нет. В соответствии с потоком, используемым в функциях импорта продуктов в Magento 2.

public function __construct(
    --
    \Magento\Store\Model\StoreManagerInterface $storeManager, 
    \Magento\Framework\App\ResourceConnection $resource, 
    --
) {
    --
    $this->_storeManager = $storeManager;
    $this->_resource = $resource;
    --  
}



public function createUrlKey($title, $sku) 
{
    $url = preg_replace('#[^0-9a-z]+#i', '-', $title);
    $urlKey = strtolower($url);
    $storeId = (int) $this->_storeManager->getStore()->getStoreId();
    
    $isUnique = $this->checkUrlKeyDuplicates($sku, $urlKey, $storeId);
    if ($isUnique) {
        return $urlKey;
    } else {
        return $urlKey . '-' . time();
    }
}

/*
 * Function to check URL Key Duplicates in Database
 */

private function checkUrlKeyDuplicates($sku, $urlKey, $storeId) 
{
    $urlKey .= '.html';

    $connection = $this->_resource->getConnection(\Magento\Framework\App\ResourceConnection::DEFAULT_CONNECTION);

    $tablename = $connection->getTableName('url_rewrite');
    $sql = $connection->select()->from(
                    ['url_rewrite' => $connection->getTableName('url_rewrite')], ['request_path', 'store_id']
            )->joinLeft(
                    ['cpe' => $connection->getTableName('catalog_product_entity')], "cpe.entity_id = url_rewrite.entity_id"
            )->where('request_path IN (?)', $urlKey)
            ->where('store_id IN (?)', $storeId)
            ->where('cpe.sku not in (?)', $sku);

    $urlKeyDuplicates = $connection->fetchAssoc($sql);

    if (!empty($urlKeyDuplicates)) {
        return false;
    } else {
        return true;
    }
}
 9
Author: Pankaj Pareek, 2021-02-11 04:43:08

Для выполнения функции CreateUrlKey я добавил во вторую строку этот код:

$lastCharTitle = substr($title, -1);
$lastUrlChar = substr($url, -1);
if ($lastUrlChar == "-" && $lastCharTitle != "-"){
    $url = substr($url, 0, strlen($url) - 1);
}

Чтобы удалить последний "-", если он сгенерирован из первой строки "preg_replace". Также я заменил метку времени уникальным артикулом, потому что иногда в процессе автоматического импорта время() двух соседних записей может быть одинаковым, поэтому оно не уникально.

Теперь функция такова:

public function createUrlKey($title, $sku)
{
    $url = preg_replace('#[^0-9a-z]+#i', '-', $title);
    $lastCharTitle = substr($title, -1);
    $lastUrlChar = substr($url, -1);
    if ($lastUrlChar == "-" && $lastCharTitle != "-"){
        $url = substr($url, 0, strlen($url) - 1);
    }

    $urlKey = strtolower($url);
    $storeId = (int) $this->_storeManager->getStore()->getStoreId();

    $isUnique = $this->checkUrlKeyDuplicates($sku, $urlKey, $storeId);
    if ($isUnique) {
        return $urlKey;
    } else {
        return $urlKey . '-' . $sku;
    }
}
 3
Author: Walter Bacchetti - Magma, 2017-07-19 15:36:17

Magento2 использует название продукта для автоматического создания URL-адреса. Поэтому, если у вас несколько продуктов с одинаковым названием, вы получите эту ошибку при попытке загрузить последующие продукты.

Мой совет состоял бы в том, чтобы либо отличать названия продуктов, поэтому, если у вас есть настраиваемый продукт с именем "КОРИЧНЕВАЯ РУБАШКА", вы бы загрузили простые продукты "КОРИЧНЕВАЯ РУБАШКА - S", "КОРИЧНЕВАЯ РУБАШКА - L" и т. Д.

В противном случае, если у вас могут быть продукты с одинаковым названием, вам нужно будет создать ваши собственные URL-ключи:

Возможно, добавьте артикул или что-то еще уникальное к названию продукта в ключе; например, "url_key": "sku001-коричневая рубашка" и т. Д.

 1
Author: BAF, 2017-06-23 15:17:11

Кто-нибудь уже сталкивался с проблемой в Magento 2.2, что у вас два разных названия продуктов, и magento создает один и тот же URL-ключ для обоих? Например:

Имя: Название продукта 1 url-ключ: название продукта-1

Название: Название продукта 2 url-ключ: название продукта-1

У меня сейчас такая проблема. Я публикую два разных продукта с разными названиями продуктов, а magento просто добавляет один продукт в магазин, и я задался вопросом, почему. Поэтому я взглянул на свой опубликованный контент и ответ от magento. И magento использует url-ключ из продукта 1 для продукта 2, хотя у меня есть две отдельные записи в api для этих двух продуктов. Не могу объяснить, почему magento делает это, и я не нашел никакого решения этой проблемы или проблемы/ошибки для Magento 2.2, но реализовал и опубликовал свой собственный URL-ключ. Я также удалил URL-ключи в базе данных url_rewrite.

Я уже добавил много продуктов в однотипный пост без каких-либо проблем.

 0
Author: Loqic, 2018-01-23 09:21:21

Более эффективный способ - использовать коллекцию url_rewrite, как показано ниже, без использования диспетчера объектов:

$urlRewriteFactory = $this->_objectManager->create('\Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollection');
        $UrlRewriteCollectionData = $urlRewriteFactory->addFieldToFilter('request_path', ['eq' => $productUrlKey] )->addFieldToFilter('store_id', $this->scopeConfig->storeId);
        $productUrlData = $UrlRewriteCollectionData->getFirstItem();
        $existingProductUrlCount = 0;
        if($productUrlData->getId()){
            $existingProductUrlCount = 1;
        }

    try {
        if ($existingProductUrlCount > 0){
            return true;
        }
    } catch (\Exception $ex) {
        $this->logInfo("Check for URL exists " . $ex->getMessage());
    }
    return false;
 0
Author: Tatenda Chuma, 2020-07-13 04:08:33