Куда идем?

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

Несмотря на все недостатки, Virtuemart обладает одним важным достоинством – для него существует огромное количество готовых расширений и хаков, позволяющих добавить магазину практически любой функционал. Но здесь есть одна проблема. Использование хаков приводит к тому, что обновлять магазин становится крайне затруднительно, т.к. новые файлы заменяют старые, которые содержат хаки. В этой статье я расскажу про одну возможность Virtuemart, о которой крайне редко можно встретить упоминание в Рунете. Благодаря ей некоторые хаки можно использовать не беспокоясь о проблемах с обновлениями. Лучше даже сказать «легализовать», превратить в нормальный код.

Virtuemart user class

Начиная с версии 1.1.4., в Virtuemart встроена возможность расширения классов. Она основана, на особенности PHP, позволяющей переопределять и расширять классы. Что вообще такое «классы»?

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

В Virtuemart есть объект «Товар». Единица, которую мы продаем в магазине. Над товаром могут совершаться различные действия. Мы можем добавлять товар, редактировать, удалять, изменять параметры, характеристики, можем сортировать товары, добавлять дочерние и многое другое. За каждое такое действие отвечает определенная функция (это сказано достаточно условно, но так проще понять, о чем идет речь). Набор таких функций объединяют в класс, отвечающий за товар. Так вот, к чему я вообще всё это рассказываю? Предположим, что вам потребовалась функция, которой нет в Virtuemart по умолчанию, например, вы хотите, чтобы при достижении определенной суммы покупок покупатель автоматически переводился в другую группу покупателей(и получал скидку). Сейчас в Virtuemart это возможно делать только вручную. Что для этого нужно сделать? Реально – написать всего пару десятков строк кода. Например, при смене статуса заказа на «Оплачен» из базы запрашиваются все заказы данного пользователя, далее суммируются, и если сумма превышает определенную величину, группа покупателей для этого пользователя изменяется. Сделать это несложно. Даже если вы не знаете PHP на фрилансе найдется много желающих помочь вам за небольшую плату. Проблема в другом. Для того, чтобы сделать это, придется править классы VM(опять же, может это и необязательно в данном конкретном случае, но для нас сейчас показательно).

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

Для того, чтобы проблемы, описанной выше, не произошло, разработчики Virtuemart предусмотрели возможность создавать в используемом шаблоне Virtuemart пользовательские классы, которые расширяют или частично изменяют стандартные классы Virtuemart. Как это работает?

1) Прежде всего нужно понять какой, собственно, класс мы будем расширять или изменять. Все классы Virtuemart находятся в папке: administrator\components\com_virtuemart\classes

Обычно это все файлы имеют префикс ps_ .

2) После того, как требуемый класс определен, мы переходим в папку components\com_virtuemart\themes\default  и создаем в ней подпапку user_class.

3) В созданной папке components\com_virtuemart\themes\default\user_class  создаем файл с названием, аналогичным названию класса, который мы собираемся расширять или изменять. Например, ps_product_attribute.php.

4) В файле, созданном в п.3, добавляем новую функцию или изменяем существующую(скопировав ее из стандартного класса, и внося изменения).

Конструкция этого файла должна выглядеть следующим образом:

1
2
3
4
5
6
7
8
<?php if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );


      class
ps_product_attribute extends vm_ ps_product_attribute {

            function myfunc($myparam) {
                //Тело функции

            }

      }

 ?>

5) И самое главное. В Virtuemart вы должны включить «секретную опцию», разрешающую использование пользовательских классов. Почему «секретную»? Потому, что она появилась только в версии VM 1.1.4, как собственно и сама возможность пользовательских классов. Т.к. локализация VM была сделана раньше и особо не переделывалась, очень часто эта опция в русском языке никак не подписана.

Найти ее можно в настройках Virtuemart, вкладка «Безопасность». Что именно нужно включить, показано на рисунке ниже:

virtuemart user class

После этого заходите на сайт и тестируете. Возможны всего два варианта:

  • О чудо! Это работает!
  • Fatal Error: бла бла бла.

Если ваш вариант – второй. Внимательно смотрите что за ошибка появилась. Она ваша и никак иначе. Ищите.

От себя могу сказать, что user_class работает. Точно, на 100%. Проверенно лично и не раз :-).

Рабочий пример

Для большей наглядности приведу рабочий пример с одного из западных блогов.

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

1) Определяем какой класс будем расширять. Т.к. работает с товаром, то класс ps_product.

2) переходим в папку components\com_virtuemart\themes\default  и создаем в ней подпапку user_class.

3) В созданной папке components\com_virtuemart\themes\default\user_class создаем файл

ps_product.php

4) В созданном файле добавляем следующий код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );


    class ps_product extends vm_ps_product { //Указываем, какой класс расширяется
       function add( &$d ) { //добавляем функцию добавления товара
          $retval=vm_ps_product::add(&$d);  //вызываем эту функцию из стандартного класса. Это сделано, чтобы не вставлять ее в пользовательский класс полностью
          if ($d['product_id']) { //если товар был добавлен
              $message='A new product has been added to your shop: ID: '.$d['product_id'].' SKU: '.$d['product_sku'].' Name: '.$d['product_name']; //формируем сообщение
              vmMail( " Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript.", "ShopAdmin", " Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript.", "New Product", $message, false, true);  //отправляем сообщение
          }
      }
     }
 ?>


