В phpBB имеются четыре «расширяемые» (hookable) функции: phpbb_user_session_handler(), append_sid(), $template->display(), exit_handler(). С помощью хуков мы можем добавлять в эти функции любой нужный нам код. Кроме того, любую написанную нами новую функцию мы тоже можем сделать расширяемой. Из этого списка наиболее интересна функция $template->display().
Пример простейшего хука.
Предположим, мы хотим добавить в шапку форума новую ссылку, причём сделать это по всем правилам, с применением функции append_sid(). Обычно это делается правкой файла includes/functions.php. Но можно обойтись без правок. Создаём файл includes/hooks/hook_links.php такого содержания:
<?php function gen_links() { global $phpbb_root_path, $phpEx, $template; $template->assign_vars(array( 'U_NEW_LINK' => append_sid("{$phpbb_root_path}link.$phpEx") )); } $phpbb_hook->register(array('template', 'display'), 'gen_links'); ?>
Теперь мы можем использовать переменную {U_NEW_LINK} в любом шаблоне. А если в дальнейшем нам понадобятся новые ссылки (или другие глобальные шаблонные переменные), мы их будем добавлять в этот же файл.
Пример посложнее — с подключением языкового файла.
1. Создаём файл includes/hooks/hook_links.php:
<?php function gen_links() { global $phpbb_root_path, $phpEx, $template, $user; $user->add_lang('mods/links'); $template->assign_vars(array( 'U_NEW_LINK' => append_sid("{$phpbb_root_path}link.$phpEx") )); } $phpbb_hook->register(array('template', 'display'), 'gen_links'); ?>
2. Создаём файл language/ru/mods/links.php:
<?php $lang = array_merge($lang, array( 'NEW_LINK' => 'Новая ссылка' )); ?>
3. Используем новые переменные в HTML-шаблоне — к примеру, в overall_header.html:
<a href="/{U_NEW_LINK}">{L_NEW_LINK}</a>
4. Очищаем кэш форума. Видим в браузере такой результат:
<a href="/./link.php">Новая ссылка</a>
И впредь все новые языковые переменные, которые нам когда-либо понадобятся, мы сможем добавлять в файл language/ru/mods/links.php.
Третий пример: вмешиваемся в тексты сообщений.
На наших форумах описан способ удаления множественных знаков препинания (!!!!!!, ?????????, :)))))) и тому подобных) из сообщений. Попробуем сделать то же самое, но с помощью хука. Для этого создаём файл includes/hooks/hook_punctuation.php следующего содержания:
<?php function anti_shkolota() { global $template; if (isset($template->_tpldata['postrow'])) { // Применяем функцию do_replace() к каждому члену массива postrow, содержащего тексты сообщений array_walk($template->_tpldata['postrow'], 'do_replace'); } } function do_replace(&$item) { // Составляем список знаков препинания $list = array('.', '?', '!', '(', ')'); // Ищем в сообщениях множественные знаки препинания и заменяем их на одиночные $item['MESSAGE'] = preg_replace(array_map(create_function('$key', 'return "#" . preg_quote($key) . "{2,}#";'), $list), $list, $item['MESSAGE']); } // Регистрируем хук $phpbb_hook->register(array('template', 'display'), 'anti_shkolota'); ?>
Далее очищаем кэш и видим результат:
Итак, мы ввели новую функцию и подключили новые переменные, в том числе и языковые, не изменив ни единой строчки в PHP-файлах форума.