Среда, 23 марта 2022 17:08

Joomla 4: классы JText и Text. Из неопубликованного

Оцените материал
(5 голосов)

Попытаюсь рассказать здесь о некоей коллизии, с которой столкнулся, переписывая старый свой модуль Joomla 3 под Joomla 4.

Материал, хочу надеяться, будет интересен профессиональным разработчикам расширений Joomla, несмотря на то обстоятельство, что автор данного текста таковым не является, давно отойдя не только от программирования под Joomla, но и вообще от кодинга на PHP. Но остались старые какие-то проекты, к которым изредка возвращаюсь, больше из ностальгических воспоминаний: что-то уже подзабыл, признаться, многое стало казаться скучным. И в этой связи хочу выразить искреннюю признательность Toivo Talikka, Global Moderator-у форума Joomla.org, чей неподдельный интерес и живое участие в обсуждении и тестировании проблемы сделали возможным написание этой статьи, вскрыв ряд недокументированных особенностей архитектуры четвертой ветки Joomla.

 

Первоначальный вариант статьи был опубликован на Хабре. В данный момент вы читаете вторую редакцию материала, исправленную и дополненную. Но суть осталась неизменной: автора по-прежнему удивляет несметное количество разбитных "жумла-программистов", никогда в своей работе не опускавшихся ниже уровня абстракций панели управления Joomla или консоли отладчика браузера. Читая joomlaforum.ru - только и делаешь, что диву даешься отдельным репликам "веб-разработчиков"... по этой ли причине, или же в силу причины иной, но и документация Joomla 4 оставляет пока что, на мой взгляд, желать много лучшего. Вполне возможно, что разработчики CMS-фреймворка попросту не видят в доках особой необходимости: зачем тратить время, коль скоро абсолютному большинству "программистов Joomla" это нафиг не нужно. Увы, подобный подход ощутимо вредит имиджу продукта в глазах бизнеса, принося свои плоды: несомненное дружелюбие очень и очень неплохой CMS сыграло, как и следовало ожидать, злую шутку.

 

К материалу
К материалу "Joomla 4: классы JText и Text. Из неопубликованного". Рисунок Петра Изосимова.

 

Сходу короткое лирическое отступление. Предпринята, как видите, попытка разбавить сухой технический материал рисунками замечательного петербургского художника Петра Изосимова, с которым автор немного знаком и чья изумительная всегда ирония вполне коррелирует в данном случае с вектором, скажем так, отношения автора к "наличию отсутствия" (в контексте ряда искомых кейсов только, разумеется) документации одного из самых популярных на сегодняшний день CMS-фреймворков. Хм, может статься, мы попросту не нашли; если так, буду благодарен за соответствующие ремарки в комментах. Но не думаю.

 

Описанный далее экзерсис основан, в частности, на анализе загрузочных файлов Joomla и вполне себе способен содержать gaps and inaccuracies, пробелы и неточности. И - тем не менее - я приступаю к рассказу: примеров и туториалов, доходчиво объясняющих простым смертным критичные подробности кодинга расширений долгожданной Joomla 4 на сегодняшний день в Сети немного, буквально считанные единицы. Уверен, пригодится и вообще в тему.

 

Dev banner 1

 

Итак. Дебажа модуль (это несложный виджет, представляющий собой удобный пользовательский интерфейс клиента ряда погодных API и сервисов определения геотаргетинга), отметил странный казус: в новой версии модуля я не мог так же запросто, как делал это ранее, использовать класс JText в хелпере модуля, объявляя, скажем, массив:

 

// Helper/FooHelper.php
namespace FooNamespace\Module\Foo\Site\Helper;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;

class FooHelper
{
    public static function getNames()
    {
            $main = array(
                JText::_('STRING_ONE'),
                JText::_('STRING_TWO')
                );
                return $main;
        }
}

 

А вот в HTML - мог. Например, так:

 

// tmpl/default.php

foreach (array_combine($names, $source) as $names => $source):
    $html .= '<tr>';
        $html .= '<td>' . JText::_($names) . '</td>';
        $html .= '<td>' . $source . '</td>';
    $html .= '</tr>';
    $i++;
endforeach;

 

Не отвлекаясь в тот момент на увлекательные рассуждения о том, как именно в парадигме MVC будет более правильно, автор задался сугубо русским вопросом: а почему нельзя-то, что мешает? - вот раньше было можно а щас нет, как так? - бага?? ниче, ща мы набьем мике баки... и ринулся с этим разбираться.

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

 

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

 

Идем дальше. Итак, попытка использовать JText в хелпере успехом не увенчалась, снова ждал афронт:

 

Class 'FooNamespace\Module\Foo\Site\Helper\JText' not found

 

К материалу
К материалу "Joomla 4: классы JText и Text. Из неопубликованного". Рисунок Петра Изосимова.

 

Как вариант, в хелпере можно было попробовать использовать класс Text вместо JText, и это вполне работает, см. в качесте аргумента сказанному libraries/src/helper/ContentHelper.php.

Но почему же так странно, почему в хелпере модуля возможен, по-видимому, только Text, а для шаблона модуля сгодится и JText?

Как это? Возможно, отработало наследование шаблоном модуля? - вряд ли, правила импорта построены так, что включенные файлы не наследуют импорт файла родительского (Importing rules are per file basis, meaning included files will NOT inherit the parent file's importing rules, Using namespaces: Aliasing/Importing). Попробуем для начала предположить, что объяснение заключено в

 

require ModuleHelper::getLayoutPath('mod_foo', $params->get('layout', 'default'));

 

, именно эту строчку содержит foo.php, точка входа модуля. Операторы require и include, в отличие от use, позволяют включенному файлу наследовать область видимости, вот оно в чем дело, да?.

 

К материалу
К материалу "Joomla 4: классы JText и Text. Из неопубликованного". Рисунок Петра Изосимова.

 

На самом деле нет, все гораздо проще.

Вспомним, как именно PHP обрабатывает пространства имен: каждый класс здесь находится в своем неймспейсе, поэтому, строго говоря, не существует никакого JText, а есть только \JText (FQN, fully qualified name). Обращение к FQN происходит еще на этапе парсинга файла (существует исключение для функций и констант, но к нашему кейсу это не имеет отношения), и если пространство имен в начале файла указано, то JText считается расположенным в нем, в противном же случае подразумевается глобальное пространство имен \. Поэтому внутри пространства имен или используем \JText, или же стандартно указываем на него в начале файла:

 

use \JText;

 

Вероятнее всего, в причинах нашей проблемы Joomla вообще ни при чем, поскольку не в состоянии повлиять на парсинг файла интерпретатором PHP.

К слову, для новых проектов - вместо \JText, который родом еще с Joomla 1.5, оптимально сразу использовать \Joomla\CMS\Language\Text, он доступен начиная с Joomla 3.8. Заметим, последовательность загрузки в libraries/classmap.php содержит сопоставление JText, обеспечивая совместимость с новым классом Text, предназначенным, очень вероятно, в Прекрасной Джумла Будущего полностью заменить JText:

 

JLoader::registerAlias('JText', '\\Joomla\\CMS\\Language\\Text', '5.0');

 

Данное сопоставление концептуально связывает JText с файлом libraries/src/Language/Text.php, который начинается со следующего объявления пространства имен, общего для файлов в папке libraries/src/Language:

 

namespace Joomla\CMS\Language;

 

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

Последнее изменениеСуббота, 26 марта 2022 01:13

Оставить комментарий

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

В блоге

Poker onRails

All sorts of things

Комментарии в блоге

Заказать сайт

Веб-разработка. Заказать сайт

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