Как установить Joomla: пошаговое руководство

Перенос сайта joomla на хостинг в интернет CMS Joomla

Ordering

Когда мы хотим расположить элементы в определенном порядке, JTable прsetQueryедоставляет нам для этого набор методов. Первый из рассмотренных нами методов будет reorder(). Этот метод исправляет ошибки в порядке расположения записей в таблице.

$table->reorder();

В более сложных таблицах записи обычно разбиты по группам, и для этого в метод reorder() нужно дописать дополнительный параметр. Представим, что в нашей таблице есть поле group. В этом примере мы упорядочим записи в группе 1.

$db =& $table::getDBO();
$where = $db->nameQuote('group').' = 1';
$table->reorder($where)

Заметьте, что мы получаем объект базы данных не из JFactory, а из таблицы! Ранее мы уже использовали метод getNextOrder(). Метод выдает нам следующую позицию в порядке упорядочивания. Как и в случае с reorder(), мы имеем возможность определения груп. Например, получим следующий номер порядка для группы 1.

$db =& $table::getDBO();
$where = $db->nameQuote('group').' = 1';
$nextPosition = $table->getNextOrder($where);

И последний метод – это move(). Он нужен для перемещения записи на одну позицию вверх или вниз. Переместим на примере запись вверх.$table->load($id); $table->move(-1); Опять у нас есть возможность для указания групп. Покажем это на примере:

$db =& $table::getDBO();
$where = $db->nameQuote('group').' = 1';
$table->load($id);
$table->move(1, $where)

Написание запросов

Вот несколько правил при написании запросов к базе данных.

  • Используйте префикс #__ вначале всех имен таблиц.
  • Используйте метод nameQuote() для формирования названных элементов в запросе.
  • Используйте метод Quote() для формирования значений.

nameQuote() – устанавливает правильность разделителей в имени поля, а Quote() – устанавливает правильность разделителей в передаваемом значении. Например:

$db = JFactory::getDBO();
$query = 'SELECT * FROM '
.$db->nameQuote('#__test')
.' WHERE '
.$db->nameQuote('name')
.' = '
.$db->Quote('Some Name');

Если мы использовали MySQL или MySQLi драйвер, то запрос в итоге будет выглядеть следующим образом:

SELECT * FROM 'jos_test' WHERE 'name' = "Some Name";

Пример схемы

Таблица нарисована для расширения названного ‘My Extension’ и записей названных обобщенно foobar. Имя таблицы будет #__myextension_foobars.

Поле Тип NOT NULL AUTO INC UNSIGNED По-уомлчанию
id INTEGER + + + NULL
content TEXT +
checked_out INTEGER + +
checked_out_time DATETIME + 0000-00-00 00:00:00
params TEXT +
ordering INTEGER + +
hits INTEGER + +
published TINYINT(1) + +

Эта таблица использует все зарезервированные поля и одно автоинкрементное ключевое поле ID. SQL запрос который создаст таблицу описанную в схеме выше:

CREATE TABLE '#__myextension_foobars' (
'id' INTEGER UNSIGNED NOT NULL DEFAULT NULL AUTO_INCREMENT,
'content' TEXT NOT NULL DEFAULT '',
'checked_out' INTEGER UNSIGNED NOT NULL DEFAULT ,
'checked_out_time' DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
'params' TEXT NOT NULL DEFAULT '',
'ordering' INTEGER UNSIGNED NOT NULL DEFAULT ,
'hits' INTEGER UNSIGNED NOT NULL DEFAULT ,
'published' INTEGER UNSIGNED NOT NULL DEFAULT ,
PRIMARY KEY('id')
)
CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';

Использование ADOdb

ADOdb – это абстрактный слой на php по управлению базами данных, работающих под BSD. ADOdb поддерживает ряд ведущих баз данных. Сама Joomla не поддерживает ADOdb, а лишь эмулирует некоторую функциональность в своих базах данных.  Мы должны использовать ADOdb методы, если мы портируем существующее приложение, использующее ADOdb, или создаем расширение, работающее standalone с использованием ADOdb. Joomla! использует JRecordSet класс для эмуляции класса ADORecordSet. JRecordSet класс еще не закончен, и обладает далеко не всеми методами класса ADORecordSet. В этом примере мы покажем простейшее использование класса JRecordSet ($row – это массив).

