Классы моделей
В 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)
{
// Protected method to auto-populate the model state.
$this->populateState();
// Set the model state set flag to 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 the context is set, assume that stateful lists are used.
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);
// Check if the ordering field is in the white list, otherwise use the incoming value.
$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);
// Check if the ordering direction is valid, otherwise use the incoming 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()
{
// Create a new query object.
$db = JFactory::getDBO();
$query = $db->getQuery(true);
// Select some fields
$query->select('id,greeting');
// From the hello table
$query->from('#__helloworld');
return $query;
}
Для получения массива объектов используем getItems:
public function getItems()
{
// Get a storage key.
$store = $this->getStoreId();
// Try to load the data from internal storage.
if (isset($this->cache[$store]))
{
return $this->cache[$store];
}
// Load the list items.
$query = $this->_getListQuery();
$items = $this->_getList($query, $this->getStart(), $this->getState('list.limit'));
// Check for a database error.
if ($this->_db->getErrorNum())
{
$this->setError($this->_db->getErrorMsg());
return false;
}
// Add the items to the internal cache.
$this->cache[$store] = $items;
return $this->cache[$store];
}
И для построения списка таблиц используются методы getPagination, getStart, getTotal:
getPagination()
public function getPagination()
{
// Get a storage key.
$store = $this->getStoreId('getPagination');
// Try to load the data from internal storage.
if (isset($this->cache[$store]))
{
return $this->cache[$store];
}
// Create the pagination object.
jimport('joomla.html.pagination');
$limit = (int) $this->getState('list.limit') - (int) $this->getState('list.links');
$page = new JPagination($this->getTotal(), $this->getStart(), $limit);
// Add the object to the internal cache.
$this->cache[$store] = $page;
return $this->cache[$store];
}
getTotal()
public function getTotal()
{
// Get a storage key.
$store = $this->getStoreId('getTotal');
// Try to load the data from internal storage.
if (isset($this->cache[$store]))
{
return $this->cache[$store];
}
// Load the total.
$query = $this->_getListQuery();
$total = (int) $this->_getListCount($query);
// Check for a database error.
if ($this->_db->getErrorNum())
{
$this->setError($this->_db->getErrorMsg());
return false;
}
// Add the total to the internal cache.
$this->cache[$store] = $total;
return $this->cache[$store];
}
getStart()
public function getStart()
{
$store = $this->getStoreId('getstart');
// Try to load the data from internal storage.
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);
}
// Add the total to the internal cache.
$this->cache[$store] = $start;
return $this->cache[$store];
}