В 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-файлах форума.
