Как убрать COM_VIRTUEMART_ из URL страницы Virtuemart

Довольно часто встречается такая проблема с компонентом Virtuemart: ни с того, ни с сего вдруг появляются паразитные записи в урлах страниц, которые генерируются компонентом Virtuemart. Эти самые URL всегда непредсказуемые, на каких-то сайтах подхватывается com_virtuemart_menu_manufacturers, на других сайтах подхватывается com_virtuemart_menu_paymentmethod и так далее. Если вы заметили этот баг на своем сайте, то скорее всего вы недавно обновили свой виртумарт до последней версии. После обновления виртумарта в базе данных появляются паразитные записи в таблице _menu
Эти самые записи ссылаются на несуществующие parent_id. Как вы знаете, основу иерархии системы меню в Joomla составляют поля id, parent_id, lft, rgt таблицы _menu.

Так вот, при создании нового пункта меню после обновления Virtuemart ядро Joomla может "случайно" подхватить одну из "битых записей" и записать в поле PATH сумму строк из поля alias и из поля title. Таким образом у нового пункта меню в поле path появляется запись вида moyalias/com_virtuemart_menu_paymentmethod
Мы не стали разбираться, как и почему это происходит, но это факт.

Мы проанализировали несколько баз данных сайтов с компонентами Virtuevart, а именно проверили таблицу menu на предмет паразитных записей и обнаружили, что чем большее число раз обновлялся виртумарт на сайте, тем больше этих паразитных строк в таблице. Так, например, на одном сайте, на котором виртумарт в течение нескольких лет постепенно обновлялся с версии 2.0.14 до версии 2.6.16 количество паразитных записей в таблице составило 93.

 Найти и удалить

 Собственно, как лечить, чтобы не навредить. Мы просто удалили паразитные записи с заголовками COM_VIRUEMART из таблицы menu. Идентифицировать паразитов очень просто: у этих записей в поле parent_id указано значение несуществующей записи.

Внимание! Первая запись Menu_Item_Root в таблице menu с ID=1 и parent_id=0. Это "корневая" запись и удалять ее нельзя. Все остальные записи должны иметь значение parent_id больше нуля.

Кто работает с таблицами MySQL, без труда отфильтрует все записи по полю title с параметром %virtue% , затем выпишет из столбца parent_id уникальные значения и проверит, есть ли в таблице запись с таким ID. Если таких записей не найдется, можно смело удалить все паразитки. В итоге должно остаться 13 записей для фильтра %virtue% в поле title. Для получения уникальных значений parent_id используйте запрос в "быстрой правке", не забудьте поменять префикс jos_ на ваш:

SELECT `parent_id`  FROM `jos_menu` WHERE `title` LIKE '%VIRTUE%' GROUP BY `jos_menu`.`parent_id`

 Не обращаем внимания на строки с ID=1, и не трогаем их.

Для надежности понимания методики, выложим несколько скриншотов.

  1. Заходим в таблицу menu
  2. Нажимаем кнопку Поиск. Напротив строки title выбираем LIKE %...%, в поле "значение" вписываем virtue и, не убирая курсор из поля, нажимаем ENTER. Получаем отфильтрованный список менюшек Virtuemart. Здесь всего 13 правильных, остальные "битые".
  3. Перемещаем нижний ползунок вправо (таблица сдвигается влево), находим поле parent_id и кликаем по заголовку. Тем самым выполняется запрос на сортировку по убыванию. Смотрим вверху слева, сколько записей всего нам вернул запрос. Если записей больше лимита отображения, то увеличьте лимит, чтобы на экран вывелись все записи. Пролистайте страницу вниз-верх, перепишите уникальные значения из столбца parent_id. Или выполните запрос, указанный выше.
  4. Проверяем айдишники на "битость". Нажмите кнопку Поиск. В первой строке ID введите первое значение из вашего списка и нажмите ENTER. Если "ничего не произошло", это не значит, что ничего не произошло. Пролистайте страницу вниз и посмотрите на зеленое сообщение: MySQL вернула пустой результат (т.е. ноль строк). ( Запрос занял 0.0002 сек. ) Это значит, что все записи в таблице menu с таким parent_id ссылаются "в никуда" и их можно с радостью удалить. Для этого стираем значение в поле ID и вводим его же в поле parent_id, нажимаем ENTER, видим список битых записей, отмечаем все флажками слева и нажимаем внизу ссылку "Удалить". Подтверждаем ДА наше действие.
  5. Таким же образом проверяем остальные айдишники. Один из них обязательно существует в базе. Именно эта запись является родительской для 13 записей меню Virtuemart. 

Пожалуйста, делайте резервную копию таблицы перед чисткой.