Комментарии

Модель в CMS Joomla 2.5
( 2 Голосов )

В предыдущих статьях сайта был рассмотрен исходный код, в котором из модели вызывались методы getState(), getltems(), getCategory() и getPagination(). Эта модель определяется в классе JoomproSubsModelCategory из файла models/category.php. Рассмотрим его исходный код, первая часть которого приведена ниже.

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

/** * Модель для компонента Joomprosubs  * @package Joomla.Site * @subpackage com_joomprosubs */
class JoomprosubsModelCategory extends JModelList {
/** * Данные для  элементов категории * @var  array
*/
protected $_item = null;
/* * Конструктор * @param array   * Дополнительный ассоциативный массив с параметрами настройки модели. * @see JController
*/
public function construct($config = array()) { if (empty($config['filter_fields'])) { $config['filter_fields'] = array( 'id', 'a.id', 'title', 'a.title', 'g.title', 'group_title', 'duration', 'a.duration' >; } parent:: construct($config); }

Рассматриваемый здесь класс модели расширяет класс JModelList, который, в свою очередь, расширяет класс JModel. Следует иметь в виду, что метод getState () наследуется из класса JModelAgetPagination () — из класса JModelList. Кроме того, в классе модели импортируется класс JCategories, используемый в методе getCategory (). В нем также определяется поле $_item, используемое для хранения объекта категории. В конструкторе данного класса создается массив полей фильтров, предназначенных для проверки достоверности данных упорядочения столбцов. После этого вызывается конструктор родительского класса.

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

protected function getListQuery() {
$user = JFactory:igetUser ();
$groups  =  implode(',',   $user->getAuthorisedViewLevels());

// создать  новый объект  запроса
$db =  $this->getDbo(); $query =  $db->getQuery(true);
//  выбрать  требуемые  поля из категорий $query->select($this->getState('list.select', 'a.*')); $query->select('g.title as  group_title'); $query->from($db->quoteName('# joompro_subscriptions').'   AS  a');
//  осуществить  соединение по  группам,   чтобы получить  название  группы $query->join('LEFT',   $db->quoteName('# usergroups').'   AS  g ON a.group_id = g.id'); $query->where('a.access IN ('.$groups.')');
// отфильтровать по категории if ($categoryId = $this->getState('category.id')) { $query->where('a.catid = '.(int) $categoryId); $query->join('LEFT', $db->quoteName('# categories').' AS с ON c.id = a.catid'); $query->where('c.access  IN   ('.$groups.') ');
//  отфильтровать  по опубликованной категории $cpublished = $this->getState('filter.c.published'); if (is_numericRepublished)) { $query->where('c.published = '.(int)   $cpublished);

В данном методе формируется запрос на компоновку списка. В этот запрос включают
ся все столбцы из таблицы # joompro_subscriptions и заголовок из таблицы групп

пользователей. Подписки включаются только в ту группу, к которой пользователю разрешен доступ, а затем они фильтруются по идентификатору категории и ее состоянию "опубликовано".

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

//  отфильтровать  по  состоянию
$state =  $this->getState('filter.state');
if (is  numeric($state)) {
$query->where('a.published = '.(int) $state); }

// отфильтровать по критериям поиска if ($this->getState('list.filter') != '') { $filter = JString::strtolower($this->getState('list.filter')); $filter = $db->quote('%'.$filter.'%', true); $query->where('a.title LIKE ' . $filter); }
// отфильтровать по начальной и конечной датам $nullDate = $db->quote($db->getNullDate{)); $nowDate = $db->quote(JFactory:rgetDate()->toSQL()); if ($this->getState('filter.publish_date')){ $query->where('(a.publish_up = ' . $nullDate . '>0R a.publish_up <= ' . $nowDate . ')'); $query->where('(a.publish_down = ' . $nullDate . ' ^>0R a.publish_down >= ' . $nowDate . ')'); }
// добавить оператор упорядочения списка $query->order($db->getEscaped($this->getState('list.ordering', Va.title')) . '.$db->getEscaped($this->getState('list.direction', 'ASC'))); return $query; }

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

Фильтр списка представляет собой текст, вводимый пользователем для фильтрации подписок по списку. В частности, пользователь может ввести текст "Chevy" ("Шевроле"), чтобы отобразить только те подписки, в названиях которых присутствует введенный текст. Этот текст вводится в запрос SQL, что требует особого внимания, чтобы отсеять любой злонамеренный код, вносимый в данный запрос. И делается это в методе quote (). Передавая этому методу логическое значение true в качестве второго аргумента, мы предписываем ему выполнить метод escape () по первому аргументу. В итоге будут экранированы любые специальные символы, которые могли быть использованы для внесения злонамеренного кода в запрос SQL.

Далее следует метод populateState (), исходный код которого приведен ниже.

protected function populateState($ordering = null,   $direction = null) {
//  инициализировать  переменные
$app = JFactory:tgetApplication();
$params = JComponentHelper::getParams('com_joomprosubs');

//  представить  сведения о состоянии списков $limit =  $app->getUserStateFromRequest('global.list.limit', 'limit', $app->getCfg('list_limit')); $this->setState('list.limit', $limit); $limitstart = JRequest:rgetVar('limitstart', 0, '', 'int'); $this->setState('list.start', $limitstart); $orderCol = JRequest::getCmd('filter_order', 'title'); if (!in_array($orderCol, $this->filter_fields)) { $orderCol = 'ordering'; } $this->setState('list.ordering', $orderCol); $listOrder = Request: :getCmd (' filter_order_Dir', *ASC); if (!in_array(strtoupper($listOrder), array ('ASC, 'DESC, ''))) { $listOrder = 'ASC; } $this->setState('list.direction', $listOrder); $this->setState(* list.filter', JRequest::getString( V filter-search')); $$id = JRequest::getlnt('id', 0) ; $this->setState('category.id', $id) ; $user = JFactory::getUser() ; if   ((!$user->authorise('core.edit.state', 'com_joomprosubs'))   && > (!$user->authorise('core.edit', 'com_joomprosubs'))){
//  ограничить  опубликованными подписками для  тех,   кому не разрешено редактировать  подписки или их состояние $this->setState('filter.state', 1) ;
//  отфильтровать  по начальной и конечной датам $this->setState('filter.publish_date',   true); } }

В этом методе устанавливаются поля объекта состояния на основании переменной запроса. Для получения ограничения, накладываемого на количество элементов, отображаемых списком на странице, вызывается метод getUserStateFromRequest (). Соответствующее значение считывается из объекта текущего сеанса работы. Используя этот метод, можно сохранить значение в текущем сеансе работы и тем самым запомнить то, что пользователь указал для данного экрана.

Далее получается начало накладываемого ограничения, т.е. то место в базе данных, откуда следует начинать листание длинного списка. Для того чтобы гарантировать получение целочисленного значения, вызывается метод getInt () из класса JRequest.

Затем получаются данные упорядочения столбцов и его направления. Следует иметь в виду, что для проверки достоверности данных упорядочения столбцов используется поле filter_fields, созданное в конструкторе класса модели. А достоверность данных о направлении упорядочения проверяется по критерию ASC (По восходящей) или DESC (По нисходящей).

После этого устанавливается поле list, filter, исходя из данных, введенных пользователем для фильтрации списка. Это место потенциальной уязвимости прикладного кода.

Ведь пользователь может ввести в данном поле любую символьную строку, а в методе getString () проверяется лишь, действительно ли введенная строка является символьной, но не отсеивается злонамеренный код. Именно поэтому при формировании запроса вызывается метод $db->quote ().

Далее из запроса извлекается идентификатор категории, которая устанавливается в соответствующее состояние. И наконец, если пользователю не разрешено редактировать состояние, он может лишь просматривать опубликованные элементы подписки.

И последним в рассматриваемом здесь файле следует метод getCategory (). Ниже приведен его исходный код.

public function getCategory() {
if (!is_object ($this->_item)) {
$categories = JCategories::getlnstance('Joomprosubs');
$this->_item = $categories->get($this->getState('category.id', 'root'));
return  $this->_item; } }  
//  конец класса



В этом методе объект категории просто получается по ее идентификатору. Следует, однако, иметь в виду, что это делается лишь один раз, а результат сохраняется в поле $_item. Если этот объект потребуется еще раз, его достаточно извлечь из данного поля.

 


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


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