[modHelpers] Фильтрация, контейнер, проверка медиа
Новость для разработчиков. В библиотеку добавлено несколько новых функций:
- is_tablet()
- is_desktop()
- app()
- filter_data()
- null_if()
И ещё немного доработана функция pls()
для работы с плейсхолдерами, logout()
и parse()
.
С первыми двумя функциями, думаю, всё понятно. Это функции-детекторы текущего устройства. Раньше можно было только проверить является ли устройство мобильным или нет, используя функцию is_mobile()
. Теперь проверка полноценнее. Особенно это хорошо впишется при использовании шаблонизатора.
{if $.php.is_tablet()} // Планшет {elseif $.php.is_mobile()} // Телефон {else} // Десктоп {/if}
Функция is_mobile()
определяет и телефоны и планшеты как мобильные. Поэтому сначала нужно проверять планшеты.
Детектор устройства использует библиотеку MobileDetect. Поэтому можно использовать все её возможности. А у неё очень много полезных методов. Эта библиотека подключается как сервис через функцию app()
(о ней ниже). Поэтому обратиться к ней можно в любом месте так
$detector = app('detector'); // И дальше уже вызывать методы $detector->version('Firefox'); if ($detector->isiOS()) {} if ($detector->is('Chrome')) {}
Теперь о функции app()
. Она возвращает объект контейнера, который используется для разрешения зависимостей. В контейнере можно хранить объект, который будет один и тот же на протяжении загрузки приложения. Это так называемый синглтон (singleton). Например, в начале загрузки определяется репозиторий (репозиторий пользователей, ресурсов и т.п.), а затем в любом месте приложения к нему можно обращаться. Синглтоны часто используются как сервисы.
Основные методы:
- bind() — регистрация зависимости.
- singleton() — регистрация синглтона через имя класса или замыкание.
- instance() — регистрация уже существующего объекта в качестве синглтона.
- bound() — проверяет, определена ли указанная зависимость.
- resolved() — проверяет, создан ли объект указанной зависимости.
Работает это так:
// В плагине при инициализации MODX определяем зависимость app()->singleton('userRepo', function() use ($modx) { return users()->where(['active'=>true])->toArray(); });
И теперь в любом месте приложения можно вызвать:
$users = app('userRepo');
И получаем всегда один и тот же репозиторий. И никаких повторных запросов к базе.
Проверяем, определена ли уже зависимость:
if (!app()->bound('alias')) { app()->bind('alias', function(){...}); }
Удобно когда нужно проводить какие-нибудь однотипные манипуляции
// Инициализируем зависимость app()->bind('user', function($app, $params = array()) { if (isset($params['id'])) $user = user($params['id']); // Делаем нужные манипуляции и инициализации ... // Возвращаем объект return $user; }); ... // В любом месте приложения вызываем $user = app('user', array('id' => 5)); // получаем подготовленный объект пользователя
Про filter_data() я уже писал. Добавлю только, что можно вызывать несколько фильтров для поля (через |), а также указывать параметры у фильтров (после :).
На сегодняшний момент фильтры следующие:
- int, integer — Приводит к integer.
- string — Удаляет теги и пробелы из начала и конца строки.
- float — Приводит к float типу.
- array — Конвертирует значение в массив.
- bool, boolean — Возвращает TRUE для «1», «true», «on» и «yes». И FALSE в остальных случаях.
- alpha — Возвращает только буквенные символы из указанного значения.
- alpha_num — Возвращает только буквы и цифры.
- num — Возвращает только цифры.
- email — Удаляет все символы кроме букв, цифр и !#$%&'*+-=?^_`{|}~@.[].
- url — Удаляет все символы кроме букв, цифр и $-_.+!*'(),{}|\\^~[]`<>#%";/?:@&=.
- limit — Обрезает строку до указанного значения и добавляет в конец указанную строку. После двоеточия через запятую можно определить 2 параметра — длина строки и окончание ('limit:20,...'). Многоточие указывается по-умолчанию.
- fromJSON — Декодирует строку из JSON формата.
- toJSON — Возвращает значение в JSON формате.
- default — Возвращает значение по-умолчанию, если указанное значение не существует ('default: Значение по-умолчанию').
Кроме того можно использовать не только замыкания (анонимные функции), но и функции php (к ним же относятся и функции самой библиотеки modHelpers). Например, из важных htmlspecialchars()
.
// $_POST['list' => 'cat1, cat2, cat5'] $post = filter_data($_POST, ['list' => 'explode|trim'; // Вызываем 2 фильтра - функции php // $post['list'] = array('cat1', 'cat2', 'cat5')
Загружает объект пользователя
// $_POST = ['user' => '5'] $rules = [ 'user' => 'user', // функция modHelpers ]; $post = filter_data($_POST, $rules); // $post['user'] - объект класса modUser с id 5.
Можно использовать контейнер для хранения правил фильтрации.
// При загрузке MODX определяем зависимость app()->bind('user_rules', function() { return array( 'username' => 'string', 'fullname' => 'string', 'email' => 'email', 'user' => 'user', ); }); // Затем при фильтрации данных формы вызывать. $rules = app('user_rules'); $post = filter_data($_POST, $rules); if (is_object($user = $post['user'])) { $user->fromArray($post); $user->Profile->fromArray($post); $user->save(); }
Ну и осталась функция null_if()
. Она возвращает NULL, если переданное значение равно второму параметру. По-умолчанию, второй параметр равен пустой строке. Эта функция — задел на будущий функционал валидации данных.
Ещё пару слов про функцию logout()
. У неё появился третий параметр, определяющий нужно ли перелогиниться. Если указать TRUE, то если пользователь залогинен в админке, он будет аутентифицирован как этот пользователь. Если указать FALSE, то он так и останется гостем. Это может пригодится при тестировании — когда нужен гость, в вы залогинены в админке, и MODX автоматом аутентифицирует пользователя сайта как админа. Вот чтобы не выходить из админки можно разлогиниться с параметром FALSE.
Что касается функции parse()
. Теперь у неё 2 режима: быстрый парсинг и полный. Быстрый — для простой замены тегов.
$tpl = '<li>[[+id]]. [[+username]]</li>'; $output = ''; foreach($users as $user) { $output .= parse($tpl, $user); } $output = '<ul>' . $output . '</ul>';
А полный парсинг работает как getChunk()
для инлайн чанка. Т.е. можно указать полноценную строку с тегами чанков, сниппетов.
$tpl = 'Строка с вызовом чанка [[$chunk]].'; $output = parse($tpl, $data, true, 5);
Для полного парсинга нужно передать в третьем параметре TRUE. В четвертом можно указать количество итераций парсера. По-умолчанию, 10.
На этом всё.
Комментарии ()
Вы должны авторизоваться, чтобы оставлять комментарии.
Изучаю документацию modHelpers и столкнулся с таким моментом:
yadi.sk/i/s6jTzs573NxNUc
Согласно доков метод parent возвращает объект, с которым ожидается возможным использовать другие методы объекта, но вот поменять ему pagetitle не получается. Может я как то не правильно код написал?
Метод parent() возвращает объект xPDOObject и это его метод set().
Сейчас если заглянуть в массив плейсхолдеров там огромная куча всего, а хотелось бы видеть только то, что даёт сниппет.
Было бы не плохо такую функцию всегда под рукой держать, а так приходится либо в документацию лезть искать либо в код сниппета заглядывать и там выискивать выставление плейсхолдеров.
Примерно по такому принципу у Василия сделана обработка параметра &tpl в сниппетах pdoTools — если указан пустой параметр, то распечатывается весь массив плейсхолдеров, вот тоже самое хотелось бы иметь в чанках, что бы это было универсальное решение независимое от сниппета.
Но вот есть такой браузер, Blisk — эмулятор устройств (как мобильных так и широкоформатных), пользуюсь им примерно год. Так вот он иногда наотрез (или через раз) отказывается определять
тогда как
— нет проблем и в эмуляторе и на реальных мобильных.
Кстати, автор пишет, что планшеты являются подмножеством мобильных. Т.е. is_mobile() будет истинно и для тех и для других. Если есть возможность, проверь этот момент.
Вот примеры из документации
Для твоего случая достаточно только is_mobile().
Было еще с MobileDetect (пакетом), что он на немецких серверах (на модхосте) и на СПБ вел себя по-разному. Т.е. буквально, меняю сервер на немецкий- работает, возвращаю на СПБ — нет.
(это я опять про тот же браузер-эмулятор Blisk, на «железных» девайсах все нормально во всех случаях, но в Blisk уж очень удобно тестить варианты отображения.)
Да, за modHelpers огромное спасибо!
Прежде всего, большое человеческое спасибо вам за modHelpers.
Вопрос по filter_data() и фильтру string.
Судя по документации и https://github.com/sergant210/modHelpers/blob/70822a0d86a24507b19535a3c072a28bdda4b863/core/components/modhelpers/functions/functions.php#L1785 должен выдавать нам
но выводит, видимо, из-за https://github.com/sergant210/modHelpers/blob/70822a0d86a24507b19535a3c072a28bdda4b863/core/components/modhelpers/functions/functions.php#L2127
Так и задумано, или это ошибка?
p.s. версия modhelpers 3.7.0-pl
Чтобы не ждать новой версии, можете сами исправить. Добавьте «string» после «url» в массиве.