Модуль Shopkeeper

Ремонт при обновлении cms

После обновления cms модуль Shopkeeper при запуске просит установить его. Не поддавайся! Если он уже был установлен, повторная установка только ухудшит ситуацию и добавит тебе работы.

01.01.2018

Соблазнительная же кнопочка, но нет - не нажимай ))

В старых версиях ModX Evolution использовалось подключение к базе с помощью расширения mysql, а потом стало использоваться mysqli. В коде старой версии Shopkeeper для выполнения запросов к базе используется не только API ModX, но и прямые вызовы mysql. И вот эти прямые обращения к mysql после обновления перестают работать. Модуль при этом с ошибкой не падает, а всего лишь не может получить информацию о настройках, из чего делает вывод, что требуется установка.

Причин для паники нет, вся информация по заказам осталась в базе.

Как исправить

Самый очевидный вариант - обновить версию Shopkeeper. Последняя версия для ModX Evolution - 1.3.6RC (01.05.2013) - лежит здесь и описанных проблем не имеет. Однако, есть большое число проектов, где требовалось реализовать дополнительные фишки. Shopkeeper там, соответственно, изменялся, и просто взять и обновить его уже не выйдет. Будем восстанавливать.

Главный принцип восстановления работоспособности: заменять обращения к mysql и устаревшим функциям API на соответственные методы API Evolution, актуальные к настоящему моменту.

Для примера я нашла Shopkeeper 1.3.5 (вот тут), пройду по основным "проблемным" моментам и покажу принцип исправления.

Метод mysql_fetch_assoc() нужно заменить на $modx->db->getRow(). Аргументы у них в этом случае одинаковые. Нужно следить за тем, как обращаться к api ModX - в файлах, описывающих классы, следует использовать конструкцию $this->modxmysql_num_rows() заменяется на $modx->db->getRecordCount()mysql_query() становится $modx->db->query().

Отдельно стоит остановиться на mysql_fetch_array(). В данной реализации этот метод возвращал массив с численными индексами, а вот соответственная ему функция API $modx->db->getRow() возвращает массив ассоциативный. Это значит, что при замене mysql_fetch_array() нужно обратить внимание и на последующую обработку данных, где числовые индексы заменить на соответствующие названия полей в таблице.

В старых версиях Shopkeeper встречаются вызовы устаревших методов API. Например, мне попадался $modx->dbQuery(). Легко понять, что его следует заменять на $modx->db->query(). Поскольку замена таких методов очевидна, я не буду останавливаться на ней подробно. Актуальный перечень методов API для работы с базой данных можно найти здесь.

Например, возьмем файл assets/snippets/shopkeeper/classes/class.shopkeeper.php

Было:

while($row = mysql_fetch_assoc($query)){
    $next_increment = $row['Auto_increment'];
}

Нужно:

while($row = $this->modx->db->getRow($query)){
    $next_increment = $row['Auto_increment'];
}

Было:

if (mysql_num_rows(mysql_query("show tables from ".$this->modx->db->config['dbase']."like '".$this->modx->db->config['table_prefix']."manager_shopkeeper'"))==0) return;

Нужно:

if ($this->modx->db->getRecordCount($this->modx->db->query( "show tables from ".$this->modx->db->config['dbase']." like '".$this->modx->db->config['table_prefix']."manager_shopkeeper'"))==0) return;

Было:

while($config = mysql_fetch_array($config_query)){
    $$config[1] = $config[2];
}

Нужно:

while($config = $this->modx->db->getRow($config_query)){
    $$config['setting'] = $config['value'];
}

И вот таким образом нужно проверить и исправить все php-файлы в папке assets/snippets/shopkeeper. Замечу, что такие же действия могут потребоваться и для других сниппетов.

Что делать, если уже попытался установить снова?

По большому счету, трагедии не случилось. Все, что произошло - слетели настройкии и продублировался список системных событий. Нужно из резервной копии достать таблицу manager_shopkeeper_config, убрать дубликаты записей в таблице system_eventnames и проверить настройки плагинов, обрабатывающих события Shopkeeper - как раз настройки системных событий и могли слететь.

Вот список событий Shopkeeper на всякий случай:

  • OnSHKbeforeSendOrder
  • OnSHKcalcTotalPrice
  • OnSHKcartLoad
  • OnSHKChangeStatus
  • OnSHKFrontendInit
  • OnSHKgetProductPrice
  • OnSHKMailApprovedForPayment
  • OnSHKmodPagePrint
  • OnSHKmodRenderTopLinks
  • OnSHKOrderDescRender
  • OnSHKsaveOrder
  • OnSHKstatusSendMail

 Успехов!