Комментарии

Модель диспетчера в CMS Joomla 2.5
( 0 Голосов )

В методе display () текущего представления из модели вызываются следующие три метода: getState (), getltems () и getPagination (). Модель для этого представления находится в классе JoomproSubsModelSubManager из файла models/submanager.php. Ниже приведен исходный код из первой части этого файла.

defined('_JEXEC') or die;
jimport('joomla.application.component.modellist');

/** * Методы, поддерживающие список записей в модели диспетчера подписок. */ class JoomproSubsModelSubManager extends JModelList { /** * Конструктор класса. * @param array Дополнительный ассоциативный массив с параметрами настройки. * @see  JController * @since  2.5 */   function construct($config = array()) { if (empty($config['filter_fields'])) { $config['filter_fields'] = array( 'id', 'a.id', 'title', 'a.title', 'alias', 'a.alias', 'checked_out', 'a.checked_out', 'checked_out_time', ' a. checked_out__time', 'catid', 'a.catid', 'category_title', 'published', 'a. published ', 'access', 'a.access', 'access_level', 'created', 'a.created', 'created_by', 'a.created_by', 'publish_up', 'a.publish_up', 'publish_down', 'a.publish_down', 'group_title', 'g.title', 'duration', 'a.duration' ); } parent:: construct($config) ; }

Как и в компоненте Weblinks, класс этой модели расширяет класс JModelList. В его конструкторе сначала создается массив достоверных полей фильтрации, а затем вызывается конструктор родительского класса. Напомним, что массив 'filter_ fields' позволяет организовать защиту от умышленного внесения запросов SQL, отфильтровывая недостоверные имена столбцов в части запроса, определяющей упорядочение данных, извлекаемых из таблицы базы данных, с помощью оператора ORDER BY. Если злоумышленник попытается внедрить какой-нибудь код SQL в заполняемую форму или формируемый URL, этот злонамеренный код будет отсеян, поскольку он не совпадает с действительными значениями в данном массиве.

Далее в рассматриваемой здесь модели диспетчера определяется метод populate-State (). Ниже приведен исходный код этого метода.

/**
* Метод для автоматического заполнения состояния модели.
* Примечание: вызов метода getStateO в этом методе приведет к рекурсии.
*/

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); $accessld =  $this->getUserStateFromRequest($this->context . ' .filter.access', 'filter_access', null, 'int'); $this->setState('filter.access', $accessld); $published =  $this->getUserStateFromRequest($this->context . ' .filter.state', 'filter_published', '', 'string'); $this->setState('filter.state', $published); $categoryId =  $this->getUserStateFromRequest($this->context . '.filter.category_id', 'filter_category_id', ''); $this->setState('filter.category_id', $categoryId);
// загрузить параметры $params = JComponentHelper::getParams('com_joomprosubs'); $this->setState('params',   $params);
// представить списком сведения о состоянии модели
parent::populateState('a.title', *asc') ;}

Напомним, что в рассматриваемом здесь диспетчере имеются фильтры для поля поиска, состояния "опубликовано", категории и уровня доступа. В данном методе различные переменные состояния извлекаются из запроса и сохраняются в поле состояния модели. Кроме того, сохраняются параметры компонента. Затем из родительского класса вызывается метод populateState (), где на представленные списком сведения о состоянии накладываются ограничения и вводятся начальные ограничительные значения для листания списка. А для проверки достоверности упорядочиваемых данных используется массив 'filter_fields', созданный ранее в конструкторе класса данной модели.

Далее в рассматриваемой здесь модели диспетчера определяется метод getStoreld (). Ниже приведен исходный код этого метода.

/*
* Метод для получения идентификатора сохранения, исходя из состояния конфигурации модели. 
* Это необходимо потому, что данная модель используется в компоненте и различных модулях, где могут потребоваться разные наборы данных или предъявлены разные требования к упорядочению.
* @param  string $id Префикс идентификатора сохранения.
* @return string Идентификатор сохранения.
*/
protected function getStoreld($id = '') {

// скомпилировать идентификатор сохранения $id.= $id.= $id.= $id.= $this->getState('filter.search'); $this->getState('filter.access'); $this->getState('filter.state'); $this->getState('filter.category_id'); return parent::getStore!d($id);

Напомним, что этот метод служит для создания однозначного ключа, предназначенного для кешируемого варианта списка элементов содержимого, объекта запроса, общего подсчета или разбиения на страницы. В данном случае однозначность списка элементов содержимого определяется из сочетания четырех доступных для использования фильтров и начала, ограничения, упорядочения и направления для упорядочения, причем четыре последних критерия вводятся в родительском методе get Store ID (), а полученный результат преобразуется в хеш-значение с помощью функции md5 () и затем сохраняется. Если далее отображается точно такой же экран, как и сохраненный в оперативной памяти, то, используя его сохраненную копию, можно сэкономить немного времени на обработку. Ведь большая часть этой обработки выполняется в классе JModelList, а следовательно, остается лишь добавить в код метод getStoreld (), включающий все возможные значения фильтров.

И последним в рассматриваемой здесь модели диспетчера определяется метод getListQuery (). Ниже приведен исходный код этого метода.

/**
* Формирует запрос SQL на загрузку данных списком.
* @return JDatabaseQuery
*/
protected function getListQuery() {

// создать новый объект запроса $db = $this->getDbo(); $query = $db->getQuery(true);
// выбрать требующиеся поля из таблицы $query->select('а.*') ; $query->from($db->quoteName('#joompro_subscriptions').' AS a');
// соединить для выбора среди пользователей того, кто снял подписку с регистрации (заблокировал ее для редактирования) $query->select('uc.name AS editor'); $query->j oin('LEFT', $db->quoteName('#users') .* AS ON uc.id=a.checked_out');
// соединить по группам пользователей, чтобы получить имя группы $query->select('g.title as group_title'); $query->join('LEFT', $db->quoteName('#usergroups').' AS '>0N a.group_id = g.id');
// соединить по категориям $query->select('с.title AS category_title'); $query->join('LEFT', $db->quoteName('# categories').' AS '. id = a.catid') ;
// отфильтровать по уровню доступа if ($access = $this->getState('filter.access')) {$query->where('a.access = '.(int) $access); }
// отфильтровать по состоянию "опубликовано" $published = $this->getState('filter.state'); if (is_numeric($published)) { $query->where('a.published = '.(int) $published); } else if ($published === 1) { $query->where('(a.published IN (0, 1))');
// отфильтровать по категории $categoryId = $this->getState{'filter.category_id'); if (is_numeric($categoryId)) { $query->where('a.catid = '.(int) $categoryId); }
// отфильтровать по критерию поиска в названии $search = $this->getState('filter.search'); if (!empty($search)) { if (stripos($search, 'id:') === 0) { $query->where('a.id = '.(int) substr($search, 3)); } else { $search = $db->Quote('%'.$db->getEscaped($search, true).'%'); $query->where('(a.title LIKE '.$search.' bOR  a.alias LIKE '.$search.')'); } }
// добавить оператор упорядочения списка $orderCol = $this->state->get('list.ordering'); $orderDirn = $this->state->get('list.direction'); $query->order($db->getEscaped($orderCol.' '.$orderDirn)); return $query;

В данном методе формируется запрос на выборку строк из таблицы базы данных. С этой целью создается новый объект типа JDatabaseQuery при вызове метода $db->getQuery (true). Следует особо отметить, что, начиная с версии Joomla 1.7, где используется платформа версии 11.1, класс JDatabaseQuery объявляется как абстрактный. Это означает, что получить экземпляр его объекта нельзя, а следовательно, и создать новый объект запроса, вызвав конструктор данного класса в операторе new JDatabaseQuery (). Но, вызывая метод $db->getQuery (true), можно все же создать объект типа JDatabaseQuery, характерный для конкретного типа базы данных (например, JDatabaseQueryMySQLi). Именно такой объект и требуется в Joomla для работы с разнотипными базами данных.

Далее в рассматриваемом здесь методе выбираются все столбцы из таблицы (в данном случае — #joompro_subscriptions) с помощью синтаксической конструкции ' а. * ' языка SQL. После этого осуществляется соединение с таблицей # users, чтобы получить имя пользователя, снявшего подписку с регистрации для редактирования (т.е. заблокировавшего ее от правки другими пользователями). Соединяя таблицы #usergroups и #categories, можно отобразить названия группы пользователей и категории для подписок.

Особое внимание следует обратить на использование префикса # в запросах. Ведь заранее неизвестно, префикс какой именно таблицы будет использоваться на веб-сайте. Поэтому нужный префикс подставляется в Joomla перед тем, как отправлять запрос в базу данных. Следует также заметить, что имена таблиц указываются в качестве аргумента при вызове метода $db->quoteName (). Это дает возможность использовать разные символы кавычек для экранирования имен таблиц и столбцов при обращении к разнотипным базам данных. Например, в базе данных MySQL для этой цели используются обратные кавычки ("). Более подробно этот вопрос рассматривался ранее на нашем сайте.

Все соединения являются левыми (LEFT), а это означает, что строка из главной таблицы, #joompro_subscriptions, будет отображаться даже в том случае, если не найде
но ни одной совпадающей строки ни в одной из упомянутых выше таблиц. Но в данном случае этого вообще не произойдет, поскольку категория, пользователь и группа пользователей должны быть всегда достоверными.

Далее проверяются уровень доступа, состояние "опубликовано", категория и фильтры поиска. Если все эти критерии поиска заданы, то в запрос базы данных вводится оператор WHERE с целью наложить определенные ограничения на результаты запроса. Следует заметить, что для поиска по идентификационному номеру имеется специальный код, в котором проверяется, совпадают ли три первых символа, введенных в поле поиска, с символьной строкой "id: ". Если они совпадают, то осуществляется поиск на совпадение с целочисленным идентификатором. В противном случае предполагается, что введенный текст частично совпадает с искомым названием. И наконец, в запрос вводится упорядочение получаемых в итоге данных в соответствии со значениями, определяющими само упорядочение и его направление в переменных состояния.


Понравился материал? Пригодилась информация? Плюсани в социалки!


 
Похожие новости