Печать

Создание MVC модуля для Joomla 1.5!

И так, «what this MVC?» — это архитектура программного обеспечения, в которой модель данных, пользовательский интерфейс и управляющая логика разделены на три отдельных компонента, и при модификации в каждом отдельном компоненте изменения оказывают минимальное влияние на остальные компоненты. Это одна из важных преимуществ использования MVC в программировании.

Шаблон MVC позволяет разделить данные, представление и обработку на три отдельных компонента 1)Модель (Model). Модель предоставляет данные (обычно для View), а также реагирует на запросы (обычно от контроллера). 3)Поведение (Controller). Интерпретирует данные, введенные пользователем, и сообщает модели и представление о необходимости выполнения определенных действий. 2)Представление (View). Отвечает за отображение информации (пользовательский интерфейс, шаблон вывода данных).

Так выглядит простейшая схема MVC:

Model View Controller Diagram

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

Ко всему этому модуль настраивается из админки, и в его настройках можно указать из какого раздела/категории использовать материалы для отображения. Тоесть должна быть возможность указать на вывод материалов из категории определенного раздела, из раздела по всем категориям этого раздела или же отказаться от разделов и категорий и выводить просто последние N-количество статей, которые опубликованы администратором. Ну и конечно же должна быть возможность указания количества выводимых материалов.

И еще чуть не забыл... Реализуем подключение стилевого файла модуля в Head документа.

И так наш моду будет иметь тематическое название — mod_mvc, и содержать в себе такую структуру файлов и каталогов:

mvc

Эта структура на картинке показана не просто так, ее необходимо описать в установочном файле модуля «mod_mvc.xml» для того что бы установщик Joomla содал такую же структуру каталогов в директории /modules, и скопировал в все файлы модуля в соответствующие каталоги данной структуры.

Установочный файл «mod_mvc.xml»:

< ?xml version="1.0" encoding="utf-8"?>
<install type="module" version="1.5.0">
<name>MVC</name>
<author>Cleverscript</author>
<creationdate>December 2009</creationdate>
<copyright></copyright>
<license>GPL 2.0</license>
<authoremail>toorr2p[dog]bigmir.net</authoremail>
<authorurl>http://cleverscript.ru/</authorurl>
<version>0.0.1</version>
<description>Module MVC</description>
<files>
<filename module="mod_mvc">mod_mvc.php</filename>
<filename>helper.php</filename>
<filename>index.html</filename>
<filename>tmpl/default.php</filename>
<filename>tmpl/index.html</filename>
<filename>tmpl/css/index.html</filename>
<filename>tmpl/css/style.css</filename>
</files>
<params>
<param name="moduleclass_sfx" type="text" default="" label="Module Class Suffix" description="PARAMMODULECLASSSUFFIX" />
<param name="source_sec" type="section" default="" label="Раздел" description="Укажите желаемый раздел для вывода превью" />
<param name="source_cat" type="category" default="" label="Категория" description="Укажите желаемую категорию раздела для вывода превью" />
<param name="show_all" type="radio" default="0" label="Без раздела и категории" description="Вывод материалов без учета раздела и категориии">
<option value="0">Нет</option>
<option value="1">Да</option>
</param>
<param name="count" type="text" default="10" label="Количество" description="Укажите желаемое количество выводимых материалов" />
<param name="template" type="filelist" default="default.php" directory="/modules/mod_mvc/tmpl" filter="\.php$" hide_none="1" hide_default="1" label="Шаблон" description="Выберите шаблон модуля" />
</params>
</install>

Начну с описания параметров группы Files (те то перечислены между тегами ) — это и есть наша структура которую будет формировать установщик Joomla при инсталляции модуля, здесь в строгом порядки указываем все файлы ходящие в наш модуль. Первый параметр немного отличается от остальных и имеет такой вид:

<filename module="mod_mvc">mod_mvc.php</filename>

