Changeset 651

Show
Ignore:
Timestamp:
10/04/2007 07:44:36 PM (14 months ago)
Author:
Shadowhand
Message:

A few small changes:

  • Replaced the "pre_output" Event with "output"
  • The "output" event can now load views during execution
  • Completely re-organized Bootstrap to use Event, instead function calls
  • Added hook loading support, and config/hooks.php
  • Added Event::get($name) and Event::clean($name, $callback)

More spit shine too.

Location:
trunk
Files:
1 added
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/application/config/config.php

    r648 r651  
    9696/* 
    9797| ----------------------------------------------------------------------------- 
    98 | Enable Hooks (EXPERT!) 
    99 | ----------------------------------------------------------------------------- 
    100 | 
    101 | User Guide: http://kohanaphp.com/user_guide/en/general/hooks.html 
    102 | 
    103 */ 
    104 $config['enable_hooks'] = FALSE; 
    105  
    106 /* 
    107 | ----------------------------------------------------------------------------- 
    10898| Extension Prefix 
    10999| ----------------------------------------------------------------------------- 
  • trunk/system/core/Bootstrap.php

    r644 r651  
    1414 * @since            Version 2.0 
    1515 * @filesource 
    16  */ 
    17  
    18 // ---------------------------------------------------------------------------- 
    19  
    20 /** 
    21  * Kohana Bootstrapping 
    2216 * 
    2317 * $Id$ 
     
    3731 
    3832// Load core classes 
    39 require SYSPATH.'core/Config'.EXT; 
    40 require SYSPATH.'core/Event'.EXT; 
    4133require SYSPATH.'core/Kohana'.EXT; 
    42 require SYSPATH.'core/Log'.EXT; 
    43 // Load UTF-8 compatible string functions 
    44 require SYSPATH.'core/utf8'.EXT; 
    4534 
    46 // Run Kohana's setup routine 
    47 // This registers the Kohana handlers and prepares the output buffer 
    48 Kohana::setup(); 
    49  
    50 // Run system.ready event 
    51 Event::run('system.ready'); 
     35// Run system.prepare event 
     36// This sets up Kohana's PHP hooks, output buffering, error handling, etc 
     37Event::run('system.setup'); 
    5238 
    5339// Stop base class loading benchmark 
     
    5642Benchmark::start(SYSTEM_BENCHMARK.'_system_initialization'); 
    5743 
    58 // Run Router's setup routine 
     44// Run system.ready event 
     45Event::run('system.ready'); 
     46 
     47// Run system.routing 
    5948// All routing is performed at this stage 
    60 Router::setup(); 
    61  
    62 // Run system.initialize 
    63 Event::run('system.initialize'); 
     49Event::run('system.routing'); 
    6450 
    6551// Stop system initialization benchmark 
     
    6854Benchmark::start(SYSTEM_BENCHMARK.'_controller_execution'); 
    6955 
    70 try 
    71 { 
    72         // Load the controller 
    73         Kohana::instance(); 
    74  
    75         // Run system.ready_controller 
    76         Event::run('system.ready_controller'); 
    77  
    78         /** 
    79          * @todo This needs to check for _remap and _default, as well as validating that method exists 
    80          */ 
    81         $controller = Kohana::instance(); 
    82  
    83         if (method_exists($controller, '_remap')) 
    84         { 
    85                 // Change arguments to be $method, $arguments. 
    86                 // This makes _remap capable of being a much more effecient dispatcher 
    87                 Router::$arguments = array(Router::$method, Router::$arguments); 
    88                 // Set the method to _remap 
    89                 Router::$method = '_remap'; 
    90         } 
    91         elseif (method_exists($controller, Router::$method)) 
    92         { 
    93                 (Router::$method !== 'kohana_include_view') or trigger_error 
    94                 ( 
    95                         'This method cannot be accessed directly.', 
    96                         E_USER_ERROR 
    97                 ); 
    98         } 
    99         elseif (method_exists($controller, '_default')) 
    100         { 
    101                 // Change arguments to be $method, $arguments. 
    102                 // This makes _default a much more effecient 404 handler 
    103                 Router::$arguments = array(Router::$method, Router::$arguments); 
    104                 // Set the method to _default 
    105                 Router::$method = '_default'; 
    106         } 
    107         else 
    108         { 
    109                 $controller->show_404(); 
    110         } 
    111         if (count(Router::$arguments) > 0) 
    112         { 
    113                 call_user_func_array(array(Kohana::instance(), Router::$method), Router::$arguments); 
    114         } 
    115         else 
    116         { 
    117                 call_user_func(array(Kohana::instance(), Router::$method)); 
    118         } 
    119  
    120         // Run system.post_controller 
    121         Event::run('system.post_controller'); 
    122  
    123         // Make sure that $controller is not available globally 
    124         unset($controller); 
    125 } 
    126 catch (controller_not_found $exception) 
    127 { 
    128         die('Controller not found: '.$exception); 
    129 } 
     56// Run system.execute 
     57// The controller is loaded and executed at this point 
     58Event::run('system.execute'); 
    13059 
    13160// Stop the controller execution benchmark 
    13261Benchmark::stop(SYSTEM_BENCHMARK.'_controller_execution'); 
     62 
     63// Manually flush the output buffer to allow loading views in the system.output event 
     64Kohana::display(); 
  • trunk/system/core/Event.php

    r644 r651  
    2525final class Event { 
    2626 
    27         public static $events = array(); 
     27        private static $events = array(); 
    2828 
    2929        /** 
     
    4040                        return FALSE; 
    4141 
     42                if (empty(self::$events[$name])) 
     43                        self::$events[$name] = array(); 
     44 
     45                if (in_array($callback, self::$events)) 
     46                        return FALSE; 
     47 
    4248                self::$events[$name][] = $callback; 
     49        } 
     50 
     51 
     52        /** 
     53         * Fetch events 
     54         * 
     55         * @access public 
     56         * @param  string 
     57         * @return mixed 
     58         */ 
     59        public static function get($name) 
     60        { 
     61                return empty(self::$events[$name]) ? array() : self::$events[$name]; 
     62        } 
     63 
     64        /** 
     65         * Clear an event 
     66         * 
     67         * @access public 
     68         * @param  string 
     69         * @param  callback 
     70         * @return void 
     71         */ 
     72        public static function clear($name, $callback = FALSE) 
     73        { 
     74                if ($callback == FALSE) 
     75                { 
     76                        self::$events[$name] = array(); 
     77                } 
     78                else 
     79                { 
     80                        if (isset(self::$events[$name])) 
     81                        { 
     82                                foreach(self::$events[$name] as $i => $event_callback) 
     83                                { 
     84                                        if ($callback == $event_callback) 
     85                                        { 
     86                                                unset(self::$events[$name][$i]); 
     87                                        } 
     88                                } 
     89                        } 
     90                } 
    4391        } 
    4492 
     
    5199         * @return  mixed 
    52100         */ 
    53         public static function run($name, $args = array()) 
     101        public static function run($name) 
    54102        { 
    55103                if ($name == FALSE) 
    56104                        return FALSE; 
    57105 
    58                 if (isset(self::$events[$name]) AND count(self::$events[$name])) 
     106                $args = func_get_args(); 
     107                $args = (empty($args) OR count($args) == 1) ? array() : array_slice($args, 1); 
     108 
     109                foreach(self::get($name) as $callback) 
    59110                { 
    60                         foreach(array_reverse(self::$events[$name]) as $event) 
    61                         { 
    62                                 if ($args == TRUE) 
    63                                 { 
    64                                         call_user_func_array($event, (array) $args); 
    65                                 } 
    66                                 else 
    67                                 { 
    68                                         call_user_func($event); 
    69                                 } 
    70                         } 
     111                        call_user_func_array($callback, $args); 
    71112                } 
    72113        } 
  • trunk/system/core/Kohana.php

    r650 r651  
    1616 */ 
    1717 
    18 // ---------------------------------------------------------------------------- 
     18require SYSPATH.'core/utf8'.EXT; 
     19require SYSPATH.'core/Event'.EXT; 
     20require SYSPATH.'core/Config'.EXT; 
     21require SYSPATH.'core/Log'.EXT; 
     22 
     23Event::add('system.setup', array('Kohana', 'setup')); 
    1924 
    2025/** 
     
    127132                set_exception_handler(array('Kohana', 'exception_handler')); 
    128133 
    129                 // Enable log writing if the log threshold is enabled 
    130                 (Config::item('log.threshold') > 0) and Event::add('system.shutdown', array('Log', 'write')); 
    131  
    132134                // Set shutdown handler to run the 'system.shutdown' event 
    133135                register_shutdown_function(array('Event', 'run'), 'system.shutdown'); 
     
    143145                } 
    144146 
     147                if ($hooks = Config::item('hooks.enable')) 
     148                { 
     149                        // All hooks are enabled, we must build an array of filenames 
     150                        if ( ! is_array($hooks)) 
     151                        { 
     152                                $hooks = array(); 
     153                                foreach(Config::include_paths() as $path) 
     154                                { 
     155                                        $files = glob($path.'hooks/*'.EXT); 
     156 
     157                                        if ( ! empty($files)) 
     158                                        { 
     159                                                $hooks = array_merge($hooks, $files); 
     160                                        } 
     161                                } 
     162                        } 
     163 
     164                        // Loop through all the hooks and load them 
     165                        foreach($hooks as $file) 
     166                        { 
     167                                Log::add('debug', 'Loading hook'.$file); 
     168                                include $file; 
     169                        } 
     170                } 
     171 
     172                // Enable log writing if the log threshold is enabled 
     173                if(Config::item('log.threshold') > 0) 
     174                { 
     175                        Event::add('system.shutdown', array('Log', 'write')); 
     176                } 
     177 
     178                // Enable routing 
     179                Event::add('system.routing', array('Router', 'setup')); 
     180 
     181                // Enabel loading a Kohana instance 
     182                Event::add('system.execute', array('Kohana', 'instance')); 
     183 
    145184                // Setup is complete 
    146185                $run = TRUE; 
     
    160199                if (self::$instance == FALSE) 
    161200                { 
    162                         require (Router::$directory.Router::$controller.EXT); 
     201                        // Run system.pre_controller 
     202                        Event::run('system.pre_controller'); 
     203 
     204                        // Include the Controller file 
     205                        require Router::$directory.Router::$controller.EXT; 
    163206 
    164207                        // Set controller class name 
    165208                        $controller = ucfirst(Router::$controller).'_Controller'; 
    166209 
    167                         // Load the controller 
    168                         $controller = new $controller(); 
     210                        try 
     211                        { 
     212                                // Load the controller 
     213                                $controller = new $controller(); 
     214                        } 
     215                        catch (Kohana_Exception $exception) 
     216                        { 
     217                                Kohana::show_404(); 
     218                                return; 
     219                        } 
     220 
     221                        if (method_exists($controller, '_remap')) 
     222                        { 
     223                                // Change arguments to be $method, $arguments. 
     224                                // This makes _remap capable of being a much more effecient dispatcher 
     225                                Router::$arguments = array(Router::$method, Router::$arguments); 
     226                                // Set the method to _remap 
     227                                Router::$method = '_remap'; 
     228                        } 
     229                        elseif (method_exists($controller, Router::$method)) 
     230                        { 
     231                                (Router::$method !== 'kohana_include_view') or trigger_error 
     232                                ( 
     233                                        'This method cannot be accessed directly.', 
     234                                        E_USER_ERROR 
     235                                ); 
     236                        } 
     237                        elseif (method_exists($controller, '_default')) 
     238                        { 
     239                                // Change arguments to be $method, $arguments. 
     240                                // This makes _default a much more effecient 404 handler 
     241                                Router::$arguments = array(Router::$method, Router::$arguments); 
     242                                // Set the method to _default 
     243                                Router::$method = '_default'; 
     244                        } 
     245                        else 
     246                        { 
     247                                $controller->show_404(); 
     248                        } 
     249                        if (count(Router::$arguments) > 0) 
     250                        { 
     251                                call_user_func_array(array(Kohana::instance(), Router::$method), Router::$arguments); 
     252                        } 
     253                        else 
     254                        { 
     255                                call_user_func(array(Kohana::instance(), Router::$method)); 
     256                        } 
     257 
     258                        // Run system.pre_controller 
     259                        Event::run('system.post_controller'); 
    169260                } 
    170261 
     
    184275                $memory = function_exists('memory_get_usage') ? (memory_get_usage() / 1024 / 1024) : 0; 
    185276 
    186                 // Bind the output to this output 
    187                 self::$output =& $output; 
    188  
    189                 // Run the pre_output event 
    190                 // -------------------------------------------------------------------- 
    191                 // This can be used for functions that require completion before headers 
    192                 // are sent. One example is cookies, which are sent with the headers, 
    193                 // and will trigger errors if you try to set them after headers. 
    194                 // -------------------------------------------------------------------- 
    195                 Event::run('system.pre_output'); 
    196  
    197277                // Replace the global template variables 
    198                 self::$output = str_replace( 
     278                $output = str_replace( 
    199279                        array 
    200280                        ( 
     
    209289                                number_format($memory, 2) 
    210290                        ), 
    211                         self::$output 
     291                        $output 
    212292                ); 
    213293 
     294                self::$output = $output; 
     295 
    214296                // Return the final output 
    215                 return self::$output; 
     297                return $output; 
     298        } 
     299 
     300        public static function display() 
     301        { 
     302                // This will flush the Kohana buffer, which sets self::$output 
     303                ob_end_clean(); 
     304 
     305                // Run the output event 
     306                // -------------------------------------------------------------------- 
     307                // This can be used for functions that require completion before headers 
     308                // are sent. One example is cookies, which are sent with the headers, 
     309                // and will trigger errors if you try to set them after headers. 
     310                // -------------------------------------------------------------------- 
     311                Event::run('system.output'); 
     312 
     313                print self::$output; 
    216314        } 
    217315 
     
    289387                        $exception->getLine() 
    290388                ); 
     389        } 
     390 
     391        public static function show_404() 
     392        { 
     393                $message = Kohana::lang('core.page_not_found', '/'.Router::$current_uri.Config::item('core.url_suffix').Router::$query_string); 
     394 
     395                // Log the error 
     396                Log::add('file_not_found', $message); 
     397 
     398                if (ob_get_level() > self::$buffer_level) 
     399                { 
     400                        // Flush the entire buffer here, to ensure the error is displayed 
     401                        while(ob_get_level() > self::$buffer_level) ob_end_clean(); 
     402                } 
     403 
     404                // Clear out the output buffer 
     405                ob_clean(); 
     406 
     407                // Send the 404 header 
     408                header('HTTP/1.1 404 File Not Found'); 
     409 
     410                // Load the error page 
     411                include self::find_file('views', 'kohana_404'); 
     412 
     413                // Display the buffer and exit 
     414                ob_end_flush(); 
     415                exit; 
    291416        } 
    292417 
     
    504629        } 
    505630 
    506         /** 
    507          * Hook Loader 
    508          * 
    509          * @access public 
    510          * @param  string 
    511          * @return void 
    512          */ 
    513         public static function load_hook($name) 
    514         { 
    515                 if (Config::item('core.enable_hooks') AND $hook = self::find_file('hooks', $name)) 
    516                 { 
    517                         require $hook; 
    518                 } 
    519         } 
    520  
    521         public static function callback($callback, $params = FALSE) 
    522         { 
    523                 if (is_string($callback)) 
    524                 { 
    525                         if ($params == FALSE) 
    526                         { 
    527                                 return $callback(); 
    528                         } 
    529                         elseif (is_array($params)) 
    530                         { 
    531                                 return call_user_func_array($callback, $params); 
    532                         } 
    533                         else 
    534                         { 
    535                                 return $callback($params); 
    536                         } 
    537                 } 
    538                 else 
    539                 { 
    540                         if (is_array($params) AND $params != FALSE) 
    541                         { 
    542                                 return call_user_func_array($callback, $params); 
    543                         } 
    544                         else 
    545                         { 
    546                                 return call_user_func($callback); 
    547                         } 
    548                 } 
    549         } 
    550  
    551         public static function show_404() 
    552         { 
    553                 $message = Kohana::lang('core.page_not_found', '/'.Router::$current_uri.Config::item('core.url_suffix').Router::$query_string); 
    554  
    555                 // Log the error 
    556                 Log::add('file_not_found', $message); 
    557  
    558                 // Flush the entire buffer here, to ensure the error is displayed 
    559                 while(ob_get_level()) ob_end_clean(); 
    560  
    561                 // Re-start the buffer 
    562                 ob_start(array('Kohana', 'output')); 
    563  
    564                 // Send the 404 header 
    565                 header('HTTP/1.1 404 File Not Found'); 
    566  
    567                 // Load the error page 
    568                 include self::find_file('views', 'kohana_404'); 
    569  
    570                 // Display the buffer and exit 
    571                 ob_end_flush(); 
    572                 exit; 
    573         } 
    574  
    575631} // End Kohana class 
    576632 
  • trunk/system/libraries/Session.php

    r647 r651  
    9393 
    9494                // Close the session just before flushing the output buffer 
    95                 Event::add('system.pre_output', 'session_write_close'); 
     95                Event::add('system.output', 'session_write_close'); 
    9696 
    9797                Log::add('debug', 'Session Class Initialized');