Changeset 3160

Show
Ignore:
Timestamp:
07/20/2008 11:03:48 AM (5 months ago)
Author:
Shadowhand
Message:

WARNING! This change makes a massive break in backwards compatibility!

Changes to core:

  • Config core class merged into Kohana: config, config_load, include_paths, config_clear
  • Log core class merged into Kohana: log, log_save, log_directory
  • Kohana::locale and l10n files removed
  • log config file removed, log_threshold and log_directory moved to core configuration
  • Kohana::cache and Kohana::cache_save now require a lifetime to be passed
  • Kohana::show_error removed
  • Optimizations applied to Kohana:: methods
Location:
trunk/system
Files:
4 removed
38 modified

Legend:

Unmodified
Added
Removed
  • trunk/system/core/Bootstrap.php

    r2627 r3160  
    3131// Load core files 
    3232require SYSPATH.'core/utf8'.EXT; 
    33 require SYSPATH.'core/Config'.EXT; 
    34 require SYSPATH.'core/Log'.EXT; 
    3533require SYSPATH.'core/Event'.EXT; 
    3634require SYSPATH.'core/Kohana'.EXT; 
  • trunk/system/core/Kohana.php

    r3152 r3160  
    1010 * @license    http://kohanaphp.com/license.html 
    1111 */ 
    12 class Kohana { 
     12final class Kohana { 
    1313 
    1414        // The singleton instance of the controller 
     
    1616 
    1717        // Output buffering level 
    18         private static $buffer_level = 0; 
     18        private static $buffer_level; 
    1919 
    2020        // Will be set to TRUE when an exception is caught 
     
    2525 
    2626        // The current user agent 
    27         public static $user_agent = ''; 
     27        public static $user_agent; 
    2828 
    2929        // The current locale 
    30         public static $locale = ''; 
    31  
    32         // File path cache 
    33         private static $paths; 
    34         private static $paths_changed = FALSE; 
     30        public static $locale; 
     31 
     32        // Configuration 
     33        private static $configuration; 
     34 
     35        // Include paths 
     36        private static $include_paths; 
     37 
     38        // Logged messages 
     39        private static $log; 
     40 
     41        // Log levels 
     42        private static $log_levels = array 
     43        ( 
     44                'error' => 1, 
     45                'alert' => 2, 
     46                'info'  => 3, 
     47                'debug' => 4, 
     48        ); 
     49 
     50        // Internal caches and write status 
     51        private static $internal_cache = array(); 
     52        private static $write_cache; 
    3553 
    3654        /** 
     
    4866         * @return  void 
    4967         */ 
    50         final public static function setup() 
     68        public static function setup() 
    5169        { 
    5270                static $run; 
     
    7694                if (function_exists('date_default_timezone_set')) 
    7795                { 
    78                         $timezone = Config::item('locale.timezone'); 
     96                        $timezone = Kohana::config('locale.timezone'); 
    7997 
    8098                        // Set default timezone, due to increased validation of date settings 
     
    87105 
    88106                // Start output buffering 
    89                 ob_start(array('Kohana', 'output_buffer')); 
     107                ob_start(array(__CLASS__, 'output_buffer')); 
    90108 
    91109                // Save buffering level 
    92110                self::$buffer_level = ob_get_level(); 
    93111 
    94                 // Load path cache 
    95                 self::$paths = Kohana::load_cache('file_paths'); 
     112                if ($lifetime = self::config('core.internal_cache')) 
     113                { 
     114                        // Load cached configuration and include paths 
     115                        self::$internal_cache['configuration'] = self::cache('configuration', $lifetime); 
     116                        self::$internal_cache['include_paths'] = self::cache('include_paths', $lifetime); 
     117 
     118                        // Enable cache saving 
     119                        Event::add('system.shutdown', array(__CLASS__, 'internal_cache_save')); 
     120                } 
    96121 
    97122                // Set autoloader 
     
    112137 
    113138                // Load locales 
    114                 $locales = Config::item('locale.language'); 
     139                $locales = self::config('locale.language'); 
    115140 
    116141                // Make first locale UTF-8 
     
    120145                self::$locale = setlocale(LC_ALL, $locales); 
    121146 
    122                 if (Config::item('log.threshold') > 0) 
    123                 { 
    124                         // Get the configured log directory 
    125                         $log_dir = Config::item('log.directory'); 
    126  
    127                         if ( ! is_dir($log_dir)) 
    128                         { 
    129                                 // Application log directory 
    130                                 $log_dir = APPPATH.$log_dir; 
    131                         } 
    132  
     147                if (self::$configuration['core']['log_threshold'] > 0) 
     148                { 
    133149                        // Set the log directory 
    134                         Log::directory($log_dir); 
    135  
    136                         // Enable log writing if the log threshold is above 0 
    137                         register_shutdown_function(array('Log', 'write')); 
     150                        self::log_directory(self::$configuration['core']['log_directory']); 
     151 
     152                        // Enable log writing at shutdown 
     153                        register_shutdown_function(array(__CLASS__, 'log_save')); 
    138154                } 
    139155 
     
    151167                Event::add('system.shutdown', array('Kohana', 'shutdown')); 
    152168 
    153                 if ($config = Config::item('hooks.enable')) 
     169                if ($config = Kohana::config('hooks.enable')) 
    154170                { 
    155171                        $hooks = array(); 
     
    173189                                        { 
    174190                                                // This should never happen 
    175                                                 Log::add('error', 'Hook not found: '.$name); 
     191                                                Kohana::log('error', 'Hook not found: '.$name); 
    176192                                        } 
    177193                                } 
     
    192208                                { 
    193209                                        // This should never happen 
    194                                         Log::add('error', 'Hook not found: '.$hook); 
     210                                        Kohana::log('error', 'Hook not found: '.$hook); 
    195211                                } 
    196212                        } 
     
    213229         * @return  object  instance of controller 
    214230         */ 
    215         final public static function & instance() 
     231        public static function & instance() 
    216232        { 
    217233                if (self::$instance === NULL) 
     
    325341 
    326342        /** 
     343         * Get all include paths. APPPATH is the first path, followed by module 
     344         * paths in the order they are configured, follow by the SYSPATH. 
     345         * 
     346         * @param   boolean  re-process the include paths 
     347         * @return  array 
     348         */ 
     349        public static function include_paths($process = FALSE) 
     350        { 
     351                if ($process === TRUE) 
     352                { 
     353                        // Add APPPATH as the first path 
     354                        self::$include_paths = array(APPPATH); 
     355 
     356                        foreach (self::$configuration['core']['modules'] as $path) 
     357                        { 
     358                                if ($path = str_replace('\\', '/', realpath($path))) 
     359                                { 
     360                                        // Add a valid path 
     361                                        self::$include_paths[] = $path.'/'; 
     362                                } 
     363                        } 
     364 
     365                        // Add SYSPATH as the last path 
     366                        self::$include_paths[] = SYSPATH; 
     367                } 
     368 
     369                return self::$include_paths; 
     370        } 
     371 
     372        /** 
     373         * Get a config item or group. 
     374         * 
     375         * @param   string   item name 
     376         * @param   boolean  force a forward slash (/) at the end of the item 
     377         * @param   boolean  is the item required? 
     378         * @return  mixed 
     379         */ 
     380        public static function config($key, $slash = FALSE) 
     381        { 
     382                if (self::$configuration === NULL) 
     383                { 
     384                        // Load core configuration 
     385                        self::$configuration['core'] = self::config_load('core'); 
     386 
     387                        // Re-parse the include paths 
     388                        self::include_paths(TRUE); 
     389                } 
     390 
     391                // Get the group name from the key 
     392                $group = explode('.', $key, 2); 
     393                $group = $group[0]; 
     394 
     395                if ( ! isset(self::$configuration[$group])) 
     396                { 
     397                        // Load the configuration group 
     398                        self::$configuration[$group] = self::config_load($group); 
     399                } 
     400 
     401                // Get the value of the key string 
     402                $value = self::key_string(self::$configuration, $key); 
     403 
     404                if ($slash === TRUE AND is_string($value) AND $value !== '') 
     405                { 
     406                        // Force the value to end with "/" 
     407                        $value = rtrim($value, '/').'/'; 
     408                } 
     409 
     410                return $value; 
     411        } 
     412 
     413        /** 
     414         * Load a config file. 
     415         * 
     416         * @param   string   config filename, without extension 
     417         * @return  array 
     418         */ 
     419        public static function config_load($name) 
     420        { 
     421                if ($name === 'core') 
     422                { 
     423                        // Load the application configuration file 
     424                        require APPPATH.'config/config'.EXT; 
     425 
     426                        if ( ! isset($config['site_domain'])) 
     427                        { 
     428                                // Invalid config file 
     429                                die('Your Kohana application configuration file is not valid.'); 
     430                        } 
     431 
     432                        return $config; 
     433                } 
     434 
     435                if (isset(self::$internal_cache['configuration'][$name])) 
     436                        return self::$internal_cache['configuration'][$name]; 
     437 
     438                // Load matching configs 
     439                $configuration = array(); 
     440 
     441                if ($files = self::find_file('config', $name, TRUE)) 
     442                { 
     443                        foreach ($files as $file) 
     444                        { 
     445                                require $file; 
     446 
     447                                if (isset($config) AND is_array($config)) 
     448                                { 
     449                                        // Merge in configuration 
     450                                        $configuration = array_merge($configuration, $config); 
     451                                } 
     452                        } 
     453                } 
     454 
     455                if ( ! isset(self::$write_cache['configuration'])) 
     456                { 
     457                        // Cache has changed 
     458                        self::$write_cache['configuration'] = TRUE; 
     459                } 
     460 
     461                return self::$internal_cache['configuration'][$name] = $configuration; 
     462        } 
     463 
     464        /** 
     465         * Clears a config group from the cached configuration. 
     466         * 
     467         * @param   string  config group 
     468         * @return  void 
     469         */ 
     470        public static function config_clear($group) 
     471        { 
     472                // Remove the group from config 
     473                unset(self::$configuration[$group], self::$internal_cache['configuration'][$group]); 
     474 
     475                if ( ! isset(self::$write_cache['configuration'])) 
     476                { 
     477                        // Cache has changed 
     478                        self::$write_cache['configuration'] = TRUE; 
     479                } 
     480        } 
     481 
     482        /** 
     483         * Add a new message to the log. 
     484         * 
     485         * @param   string  type of message 
     486         * @param   string  message text 
     487         * @return  void 
     488         */ 
     489        public static function log($type, $message) 
     490        { 
     491                if (self::$log_levels[$type] <= self::$configuration['core']['log_threshold']) 
     492                { 
     493                        self::$log[] = array(date('Y-m-d H:i:s P'), $type, $message); 
     494                } 
     495        } 
     496 
     497        /** 
     498         * Save all currently logged messages. 
     499         * 
     500         * @return  void 
     501         */ 
     502        public static function log_save() 
     503        { 
     504                if (empty(self::$log)) 
     505                        return; 
     506 
     507                // Filename of the log 
     508                $filename = self::log_directory().date('Y-m-d').'.log'.EXT; 
     509 
     510                if ( ! file_exists($filename)) 
     511                { 
     512                        // Write the SYSPATH checking header 
     513                        file_put_contents($filename, 
     514                                '<?php defined(\'SYSPATH\') or die(\'No direct script access.\'); ?>'.PHP_EOL.PHP_EOL); 
     515 
     516                        // Prevent external writes 
     517                        chmod($filename, 0644); 
     518                } 
     519 
     520                // Messages to write 
     521                $messages = array(); 
     522 
     523                do 
     524                { 
     525                        // Load the next mess 
     526                        list ($date, $type, $text) = array_shift(self::$log); 
     527 
     528                        // Add a new message line 
     529                        $messages[] = $date.' --- '.$type.': '.$text; 
     530                } 
     531                while ( ! empty(self::$log)); 
     532 
     533                // Write messages to log file 
     534                file_put_contents($filename, implode(PHP_EOL, $messages).PHP_EOL, FILE_APPEND); 
     535        } 
     536 
     537        /** 
     538         * Get or set the logging directory. 
     539         * 
     540         * @param   string  new log directory 
     541         * @return  string 
     542         */ 
     543        public static function log_directory($dir = NULL) 
     544        { 
     545                static $directory; 
     546 
     547                if ( ! empty($dir)) 
     548                { 
     549                        // Get the directory path 
     550                        $dir = realpath($dir); 
     551 
     552                        if (file_exists($dir) AND is_dir($dir) AND is_writable($dir)) 
     553                        { 
     554                                // Change the log directory 
     555                                $directory = str_replace('\\', '/', $dir).'/'; 
     556                        } 
     557                        else 
     558                        { 
     559                                // Log directory is invalid 
     560                                throw new Kohana_Exception('core.log_dir_unwritable', $dir); 
     561                        } 
     562                } 
     563 
     564                return $directory; 
     565        } 
     566 
     567        /** 
     568         * Load data from a simple cache file. This should only be used internally, 
     569         * and is NOT a replacement for the Cache library. 
     570         * 
     571         * @param   string   unique name of cache 
     572         * @param   integer  lifetime of cache 
     573         * @return  mixed 
     574         */ 
     575        public static function cache($name, $lifetime) 
     576        { 
     577                if ($lifetime > 0) 
     578                { 
     579                        $path = APPPATH.'cache/kohana_'.$name; 
     580 
     581                        if (file_exists($path)) 
     582                        { 
     583                                // Check the file modification time 
     584                                if ((time() - filemtime($path)) < $lifetime) 
     585                                { 
     586                                        // Cache is valid 
     587                                        return unserialize(file_get_contents($path)); 
     588                                } 
     589                                else 
     590                                { 
     591                                        // Cache is invalid, delete it 
     592                                        unlink($path); 
     593                                } 
     594                        } 
     595                } 
     596 
     597                // No cache found 
     598                return NULL; 
     599        } 
     600 
     601        /** 
     602         * Save data to a simple cache file. This should only be used internally, and 
     603         * is NOT a replacement for the Cache library. 
     604         * 
     605         * @param   string  cache name 
     606         * @param   mixed   data to cache 
     607         * @return  boolean 
     608         */ 
     609        public static function cache_save($name, $data, $lifetime) 
     610        { 
     611                if ($lifetime > 0) 
     612                { 
     613                        $path = APPPATH.'cache/kohana_'.$name; 
     614 
     615                        if ($data === NULL) 
     616                        { 
     617                                // Delete cache 
     618                                return (file_exists($path) and unlink($path)); 
     619                        } 
     620                        else 
     621                        { 
     622                                // Write data to cache file 
     623                                return (bool) file_put_contents($path, serialize($data)); 
     624                        } 
     625                } 
     626                else 
     627                { 
     628                        // No caching enabled 
     629                        return FALSE; 
     630                } 
     631        } 
     632 
     633        /** 
    327634         * Kohana output handler. 
    328635         * 
     
    330637         * @return  string 
    331638         */ 
    332         final public static function output_buffer($output) 
    333         { 
    334                 // Run the send_headers event, specifically for cookies being set 
    335                 Event::has_run('system.send_headers') or Event::run('system.send_headers'); 
     639        public static function output_buffer($output) 
     640        { 
     641                if ( ! Event::has_run('system.send_headers')) 
     642                { 
     643                        // Run the send_headers event, specifically for cookies being set 
     644                        Event::run('system.send_headers'); 
     645                } 
    336646 
    337647                // Set final output 
     
    364674                        // This will flush the Kohana buffer, which sets self::$output 
    365675                        ob_end_clean(); 
     676 
     677                        // Reset the buffer level 
     678                        self::$buffer_level = ob_get_level(); 
    366679                } 
    367680        } 
     
    398711                $benchmark = Benchmark::get(SYSTEM_BENCHMARK.'_total_execution'); 
    399712 
    400                 if (Config::item('core.render_stats') === TRUE) 
     713                if (Kohana::config('core.render_stats') === TRUE) 
    401714                { 
    402715                        // Replace the global template variables 
     
    422735                } 
    423736 
    424                 if ($level = Config::item('core.output_compression') AND ini_get('output_handler') !== 'ob_gzhandler' AND (int) ini_get('zlib.output_compression') === 0) 
     737                if ($level = Kohana::config('core.output_compression') AND ini_get('output_handler') !== 'ob_gzhandler' AND (int) ini_get('zlib.output_compression') === 0) 
    425738                { 
    426739                        if ($level < 1 OR $level > 9) 
     
    473786 
    474787        /** 
     788         * Displays a 404 page. 
     789         * 
     790         * @throws  Kohana_404_Exception 
     791         * @param   string  URI of page 
     792         * @param   string  custom template 
     793         * @return  void 
     794         */ 
     795        public static function show_404($page = FALSE, $template = FALSE) 
     796        { 
     797                throw new Kohana_404_Exception($page, $template); 
     798        } 
     799 
     800        /** 
    475801         * Dual-purpose PHP error and exception handler. Uses the kohana_error_page 
    476802         * view to display the message. 
     
    513839                if (is_numeric($code)) 
    514840                { 
    515                         $codes = Kohana::lang('errors'); 
     841                        $codes = self::lang('errors'); 
    516842 
    517843                        if ( ! empty($codes[$code])) 
     
    538864                $file = preg_replace('|^'.preg_quote(DOCROOT).'|', '', $file); 
    539865 
    540                 if (Config::item('log.threshold') >= $level) 
     866                if ($level >= self::$configuration['core']['log_threshold']) 
    541867                { 
    542868                        // Log the error 
    543                         Log::add('error', Kohana::lang('core.uncaught_exception', $type, $message, $file, $line)); 
     869                        self::log('error', self::lang('core.uncaught_exception', $type, $message, $file, $line)); 
    544870                } 
    545871 
    546872                if ($PHP_ERROR) 
    547873                { 
    548                         $description = Kohana::lang('errors.'.E_RECOVERABLE_ERROR); 
     874                        $description = self::lang('errors.'.E_RECOVERABLE_ERROR); 
    549875                        $description = is_array($description) ? $description[2] : ''; 
    550876                } 
    551877                else 
    552878                { 
    553                         if (method_exists($exception, 'sendHeaders')) 
     879                        if (method_exists($exception, 'sendHeaders') AND ! headers_sent()) 
    554880              &nbs