4 апреля 2015 г.

В OpenCart есть один досадный недостаток, точнее этот недостаток присутствует только в ограниченной версии ПО OpenCart, которое распространяется свободно. Касается это канонических имён товаров и страниц (SEO URL), которые должны быть уникальны на всю систему.

При создании нового товара или категории в стандартной версии OpenCart нет проверки на наличие существующего в системе SEO URL, поэтому при большом количестве товаров возможно появление дубликатов по ссылкам. На практике это будет означать, что один из товаров с одинаковыми каноническими именами никогда не будет отображён, или под видом одного будет представлен другой товар. Очень часто подобная "неприятность" возникает у тех, кто пользуется разного рода выгрузками из сторонних программ по торговой и предпринимательской деятельности.

Чтобы обнаружить дубликаты, нам потребуется доступ к базе данных MySQL. Подойдёт всем известный phpMyAdmin или любой другой менеджер БД с возможностью выполнения прямых SQL-запросов. Прежде чем начать работы, помните, что перед любыми манипуляциями с БД напрямую, необходимо сделать резервную копию!

Первый запрос касается таблицы url_alias, он покажет, есть ли в ней дубликаты канонических имён:
SELECT ua1.`query` FROM `oc_url_alias` ua1
LEFT JOIN `oc_url_alias` ua2 ON (ua1.keyword = ua2.keyword)
WHERE ua1.`query` <> ua2.`query` ORDER BY ua1.`query`

Примечание: Здесь и далее oc_ является префиксом таблиц, у каждого он может быть свой (см. DB_PREFIX в файле config.php).

Если запрос вернул небольшое количество строк, то можно использовать его результаты как список для ручной правки объектов по прямым ссылкам в панели администрирования, например, для элемента product_id=48 прямая ссылка примет вид http://[domain]/admin/index.php?route=catalog/product/update&token=[token]&product_id=48

При большом количестве товаров ситуация немного меняется. Если вы уверены, что под одинаковыми ссылками разные товары (не только по описанию, но и опциям или дополнительным изображениям и т.п.), то можно дополнить ссылки их идентификаторами или просто удалить дублирующие записи, в последнем случае товар в магазине будет представлен под стандартной ссылкой-идентификатором.

Второй запрос для первого варианта будет выглядеть следующим образом:
UPDATE `oc_url_alias` ua1 LEFT JOIN `oc_url_alias` ua2 ON (ua1.keyword = ua2.keyword) SET ua1.keyword = CONCAT(ua1.keyword, '_', ua1.url_alias_id) WHERE ua1.`query` <> ua2.`query`
Соответственно, для альтернативного варианта (простого удаления) он примет иной вид:
DELETE FROM `oc_url_alias` WHERE url_alias_id IN (SELECT * FROM (SELECT ua2.url_alias_id FROM `oc_url_alias` ua1
LEFT JOIN `oc_url_alias` ua2 ON (ua1.keyword = ua2.keyword)
WHERE ua1.`query` <> ua2.`query` GROUP BY ua1.`keyword`) as tbl)

Третий запрос
для тех, кто действительно уверен, что в БД присутствуют полноценные дубликаты товаров. Этот запрос должен быть выполнен до второго запроса, поскольку всё ещё требуется информация о связях дубликатов по ссылкам:
DELETE p, p2c FROM `oc_product` p
LEFT JOIN `oc_product_to_category` p2c ON (p2c.product_id = p.product_id)
WHERE p.product_id IN (SELECT SUBSTRING_INDEX(ua1.query,'=',-1) AS product_id FROM `oc_url_alias` ua1
LEFT JOIN `oc_url_alias` ua2 ON (ua1.keyword = ua2.keyword)
WHERE ua1.`query` <> ua2.`query` GROUP BY ua1.`keyword`)

Этот запрос удаляет дублирующие товары из таблицы product и их связи с категориями из таблицы product_to_category.

Обратите внимание, в этом запросе не представлены все возможные связи товаров с другими таблицами (изображения, загрузки, заказы, модули и т.д.). Здесь необходим полноценный анализ существующей модели БД, выявления зависимых таблиц и построения аналогичного, но уже более сложного запроса на примере выше.

Автор блога готов выполнить все необходимые работы по анализу и выявлению потерянных связей в БД; поиску и удалению объектов-дубликатов, а также выполнить оптимизацию таблиц базы данных стандартными средствами. Кроме того, доступен отдельный заказ по доработке карточек объектов с полями SEO URL в административной панели OpenCart (проверка на наличие существующих канонических имён в процессе редактирования). По вопросам заказов просьба обращаться через страницу обратной связи.

0 comments:

Отправить комментарий

  • RSS
  • Twitter
  • Youtube