Блог Веб-разработчика.

Если перед вами стоит задача разработать плагин, реализующий необходимый вам функционал для автоматизированной модификации цен на товары в магазине virtuemart 2 - скорее всего вы уже столкнулись с трудностями информационного характера. Никто не знает как его делать. Кроме самих разработчиков virtuemart, естественно. Если у вас есть друзья среди них  - то вам повезло, а если нет... То далеко не всем удается справиться с задачей разработки подобного расширения. Потому что даже в официальной документации по virtuemart 2, в части посвященной группе плагинов “vmcalculation” - никакой информации нет,  страница пустая на момент подготовки материала (http://dev.virtuemart.net/projects/virtuemart/wiki/Calculation_Plugins). В этой статье я постараюсь в общем описать все доступные методы функционального класса, которые мне удалось обнаружить в коде магазина и задействовать в работе плагина.

Описание использования плагина

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

Плагин относящийся к группе “vmcalculation” выносит свои управляющие элементы и работает с данными сохраненными через интерфейс раздела “товары” => “налоги и правила расчета”.

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

Базовый интерфейс позволяет определить для текущего правила: вид расчета (например, “цена перед уплатой налогов”, “цена после уплаты налогов”, “наценка” и др...), тип операции (сложение или вычитание абсолютных величин или относительных), само значение пересчета (в зависимости от выбранной операции либо значение в валюте магазина, либо процентная ставка) и валюту (из списка тех, что определены в системе магазина). Выполнение правил пересчета стоимости можно таргетировать по категориям товаров, по группам пользователей, по странам и регионам (если таковые настроены) и по производителям товаров в магазине. Можно также определить срок действия данного правила модификации стоимости.

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

Установленный и включенный плагин, относящийся к группе “vmcalculation”, может добавить новый вид операции пересчета и чуть ниже базовой формы - свои собственные поля настроек, которые можно очень гибко оформить. Например, в моем случае это выглядело примерно так:

В моем случае предполагалось, что можно создать неограниченное количество “уровней” скидки в зависимости от общей суммы заказа.

Еще раз отмечу, что в данной статье, мы не будем касаться конкретных реализаций, а лишь рассмотрим все доступные методы плагинов “vmcalculation”, которые вызываются из различных частей магазина. Для условного обозначения, назовем гипотетический плагин “MyPlugin”, тогда согласно правилу наименований в системе магазина, функциональный класс расширения будет иметь название “plgVmCalculationMyPlugin” (регистр не имеет значения).

Класс plgVmCalculationMyPlugin

Является расширением (подклассом) класса vmCalculationPlugin.

class plgVmCalculationMyPlugin extends vmCalculationPlugin {
 
}

Ниже буду использовать обозначение “название_класса::название_метода (параметры)”, который будет обозначать лишь принадлежность метода к классу, а не вызов статического метода.

plgVmCalculationMyPlugin::__construct ($subject, $config)

Инициализирует встроенные свойства класса. На практике, для корректной работы плагина, вполне достаточно указать имена полей настроек в админке, их начальные значения и типы данных.

    public function __construct ($subject, $config) {
        parent::__construct($subject, $config);
        $varsToPush = array(
            "discount_activate" => array(0,"int"),
            "discount_start_price" => array(0,"int")
        );
        $this->setConfigParameterable("calc_params",$varsToPush);
    }

$subject - содержит ссылку на экзепляр объекта JDispatcher. Если посмотреть справку виртумарта по другим плагинам, то там часто можно видеть, что параметр $subject передается в конструктор по ссылке “&”. Вероятнее всего это связано с тем что документация писалась в те времена, когда объекты при передаче в метод - копировались, и чтобы этого не происходило, необходимо было указывать “&” чтобы содержимое переменной передавалось по ссылке, а не по значению. Сейчас в этом нет необходимости, начиная с php 5, все экземпляры объектов по-умолчанию передаются в метод по ссылке, поэтому указывать знак амперсанда - не обязательно.

$config - содержит массив с данными по текущему плагину. Для vmcalculation это скорее всего не представляет никакого интереса, так как кроме типа плагина и его названия - там больше ничего нет.

Обратите внимание, что обязательно необходимо выполнить вызов родительского конструктора, иначе инициализация нового объекта пройдет некорректно.

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

plgVmCalculationMyPlugin::plgVmAddMathOp (&$entryPoints)

Позволяет добавить название новой вычислительной операции в выпадающий список “операция” в панели редактирования правил расчета.

    public function plgVmAddMathOp(&$entryPoints){
     $entryPoints[] = array("calc_value_mathop" => "progress", "calc_value_mathop_name" => "Progressive Discount");
    }

$entryPoints - содержит в себе массив уже имеющихся на данный момент в системе типов “математических” операций, которые могут быть использованы при пересчете. Обратите внимание, что значение переменной передается по ссылке. Это означает что она модифицируется и за пределами области видимости метода, и возвращать какое-либо значение - не обязательно. Индекс ‘calc_value_mathop’ - это что-то вроде ключа операции, системного названия; ‘calc_value_mathop_name’ - название операции, которое будет видно в админке пользователю.

plgVmCalculationMyPlugin::plgVmInGatherEffectRulesBill ($calculationHelper, &$testedRules)

Какую изначальную идею разработчики хотели вложить в этот метод, мне сказать трудно. Судя по названию метод должен собирать правила пересчета, наверное... Но лично я использовал метод для того, чтобы передать в корзину дополнительную информацию для отображения (цена без скидки, сумма скидки, сообщение о текущем уровне скидки и т.д...). Эти данные потом отлавливаются через ajax, и их можно вставить в модуль корзины virtuemart.

    public function plgVmInGatherEffectRulesBill($calculationHelper, &$testedRules) {
        // $calculationHelper->_cart->products - содержит массив с данными 
        // по всем товарм добавленным в корзину. Эти данные можно использовать 
        // чтобы уже здесь выполнить все подсчеты.
 
        // Раскомментируйте, чтобы посмотреть содержимое.
        // echo "<pre>";
        // var_dump($calculationHelper->_cart->products);
        // echo "</pre>";
 
        // А можно этот метод использовать только для передачи дополнительных 
        // сообщений в модуль корзины.
 
        // Для этого используйте $calculationHelper->_cart->data - данный объект
        // содержит все информацию по корзине. В нем можно изменить значения уже имеющихся 
        // данных и можно добавить новые.
        // Например, конструкция
        // $calculationHelper->_cart->data->discountMessage = "Ваша скидка...";
        // добавляет новое свойство "discountMessage".
 
        // Раскомментируйте, чтобы посмотреть содержимое.
        // echo "<pre>";
        // var_dump($calculationHelper->_cart->products);
        // echo "</pre>";
    }

$calculationHelper - содержит ссылку на объект CalculationHelper, содержит довольно много информации, на мой взгляд наиболее ценной является та, что указал в блоке кода.

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

plgVmCalculationMyPlugin::plgVmInGatherEffectRulesProduct ($calculationHelper, &$testedRules)

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

plgVmCalculationMyPlugin::plgVmInterpreteMathOp ($calculationHelper, $rule, $price, $revert)

В файле “administrator/components/com_virtuemart/helpers/calculationh.php” в строке 1479 формируется событие, вызывающее метод с именем “plgVmInterpreteMathOp”, при этом ожидается возврат пересчитанной стоимости. Таким образом этот метод удобнее всего использовать для непосредственных вычислений и преобразования стоимости.

    public function plgVmInterpreteMathOp($calculationHelper, $rule, $price, $revert) {
        $rule = (object) $rule;
        $mathOp = $rule->calc_value_mathop;
        $calcValueMathOp = $rule->calc_kind;
        $calcParams = $this->explodeParams($rule->calc_params);
        $calcValue = $rule->calc_value;
    // цикл или блок проверки и пересчет....
    return $newPrice;
    }

В этом методе почти наверняка будет какой-то блок проверки или цикл с блоком проверки - все перечисленные выше в коде данные, в таком случае, пригодятся точно.

$calculationHelper - ссылка на объект CalculationHelper.

$rule - массив всех правил пересчета (всех, а не только текущего плагина), если конечно его содержимое не было изменено выше.

$price - стоимость, основанная на базовой цене товаров, число с плавающей точкой.

$revert - булево значение, по смыслу связано с преобразованием знака числа.

plgVmCalculationMyPlugin::plgVmOnDisplayEdit ($calc, &$html)

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

    public function plgVmOnDisplayEdit($calc, &$html) {
    // проверка существования файла шаблона
    // и инициализация переменных для вставки, если это необходимо
    ob_start();
        include $path;
        $html = ob_get_clean();
    }

$calc - содержит ссылку на объект TableCalcs, содержит всю информацию по настройкам текущего правила пересчета, в том числе данные по дополнительным полям. Значение ранее сохраненных настроек в дополнительных полях, хранится в свойствах, имена которых полностью повторяют имена дополнительных полей.

$html - содержит строку уже ранее сформированного участка html разметки (от другого плагина vmcalculation). Обратите внимание, что строка передается в метод по ссылке.

plgVmCalculationMyPlugin::plgVmStorePluginInternalDataCalc (&$data)

Метод сохраняет введенные в админке данные в базу данных.

    public function plgVmStorePluginInternalDataCalc(&$data){
            if (!class_exists ("TableCalcs")) {
                    require(JPATH_VM_ADMINISTRATOR . DS . "tables" . DS . "calcs.php");
            }
            $db = JFactory::getDBO ();
            $table = new TableCalcs($db);
            $table->setUniqueName("calc_name");
            $table->setObligatoryKeys("calc_kind");
            $table->setLoggable();
            $table->setParameterable ($this->_xParams, $this->_varsToPushParam);
            $table->bindChecknStore($data);
    }

Думаю, что этот метод вы сможете использовать без каких-либо изменений, он скорее всего для любого плагина “vmcalculation” подойдет, если конечно вы при этом не захотите выполнить какие-либо дополнительные действия (например, записи в логи или какие-то дополнительные проверки).

$data - содержит массив введенных данных. Передается по ссылке!

plgVmCalculationMyPlugin::plgVmGetPluginInternalDataCalc ($calcData)

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

    public function plgVmGetPluginInternalDataCalc($calcData){
 
            $calcData->setParameterable ($this->_xParams, $this->_varsToPushParam);
 
            if (!class_exists ("VmTable")) {
                    require(JPATH_VM_ADMINISTRATOR . DS . "helpers" . DS . "vmtable.php");
            }
            VmTable::bindParameterable ($calcData, $this->_xParams, $this->_varsToPushParam);
            return TRUE;
    }

Данный метод тоже, скорее всего, сможете использовать без изменений в определении.

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

Прочие методы

Все перечисленные выше методы непосредственно понадобились для реализации плагина накопительной скидки. Далее идет перечисление методов, которые тоже будут вызваны из плагина типа “vmcalculation”, если они будут в нем определены. Детали использования этих методов изучать не стал, пока в этом потребности нет, а если кому нужно - без труда изучит сам.

Названия некоторых методов явно указывают на то, что они должны относиться к плагинам другого типа (например, “vmpayment”). Это действительно так, однако код в магазине virtuemart устроен так, что иногда в одном блоке кода одновременно импортируются плагины различных типов, а уже затем через JDispatcher::trigger вызываются их методы. JDispatcher::trigger при этом проходит по всем доступным плагинам. Поэтому, фактически, при одновременном импортировании происходит “перемешивание” плагинов, из-за этого и получается что из плагина типа “vmcalculation” можно вызвать метод формально относящийся к плагину типа “vmpayment”. Этим можно воспользоваться.

  • plgVmCalculationMyPlugin::plgVmConfirmedOrder ($this, $orderDetails) - метод вызывается при нажатии на кнопку “отправить заказ” пользователем, после того как он полностью оформил заказ на лицевой панели сайта.
  • plgVmCalculationMyPlugin::plgVmOnDisplayProductVariantFE ($productCustom, &$row, &$group) - метод вызывается при отображении в карточке товара и в категории товара, товаров с дочерними товарами.
  • plgVmCalculationMyPlugin::plgVmOnUpdateOrderShipment (&$data,$old_order_status) - метод вызывается при изменении статуса заказа (в админке).
  • plgVmCalculationMyPlugin::plgVmOnUpdateOrderPayment (&$data,$old_order_status) - метод вызывается при изменении статуса заказа (в админке).
  • plgVmCalculationMyPlugin::plgVmOnCancelPayment (&$data,$old_order_status) - метод вызывается при отмене оформленного заказа (из админки).
  • plgVmCalculationMyPlugin::plgVmOnSelfCallBE ($type, $name, &$render) - скорее всего, метод вызывается при использовании ajax в админке (не уверен).
  • plgVmCalculationMyPlugin::plgVmOnSelfCallFE ($type, $name, &$render) - скорее всего, метод вызывается при использовании ajax на лицевой панели сайта (тоже не уверен)
  • plgVmCalculationMyPlugin::plgVmDeleteCalculationRow ($id) - метод вызывается при удалении ранее созданного правила расчета в админке (в панели “налоги и правила расчета”). Данный метод напрямую относится к плагинам типа “vmcalculation”.
  • plgVmCalculationMyPlugin::getVmPluginCreateTableSQL() - метод вызывается при установке плагина, должен вернуть готовую строку sql-запроса на созадние новой таблицы в базе данных.

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

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

Комментарии к статье:


Всеволод Чупрыгин © webengineer.pro 2014. Все права защищены.
Копирование материалов сайта разрешено только с указанием имени автора (Всеволод Чупрыгин) и прямой индексируемой ссылки на источник на сайте www.WebEngineer.pro.
ИП Чупрыгин Всеволод Андреевич, ИНН: 333410747832, ОГРН: 311333426300044
http://vkontakte.ru/chuprygin_va, Google +

.
Проверить аттестат
Мы принимаем Webmoney Мы принимаем практически все платежи через Robokassa Мы принимаем Яндекс.Деньги Мы принимаем платежи через QIWI. Мы принимаем платежи через привязанные к QIWI карты VISA/Mastercard.