PageRenderTime 62ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/cake/libs/configure.php

https://github.com/tiwasaki/hero_web_api
PHP | 1195 lines | 720 code | 68 blank | 407 comment | 167 complexity | ebb7ba734d9304e00a92f2ed0c869170 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /* SVN FILE: $Id: configure.php,v 1.1 2011/09/20 08:32:26 iwasaki Exp $ */
  3. /**
  4. * Short description for file.
  5. *
  6. * Long description for filec
  7. *
  8. * PHP versions 4 and 5
  9. *
  10. * CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
  11. * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
  12. *
  13. * Licensed under The MIT License
  14. * Redistributions of files must retain the above copyright notice.
  15. *
  16. * @filesource
  17. * @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
  18. * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
  19. * @package cake
  20. * @subpackage cake.cake.libs
  21. * @since CakePHP(tm) v 1.0.0.2363
  22. * @version $Revision: 1.1 $
  23. * @modifiedby $LastChangedBy: gwoo $
  24. * @lastmodified $Date: 2011/09/20 08:32:26 $
  25. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  26. */
  27. /**
  28. * Configuration class (singleton). Used for managing runtime configuration information.
  29. *
  30. * @package cake
  31. * @subpackage cake.cake.libs
  32. * @link http://book.cakephp.org/view/42/The-Configuration-Class
  33. */
  34. class Configure extends Object {
  35. /**
  36. * List of additional path(s) where model files reside.
  37. *
  38. * @var array
  39. * @access public
  40. */
  41. var $modelPaths = array();
  42. /**
  43. * List of additional path(s) where behavior files reside.
  44. *
  45. * @var array
  46. * @access public
  47. */
  48. var $behaviorPaths = array();
  49. /**
  50. * List of additional path(s) where controller files reside.
  51. *
  52. * @var array
  53. * @access public
  54. */
  55. var $controllerPaths = array();
  56. /**
  57. * List of additional path(s) where component files reside.
  58. *
  59. * @var array
  60. * @access public
  61. */
  62. var $componentPaths = array();
  63. /**
  64. * List of additional path(s) where view files reside.
  65. *
  66. * @var array
  67. * @access public
  68. */
  69. var $viewPaths = array();
  70. /**
  71. * List of additional path(s) where helper files reside.
  72. *
  73. * @var array
  74. * @access public
  75. */
  76. var $helperPaths = array();
  77. /**
  78. * List of additional path(s) where plugins reside.
  79. *
  80. * @var array
  81. * @access public
  82. */
  83. var $pluginPaths = array();
  84. /**
  85. * List of additional path(s) where vendor packages reside.
  86. *
  87. * @var array
  88. * @access public
  89. */
  90. var $vendorPaths = array();
  91. /**
  92. * List of additional path(s) where locale files reside.
  93. *
  94. * @var array
  95. * @access public
  96. */
  97. var $localePaths = array();
  98. /**
  99. * List of additional path(s) where console shell files reside.
  100. *
  101. * @var array
  102. * @access public
  103. */
  104. var $shellPaths = array();
  105. /**
  106. * Current debug level.
  107. *
  108. * @link http://book.cakephp.org/view/44/CakePHP-Core-Configuration-Variables
  109. * @var integer
  110. * @access public
  111. */
  112. var $debug = null;
  113. /**
  114. * Determines if $__objects cache should be written.
  115. *
  116. * @var boolean
  117. * @access private
  118. */
  119. var $__cache = false;
  120. /**
  121. * Holds and key => value array of objects' types.
  122. *
  123. * @var array
  124. * @access private
  125. */
  126. var $__objects = array();
  127. /**
  128. * Returns a singleton instance of the Configure class.
  129. *
  130. * @return Configure instance
  131. * @access public
  132. */
  133. function &getInstance($boot = true) {
  134. static $instance = array();
  135. if (!$instance) {
  136. //$instance[0] =& new Configure();
  137. $instance[0] = new Configure();
  138. $instance[0]->__loadBootstrap($boot);
  139. }
  140. return $instance[0];
  141. }
  142. /**
  143. * Returns an index of objects of the given type, with the physical path to each object.
  144. *
  145. * @param string $type Type of object, i.e. 'model', 'controller', 'helper', or 'plugin'
  146. * @param mixed $path Optional
  147. * @return Configure instance
  148. * @access public
  149. */
  150. function listObjects($type, $path = null, $cache = true) {
  151. $objects = array();
  152. $extension = false;
  153. $name = $type;
  154. if ($type === 'file' && !$path) {
  155. return false;
  156. } elseif ($type === 'file') {
  157. $extension = true;
  158. $name = $type . str_replace(DS, '', $path);
  159. }
  160. $_this =& Configure::getInstance();
  161. if (empty($_this->__objects) && $cache === true) {
  162. $_this->__objects = Cache::read('object_map', '_cake_core_');
  163. }
  164. if (empty($_this->__objects) || !isset($_this->__objects[$type]) || $cache !== true) {
  165. $types = array(
  166. 'model' => array('suffix' => '.php', 'base' => 'AppModel', 'core' => false),
  167. 'behavior' => array('suffix' => '.php', 'base' => 'ModelBehavior'),
  168. 'controller' => array('suffix' => '_controller.php', 'base' => 'AppController'),
  169. 'component' => array('suffix' => '.php', 'base' => null),
  170. 'view' => array('suffix' => '.php', 'base' => null),
  171. 'helper' => array('suffix' => '.php', 'base' => 'AppHelper'),
  172. 'plugin' => array('suffix' => '', 'base' => null),
  173. 'vendor' => array('suffix' => '', 'base' => null),
  174. 'class' => array('suffix' => '.php', 'base' => null),
  175. 'file' => array('suffix' => '.php', 'base' => null)
  176. );
  177. if (!isset($types[$type])) {
  178. return false;
  179. }
  180. $objects = array();
  181. if (empty($path)) {
  182. $path = $_this->{$type . 'Paths'};
  183. if (isset($types[$type]['core']) && $types[$type]['core'] === false) {
  184. array_pop($path);
  185. }
  186. }
  187. $items = array();
  188. foreach ((array)$path as $dir) {
  189. if ($type === 'file' || $type === 'class' || strpos($dir, $type) !== false) {
  190. $items = $_this->__list($dir, $types[$type]['suffix'], $extension);
  191. $objects = array_merge($items, array_diff($objects, $items));
  192. }
  193. }
  194. if ($type !== 'file') {
  195. foreach ($objects as $key => $value) {
  196. $objects[$key] = Inflector::camelize($value);
  197. }
  198. }
  199. if ($cache === true && !empty($objects)) {
  200. $_this->__objects[$name] = $objects;
  201. $_this->__cache = true;
  202. } else {
  203. return $objects;
  204. }
  205. }
  206. return $_this->__objects[$name];
  207. }
  208. /**
  209. * Returns an array of filenames of PHP files in the given directory.
  210. *
  211. * @param string $path Path to scan for files
  212. * @param string $suffix if false, return only directories. if string, match and return files
  213. * @return array List of directories or files in directory
  214. */
  215. function __list($path, $suffix = false, $extension = false) {
  216. if (!class_exists('Folder')) {
  217. require LIBS . 'folder.php';
  218. }
  219. $items = array();
  220. //$Folder =& new Folder($path);
  221. $Folder = new Folder($path);
  222. $contents = $Folder->read(false, true);
  223. if (is_array($contents)) {
  224. if (!$suffix) {
  225. return $contents[0];
  226. } else {
  227. foreach ($contents[1] as $item) {
  228. if (substr($item, - strlen($suffix)) === $suffix) {
  229. if ($extension) {
  230. $items[] = $item;
  231. } else {
  232. $items[] = substr($item, 0, strlen($item) - strlen($suffix));
  233. }
  234. }
  235. }
  236. }
  237. }
  238. return $items;
  239. }
  240. /**
  241. * Used to store a dynamic variable in the Configure instance.
  242. *
  243. * Usage
  244. * Configure::write('One.key1', 'value of the Configure::One[key1]');
  245. * Configure::write(array('One.key1' => 'value of the Configure::One[key1]'));
  246. * Configure::write('One', array(
  247. * 'key1' => 'value of the Configure::One[key1]',
  248. * 'key2' => 'value of the Configure::One[key2]'
  249. * );
  250. * Configure::write(array(
  251. * 'One.key1' => 'value of the Configure::One[key1]',
  252. * 'One.key2' => 'value of the Configure::One[key2]'
  253. * ));
  254. *
  255. * @link http://book.cakephp.org/view/412/write
  256. * @param array $config Name of var to write
  257. * @param mixed $value Value to set for var
  258. * @return void
  259. * @access public
  260. */
  261. function write($config, $value = null) {
  262. $_this =& Configure::getInstance();
  263. if (!is_array($config)) {
  264. $config = array($config => $value);
  265. }
  266. foreach ($config as $names => $value) {
  267. $name = $_this->__configVarNames($names);
  268. switch (count($name)) {
  269. case 3:
  270. $_this->{$name[0]}[$name[1]][$name[2]] = $value;
  271. break;
  272. case 2:
  273. $_this->{$name[0]}[$name[1]] = $value;
  274. break;
  275. case 1:
  276. $_this->{$name[0]} = $value;
  277. break;
  278. }
  279. }
  280. if (isset($config['debug'])) {
  281. if ($_this->debug) {
  282. error_reporting(E_ALL);
  283. if (function_exists('ini_set')) {
  284. ini_set('display_errors', 1);
  285. }
  286. if (!class_exists('Debugger')) {
  287. require LIBS . 'debugger.php';
  288. }
  289. if (!class_exists('CakeLog')) {
  290. require LIBS . 'cake_log.php';
  291. }
  292. Configure::write('log', LOG_NOTICE);
  293. } else {
  294. error_reporting(0);
  295. Configure::write('log', LOG_NOTICE);
  296. }
  297. }
  298. }
  299. /**
  300. * Used to read information stored in the Configure instance.
  301. *
  302. * Usage
  303. * Configure::read('Name'); will return all values for Name
  304. * Configure::read('Name.key'); will return only the value of Configure::Name[key]
  305. *
  306. * @link http://book.cakephp.org/view/413/read
  307. * @param string $var Variable to obtain
  308. * @return string value of Configure::$var
  309. * @access public
  310. */
  311. function read($var = 'debug') {
  312. $_this =& Configure::getInstance();
  313. if ($var === 'debug') {
  314. if (!isset($_this->debug)) {
  315. if (defined('DEBUG')) {
  316. $_this->debug = DEBUG;
  317. } else {
  318. $_this->debug = 0;
  319. }
  320. }
  321. return $_this->debug;
  322. }
  323. $name = $_this->__configVarNames($var);
  324. switch (count($name)) {
  325. case 3:
  326. if (isset($_this->{$name[0]}[$name[1]][$name[2]])) {
  327. return $_this->{$name[0]}[$name[1]][$name[2]];
  328. }
  329. break;
  330. case 2:
  331. if (isset($_this->{$name[0]}[$name[1]])) {
  332. return $_this->{$name[0]}[$name[1]];
  333. }
  334. break;
  335. case 1:
  336. if (isset($_this->{$name[0]})) {
  337. return $_this->{$name[0]};
  338. }
  339. break;
  340. }
  341. return null;
  342. }
  343. /**
  344. * Used to delete a variable from the Configure instance.
  345. *
  346. * Usage:
  347. * Configure::delete('Name'); will delete the entire Configure::Name
  348. * Configure::delete('Name.key'); will delete only the Configure::Name[key]
  349. *
  350. * @link http://book.cakephp.org/view/414/delete
  351. * @param string $var the var to be deleted
  352. * @return void
  353. * @access public
  354. */
  355. function delete($var = null) {
  356. $_this =& Configure::getInstance();
  357. $name = $_this->__configVarNames($var);
  358. if (count($name) > 1) {
  359. unset($_this->{$name[0]}[$name[1]]);
  360. } else {
  361. unset($_this->{$name[0]});
  362. }
  363. }
  364. /**
  365. * Loads a file from app/config/configure_file.php.
  366. * Config file variables should be formated like:
  367. * $config['name'] = 'value';
  368. * These will be used to create dynamic Configure vars.
  369. *
  370. * Usage Configure::load('configure_file');
  371. *
  372. * @link http://book.cakephp.org/view/415/load
  373. * @param string $fileName name of file to load, extension must be .php and only the name
  374. * should be used, not the extenstion
  375. * @return mixed false if file not found, void if load successful
  376. * @access public
  377. */
  378. function load($fileName) {
  379. $found = false;
  380. if (file_exists(CONFIGS . $fileName . '.php')) {
  381. include(CONFIGS . $fileName . '.php');
  382. $found = true;
  383. } elseif (file_exists(CACHE . 'persistent' . DS . $fileName . '.php')) {
  384. include(CACHE . 'persistent' . DS . $fileName . '.php');
  385. $found = true;
  386. } else {
  387. foreach (Configure::corePaths('cake') as $key => $path) {
  388. if (file_exists($path . DS . 'config' . DS . $fileName . '.php')) {
  389. include($path . DS . 'config' . DS . $fileName . '.php');
  390. $found = true;
  391. break;
  392. }
  393. }
  394. }
  395. if (!$found) {
  396. return false;
  397. }
  398. if (!isset($config)) {
  399. $error = __("Configure::load() - no variable \$config found in %s.php", true);
  400. trigger_error(sprintf($error, $fileName), E_USER_WARNING);
  401. return false;
  402. }
  403. return Configure::write($config);
  404. }
  405. /**
  406. * Used to determine the current version of CakePHP.
  407. *
  408. * Usage Configure::version();
  409. *
  410. * @link http://book.cakephp.org/view/416/version
  411. * @return string Current version of CakePHP
  412. * @access public
  413. */
  414. function version() {
  415. $_this =& Configure::getInstance();
  416. if (!isset($_this->Cake['version'])) {
  417. require(CORE_PATH . 'cake' . DS . 'config' . DS . 'config.php');
  418. $_this->write($config);
  419. }
  420. return $_this->Cake['version'];
  421. }
  422. /**
  423. * Used to write a config file to disk.
  424. *
  425. * Configure::store('Model', 'class.paths', array('Users' => array(
  426. * 'path' => 'users', 'plugin' => true
  427. * )));
  428. *
  429. * @param string $type Type of config file to write, ex: Models, Controllers, Helpers, Components
  430. * @param string $name file name.
  431. * @param array $data array of values to store.
  432. * @return void
  433. * @access public
  434. */
  435. function store($type, $name, $data = array()) {
  436. $write = true;
  437. $content = '';
  438. foreach ($data as $key => $value) {
  439. $content .= "\$config['$type']['$key']";
  440. if (is_array($value)) {
  441. $content .= " = array(";
  442. foreach ($value as $key1 => $value2) {
  443. $value2 = addslashes($value2);
  444. $content .= "'$key1' => '$value2', ";
  445. }
  446. $content .= ");\n";
  447. } else {
  448. $value = addslashes($value);
  449. $content .= " = '$value';\n";
  450. }
  451. }
  452. if (is_null($type)) {
  453. $write = false;
  454. }
  455. Configure::__writeConfig($content, $name, $write);
  456. }
  457. /**
  458. * Returns a key/value list of all paths where core libs are found.
  459. * Passing $type only returns the values for a given value of $key.
  460. *
  461. * @param string $type valid values are: 'model', 'behavior', 'controller', 'component',
  462. * 'view', 'helper', 'datasource', 'libs', and 'cake'
  463. * @return array numeric keyed array of core lib paths
  464. * @access public
  465. */
  466. function corePaths($type = null) {
  467. $paths = Cache::read('core_paths', '_cake_core_');
  468. if (!$paths) {
  469. $paths = array();
  470. $openBasedir = ini_get('open_basedir');
  471. if ($openBasedir) {
  472. $all = explode(PATH_SEPARATOR, $openBasedir);
  473. $all = array_flip(array_flip((array_merge(array(CAKE_CORE_INCLUDE_PATH), $all))));
  474. } else {
  475. $all = explode(PATH_SEPARATOR, ini_get('include_path'));
  476. $all = array_flip(array_flip((array_merge(array(CAKE_CORE_INCLUDE_PATH), $all))));
  477. }
  478. foreach ($all as $path) {
  479. if ($path !== DS) {
  480. $path = rtrim($path, DS);
  481. }
  482. if (empty($path) || $path === '.') {
  483. continue;
  484. }
  485. $cake = $path . DS . 'cake' . DS;
  486. $libs = $cake . 'libs' . DS;
  487. if (is_dir($libs)) {
  488. $paths['libs'][] = $libs;
  489. $paths['model'][] = $libs . 'model' . DS;
  490. $paths['behavior'][] = $libs . 'model' . DS . 'behaviors' . DS;
  491. $paths['controller'][] = $libs . 'controller' . DS;
  492. $paths['component'][] = $libs . 'controller' . DS . 'components' . DS;
  493. $paths['view'][] = $libs . 'view' . DS;
  494. $paths['helper'][] = $libs . 'view' . DS . 'helpers' . DS;
  495. $paths['cake'][] = $cake;
  496. $paths['vendor'][] = $path . DS . 'vendors' . DS;
  497. $paths['shell'][] = $cake . 'console' . DS . 'libs' . DS;
  498. break;
  499. }
  500. }
  501. Cache::write('core_paths', array_filter($paths), '_cake_core_');
  502. }
  503. if ($type && isset($paths[$type])) {
  504. return $paths[$type];
  505. }
  506. return $paths;
  507. }
  508. /**
  509. * Creates a cached version of a configuration file.
  510. * Appends values passed from Configure::store() to the cached file
  511. *
  512. * @param string $content Content to write on file
  513. * @param string $name Name to use for cache file
  514. * @param boolean $write true if content should be written, false otherwise
  515. * @return void
  516. * @access private
  517. */
  518. function __writeConfig($content, $name, $write = true) {
  519. $file = CACHE . 'persistent' . DS . $name . '.php';
  520. if (Configure::read() > 0) {
  521. $expires = "+10 seconds";
  522. } else {
  523. $expires = "+999 days";
  524. }
  525. $cache = cache('persistent' . DS . $name . '.php', null, $expires);
  526. if ($cache === null) {
  527. cache('persistent' . DS . $name . '.php', "<?php\n\$config = array();\n", $expires);
  528. }
  529. if ($write === true) {
  530. if (!class_exists('File')) {
  531. require LIBS . 'file.php';
  532. }
  533. $fileClass = new File($file);
  534. if ($fileClass->writable()) {
  535. $fileClass->append($content);
  536. }
  537. }
  538. }
  539. /**
  540. * Checks $name for dot notation to create dynamic Configure::$var as an array when needed.
  541. *
  542. * @param mixed $name Name to split
  543. * @return array Name separated in items through dot notation
  544. * @access private
  545. */
  546. function __configVarNames($name) {
  547. if (is_string($name)) {
  548. if (strpos($name, ".")) {
  549. return explode(".", $name);
  550. }
  551. return array($name);
  552. }
  553. return $name;
  554. }
  555. /**
  556. * Build path references. Merges the supplied $paths
  557. * with the base paths and the default core paths.
  558. *
  559. * @param array $paths paths defines in config/bootstrap.php
  560. * @return void
  561. * @access public
  562. */
  563. function buildPaths($paths) {
  564. $_this =& Configure::getInstance();
  565. $core = $_this->corePaths();
  566. $basePaths = array(
  567. 'model' => array(MODELS),
  568. 'behavior' => array(BEHAVIORS),
  569. 'controller' => array(CONTROLLERS),
  570. 'component' => array(COMPONENTS),
  571. 'view' => array(VIEWS),
  572. 'helper' => array(HELPERS),
  573. 'plugin' => array(APP . 'plugins' . DS),
  574. 'vendor' => array(APP . 'vendors' . DS, VENDORS),
  575. 'locale' => array(APP . 'locale' . DS),
  576. 'shell' => array(),
  577. 'datasource' => array(MODELS . 'datasources')
  578. );
  579. foreach ($basePaths as $type => $default) {
  580. $pathsVar = $type . 'Paths';
  581. $merge = array();
  582. if (isset($core[$type])) {
  583. $merge = $core[$type];
  584. }
  585. if ($type === 'model' || $type === 'controller' || $type === 'helper') {
  586. $merge = array_merge(array(APP), $merge);
  587. }
  588. if (!is_array($default)) {
  589. $default = array($default);
  590. }
  591. $_this->{$pathsVar} = $default;
  592. if (isset($paths[$pathsVar]) && !empty($paths[$pathsVar])) {
  593. $path = array_flip(array_flip((array_merge(
  594. $_this->{$pathsVar}, (array)$paths[$pathsVar], $merge
  595. ))));
  596. $_this->{$pathsVar} = array_values($path);
  597. } else {
  598. $path = array_flip(array_flip((array_merge($_this->{$pathsVar}, $merge))));
  599. $_this->{$pathsVar} = array_values($path);
  600. }
  601. }
  602. }
  603. /**
  604. * Loads app/config/bootstrap.php.
  605. * If the alternative paths are set in this file
  606. * they will be added to the paths vars.
  607. *
  608. * @param boolean $boot Load application bootstrap (if true)
  609. * @return void
  610. * @access private
  611. */
  612. function __loadBootstrap($boot) {
  613. $modelPaths = $behaviorPaths = $controllerPaths = $componentPaths = $viewPaths = $helperPaths = $pluginPaths = $vendorPaths = $localePaths = $shellPaths = null;
  614. if ($boot) {
  615. Configure::write('App', array('base' => false, 'baseUrl' => false, 'dir' => APP_DIR, 'webroot' => WEBROOT_DIR));
  616. if (!include(CONFIGS . 'core.php')) {
  617. 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);
  618. }
  619. if (!include(CONFIGS . 'bootstrap.php')) {
  620. 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);
  621. }
  622. if (Configure::read('Cache.disable') !== true) {
  623. $cache = Cache::config('default');
  624. if (empty($cache['settings'])) {
  625. trigger_error('Cache not configured properly. Please check Cache::config(); in APP/config/core.php', E_USER_WARNING);
  626. $cache = Cache::config('default', array('engine' => 'File'));
  627. }
  628. $path = $prefix = $duration = null;
  629. if (!empty($cache['settings']['path'])) {
  630. $path = realpath($cache['settings']['path']);
  631. } else {
  632. $prefix = $cache['settings']['prefix'];
  633. }
  634. if (Configure::read() >= 1) {
  635. $duration = '+10 seconds';
  636. } else {
  637. $duration = '+999 days';
  638. }
  639. if (Cache::config('_cake_core_') === false) {
  640. Cache::config('_cake_core_', array_merge($cache['settings'], array(
  641. 'prefix' => $prefix . 'cake_core_', 'path' => $path . DS . 'persistent' . DS,
  642. 'serialize' => true, 'duration' => $duration
  643. )));
  644. }
  645. if (Cache::config('_cake_model_') === false) {
  646. Cache::config('_cake_model_', array_merge($cache['settings'], array(
  647. 'prefix' => $prefix . 'cake_model_', 'path' => $path . DS . 'models' . DS,
  648. 'serialize' => true, 'duration' => $duration
  649. )));
  650. }
  651. Cache::config('default');
  652. }
  653. Configure::buildPaths(compact(
  654. 'modelPaths', 'viewPaths', 'controllerPaths', 'helperPaths', 'componentPaths',
  655. 'behaviorPaths', 'pluginPaths', 'vendorPaths', 'localePaths', 'shellPaths'
  656. ));
  657. }
  658. }
  659. /**
  660. * Caches the object map when the instance of the Configure class is destroyed
  661. *
  662. * @access public
  663. */
  664. function __destruct() {
  665. if ($this->__cache) {
  666. Cache::write('object_map', array_filter($this->__objects), '_cake_core_');
  667. }
  668. }
  669. }
  670. /**
  671. * Class and file loader.
  672. *
  673. * @link http://book.cakephp.org/view/499/The-App-Class
  674. * @since CakePHP(tm) v 1.2.0.6001
  675. * @package cake
  676. * @subpackage cake.cake.libs
  677. */
  678. class App extends Object {
  679. /**
  680. * Paths to search for files.
  681. *
  682. * @var array
  683. * @access public
  684. */
  685. var $search = array();
  686. /**
  687. * Whether or not to return the file that is loaded.
  688. *
  689. * @var boolean
  690. * @access public
  691. */
  692. var $return = false;
  693. /**
  694. * Determines if $__maps and $__paths cache should be written.
  695. *
  696. * @var boolean
  697. * @access private
  698. */
  699. var $__cache = false;
  700. /**
  701. * Holds key/value pairs of $type => file path.
  702. *
  703. * @var array
  704. * @access private
  705. */
  706. var $__map = array();
  707. /**
  708. * Holds paths for deep searching of files.
  709. *
  710. * @var array
  711. * @access private
  712. */
  713. var $__paths = array();
  714. /**
  715. * Holds loaded files.
  716. *
  717. * @var array
  718. * @access private
  719. */
  720. var $__loaded = array();
  721. /**
  722. * Finds classes based on $name or specific file(s) to search.
  723. *
  724. * @link http://book.cakephp.org/view/529/Using-App-import
  725. * @param mixed $type The type of Class if passed as a string, or all params can be passed as
  726. * an single array to $type,
  727. * @param string $name Name of the Class or a unique name for the file
  728. * @param mixed $parent boolean true if Class Parent should be searched, accepts key => value
  729. * array('parent' => $parent ,'file' => $file, 'search' => $search, 'ext' => '$ext');
  730. * $ext allows setting the extension of the file name
  731. * based on Inflector::underscore($name) . ".$ext";
  732. * @param array $search paths to search for files, array('path 1', 'path 2', 'path 3');
  733. * @param string $file full name of the file to search for including extension
  734. * @param boolean $return, return the loaded file, the file must have a return
  735. * statement in it to work: return $variable;
  736. * @return boolean true if Class is already in memory or if file is found and loaded, false if not
  737. * @access public
  738. */
  739. function import($type = null, $name = null, $parent = true, $search = array(), $file = null, $return = false) {
  740. $plugin = $directory = null;
  741. if (is_array($type)) {
  742. extract($type, EXTR_OVERWRITE);
  743. }
  744. if (is_array($parent)) {
  745. extract($parent, EXTR_OVERWRITE);
  746. }
  747. if ($name === null && $file === null) {
  748. $name = $type;
  749. $type = 'Core';
  750. } elseif ($name === null) {
  751. $type = 'File';
  752. }
  753. if (is_array($name)) {
  754. foreach ($name as $class) {
  755. $tempType = $type;
  756. $plugin = null;
  757. if (strpos($class, '.') !== false) {
  758. $value = explode('.', $class);
  759. $count = count($value);
  760. if ($count > 2) {
  761. $tempType = $value[0];
  762. $plugin = $value[1] . '.';
  763. $class = $value[2];
  764. } elseif ($count === 2 && ($type === 'Core' || $type === 'File')) {
  765. $tempType = $value[0];
  766. $class = $value[1];
  767. } else {
  768. $plugin = $value[0] . '.';
  769. $class = $value[1];
  770. }
  771. }
  772. if (!App::import($tempType, $plugin . $class)) {
  773. return false;
  774. }
  775. }
  776. return true;
  777. }
  778. if ($name != null && strpos($name, '.') !== false) {
  779. list($plugin, $name) = explode('.', $name);
  780. }
  781. $_this =& App::getInstance();
  782. $_this->return = $return;
  783. if (isset($ext)) {
  784. $file = Inflector::underscore($name) . ".$ext";
  785. }
  786. $ext = $_this->__settings($type, $plugin, $parent);
  787. if ($name != null && !class_exists($name . $ext['class'])) {
  788. if ($load = $_this->__mapped($name . $ext['class'], $type, $plugin)) {
  789. if ($_this->__load($load)) {
  790. $_this->__overload($type, $name . $ext['class']);
  791. if ($_this->return) {
  792. $value = include $load;
  793. return $value;
  794. }
  795. return true;
  796. } else {
  797. $_this->__remove($name . $ext['class'], $type, $plugin);
  798. $_this->__cache = true;
  799. }
  800. }
  801. if (!empty($search)) {
  802. $_this->search = $search;
  803. } elseif ($plugin) {
  804. $_this->search = $_this->__paths('plugin');
  805. } else {
  806. $_this->search = $_this->__paths($type);
  807. }
  808. $find = $file;
  809. if ($find === null) {
  810. $find = Inflector::underscore($name . $ext['suffix']).'.php';
  811. if ($plugin) {
  812. $paths = $_this->search;
  813. foreach ($paths as $key => $value) {
  814. $_this->search[$key] = $value . $ext['path'];
  815. }
  816. $plugin = Inflector::camelize($plugin);
  817. }
  818. }
  819. if (strtolower($type) !== 'vendor' && empty($search) && $_this->__load($file)) {
  820. $directory = false;
  821. } else {
  822. $file = $find;
  823. $directory = $_this->__find($find, true);
  824. }
  825. if ($directory !== null) {
  826. $_this->__cache = true;
  827. $_this->__map($directory . $file, $name . $ext['class'], $type, $plugin);
  828. $_this->__overload($type, $name . $ext['class']);
  829. if ($_this->return) {
  830. $value = include $directory . $file;
  831. return $value;
  832. }
  833. return true;
  834. }
  835. return false;
  836. }
  837. return true;
  838. }
  839. /**
  840. * Returns a single instance of App.
  841. *
  842. * @return object
  843. * @access public
  844. */
  845. function &getInstance() {
  846. static $instance = array();
  847. if (!$instance) {
  848. //$instance[0] =& new App();
  849. $instance[0] = new App();
  850. $instance[0]->__map = Cache::read('file_map', '_cake_core_');
  851. }
  852. return $instance[0];
  853. }
  854. /**
  855. * Locates the $file in $__paths, searches recursively.
  856. *
  857. * @param string $file full file name
  858. * @param boolean $recursive search $__paths recursively
  859. * @return mixed boolean on fail, $file directory path on success
  860. * @access private
  861. */
  862. function __find($file, $recursive = true) {
  863. if (empty($this->search)) {
  864. return null;
  865. } elseif (is_string($this->search)) {
  866. $this->search = array($this->search);
  867. }
  868. if (empty($this->__paths)) {
  869. $this->__paths = Cache::read('dir_map', '_cake_core_');
  870. }
  871. foreach ($this->search as $path) {
  872. $path = rtrim($path, DS);
  873. if ($path === rtrim(APP, DS)) {
  874. $recursive = false;
  875. }
  876. if ($recursive === false) {
  877. if ($this->__load($path . DS . $file)) {
  878. return $path . DS;
  879. }
  880. continue;
  881. }
  882. if (!isset($this->__paths[$path])) {
  883. if (!class_exists('Folder')) {
  884. require LIBS . 'folder.php';
  885. }
  886. //$Folder =& new Folder();
  887. $Folder = new Folder();
  888. $directories = $Folder->tree($path, false, 'dir');
  889. $this->__paths[$path] = $directories;
  890. }
  891. foreach ($this->__paths[$path] as $directory) {
  892. if ($this->__load($directory . DS . $file)) {
  893. return $directory . DS;
  894. }
  895. }
  896. }
  897. return null;
  898. }
  899. /**
  900. * Attempts to load $file.
  901. *
  902. * @param string $file full path to file including file name
  903. * @return boolean
  904. * @access private
  905. */
  906. function __load($file) {
  907. if (empty($file)) {
  908. return false;
  909. }
  910. if (!$this->return && isset($this->__loaded[$file])) {
  911. return true;
  912. }
  913. if (file_exists($file)) {
  914. if (!$this->return) {
  915. require($file);
  916. $this->__loaded[$file] = true;
  917. }
  918. return true;
  919. }
  920. return false;
  921. }
  922. /**
  923. * Maps the $name to the $file.
  924. *
  925. * @param string $file full path to file
  926. * @param string $name unique name for this map
  927. * @param string $type type object being mapped
  928. * @param string $plugin if object is from a plugin, the name of the plugin
  929. * @access private
  930. */
  931. function __map($file, $name, $type, $plugin) {
  932. if ($plugin) {
  933. $plugin = Inflector::camelize($plugin);
  934. $this->__map['Plugin'][$plugin][$type][$name] = $file;
  935. } else {
  936. $this->__map[$type][$name] = $file;
  937. }
  938. }
  939. /**
  940. * Returns a file's complete path.
  941. *
  942. * @param string $name unique name
  943. * @param string $type type object
  944. * @param string $plugin if object is from a plugin, the name of the plugin
  945. * @return mixed, file path if found, false otherwise
  946. * @access private
  947. */
  948. function __mapped($name, $type, $plugin) {
  949. if ($plugin) {
  950. $plugin = Inflector::camelize($plugin);
  951. if (isset($this->__map['Plugin'][$plugin][$type]) && isset($this->__map['Plugin'][$plugin][$type][$name])) {
  952. return $this->__map['Plugin'][$plugin][$type][$name];
  953. }
  954. return false;
  955. }
  956. if (isset($this->__map[$type]) && isset($this->__map[$type][$name])) {
  957. return $this->__map[$type][$name];
  958. }
  959. return false;
  960. }
  961. /**
  962. * Used to overload objects as needed.
  963. *
  964. * @param string $type Model or Helper
  965. * @param string $name Class name to overload
  966. * @access private
  967. */
  968. function __overload($type, $name) {
  969. if (($type === 'Model' || $type === 'Helper') && strtolower($name) != 'schema') {
  970. Overloadable::overload($name);
  971. }
  972. }
  973. /**
  974. * Loads parent classes based on $type.
  975. * Returns a prefix or suffix needed for loading files.
  976. *
  977. * @param string $type type of object
  978. * @param string $plugin name of plugin
  979. * @param boolean $parent false will not attempt to load parent
  980. * @return array
  981. * @access private
  982. */
  983. function __settings($type, $plugin, $parent) {
  984. if (!$parent) {
  985. return null;
  986. }
  987. if ($plugin) {
  988. $plugin = Inflector::underscore($plugin);
  989. $name = Inflector::camelize($plugin);
  990. }
  991. $path = null;
  992. $load = strtolower($type);
  993. switch ($load) {
  994. case 'model':
  995. if (!class_exists('Model')) {
  996. App::import('Core', 'Model', false, Configure::corePaths('model'));
  997. }
  998. if (!class_exists('AppModel')) {
  999. App::import($type, 'AppModel', false, Configure::read('modelPaths'));
  1000. }
  1001. if ($plugin) {
  1002. if (!class_exists($name . 'AppModel')) {
  1003. App::import($type, $plugin . '.' . $name . 'AppModel', false, array(), $plugin . DS . $plugin . '_app_model.php');
  1004. }
  1005. $path = $plugin . DS . 'models' . DS;
  1006. }
  1007. return array('class' => null, 'suffix' => null, 'path' => $path);
  1008. break;
  1009. case 'behavior':
  1010. if ($plugin) {
  1011. $path = $plugin . DS . 'models' . DS . 'behaviors' . DS;
  1012. }
  1013. return array('class' => $type, 'suffix' => null, 'path' => $path);
  1014. break;
  1015. case 'controller':
  1016. App::import($type, 'AppController', false);
  1017. if ($plugin) {
  1018. App::import($type, $plugin . '.' . $name . 'AppController', false, array(), $plugin . DS . $plugin . '_app_controller.php');
  1019. $path = $plugin . DS . 'controllers' . DS;
  1020. }
  1021. return array('class' => $type, 'suffix' => $type, 'path' => $path);
  1022. break;
  1023. case 'component':
  1024. if ($plugin) {
  1025. $path = $plugin . DS . 'controllers' . DS . 'components' . DS;
  1026. }
  1027. return array('class' => $type, 'suffix' => null, 'path' => $path);
  1028. break;
  1029. case 'view':
  1030. if ($plugin) {
  1031. $path = $plugin . DS . 'views' . DS;
  1032. }
  1033. return array('class' => $type, 'suffix' => null, 'path' => $path);
  1034. break;
  1035. case 'helper':
  1036. if (!class_exists('AppHelper')) {
  1037. App::import($type, 'AppHelper', false);
  1038. }
  1039. if ($plugin) {
  1040. $path = $plugin . DS . 'views' . DS . 'helpers' . DS;
  1041. }
  1042. return array('class' => $type, 'suffix' => null, 'path' => $path);
  1043. break;
  1044. case 'vendor':
  1045. if ($plugin) {
  1046. $path = $plugin . DS . 'vendors' . DS;
  1047. }
  1048. return array('class' => null, 'suffix' => null, 'path' => $path);
  1049. break;
  1050. default:
  1051. $type = $suffix = $path = null;
  1052. break;
  1053. }
  1054. return array('class' => null, 'suffix' => null, 'path' => null);
  1055. }
  1056. /**
  1057. * Returns default search paths.
  1058. *
  1059. * @param string $type type of object to be searched
  1060. * @return array list of paths
  1061. * @access private
  1062. */
  1063. function __paths($type) {
  1064. $type = strtolower($type);
  1065. if ($type === 'core') {
  1066. $path = Configure::corePaths();
  1067. $paths = array();
  1068. foreach ($path as $key => $value) {
  1069. $count = count($key);
  1070. for ($i = 0; $i < $count; $i++) {
  1071. $paths[] = $path[$key][$i];
  1072. }
  1073. }
  1074. return $paths;
  1075. }
  1076. if ($paths = Configure::read($type . 'Paths')) {
  1077. return $paths;
  1078. }
  1079. switch ($type) {
  1080. case 'plugin':
  1081. return array(APP . 'plugins' . DS);
  1082. case 'vendor':
  1083. return array(APP . 'vendors' . DS, VENDORS, APP . 'plugins' . DS);
  1084. case 'controller':
  1085. return array(APP . 'controllers' . DS, APP);
  1086. case 'model':
  1087. return array(APP . 'models' . DS, APP);
  1088. case 'view':
  1089. return array(APP . 'views' . DS);
  1090. }
  1091. }
  1092. /**
  1093. * Removes file location from map if the file has been deleted.
  1094. *
  1095. * @param string $name name of object
  1096. * @param string $type type of object
  1097. * @param string $plugin name of plugin
  1098. * @return void
  1099. * @access private
  1100. */
  1101. function __remove($name, $type, $plugin) {
  1102. if ($plugin) {
  1103. $plugin = Inflector::camelize($plugin);
  1104. unset($this->__map['Plugin'][$plugin][$type][$name]);
  1105. } else {
  1106. unset($this->__map[$type][$name]);
  1107. }
  1108. }
  1109. /**
  1110. * Object destructor.
  1111. *
  1112. * Writes cache file if changes have been made to the $__map or $__paths
  1113. *
  1114. * @return void
  1115. * @access private
  1116. */
  1117. function __destruct() {
  1118. if ($this->__cache) {
  1119. $core = Configure::corePaths('cake');
  1120. unset($this->__paths[rtrim($core[0], DS)]);
  1121. Cache::write('dir_map', array_filter($this->__paths), '_cake_core_');
  1122. Cache::write('file_map', array_filter($this->__map), '_cake_core_');
  1123. }
  1124. }
  1125. }
  1126. ?>