Не секрет, что разработанный в 2014 году SmartAddons.com модуль Sj Minicart Pro for Hikashop под Joomla 2.5+ не работает без другого плагина - Sj Ajax Minicart Pro (прослушивателя событий - отработка нажатий на определенные кнопки модуля). Если в CMS Joomla 3+ установить модуль ещё возможно и он будет относительно "хорошо" работать (класс plgSystemPlg_Sj_Hk_Ajax_MiniCart_Pro определяется, а модуль появляется в нужном месте, одновременно работают некоторые кнопки модуля) , то в Joomla 4+ вы столкнетесь с проблемой неработоспособности (невидимости) модуля Sj Minicart Pro for Hikashop ("Плагин Sj Ajax Minicart Pro не установлен. Установите сначала его"), а всё из-за неопределенного самой Joomla4 класса плагина Sj Ajax Minicart Pro в самом модуле. Как это исправить?
Разберемся, почему это происходит (проблема относится ко всем ранее разработанным плагинам и модулям, требующим обеспечить режим совместимости с Joomla 4+ ). Дополнительно приведем примеры для замены устаревшего кода с классом JRequest::getVar('option').
Необходимо отметить, что код разработчиков SMARTADDONS, используемых в модуле Sj Minicart Pro for Hikashop от 2014 года и плагине Sj Ajax Minicart Pro-2014, далек от совершества и запутан до невозможности (сплошь и рядом используются похожие переменные типа $cart и $_cart, которые то создаются, то обнуляются), он даже не тянет на средние стандарты PHP, причем отличается и от стандарта HIKASHOP , поэтому производить замену кода затруднительно (в файлах helper модуля продублированы функции компонента Hikashop образца 2014 года). При этом модуль создает в корне каталога Joomla свои папки, что ни есть "good". Даже на официальном сайте smartaddons.com эти модули работают не правильно - "зависают" при обновлении корзины и удалении товаров. Сам модуль MINICART показывает лишь товары в корзине (без стоимости доставки и пр.) - это лишь усеченная версия стандартного модуля HIKASHOPMODULECART компонента Hikashop, поэтому использовать его или нет у себя на сайте, решаете только Вы.
Используя плагин-прослушиватель событий Sj Ajax Minicart Pro , разработчики SMARTADDONS на тот момент пошли по своему пути, создали для модуля Joomla свой "прослушиватель" событий [в Joomla его нет априори], но, по-моему мнению, зашли в тупик - создали только "костыль" для давно устаревшей версии Hikashop v2 (ранее в v2 использовалась запись нахождения значения id продукта: $product->cart_hikashop_product_id - и давно устаревшая), тогда как в самом компоненте Hikashop уже все предусмотретрено - там есть скрипт hikashop.js , позволяющий справиться с любой задачей по использованию сторонних модулей как по технологии ajax, так и простой перезагрузкой страницы для обновления параметров.
То есть, при модернизации модуля под Joomla 4 можно использовать только сам модуль Sj Minicart Pro for Hikashop без плагина Sj Ajax Minicart Pro.
Необходимо отметить, что
Главная и основная причина не работоспособности связки модуля и плагина в том, что в модуле Sj Ajax Minicart Pro, состоящем из нескольких файлов php, используется расширение для устаревшего и удаленного из Joomla4 класса JPlugin и JRequest - поэтому не работает предусмотренный ajax , а сам модуль не видит класс системного плагина Sj Ajax Minicart Pro и выдает сообщение об ошибке "WARNING_NOT_INSTALL_PLUGIN" ( перевод ru-RU: "Не установлен плагин Sj Ajax Minicart Pro. Установите сначала его") + идет использование устаревших системных функций Joomla3.
класс JRequest - фильтрация данных $_GET и $_POST
Для анализа обратимся к старому коду php. Для разработчика-новичка PHP важно понимать, что устарело и что надо поменять, т.е. обратиться к документации Joomla4.
После изучения справочных материалов по Joomla4 первыми нашими шагами будут:
- Подключение требуемых плагинов для расширение класса
стандартное расположение нового класса (по документации) в каталоге Joomla4 (корневая папка сайта) - /libraries/joomla/factory.php
но в зависимости от хостинга это может и другой путь - /libraries/vendor/joomla/factory.php
----------------------------------------------------------------------------------------------------------------------------------
используем обязательное подключение для сторонних плагинов, используемых в Joomla4, через запись в файле php - use Joomla\...;
/*пояснение от автора ->в Hikashop Joomla4+ class HikaStringHelper extends Joomla\String\StringHelper*/
---------------------------------------------------------------------------------------------------------------------------------
class hikaParameter extends JRegistry
class hikaLanguage extends JLanguage
class hikaInput ( for Joomla J30 ) - [по умолчанию $ref = null] return $ref = & JFactory::getApplication()->input
class hikaInput ( for Joomla J40 ) - [используются переменные $ret и $ref = null] где переменная $ret = call_user_func_array (array($ref, 'getVar'), func_get_args() ); а переменная $ref = new hikaInput();
* - call_user_func_array — вызывает пользовательскую функцию с массивом параметров
* - func_get_args — возвращает массив, содержащий аргументы функции
----------------------------------------------------------------------------------------------------------------------------------
заменим основной класс JPlugin (Joomla3) -> класс удален из Joomla4 --- на новое обозначение - CMSPlugin (Joomla4)
**- class PlgSystemSjAjaxMinicartPro extends CMSPlugin
-------------------------------------------------------------------------------------------------------------------------------------
Приемы нахождения переданных серверу значений переменной с помощью записи с использованием методов get, post, server, cookie, request:
$ = hikaInput::&get()->_get('task',' ') => $=hikaInput::get()->getCmd('task',' ')
Что ищет данный метод? Все "просто" - форма документа для общения пользователя с сервером <form> при передаче данных формы с использованием метода GET или POST предусматривает поле <input name ="task" > с определенным значением ,
поэтому в браузерной строке возникает код "&task=updatecart", вот это значение task в массиве переданных данных и ищет метод hikaInput (извлекает и возвращает заданную отфильтрованную переменную. при этом фильтр cmd допускает только символы [A-Za-z0-9.-_]). Но чтобы понять это, для новичка-backup-разработчика PHP может уйти много времени (ведь как правило, мы просто копируем код и переносим на свой проект).
Вообще, в Hikashop и в Joomla переменная $task может принимать разнообразные значения:
/********************************** * task = printcart * task = show * task = updatecart * task = listing * task = showcart * task = download * task = wizard * task = blog * task = edit /***********************************/
Но главная переменная отвечающая за то, что мы увидим на экране в данный момент - это $view и $ctrl
/********************************** * view = product * view = cart * view = checkout * view = quantity
* view = ... /***********************************/
Как мы это увидим, с перезагрузкой страницы или без, зависит от другой переменной - $tmpl
Как правило, для отображения объекта в файле php используется только одна форма документа <form> с заданными значениями task, ctrl,view и с запрограммированным событием - onclick (обновить продукт, обновить корзину и т.п.). Поэтому модулю важно получать информацию о предыдущих событиях. Для этого в Hikashop используется класс HIKAINPUT с использованием встроенного в joomla класса JFACTORY (пришедшего на замену JRequest и полностью заменившего его в Joomla4)
hikaInput:: - class hikaInput
&get() - public static function;
_get($name) - public function;
Старая запись:
Новая запись:
Т.е. можно заменить
В HIKASHOP для получения установленных и используемых значений переменных в файлах модуля и плагина (из заполненных полей форм) возможно использование как класса JFACTORY , так и класса HIKAINPUT - находим через:
JFactory::getApplication()->input->get(' **** ', ' '); или hikaInput::get()->get(' **** ', ' ');
---------------------------------------------------------------------------------------------------------------------------------
В нашем случае, прямое нахождение по методу hikaInput в модуле MINICART HK PRO этих рассмотренных переменных будет давать NULL (т.е. $task =null ) или " ".
А вот метод JFactory после отправки <form> дает значение "listing"
РАБОТУ МОДУЛЯ МОЖНО ПОСМОТРЕТЬ
На данный момент модуль протестирован на Joomla 4.3.3 и Hikashop 4.7.5 и может иметь некоторые баги (в т.ч. самопроизвольное увеличение количества товаров в окошке выбора количества товара).Изображение | Товар | Цена | |
---|---|---|---|
Мешок Практика для пылесоса Bosch GAS-25 (1шт.) | -60%112,00 руб |
54 шт. на складе
![]() много |
|
Мешок Практика для пылесоса Bosch GAS-50 (1шт.) | -60%140,00 руб |
16 шт. на складе
![]() много |
|
Мешок Практика для пылесоса Makita 440 (1шт.) | -60%140,00 руб |
31 шт. на складе
![]() много |
Удаление используемого в Joomla3 (или адекватная замена) класса JString (abstract class JString extends StringHelper) (в модуле используется запись--> JString::parse_url($path) )
Замена на используемый в Joomla4 класс StringHelper не возможна ( abstract class StringHelper) (у него нет метода parse_url($path)) - (справочно: сам класс подключаем через запись use Joomla\String\StringHelper )
Поэтому для работоспособности модуля используем чистый php - parse_url($path)
Данные занесем в таблицу для дальнейшей замены в коде php:
Было (JOOMLA 3) | Надо (JOOMLA 4) |
---|---|
class PlgSystemSjAjaxMinicartPro extends JPlugin | class plgSystemHkAjaxMiniCartPro extends CMSPlugin |
defined('_JEXEC') or die;
if(!class_exists('plgSystemPlg_Sj_Hk_Ajax_MiniCart_Pro')){
echo '<p ><b>'.JText::_('WARNING_NOT_INSTALL_PLUGIN').'</b></p>';
return ;
}
|
defined('_JEXEC') or die;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Event\Event;
JPluginHelper::importPlugin('plg_system_hk_ajax_minicart_pro');
include_once JPATH_ROOT.'/plugins/system/plg_system_hk_ajax_minicart_pro/
plg_system_hk_ajax_minicart_pro.php';
if(!class_exists('plgSystemHkAjaxMiniCartPro')){
echo '<p ><b>'.JText::_('WARNING_NOT_INSTALL_PLUGIN').'</b></p>';
return ;
}
|
использование функции Jomla3 - function onAfterDispatch(){..*...} | в Joomla4 необходима замена функции function onAfterDispatch() - возможно на ........onAfterInitialise(){...***.....} |
При использовании в Joomla4 предупреждение от неработающего модуля Sj Minicart Pro for Hikashop (хотя плагин Sj Ajax Minicart Pro успешно установлен): "Плагин Sj Ajax Minicart Pro не установлен. Установите сначала его" |
При коррекции кода (см. выше) появление в браузере "работающего" модуля Sj Minicart Pro for Hikashop :
|
Ниже приведен модуль для Joomla3 и он не может работать "синхронно" с модулями HIKASHOPCARTMODULE компонента HIKASHOP (после обновления информации в модуле MINICART актуальная информация о товарах не отображается в модуле HIKASHOPCARTMODULE - даже после перезагрузки страницы), хотя обратная связь присутствует --> после коррекции информации о товарах в HIKASHOPCARTMODULE в модуле MINICART отображается аналогичная информация.
2. Замена в файле кода php класса JRequest на Input
например, для работоспособности плагина в Joomla 4+ надо поменять строчку кода JRequest::getVar(' значение ');
на JFactory::getApplication()->input->get ( 'значение' )
Это можно сделать и другим способом:
$input = \Joomla\CMS\Factory::getApplication()->input;
например, для замены записи $option = JRequest::getVar('option'); потребуется ввести две строчки кода $input = JFactory::getApplication()->input; $option = $input->get('option', '');
option = filter_input(INPUT_GET, 'option', FILTER_SANITIZE_STRING); //но это уже чистый php
В самом простом случае (используется один параметр - 'option') - на практике применение класса JRequest разнообразно и это использование методов getlnt(), getUInt (),getFloat (),getBool(), getWord(), getCmd() и getString() может содержать несколько аргументов.
Так в рассматриваемых плагинах используются следующие записи:
Вероятно наиболее подходящая запись для замены в Joomla 4:
$data = $jinput->post->getArray(array());
Ниже приведен характерный пример применения фильтра ARRAY в классе JRequest.
Ранее в состав класса JRequest входили следующие служебные методы, допускающие фильтрацию данных: getlnt(), getUInt (),getFloat (),getBool(), getWord(), getCmd() и getString().
Класс JInput считается относительно новым, поскольку он был внедрен в версии 11.1 платформы Joomla, заменив собой класс JRequest. В этом классе имеется метод get (), используемый таким же образом, как и метод JRequest: : getVar (). В качестве третьего аргумента этого метода указывается тип фильтра. Ниже приведены три равнозначных примера применения фильтра CMD, название которого выделено полужирным.
- $х = JRequest::getVar('option','post', 'default', 'cmd');
- $x = JRequest:: getCmd ('option', 'default');
- $x = JFactory:: getApplication()->input->get('option', 'default', 'and');
Углубимся в суть проблемы для понимания - разберем распространенный пример с 4-мя аргументами
$name = JRequest::getVar('fio', 'неизвестный пользователь', 'get', 'string');
где
'fio' - заданное значение поля в форме какого-нибудь модуля (конфигурации) и мы хотим получить значение Ф.И.О. человека из поля "fio" формы, в которую вводятся (set) или уже введены (get) какие-то значения и затем сохранить это значение в переменную $name
'неизвестный пользователь' - если человек, при заполнении формы не укажет свое имя, ему будет присвоено имя "неизвестный пользователь" или так называемое default - 'значение по умолчанию'
'get' - разработчики предпочитают явно указывать откуда они хотят получить переменную. Это слегка увеличивает безопасность компонента, а так же упрощает работу, например при использовании технологии AJAX. Теперь переменная явно будет браться из массива $_GET.В качестве атрибута можно использовать одно из следующих ключевых слов:
- GET
- POST
- FILES
- COOKIE
- ENV
- SERVER
- REQUEST
'string' - Четвертым параметром явно указываем тип переменной. В нашем случае это "string". Для удобства ранее использовались методы класса "JRequest" следующего типа:
- getInt
- getFloat
- getBool
- getWord
- getCmd - (Извлекает и возвращает заданную отфильтрованную переменную. Фильтр cmd допускает только символы) возвращает JRequest::getVar($name, $default, $hash, 'cmd');getCmd($name, $default= ", $hash= 'по умолчанию')
Имя параметра Значение по умолчанию Описание $name Имя переменной $name $default $default Значение по умолчанию, если переменная не существует $hash 'по умолчанию' $hash, из которого должен исходить var (POST, GET, FILES, COOKIE, METHOD) - getString
- get
Методы выполняют ту же самую роль что и "getVar", аргументы те же, за исключением того что нет маски ('неизвестный пользователь') и типа переменной (string''). Метод "get" использует два параметра - название переменной ('fio') и маска ('неизвестный пользователь') .
Пятым параметром мы можем наложить маску фильтрации. Фильтр устанавливает специальным числом - битом. Маски бывают 3 типов:
- 1 - JREQUEST_NOTRIM - если установлен, то пробелы по краям не обрежутся, по умолчанию пробелы отсекаются.
- 2 - JREQUEST_ALLOWRAW - если установлен, то будет отключена всякая фильтрация, при этом более высокие биты игнорируются.
- 4 - JREQUEST_ALLOWHTML - позволяет html-код. Но если установлен, то все равно будет включен фильтр безопасности по очистке html-кода.
не забывайте, что вы можете легко подделать любой заголовок с помощью cURL вот так
curl_setopt($ch,CURLOPT_HTTPHEADER,array("X-Requested-With : XMLHttpRequest"));
Попробуем всю полученную информацию свести в таблицу для дальнейшего изменения кода в нашем модуле Sj Minicart Pro for Hikashop и плагине Sj Ajax Minicart Pro:
К сожалению, при использовании в модуле НОВОГО КОДА сам модуль может не найти установленные значения переменных - и ему надо помочь, создав дополнительно значения по умолчанию.
Например, используя строчку кода PHP (при изменении данных о количестве товара в корзине )
$prefix = hikaInput::get()->get('id_prefix', 'hikashop_product_quantity_field');
мы заранее предугадываем, что значение переменной $ id_prefix не будет найдено сторонним модулем и поэтому используем значение по умолчанию 'hikashop_product_quantity_field' - в итоге после обработки кода получаем
$prefix = 'hikashop_product_quantity_field';
и модуль продолжает корректно работать даже при отсутствии данных
3. доработаем плагин: замена функции-прослушивателя событий - function onAfterDispatch()
не используем её вообще !!!
4. доработаем файлы модуля: заменим код default.php - default_js.php - default_list.php
Для корректнной работы модуля по технологии ajax необходимо добавить некоторые элементы HTML и JS.
Заменим идущий изначально метод замены классов в модуле на использование onclick и onchange в используемых кнопках и ссылках. Например:
<!-- PROCEED TO CHECKOUT BUTTON -->
<a class="<?php echo $css_button . ' ' . $css_button_checkout; ?>" href="/<?php echo $url_checkout; ?>" onclick="if(this.disable) return false; this.disable = true;"> <span><?php echo JText::_('PROCEED_TO_CHECKOUT');?></span> </a>
Использование аттрибута href перезагружает страницу сайта - правильное использование onclick позволяет использовать технологию ajax (изменение без перезагрузки страницы сайта).
Необходимо отметить, что внутри модуля - в default_list.php - можно и надо создать тег <form nane="hikashop_cart_form"> с аттрибутами <input>, взятыми из новейшей версии стандартного файла front/view/cart/tmpl/showcart.php - это позволит без напряга синхронизировать работу всех модулей Hikashop.
5. доработаем файлы модуля для использования с PHP8 и PHP8.1 и Joomla4.2+
Переход к версиям PHP8 предполагает использование более"строгих" правил . Работоспособность модуля зависит от пробелов, запятых и прочей ерунды, мелких ошибок - что для PHP7 было нормой.
Так, например, при использовании PHP8 в строке при копировании была допущена вроде простая орфографическая ошибка use Joomla\_CMS\Factory; --> появился лишний пробел --> и сайт сразу упал с ошибкой 500, чего не было на PHP7.
Вообще, адаптация модуля MINICARTPRO, в т.ч. и самого плагина оплаты через сбербанк EXAMPLE для работы с PHP8 идет пока со скрипом, например, на хостинге не обновляется DOMPDF до версии 2.0.0
Пока пыхтю, не понимаю некоторые моменты, получаю самообразование .....
Как я неоднократно упоминал, все мои статьи - это шпаргалки для меня. Поэтому продолжаю излагать свои мысли на "бумаге". Собираю информацию от разработчиков, адаптирую под себя.
Пока на разных платформах PHP модуль ведет себя по-разному. На сайте техноклимат21.рф одно (Joomla 4.2.2 + Hikashop 4.6.1 + PHP 8.0.15) , на тестовом сайте другое(Joomla 4.2.2 + Hikashop 4.6.1 + PHP 8.0.15), здесь третье (Joomla 3.10.11 + Hikashop 4.6.1 + PHP 7.4) . Разбираюсь...