Наверняка вы сталкивались с ситуацией, когда выполнено какое-то действие и необходимо направить пользователя на страницу с полученными результатами. Например, при регистрации пользователя мы либо должны показать пользователю страницу с информацией о дальнейших действиях (послано письмо с подтверждением или можно сразу входить на сайт), либо вернуть обратно на страницу с заполненной им формой и указать, какие поля не прошли валидацию. Для работы с подобными я решил написать хэлпер.
Постановка задачи
Изначально я использовал сессию, чтобы складировать туда переменные. Однако т.к. в различных контроллерах сохранялась разная информация, запоминать которую становилось все сложнее и сложнее, возникла необходимость в систематизации принципов хранения, обработки и получения данных. Толчком в нужном направлении для меня послужил хэлпер notice из дистрибутива YurikoCMS, о которой я недавно писал. Однако он не обеспечивал всего нужного мне функционала, а хотелось мне вот чего:
- Хранение информации различного типа с возможностью выбора данных только этого типа.
- Данные из «предыдущей жизни» далее не сохраняются (т.е. неиспользованный мусор не накапливается от страницы к странице).
- Хранение данных валидации (с учетом имени поля и формированием i18n-сообщения об ошибке).
- Хранение прочих данных (например, заполненные поля анкеты, которые необходимо показать еще раз), возможность запроса конкретной записи по имени ключа (tagname).
Нет ничего приятнее, чем решить проблему самостоятельно, поэтому я сел за написание скрипта.
Что вышло в итоге.
В результате получился такой вот хэлпер (посмотреть). Использование довольно простое:
<? // где-то в контроллере, идет валидация полей пользовательской формы if (!$this->user->validate($data, TRUE)) { message::add_validation($data->errors(), "auth"); arr::remove('password', $_POST); arr::remove('password_confirm', $_POST); message::add($_POST, 'custom'); } else { message::add(Kohana::lang('auth.registration_ok'), 'success'); url::redirect(Router::uri('auth', array('method'=>'login'))); } // в шаблоне формы для ввода регистрационных данных <ul> ... <li><!-- Email field --> <?=message::render('validation', 'email')?> <label for="email"><?=Kohana::lang('auth.email')?></label> <input type="text" name="email" id="email" value="<?=message::custom('email')?>" /> </li> ... </ul> // в шаблоне для большинства страниц <div id="content"> <?message::render()?> <?=$content?> </div> |
Метод message::add() является основным методом добавления информации в хэлпер. Так как ошибки валидации, возвращаемые методом errors(), являются массивом вида $fieldname=>$rulename, для них создан метод message::add_validation(), вторым параметром которого является имя i18n-файла, в котором описаны используемые формой ресурсы. Для показа сообщений используется метод message::render(), который может выводить как сообщения конкретного типа, так и все имеющиеся сообщения (за исключением ошибок валидации и custom-данных). Ошибки валидации показываются по отдельности перед полями ввода, с помощью все того же метода message::render(). А значения полей заполняются на основе работы метода message::custom(), который пытается найти в сообщениях типа ‘custom‘ указанную переменную. Дополнительно можно использовать метод get_type(), который вернет массив записей указанного типа без использования шаблонов (т.е. без вызова render()).
При использовании получаются примерно такие сообщения (кликабельно):
Как это работает?
Для того, чтобы данные сохранялись и загружались, использованы хуки. В принципе, все аналогично Zeelot‘овскому notice, мы сохраняем данные при отправке заголовков системой или если пойман редирект, а инициализация происходит сразу после загрузки ядра фреймворка:
// в любом хуке Event::add('system.ready', array('message', 'init')); Event::add('system.send_headers', array('message', 'save')); Event::add('system.redirect', array('message', 'save')); |
В момент инициализации считывается значение конфигурации из файла config/message.php, где должно быть прописано имя переменной для сохранения в сессии (параметр ‘message_key‘). В принципе, вы можете изменить текст хэлпера, просто я не хотел жестко прописывать какое-то конкретное значение.
Исходники
Архив хэлпера. В выложенном мной файле помимо самого хэлпера лежит использовавшийся мной шаблон для вывода ошибок, а также фрагмент файла стилей (на всякий случай).
В связи с моим переходом на Ko3 предлагаю вам соответствующую версию класса.
Не могу понять, почему вот так работает правильно:
session->set(‘smth’, ‘value’);
потом get(‘smth’) вернет value
А вот при передаче переменной в значение
session->set(‘smth’, $somevar);
echo session->get(‘smth’); вернет PUBLIC
тоже самое с этой библиотекой. Помогите пожалуйста.
Разобрался . Похоже, что нельзя писать в сессию то, что передается через параметры функции)).
Теперь другая проблема. Массив не хочет храниться в сессии)). Очищается
В чем отличие от flash?
1. Возможность группировать данные по категориям (ERROR/INFO/SUCCESS/CUSTOM и т.д.), работать как с целой категорией, так и выбирать отдельные объекты.
2. Возможность хранить в CUSTOM массивы, и обращаться к отдельным их элементам через точку, например message::custom(‘user.username’);
3. Расширяемость, в конце концов С классом можно делать что угодно.
ЗЫ. Кстати, в Ko3 flash в сессиях на данный момент отсутствует.
Понятненько. Попробуем)
А КО3 по-моему вообще пока бесполезна. Столько изменений, а радости больше не стало.
Выложи, пожалуйста, новую версию хелпера
Здесь в принципе актуальная версия для Ko3. Под вторую ветку не обновлял, т.к. не использую.