Создание сайтов в Челябинске. Продвижение. Оптимизация

Разработка сайтов, поисковая оптимизация, продвижение, техническая поддержка и обслуживание вебсайтов любой сложности. Быстро, качественно и по разумной цене.

Создание компонента "Каталог" для Joomla 3 (Часть 3)

Разработка компонента для Joomla 3 с нуляВ прошлой статье мы написали класс основного контроллера и подробно разобрали функцию JController::display(). Пока что он совсем маленький, но для начала - нормально. В этой статье мы создадим класс модели JModelList и класс таблицы JTable, которые позволят нам создать список записей из таблицы базы данных. Предыдущая статья Создание класса контроллера JController.

5. Шаг - создание модели JModelList

Итак приступим к созданию модели, для нее у нас уже подготовлена папка models в структуре нашего компонента, там нужно создать файл с названием catalogue.php. Основной функцией модели является обращение к базе данных и вытаскивание из нее записей в зависимости от запроса пользователей, также в модели есть функция для хранения текущего состояния компонента в сессии. Обо всем об этом по порядку!

<?php defined('_JEXEC') or die;

class CatalogueModelCatalogue extends JModelList
{
  protected function getListQuery()
  {
    $db  = $this->getDbo();
$query = $db->getQuery(true); $query->select('c.id, c.cat_id, c.name, c.intro, c.desc, c.price, c.ordering, c.state, c.image, c.sticker, c.published, c.params'); $query->from($db->quoteName('#__catalogue_items').' AS c'); $query->select('cat.title AS category_title'); $query->join('LEFT', '#__catalogue_categories AS cat ON cat.id = c.cat_id'); $published = $this->getState('filter.state'); if (is_numeric($published)) { $query->where('c.state = '.(int) $published); } elseif ($published === '') { $query->where('(c.state IN (0, 1))'); } $categoryId = $this->getState('filter.cat_id'); if (is_numeric($categoryId)) { $query->where('c.cat_id = '.(int) $categoryId); } $published = $this->getState('filter.published'); if (is_numeric($published)) { $query->where('c.published = ' . (int) $published); } elseif ($published === '') { $query->where('(c.published = 0 OR c.published = 1)'); } $search = $this->getState('filter.search'); if (!empty($search)) { if (stripos($search, 'id:') === 0) { $query->where('c.id = '.(int) substr($search, 3)); } else { $search = $db->Quote('%'.$db->escape($search, true).'%'); $query->where('(c.name LIKE '.$search.' OR c.intro LIKE '.$search.')'); } } $orderCol = $this->state->get('list.ordering', 'ordering'); $orderDirn = $this->state->get('list.direction', 'ASC'); if ($orderCol == 'ordering') { $orderCol = 'c.name '.$orderDirn.', c.ordering'; } $query->order($db->escape($orderCol.' '.$orderDirn)); return $query; } protected function getStoreId($id = '') { $id .= ':'.$this->getState('filter.search'); $id .= ':'.$this->getState('filter.access'); $id .= ':'.$this->getState('filter.state'); $id .= ':'.$this->getState('filter.published'); $id .= ':'.$this->getState('filter.cat_id'); return parent::getStoreId($id); } public function getTable($type = 'Catalogue', $prefix = 'CatalogueTable', $config = array()) { return JTable::getInstance($type, $prefix, $config); } protected function populateState($ordering = null, $direction = null) { $app = JFactory::getApplication('administrator'); $search = $this->getUserStateFromRequest($this->context.'.filter.search', 'filter_search'); $this->setState('filter.search', $search); $state = $this->getUserStateFromRequest($this->context.'.filter.state', 'filter_state', '', 'string'); $this->setState('filter.state', $state); $access = $this->getUserStateFromRequest($this->context.'.filter.access', 'filter_access', 0, 'int'); $this->setState('filter.access', $access); $published = $this->getUserStateFromRequest($this->context.'.filter.published', 'filter_published', ''); $this->setState('filter.published', $published); $categoryId = $this->getUserStateFromRequest($this->context.'.filter.cat_id', 'filter_cat_id', ''); $this->setState('filter.cat_id', $categoryId); $id = $this->getUserStateFromRequest($this->context.'.item.id', 'id', 'int', 0); $this->setState('item.id', $id); $params = JComponentHelper::getParams('com_catalogue'); $this->setState('params', $params); parent::populateState('c.name', 'asc'); } }