5) Активируем опцию в настройках Virtuemart.

На этом всё. Теперь после добавления нового товара на указанный в функции email будет отправляться письмо с указанным содержимым.

Несколько дополнительных мыслей о user_class

  1. Для тех, кто так и не понял смысла: user_class работает аналогично перенаправлениям в шаблонах Joomla(помните, когда мы создаем папку html и помещаем в нее макет, или модуль, который нужно исправить?)
  2. Убедитесь, что функции, которые вы добавляете в класс, надежны. За их безопасность отвечаете вы, а не разработчики Virtuemart.
  3. Файлы еще одной очень важной папки administrator\components\com_virtuemart\html не будут работать в user_class. Их можно редактировать только напрямую, создавая тем самым хаки. И хотя разработчики и утверждают, что файлы этой папки стабильны и с выпуском обновлений не будут подвергаться изменениям(а значит и не будут заменять текущие файлы с хаками), что-то я им не очень верю.
  4. Если вы рядовой пользователь Virtuemart и ничего не поняли из этой статьи – не огорчайтесь. Эта информация предназначена в первую очередь для программистов и разработчиков. Возможно, когда-то, когда вам понадобится дополнительная функция, вы займетесь ее поиском, найдете, вернетесь к этой статье, прочитаете её еще несколько раз и поймете, как внедрить функцию без хаков ядра Virtuemart.
Об авторе
Wedal
(Виталий). Веб-разработчик полного цикла (Full Stack). Создатель и автор сайта Wedal.ru.
Основной профиль – создание сайтов и расширений на CMS Joomla.

Похожие статьи

Добавить комментарий

Комментарии  
1
Несмотря на наличие этой возможности, затраты на внесение исправлений в существующий код гораздо меньше, чем переписывание функциональности через классы. А для контроля исходного кода обычно используются специальные программы. По моему опыту большинство исправлений в Virtuemart связано с изменением способов представления данных, а не функциональных возможностей.
0
kordima,

Цитата:

Несмотря на наличие этой возможности, затраты на внесение исправлений в существующий код гораздо меньше, чем переписывание функциональности через классы.

А кто говорит о переписывании? Вы просто копируете существующую функцию класса и исправляете ее под свои нужны.

Цитата:

А для контроля исходного кода обычно используются специальные программы.

Системы контроля версий? Но это совсем не наш случай. Данные системы могут использоваться разработчиками Virtuemart, но не его пользователями.

Цитата:

По моему опыту большинство исправлений в Virtuemart связано с изменением способов представления данных, а не функциональных возможностей.

. А вот разработчики на форуме говорят как раз наоборот: представление данных не меняется, меняются способы их обработки.
0
Реально споры бесполезны. Каждый выбирает свой способ доработки.

Я пытался донести что способ хака + инструмент контроля версий в случае Virtuemart иногда (почти всегда) эффективнее, чем копирование чужих ошибок, которые Вы получаете копируя чужой класс.

А по поводу форумов. Зайдите на JoomlaForum, посмотрите темы по Virtuemart. Не особо там про переопределение классов.

Тему закрыл.
0
kordima,
да нет, я не спорю с вами, только обсуждаю. Так и нам с вами и другим читателям будет проще понять эту тему.


Цитата:

Я пытался донести что способ хака + инструмент контроля версий в случае Virtuemart иногда (почти всегда) эффективнее, чем копирование чужих ошибок, которые Вы получаете копируя чужой класс.

Не пойму, почему чужой-то класс? Мы копируем родной класс Virtuemart, точнее некоторые из его функций, а далее дополняем их, либо добавляем свои. Речь-то идет не об отказе от хаков, а об их легализации, т.е. внесении их так, чтобы не затрагивать напрямую код ядра.


Цитата:

А по поводу форумов. Зайдите на JoomlaForum, посмотрите темы по Virtuemart. Не особо там про переопределение классов.