Это файл-входной точки модуля, то есть наш как-бы наш контроллер который запускается Фреймверком Joomla и далее передает параметры в helper.php который использует их для выборки записей из БД и возвращает данные, это будет описано ниже... А так, на что здесь следует обратить внимание это на атрибут module="" в котором должно содержатся имя модуля, которое в свою очередь соответствует названию файла-входа в модуль («контроллера»). Исходя из этого установщик Joomla создаст каталог для модуля с названием из параметра module.

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

Файлы модуля описаны, теперь самое интересное, опишем параметры которые будут доступны в настройках модуля из адми-панели, это те которые в группе «params» (заключены между тегами ).

Первый параметр стандартный — он позволяет указать суффикс класса для выводимого модуля, для применения к нему специфических CSS стилей.

<param name="moduleclass_sfx" type="text" default="" label="Module Class Suffix" description="PARAMMODULECLASSSUFFIX" />

Содержит атрибуты:

1) name — имя параметра; 2) type — тип (тип поля); 3) default — значение поля по умолчанию; 4) label — ярлык возле поля; 5) description — подсказка-описание для поля

Таким образом создается параметр для модуля, значение которого будет доступно в коде модуля и в зависимости от его значения можно выполнять те или иные действия. при этом данное значение хранится в БД Joomla в таблице «dim_modules» в поле «params», для нашего модуля.

Следующие два параметра «source_sec» и «source_cat» имеют другой тип (атрибут type), первый из них отображает выпадающий список всех разделов сайта, а второй категорий по этим разделам, и в своих значениях содержит id раздела и категории — соответственно. С помощью этих двух типов полей администратор может выбрать какой материал выводить.

Третий параметр «show_all» имеет тип radio и содержит для выбора два значения 0 и 1 где ноль это «Нет» а 1 это «Да», по дефолту (default) устанавливается значение 0 — «Нет».

Четвертый параметр «count» — в нем администратор будет указывать какое количество записей отображать.

Ну и наконец то пятый параметр «template» — позволяет выбрать один из нескольких возможных шаблонов вывода материалов, обратите внимание на атрибут «directory» и «filter» первый указывает на папку c шаблонами модуля, а второй на расширение в названии используемых файлов в качестве шаблона.

Ну вот все параметры описаны и теперь после установки модуля в его административной части будет такая картина:

модуль joomla

Двигаемся далее, и подходим к описанию принципа работы модуля по шаблону MVC. Запуск модуля, фреймверком Joomla осуществляется таким образом (упрощенное описание) — вызывается файл модуля, в нашем случае это файл mod_mvc.php в котором доступны все значения из полей формы в админке модуля, другими словами доступны параметры в виде пара-значение.

Значение параметра получаем таким образом:

$source_sec  = $params->get('source_sec');

Таким образом например, мы получим значение ID раздела, указанного в настройках модуля. Теперь по порядку... Файл модуля mod_mvc.php — это «входная точка» нашего модуля, при его запуске вызывается метод (функция) из helper.php которой передаются параметры о которых я говорил чуть выше, этот метод выполняет определенные операции (выбр из БД, обработка данных и их преобразование и т.д) возвращает данные которые будут выводится через шаблон модуля.

В упрощенном виде это звучит так:

1)Вызов функции с передачей ей параметров и получение данных возвращаемых этой функцией. 3)Подключаем в HEAD стили CSS модуля. 2)Подключение шаблона. 3)Вывод данных в шаблоне.

В файле mod_mvc.php это выглядит так:

< ?php
defined('_JEXEC') or die('Restricted access');
 
//параметры доступные модулю
//print_r($params);
 
//Получаем паремтр с именем шаблона
$tmpl = str_replace('.php', '', $params->def('template', 'default.php'));
 
//Подключаем наш helper и
//и обращаемся к его классу, вызывая метод - который возвращает нам массив обьектов
//при этом передавая методу все параметры полученные модулем (из админки)
require_once (dirname(__FILE__).DS.'helper.php');
$list = MVC::getList($params);
if (!count($list)) {
return;
}
 
