Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Помощник модуля

Помощник (Helper) — класс, в который выносят получение данных: запрос к базе, обращение к внешнему сервису, расчёты. Диспетчер остаётся коротким: он только просит данные у помощника и передаёт их макету. Научим модуль mod_hello показывать последние статьи сайта.

Где лежит

Создайте вручную папку src/Helper и файл в ней:

modules/mod_hello/
├── mod_hello.xml
├── services/provider.php
├── src/
│   ├── Dispatcher/Dispatcher.php
│   └── Helper/
│       └── HelloHelper.php          новый файл
└── tmpl/default.php

Манифест менять не нужно: папка src в нём уже указана целиком.

Класс помощника

// modules/mod_hello/src/Helper/HelloHelper.php
namespace My\Module\Hello\Site\Helper;
 
defined('_JEXEC') or die;
 
use Joomla\Database\DatabaseAwareInterface;
use Joomla\Database\DatabaseAwareTrait;
 
class HelloHelper implements DatabaseAwareInterface
{
    use DatabaseAwareTrait;
 
    public function getArticles(int $limit): array
    {
        $db = $this->getDatabase();
 
        $query = $db->getQuery(true)
            ->select($db->quoteName(['id', 'title', 'catid', 'language']))
            ->from($db->quoteName('#__content'))
            ->where($db->quoteName('state') . ' = 1')
            ->order($db->quoteName('created') . ' DESC')
            ->setLimit($limit);
 
        return $db->setQuery($query)->loadObjectList();
    }
}

Метод возвращает массив объектов — последние опубликованные статьи. Интерфейс DatabaseAwareInterface говорит Joomla: «этому классу нужна база», и она сама передаёт подключение; getDatabase() его возвращает. Запросы подробно разобраны в главе о компоненте.

Вызов из диспетчера

Помощника получают через фабрику — ту самую, что зарегистрирована в провайдере строкой HelperFactory:

// modules/mod_hello/src/Dispatcher/Dispatcher.php
namespace My\Module\Hello\Site\Dispatcher;
 
defined('_JEXEC') or die;
 
use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
 
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
{
    use HelperFactoryAwareTrait;
 
    protected function getLayoutData(): array
    {
        $data = parent::getLayoutData();
 
        $data['greeting'] = 'Привет!';
        $data['articles'] = $this->getHelperFactory()
            ->getHelper('HelloHelper')
            ->getArticles(5);
 
        return $data;
    }
}

getHelper('HelloHelper') создаёт объект класса из папки src/Helper. В макет уходит новая переменная $articles.

Вывод в макете

<?php
// modules/mod_hello/tmpl/default.php
 
defined('_JEXEC') or die;
 
use Joomla\CMS\Router\Route;
use Joomla\Component\Content\Site\Helper\RouteHelper;
?>
<div class="mod-hello">
    <p><?php echo htmlspecialchars($greeting, ENT_QUOTES, 'UTF-8'); ?></p>
 
    <ul>
        <?php foreach ($articles as $article) : ?>
            <li>
                <a href="<?php echo Route::_(RouteHelper::getArticleRoute($article->id, $article->catid, $article->language)); ?>">
                    <?php echo htmlspecialchars($article->title, ENT_QUOTES, 'UTF-8'); ?>
                </a>
            </li>
        <?php endforeach; ?>
    </ul>
</div>

Обновите страницу сайта: под приветствием появился список из пяти последних статей со ссылками. RouteHelper::getArticleRoute() — готовый метод компонента статей, который собирает адрес статьи, а Route::_() превращает его в понятный адрес.

Что ещё есть в данных

Родительский getLayoutData() уже кладёт в массив несколько значений:

Переменная в макетеЧто в ней
$moduleСам модуль: $module->title, $module->position
$paramsНастройки модуля
$appПриложение Joomla
$inputДанные запроса

Частая ошибка

Запрос к базе пишут прямо в макете tmpl/default.php. Работать будет, но макет перестаёт быть просто разметкой: владелец сайта, переопределив его в шаблоне, получит копию запроса и сломает модуль при первом обновлении. Данные готовит помощник, макет только выводит.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.