Joomla CMS как Framework

627b1361d9dd82c2c4d38d354fe61df6_full — каркас программной системы (или подсистемы). Может включать вспомогательные программы, библиотеки кода, язык сценариев и другое ПО, облегчающее разработку и объединение разных компонентов большого программного проекта. Обычно объединение происходит за счёт использования единого API. Application - это глобальный объект, отвечающий за процессинг запроса. Два класса этого объекта, которые нам интересны, это JSite и JAdministrator. Joomla! использует эти классы для выполнения запросов к фронт-енду и к бэк-енду соответственно. Классы приложения расширяют базовый абстрактный класс JApplication; бОльшая часть функциональности JSite и JAdministrator совпадает.
Документ — глобальный объект, используемый для буферизации запроса. Когда мы выводим данные в наших расширениях, они добавляются в Документ. Это дает возможность изменять вывод перед отправкой.
Объект Приложение(application) всегда хранится в переменной $mainframe. Это глобальная переменная, доступ к которой может быть получен после декларации ее глобальной, т. е .

<span style="color: #000000; font-weight: bold;">function</span> isAdmin<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #990000;">global</span> <span style="color: #000088;">$mailframe</span>;
<span style="color: #b1b100;">return</span> <span style="color: #000088;">$mainframe</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isAdmin</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>;
<span style="color: #009900;">}</span>

Для обращения к глобальному объекту Документ(document) используется static метод JFactory::getInstance ()

<span style="color: #000088;">$document</span><span style="color: #339933;">=&amp;</span> Jfactory<span style="color: #339933;">::</span><span style="color: #004000;">getDocument</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>;

Обратите внимание, что мы создаем ссылку на объект с помощью “=&” а не копируем объект полностью.

Структура URI.
Запрос — это часть URI из которой мы получаем данные, состоящая из пар ключ-значение, разделенных амперсандом.
Сначала мы рассмотрим значение option. Это значение определяет компонент, к которому мы обращаемся, имя начинается с com_. Например:

http<span style="color: #339933;">:</span><span style="font-style: italic; color: #666666;">//www.example.org/joomla/index.php?option=com_example</span>

Меню — основное средство навигации по Joomla! для пользователей. Каждый из пунктов меню содержит ссылку на компонент (внутреннюю) или URL (внешнюю ссылку). Мы можем изменять параметры для отдельно взятого компонента и назначать шаблоны.
Каждый пункт меню имеет свой ID. ID позволяет нам обращаться к компоненту, используя значение Itemid вместо option. У Itemid есть еще одно применение: когда известен ID пункта меню, пункт может быть выделен и показаны пункты подменю. Например, обратимся к пункту меню с ID=1:

http<span style="color: #339933;">:</span><span style="font-style: italic; color: #666666;">//www.example.org/joomla/index.php?Itemid=1</span>

Некоторые компоненты могут выводить данные в разных форматах, используя значение format. Это сработает в том случае, если данный компонент поддерживает запрошенный формат. Например получим данные от компонента example в формате фида:

http<span style="color: #339933;">:</span><span style="font-style: italic; color: #666666;">//www.example.org/joomla/index.php?option=com_example&amp;format=feed</span>

Другое часто использующееся значение, task, определяет задачу, которую должен выполнить компонент. При создании собственных компонентов, использование данного значения является приоритетным. Причина этого в том, что компонент частично является реализацией фреймворка. Например, обратимся к компоненту example с задачей view:

http<span style="color: #339933;">:</span><span style="font-style: italic; color: #666666;">//www.example.org/joomla/index.php?option=com_example&amp;task=view</span>

При построении своих собственных URI мы должны быть уверены, что используемые значения не конфликтуют со значениями фреймворка. Список основных значений запроса, используемых ядром Joomla:

  • format
  • hidemainmenu (только для админки)
  • Itemid
  • layout
  • limit
  • limitstart
  • no_html
  • option
  • start
  • task
  • tmpl
  • tp
  • vars
  • view

Когда мы выводим URI, следует использовать метод JRoute::_ (). Использование его означает, что нам не придется отслеживаить ID меню. Вот как мы используем этот метод:

<span style="color: #990000;">echo</span> JRoute<span style="color: #339933;">::</span><span style="color: #990000;">_</span><span style="color: #009900;">(</span><span>'index.php?option=com_example&amp;task=view'</span><span style="color: #009900;">)</span>;

Если мы используем данный метод в компоненте, и ссылаемся на этот же компонент, можно опустить значение option. Обратите внимание, что мы не кодировали амперсанд согласно стандарту XHTML, JRoute сделает это за нас :)
Еще одним преимуществом использования JRoute является его поддержка SEO, он автоматически делает из адреса seo-friendly ссылку. То есть, для предыдущего примера ссылка будет выглядеть так:

