Классы моделей
В Joomla для создания объектов модели используются несколько классов:
abstract class JModel extends JObject
На основе JModel создается класс JModelList
class JModelList extends JModel
Он используется для вывода списка
abstract class JModelItem extends JModel
JModelItem используется для вывода элемента списка
Для редактирования элемента списка есть класс JModelForm и на его основе JModelAdmin
abstract class JModelForm extends JModel
abstract class JModelAdmin extends JModelForm
Загрузка файла с классом модели:
jimport('joomla.application.component.modellist');
model
modellist
modelitem
modelform
modeladmin
Основные методы класса JModel
public static function addIncludePath($path = '', $prefix = '')
Указываем дополнительные пути где искать файл модели, например
JModel::addIncludePath(JPATH_COMPONENT_ADMINISTRATOR.DS.'models');
getInstance - для получение объекта модели:
public static function getInstance($type, $prefix = '', $config = array())
Аналогично, для добавления таблиц используется addTablePath:
public static function addTablePath($path)
getTable - для получения объекта таблицы:
public function getTable($name = '', $prefix = 'Table', $options = array())
Для получения объекта базы данных getDbo:
public function getDbo()
{
return $this->_db;
}
Задание состояния модели setState:
public function setState($property, $value = null)
{
return $this->state->set($property, $value);
}
Для сохранения состояния используется объект JObjects
И получение состояния объекта
public function getState($property = null, $default = null)
{
if (!$this->__state_set)
{
// Защищенный метод для автоматического заполнения состояния модели.
$this->populateState();
// Установите флаг model state set в значение true.
$this->__state_set = true;
}
return $property === null ? $this->state : $this->state->get($property, $default);
}
При получении выполняется метод populateState для формирования объекта состояния модели.
Основные методы класса JModellist
JModellist создается на основе класса JModel, следовательно для него действительны методы, описанные выше методы для класса JModel
Дополнительно для работы со списком в нем добавлены методы:
protected function populateState($ordering = null, $direction = null)
{
// Если контекст задан, предположим, что используются списки с отслеживанием состояния.
if ($this->context)
{
$app = JFactory::getApplication();
$value = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->getCfg('list_limit'));
$limit = $value;
$this->setState('list.limit', $limit);
$value = $app->getUserStateFromRequest($this->context . '.limitstart', 'limitstart', 0);
$limitstart = ($limit != 0 ? (floor($value / $limit) * $limit) : 0);
$this->setState('list.start', $limitstart);
// Проверьте, есть ли поле для заказа в белом списке, в противном случае используйте входящее значение.
$value = $app->getUserStateFromRequest($this->context . '.ordercol', 'filter_order', $ordering);
if (!in_array($value, $this->filter_fields))
{
$value = $ordering;
$app->setUserState($this->context . '.ordercol', $value);
}
$this->setState('list.ordering', $value);
// Проверьте правильность направления заказа, в противном случае используйте входящее значение.
$value = $app->getUserStateFromRequest($this->context . '.orderdirn', 'filter_order_Dir', $direction);
if (!in_array(strtoupper($value), array('ASC', 'DESC', '')))
{
$value = $direction;
$app->setUserState($this->context . '.orderdirn', $value);
}
$this->setState('list.direction', $value);
}
else
{
$this->setState('list.start', 0);
$this->state->set('list.limit', 0);
}
}
getListQuery используется для формирования запроса, выполнение которого происходит в getItems
protected function getListQuery()
{
$db = $this->getDbo();
$query = $db->getQuery(true);
return $query;
}
Например, в классе модели компонента переопределям getListQuery:
protected function getListQuery()
{
// Создайте новый объект запроса.
$db = JFactory::getDBO();
$query = $db->getQuery(true);
// Выберите несколько полей
$query->select('id,greeting');
// Из таблицы приветствий
$query->from('#__helloworld');
return $query;
}
Для получения массива объектов используем getItems:
public function getItems()
{
// Получите ключ от хранилища.
$store = $this->getStoreId();
// Попробуйте загрузить данные из внутреннего хранилища.
if (isset($this->cache[$store]))
{
return $this->cache[$store];
}
// Загрузите элементы списка.
$query = $this->_getListQuery();
$items = $this->_getList($query, $this->getStart(), $this->getState('list.limit'));
// Проверьте, нет ли ошибки в базе данных.
if ($this->_db->getErrorNum())
{
$this->setError($this->_db->getErrorMsg());
return false;
}
// Добавьте элементы во внутренний кэш.
$this->cache[$store] = $items;
return $this->cache[$store];
}
И для построения списка таблиц используются методы getPagination, getStart, getTotal:
getPagination()
public function getPagination()
{
// Получите ключ от хранилища.
$store = $this->getStoreId('getPagination');
// Попробуйте загрузить данные из внутреннего хранилища.
if (isset($this->cache[$store]))
{
return $this->cache[$store];
}
// Создайте объект разбивки на страницы.
jimport('joomla.html.pagination');
$limit = (int) $this->getState('list.limit') - (int) $this->getState('list.links');
$page = new JPagination($this->getTotal(), $this->getStart(), $limit);
// Добавьте объект во внутренний кэш.
$this->cache[$store] = $page;
return $this->cache[$store];
}
getTotal()
public function getTotal()
{
// Получите ключ от хранилища.
$store = $this->getStoreId('getTotal');
// Попробуйте загрузить данные из внутреннего хранилища.
if (isset($this->cache[$store]))
{
return $this->cache[$store];
}
// Загрузите общее количество.
$query = $this->_getListQuery();
$total = (int) $this->_getListCount($query);
// Проверьте, нет ли ошибки в базе данных.
if ($this->_db->getErrorNum())
{
$this->setError($this->_db->getErrorMsg());
return false;
}
// Добавьте итоговую сумму во внутренний кэш.
$this->cache[$store] = $total;
return $this->cache[$store];
}
getStart()
public function getStart()
{
$store = $this->getStoreId('getstart');
// Попробуйте загрузить данные из внутреннего хранилища.
if (isset($this->cache[$store]))
{
return $this->cache[$store];
}
$start = $this->getState('list.start');
$limit = $this->getState('list.limit');
$total = $this->getTotal();
if ($start > $total - $limit)
{
$start = max(0, (int) (ceil($total / $limit) - 1) * $limit);
}
// Добавьте итоговую сумму во внутренний кэш.
$this->cache[$store] = $start;
return $this->cache[$store];
}