Недавно, мне позвонил один приятель и попросил помочь с интернет-магазином. Сказал, что его разработчик никак не справляется, а сроки сильно поджимают. Почему бы не помочь человеку? Благо один баг починить зачастую много времени не занимает (если знаешь язык, конечно). Спрашиваю, на что жалуемся? Ситуация оказалась следующей: есть сайт на движке Joomla с модулем интернет-магазина Virtuemart и заказы там можно совершать в разных валютах. Проблема в том, что для всех заказанных продуктов валюта такая, как выбрал пользователь, а общая сумма всегда в валюте по умолчанию (в гривне). Я немного пошерстил на эту тему интернеты, но ничего полезного не нашел. Потому, после того, как разобрался, решил написать небольшую статью. Может, кому-нибудь она пригодится.

Так сложилось, что раньше с Joomla я никогда не работал, но поскольку все движки устроены примерно одинаково, это не было большой проблемой. Первым делом я поискал файлик конфигурации, чтоб выяснить пароль от mysql. Он весьма услужливо был расположен прямо в корне и назывался configuration.php, так что я его сразу узнал.

Затем, я полез в базу. Где в таблице joomla_virtuemart_orders, я с удовольствием обнаружил записи обо всех заказах. Структура таблицы, как бывает всегда, при использовании готовых модулей, изобиловала странными полями о назначении которых мне оставалось только догадываться. Я решил себя не утруждать, поскольку задача у меня была другая, и принялся искать те поля, которые мне были понятны. Поле order_currency выглядело очень похожим на то, что мне нужно (хотя это было не единственное поле с валютой). Просмотрев записи о заказах, я выяснил, что значение поля order_currency во всех записях одинаковое и соответствует гривне. Далее я изучил таблицу joomla_virtuemart_order_items в которой, как я догадался, хранятся заказанные товары. Обнаружил в ней поле order_item_currency, чего, пожалуй, и следовало ожидать. Значения этого поля варьировались в зависимости от записи. Логичный вывод: ошибка при создании заказа.

Теперь уже зная, что мне необходимо я полез в php-код. Некоторое время я провел исследуя Joomla. В результате удалось сделать несколько заключений. Во-первых, этот движок построен по принципам MVC (что в целом ожидаемо). Во-вторых, в нем есть понятия модулей и компонент (разницу между ними я не очень уловил). В-третьих, папки modules и components есть в корне и в папке administrator. Я предположил, что таким образом происходит разделение на фронт- и бэк-энд (скорее всего так оно и есть, но гарантировать не берусь). Но, при более детальном рассмотрении выяснилась одна довольно занятная вещь. В папке components, размещенной в корне у компонент отсутствуют папки с моделями. Как выяснилось модели, размещенные в папке administrator, являются общими.

Далее я занялся изучением модели компоненты com_virtuemart. В папке с моделями я быстро нашел интересующий меня файл orders.php. Файл, правда, оказался довольно немаленьким, но через некоторое время мне удалось найти там метод _createOrder. В нем инициализировался и заполнялся некоторый объект $_orderData, который в итоге вставлялся в таблицу с помощью какой-то ORM-обертки для работы с базой данных. Стало ясно, что объект $_orderData нас как раз и интересует. Я поискал, где в нем присваивается значение полю order_currency. Нашел я следующий код:


$_orderData->order_currency = $this->getVendorCurrencyId($_orderData->virtuemart_vendor_id);



К счастью для меня, именование методов и полей здесь хорошее, потому сразу стало понятно, что здесь происходит. Посмотрев еще немного на структуру таблицы joomla_virtuemart_vendors (хранящей данные о продавцах), я окончательно укрепился в своей догадке. У каждого продавца есть валюта, в которой он принимает платежи. Собственно именно эта валюта заносится в поле order_currency, в приведенном выше коде. Валюта единственного продавца в этом магазине была гривна, что и привело к такой странной ошибке. Судя по всему, этот код был исходном файле компоненты Virtuemart, и его решили оставить, поскольку не понимали, что он делает. В итоге, я переписал это так:

$_orderData->order_currency = $_prices['currency'];



Валюта заказа стала нормальной. Правда, только для новосозданных заказов, поскольку для старых неправильные данные уже хранились в базе, о чем я конечно же, предупредил своего приятеля. Вот собственно и все.

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

Комментарии

Для того, чтоб оставлять комментарии или зарегистрируйтесь.