http://example.org/joomla/index.php/component/com_example

Библиотеки.
Joomla! содержит достаточное количество полезных библиотек, включая свою собственную — joomla. Для импорта библиотеки используется функция jimport (). В примере мы импортируем библиотеку joomla.filesystem.file для работы с файловой системой:

jimport <span style="color: #009900;">(</span><span>'joomla.filesystem.file'</span><span style="color: #009900;">)</span>;

При импортировании, возможно инклудить не всю библиотеку, а лишь часть ее. Предыдущий пример импортирует /libraries/joomla/filesystem/file.php Мы можем импортировать все файлы в каталоге filesystem:

jimport<span style="color: #009900;">(</span><span>'joomla.filesystem.*'</span><span style="color: #009900;">)</span>;

Наследование JObject.

Многие классы в Joomla! — подклассы JObject. В базовом классе довольно много полезных методов, включая стандартные аксессоры и методы error handling. JObject также эмулирует конструкторы PHP5, что дает возможность использовать __constructor () независимо от версии PHP. При наследовании, в классах как правило используется конструктор родительского класса parent::__construct ().
Почти все классы и объекты Joomla происходят от класса JObject. Методы get () и set () используются для работы со свойствами, при использовании get () с несуществующим свойством будет возвращено значение по умолчанию; при использовании set () с несуществующим свойством оно будет создано. Оба метода работают также и с private свойствами.
Ошибки в объекте отслеживаются с помощью getErrors (), getError () и setError (). Ошибки записываются свойство-массив _errors. Ошибки могут быть потоками, либо объектами классов Exeption и JExeption.

Обработка запроса.
При PHP разработке обычно работают с глобальными массивами $_GET, $_POST, $_FILES, $_COOKIE, $_REQUEST. В Joomla вместо всего этого используется static класс JRequest, что позволяет сократить объем кода и улучшить безопасность. Глобальные массивы доступны для работы, и все еще используются в некоторых расширениях.
Наиболее часто используются методы JRequest::setVar () и JRequest::gerVar (). Для чего они используются, понятно из их названий. В следующем примере мы получаем значение id, если оно не установлено, то возвращаем значение по умолчанию 0 (устанавливается).

<span style="color: #000088;">$id</span><span style="color: #339933;">=</span>JRequest<span style="color: #339933;">::</span><span style="color: #004000;">getVar</span><span style="color: #009900;">(</span><span>'id'</span><span style="color: #339933;">,</span> <span style="color: #800080;">0</span><span style="color: #009900;">)</span>;

Метод JRequest::setVar () используется для установки значений, и по сравнению с предыдущим, используется реже. Чаще всего он используется для установки значений по умолчанию. Например, мы может установить задачу (task) по умолчанию в компоненте, если он не выбран.

JRequest<span style="color: #339933;">::</span><span style="color: #004000;">setVar</span><span style="color: #009900;">(</span><span>'task'</span><span style="color: #339933;">,</span> <span>'someDefaultTask'</span><span style="color: #009900;">)</span>;

Есть полезный фокус для того чтоб быть уверенным, что переменная установлена, включающий совместное использование обоих методов. В примере, если name не установлено, то мы присваиваем ему значение по умолчанию ‘unknown’:

