configure.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: configure.php 8015 2009-02-04 05:00:59Z mark_story $ */
00003 /**
00004  * Short description for file.
00005  *
00006  * Long description for filec
00007  *
00008  * PHP versions 4 and 5
00009  *
00010  * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
00011  * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00012  *
00013  * Licensed under The MIT License
00014  * Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00018  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00019  * @package       cake
00020  * @subpackage    cake.cake.libs
00021  * @since         CakePHP(tm) v 1.0.0.2363
00022  * @version       $Revision: 8015 $
00023  * @modifiedby    $LastChangedBy: mark_story $
00024  * @lastmodified  $Date: 2009-02-04 00:00:59 -0500 (Wed, 04 Feb 2009) $
00025  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00026  */
00027 /**
00028  * Configuration class (singleton). Used for managing runtime configuration information.
00029  *
00030  * @package       cake
00031  * @subpackage    cake.cake.libs
00032  * @link          http://book.cakephp.org/view/42/The-Configuration-Class
00033  */
00034 class Configure extends Object {
00035 /**
00036  * List of additional path(s) where model files reside.
00037  *
00038  * @var array
00039  * @access public
00040  */
00041     var $modelPaths = array();
00042 /**
00043  * List of additional path(s) where behavior files reside.
00044  *
00045  * @var array
00046  * @access public
00047  */
00048     var $behaviorPaths = array();
00049 /**
00050  * List of additional path(s) where controller files reside.
00051  *
00052  * @var array
00053  * @access public
00054  */
00055     var $controllerPaths = array();
00056 /**
00057  * List of additional path(s) where component files reside.
00058  *
00059  * @var array
00060  * @access public
00061  */
00062     var $componentPaths = array();
00063 /**
00064  * List of additional path(s) where view files reside.
00065  *
00066  * @var array
00067  * @access public
00068  */
00069     var $viewPaths = array();
00070 /**
00071  * List of additional path(s) where helper files reside.
00072  *
00073  * @var array
00074  * @access public
00075  */
00076     var $helperPaths = array();
00077 /**
00078  * List of additional path(s) where plugins reside.
00079  *
00080  * @var array
00081  * @access public
00082  */
00083     var $pluginPaths = array();
00084 /**
00085  * List of additional path(s) where vendor packages reside.
00086  *
00087  * @var array
00088  * @access public
00089  */
00090     var $vendorPaths = array();
00091 /**
00092  * List of additional path(s) where locale files reside.
00093  *
00094  * @var array
00095  * @access public
00096  */
00097     var $localePaths = array();
00098 /**
00099  * List of additional path(s) where console shell files reside.
00100  *
00101  * @var array
00102  * @access public
00103  */
00104     var $shellPaths = array();
00105 /**
00106  * Current debug level.
00107  *
00108  * @link          http://book.cakephp.org/view/44/CakePHP-Core-Configuration-Variables
00109  * @var integer
00110  * @access public
00111  */
00112     var $debug = null;
00113 /**
00114  * Determines if $__objects cache should be written.
00115  *
00116  * @var boolean
00117  * @access private
00118  */
00119     var $__cache = false;
00120 /**
00121  * Holds and key => value array of objects' types.
00122  *
00123  * @var array
00124  * @access private
00125  */
00126     var $__objects = array();
00127 /**
00128  * Returns a singleton instance of the Configure class.
00129  *
00130  * @return Configure instance
00131  * @access public
00132  */
00133     function &getInstance($boot = true) {
00134         static $instance = array();
00135         if (!$instance) {
00136             $instance[0] =& new Configure();
00137             $instance[0]->__loadBootstrap($boot);
00138         }
00139         return $instance[0];
00140     }
00141 /**
00142  * Returns an index of objects of the given type, with the physical path to each object.
00143  *
00144  * @param string    $type Type of object, i.e. 'model', 'controller', 'helper', or 'plugin'
00145  * @param mixed     $path Optional
00146  * @return Configure instance
00147  * @access public
00148  */
00149     function listObjects($type, $path = null, $cache = true) {
00150         $objects = array();
00151         $extension = false;
00152         $name = $type;
00153 
00154         if ($type === 'file' && !$path) {
00155             return false;
00156         } elseif ($type === 'file') {
00157             $extension = true;
00158             $name = $type . str_replace(DS, '', $path);
00159         }
00160         $_this =& Configure::getInstance();
00161 
00162         if (empty($_this->__objects) && $cache === true) {
00163             $_this->__objects = Cache::read('object_map', '_cake_core_');
00164         }
00165 
00166         if (empty($_this->__objects) || !isset($_this->__objects[$type]) || $cache !== true) {
00167             $types = array(
00168                 'model' => array('suffix' => '.php', 'base' => 'AppModel', 'core' => false),
00169                 'behavior' => array('suffix' => '.php', 'base' => 'ModelBehavior'),
00170                 'controller' => array('suffix' => '_controller.php', 'base' => 'AppController'),
00171                 'component' => array('suffix' => '.php', 'base' => null),
00172                 'view' => array('suffix' => '.php', 'base' => null),
00173                 'helper' => array('suffix' => '.php', 'base' => 'AppHelper'),
00174                 'plugin' => array('suffix' => '', 'base' => null),
00175                 'vendor' => array('suffix' => '', 'base' => null),
00176                 'class' => array('suffix' => '.php', 'base' => null),
00177                 'file' => array('suffix' => '.php', 'base' => null)
00178             );
00179 
00180             if (!isset($types[$type])) {
00181                 return false;
00182             }
00183             $objects = array();
00184 
00185             if (empty($path)) {
00186                 $path = $_this->{$type . 'Paths'};
00187                 if (isset($types[$type]['core']) && $types[$type]['core'] === false) {
00188                     array_pop($path);
00189                 }
00190             }
00191             $items = array();
00192 
00193             foreach ((array)$path as $dir) {
00194                 if ($type === 'file' || $type === 'class' || strpos($dir, $type) !== false) {
00195                     $items = $_this->__list($dir, $types[$type]['suffix'], $extension);
00196                     $objects = array_merge($items, array_diff($objects, $items));
00197                 }
00198             }
00199 
00200             if ($type !== 'file') {
00201                 foreach ($objects as $key => $value) {
00202                     $objects[$key] = Inflector::camelize($value);
00203                 }
00204             }
00205             if ($cache === true && !empty($objects)) {
00206                 $_this->__objects[$name] = $objects;
00207                 $_this->__cache = true;
00208             } else {
00209                 return $objects;
00210             }
00211         }
00212         return $_this->__objects[$name];
00213     }
00214 /**
00215  * Returns an array of filenames of PHP files in the given directory.
00216  *
00217  * @param  string $path Path to scan for files
00218  * @param  string $suffix if false, return only directories. if string, match and return files
00219  * @return array  List of directories or files in directory
00220  */
00221     function __list($path, $suffix = false, $extension = false) {
00222         if (!class_exists('Folder')) {
00223             require LIBS . 'folder.php';
00224         }
00225         $items = array();
00226         $Folder =& new Folder($path);
00227         $contents = $Folder->read(false, true);
00228 
00229         if (is_array($contents)) {
00230             if (!$suffix) {
00231                 return $contents[0];
00232             } else {
00233                 foreach ($contents[1] as $item) {
00234                     if (substr($item, - strlen($suffix)) === $suffix) {
00235                         if ($extension) {
00236                             $items[] = $item;
00237                         } else {
00238                             $items[] = substr($item, 0, strlen($item) - strlen($suffix));
00239                         }
00240                     }
00241                 }
00242             }
00243         }
00244         return $items;
00245     }
00246 /**
00247  * Used to store a dynamic variable in the Configure instance.
00248  *
00249  * Usage:
00250  * {{{
00251  * Configure::write('One.key1', 'value of the Configure::One[key1]');
00252  * Configure::write(array('One.key1' => 'value of the Configure::One[key1]'));
00253  * Configure::write('One', array(
00254  *     'key1' => 'value of the Configure::One[key1]',
00255  *     'key2' => 'value of the Configure::One[key2]'
00256  * );
00257  * 
00258  * Configure::write(array(
00259  *     'One.key1' => 'value of the Configure::One[key1]',
00260  *     'One.key2' => 'value of the Configure::One[key2]'
00261  * ));
00262  * }}}
00263  *
00264  * @link http://book.cakephp.org/view/412/write
00265  * @param array $config Name of var to write
00266  * @param mixed $value Value to set for var
00267  * @return void
00268  * @access public
00269  */
00270     function write($config, $value = null) {
00271         $_this =& Configure::getInstance();
00272 
00273         if (!is_array($config)) {
00274             $config = array($config => $value);
00275         }
00276 
00277         foreach ($config as $names => $value) {
00278             $name = $_this->__configVarNames($names);
00279 
00280             switch (count($name)) {
00281                 case 3:
00282                     $_this->{$name[0]}[$name[1]][$name[2]] = $value;
00283                 break;
00284                 case 2:
00285                     $_this->{$name[0]}[$name[1]] = $value;
00286                 break;
00287                 case 1:
00288                     $_this->{$name[0]} = $value;
00289                 break;
00290             }
00291         }
00292 
00293         if (isset($config['debug'])) {
00294             if ($_this->debug) {
00295                 error_reporting(E_ALL);
00296 
00297                 if (function_exists('ini_set')) {
00298                     ini_set('display_errors', 1);
00299                 }
00300 
00301                 if (!class_exists('Debugger')) {
00302                     require LIBS . 'debugger.php';
00303                 }
00304                 if (!class_exists('CakeLog')) {
00305                     require LIBS . 'cake_log.php';
00306                 }
00307                 Configure::write('log', LOG_NOTICE);
00308             } else {
00309                 error_reporting(0);
00310                 Configure::write('log', LOG_NOTICE);
00311             }
00312         }
00313     }
00314 /**
00315  * Used to read information stored in the Configure instance.
00316  *
00317  * Usage
00318  * Configure::read('Name'); will return all values for Name
00319  * Configure::read('Name.key'); will return only the value of Configure::Name[key]
00320  *
00321  * @link          http://book.cakephp.org/view/413/read
00322  * @param string $var Variable to obtain
00323  * @return string value of Configure::$var
00324  * @access public
00325  */
00326     function read($var = 'debug') {
00327         $_this =& Configure::getInstance();
00328 
00329         if ($var === 'debug') {
00330             if (!isset($_this->debug)) {
00331                 if (defined('DEBUG')) {
00332                     $_this->debug = DEBUG;
00333                 } else {
00334                     $_this->debug = 0;
00335                 }
00336             }
00337             return $_this->debug;
00338         }
00339         $name = $_this->__configVarNames($var);
00340 
00341         switch (count($name)) {
00342             case 3:
00343                 if (isset($_this->{$name[0]}[$name[1]][$name[2]])) {
00344                     return $_this->{$name[0]}[$name[1]][$name[2]];
00345                 }
00346             break;
00347             case 2:
00348                 if (isset($_this->{$name[0]}[$name[1]])) {
00349                     return $_this->{$name[0]}[$name[1]];
00350                 }
00351             break;
00352             case 1:
00353                 if (isset($_this->{$name[0]})) {
00354                     return $_this->{$name[0]};
00355                 }
00356             break;
00357         }
00358         return null;
00359     }
00360 /**
00361  * Used to delete a variable from the Configure instance.
00362  *
00363  * Usage:
00364  * Configure::delete('Name'); will delete the entire Configure::Name
00365  * Configure::delete('Name.key'); will delete only the Configure::Name[key]
00366  *
00367  * @link          http://book.cakephp.org/view/414/delete
00368  * @param string $var the var to be deleted
00369  * @return void
00370  * @access public
00371  */
00372     function delete($var = null) {
00373         $_this =& Configure::getInstance();
00374         $name = $_this->__configVarNames($var);
00375 
00376         if (count($name) > 1) {
00377             unset($_this->{$name[0]}[$name[1]]);
00378         } else {
00379             unset($_this->{$name[0]});
00380         }
00381     }
00382 /**
00383  * Loads a file from app/config/configure_file.php.
00384  * Config file variables should be formated like:
00385  *  $config['name'] = 'value';
00386  * These will be used to create dynamic Configure vars.
00387  *
00388  * Usage Configure::load('configure_file');
00389  *
00390  * @link          http://book.cakephp.org/view/415/load
00391  * @param string $fileName name of file to load, extension must be .php and only the name
00392  *                         should be used, not the extenstion
00393  * @return mixed false if file not found, void if load successful
00394  * @access public
00395  */
00396     function load($fileName) {
00397         $found = false;
00398 
00399         if (file_exists(CONFIGS . $fileName . '.php')) {
00400             include(CONFIGS . $fileName . '.php');
00401             $found = true;
00402         } elseif (file_exists(CACHE . 'persistent' . DS . $fileName . '.php')) {
00403             include(CACHE . 'persistent' . DS . $fileName . '.php');
00404             $found = true;
00405         } else {
00406             foreach (Configure::corePaths('cake') as $key => $path) {
00407                 if (file_exists($path . DS . 'config' . DS . $fileName . '.php')) {
00408                     include($path . DS . 'config' . DS . $fileName . '.php');
00409                     $found = true;
00410                     break;
00411                 }
00412             }
00413         }
00414 
00415         if (!$found) {
00416             return false;
00417         }
00418 
00419         if (!isset($config)) {
00420             $error = __("Configure::load() - no variable \$config found in %s.php", true);
00421             trigger_error(sprintf($error, $fileName), E_USER_WARNING);
00422             return false;
00423         }
00424         return Configure::write($config);
00425     }
00426 /**
00427  * Used to determine the current version of CakePHP.
00428  *
00429  * Usage Configure::version();
00430  *
00431  * @link          http://book.cakephp.org/view/416/version
00432  * @return string Current version of CakePHP
00433  * @access public
00434  */
00435     function version() {
00436         $_this =& Configure::getInstance();
00437 
00438         if (!isset($_this->Cake['version'])) {
00439             require(CORE_PATH . 'cake' . DS . 'config' . DS . 'config.php');
00440             $_this->write($config);
00441         }
00442         return $_this->Cake['version'];
00443     }
00444 /**
00445  * Used to write a config file to disk.
00446  *
00447  * Configure::store('Model', 'class.paths', array('Users' => array(
00448  *      'path' => 'users', 'plugin' => true
00449  * )));
00450  *
00451  * @param string $type Type of config file to write, ex: Models, Controllers, Helpers, Components
00452  * @param string $name file name.
00453  * @param array $data array of values to store.
00454  * @return void
00455  * @access public
00456  */
00457     function store($type, $name, $data = array()) {
00458         $write = true;
00459         $content = '';
00460 
00461         foreach ($data as $key => $value) {
00462             $content .= "\$config['$type']['$key']";
00463 
00464             if (is_array($value)) {
00465                 $content .= " = array(";
00466 
00467                 foreach ($value as $key1 => $value2) {
00468                     $value2 = addslashes($value2);
00469                     $content .= "'$key1' => '$value2', ";
00470                 }
00471                 $content .= ");\n";
00472             } else {
00473                 $value = addslashes($value);
00474                 $content .= " = '$value';\n";
00475             }
00476         }
00477         if (is_null($type)) {
00478             $write = false;
00479         }
00480         Configure::__writeConfig($content, $name, $write);
00481     }
00482 /**
00483  * Returns a key/value list of all paths where core libs are found.
00484  * Passing $type only returns the values for a given value of $key.
00485  *
00486  * @param string $type valid values are: 'model', 'behavior', 'controller', 'component',
00487  *                      'view', 'helper', 'datasource', 'libs', and 'cake'
00488  * @return array numeric keyed array of core lib paths
00489  * @access public
00490  */
00491     function corePaths($type = null) {
00492         $paths = Cache::read('core_paths', '_cake_core_');
00493         if (!$paths) {
00494             $paths = array();
00495             $openBasedir = ini_get('open_basedir');
00496             if ($openBasedir) {
00497                 $all = explode(PATH_SEPARATOR, $openBasedir);
00498                 $all = array_flip(array_flip((array_merge(array(CAKE_CORE_INCLUDE_PATH), $all))));
00499             } else {
00500                 $all = explode(PATH_SEPARATOR, ini_get('include_path'));
00501                 $all = array_flip(array_flip((array_merge(array(CAKE_CORE_INCLUDE_PATH), $all))));
00502             }
00503             foreach ($all as $path) {
00504                 if ($path !== DS) {
00505                     $path = rtrim($path, DS);
00506                 }
00507                 if (empty($path) || $path === '.') {
00508                     continue;
00509                 }
00510                 $cake = $path .  DS . 'cake' . DS;
00511                 $libs = $cake . 'libs' . DS;
00512                 if (is_dir($libs)) {
00513                     $paths['libs'][] = $libs;
00514                     $paths['model'][] = $libs . 'model' . DS;
00515                     $paths['behavior'][] = $libs . 'model' . DS . 'behaviors' . DS;
00516                     $paths['controller'][] = $libs . 'controller' . DS;
00517                     $paths['component'][] = $libs . 'controller' . DS . 'components' . DS;
00518                     $paths['view'][] = $libs . 'view' . DS;
00519                     $paths['helper'][] = $libs . 'view' . DS . 'helpers' . DS;
00520                     $paths['cake'][] = $cake;
00521                     $paths['vendor'][] = $path . DS . 'vendors' . DS;
00522                     $paths['shell'][] = $cake . 'console' . DS . 'libs' . DS;
00523                     break;
00524                 }
00525             }
00526             Cache::write('core_paths', array_filter($paths), '_cake_core_');
00527         }
00528         if ($type && isset($paths[$type])) {
00529             return $paths[$type];
00530         }
00531         return $paths;
00532     }
00533 /**
00534  * Creates a cached version of a configuration file.
00535  * Appends values passed from Configure::store() to the cached file
00536  *
00537  * @param string $content Content to write on file
00538  * @param string $name Name to use for cache file
00539  * @param boolean $write true if content should be written, false otherwise
00540  * @return void
00541  * @access private
00542  */
00543     function __writeConfig($content, $name, $write = true) {
00544         $file = CACHE . 'persistent' . DS . $name . '.php';
00545 
00546         if (Configure::read() > 0) {
00547             $expires = "+10 seconds";
00548         } else {
00549             $expires = "+999 days";
00550         }
00551         $cache = cache('persistent' . DS . $name . '.php', null, $expires);
00552 
00553         if ($cache === null) {
00554             cache('persistent' . DS . $name . '.php', "<?php\n\$config = array();\n", $expires);
00555         }
00556 
00557         if ($write === true) {
00558             if (!class_exists('File')) {
00559                 require LIBS . 'file.php';
00560             }
00561             $fileClass = new File($file);
00562 
00563             if ($fileClass->writable()) {
00564                 $fileClass->append($content);
00565             }
00566         }
00567     }
00568 /**
00569  * Checks $name for dot notation to create dynamic Configure::$var as an array when needed.
00570  *
00571  * @param mixed $name Name to split
00572  * @return array Name separated in items through dot notation
00573  * @access private
00574  */
00575     function __configVarNames($name) {
00576         if (is_string($name)) {
00577             if (strpos($name, ".")) {
00578                 return explode(".", $name);
00579             }
00580             return array($name);
00581         }
00582         return $name;
00583     }
00584 /**
00585  * Build path references. Merges the supplied $paths
00586  * with the base paths and the default core paths.
00587  *
00588  * @param array $paths paths defines in config/bootstrap.php
00589  * @return void
00590  * @access public
00591  */
00592     function buildPaths($paths) {
00593         $_this =& Configure::getInstance();
00594         $core = $_this->corePaths();
00595         $basePaths = array(
00596             'model' => array(MODELS),
00597             'behavior' => array(BEHAVIORS),
00598             'controller' => array(CONTROLLERS),
00599             'component' => array(COMPONENTS),
00600             'view' => array(VIEWS),
00601             'helper' => array(HELPERS),
00602             'plugin' => array(APP . 'plugins' . DS),
00603             'vendor' => array(APP . 'vendors' . DS, VENDORS),
00604             'locale' => array(APP . 'locale' . DS),
00605             'shell' => array(),
00606             'datasource' => array(MODELS . 'datasources')
00607         );
00608 
00609         foreach ($basePaths as $type => $default) {
00610             $pathsVar = $type . 'Paths';
00611             $merge = array();
00612 
00613             if (isset($core[$type])) {
00614                 $merge = $core[$type];
00615             }
00616             if ($type === 'model' || $type === 'controller' || $type === 'helper') {
00617                 $merge = array_merge(array(APP), $merge);
00618             }
00619 
00620             if (!is_array($default)) {
00621                 $default = array($default);
00622             }
00623             $_this->{$pathsVar} = $default;
00624 
00625             if (isset($paths[$pathsVar]) && !empty($paths[$pathsVar])) {
00626                 $path = array_flip(array_flip((array_merge(
00627                     $_this->{$pathsVar}, (array)$paths[$pathsVar], $merge
00628                 ))));
00629                 $_this->{$pathsVar} = array_values($path);
00630             } else {
00631                 $path = array_flip(array_flip((array_merge($_this->{$pathsVar}, $merge))));
00632                 $_this->{$pathsVar} = array_values($path);
00633             }
00634         }
00635     }
00636 /**
00637  * Loads app/config/bootstrap.php.
00638  * If the alternative paths are set in this file
00639  * they will be added to the paths vars.
00640  *
00641  * @param boolean $boot Load application bootstrap (if true)
00642  * @return void
00643  * @access private
00644  */
00645     function __loadBootstrap($boot) {
00646         $modelPaths = $behaviorPaths = $controllerPaths = $componentPaths = $viewPaths = $helperPaths = $pluginPaths = $vendorPaths = $localePaths = $shellPaths = null;
00647 
00648         if ($boot) {
00649             Configure::write('App', array('base' => false, 'baseUrl' => false, 'dir' => APP_DIR, 'webroot' => WEBROOT_DIR));
00650 
00651             if (!include(CONFIGS . 'core.php')) {
00652                 trigger_error(sprintf(__("Can't find application core file. Please create %score.php, and make sure it is readable by PHP.", true), CONFIGS), E_USER_ERROR);
00653             }
00654 
00655             if (!include(CONFIGS . 'bootstrap.php')) {
00656                 trigger_error(sprintf(__("Can't find application bootstrap file. Please create %sbootstrap.php, and make sure it is readable by PHP.", true), CONFIGS), E_USER_ERROR);
00657             }
00658 
00659             if (Configure::read('Cache.disable') !== true) {
00660                 $cache = Cache::config('default');
00661 
00662                 if (empty($cache['settings'])) {
00663                     trigger_error('Cache not configured properly. Please check Cache::config(); in APP/config/core.php', E_USER_WARNING);
00664                     $cache = Cache::config('default', array('engine' => 'File'));
00665                 }
00666                 $path = $prefix = $duration = null;
00667 
00668                 if (!empty($cache['settings']['path'])) {
00669                     $path = realpath($cache['settings']['path']);
00670                 } else {
00671                     $prefix = $cache['settings']['prefix'];
00672                 }
00673 
00674                 if (Configure::read() >= 1) {
00675                     $duration = '+10 seconds';
00676                 } else {
00677                     $duration = '+999 days';
00678                 }
00679 
00680                 if (Cache::config('_cake_core_') === false) {
00681                     Cache::config('_cake_core_', array_merge($cache['settings'], array(
00682                         'prefix' => $prefix . 'cake_core_', 'path' => $path . DS . 'persistent' . DS,
00683                         'serialize' => true, 'duration' => $duration
00684                     )));
00685                 }
00686 
00687                 if (Cache::config('_cake_model_') === false) {
00688                     Cache::config('_cake_model_', array_merge($cache['settings'], array(
00689                         'prefix' => $prefix . 'cake_model_', 'path' => $path . DS . 'models' . DS,
00690                         'serialize' => true, 'duration' => $duration
00691                     )));
00692                 }
00693                 Cache::config('default');
00694             }
00695             Configure::buildPaths(compact(
00696                 'modelPaths', 'viewPaths', 'controllerPaths', 'helperPaths', 'componentPaths',
00697                 'behaviorPaths', 'pluginPaths', 'vendorPaths', 'localePaths', 'shellPaths'
00698             ));
00699         }
00700     }
00701 /**
00702  * Caches the object map when the instance of the Configure class is destroyed
00703  *
00704  * @access public
00705  */
00706     function __destruct() {
00707         if ($this->__cache) {
00708             Cache::write('object_map', array_filter($this->__objects), '_cake_core_');
00709         }
00710     }
00711 }
00712 /**
00713  * Class and file loader.
00714  *
00715  * @link          http://book.cakephp.org/view/499/The-App-Class
00716  * @since         CakePHP(tm) v 1.2.0.6001
00717  * @package       cake
00718  * @subpackage    cake.cake.libs
00719  */
00720 class App extends Object {
00721 /**
00722  * Paths to search for files.
00723  *
00724  * @var array
00725  * @access public
00726  */
00727     var $search = array();
00728 /**
00729  * Whether or not to return the file that is loaded.
00730  *
00731  * @var boolean
00732  * @access public
00733  */
00734     var $return = false;
00735 /**
00736  * Determines if $__maps and $__paths cache should be written.
00737  *
00738  * @var boolean
00739  * @access private
00740  */
00741     var $__cache = false;
00742 /**
00743  * Holds key/value pairs of $type => file path.
00744  *
00745  * @var array
00746  * @access private
00747  */
00748     var $__map = array();
00749 /**
00750  * Holds paths for deep searching of files.
00751  *
00752  * @var array
00753  * @access private
00754  */
00755     var $__paths = array();
00756 /**
00757  * Holds loaded files.
00758  *
00759  * @var array
00760  * @access private
00761  */
00762     var $__loaded = array();
00763 /**
00764  * Finds classes based on $name or specific file(s) to search.
00765  *
00766  * @link          http://book.cakephp.org/view/529/Using-App-import
00767  * @param mixed $type The type of Class if passed as a string, or all params can be passed as
00768  *                    an single array to $type,
00769  * @param string $name Name of the Class or a unique name for the file
00770  * @param mixed $parent boolean true if Class Parent should be searched, accepts key => value
00771  *              array('parent' => $parent ,'file' => $file, 'search' => $search, 'ext' => '$ext');
00772  *              $ext allows setting the extension of the file name
00773  *              based on Inflector::underscore($name) . ".$ext";
00774  * @param array $search paths to search for files, array('path 1', 'path 2', 'path 3');
00775  * @param string $file full name of the file to search for including extension
00776  * @param boolean $return, return the loaded file, the file must have a return
00777  *                         statement in it to work: return $variable;
00778  * @return boolean true if Class is already in memory or if file is found and loaded, false if not
00779  * @access public
00780  */
00781     function import($type = null, $name = null, $parent = true, $search = array(), $file = null, $return = false) {
00782         $plugin = $directory = null;
00783 
00784         if (is_array($type)) {
00785             extract($type, EXTR_OVERWRITE);
00786         }
00787 
00788         if (is_array($parent)) {
00789             extract($parent, EXTR_OVERWRITE);
00790         }
00791 
00792         if ($name === null && $file === null) {
00793             $name = $type;
00794             $type = 'Core';
00795         } elseif ($name === null) {
00796             $type = 'File';
00797         }
00798 
00799         if (is_array($name)) {
00800             foreach ($name as $class) {
00801                 $tempType = $type;
00802                 $plugin = null;
00803 
00804                 if (strpos($class, '.') !== false) {
00805                     $value = explode('.', $class);
00806                     $count = count($value);
00807 
00808                     if ($count > 2) {
00809                         $tempType = $value[0];
00810                         $plugin = $value[1] . '.';
00811                         $class = $value[2];
00812                     } elseif ($count === 2 && ($type === 'Core' || $type === 'File')) {
00813                         $tempType = $value[0];
00814                         $class = $value[1];
00815                     } else {
00816                         $plugin = $value[0] . '.';
00817                         $class = $value[1];
00818                     }
00819                 }
00820 
00821                 if (!App::import($tempType, $plugin . $class)) {
00822                     return false;
00823                 }
00824             }
00825             return true;
00826         }
00827 
00828         if ($name != null && strpos($name, '.') !== false) {
00829             list($plugin, $name) = explode('.', $name);
00830         }
00831         $_this =& App::getInstance();
00832         $_this->return = $return;
00833 
00834         if (isset($ext)) {
00835             $file = Inflector::underscore($name) . ".$ext";
00836         }
00837         $ext = $_this->__settings($type, $plugin, $parent);
00838 
00839         if ($name != null && !class_exists($name . $ext['class'])) {
00840             if ($load = $_this->__mapped($name . $ext['class'], $type, $plugin)) {
00841                 if ($_this->__load($load)) {
00842                     $_this->__overload($type, $name . $ext['class']);
00843 
00844                     if ($_this->return) {
00845                         $value = include $load;
00846                         return $value;
00847                     }
00848                     return true;
00849                 } else {
00850                     $_this->__remove($name . $ext['class'], $type, $plugin);
00851                     $_this->__cache = true;
00852                 }
00853             }
00854             if (!empty($search)) {
00855                 $_this->search = $search;
00856             } elseif ($plugin) {
00857                 $_this->search = $_this->__paths('plugin');
00858             } else {
00859                 $_this->search = $_this->__paths($type);
00860             }
00861             $find = $file;
00862 
00863             if ($find === null) {
00864                 $find = Inflector::underscore($name . $ext['suffix']).'.php';
00865 
00866                 if ($plugin) {
00867                     $paths = $_this->search;
00868                     foreach ($paths as $key => $value) {
00869                         $_this->search[$key] = $value . $ext['path'];
00870                     }
00871                     $plugin = Inflector::camelize($plugin);
00872                 }
00873             }
00874 
00875             if (strtolower($type) !== 'vendor' && empty($search) && $_this->__load($file)) {
00876                 $directory = false;
00877             } else {
00878                 $file = $find;
00879                 $directory = $_this->__find($find, true);
00880             }
00881 
00882             if ($directory !== null) {
00883                 $_this->__cache = true;
00884                 $_this->__map($directory . $file, $name . $ext['class'], $type, $plugin);
00885                 $_this->__overload($type, $name . $ext['class']);
00886 
00887                 if ($_this->return) {
00888                     $value = include $directory . $file;
00889                     return $value;
00890                 }
00891                 return true;
00892             }
00893             return false;
00894         }
00895         return true;
00896     }
00897 /**
00898  * Returns a single instance of App.
00899  *
00900  * @return object
00901  * @access public
00902  */
00903     function &getInstance() {
00904         static $instance = array();
00905         if (!$instance) {
00906             $instance[0] =& new App();
00907             $instance[0]->__map = Cache::read('file_map', '_cake_core_');
00908         }
00909         return $instance[0];
00910     }
00911 /**
00912  * Locates the $file in $__paths, searches recursively.
00913  *
00914  * @param string $file full file name
00915  * @param boolean $recursive search $__paths recursively
00916  * @return mixed boolean on fail, $file directory path on success
00917  * @access private
00918  */
00919     function __find($file, $recursive = true) {
00920         if (empty($this->search)) {
00921             return null;
00922         } elseif (is_string($this->search)) {
00923             $this->search = array($this->search);
00924         }
00925 
00926         if (empty($this->__paths)) {
00927             $this->__paths = Cache::read('dir_map', '_cake_core_');
00928         }
00929 
00930         foreach ($this->search as $path) {
00931             $path = rtrim($path, DS);
00932 
00933             if ($path === rtrim(APP, DS)) {
00934                 $recursive = false;
00935             }
00936             if ($recursive === false) {
00937                 if ($this->__load($path . DS . $file)) {
00938                     return $path . DS;
00939                 }
00940                 continue;
00941             }
00942             if (!isset($this->__paths[$path])) {
00943                 if (!class_exists('Folder')) {
00944                     require LIBS . 'folder.php';
00945                 }
00946                 $Folder =& new Folder();
00947                 $directories = $Folder->tree($path, false, 'dir');
00948                 $this->__paths[$path] = $directories;
00949             }
00950 
00951             foreach ($this->__paths[$path] as $directory) {
00952                 if ($this->__load($directory . DS . $file)) {
00953                     return $directory . DS;
00954                 }
00955             }
00956         }
00957         return null;
00958     }
00959 /**
00960  * Attempts to load $file.
00961  *
00962  * @param string $file full path to file including file name
00963  * @return boolean
00964  * @access private
00965  */
00966     function __load($file) {
00967         if (empty($file)) {
00968             return false;
00969         }
00970         if (!$this->return && isset($this->__loaded[$file])) {
00971             return true;
00972         }
00973         if (file_exists($file)) {
00974             if (!$this->return) {
00975                 require($file);
00976                 $this->__loaded[$file] = true;
00977             }
00978             return true;
00979         }
00980         return false;
00981     }
00982 /**
00983  * Maps the $name to the $file.
00984  *
00985  * @param string $file full path to file
00986  * @param string $name unique name for this map
00987  * @param string $type type object being mapped
00988  * @param string $plugin if object is from a plugin, the name of the plugin
00989  * @access private
00990  */
00991     function __map($file, $name, $type, $plugin) {
00992         if ($plugin) {
00993             $plugin = Inflector::camelize($plugin);
00994             $this->__map['Plugin'][$plugin][$type][$name] = $file;
00995         } else {
00996             $this->__map[$type][$name] = $file;
00997         }
00998     }
00999 /**
01000  * Returns a file's complete path.
01001  *
01002  * @param string $name unique name
01003  * @param string $type type object
01004  * @param string $plugin if object is from a plugin, the name of the plugin
01005  * @return mixed, file path if found, false otherwise
01006  * @access private
01007  */
01008     function __mapped($name, $type, $plugin) {
01009         if ($plugin) {
01010             $plugin = Inflector::camelize($plugin);
01011 
01012             if (isset($this->__map['Plugin'][$plugin][$type]) && isset($this->__map['Plugin'][$plugin][$type][$name])) {
01013                 return $this->__map['Plugin'][$plugin][$type][$name];
01014             }
01015             return false;
01016         }
01017 
01018         if (isset($this->__map[$type]) && isset($this->__map[$type][$name])) {
01019             return $this->__map[$type][$name];
01020         }
01021         return false;
01022     }
01023 /**
01024  * Used to overload objects as needed.
01025  *
01026  * @param string $type Model or Helper
01027  * @param string $name Class name to overload
01028  * @access private
01029  */
01030     function __overload($type, $name) {
01031         if (($type === 'Model' || $type === 'Helper') && strtolower($name) != 'schema') {
01032             Overloadable::overload($name);
01033         }
01034     }
01035 /**
01036  * Loads parent classes based on $type.
01037  * Returns a prefix or suffix needed for loading files.
01038  *
01039  * @param string $type type of object
01040  * @param string $plugin name of plugin
01041  * @param boolean $parent false will not attempt to load parent
01042  * @return array
01043  * @access private
01044  */
01045     function __settings($type, $plugin, $parent) {
01046         if (!$parent) {
01047             return null;
01048         }
01049 
01050         if ($plugin) {
01051             $plugin = Inflector::underscore($plugin);
01052             $name = Inflector::camelize($plugin);
01053         }
01054         $path = null;
01055         $load = strtolower($type);
01056 
01057         switch ($load) {
01058             case 'model':
01059                 if (!class_exists('Model')) {
01060                     App::import('Core', 'Model', false, Configure::corePaths('model'));
01061                 }
01062                 if (!class_exists('AppModel')) {
01063                     App::import($type, 'AppModel', false, Configure::read('modelPaths'));
01064                 }
01065                 if ($plugin) {
01066                     if (!class_exists($name . 'AppModel')) {
01067                         App::import($type, $plugin . '.' . $name . 'AppModel', false, array(), $plugin . DS . $plugin . '_app_model.php');
01068                     }
01069                     $path = $plugin . DS . 'models' . DS;
01070                 }
01071                 return array('class' => null, 'suffix' => null, 'path' => $path);
01072             break;
01073             case 'behavior':
01074                 if ($plugin) {
01075                     $path = $plugin . DS . 'models' . DS . 'behaviors' . DS;
01076                 }
01077                 return array('class' => $type, 'suffix' => null, 'path' => $path);
01078             break;
01079             case 'controller':
01080                 App::import($type, 'AppController', false);
01081                 if ($plugin) {
01082                     App::import($type, $plugin . '.' . $name . 'AppController', false, array(), $plugin . DS . $plugin . '_app_controller.php');
01083                     $path = $plugin . DS . 'controllers' . DS;
01084                 }
01085                 return array('class' => $type, 'suffix' => $type, 'path' => $path);
01086             break;
01087             case 'component':
01088                 if ($plugin) {
01089                     $path = $plugin . DS . 'controllers' . DS . 'components' . DS;
01090                 }
01091                 return array('class' => $type, 'suffix' => null, 'path' => $path);
01092             break;
01093             case 'view':
01094                 if ($plugin) {
01095                     $path = $plugin . DS . 'views' . DS;
01096                 }
01097                 return array('class' => $type, 'suffix' => null, 'path' => $path);
01098             break;
01099             case 'helper':
01100                 if (!class_exists('AppHelper')) {
01101                     App::import($type, 'AppHelper', false);
01102                 }
01103                 if ($plugin) {
01104                     $path = $plugin . DS . 'views' . DS . 'helpers' . DS;
01105                 }
01106                 return array('class' => $type, 'suffix' => null, 'path' => $path);
01107             break;
01108             case 'vendor':
01109                 if ($plugin) {
01110                     $path = $plugin . DS . 'vendors' . DS;
01111                 }
01112                 return array('class' => null, 'suffix' => null, 'path' => $path);
01113             break;
01114             default:
01115                 $type = $suffix = $path = null;
01116             break;
01117         }
01118         return array('class' => null, 'suffix' => null, 'path' => null);
01119     }
01120 /**
01121  * Returns default search paths.
01122  *
01123  * @param string $type type of object to be searched
01124  * @return array list of paths
01125  * @access private
01126  */
01127     function __paths($type) {
01128         $type = strtolower($type);
01129 
01130         if ($type === 'core') {
01131             $path = Configure::corePaths();
01132             $paths = array();
01133 
01134             foreach ($path as $key => $value) {
01135                 $count = count($key);
01136                 for ($i = 0; $i < $count; $i++) {
01137                     $paths[] = $path[$key][$i];
01138                 }
01139             }
01140             return $paths;
01141         }
01142 
01143         if ($paths = Configure::read($type . 'Paths')) {
01144             return $paths;
01145         }
01146 
01147         switch ($type) {
01148             case 'plugin':
01149                 return array(APP . 'plugins' . DS);
01150             case 'vendor':
01151                 return array(APP . 'vendors' . DS, VENDORS, APP . 'plugins' . DS);
01152             case 'controller':
01153                 return array(APP . 'controllers' . DS, APP);
01154             case 'model':
01155                 return array(APP . 'models' . DS, APP);
01156             case 'view':
01157                 return array(APP . 'views' . DS);
01158         }
01159     }
01160 /**
01161  * Removes file location from map if the file has been deleted.
01162  *
01163  * @param string $name name of object
01164  * @param string $type type of object
01165  * @param string $plugin name of plugin
01166  * @return void
01167  * @access private
01168  */
01169     function __remove($name, $type, $plugin) {
01170         if ($plugin) {
01171             $plugin = Inflector::camelize($plugin);
01172             unset($this->__map['Plugin'][$plugin][$type][$name]);
01173         } else {
01174             unset($this->__map[$type][$name]);
01175         }
01176     }
01177 /**
01178  * Object destructor.
01179  *
01180  * Writes cache file if changes have been made to the $__map or $__paths
01181  *
01182  * @return void
01183  * @access private
01184  */
01185     function __destruct() {
01186         if ($this->__cache) {
01187             $core = Configure::corePaths('cake');
01188             unset($this->__paths[rtrim($core[0], DS)]);
01189             Cache::write('dir_map', array_filter($this->__paths), '_cake_core_');
01190             Cache::write('file_map', array_filter($this->__map), '_cake_core_');
01191         }
01192     }
01193 }
01194 ?>

Generated on Sun Nov 22 00:30:52 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7