Не секрет, что разработанный в 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  первыми нашими шагами будут:

  1. Подключение требуемых плагинов для расширение класса

стандартное расположение нового класса (по документации) в каталоге Joomla4 (корневая папка сайта) -  /libraries/joomla/factory.php

но в зависимости от хостинга это может и другой путь - /libraries/vendor/joomla/factory.php

----------------------------------------------------------------------------------------------------------------------------------

используем обязательное подключение для сторонних плагинов, используемых в Joomla4,  через запись в файле php  -  use Joomla\...;

/*пояснение от автора ->в Hikashop Joomla4+ class HikaStringHelper extends Joomla\String\StringHelper*/

use Joomla\CMS\Plugin\CMSPlugin 
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use 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шт.) 280,00 руб 54 шт. на складе

много

Мешок Практика для пылесоса Bosch GAS-50 (1шт.) 350,00 руб 16 шт. на складе

много

Мешок Практика для пылесоса Makita 440 (1шт.) 350,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() может содержать несколько аргументов.

Так в рассматриваемых плагинах используются следующие записи:

JRequest::getCmd('minicart_task')
(int)JRequest::getVar('minicart_ajax', 0);
JRequest::getVar('quantity',array(),'POST', 'array');
JRequest::setVar('quantity', $update_qty);
и др.

Вероятно наиболее подходящая запись для замены в Joomla 4:

$option = JFactory::getApplication()->input->post->get('options');
$minicart_task = hikaInput::get()->getCmd('minicart_task');
hikaInput::get()->set('ctrl', $view);
$classGroup = hikashop_get('controller.'.$taskGroup);
hikaInput::get()->set('view', $classGroup->getName() );
$classGroup->execute( hikaInput::get()->getCmd('task','listing'));
$classGroup->redirect();
 
например,
меняем $controller->execute(JRequest::getVar('task', null, 'default', 'cmd'));
на 
use Joomla\CMS\Factory;
use Joomla\CMS\MVC\Controller\BaseController;
$controller = BaseController::getInstance('Easyupdate');
$controller->execute(Factory::getApplication()->input->get('task', 'display'));
$controller->redirect();
 
 получить в запросе значения переменных :
$input->$method->get($var, $default, $filter);
$input->post->get($var, $default, $filter);
 
Для получения любой переменной (скажем, name) из метода post используйте приведенную ниже строку кода
JFactory::getApplication()->input->post->get('name');
JFactory::getApplication()->input-> post-> getArray(array())
или с помощью метода get
$jinput = JFactory::getApplication()->input;
$name = $jinput->get('name');
если вы хотите получить массив данных, скажем, из формы с несколькими полями , вы можете использовать:
$data = $jinput->post->getArray(array());

 Ниже приведен характерный пример применения фильтра ARRAY в классе JRequest.

  1. $data =JRequest::getVar('jform', array(), 'post', 'array');

 Ранее в состав класса JRequest входили следующие служебные методы, допускающие фильтрацию данных: getlnt(), getUInt (),getFloat (),getBool(), getWord(), getCmd() и getString().

 Класс JInput считается относительно новым, поскольку он был внедрен в версии 11.1 платформы Joomla, заменив собой класс JRequest. В этом классе имеется метод get (), используемый таким же образом, как и метод JRequest: : getVar (). В качестве третьего аргумента этого метода указывается тип фильтра. Ниже приведены три равнозначных примера применения фильтра CMD, название которого выделено полужирным.

  1. $х = JRequest::getVar('option','post', 'default', 'cmd');
  2. $x = JRequest:: getCmd ('option', 'default');
  3. $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:

Устаревший кодГде используется, назначение операцииНовый код
(int)JRequest::getVar('minicart_ajax', 0);  Sj Ajax Minicart Pro , получить значение 'minicart_ajax' и проверить включение ajax для модуля Sj Minicart Pro for Hikashop

(int)JFactory:: getApplication()->input->get('minicart_ajax', 0);

JRequest::getCmd('minicart_task')  Sj Ajax Minicart Pro

JFactory:: getApplication()->input->get('minicart_task', $default ('update', 'refresh', 'delete', 'invalid task'));

или

hikaInput::get()->getCmd('minicart_task');

JRequest::setVar('quantity', $update_qty); 'по умолчанию' hikaInput::get()->set('quantity', $update_qty);
JRequest::getInt('minicart_modid')   JFactory:: getApplication()->input->getInt('minicart_modid')
 замена jQuery 1.8  обеспечить совместимость  на jQuery 3.6
     
     

 

К сожалению, при использовании в модуле НОВОГО КОДА сам модуль  может не найти установленные значения переменных - и ему надо помочь, создав дополнительно значения по умолчанию.

Например,  используя строчку кода 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) . Разбираюсь...