Я про это и говорю. В Рунете данная тема вообще малоизвестна. Это связано с тем, что многие веб-мастера далеки от php, а тем более от ООП. Я говорил про официальный форум разработчиков forum.virtuemart.net.
1
Вооооооо! Так вот с помощью чего можно переделать виртумарт из просто магазина в удобную систему бронирования )) Надо только найти способ календарь сюда прикрутить!
0
Моисей, так может не переделывать, а сразу взять систему бронирования?
http://extensions.joomla.org/extensions/vertical-markets/booking-a-reservations
0
Ну, тут есть сразу несколько бед, которые сводят на нет все плюсы. Во-первых, большинство из них заточены все-таки под бронирование номеров, то есть там обязательный параметр - дата въезда и дата выезда. То есть, нужно искать очень мощную систему с очень широким спектром настроек (а это наверняка коммерческая программа стоимостью не менее 10к рублей), либо лихо дорабатывать ее напильником.
Второе, абсолютное большинство таких компонентов тоже сделаны в виде простых пре-уведомлялок. Я несколько вариантов уже опробовал, лишь немногие могут дату "забить" сами и тем более сформировать счет к онлайн-оплате. Чаще всё, чего добился, - это сообщения на мэйл. То есть опять пошла ручная обработка, и нафига ж тогда, спрашивается, менять машу на дашу?
Ну и третье. У большинства таких программ очень скромные возможности по оплате. Грубо говоря, пай-палка и кредитки, вот и весь выбор. А тут человек хочет всего, подключиться куда-нибудь типа робокассы или спрей-пей. Опять возникает необходимость глубокого ковыряния. В то время как у Вирта настолько лихой спектр настроек и такая популярность, что готовые решения под него есть практически у каждой второй платежной системы.
Я, кстати, очень сильно удивлен, что на Вирте до сих пор нет собственного модуля под бронирование. Думаю, это не так сложно, а люди этого хочут-плачут. Я аж с 2008 года нашел такие запросы на биржах у фрилансеров. В большинстве своем - запросы брошенные, не исполненные.
0
День добрый.
Имеется товар, например, стул. В зависимости от выбора его характеристик (цвет обивки, цвет каркаса и т.п.) вид товара на картинке будет разный. Есть ли какая возможность, чтобы при оформлении заказа, на ряду с ценой и пр. характеристиками, отображалась еще и картинка выбранного товара?
0
Crusader, стандартными средствами - никак. С помощью хаков - можно, но всё зависит от того, насколько хорошо вы знаете PHP.
0
Не устаю говорить тебе СПАСИБО!
Статья полезная, особенно когда я только стал осваивать VM.
Польза очевидна, например все модули, к примеру mod_virtuemart_latestprod, используют картинки товара малого размера (для товара сохранять можно два изображения: маленькое и большое), точнее модуль использует встроенные классы ВМ (например $ps_product->show_snapshot), а те используют шаблоны темы, так вот тему можно переделать (тонее создать свою тему), а вот что бы внести возможность в шаблоне указать что хочу использовать большую картинку, пришлось изменить методы (получились хаки)
файла ps_product.php
$ps_product->show_snapshot
и
$ps_product->product_snapshot (добавил поле "product_full_image" в sql-запрос и переменную для шаблона common/productsnapshot.tpl.php)

Таких мелких хаков несколько и в разных фалайх.

Знал бы раньше то сделал бы их частью своей темы, ведь насколько я понял, не обязательно user_class ложить в дефолтную тему (components\com_virtuemart\themes\default\user_class), можно и в свою (components\com_virtuemart\themes\my-template\user_class) наверное, на следующем шаблоне для сайта + ВМ испробую.

Жаль нельзя что "цивилизовано" заменить в administrator\components\com_virtuemart\html, поскольку тут (без мата не обходится), а почему без мата, да потому что там все стиле прописаны прямо в шаблонах, например < td width="24%" align="right" valign="top" > , а что сказать про изображения к которым прописываются атрибуты размеров, этож никак не исправить с помощью css, ведь то что указано в хтмл вприоритете, да и вообще кто, будучи в адекватном состоянии будет все верстать таблицами?

Еще раз спасибо, и хорошо, что я узнал про эту возможность на этапе освоения, этот проект так доведу, а в следующих проектах хаки попробую сделать частью пользовательской темы.
0
Вспомнил, тут в комментариях к одной из статей кто-то спрашивал как увеличить число отображаемых комментариев к товары (не 5, а больше), я написал, что хак надо внести в файл ps_rewiews, кажется, а так можно вынести в пользовательсий класс, так что польза этой статьи очевидная.
0
Здравствуйте, лазаю по инету, пытаюсь найти решение своей проблемы, зашел к вам. Я сам лазаю по вашему сайту, модуль оплаты робокасса - шикарный.

Проблема такая: при изменении статуса товара на confermed, должно высылаться письмо, содержащее данные из некоторых полей бд (как их взять я знаю)
не знаю как и где заставить отправить пользователю

Нашел несколько файолов, вроде отвечающих за отправку сообщения

/components/com_virtuemart/themes/default/templates/order_emails/comfirmation_email.tpl
/components/com_virtuemart/themes/default/templates/order_emails/enquiry_email.tpl
1- /administrator/components/com_virtuemart/classes/ps_order.php
2- /administrator/components/com_virtuemart/classes/ps_order_change.php
3- /administrator/components/com_virtuemart/classes/ps_order_change_html.php
4- /administrator/components/com_virtuemart/classes/ps_order_status.php

Может поможете с ними разобраться, или указанным вами способом отсылать еще одно письмо

Пошарился по форумам, они там разбирают, как картинки менять. Из серьезного, только копипастят с других сайтов.

Обращаюсь к вам, вы мне помогли разобраться с модулем оплаты робокассы.

Заранее спасибо
С уважением
0
А как с этим VIrtuemart 2?
0
dmitry b, для Virtuemart 2 можно использовать способ, описанный в статье: http://wedal.ru/uroki-joomla/pereopredelenie-mvc-komponentov-joomla.html