В 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];

}