Общая информация

В Joomla! CMS существует множество различных типов полей. Поля добавляются в XML-файлы формы и имеют стандартный набор атрибутов, среди которых нередко можно встретить атрибут filter.

Из названия атрибута несложно догадаться, что он используется для фильтрации введённых пользователем данных. Этот атрибут очень важен в плане безопасности, ведь золотое правило разработчика – никогда не доверяй пользователю и тем более пользовательским данным.

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

Реализация

Фильтрация полей формы реализуется в методе filter($data, $group=null) класса JForm (/libraries/joomla/form/form.php), где:

  • $data – массив значений полей для фильтрации
  • $group – путь группы формы, разделенный точкой, по которой необходимо фильтровать поля

В методе осуществляется проход по массиву полей текущего объекта формы и для каждого значения элемента массива применяется фильтрация поля с помощью метода filterField($element, $value), где:

  • $element – поле формы, представленное в виде объекта XML-элемента класса SimpleXMLElement
  • $value – значение поля

Непосредственно фильтрация в зависимости от типа фильтра осуществляется либо с помощью класса JFilterInput, либо применяется фильтрация класса JForm, либо вызывается функция обратного вызова (callback), в которой вы можете реализовать свою собственную обработку значения поля.

Если в своем компоненте вы используете контроллеры и модели CMS, то фильтрация происходит автоматически в методе save($key = null, $urlVar = null) контроллера класса JControllerForm, который использует метод validate($form, $data, $group = null) модели класса JModelForm:

// Фильтрция и провера данных формы.
$data = $form->filter($data);

Таким образом, вам не нужно дополнительно думать о фильтрации, так как CMS всё сделает за вас. Но если вы реализуете свои собственные методы обработки входных данных, то про фильтрацию забывать не стоит. Безопасность должна быть на первом месте.

Типы фильтров

Большая часть фильтров реализована в классе JFilterInput, которым активно пользуются не только формы CMS в лице класса JForm, но также и класс JInput для фильтрации переменных запроса. Это такие типы как: int, word, cmd, html, string и другие. Подробнее о фильтрах класса JFilterInput можно прочитать в материале JInput - получение и фильтрация переменных запроса нашей документации.

Класс JForm в свою очередь предоставляет нам дополнительные типы фильтров, которые находятся в методе filterField():

  • rules – фильтр предназначен для Access Control Rules (для поля типа rules).
  • unset – ничего не делает и возвращает null.
  • raw – фильтрация не применяется (очень опасный фильтр - используйте только в самых необходимых случаях).
  • int_array – преобразует массив в массив чисел.
  • safehtml – очищает все нежелательные HTML теги и атрибуты.
  • server_utc – конвертирует дату в UTC исходя из настройки временной зоны сервера.
  • user_utc –конвертирует дату в UTC исходя из настройки временной зоны пользователя.
  • url – фильтрует все теги, которые не могут содержаться в URL, при этом протокол остается.
  • tel – фильтрует как номер телефона. Пытается сопоставить значение с некоторыми шаблонами, в противном случае возвращает строку с цифрами.

Если ни один из этих типов не найден, то происходит попытка вызвать пользовательскую функцию. Если же пользовательская функция не найдена, то для фильтрации используется класс JFilterInput.

// Проверка фильтрация обратного вызова.
if (strpos($filter, '::') !== false && is_callable(explode('::', $filter)))
{
    $return = call_user_func(explode('::', $filter), $value);
}
// Фильтровать с помощью функции обратного вызова, если она указана.
elseif (function_exists($filter))
{
    $return = call_user_func($filter, $value);
}
// Фильтровать с помощью JFilterInput. Весь HTML-код фильтруется по умолчанию.
else
{
    $return = JFilterInput::getInstance()->clean($value, $filter);
}

Вызов пользовательской функции дает возможность разработчику создать свой тип фильтра. Для этого в атрибуте filter мы задаем название класса и метода (который реализует фильтрацию) в формате filter="Class::method", либо просто указываем имя функции.

Хорошим примером такой пользовательской функции является JComponentHelper::filterText (/libraries/cms/component/helper.php), которая чаще всего используется для поля типа editor (редактор). При обработке текста она учитывает фильтры, которые указываются в общих настройках сайта во вкладке Фильтры текста.