Создание собственных хуков в CodeIgniter

О том как работать с системными хуками, достаточно подробно написано в документации фреймворка, и сейчас разговор пойдет не о них. Что же такое хуки в принципе и зачем они нужны? Расскажу сразу на примере. Допустим требуется написать фото-галерею, причем некоторый функционал будет существовать как дополнительный, например создание миниатюр. Под дополнительным функционалом я подразумеваю, что приложение должно уметь работать и без него, а при его добавлении, не должно производиться никаких действий с кодом приложения.

Итого, допустим есть некий скрипт который удаляет фото с сервера. В общем виде алгоритм удаления примерно следующий:

  • удаляем информацию об изображении из базы данных
  • удаляем изображения с диска
  • удаляем информацию об изображении отовсюду где она есть

С первыми двумя пунктами вроде все понятно, а вот третий звучит достаточно абстрактно. Гибкое приложение подразумевает модульность. Когда я пишу скрипт удаления изображения, то не хочу думать о том, а какую информацию еще надо удалить и откуда: созданы ли десятки миниатюр в разном размере, или где-то считается количество просмотров картинки... Может быть десяток дополнительных скриптов, которые используют базу картинок, и в каждом из них нужно удалить информацию.

Учитывая, что скрипту удаления заранее не известно, какие модули(модели) в системе хотят получать информацию о событии удаления изображения, очевидно что эту информацию нужно получать из конфигурации приложения.

В СodeIgniter уже существует система событий (хуков), правда разработчики её спрятали как можно дальше. Наверное чтобы никто не писал гибких приложений, а вдруг получиться лучше чем их детище Expression Engine. Я про то, что в официальной документации фреймворка нигде не написано как создавать свои хуки, и наводит на размышление почему класс Hooks не доступен как свойство контроллера, аналогично классам Input, Config, и др.

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

Для решения поставленных задач я предлагаю воспользоваться следующим хелпером:

if (function_exists('hook') === FALSE)
{
    function hook($name, $params = array())
    {
        $EXT = & load_class('Hooks');
    
        if ($params != FALSE)
        {
			if (isset($EXT->hooks[$name]) === TRUE)
			{
				if (isset($EXT->hooks[$name][0]) === TRUE)
				{
					foreach($EXT->hooks[$name] as $k => $v)
					{
						foreach($params as $key => $value)
						{
							$EXT->hooks[$name][$k]['params'][$key] = $value;
						}
					}
				}
				else
				{
					foreach($params as $key => $value)
					{
						$EXT->hooks[$name]['params'][$key] = $value;
					}
				}
			}
        }
        
        $EXT->_call_hook($name);
    }
}

Теперь после удаления файла изображения с диска и из базы данных я вызываю функцию hook:


hook('on_picture_delete', array('picture_id' => $picture_id));

Настраивать и обрабатывать такое событие точно также как и системные события фреймворка, об этом подробно написано в документации.

Добавление комментария

Имя*:
E-mail*:
Личный сайт:
Текст комментария*:
Проверочный код*: