Welcome Guest, Not a member yet? Register   Sign In
Create Your Own Hook Point
#1

[eluser]Lâm Tế[/eluser]
Q: How can I create my own hook point at a particular stage ?
There are 8 hook points are defined in CodeIgniter.php, and here is the helper to create a hook point.
Code:
if(!function_exists('call_hook'))
{
    function call_hook($hook_name)
    {
        $EXT =& load_class('Hooks');
        return $EXT->_call_hook($hook_name);
    }
}
Code:
$this->load->helper('hook');
call_hook('pre_login');

Q: How can you pass arguments to hook function ?
You want something like that.
Code:
call_hook('pre_login',$username,$password);
Modify hook_helper to pass many arguments as you want.
Code:
if(!function_exists('call_hook'))
{
    function call_hook($hook_name, &$params = null)
    {
        $args = array();
        if(isset($params)) {
            $args[] =& $params; // pass by reference to modify in hook funtion
        }
        for($a = 2; $a < func_num_args(); $a++) {
            $args[] = func_get_arg($a);
        }
        $EXT =& load_class('Hooks');
        return $EXT->_call_hook($hook_name, $args);
    }
}
Extend CI_Hook class
Code:
/**
* Extend CI_Hooks class to call hook anywhere with reference paramenters.
*
* @author lamiffvn
* @see hook_helper.php
*/
class MY_Hooks extends CI_Hooks {
    
    function MY_Hooks() {
        parent::CI_Hooks();
    }
    
    /**
     * Call Hook
     *
     * Calls a particular hook. Override CI_Hooks::_call_hook to pass paramenter directly to hook_helper.
     *
     * @see hook_helper.php
     * @access  private
     * @param   string  the hook name
     * @return  mixed
     *
     */
    function _call_hook($which, &$params = null){
        
        if ( ! $this->enabled OR ! isset($this->hooks[$which]))
        {
            return FALSE;
        }

        if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))
        {
            foreach ($this->hooks[$which] as $val)
            {
                if (!empty($params)) {
                    $val['params'] = $params; //new
                }
                $this->_run_hook($val);
            }
        }
        else
        {
            if (!empty($params)) {
                $this->hooks[$which]['params'] = $params;  //new
            }
            $this->_run_hook($this->hooks[$which]);
        }

        return TRUE;
    }
    
    /**
     * Run Hook
     *
     * Runs a particular hook. Override CI_Hooks::_run_hook to pass paramenter by reference to hook.
     *
     * @access  private
     * @param   array   the hook details
     * @return  bool
     */
    function _run_hook($data)
    {
        if ( ! is_array($data))
        {
            return FALSE;
        }

        // -----------------------------------
        // Safety - Prevents run-away loops
        // -----------------------------------

        // If the script being called happens to have the same
        // hook call within it a loop can happen

        if ($this->in_progress == TRUE)
        {
            return;
        }

        // -----------------------------------
        // Set file path
        // -----------------------------------

        if ( ! isset($data['filepath']) OR ! isset($data['filename']))
        {
            return FALSE;
        }

        $filepath = APPPATH.$data['filepath'].'/'.$data['filename'];

        if ( ! file_exists($filepath))
        {
            return FALSE;
        }

        // -----------------------------------
        // Set class/function name
        // -----------------------------------

        $class      = FALSE;
        $function   = FALSE;
        $params     = '';

        if (isset($data['class']) AND $data['class'] != '')
        {
            $class = $data['class'];
        }

        if (isset($data['function']))
        {
            $function = $data['function'];
        }

        if (isset($data['params']))
        {
            $params = $data['params'];
        }

        if ($class === FALSE AND $function === FALSE)
        {
            return FALSE;
        }

        // -----------------------------------
        // Set the in_progress flag
        // -----------------------------------

        $this->in_progress = TRUE;

        // -----------------------------------
        // Call the requested class and/or function
        // -----------------------------------

        if ($class !== FALSE)
        {
            if ( ! class_exists($class))
            {
                require($filepath);
            }

            $HOOK = new $class;
            call_user_func_array(array($HOOK,$function), $params); //edited
        }
        else
        {
            if ( ! function_exists($function))
            {
                require($filepath);
            }

            call_user_func_array($function,$params); //edited
        }

        $this->in_progress = FALSE;
        return TRUE;
    }
}

End of the world.
#2

[eluser]Phil Sturgeon[/eluser]
I just throw the following line in:

Code:
$GLOBALS['EXT']->_call_hook('post_core_controller_constructor');

It's not pretty but you can create hook points anywhere that work the same as the core ones with no extra crazy code or extended stuff.
#3

[eluser]Lâm Tế[/eluser]
Yes, I want something like WP hook do_action() and apply_filters()
#4

[eluser]jpi[/eluser]
I like when a CI guru defeats, with one line of code, dozens of lines of code by a "less advanced" person. It makes me thing there are so many possibilities with CI. This framework est quite "loose", you can do every things. Sometimes, even hacks are nice in CI Smile
#5

[eluser]Lâm Tế[/eluser]
Yep, with one line of code I can create hook points.
But any CI guru could tell me how I can pass arguments to a hook ?




Theme © iAndrew 2016 - Forum software by © MyBB