$db =& JFactory::getDBO();
$rs = $db->Execute('SELECT * FROM #__test');
while ($row = $rs->FetchRow())
{
    // обрабатываем $row
}

JTableJoomla! предоставляет нам мощный абстрактный класс JTable; при этом мы можем выполнять все основные функции по работе с таблицей. Для каждой таблицы, которую мы хотим использовать в классе JTable, мы должны создать новый подкласс. При создании подкласса JTable, мы должны придерживаться некоторых правил. Эти правила позволят нам интегрировать наше расширение в фрэймворк Joomla. Итак, каждый подкласс JTable должен быть распложен в отдельном файле в каталоге tables (в административной части компонента). Имя создаваемого класса должно иметь префикс table. Имя файла обязательно должно быть в единственном числе. Используем описанную выше схему таблицы, чтобы показать на примере как работать с классом JTable. Класс должен называться TableFoobar и расположен в каталоге JPATH_COMPONENT_ADMINISTRATOR.DS.’tables’.DS.’foobar.php’. При первом использовании нашего класса мы должны определить глобальные свойства. Глобальные свойства соответствуют полям таблицы и должны иметь такие же названия. Мы используем эти свойства как буфер для хранения отдельных записей. Во-вторых. В целях использования метода JTable::getInstance() мы должны определить конструктор. В-третьих нам нужно переопределить метод check(). Этот метод проверяет содержимое буфера и возвращает булев результат. Если метод вернул значение false, то используем метод setError() для пояснения ошибки.

/** * обработчик таблицы #__myextenstion_foobars * */
class TableFoobar extends JTable
{
    /** @var int Primary key */ 
    var $id = null;
    /** @var string Content */ 
    var $content = null;
    /** @var int Checked-out owner */ 
    var $checked_out = null;
    /** @var string Checked-out time */ 
    var $checked_out_time = null;
    /** @var string Parameters */ 
    var $params = null;
    /** @var int Order position */ 
    var $ordering = null;
    /** @var int Number of views */
 
    var $hits = null;
    /** * Constructor * * @param database Database object */
    function __construct( &$db )
    {
        parent::__construct('#__myextension_foobars', 'id', $db);
    }
    /** * Проверка * * @return boolean True if buffer is valid */
    function check()
    {
        if(!$this->content)
        {
            $this->setError(JText::_('Ваш Foobar должен содержать контент'));
            return false;
        }
        return true;
    }
}

Теперь, когда мы создали TableFoobar класс нужно инстанцировать объект с помощью статического метода JTable:: getInstance().

JTable::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.DS.'tables');
$table = JTable::getInstance('foobar', 'Table');

Заметьте, что мы подключаем не foobar.php а только каталог с таблицами. Когда JTable начинает инстанцировать TableFoobar на объект, автоматически подключается foobar.php.

В качестве заключения

Если вы ищите компонент для создания карты сайта на Joomla 3 или Joomla 4, то первым делом обратите внимание на JL Sitemap; если на вашем сайте используется компонент, для которого еще нет плагина к JL Sitemap, то обратите внимание на OSMap и список существующих к нему плагинов; компоненты Xmap и mapX морально устарели и не обновляются, поэтому не рекомендуем тратить на них время; компонент OSMap является актуальным наследником Xmap; если сайт использует только базовые компоненты Joomla, то для генерации карты сайта будет предостаточно бесплатной версии OSMap; если сайт использует только базовые компоненты Joomla, то для генерации карты сайта будет предостаточно бесплатной версии OSMap; если на сайте используются компоненты сторонних разработчиков, то не спешите покупать OSMap Pro — сперва протестируйте совместимость OSMap Free с соответствующими плагинами для Xmap; если карта сайта будет генерироваться некорректно в связке OSMap + плагин для Xmap, то проверьте, включается ли нужный плагин в платную версию OSMap: возможно, придется приобретать плагин отдельно; если вы ищите генератор карты сайта Sitemap для Joomla, то не рассматривайте jSitemap, т. к

это «тяжелое» во многих отношениях расширение, требующее время на освоение.

CRUD