1: не нуждается в комментариях;

3: Объявляем класс CatalogueModelCatalogue именно так и не как иначе. Если будет ошибка в названии ничего не получится (Fatal Error! и все);

5: Функция в которой мы составим запрос к базе данных;

7: Получаем объект базы данных и сохраняем в переменную $db;

8: Создаем объект JDataBaseQuery - это конструктор запросов функция getQuery имеет единственный параметр, который указывает на то что это должен быть новый запрос - true, если напишем false (по умолчанию) то наш запрос попадет в стек - это нужно когда делаем много INSERT чтобы сложить их в кучу, а потом выполнить за один заход, но нам это не пригодится;

10: Выполняем метод JDataBaseQuery::select() и передаем ему все поля, по которым делаем выборку из таблицы;

11: Методом JDataBaseQuery::from() указываем таблицу (не забываем про префикс #__);

12: Дальше докидываем еще немного в select (этим и удобен объект $query можно вызывать select хоть на каждое поле);

13: Тут выполняем Join чтобы получить в из таблицы категорий названия;

15 - 20: Первый фильтр - состояние state (бывает -2 - в корзине ,-1 - в архиве ,0 - не опубликовано ,1 - опубликовано) значение фильра хранится в сессии, о том как оно там очутилось обсудим позже.

22 - 25: Опять фильтр теперь по категории;

27 - 33: Теперь фильтруем по полю published (0 - не опубликовано, 1 - опубликовано)

35 - 42: Реализация поиска по имени;

45: Поле сортировки;

46: Направление сортировки

47 - 48: Небольшая плюшка - если сортировка по умолчанию (т.е. по полю ordering) то добавляем еще и поле name;

51: Применяем наши манипуляции с сортировкой с помощью JDataBaseQuery::order();

53: Возвращаем модели наш собранный запрос!

57 - 66: Функция для сохранения Stored ID в справке написано что он нужен для формирования уникального ключа (хеша) для каждого состояния модели ее сильно описывать не будем в ней просто идет формирование $id;

68 - 71: Функция getTable она возвращает объект класса JCatalogueTableCatalogue с помощью, которого можно выполнить запрос к базе и получить данные. О самом классе чуть позже.

73: Функция populateState - очень хорошая функция, которой очень не хватало в J1.5, в ней реализуется сохранение состояния модели в сессии (т.е. значение фильтров, постраничной навигации, поиска и прочих переменных, которые могут понадобиться от запроса к запросу). Каждую строку описывать смысла нет. Сделаю акцент только на функцию getUserStateFromRequest($context, $name, $default) она возвращает значение переменной, которое ищет либо в сессии либо берет из запроса и если нет ничего берет его из третьего аргумента (т.е. предусмотренное по умолчанию) - это очень удобно! А функция setState сохраняет найденное значение в сессию таким образом даже при первой загрузке модели мы уже имеем вполне определенное состояние компонента и можем прогнозировать запрос к базе.

6. Шаг - создание класса таблицы JTable

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

<?php defined('_JEXEC') or die;

class CatalogueTableCatalogue extends JTable
{
  public function __construct(&$_db)
  {
    parent::__construct('#__catalogue_items', 'id', $_db);
  }
}

Время нарисовать диаграмму что бы понять что мы сделали

MVC разработка компонента Joomla Шаг 5

Продолжение следует! Задавайте вопросы в комментариях.

Понравилась статья? Возник вопрос? Вступайте в нашу группу и смело задавайте vk.com/saity74