//Подключаем CSS
jimport('joomla.document.html.html');
$document =& JFactory::getDocument();
$link = JURI::root().'modules/mod_mvc/tmpl/css/style.css';
$attribs = array('type' => 'text/css');
$document->addHeadLink(JRoute::_($link), 'stylesheet', 'rel', $attribs);
 
//Подключаем шаблон (который указан из админке)
$template = JModuleHelper::getLayoutPath('mod_mvc', $tmpl);
if (file_exists($template)) {
require($template);
} else {
echo JText::_('ERROR_TEMPLATE');
}
?>

Далее поговорим о helper.php который является по сути «моделью» для получения данных, этот файл содержит в себе один класс — «MVC» который содержит метод (это он вызывается как было описано выше) «getList ()» который принимает параметры, и использует их в своей работе.

Эта функция выполняет запрос к БД и выполняет выборку записей (статей) на основе полученных параметров (настроек из админки модуля).

И так как выглядит этот класс с принадлежащим ему методом, для начала приведу пример того каким образом принимаются параметры (настройки из админки).

Выглядит это так:

class MVC {
function getList(&$params) {
$db =& JFactory::getDBO();
$source_sec = $params->get('source_sec');
$source_cat = $params->get('source_cat');
$show_all = $params->get('show_all');
$count = $params->get('count');
}
}

Здесь получаем соединение с БД JFactory::getDBO () и присваиваем значения параметров переменным. $params — это объект (экземпляр класс stdClass), который является удобным контейнером для передачи данных, в данном случае параметров, print_r ($params) выведет на экран такое:

JParameter Object ( [_raw] => source_sec=9 source_cat=35 template=default.php count= [_xml] => [_elements] => Array ( ) [_elementPath] => Array ( [0] => W:\home\localhost\www\funky_dyk\libraries\joomla\html\parameter\element ) [_defaultNameSpace] => _default [_registry] => Array ( [_default] => Array ( [data] => stdClass Object ( [source_sec] => 9 [source_cat] => 35 [template] => default.php [count] => ) ) ) [_errors] => Array ( ) )

Присвоив переменным значения параметров используем их для формирования запроса к Базе Данных Joomla. А конкретней — в случае если пользователь в настройках модуля указал раздел и категорию и не выбрал опцию «Показывать без учета раздел / категория», а также указал количество выводимых записей (если не указано то 10) формируем запрос следующим образом:

1)Условие в запросе:

 
    if($show_all == 0){
    $where = 'sectionid='.$source_sec.' AND catid='.$source_cat.' AND ';
    }else{
    $where = '';
    }

2)Сам запрос:

$query = 'SELECT a.*, s.title as stitle, c.title as ctitle, u.name, ' .
' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(":", a.id, a.alias) ELSE a.id END as slug,'.
' CASE WHEN CHAR_LENGTH(c.alias) THEN CONCAT_WS(":", c.id, c.alias) ELSE c.id END as catslug'.
' FROM #__content AS a' .
' LEFT JOIN #__users AS u ON u.id = a.created_by' .
' INNER JOIN #__categories AS c ON c.id = a.catid' .
' INNER JOIN #__sections AS s ON s.id = a.sectionid' .
' WHERE '.$where.
' s.published = 1' .
' AND c.published = 1' .
' ORDER BY id DESC';

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

Выполняем запрос. Если лимит не указан пользователем то выводим все

if($count == ''){
$db->setQuery($query);
}else{
$db->setQuery($query, 0, $count);
}

Загружаем результаты запроса к БД в массив

$rows = $db->loadObjectList();

А теперь самое интересное, из полученных данных, которые содержатся в виде объекта stdClass, формируем контент с помощью итерации, помещая данные(переменные) в массив в виде ключ=>значение:

$i=0;
$lists = array();
foreach ($rows as $row) {
//формируем ссылку
$lists[$i]->link = JRoute::_(ContentHelperRoute::getArticleRoute($row->slug, $row->catslug, $row->sectionid));
//формируем превью
$text = strtolower($row->introtext.$row->fulltext);
$regex = "/<img [^/>]+src\s*=\s*[\"']\/?([^\"']+)[\"'][^>]*\>/";//поиск картинки
preg_match ($regex, $text, $matches);
$images = (count($matches)) ? $matches : array();
if ($images) {
$lists[$i]->image = '<img src="'.$images[1].'" alt="thumbs" class="thumbs" />';
$lists[$i]->image = '<a href="'. $lists[$i]->link .'">'.$lists[$i]->image.'</a>';
}
//формируем интротекст
$lists[$i]->introtext = strip_tags($row->introtext);
$lists[$i]->paramss = $params;
$i++;
}

В начале формируем URL который будет указывать на материал и использоваться в ссылке «Далее» в шаблоне модуля, для этого в самом начале файла нужно было добавить подгрузку файла route.php, в котором содержится класс ContentHelperRoute и вызываемый нами метод getArticleRoute которому в качестве аргументов передаются параметры статьи — id материала с псевдонимом(через двоеточие), id категории и id раздела. При этом формируется ссылка на материал и заносится в элемент массива с ключом «link»:

$lists[$i]->link = JRoute::_(ContentHelperRoute::getArticleRoute($row->slug, $row->catslug, $row->sectionid));

Далее формируем превью (изображение к статье), для этого приводим весь интро-текст и фулл-текст к нижнему регистру и используем поиск тега IMG сразу и в introtext и в fulltext.

Первый найденный тег IMG (или из интро-текста или фул-текста), будет использоваться в качестве превью, вернее из этого тега будет извлечен параметр SRC содержащий путь к картинке, и далее использован в формировании картинки:

//формируем превью
$text = strtolower($row->introtext.$row->fulltext);
$regex = "/<img [^/>]+src\s*=\s*[\"']\/?([^\"']+)[\"'][^>]*\>/";//поиск картинки
preg_match ($regex, $text, $matches);
$images = (count($matches)) ? $matches : array();
if ($images) {
$lists[$i]->image = '<img src="'.$images[1].'" alt="thumbs" class="thumbs" />';
$lists[$i]->image = '<a href="'. $lists[$i]->link .'">'.$lists[$i]->image.'</a>';
}

К тому же эта картинка еще и является ссылкой на материал.

Следующий этап — формирование интротекста:

//формируем интротекст
$lists[$i]->introtext = strip_tags($row->introtext);

При этом с помощью функции strip_tags () удаляем все теги, оставляя только текст.

Сформировав массив с данными возвращаем его в качестве результата работы функции:

function getList(&$params) {
 
...
 
//возвращаем многомерный массив объектов
return $lists;
}

Теперь поговорим о шаблоне, файле default.php который находится в папке tmpl. Этот файл подгружается ниже вызова функции getList () в нашем главном файле-входной точки модуля mod_mvc.php (см. выше), и поэтому в нем доступен результат вызова функции.

Так как этим результатом является многомерный массив то в шаблоне обрабатываем его соответствующим образом:

< ?php
defined('_JEXEC') or die('Restricted access');
 
echo "<ul class='mod_mvc'>";
 
foreach ($list as $item){
echo '<li>';
if (!empty($item->image)) :
echo $item->image;
endif;
echo "<p>".$item->introtext."</p>";
echo "<a href='".$item->link."'>Далее</a>";
echo '</li>';
}
echo "";
?>

Здесь с помощью итерации извлекаем данные из массива и помещаем их в нужные вам контейнеры, для наглядности я решил использовать не маркированный список UL, в котором каждый LI это отдельное краткое описание статьи с превью и ссылкой «Далее».

А оформление CSS прописывается в файле style.css который находится в папке css шаблона модуля, и подключается в документ из файла модуля mod_mvc.php, перед подгрузкой шаблона модуля (см. выше).

В данном примере он содержит описание для элементов списка:

ul.mod_mvc li{width:100%;height:160px;}

Структуру шаблона вы можете изменять по своему усмотрению или же просто создать еще один шаблон и положить его в папку tmpl, а затем указать ваш шаблон из админки.

Интересная статья? Поделись ей с другими: