pictcode / lib / Cake / Core / App.php @ 001918d1
履歴 | 表示 | アノテート | ダウンロード (27.506 KB)
| 1 | 
      <?php
     | 
  
|---|---|
| 2 | 
      /**
     | 
  
| 3 | 
       * App class
     | 
  
| 4 | 
       *
     | 
  
| 5 | 
       * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
     | 
  
| 6 | 
       * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
     | 
  
| 7 | 
       *
     | 
  
| 8 | 
       * Licensed under The MIT License
     | 
  
| 9 | 
       * For full copyright and license information, please see the LICENSE.txt
     | 
  
| 10 | 
       * Redistributions of files must retain the above copyright notice.
     | 
  
| 11 | 
       *
     | 
  
| 12 | 
       * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
     | 
  
| 13 | 
       * @link          http://cakephp.org CakePHP(tm) Project
     | 
  
| 14 | 
       * @package       Cake.Core
     | 
  
| 15 | 
       * @since         CakePHP(tm) v 1.2.0.6001
     | 
  
| 16 | 
       * @license       http://www.opensource.org/licenses/mit-license.php MIT License
     | 
  
| 17 | 
       */
     | 
  
| 18 | 
       | 
  
| 19 | 
      App::uses('Inflector', 'Utility');  | 
  
| 20 | 
      App::uses('CakePlugin', 'Core');  | 
  
| 21 | 
       | 
  
| 22 | 
      /**
     | 
  
| 23 | 
       * App is responsible for path management, class location and class loading.
     | 
  
| 24 | 
       *
     | 
  
| 25 | 
       * ### Adding paths
     | 
  
| 26 | 
       *
     | 
  
| 27 | 
       * You can add paths to the search indexes App uses to find classes using `App::build()`. Adding
     | 
  
| 28 | 
       * additional controller paths for example would alter where CakePHP looks for controllers.
     | 
  
| 29 | 
       * This allows you to split your application up across the filesystem.
     | 
  
| 30 | 
       *
     | 
  
| 31 | 
       * ### Packages
     | 
  
| 32 | 
       *
     | 
  
| 33 | 
       * CakePHP is organized around the idea of packages, each class belongs to a package or folder where other
     | 
  
| 34 | 
       * classes reside. You can configure each package location in your application using `App::build('APackage/SubPackage', $paths)`
     | 
  
| 35 | 
       * to inform the framework where should each class be loaded. Almost every class in the CakePHP framework can be swapped
     | 
  
| 36 | 
       * by your own compatible implementation. If you wish to use your own class instead of the classes the framework provides,
     | 
  
| 37 | 
       * just add the class to your libs folder mocking the directory location of where CakePHP expects to find it.
     | 
  
| 38 | 
       *
     | 
  
| 39 | 
       * For instance if you'd like to use your own HttpSocket class, put it under
     | 
  
| 40 | 
       *
     | 
  
| 41 | 
       *                app/Network/Http/HttpSocket.php
     | 
  
| 42 | 
       *
     | 
  
| 43 | 
       * ### Inspecting loaded paths
     | 
  
| 44 | 
       *
     | 
  
| 45 | 
       * You can inspect the currently loaded paths using `App::path('Controller')` for example to see loaded
     | 
  
| 46 | 
       * controller paths.
     | 
  
| 47 | 
       *
     | 
  
| 48 | 
       * It is also possible to inspect paths for plugin classes, for instance, to see a plugin's helpers you would call
     | 
  
| 49 | 
       * `App::path('View/Helper', 'MyPlugin')`
     | 
  
| 50 | 
       *
     | 
  
| 51 | 
       * ### Locating plugins and themes
     | 
  
| 52 | 
       *
     | 
  
| 53 | 
       * Plugins and Themes can be located with App as well. Using App::pluginPath('DebugKit') for example, will
     | 
  
| 54 | 
       * give you the full path to the DebugKit plugin. App::themePath('purple'), would give the full path to the
     | 
  
| 55 | 
       * `purple` theme.
     | 
  
| 56 | 
       *
     | 
  
| 57 | 
       * ### Inspecting known objects
     | 
  
| 58 | 
       *
     | 
  
| 59 | 
       * You can find out which objects App knows about using App::objects('Controller') for example to find
     | 
  
| 60 | 
       * which application controllers App knows about.
     | 
  
| 61 | 
       *
     | 
  
| 62 | 
       * @link          http://book.cakephp.org/2.0/en/core-utility-libraries/app.html
     | 
  
| 63 | 
       * @package       Cake.Core
     | 
  
| 64 | 
       */
     | 
  
| 65 | 
      class App {  | 
  
| 66 | 
       | 
  
| 67 | 
      /**
     | 
  
| 68 | 
       * Append paths
     | 
  
| 69 | 
       *
     | 
  
| 70 | 
       * @var string
     | 
  
| 71 | 
       */
     | 
  
| 72 | 
      const APPEND = 'append';  | 
  
| 73 | 
       | 
  
| 74 | 
      /**
     | 
  
| 75 | 
       * Prepend paths
     | 
  
| 76 | 
       *
     | 
  
| 77 | 
       * @var string
     | 
  
| 78 | 
       */
     | 
  
| 79 | 
      const PREPEND = 'prepend';  | 
  
| 80 | 
       | 
  
| 81 | 
      /**
     | 
  
| 82 | 
       * Register package
     | 
  
| 83 | 
       *
     | 
  
| 84 | 
       * @var string
     | 
  
| 85 | 
       */
     | 
  
| 86 | 
      const REGISTER = 'register';  | 
  
| 87 | 
       | 
  
| 88 | 
      /**
     | 
  
| 89 | 
       * Reset paths instead of merging
     | 
  
| 90 | 
       *
     | 
  
| 91 | 
       * @var bool
     | 
  
| 92 | 
       */
     | 
  
| 93 | 
      const RESET = true;  | 
  
| 94 | 
       | 
  
| 95 | 
      /**
     | 
  
| 96 | 
       * List of object types and their properties
     | 
  
| 97 | 
       *
     | 
  
| 98 | 
       * @var array
     | 
  
| 99 | 
       */
     | 
  
| 100 | 
      public static $types = array(  | 
  
| 101 | 
      'class' => array('extends' => null, 'core' => true),  | 
  
| 102 | 
      'file' => array('extends' => null, 'core' => true),  | 
  
| 103 | 
      'model' => array('extends' => 'AppModel', 'core' => false),  | 
  
| 104 | 
      'behavior' => array('suffix' => 'Behavior', 'extends' => 'Model/ModelBehavior', 'core' => true),  | 
  
| 105 | 
      'controller' => array('suffix' => 'Controller', 'extends' => 'AppController', 'core' => true),  | 
  
| 106 | 
      'component' => array('suffix' => 'Component', 'extends' => null, 'core' => true),  | 
  
| 107 | 
      'lib' => array('extends' => null, 'core' => true),  | 
  
| 108 | 
      'view' => array('suffix' => 'View', 'extends' => null, 'core' => true),  | 
  
| 109 | 
      'helper' => array('suffix' => 'Helper', 'extends' => 'AppHelper', 'core' => true),  | 
  
| 110 | 
      'vendor' => array('extends' => null, 'core' => true),  | 
  
| 111 | 
      'shell' => array('suffix' => 'Shell', 'extends' => 'AppShell', 'core' => true),  | 
  
| 112 | 
      'plugin' => array('extends' => null, 'core' => true)  | 
  
| 113 | 
      );  | 
  
| 114 | 
       | 
  
| 115 | 
      /**
     | 
  
| 116 | 
       * Paths to search for files.
     | 
  
| 117 | 
       *
     | 
  
| 118 | 
       * @var array
     | 
  
| 119 | 
       */
     | 
  
| 120 | 
      public static $search = array();  | 
  
| 121 | 
       | 
  
| 122 | 
      /**
     | 
  
| 123 | 
       * Whether or not to return the file that is loaded.
     | 
  
| 124 | 
       *
     | 
  
| 125 | 
       * @var bool
     | 
  
| 126 | 
       */
     | 
  
| 127 | 
      public static $return = false;  | 
  
| 128 | 
       | 
  
| 129 | 
      /**
     | 
  
| 130 | 
       * Holds key/value pairs of $type => file path.
     | 
  
| 131 | 
       *
     | 
  
| 132 | 
       * @var array
     | 
  
| 133 | 
       */
     | 
  
| 134 | 
      protected static $_map = array();  | 
  
| 135 | 
       | 
  
| 136 | 
      /**
     | 
  
| 137 | 
       * Holds and key => value array of object types.
     | 
  
| 138 | 
       *
     | 
  
| 139 | 
       * @var array
     | 
  
| 140 | 
       */
     | 
  
| 141 | 
      protected static $_objects = array();  | 
  
| 142 | 
       | 
  
| 143 | 
      /**
     | 
  
| 144 | 
       * Holds the location of each class
     | 
  
| 145 | 
       *
     | 
  
| 146 | 
       * @var array
     | 
  
| 147 | 
       */
     | 
  
| 148 | 
      protected static $_classMap = array();  | 
  
| 149 | 
       | 
  
| 150 | 
      /**
     | 
  
| 151 | 
       * Holds the possible paths for each package name
     | 
  
| 152 | 
       *
     | 
  
| 153 | 
       * @var array
     | 
  
| 154 | 
       */
     | 
  
| 155 | 
      protected static $_packages = array();  | 
  
| 156 | 
       | 
  
| 157 | 
      /**
     | 
  
| 158 | 
       * Holds the templates for each customizable package path in the application
     | 
  
| 159 | 
       *
     | 
  
| 160 | 
       * @var array
     | 
  
| 161 | 
       */
     | 
  
| 162 | 
      protected static $_packageFormat = array();  | 
  
| 163 | 
       | 
  
| 164 | 
      /**
     | 
  
| 165 | 
       * Maps an old style CakePHP class type to the corresponding package
     | 
  
| 166 | 
       *
     | 
  
| 167 | 
       * @var array
     | 
  
| 168 | 
       */
     | 
  
| 169 | 
      public static $legacy = array(  | 
  
| 170 | 
      'models' => 'Model',  | 
  
| 171 | 
      'behaviors' => 'Model/Behavior',  | 
  
| 172 | 
      'datasources' => 'Model/Datasource',  | 
  
| 173 | 
      'controllers' => 'Controller',  | 
  
| 174 | 
      'components' => 'Controller/Component',  | 
  
| 175 | 
      'views' => 'View',  | 
  
| 176 | 
      'helpers' => 'View/Helper',  | 
  
| 177 | 
      'shells' => 'Console/Command',  | 
  
| 178 | 
      'libs' => 'Lib',  | 
  
| 179 | 
      'vendors' => 'Vendor',  | 
  
| 180 | 
      'plugins' => 'Plugin',  | 
  
| 181 | 
      'locales' => 'Locale'  | 
  
| 182 | 
      );  | 
  
| 183 | 
       | 
  
| 184 | 
      /**
     | 
  
| 185 | 
       * Indicates whether the class cache should be stored again because of an addition to it
     | 
  
| 186 | 
       *
     | 
  
| 187 | 
       * @var bool
     | 
  
| 188 | 
       */
     | 
  
| 189 | 
      protected static $_cacheChange = false;  | 
  
| 190 | 
       | 
  
| 191 | 
      /**
     | 
  
| 192 | 
       * Indicates whether the object cache should be stored again because of an addition to it
     | 
  
| 193 | 
       *
     | 
  
| 194 | 
       * @var bool
     | 
  
| 195 | 
       */
     | 
  
| 196 | 
      protected static $_objectCacheChange = false;  | 
  
| 197 | 
       | 
  
| 198 | 
      /**
     | 
  
| 199 | 
       * Indicates the the Application is in the bootstrapping process. Used to better cache
     | 
  
| 200 | 
       * loaded classes while the cache libraries have not been yet initialized
     | 
  
| 201 | 
       *
     | 
  
| 202 | 
       * @var bool
     | 
  
| 203 | 
       */
     | 
  
| 204 | 
      public static $bootstrapping = false;  | 
  
| 205 | 
       | 
  
| 206 | 
      /**
     | 
  
| 207 | 
       * Used to read information stored path
     | 
  
| 208 | 
       *
     | 
  
| 209 | 
       * Usage:
     | 
  
| 210 | 
       *
     | 
  
| 211 | 
       * `App::path('Model'); will return all paths for models`
     | 
  
| 212 | 
       *
     | 
  
| 213 | 
       * `App::path('Model/Datasource', 'MyPlugin'); will return the path for datasources under the 'MyPlugin' plugin`
     | 
  
| 214 | 
       *
     | 
  
| 215 | 
       * @param string $type type of path
     | 
  
| 216 | 
       * @param string $plugin name of plugin
     | 
  
| 217 | 
       * @return array
     | 
  
| 218 | 
       * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::path
     | 
  
| 219 | 
       */
     | 
  
| 220 | 
      public static function path($type, $plugin = null) {  | 
  
| 221 | 
      if (!empty(static::$legacy[$type])) {  | 
  
| 222 | 
      $type = static::$legacy[$type];  | 
  
| 223 | 
      }  | 
  
| 224 | 
       | 
  
| 225 | 
      if (!empty($plugin)) {  | 
  
| 226 | 
      $path = array();  | 
  
| 227 | 
      $pluginPath = CakePlugin::path($plugin);  | 
  
| 228 | 
      $packageFormat = static::_packageFormat();  | 
  
| 229 | 
      if (!empty($packageFormat[$type])) {  | 
  
| 230 | 
      foreach ($packageFormat[$type] as $f) {  | 
  
| 231 | 
      $path[] = sprintf($f, $pluginPath);  | 
  
| 232 | 
      }  | 
  
| 233 | 
      }  | 
  
| 234 | 
      return $path;  | 
  
| 235 | 
      }  | 
  
| 236 | 
       | 
  
| 237 | 
      if (!isset(static::$_packages[$type])) {  | 
  
| 238 | 
      return array();  | 
  
| 239 | 
      }  | 
  
| 240 | 
      return static::$_packages[$type];  | 
  
| 241 | 
      }  | 
  
| 242 | 
       | 
  
| 243 | 
      /**
     | 
  
| 244 | 
       * Get all the currently loaded paths from App. Useful for inspecting
     | 
  
| 245 | 
       * or storing all paths App knows about. For a paths to a specific package
     | 
  
| 246 | 
       * use App::path()
     | 
  
| 247 | 
       *
     | 
  
| 248 | 
       * @return array An array of packages and their associated paths.
     | 
  
| 249 | 
       * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::paths
     | 
  
| 250 | 
       */
     | 
  
| 251 | 
      public static function paths() {  | 
  
| 252 | 
      return static::$_packages;  | 
  
| 253 | 
      }  | 
  
| 254 | 
       | 
  
| 255 | 
      /**
     | 
  
| 256 | 
       * Sets up each package location on the file system. You can configure multiple search paths
     | 
  
| 257 | 
       * for each package, those will be used to look for files one folder at a time in the specified order
     | 
  
| 258 | 
       * All paths should be terminated with a Directory separator
     | 
  
| 259 | 
       *
     | 
  
| 260 | 
       * Usage:
     | 
  
| 261 | 
       *
     | 
  
| 262 | 
       * `App::build(array('Model' => array('/a/full/path/to/models/'))); will setup a new search path for the Model package`
     | 
  
| 263 | 
       *
     | 
  
| 264 | 
       * `App::build(array('Model' => array('/path/to/models/')), App::RESET); will setup the path as the only valid path for searching models`
     | 
  
| 265 | 
       *
     | 
  
| 266 | 
       * `App::build(array('View/Helper' => array('/path/to/helpers/', '/another/path/'))); will setup multiple search paths for helpers`
     | 
  
| 267 | 
       *
     | 
  
| 268 | 
       * `App::build(array('Service' => array('%s' . 'Service' . DS)), App::REGISTER); will register new package 'Service'`
     | 
  
| 269 | 
       *
     | 
  
| 270 | 
       * If reset is set to true, all loaded plugins will be forgotten and they will be needed to be loaded again.
     | 
  
| 271 | 
       *
     | 
  
| 272 | 
       * @param array $paths associative array with package names as keys and a list of directories for new search paths
     | 
  
| 273 | 
       * @param bool|string $mode App::RESET will set paths, App::APPEND with append paths, App::PREPEND will prepend paths (default)
     | 
  
| 274 | 
       *         App::REGISTER will register new packages and their paths, %s in path will be replaced by APP path
     | 
  
| 275 | 
       * @return void
     | 
  
| 276 | 
       * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::build
     | 
  
| 277 | 
       */
     | 
  
| 278 | 
      public static function build($paths = array(), $mode = App::PREPEND) {  | 
  
| 279 | 
                      //Provides Backwards compatibility for old-style package names
     | 
  
| 280 | 
      $legacyPaths = array();  | 
  
| 281 | 
      foreach ($paths as $type => $path) {  | 
  
| 282 | 
      if (!empty(static::$legacy[$type])) {  | 
  
| 283 | 
      $type = static::$legacy[$type];  | 
  
| 284 | 
      }  | 
  
| 285 | 
      $legacyPaths[$type] = $path;  | 
  
| 286 | 
      }  | 
  
| 287 | 
      $paths = $legacyPaths;  | 
  
| 288 | 
       | 
  
| 289 | 
      if ($mode === App::RESET) {  | 
  
| 290 | 
      foreach ($paths as $type => $new) {  | 
  
| 291 | 
      static::$_packages[$type] = (array)$new;  | 
  
| 292 | 
      static::objects($type, null, false);  | 
  
| 293 | 
      }  | 
  
| 294 | 
                              return;
     | 
  
| 295 | 
      }  | 
  
| 296 | 
       | 
  
| 297 | 
      if (empty($paths)) {  | 
  
| 298 | 
      static::$_packageFormat = null;  | 
  
| 299 | 
      }  | 
  
| 300 | 
       | 
  
| 301 | 
      $packageFormat = static::_packageFormat();  | 
  
| 302 | 
       | 
  
| 303 | 
      if ($mode === App::REGISTER) {  | 
  
| 304 | 
      foreach ($paths as $package => $formats) {  | 
  
| 305 | 
      if (empty($packageFormat[$package])) {  | 
  
| 306 | 
      $packageFormat[$package] = $formats;  | 
  
| 307 | 
                                      } else {
     | 
  
| 308 | 
      $formats = array_merge($packageFormat[$package], $formats);  | 
  
| 309 | 
      $packageFormat[$package] = array_values(array_unique($formats));  | 
  
| 310 | 
      }  | 
  
| 311 | 
      }  | 
  
| 312 | 
      static::$_packageFormat = $packageFormat;  | 
  
| 313 | 
      }  | 
  
| 314 | 
       | 
  
| 315 | 
      $defaults = array();  | 
  
| 316 | 
      foreach ($packageFormat as $package => $format) {  | 
  
| 317 | 
      foreach ($format as $f) {  | 
  
| 318 | 
      $defaults[$package][] = sprintf($f, APP);  | 
  
| 319 | 
      }  | 
  
| 320 | 
      }  | 
  
| 321 | 
       | 
  
| 322 | 
      if (empty($paths)) {  | 
  
| 323 | 
      static::$_packages = $defaults;  | 
  
| 324 | 
                              return;
     | 
  
| 325 | 
      }  | 
  
| 326 | 
       | 
  
| 327 | 
      if ($mode === App::REGISTER) {  | 
  
| 328 | 
      $paths = array();  | 
  
| 329 | 
      }  | 
  
| 330 | 
       | 
  
| 331 | 
      foreach ($defaults as $type => $default) {  | 
  
| 332 | 
      if (!empty(static::$_packages[$type])) {  | 
  
| 333 | 
      $path = static::$_packages[$type];  | 
  
| 334 | 
                              } else {
     | 
  
| 335 | 
      $path = $default;  | 
  
| 336 | 
      }  | 
  
| 337 | 
       | 
  
| 338 | 
      if (!empty($paths[$type])) {  | 
  
| 339 | 
      $newPath = (array)$paths[$type];  | 
  
| 340 | 
       | 
  
| 341 | 
      if ($mode === App::PREPEND) {  | 
  
| 342 | 
      $path = array_merge($newPath, $path);  | 
  
| 343 | 
                                      } else {
     | 
  
| 344 | 
      $path = array_merge($path, $newPath);  | 
  
| 345 | 
      }  | 
  
| 346 | 
       | 
  
| 347 | 
      $path = array_values(array_unique($path));  | 
  
| 348 | 
      }  | 
  
| 349 | 
       | 
  
| 350 | 
      static::$_packages[$type] = $path;  | 
  
| 351 | 
      }  | 
  
| 352 | 
      }  | 
  
| 353 | 
       | 
  
| 354 | 
      /**
     | 
  
| 355 | 
       * Gets the path that a plugin is on. Searches through the defined plugin paths.
     | 
  
| 356 | 
       *
     | 
  
| 357 | 
       * Usage:
     | 
  
| 358 | 
       *
     | 
  
| 359 | 
       * `App::pluginPath('MyPlugin'); will return the full path to 'MyPlugin' plugin'`
     | 
  
| 360 | 
       *
     | 
  
| 361 | 
       * @param string $plugin CamelCased/lower_cased plugin name to find the path of.
     | 
  
| 362 | 
       * @return string full path to the plugin.
     | 
  
| 363 | 
       * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::pluginPath
     | 
  
| 364 | 
       * @deprecated 3.0.0 Use `CakePlugin::path()` instead.
     | 
  
| 365 | 
       */
     | 
  
| 366 | 
      public static function pluginPath($plugin) {  | 
  
| 367 | 
      return CakePlugin::path($plugin);  | 
  
| 368 | 
      }  | 
  
| 369 | 
       | 
  
| 370 | 
      /**
     | 
  
| 371 | 
       * Finds the path that a theme is on. Searches through the defined theme paths.
     | 
  
| 372 | 
       *
     | 
  
| 373 | 
       * Usage:
     | 
  
| 374 | 
       *
     | 
  
| 375 | 
       * `App::themePath('MyTheme'); will return the full path to the 'MyTheme' theme`
     | 
  
| 376 | 
       *
     | 
  
| 377 | 
       * @param string $theme theme name to find the path of.
     | 
  
| 378 | 
       * @return string full path to the theme.
     | 
  
| 379 | 
       * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::themePath
     | 
  
| 380 | 
       */
     | 
  
| 381 | 
      public static function themePath($theme) {  | 
  
| 382 | 
      $themeDir = 'Themed' . DS . Inflector::camelize($theme);  | 
  
| 383 | 
      foreach (static::$_packages['View'] as $path) {  | 
  
| 384 | 
      if (is_dir($path . $themeDir)) {  | 
  
| 385 | 
      return $path . $themeDir . DS;  | 
  
| 386 | 
      }  | 
  
| 387 | 
      }  | 
  
| 388 | 
      return static::$_packages['View'][0] . $themeDir . DS;  | 
  
| 389 | 
      }  | 
  
| 390 | 
       | 
  
| 391 | 
      /**
     | 
  
| 392 | 
       * Returns the full path to a package inside the CakePHP core
     | 
  
| 393 | 
       *
     | 
  
| 394 | 
       * Usage:
     | 
  
| 395 | 
       *
     | 
  
| 396 | 
       * `App::core('Cache/Engine'); will return the full path to the cache engines package`
     | 
  
| 397 | 
       *
     | 
  
| 398 | 
       * @param string $type Package type.
     | 
  
| 399 | 
       * @return array full path to package
     | 
  
| 400 | 
       * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::core
     | 
  
| 401 | 
       */
     | 
  
| 402 | 
      public static function core($type) {  | 
  
| 403 | 
      return array(CAKE . str_replace('/', DS, $type) . DS);  | 
  
| 404 | 
      }  | 
  
| 405 | 
       | 
  
| 406 | 
      /**
     | 
  
| 407 | 
       * Returns an array of objects of the given type.
     | 
  
| 408 | 
       *
     | 
  
| 409 | 
       * Example usage:
     | 
  
| 410 | 
       *
     | 
  
| 411 | 
       * `App::objects('plugin');` returns `array('DebugKit', 'Blog', 'User');`
     | 
  
| 412 | 
       *
     | 
  
| 413 | 
       * `App::objects('Controller');` returns `array('PagesController', 'BlogController');`
     | 
  
| 414 | 
       *
     | 
  
| 415 | 
       * You can also search only within a plugin's objects by using the plugin dot
     | 
  
| 416 | 
       * syntax.
     | 
  
| 417 | 
       *
     | 
  
| 418 | 
       * `App::objects('MyPlugin.Model');` returns `array('MyPluginPost', 'MyPluginComment');`
     | 
  
| 419 | 
       *
     | 
  
| 420 | 
       * When scanning directories, files and directories beginning with `.` will be excluded as these
     | 
  
| 421 | 
       * are commonly used by version control systems.
     | 
  
| 422 | 
       *
     | 
  
| 423 | 
       * @param string $type Type of object, i.e. 'Model', 'Controller', 'View/Helper', 'file', 'class' or 'plugin'
     | 
  
| 424 | 
       * @param string|array $path Optional Scan only the path given. If null, paths for the chosen type will be used.
     | 
  
| 425 | 
       * @param bool $cache Set to false to rescan objects of the chosen type. Defaults to true.
     | 
  
| 426 | 
       * @return mixed Either false on incorrect / miss. Or an array of found objects.
     | 
  
| 427 | 
       * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::objects
     | 
  
| 428 | 
       */
     | 
  
| 429 | 
      public static function objects($type, $path = null, $cache = true) {  | 
  
| 430 | 
      if (empty(static::$_objects) && $cache === true) {  | 
  
| 431 | 
      static::$_objects = (array)Cache::read('object_map', '_cake_core_');  | 
  
| 432 | 
      }  | 
  
| 433 | 
       | 
  
| 434 | 
      $extension = '/\.php$/';  | 
  
| 435 | 
      $includeDirectories = false;  | 
  
| 436 | 
      $name = $type;  | 
  
| 437 | 
       | 
  
| 438 | 
      if ($type === 'plugin') {  | 
  
| 439 | 
      $type = 'plugins';  | 
  
| 440 | 
      }  | 
  
| 441 | 
       | 
  
| 442 | 
      if ($type === 'plugins') {  | 
  
| 443 | 
      $extension = '/.*/';  | 
  
| 444 | 
      $includeDirectories = true;  | 
  
| 445 | 
      }  | 
  
| 446 | 
       | 
  
| 447 | 
      list($plugin, $type) = pluginSplit($type);  | 
  
| 448 | 
       | 
  
| 449 | 
      if (isset(static::$legacy[$type . 's'])) {  | 
  
| 450 | 
      $type = static::$legacy[$type . 's'];  | 
  
| 451 | 
      }  | 
  
| 452 | 
       | 
  
| 453 | 
      if ($type === 'file' && !$path) {  | 
  
| 454 | 
      return false;  | 
  
| 455 | 
      } elseif ($type === 'file') {  | 
  
| 456 | 
      $extension = '/\.php$/';  | 
  
| 457 | 
      $name = $type . str_replace(DS, '', $path);  | 
  
| 458 | 
      }  | 
  
| 459 | 
       | 
  
| 460 | 
      $cacheLocation = empty($plugin) ? 'app' : $plugin;  | 
  
| 461 | 
       | 
  
| 462 | 
      if ($cache !== true || !isset(static::$_objects[$cacheLocation][$name])) {  | 
  
| 463 | 
      $objects = array();  | 
  
| 464 | 
       | 
  
| 465 | 
      if (empty($path)) {  | 
  
| 466 | 
      $path = static::path($type, $plugin);  | 
  
| 467 | 
      }  | 
  
| 468 | 
       | 
  
| 469 | 
      foreach ((array)$path as $dir) {  | 
  
| 470 | 
      if ($dir != APP && is_dir($dir)) {  | 
  
| 471 | 
      $files = new RegexIterator(new DirectoryIterator($dir), $extension);  | 
  
| 472 | 
      foreach ($files as $file) {  | 
  
| 473 | 
      $fileName = basename($file);  | 
  
| 474 | 
      if (!$file->isDot() && $fileName[0] !== '.') {  | 
  
| 475 | 
      $isDir = $file->isDir();  | 
  
| 476 | 
      if ($isDir && $includeDirectories) {  | 
  
| 477 | 
      $objects[] = $fileName;  | 
  
| 478 | 
      } elseif (!$includeDirectories && !$isDir) {  | 
  
| 479 | 
      $objects[] = substr($fileName, 0, -4);  | 
  
| 480 | 
      }  | 
  
| 481 | 
      }  | 
  
| 482 | 
      }  | 
  
| 483 | 
      }  | 
  
| 484 | 
      }  | 
  
| 485 | 
       | 
  
| 486 | 
      if ($type !== 'file') {  | 
  
| 487 | 
      foreach ($objects as $key => $value) {  | 
  
| 488 | 
      $objects[$key] = Inflector::camelize($value);  | 
  
| 489 | 
      }  | 
  
| 490 | 
      }  | 
  
| 491 | 
       | 
  
| 492 | 
      sort($objects);  | 
  
| 493 | 
      if ($plugin) {  | 
  
| 494 | 
      return $objects;  | 
  
| 495 | 
      }  | 
  
| 496 | 
       | 
  
| 497 | 
      static::$_objects[$cacheLocation][$name] = $objects;  | 
  
| 498 | 
      if ($cache) {  | 
  
| 499 | 
      static::$_objectCacheChange = true;  | 
  
| 500 | 
      }  | 
  
| 501 | 
      }  | 
  
| 502 | 
       | 
  
| 503 | 
      return static::$_objects[$cacheLocation][$name];  | 
  
| 504 | 
      }  | 
  
| 505 | 
       | 
  
| 506 | 
      /**
     | 
  
| 507 | 
       * Declares a package for a class. This package location will be used
     | 
  
| 508 | 
       * by the automatic class loader if the class is tried to be used
     | 
  
| 509 | 
       *
     | 
  
| 510 | 
       * Usage:
     | 
  
| 511 | 
       *
     | 
  
| 512 | 
       * `App::uses('MyCustomController', 'Controller');` will setup the class to be found under Controller package
     | 
  
| 513 | 
       *
     | 
  
| 514 | 
       * `App::uses('MyHelper', 'MyPlugin.View/Helper');` will setup the helper class to be found in plugin's helper package
     | 
  
| 515 | 
       *
     | 
  
| 516 | 
       * @param string $className the name of the class to configure package for
     | 
  
| 517 | 
       * @param string $location the package name
     | 
  
| 518 | 
       * @return void
     | 
  
| 519 | 
       * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::uses
     | 
  
| 520 | 
       */
     | 
  
| 521 | 
      public static function uses($className, $location) {  | 
  
| 522 | 
      static::$_classMap[$className] = $location;  | 
  
| 523 | 
      }  | 
  
| 524 | 
       | 
  
| 525 | 
      /**
     | 
  
| 526 | 
       * Method to handle the automatic class loading. It will look for each class' package
     | 
  
| 527 | 
       * defined using App::uses() and with this information it will resolve the package name to a full path
     | 
  
| 528 | 
       * to load the class from. File name for each class should follow the class name. For instance,
     | 
  
| 529 | 
       * if a class is name `MyCustomClass` the file name should be `MyCustomClass.php`
     | 
  
| 530 | 
       *
     | 
  
| 531 | 
       * @param string $className the name of the class to load
     | 
  
| 532 | 
       * @return bool
     | 
  
| 533 | 
       */
     | 
  
| 534 | 
      public static function load($className) {  | 
  
| 535 | 
      if (!isset(static::$_classMap[$className])) {  | 
  
| 536 | 
      return false;  | 
  
| 537 | 
      }  | 
  
| 538 | 
      if (strpos($className, '..') !== false) {  | 
  
| 539 | 
      return false;  | 
  
| 540 | 
      }  | 
  
| 541 | 
       | 
  
| 542 | 
      $parts = explode('.', static::$_classMap[$className], 2);  | 
  
| 543 | 
      list($plugin, $package) = count($parts) > 1 ? $parts : array(null, current($parts));  | 
  
| 544 | 
       | 
  
| 545 | 
      $file = static::_mapped($className, $plugin);  | 
  
| 546 | 
      if ($file) {  | 
  
| 547 | 
      return include $file;  | 
  
| 548 | 
      }  | 
  
| 549 | 
      $paths = static::path($package, $plugin);  | 
  
| 550 | 
       | 
  
| 551 | 
      if (empty($plugin)) {  | 
  
| 552 | 
      $appLibs = empty(static::$_packages['Lib']) ? APPLIBS : current(static::$_packages['Lib']);  | 
  
| 553 | 
      $paths[] = $appLibs . $package . DS;  | 
  
| 554 | 
      $paths[] = APP . $package . DS;  | 
  
| 555 | 
      $paths[] = CAKE . $package . DS;  | 
  
| 556 | 
                      } else {
     | 
  
| 557 | 
      $pluginPath = CakePlugin::path($plugin);  | 
  
| 558 | 
      $paths[] = $pluginPath . 'Lib' . DS . $package . DS;  | 
  
| 559 | 
      $paths[] = $pluginPath . $package . DS;  | 
  
| 560 | 
      }  | 
  
| 561 | 
       | 
  
| 562 | 
      $normalizedClassName = str_replace('\\', DS, $className);  | 
  
| 563 | 
      foreach ($paths as $path) {  | 
  
| 564 | 
      $file = $path . $normalizedClassName . '.php';  | 
  
| 565 | 
      if (file_exists($file)) {  | 
  
| 566 | 
      static::_map($file, $className, $plugin);  | 
  
| 567 | 
      return include $file;  | 
  
| 568 | 
      }  | 
  
| 569 | 
      }  | 
  
| 570 | 
       | 
  
| 571 | 
      return false;  | 
  
| 572 | 
      }  | 
  
| 573 | 
       | 
  
| 574 | 
      /**
     | 
  
| 575 | 
       * Returns the package name where a class was defined to be located at
     | 
  
| 576 | 
       *
     | 
  
| 577 | 
       * @param string $className name of the class to obtain the package name from
     | 
  
| 578 | 
       * @return string|null Package name, or null if not declared
     | 
  
| 579 | 
       * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::location
     | 
  
| 580 | 
       */
     | 
  
| 581 | 
      public static function location($className) {  | 
  
| 582 | 
      if (!empty(static::$_classMap[$className])) {  | 
  
| 583 | 
      return static::$_classMap[$className];  | 
  
| 584 | 
      }  | 
  
| 585 | 
      return null;  | 
  
| 586 | 
      }  | 
  
| 587 | 
       | 
  
| 588 | 
      /**
     | 
  
| 589 | 
       * Finds classes based on $name or specific file(s) to search. Calling App::import() will
     | 
  
| 590 | 
       * not construct any classes contained in the files. It will only find and require() the file.
     | 
  
| 591 | 
       *
     | 
  
| 592 | 
       * @param string|array $type The type of Class if passed as a string, or all params can be passed as
     | 
  
| 593 | 
       *   a single array to $type.
     | 
  
| 594 | 
       * @param string $name Name of the Class or a unique name for the file
     | 
  
| 595 | 
       * @param bool|array $parent boolean true if Class Parent should be searched, accepts key => value
     | 
  
| 596 | 
       *   array('parent' => $parent, 'file' => $file, 'search' => $search, 'ext' => '$ext');
     | 
  
| 597 | 
       *   $ext allows setting the extension of the file name
     | 
  
| 598 | 
       *   based on Inflector::underscore($name) . ".$ext";
     | 
  
| 599 | 
       * @param array $search paths to search for files, array('path 1', 'path 2', 'path 3');
     | 
  
| 600 | 
       * @param string $file full name of the file to search for including extension
     | 
  
| 601 | 
       * @param bool $return Return the loaded file, the file must have a return
     | 
  
| 602 | 
       *   statement in it to work: return $variable;
     | 
  
| 603 | 
       * @return bool true if Class is already in memory or if file is found and loaded, false if not
     | 
  
| 604 | 
       * @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#including-files-with-app-import
     | 
  
| 605 | 
       */
     | 
  
| 606 | 
      public static function import($type = null, $name = null, $parent = true, $search = array(), $file = null, $return = false) {  | 
  
| 607 | 
      $ext = null;  | 
  
| 608 | 
       | 
  
| 609 | 
      if (is_array($type)) {  | 
  
| 610 | 
      extract($type, EXTR_OVERWRITE);  | 
  
| 611 | 
      }  | 
  
| 612 | 
       | 
  
| 613 | 
      if (is_array($parent)) {  | 
  
| 614 | 
      extract($parent, EXTR_OVERWRITE);  | 
  
| 615 | 
      }  | 
  
| 616 | 
       | 
  
| 617 | 
      if (!$name && !$file) {  | 
  
| 618 | 
      return false;  | 
  
| 619 | 
      }  | 
  
| 620 | 
       | 
  
| 621 | 
      if (is_array($name)) {  | 
  
| 622 | 
      foreach ($name as $class) {  | 
  
| 623 | 
      if (!App::import(compact('type', 'parent', 'search', 'file', 'return') + array('name' => $class))) {  | 
  
| 624 | 
      return false;  | 
  
| 625 | 
      }  | 
  
| 626 | 
      }  | 
  
| 627 | 
      return true;  | 
  
| 628 | 
      }  | 
  
| 629 | 
       | 
  
| 630 | 
      $originalType = strtolower($type);  | 
  
| 631 | 
      $specialPackage = in_array($originalType, array('file', 'vendor'));  | 
  
| 632 | 
      if (!$specialPackage && isset(static::$legacy[$originalType . 's'])) {  | 
  
| 633 | 
      $type = static::$legacy[$originalType . 's'];  | 
  
| 634 | 
      }  | 
  
| 635 | 
      list($plugin, $name) = pluginSplit($name);  | 
  
| 636 | 
      if (!empty($plugin)) {  | 
  
| 637 | 
      if (!CakePlugin::loaded($plugin)) {  | 
  
| 638 | 
      return false;  | 
  
| 639 | 
      }  | 
  
| 640 | 
      }  | 
  
| 641 | 
       | 
  
| 642 | 
      if (!$specialPackage) {  | 
  
| 643 | 
      return static::_loadClass($name, $plugin, $type, $originalType, $parent);  | 
  
| 644 | 
      }  | 
  
| 645 | 
       | 
  
| 646 | 
      if ($originalType === 'file' && !empty($file)) {  | 
  
| 647 | 
      return static::_loadFile($name, $plugin, $search, $file, $return);  | 
  
| 648 | 
      }  | 
  
| 649 | 
       | 
  
| 650 | 
      if ($originalType === 'vendor') {  | 
  
| 651 | 
      return static::_loadVendor($name, $plugin, $file, $ext);  | 
  
| 652 | 
      }  | 
  
| 653 | 
       | 
  
| 654 | 
      return false;  | 
  
| 655 | 
      }  | 
  
| 656 | 
       | 
  
| 657 | 
      /**
     | 
  
| 658 | 
       * Helper function to include classes
     | 
  
| 659 | 
       * This is a compatibility wrapper around using App::uses() and automatic class loading
     | 
  
| 660 | 
       *
     | 
  
| 661 | 
       * @param string $name unique name of the file for identifying it inside the application
     | 
  
| 662 | 
       * @param string $plugin camel cased plugin name if any
     | 
  
| 663 | 
       * @param string $type name of the packed where the class is located
     | 
  
| 664 | 
       * @param string $originalType type name as supplied initially by the user
     | 
  
| 665 | 
       * @param bool $parent whether to load the class parent or not
     | 
  
| 666 | 
       * @return bool true indicating the successful load and existence of the class
     | 
  
| 667 | 
       */
     | 
  
| 668 | 
      protected static function _loadClass($name, $plugin, $type, $originalType, $parent) {  | 
  
| 669 | 
      if ($type === 'Console/Command' && $name === 'Shell') {  | 
  
| 670 | 
      $type = 'Console';  | 
  
| 671 | 
      } elseif (isset(static::$types[$originalType]['suffix'])) {  | 
  
| 672 | 
      $suffix = static::$types[$originalType]['suffix'];  | 
  
| 673 | 
      $name .= ($suffix === $name) ? '' : $suffix;  | 
  
| 674 | 
      }  | 
  
| 675 | 
      if ($parent && isset(static::$types[$originalType]['extends'])) {  | 
  
| 676 | 
      $extends = static::$types[$originalType]['extends'];  | 
  
| 677 | 
      $extendType = $type;  | 
  
| 678 | 
      if (strpos($extends, '/') !== false) {  | 
  
| 679 | 
      $parts = explode('/', $extends);  | 
  
| 680 | 
      $extends = array_pop($parts);  | 
  
| 681 | 
      $extendType = implode('/', $parts);  | 
  
| 682 | 
      }  | 
  
| 683 | 
      App::uses($extends, $extendType);  | 
  
| 684 | 
      if ($plugin && in_array($originalType, array('controller', 'model'))) {  | 
  
| 685 | 
      App::uses($plugin . $extends, $plugin . '.' . $type);  | 
  
| 686 | 
      }  | 
  
| 687 | 
      }  | 
  
| 688 | 
      if ($plugin) {  | 
  
| 689 | 
      $plugin .= '.';  | 
  
| 690 | 
      }  | 
  
| 691 | 
      $name = Inflector::camelize($name);  | 
  
| 692 | 
      App::uses($name, $plugin . $type);  | 
  
| 693 | 
      return class_exists($name);  | 
  
| 694 | 
      }  | 
  
| 695 | 
       | 
  
| 696 | 
      /**
     | 
  
| 697 | 
       * Helper function to include single files
     | 
  
| 698 | 
       *
     | 
  
| 699 | 
       * @param string $name unique name of the file for identifying it inside the application
     | 
  
| 700 | 
       * @param string $plugin camel cased plugin name if any
     | 
  
| 701 | 
       * @param array $search list of paths to search the file into
     | 
  
| 702 | 
       * @param string $file filename if known, the $name param will be used otherwise
     | 
  
| 703 | 
       * @param bool $return whether this function should return the contents of the file after being parsed by php or just a success notice
     | 
  
| 704 | 
       * @return mixed if $return contents of the file after php parses it, boolean indicating success otherwise
     | 
  
| 705 | 
       */
     | 
  
| 706 | 
      protected static function _loadFile($name, $plugin, $search, $file, $return) {  | 
  
| 707 | 
      $mapped = static::_mapped($name, $plugin);  | 
  
| 708 | 
      if ($mapped) {  | 
  
| 709 | 
      $file = $mapped;  | 
  
| 710 | 
      } elseif (!empty($search)) {  | 
  
| 711 | 
      foreach ($search as $path) {  | 
  
| 712 | 
      $found = false;  | 
  
| 713 | 
      if (file_exists($path . $file)) {  | 
  
| 714 | 
      $file = $path . $file;  | 
  
| 715 | 
      $found = true;  | 
  
| 716 | 
                                              break;
     | 
  
| 717 | 
      }  | 
  
| 718 | 
      if (empty($found)) {  | 
  
| 719 | 
      $file = false;  | 
  
| 720 | 
      }  | 
  
| 721 | 
      }  | 
  
| 722 | 
      }  | 
  
| 723 | 
      if (!empty($file) && file_exists($file)) {  | 
  
| 724 | 
      static::_map($file, $name, $plugin);  | 
  
| 725 | 
      $returnValue = include $file;  | 
  
| 726 | 
      if ($return) {  | 
  
| 727 | 
      return $returnValue;  | 
  
| 728 | 
      }  | 
  
| 729 | 
      return (bool)$returnValue;  | 
  
| 730 | 
      }  | 
  
| 731 | 
      return false;  | 
  
| 732 | 
      }  | 
  
| 733 | 
       | 
  
| 734 | 
      /**
     | 
  
| 735 | 
       * Helper function to load files from vendors folders
     | 
  
| 736 | 
       *
     | 
  
| 737 | 
       * @param string $name unique name of the file for identifying it inside the application
     | 
  
| 738 | 
       * @param string $plugin camel cased plugin name if any
     | 
  
| 739 | 
       * @param string $file file name if known
     | 
  
| 740 | 
       * @param string $ext file extension if known
     | 
  
| 741 | 
       * @return bool true if the file was loaded successfully, false otherwise
     | 
  
| 742 | 
       */
     | 
  
| 743 | 
      protected static function _loadVendor($name, $plugin, $file, $ext) {  | 
  
| 744 | 
      if ($mapped = static::_mapped($name, $plugin)) {  | 
  
| 745 | 
      return (bool)include_once $mapped;  | 
  
| 746 | 
      }  | 
  
| 747 | 
      $fileTries = array();  | 
  
| 748 | 
      $paths = ($plugin) ? App::path('vendors', $plugin) : App::path('vendors');  | 
  
| 749 | 
      if (empty($ext)) {  | 
  
| 750 | 
      $ext = 'php';  | 
  
| 751 | 
      }  | 
  
| 752 | 
      if (empty($file)) {  | 
  
| 753 | 
      $fileTries[] = $name . '.' . $ext;  | 
  
| 754 | 
      $fileTries[] = Inflector::underscore($name) . '.' . $ext;  | 
  
| 755 | 
                      } else {
     | 
  
| 756 | 
      $fileTries[] = $file;  | 
  
| 757 | 
      }  | 
  
| 758 | 
       | 
  
| 759 | 
      foreach ($fileTries as $file) {  | 
  
| 760 | 
      foreach ($paths as $path) {  | 
  
| 761 | 
      if (file_exists($path . $file)) {  | 
  
| 762 | 
      static::_map($path . $file, $name, $plugin);  | 
  
| 763 | 
      return (bool)include $path . $file;  | 
  
| 764 | 
      }  | 
  
| 765 | 
      }  | 
  
| 766 | 
      }  | 
  
| 767 | 
      return false;  | 
  
| 768 | 
      }  | 
  
| 769 | 
       | 
  
| 770 | 
      /**
     | 
  
| 771 | 
       * Initializes the cache for App, registers a shutdown function.
     | 
  
| 772 | 
       *
     | 
  
| 773 | 
       * @return void
     | 
  
| 774 | 
       */
     | 
  
| 775 | 
      public static function init() {  | 
  
| 776 | 
      static::$_map += (array)Cache::read('file_map', '_cake_core_');  | 
  
| 777 | 
      register_shutdown_function(array('App', 'shutdown'));  | 
  
| 778 | 
      }  | 
  
| 779 | 
       | 
  
| 780 | 
      /**
     | 
  
| 781 | 
       * Maps the $name to the $file.
     | 
  
| 782 | 
       *
     | 
  
| 783 | 
       * @param string $file full path to file
     | 
  
| 784 | 
       * @param string $name unique name for this map
     | 
  
| 785 | 
       * @param string $plugin camelized if object is from a plugin, the name of the plugin
     | 
  
| 786 | 
       * @return void
     | 
  
| 787 | 
       */
     | 
  
| 788 | 
      protected static function _map($file, $name, $plugin = null) {  | 
  
| 789 | 
      $key = $name;  | 
  
| 790 | 
      if ($plugin) {  | 
  
| 791 | 
      $key = 'plugin.' . $name;  | 
  
| 792 | 
      }  | 
  
| 793 | 
      if ($plugin && empty(static::$_map[$name])) {  | 
  
| 794 | 
      static::$_map[$key] = $file;  | 
  
| 795 | 
      }  | 
  
| 796 | 
      if (!$plugin && empty(static::$_map['plugin.' . $name])) {  | 
  
| 797 | 
      static::$_map[$key] = $file;  | 
  
| 798 | 
      }  | 
  
| 799 | 
      if (!static::$bootstrapping) {  | 
  
| 800 | 
      static::$_cacheChange = true;  | 
  
| 801 | 
      }  | 
  
| 802 | 
      }  | 
  
| 803 | 
       | 
  
| 804 | 
      /**
     | 
  
| 805 | 
       * Returns a file's complete path.
     | 
  
| 806 | 
       *
     | 
  
| 807 | 
       * @param string $name unique name
     | 
  
| 808 | 
       * @param string $plugin camelized if object is from a plugin, the name of the plugin
     | 
  
| 809 | 
       * @return mixed file path if found, false otherwise
     | 
  
| 810 | 
       */
     | 
  
| 811 | 
      protected static function _mapped($name, $plugin = null) {  | 
  
| 812 | 
      $key = $name;  | 
  
| 813 | 
      if ($plugin) {  | 
  
| 814 | 
      $key = 'plugin.' . $name;  | 
  
| 815 | 
      }  | 
  
| 816 | 
      return isset(static::$_map[$key]) ? static::$_map[$key] : false;  | 
  
| 817 | 
      }  | 
  
| 818 | 
       | 
  
| 819 | 
      /**
     | 
  
| 820 | 
       * Sets then returns the templates for each customizable package path
     | 
  
| 821 | 
       *
     | 
  
| 822 | 
       * @return array templates for each customizable package path
     | 
  
| 823 | 
       */
     | 
  
| 824 | 
      protected static function _packageFormat() {  | 
  
| 825 | 
      if (empty(static::$_packageFormat)) {  | 
  
| 826 | 
      static::$_packageFormat = array(  | 
  
| 827 | 
      'Model' => array(  | 
  
| 828 | 
      '%s' . 'Model' . DS  | 
  
| 829 | 
      ),  | 
  
| 830 | 
      'Model/Behavior' => array(  | 
  
| 831 | 
      '%s' . 'Model' . DS . 'Behavior' . DS  | 
  
| 832 | 
      ),  | 
  
| 833 | 
      'Model/Datasource' => array(  | 
  
| 834 | 
      '%s' . 'Model' . DS . 'Datasource' . DS  | 
  
| 835 | 
      ),  | 
  
| 836 | 
      'Model/Datasource/Database' => array(  | 
  
| 837 | 
      '%s' . 'Model' . DS . 'Datasource' . DS . 'Database' . DS  | 
  
| 838 | 
      ),  | 
  
| 839 | 
      'Model/Datasource/Session' => array(  | 
  
| 840 | 
      '%s' . 'Model' . DS . 'Datasource' . DS . 'Session' . DS  | 
  
| 841 | 
      ),  | 
  
| 842 | 
      'Controller' => array(  | 
  
| 843 | 
      '%s' . 'Controller' . DS  | 
  
| 844 | 
      ),  | 
  
| 845 | 
      'Controller/Component' => array(  | 
  
| 846 | 
      '%s' . 'Controller' . DS . 'Component' . DS  | 
  
| 847 | 
      ),  | 
  
| 848 | 
      'Controller/Component/Auth' => array(  | 
  
| 849 | 
      '%s' . 'Controller' . DS . 'Component' . DS . 'Auth' . DS  | 
  
| 850 | 
      ),  | 
  
| 851 | 
      'Controller/Component/Acl' => array(  | 
  
| 852 | 
      '%s' . 'Controller' . DS . 'Component' . DS . 'Acl' . DS  | 
  
| 853 | 
      ),  | 
  
| 854 | 
      'View' => array(  | 
  
| 855 | 
      '%s' . 'View' . DS  | 
  
| 856 | 
      ),  | 
  
| 857 | 
      'View/Helper' => array(  | 
  
| 858 | 
      '%s' . 'View' . DS . 'Helper' . DS  | 
  
| 859 | 
      ),  | 
  
| 860 | 
      'Console' => array(  | 
  
| 861 | 
      '%s' . 'Console' . DS  | 
  
| 862 | 
      ),  | 
  
| 863 | 
      'Console/Command' => array(  | 
  
| 864 | 
      '%s' . 'Console' . DS . 'Command' . DS  | 
  
| 865 | 
      ),  | 
  
| 866 | 
      'Console/Command/Task' => array(  | 
  
| 867 | 
      '%s' . 'Console' . DS . 'Command' . DS . 'Task' . DS  | 
  
| 868 | 
      ),  | 
  
| 869 | 
      'Lib' => array(  | 
  
| 870 | 
      '%s' . 'Lib' . DS  | 
  
| 871 | 
      ),  | 
  
| 872 | 
      'Locale' => array(  | 
  
| 873 | 
      '%s' . 'Locale' . DS  | 
  
| 874 | 
      ),  | 
  
| 875 | 
      'Vendor' => array(  | 
  
| 876 | 
      '%s' . 'Vendor' . DS,  | 
  
| 877 | 
      ROOT . DS . 'vendors' . DS,  | 
  
| 878 | 
      dirname(dirname(CAKE)) . DS . 'vendors' . DS  | 
  
| 879 | 
      ),  | 
  
| 880 | 
      'Plugin' => array(  | 
  
| 881 | 
      APP . 'Plugin' . DS,  | 
  
| 882 | 
      ROOT . DS . 'plugins' . DS,  | 
  
| 883 | 
      dirname(dirname(CAKE)) . DS . 'plugins' . DS  | 
  
| 884 | 
      )  | 
  
| 885 | 
      );  | 
  
| 886 | 
      }  | 
  
| 887 | 
       | 
  
| 888 | 
      return static::$_packageFormat;  | 
  
| 889 | 
      }  | 
  
| 890 | 
       | 
  
| 891 | 
      /**
     | 
  
| 892 | 
       * Object destructor.
     | 
  
| 893 | 
       *
     | 
  
| 894 | 
       * Writes cache file if changes have been made to the $_map. Also, check if a fatal
     | 
  
| 895 | 
       * error happened and call the handler.
     | 
  
| 896 | 
       *
     | 
  
| 897 | 
       * @return void
     | 
  
| 898 | 
       */
     | 
  
| 899 | 
      public static function shutdown() {  | 
  
| 900 | 
      if (static::$_cacheChange) {  | 
  
| 901 | 
      Cache::write('file_map', array_filter(static::$_map), '_cake_core_');  | 
  
| 902 | 
      }  | 
  
| 903 | 
      if (static::$_objectCacheChange) {  | 
  
| 904 | 
      Cache::write('object_map', static::$_objects, '_cake_core_');  | 
  
| 905 | 
      }  | 
  
| 906 | 
                      static::_checkFatalError();
     | 
  
| 907 | 
      }  | 
  
| 908 | 
       | 
  
| 909 | 
      /**
     | 
  
| 910 | 
       * Check if a fatal error happened and trigger the configured handler if configured
     | 
  
| 911 | 
       *
     | 
  
| 912 | 
       * @return void
     | 
  
| 913 | 
       */
     | 
  
| 914 | 
      protected static function _checkFatalError() {  | 
  
| 915 | 
      $lastError = error_get_last();  | 
  
| 916 | 
      if (!is_array($lastError)) {  | 
  
| 917 | 
                              return;
     | 
  
| 918 | 
      }  | 
  
| 919 | 
       | 
  
| 920 | 
      list(, $log) = ErrorHandler::mapErrorCode($lastError['type']);  | 
  
| 921 | 
      if ($log !== LOG_ERR) {  | 
  
| 922 | 
                              return;
     | 
  
| 923 | 
      }  | 
  
| 924 | 
       | 
  
| 925 | 
      if (PHP_SAPI === 'cli') {  | 
  
| 926 | 
      $errorHandler = Configure::read('Error.consoleHandler');  | 
  
| 927 | 
                      } else {
     | 
  
| 928 | 
      $errorHandler = Configure::read('Error.handler');  | 
  
| 929 | 
      }  | 
  
| 930 | 
      if (!is_callable($errorHandler)) {  | 
  
| 931 | 
                              return;
     | 
  
| 932 | 
      }  | 
  
| 933 | 
      call_user_func($errorHandler, $lastError['type'], $lastError['message'], $lastError['file'], $lastError['line'], array());  | 
  
| 934 | 
      }  | 
  
| 935 | 
       | 
  
| 936 | 
      }  |