CRUD (Create Read Update Delete) – это общее название основных задач по управлению таблицей. Все CRUD примеры $table ссылаются на класс TableFoobar и $id ссылается на идентификатор записи которую мы в данный момент обрабатываем. В этом примере мы создаем новую запись; $table – экземпляр класса TableFoobar.

$table->reset();
$table->set('content', "Наш контент");
$table->set('ordering', $table->getNextOrder());
if ($table->check())
{
    if (!$table->store())
    {
        // обработчик ошибок записи
        // используем $table->getError()
    }
}
else
{
    // обработчик ошибки проверки буфера
    // тоже используем $table->getError()
}

Метод reset() очищает наш буфер и приводит значения всех свойств к значениям по-умолчанию. Метод getNextOrder() определяет следующий по порядку вложенности элемент. Если запись не существующая, то он ставит значение 1. Давайте рассмотрим наш пример подробнее. Некоторые из полей имели значение по-умолчанию, и после записи, значение даты будет пустым. После выполнения предыдущего примера буфер $table выглядит так:

 => 1
  => Наш контент
  => 
  => 
  => 
  => 1
  => 0

После выполнения метода store() (сохранения записи), мы можем загрузить его:

$table->load($table->id);

Теперь наш буфер выглядит так:

 => 1
  => Наш контент
  => 0
  => 0000-00-00 00:00:00
  => 
  => 1
  => 0

Вместо загрузки нашей сохраненной записи, мы могли бы изначально верно установить значения по-умолчанию, и нам бы не пришлось перезагружать запись.Однако некоторые значения по-умолчанию зависят от типа данных. Поэтому нам нужно переопределить метод reset(). Для примера значение checked_out_time будет равно $db->getNullDate(). Итак для загрузки конкретной записи используем метод:

if (!$table->load($id))
{
    // обработчик загрузки
    // используем $table->getError() для ловли ошибок
}

Для обновления записи в буфере мы можем использовать два метода: первый – это загрузить запись из БД, второй – это установить конкретные значения для свойств буфера.В этом примере покажем как обновить запись:

// установка значений
$table->reset();
$table->setVar('id', $id);
$table->setVar('content', JRequest::getString('content'));
if ($table->check())
{
    if (!$table->store())
    {
        // обрабатываем ошибки записи с помощью $table->getError()
    }
}
else
{
    // обрабатываем ошибки ввода в буфер $table->getError()
}

Последнее что мы расмотрим – это удаление записи:

if (!$table->delete($id))
{
    // обрабатываем ошибки
}

Если мы не указываем в методе delete() номер id, то id будет браться из буфера. Если наша запись в таблице имеет родственные записи с другими таблицами, то мы должны сначала выполнить проверку методом canDelete(). Этот метод имеет всего один параметр в виде двумерного массива. Внутри массива должно быть несколько ключей – idfield, name, joinfield, и label. idfield – это имя первичного ключа в соответствующей таблице. name – это название самой таблицы. joinfield – это имя внешнего ключа соответствующей таблицы. label – это описание отношения между таблицами, для вывода сообщения об ошибке, если родственных связей не найдено.Представьте что есть еще одна таблица #__myextension_children. Эта таблица имеет первичный ключ childid и внешний ключ primary, который ссылается на запись в таблице #__myextension_foobars. В этом примере мы проверим нет ли зависимости между записями таблицами  #__myextension_children и #__myextension_foobars, перед удалением записи из таблицы #__myextension_foobars.

$join1 = array('idfield'   => 'childid', 
               'name'      => '#__myextension_children', 
               'joinfield' => 'parent', 
               'label'     => 'Children');
 
$joins = array($join1);
if ($table->canDelete($id, $joins))
{
    if (!$table->delete($id))
    {
        // обрабатываем ошибки удаления
    }
}
else
{
    // обрабатываем в случае нахождения зависимостей
}

Мы можем определить более одной межтабличной связи. Допустим еще существует таблица #__myextension_illegitimate_children:

$join1 = array('idfield'   => 'childid', 
               'name'      => '#__myextension_children', 
               'joinfield' => 'parent', 
               'label'     => 'Children');
$join2 = array('idfield'   => 'ichildid', 
               'name'      => '#__myextension_illegitimate_children', 
               'joinfield' => 'parent', 
               'label'     => 'illegitimate Children');
$joins = array($join1, $join2);

Rate article