JRequest<span style="color: #339933;">::</span><span style="color: #004000;">setVar</span><span style="color: #009900;">(</span><span>'name'</span><span style="color: #339933;">,</span> JRequest<span style="color: #339933;">::</span><span style="color: #004000;">getVar</span><span style="color: #009900;">(</span><span>'name'</span><span style="color: #339933;">,</span> <span>'unknown'</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span>;

Есть еще несколько полезных методов этого класса, getInt (), getFloat (), getBool (), getWord (), getCmd (), getString (), используя которые мы можем быть уверены что вернем значение нужного типа.

Паттерн Factory.
Перед тем как мы рассмотрим Joomla Factory, разберем немного паттерны вообще.
Один из наиболее часто используемых паттернов — iterator, описывающий выполнение одной задачи много раз в цикле. Joomla использует достаточно много паттернов, многие из которых сложнее чем iterator.
Паттерн Factory — создающий паттерн (creational pattern) использующийся для создания и возврата объектов. Используется в случаях, когда согласно параметрам создаются объекты разных классов, часто подклассов одного абстрактного класса. В Joomla есть static класс JFactory, наследующий factory паттерн. Данный класс позволяет нам легко создавать глобальные объекты и получать к ним доступ.
Например:

<span style="color: #000088;">$db</span><span style="color: #339933;">=&amp;</span> JFactory<span style="color: #339933;">::</span><span style="color: #004000;">getDBO</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>;
<span style="color: #000088;">$user</span><span style="color: #339933;">=&amp;</span> JFactory<span style="color: #339933;">::</span><span style="color: #004000;">getUser</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>;
<span style="color: #000088;">$document</span><span style="color: #339933;">=&amp;</span> JFactory<span style="color: #339933;">::</span><span style="color: #004000;">getDocument</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>;

Паттерн singleton используется для создания только одного объекта указанного класса. Конструктор такого класса делается protected или private и используется static метод для создания класса. Многие классы Joomla используют псевдо-singleton паттерн для работы с объектами, в частности, для этого есть static метод getInstance (); в некоторых случаях JFactory используется для работы с этим методом. Классы которые наследуют этот метод, не всегда являются классами типа singleton.
Имеет смысл использовать вышеперечисленное в иерархическом порядке: JFactory метод, getInstance (), нормальный конструктор (new).
В случаях, когда и JFactory и класс имеют методы для создания объекта, предпочтение стоит отдавать JFactory. Если класс предлагает более подходящий метод getInstance () чем JFactory, конечно, можете использовать его.

Сессии.
Joomla всегда начинает сессию, независимо от того, залогинился пользователь или нет. Вместо глобального массива $_SESSION используется глобальный объект. Данные сессии хранятся в пространстве имен (namespaces); namespace по умолчанию — default. В примере мы получаем значение default.example :

<span style="color: #000088;">$session</span><span style="color: #339933;">=&amp;</span> JFactory<span style="color: #339933;">::</span><span style="color: #004000;">getSession</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>;
<span style="color: #000088;">$value</span><span style="color: #339933;">=</span><span style="color: #000088;">$session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">(</span><span>'example'</span><span style="color: #009900;">)</span>;

Если мы хотим получить данные из другого namespace, кроме default, мы должны указать значение по умолчанию. В примере мы получаем значение myextension.example и устанавливаем значение по умолчанию null:

<span style="color: #000088;">$session</span><span style="color: #339933;">=&amp;</span> JFactory<span style="color: #339933;">::</span><span style="color: #004000;">getSession</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>;
<span style="color: #000088;">$value</span><span style="color: #339933;">=</span><span style="color: #000088;">$session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">(</span><span>'example'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">null</span><span style="color: #339933;">,</span> <span>'myextension'</span><span style="color: #009900;">)</span>;

Установка значений очень похожа на их получение. В примере мы установим значение myextension.example равным 1:

<span style="color: #000088;">$session</span><span style="color: #339933;">=&amp;</span> JFactory<span style="color: #339933;">::</span><span style="color: #004000;">getSession</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>;
<span style="color: #000088;">$session</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">(</span><span>'example'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span>'myextension'</span><span style="color: #009900;">)</span>;

Сессии хранятся подобно плоским файлам; поэтому существует объект JRegistry внутри сессии. Класс JRegistry использует более сложный способ хранения данных в namespaces. Для использования этого элемента сессии есть метод Приложения (application) getUserState ().

Перепрыгиваем языковой барьер с Joomla.
Язык по умолчанию выставляется в опциях, но может быть заменен для конкретного пользователя. Static класс JText используется как стандартный механизм для перевода, включает три метода: _ (), sprintf (), printf (). Скорее всего, вы чаще всего будете использовать метод _ (), он переводит строку. В примере мы переведем строку ‘Понедельник’, если строка не может быть переведена, то возвращается переданное значение.

<span style="color: #990000;">echo</span> JText<span style="color: #339933;">::</span><span style="color: #990000;">_</span><span style="color: #009900;">(</span><span>'Понедельник'</span><span style="color: #009900;">)</span>;

Метод JText::sprintf () похож на функцию PHP sprintf (). Мы передаем ей строку и любое число параметров для вставки в переведенную строку. Например, если перевод для строки SAVED_ITEMS — Saved %d items, метод возвратит Saved 3 items.

<span style="color: #000088;">$value</span><span style="color: #339933;">=</span>JText<span style="color: #339933;">::</span><span style="color: #990000;">_</span><span style="color: #009900;">(</span><span>'SAVED_ITEMS'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">)</span>;

Метод JText::printf () возвратит длину переводимой строки и собственно, саму переведенную строку.

<span style="color: #000088;">$length</span><span style="color: #339933;">=</span>JText<span style="color: #339933;">::</span><span style="color: #990000;">printf</span><span style="color: #009900;">(</span><span>'SAVED_ITEMS'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span><span style="color: #009900;">)</span>;
Для создания переводов собственных расширений требуется создание специальных INI файлов с переводом

Запись навигация

Top