mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-09-02 01:22:37 +00:00
Renaming more core classes, next step would be to tweek the autoloader to find only on Cake/ "namespace" (for now)
This commit is contained in:
parent
96cb90a82b
commit
ca34b22dbb
4 changed files with 0 additions and 0 deletions
908
lib/Cake/Core/App.php
Normal file
908
lib/Cake/Core/App.php
Normal file
|
@ -0,0 +1,908 @@
|
|||
<?php
|
||||
/**
|
||||
* App class
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs
|
||||
* @since CakePHP(tm) v 1.2.0.6001
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
/**
|
||||
* App is responsible for path managment, class location and class loading.
|
||||
*
|
||||
* ### Adding paths
|
||||
*
|
||||
* You can add paths to the search indexes App uses to find classes using `App::build()`. Adding
|
||||
* additional controller paths for example would alter where CakePHP looks for controllers when you
|
||||
* call App::import('Controller', 'Posts'); This allows you to split your application up across the filesystem.
|
||||
*
|
||||
* ### Inspecting loaded paths
|
||||
*
|
||||
* You can inspect the currently loaded paths using `App::path('controller')` for example to see loaded
|
||||
* controller paths.
|
||||
*
|
||||
* ### Locating plugins and themes
|
||||
*
|
||||
* Plugins and Themes can be located with App as well. Using App::pluginPath('DebugKit') for example, will
|
||||
* give you the full path to the DebugKit plugin. App::themePath('purple'), would give the full path to the
|
||||
* `purple` theme.
|
||||
*
|
||||
* ### Inspecting known objects
|
||||
*
|
||||
* You can find out which objects App knows about using App::objects('controller') for example to find
|
||||
* which application controllers App knows about.
|
||||
*
|
||||
* @link http://book.cakephp.org/view/933/The-App-Class
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs
|
||||
*/
|
||||
class App {
|
||||
|
||||
/**
|
||||
* List of object types and their properties
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $types = array(
|
||||
'class' => array('suffix' => '.php', 'extends' => null, 'core' => true),
|
||||
'file' => array('suffix' => '.php', 'extends' => null, 'core' => true),
|
||||
'model' => array('suffix' => '.php', 'extends' => 'AppModel', 'core' => false),
|
||||
'behavior' => array('suffix' => '.php', 'extends' => 'ModelBehavior', 'core' => true),
|
||||
'controller' => array('suffix' => '_controller.php', 'extends' => 'AppController', 'core' => true),
|
||||
'component' => array('suffix' => '.php', 'extends' => null, 'core' => true),
|
||||
'lib' => array('suffix' => '.php', 'extends' => null, 'core' => true),
|
||||
'view' => array('suffix' => '.php', 'extends' => null, 'core' => true),
|
||||
'helper' => array('suffix' => '.php', 'extends' => 'AppHelper', 'core' => true),
|
||||
'vendor' => array('suffix' => '', 'extends' => null, 'core' => true),
|
||||
'shell' => array('suffix' => '.php', 'extends' => 'Shell', 'core' => true),
|
||||
'plugin' => array('suffix' => '', 'extends' => null, 'core' => true)
|
||||
);
|
||||
|
||||
/**
|
||||
* List of additional path(s) where model files reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $models = array();
|
||||
|
||||
/**
|
||||
* List of additional path(s) where behavior files reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $behaviors = array();
|
||||
|
||||
/**
|
||||
* List of additional path(s) where controller files reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $controllers = array();
|
||||
|
||||
/**
|
||||
* List of additional path(s) where component files reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $components = array();
|
||||
|
||||
/**
|
||||
* List of additional path(s) where datasource files reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $datasources = array();
|
||||
|
||||
/**
|
||||
* List of additional path(s) where libs files reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $libs = array();
|
||||
|
||||
/**
|
||||
* List of additional path(s) where view files reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $views = array();
|
||||
|
||||
/**
|
||||
* List of additional path(s) where helper files reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $helpers = array();
|
||||
|
||||
/**
|
||||
* List of additional path(s) where plugins reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $plugins = array();
|
||||
|
||||
/**
|
||||
* List of additional path(s) where vendor packages reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $vendors = array();
|
||||
|
||||
/**
|
||||
* List of additional path(s) where locale files reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $locales = array();
|
||||
|
||||
/**
|
||||
* List of additional path(s) where console shell files reside.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $shells = array();
|
||||
|
||||
/**
|
||||
* Paths to search for files.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $search = array();
|
||||
|
||||
/**
|
||||
* Whether or not to return the file that is loaded.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
public static $return = false;
|
||||
|
||||
/**
|
||||
* Determines if $__maps and $__paths cache should be written.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private static $__cache = false;
|
||||
|
||||
/**
|
||||
* Holds key/value pairs of $type => file path.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $__map = array();
|
||||
|
||||
/**
|
||||
* Holds paths for deep searching of files.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $__paths = array();
|
||||
|
||||
/**
|
||||
* Holds loaded files.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $__loaded = array();
|
||||
|
||||
/**
|
||||
* Holds and key => value array of object types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $__objects = array();
|
||||
|
||||
/**
|
||||
* Holds the location of each class
|
||||
*
|
||||
*/
|
||||
private static $__classMap = array();
|
||||
|
||||
/**
|
||||
* Used to read information stored path
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* `App::path('models'); will return all paths for models`
|
||||
*
|
||||
* @param string $type type of path
|
||||
* @return string array
|
||||
*/
|
||||
public static function path($type) {
|
||||
if (!isset(self::${$type})) {
|
||||
return array();
|
||||
}
|
||||
return self::${$type};
|
||||
}
|
||||
|
||||
/**
|
||||
* Build path references. Merges the supplied $paths
|
||||
* with the base paths and the default core paths.
|
||||
*
|
||||
* @param array $paths paths defines in config/bootstrap.php
|
||||
* @param boolean $reset true will set paths, false merges paths [default] false
|
||||
* @return void
|
||||
*/
|
||||
public static function build($paths = array(), $reset = false) {
|
||||
$defaults = array(
|
||||
'models' => array(MODELS),
|
||||
'behaviors' => array(BEHAVIORS),
|
||||
'datasources' => array(MODELS . 'datasources'),
|
||||
'controllers' => array(CONTROLLERS),
|
||||
'components' => array(COMPONENTS),
|
||||
'libs' => array(APPLIBS),
|
||||
'views' => array(VIEWS),
|
||||
'helpers' => array(HELPERS),
|
||||
'locales' => array(APP . 'locale' . DS),
|
||||
'shells' => array(
|
||||
APP . 'console' . DS . 'shells' . DS,
|
||||
APP . 'vendors' . DS . 'shells' . DS,
|
||||
VENDORS . 'shells' . DS
|
||||
),
|
||||
'vendors' => array(APP . 'vendors' . DS, VENDORS),
|
||||
'plugins' => array(APP . 'plugins' . DS)
|
||||
);
|
||||
|
||||
if ($reset == true) {
|
||||
foreach ($paths as $type => $new) {
|
||||
self::${$type} = (array)$new;
|
||||
}
|
||||
return $paths;
|
||||
}
|
||||
|
||||
$core = self::core();
|
||||
$app = array('models' => true, 'controllers' => true, 'helpers' => true);
|
||||
|
||||
foreach ($defaults as $type => $default) {
|
||||
$merge = array();
|
||||
|
||||
if (isset($app[$type])) {
|
||||
$merge = array(APP);
|
||||
}
|
||||
if (isset($core[$type])) {
|
||||
$merge = array_merge($merge, (array)$core[$type]);
|
||||
}
|
||||
|
||||
if (empty(self::${$type}) || empty($paths)) {
|
||||
self::${$type} = $default;
|
||||
}
|
||||
|
||||
if (!empty($paths[$type])) {
|
||||
$path = array_flip(array_flip(array_merge(
|
||||
(array)$paths[$type], self::${$type}, $merge
|
||||
)));
|
||||
self::${$type} = array_values($path);
|
||||
} else {
|
||||
$path = array_flip(array_flip(array_merge(self::${$type}, $merge)));
|
||||
self::${$type} = array_values($path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path that a plugin is on. Searches through the defined plugin paths.
|
||||
*
|
||||
* @param string $plugin CamelCased/lower_cased plugin name to find the path of.
|
||||
* @return string full path to the plugin.
|
||||
*/
|
||||
public static function pluginPath($plugin) {
|
||||
$pluginDir = Inflector::underscore($plugin);
|
||||
for ($i = 0, $length = count(self::$plugins); $i < $length; $i++) {
|
||||
if (is_dir(self::$plugins[$i] . $pluginDir)) {
|
||||
return self::$plugins[$i] . $pluginDir . DS ;
|
||||
}
|
||||
}
|
||||
return self::$plugins[0] . $pluginDir . DS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the path that a theme is on. Search through the defined theme paths.
|
||||
*
|
||||
* @param string $theme lower_cased theme name to find the path of.
|
||||
* @return string full path to the theme.
|
||||
*/
|
||||
public static function themePath($theme) {
|
||||
$themeDir = 'themed' . DS . Inflector::underscore($theme);
|
||||
for ($i = 0, $length = count(self::$views); $i < $length; $i++) {
|
||||
if (is_dir(self::$views[$i] . $themeDir)) {
|
||||
return self::$views[$i] . $themeDir . DS ;
|
||||
}
|
||||
}
|
||||
return self::$views[0] . $themeDir . DS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a key/value list of all paths where core libs are found.
|
||||
* Passing $type only returns the values for a given value of $key.
|
||||
*
|
||||
* @param string $type valid values are: 'model', 'behavior', 'controller', 'component',
|
||||
* 'view', 'helper', 'datasource', 'libs', and 'cake'
|
||||
* @return array numeric keyed array of core lib paths
|
||||
*/
|
||||
public static function core($type = null) {
|
||||
static $paths = false;
|
||||
if (!$paths) {
|
||||
$paths = array();
|
||||
$libs = dirname(__FILE__) . DS;
|
||||
$cake = dirname($libs) . DS;
|
||||
$path = dirname($cake) . DS;
|
||||
|
||||
$paths['cake'][] = $cake;
|
||||
$paths['libs'][] = $libs;
|
||||
$paths['models'][] = $libs . 'model' . DS;
|
||||
$paths['datasources'][] = $libs . 'model' . DS . 'datasources' . DS;
|
||||
$paths['behaviors'][] = $libs . 'model' . DS . 'behaviors' . DS;
|
||||
$paths['controllers'][] = $libs . 'controller' . DS;
|
||||
$paths['components'][] = $libs . 'controller' . DS . 'components' . DS;
|
||||
$paths['views'][] = $libs . 'view' . DS;
|
||||
$paths['helpers'][] = $libs . 'view' . DS . 'helpers' . DS;
|
||||
$paths['plugins'][] = $path . 'plugins' . DS;
|
||||
$paths['vendors'][] = $path . 'vendors' . DS;
|
||||
$paths['shells'][] = $cake . 'console' . DS . 'shells' . DS;
|
||||
// Provide BC path to vendors/shells
|
||||
$paths['shells'][] = $path . 'vendors' . DS . 'shells' . DS;
|
||||
}
|
||||
if ($type && isset($paths[$type])) {
|
||||
return $paths[$type];
|
||||
}
|
||||
return $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of objects of the given type.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* `App::objects('plugin');` returns `array('DebugKit', 'Blog', 'User');`
|
||||
*
|
||||
* @param string $type Type of object, i.e. 'model', 'controller', 'helper', or 'plugin'
|
||||
* @param mixed $path Optional Scan only the path given. If null, paths for the chosen
|
||||
* type will be used.
|
||||
* @param boolean $cache Set to false to rescan objects of the chosen type. Defaults to true.
|
||||
* @return mixed Either false on incorrect / miss. Or an array of found objects.
|
||||
*/
|
||||
public static function objects($type, $path = null, $cache = true) {
|
||||
$objects = array();
|
||||
$extension = false;
|
||||
$name = $type;
|
||||
|
||||
if ($type === 'file' && !$path) {
|
||||
return false;
|
||||
} elseif ($type === 'file') {
|
||||
$extension = true;
|
||||
$name = $type . str_replace(DS, '', $path);
|
||||
}
|
||||
|
||||
if (empty(self::$__objects) && $cache === true) {
|
||||
self::$__objects = Cache::read('object_map', '_cake_core_');
|
||||
}
|
||||
|
||||
if (!isset(self::$__objects[$name]) || $cache !== true) {
|
||||
$types = self::$types;
|
||||
|
||||
if (!isset($types[$type])) {
|
||||
return false;
|
||||
}
|
||||
$objects = array();
|
||||
|
||||
if (empty($path)) {
|
||||
$path = self::${"{$type}s"};
|
||||
if (isset($types[$type]['core']) && $types[$type]['core'] === false) {
|
||||
array_pop($path);
|
||||
}
|
||||
}
|
||||
$items = array();
|
||||
|
||||
foreach ((array)$path as $dir) {
|
||||
if ($dir != APP) {
|
||||
$items = self::__list($dir, $types[$type]['suffix'], $extension);
|
||||
$objects = array_merge($items, array_diff($objects, $items));
|
||||
}
|
||||
}
|
||||
|
||||
if ($type !== 'file') {
|
||||
foreach ($objects as $key => $value) {
|
||||
$objects[$key] = Inflector::camelize($value);
|
||||
}
|
||||
}
|
||||
|
||||
if ($cache === true) {
|
||||
self::$__cache = true;
|
||||
}
|
||||
self::$__objects[$name] = $objects;
|
||||
}
|
||||
|
||||
return self::$__objects[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows you to modify the object listings that App maintains inside of it
|
||||
* Useful for testing
|
||||
*
|
||||
* @param string $type Type of object listing you are changing
|
||||
* @param array $values The values $type should be set to.
|
||||
* @return void
|
||||
*/
|
||||
public static function setObjects($type, $values) {
|
||||
self::$__objects[$type] = $values;
|
||||
}
|
||||
|
||||
public static function uses($className, $location) {
|
||||
self::$__classMap[$className] = $location;
|
||||
}
|
||||
|
||||
public static function load($className) {
|
||||
if (isset(self::$__classMap[$className])) {
|
||||
return App::import(self::$__classMap[$className], $className, false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds classes based on $name or specific file(s) to search. Calling App::import() will
|
||||
* not construct any classes contained in the files. It will only find and require() the file.
|
||||
*
|
||||
* @link http://book.cakephp.org/view/934/Using-App-import
|
||||
* @param mixed $type The type of Class if passed as a string, or all params can be passed as
|
||||
* an single array to $type,
|
||||
* @param string $name Name of the Class or a unique name for the file
|
||||
* @param mixed $parent boolean true if Class Parent should be searched, accepts key => value
|
||||
* array('parent' => $parent ,'file' => $file, 'search' => $search, 'ext' => '$ext');
|
||||
* $ext allows setting the extension of the file name
|
||||
* based on Inflector::underscore($name) . ".$ext";
|
||||
* @param array $search paths to search for files, array('path 1', 'path 2', 'path 3');
|
||||
* @param string $file full name of the file to search for including extension
|
||||
* @param boolean $return, return the loaded file, the file must have a return
|
||||
* statement in it to work: return $variable;
|
||||
* @return boolean true if Class is already in memory or if file is found and loaded, false if not
|
||||
*/
|
||||
public static function import($type = null, $name = null, $parent = true, $search = array(), $file = null, $return = false) {
|
||||
$plugin = $directory = null;
|
||||
|
||||
if (is_array($type)) {
|
||||
extract($type, EXTR_OVERWRITE);
|
||||
}
|
||||
|
||||
if (is_array($parent)) {
|
||||
extract($parent, EXTR_OVERWRITE);
|
||||
}
|
||||
|
||||
if ($name === null && $file === null) {
|
||||
$name = $type;
|
||||
$type = 'Core';
|
||||
} elseif ($name === null) {
|
||||
$type = 'File';
|
||||
}
|
||||
|
||||
if (is_array($name)) {
|
||||
foreach ($name as $class) {
|
||||
$tempType = $type;
|
||||
$plugin = null;
|
||||
|
||||
if (strpos($class, '.') !== false) {
|
||||
$value = explode('.', $class);
|
||||
$count = count($value);
|
||||
|
||||
if ($count > 2) {
|
||||
$tempType = $value[0];
|
||||
$plugin = $value[1] . '.';
|
||||
$class = $value[2];
|
||||
} elseif ($count === 2 && ($type === 'Core' || $type === 'File')) {
|
||||
$tempType = $value[0];
|
||||
$class = $value[1];
|
||||
} else {
|
||||
$plugin = $value[0] . '.';
|
||||
$class = $value[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (!App::import($tempType, $plugin . $class, $parent)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($name != null && strpos($name, '.') !== false) {
|
||||
list($plugin, $name) = explode('.', $name);
|
||||
$plugin = Inflector::camelize($plugin);
|
||||
}
|
||||
self::$return = $return;
|
||||
|
||||
if (isset($ext)) {
|
||||
$file = Inflector::underscore($name) . ".{$ext}";
|
||||
}
|
||||
$ext = self::__settings($type, $plugin, $parent);
|
||||
$className = $name;
|
||||
if (strpos($className, '/') !== false) {
|
||||
$className = substr($className, strrpos($className, '/') + 1);
|
||||
}
|
||||
if ($name != null && !class_exists($className . $ext['class'])) {
|
||||
if ($load = self::__mapped($name . $ext['class'], $type, $plugin)) {
|
||||
if (self::__load($load)) {
|
||||
if (self::$return) {
|
||||
return include($load);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
self::__remove($name . $ext['class'], $type, $plugin);
|
||||
self::$__cache = true;
|
||||
}
|
||||
}
|
||||
if (!empty($search)) {
|
||||
self::$search = $search;
|
||||
} elseif ($plugin) {
|
||||
self::$search = self::__paths('plugin');
|
||||
} else {
|
||||
self::$search = self::__paths($type);
|
||||
}
|
||||
$find = $file;
|
||||
|
||||
if ($find === null) {
|
||||
$find = Inflector::underscore($name . $ext['suffix']).'.php';
|
||||
|
||||
if ($plugin) {
|
||||
$paths = self::$search;
|
||||
foreach ($paths as $key => $value) {
|
||||
self::$search[$key] = $value . $ext['path'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strtolower($type) !== 'vendor' && empty($search) && self::__load($file)) {
|
||||
$directory = false;
|
||||
} else {
|
||||
$file = $find;
|
||||
$directory = self::__find($find, true);
|
||||
}
|
||||
|
||||
if ($directory !== null) {
|
||||
self::$__cache = true;
|
||||
self::__map($directory . $file, $name . $ext['class'], $type, $plugin);
|
||||
|
||||
if (self::$return) {
|
||||
return include($directory . $file);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the cache for App, registers a shutdown function.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function init() {
|
||||
self::$__map = (array)Cache::read('file_map', '_cake_core_');
|
||||
register_shutdown_function(array('App', 'shutdown'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the $file in $__paths, searches recursively.
|
||||
*
|
||||
* @param string $file full file name
|
||||
* @param boolean $recursive search $__paths recursively
|
||||
* @return mixed boolean on fail, $file directory path on success
|
||||
*/
|
||||
private static function __find($file, $recursive = true) {
|
||||
static $appPath = false;
|
||||
|
||||
if (empty(self::$search)) {
|
||||
return null;
|
||||
} elseif (is_string(self::$search)) {
|
||||
$this->search = array(self::$search);
|
||||
}
|
||||
|
||||
if (empty(self::$__paths)) {
|
||||
self::$__paths = Cache::read('dir_map', '_cake_core_');
|
||||
}
|
||||
|
||||
foreach (self::$search as $path) {
|
||||
if ($appPath === false) {
|
||||
$appPath = rtrim(APP, DS);
|
||||
}
|
||||
$path = rtrim($path, DS);
|
||||
|
||||
if ($path === $appPath) {
|
||||
$recursive = false;
|
||||
}
|
||||
if ($recursive === false) {
|
||||
if (self::__load($path . DS . $file)) {
|
||||
return $path . DS;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset(self::$__paths[$path])) {
|
||||
if (!class_exists('Folder')) {
|
||||
require LIBS . 'folder.php';
|
||||
}
|
||||
$Folder = new Folder();
|
||||
$directories = $Folder->tree($path, array('.svn', '.git', 'CVS', 'tests', 'templates'), 'dir');
|
||||
sort($directories);
|
||||
self::$__paths[$path] = $directories;
|
||||
}
|
||||
|
||||
foreach (self::$__paths[$path] as $directory) {
|
||||
if (self::__load($directory . DS . $file)) {
|
||||
return $directory . DS;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to load $file.
|
||||
*
|
||||
* @param string $file full path to file including file name
|
||||
* @return boolean
|
||||
* @access private
|
||||
*/
|
||||
private static function __load($file) {
|
||||
if (empty($file)) {
|
||||
return false;
|
||||
}
|
||||
if (!self::$return && isset(self::$__loaded[$file])) {
|
||||
return true;
|
||||
}
|
||||
if (file_exists($file)) {
|
||||
if (!self::$return) {
|
||||
require($file);
|
||||
self::$__loaded[$file] = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the $name to the $file.
|
||||
*
|
||||
* @param string $file full path to file
|
||||
* @param string $name unique name for this map
|
||||
* @param string $type type object being mapped
|
||||
* @param string $plugin camelized if object is from a plugin, the name of the plugin
|
||||
* @return void
|
||||
* @access private
|
||||
*/
|
||||
private static function __map($file, $name, $type, $plugin) {
|
||||
if ($plugin) {
|
||||
self::$__map['Plugin'][$plugin][$type][$name] = $file;
|
||||
} else {
|
||||
self::$__map[$type][$name] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a file's complete path.
|
||||
*
|
||||
* @param string $name unique name
|
||||
* @param string $type type object
|
||||
* @param string $plugin camelized if object is from a plugin, the name of the plugin
|
||||
* @return mixed, file path if found, false otherwise
|
||||
* @access private
|
||||
*/
|
||||
private static function __mapped($name, $type, $plugin) {
|
||||
if ($plugin) {
|
||||
if (isset(self::$__map['Plugin'][$plugin][$type]) && isset(self::$__map['Plugin'][$plugin][$type][$name])) {
|
||||
return self::$__map['Plugin'][$plugin][$type][$name];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset(self::$__map[$type]) && isset(self::$__map[$type][$name])) {
|
||||
return self::$__map[$type][$name];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads parent classes based on $type.
|
||||
* Returns a prefix or suffix needed for loading files.
|
||||
*
|
||||
* @param string $type type of object
|
||||
* @param string $plugin camelized name of plugin
|
||||
* @param boolean $parent false will not attempt to load parent
|
||||
* @return array
|
||||
* @access private
|
||||
*/
|
||||
private static function __settings($type, $plugin, $parent) {
|
||||
if (!$parent) {
|
||||
return array('class' => null, 'suffix' => null, 'path' => null);
|
||||
}
|
||||
|
||||
if ($plugin) {
|
||||
$pluginPath = Inflector::underscore($plugin);
|
||||
}
|
||||
$path = null;
|
||||
$load = strtolower($type);
|
||||
|
||||
switch ($load) {
|
||||
case 'model':
|
||||
if (!class_exists('Model')) {
|
||||
require LIBS . 'model' . DS . 'model.php';
|
||||
}
|
||||
if (!class_exists('AppModel')) {
|
||||
App::import($type, 'AppModel', false);
|
||||
}
|
||||
if ($plugin) {
|
||||
if (!class_exists($plugin . 'AppModel')) {
|
||||
App::import($type, $plugin . '.' . $plugin . 'AppModel', false, array(), $pluginPath . DS . $pluginPath . '_app_model.php');
|
||||
}
|
||||
$path = $pluginPath . DS . 'models' . DS;
|
||||
}
|
||||
return array('class' => null, 'suffix' => null, 'path' => $path);
|
||||
break;
|
||||
case 'behavior':
|
||||
if ($plugin) {
|
||||
$path = $pluginPath . DS . 'models' . DS . 'behaviors' . DS;
|
||||
}
|
||||
return array('class' => $type, 'suffix' => null, 'path' => $path);
|
||||
break;
|
||||
case 'datasource':
|
||||
if ($plugin) {
|
||||
$path = $pluginPath . DS . 'models' . DS . 'datasources' . DS;
|
||||
}
|
||||
return array('class' => $type, 'suffix' => null, 'path' => $path);
|
||||
case 'controller':
|
||||
App::import($type, 'AppController', false);
|
||||
if ($plugin) {
|
||||
App::import($type, $plugin . '.' . $plugin . 'AppController', false, array(), $pluginPath . DS . $pluginPath . '_app_controller.php');
|
||||
$path = $pluginPath . DS . 'controllers' . DS;
|
||||
}
|
||||
return array('class' => $type, 'suffix' => $type, 'path' => $path);
|
||||
break;
|
||||
case 'component':
|
||||
App::import('Core', 'Component', false);
|
||||
if ($plugin) {
|
||||
$path = $pluginPath . DS . 'controllers' . DS . 'components' . DS;
|
||||
}
|
||||
return array('class' => $type, 'suffix' => null, 'path' => $path);
|
||||
break;
|
||||
case 'lib':
|
||||
if ($plugin) {
|
||||
$path = $pluginPath . DS . 'libs' . DS;
|
||||
}
|
||||
return array('class' => null, 'suffix' => null, 'path' => $path);
|
||||
break;
|
||||
case 'view':
|
||||
App::import('View', 'View', false);
|
||||
if ($plugin) {
|
||||
$path = $pluginPath . DS . 'views' . DS;
|
||||
}
|
||||
return array('class' => $type, 'suffix' => null, 'path' => $path);
|
||||
break;
|
||||
case 'helper':
|
||||
if (!class_exists('AppHelper')) {
|
||||
App::import($type, 'AppHelper', false);
|
||||
}
|
||||
if ($plugin) {
|
||||
$path = $pluginPath . DS . 'views' . DS . 'helpers' . DS;
|
||||
}
|
||||
return array('class' => $type, 'suffix' => null, 'path' => $path);
|
||||
break;
|
||||
case 'shell':
|
||||
if (!class_exists('Shell')) {
|
||||
App::import($type, 'Shell', false);
|
||||
}
|
||||
if (!class_exists('AppShell')) {
|
||||
App::import($type, 'AppShell', false);
|
||||
}
|
||||
if ($plugin) {
|
||||
$path = $pluginPath . DS . 'console' . DS . 'shells' . DS;
|
||||
}
|
||||
return array('class' => $type, 'suffix' => null, 'path' => $path);
|
||||
break;
|
||||
case 'vendor':
|
||||
if ($plugin) {
|
||||
$path = $pluginPath . DS . 'vendors' . DS;
|
||||
}
|
||||
return array('class' => null, 'suffix' => null, 'path' => $path);
|
||||
break;
|
||||
default:
|
||||
$type = $suffix = $path = null;
|
||||
break;
|
||||
}
|
||||
return array('class' => null, 'suffix' => null, 'path' => null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default search paths.
|
||||
*
|
||||
* @param string $type type of object to be searched
|
||||
* @return array list of paths
|
||||
*/
|
||||
private static function __paths($type) {
|
||||
$type = strtolower($type);
|
||||
$paths = array();
|
||||
|
||||
if ($type === 'core') {
|
||||
return App::core('libs');
|
||||
}
|
||||
if (isset(self::${$type . 's'})) {
|
||||
return self::${$type . 's'};
|
||||
}
|
||||
return $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes file location from map if the file has been deleted.
|
||||
*
|
||||
* @param string $name name of object
|
||||
* @param string $type type of object
|
||||
* @param string $plugin camelized name of plugin
|
||||
* @return void
|
||||
*/
|
||||
private static function __remove($name, $type, $plugin) {
|
||||
if ($plugin) {
|
||||
unset(self::$__map['Plugin'][$plugin][$type][$name]);
|
||||
} else {
|
||||
unset(self::$__map[$type][$name]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of filenames of PHP files in the given directory.
|
||||
*
|
||||
* @param string $path Path to scan for files
|
||||
* @param string $suffix if false, return only directories. if string, match and return files
|
||||
* @return array List of directories or files in directory
|
||||
*/
|
||||
private static function __list($path, $suffix = false, $extension = false) {
|
||||
if (!class_exists('Folder')) {
|
||||
require LIBS . 'folder.php';
|
||||
}
|
||||
$items = array();
|
||||
$Folder = new Folder($path);
|
||||
$contents = $Folder->read(false, true);
|
||||
|
||||
if (is_array($contents)) {
|
||||
if (!$suffix) {
|
||||
return $contents[0];
|
||||
} else {
|
||||
foreach ($contents[1] as $item) {
|
||||
if (substr($item, - strlen($suffix)) === $suffix) {
|
||||
if ($extension) {
|
||||
$items[] = $item;
|
||||
} else {
|
||||
$items[] = substr($item, 0, strlen($item) - strlen($suffix));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Object destructor.
|
||||
*
|
||||
* Writes cache file if changes have been made to the $__map or $__paths
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function shutdown() {
|
||||
if (self::$__cache) {
|
||||
$core = App::core('cake');
|
||||
unset(self::$__paths[rtrim($core[0], DS)]);
|
||||
Cache::write('dir_map', array_filter(self::$__paths), '_cake_core_');
|
||||
Cache::write('file_map', array_filter(self::$__map), '_cake_core_');
|
||||
Cache::write('object_map', self::$__objects, '_cake_core_');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spl_autoload_register(array('App', 'load'));
|
1216
lib/Cake/Routing/Router.php
Normal file
1216
lib/Cake/Routing/Router.php
Normal file
File diff suppressed because it is too large
Load diff
765
lib/Cake/Utility/Folder.php
Normal file
765
lib/Cake/Utility/Folder.php
Normal file
|
@ -0,0 +1,765 @@
|
|||
<?php
|
||||
/**
|
||||
* Convenience class for handling directories.
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Folder structure browser, lists folders and files.
|
||||
* Provides an Object interface for Common directory related tasks.
|
||||
*
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs
|
||||
*/
|
||||
class Folder {
|
||||
|
||||
/**
|
||||
* Path to Folder.
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
public $path = null;
|
||||
|
||||
/**
|
||||
* Sortedness. Whether or not list results
|
||||
* should be sorted by name.
|
||||
*
|
||||
* @var boolean
|
||||
* @access public
|
||||
*/
|
||||
public $sort = false;
|
||||
|
||||
/**
|
||||
* Mode to be used on create. Does nothing on windows platforms.
|
||||
*
|
||||
* @var integer
|
||||
* @access public
|
||||
*/
|
||||
public $mode = 0755;
|
||||
|
||||
/**
|
||||
* Holds messages from last method.
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
private $__messages = array();
|
||||
|
||||
/**
|
||||
* Holds errors from last method.
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
private $__errors = array();
|
||||
|
||||
/**
|
||||
* Holds array of complete directory paths.
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
private $__directories;
|
||||
|
||||
/**
|
||||
* Holds array of complete file paths.
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
private $__files;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $path Path to folder
|
||||
* @param boolean $create Create folder if not found
|
||||
* @param mixed $mode Mode (CHMOD) to apply to created folder, false to ignore
|
||||
*/
|
||||
function __construct($path = false, $create = false, $mode = false) {
|
||||
if (empty($path)) {
|
||||
$path = TMP;
|
||||
}
|
||||
if ($mode) {
|
||||
$this->mode = $mode;
|
||||
}
|
||||
|
||||
if (!file_exists($path) && $create === true) {
|
||||
$this->create($path, $this->mode);
|
||||
}
|
||||
if (!Folder::isAbsolute($path)) {
|
||||
$path = realpath($path);
|
||||
}
|
||||
if (!empty($path)) {
|
||||
$this->cd($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current path.
|
||||
*
|
||||
* @return string Current path
|
||||
*/
|
||||
public function pwd() {
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change directory to $path.
|
||||
*
|
||||
* @param string $path Path to the directory to change to
|
||||
* @return string The new path. Returns false on failure
|
||||
*/
|
||||
public function cd($path) {
|
||||
$path = $this->realpath($path);
|
||||
if (is_dir($path)) {
|
||||
return $this->path = $path;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of the contents of the current directory.
|
||||
* The returned array holds two arrays: One of directories and one of files.
|
||||
*
|
||||
* @param boolean $sort Whether you want the results sorted, set this and the sort property
|
||||
* to false to get unsorted results.
|
||||
* @param mixed $exceptions Either an array or boolean true will not grab dot files
|
||||
* @param boolean $fullPath True returns the full path
|
||||
* @return mixed Contents of current directory as an array, an empty array on failure
|
||||
*/
|
||||
public function read($sort = true, $exceptions = false, $fullPath = false) {
|
||||
$dirs = $files = array();
|
||||
|
||||
if (!$this->pwd()) {
|
||||
return array($dirs, $files);
|
||||
}
|
||||
if (is_array($exceptions)) {
|
||||
$exceptions = array_flip($exceptions);
|
||||
}
|
||||
$skipHidden = isset($exceptions['.']) || $exceptions === true;
|
||||
|
||||
if (false === ($dir = @opendir($this->path))) {
|
||||
return array($dirs, $files);
|
||||
}
|
||||
|
||||
while (false !== ($item = readdir($dir))) {
|
||||
if ($item === '.' || $item === '..' || ($skipHidden && $item[0] === '.') || isset($exceptions[$item])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$path = Folder::addPathElement($this->path, $item);
|
||||
if (is_dir($path)) {
|
||||
$dirs[] = $fullPath ? $path : $item;
|
||||
} else {
|
||||
$files[] = $fullPath ? $path : $item;
|
||||
}
|
||||
}
|
||||
|
||||
if ($sort || $this->sort) {
|
||||
sort($dirs);
|
||||
sort($files);
|
||||
}
|
||||
|
||||
closedir($dir);
|
||||
return array($dirs, $files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all matching files in current directory.
|
||||
*
|
||||
* @param string $pattern Preg_match pattern (Defaults to: .*)
|
||||
* @param boolean $sort Whether results should be sorted.
|
||||
* @return array Files that match given pattern
|
||||
*/
|
||||
public function find($regexpPattern = '.*', $sort = false) {
|
||||
list($dirs, $files) = $this->read($sort);
|
||||
return array_values(preg_grep('/^' . $regexpPattern . '$/i', $files)); ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all matching files in and below current directory.
|
||||
*
|
||||
* @param string $pattern Preg_match pattern (Defaults to: .*)
|
||||
* @param boolean $sort Whether results should be sorted.
|
||||
* @return array Files matching $pattern
|
||||
*/
|
||||
public function findRecursive($pattern = '.*', $sort = false) {
|
||||
if (!$this->pwd()) {
|
||||
return array();
|
||||
}
|
||||
$startsOn = $this->path;
|
||||
$out = $this->_findRecursive($pattern, $sort);
|
||||
$this->cd($startsOn);
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private helper function for findRecursive.
|
||||
*
|
||||
* @param string $pattern Pattern to match against
|
||||
* @param boolean $sort Whether results should be sorted.
|
||||
* @return array Files matching pattern
|
||||
* @access private
|
||||
*/
|
||||
function _findRecursive($pattern, $sort = false) {
|
||||
list($dirs, $files) = $this->read($sort);
|
||||
$found = array();
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (preg_match('/^' . $pattern . '$/i', $file)) {
|
||||
$found[] = Folder::addPathElement($this->path, $file);
|
||||
}
|
||||
}
|
||||
$start = $this->path;
|
||||
|
||||
foreach ($dirs as $dir) {
|
||||
$this->cd(Folder::addPathElement($start, $dir));
|
||||
$found = array_merge($found, $this->findRecursive($pattern, $sort));
|
||||
}
|
||||
return $found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given $path is a Windows path.
|
||||
*
|
||||
* @param string $path Path to check
|
||||
* @return boolean true if windows path, false otherwise
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isWindowsPath($path) {
|
||||
return (preg_match('/^[A-Z]:\\\\/i', $path) || substr($path, 0, 2) == '\\\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given $path is an absolute path.
|
||||
*
|
||||
* @param string $path Path to check
|
||||
* @return bool true if path is absolute.
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isAbsolute($path) {
|
||||
return !empty($path) && ($path[0] === '/' || preg_match('/^[A-Z]:\\\\/i', $path) || substr($path, 0, 2) == '\\\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a correct set of slashes for given $path. (\\ for Windows paths and / for other paths.)
|
||||
*
|
||||
* @param string $path Path to check
|
||||
* @return string Set of slashes ("\\" or "/")
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function normalizePath($path) {
|
||||
return Folder::correctSlashFor($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a correct set of slashes for given $path. (\\ for Windows paths and / for other paths.)
|
||||
*
|
||||
* @param string $path Path to check
|
||||
* @return string Set of slashes ("\\" or "/")
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function correctSlashFor($path) {
|
||||
return (Folder::isWindowsPath($path)) ? '\\' : '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns $path with added terminating slash (corrected for Windows or other OS).
|
||||
*
|
||||
* @param string $path Path to check
|
||||
* @return string Path with ending slash
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function slashTerm($path) {
|
||||
if (Folder::isSlashTerm($path)) {
|
||||
return $path;
|
||||
}
|
||||
return $path . Folder::correctSlashFor($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns $path with $element added, with correct slash in-between.
|
||||
*
|
||||
* @param string $path Path
|
||||
* @param string $element Element to and at end of path
|
||||
* @return string Combined path
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function addPathElement($path, $element) {
|
||||
return rtrim($path, DS) . DS . $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the File is in a given CakePath.
|
||||
*
|
||||
* @param string $path The path to check.
|
||||
* @return bool
|
||||
*/
|
||||
public function inCakePath($path = '') {
|
||||
$dir = substr(Folder::slashTerm(ROOT), 0, -1);
|
||||
$newdir = $dir . $path;
|
||||
|
||||
return $this->inPath($newdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the File is in given path.
|
||||
*
|
||||
* @param string $path The path to check that the current pwd() resides with in.
|
||||
* @param boolean $reverse
|
||||
* @return bool
|
||||
*/
|
||||
public function inPath($path = '', $reverse = false) {
|
||||
$dir = Folder::slashTerm($path);
|
||||
$current = Folder::slashTerm($this->pwd());
|
||||
|
||||
if (!$reverse) {
|
||||
$return = preg_match('/^(.*)' . preg_quote($dir, '/') . '(.*)/', $current);
|
||||
} else {
|
||||
$return = preg_match('/^(.*)' . preg_quote($current, '/') . '(.*)/', $dir);
|
||||
}
|
||||
return (bool)$return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the mode on a directory structure recursively. This includes changing the mode on files as well.
|
||||
*
|
||||
* @param string $path The path to chmod
|
||||
* @param integer $mode octal value 0755
|
||||
* @param boolean $recursive chmod recursively, set to false to only change the current directory.
|
||||
* @param array $exceptions array of files, directories to skip
|
||||
* @return boolean Returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
public function chmod($path, $mode = false, $recursive = true, $exceptions = array()) {
|
||||
if (!$mode) {
|
||||
$mode = $this->mode;
|
||||
}
|
||||
|
||||
if ($recursive === false && is_dir($path)) {
|
||||
if (@chmod($path, intval($mode, 8))) {
|
||||
$this->__messages[] = sprintf(__('%s changed to %s'), $path, $mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->__errors[] = sprintf(__('%s NOT changed to %s'), $path, $mode);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_dir($path)) {
|
||||
$paths = $this->tree($path);
|
||||
|
||||
foreach ($paths as $type) {
|
||||
foreach ($type as $key => $fullpath) {
|
||||
$check = explode(DS, $fullpath);
|
||||
$count = count($check);
|
||||
|
||||
if (in_array($check[$count - 1], $exceptions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (@chmod($fullpath, intval($mode, 8))) {
|
||||
$this->__messages[] = sprintf(__('%s changed to %s'), $fullpath, $mode);
|
||||
} else {
|
||||
$this->__errors[] = sprintf(__('%s NOT changed to %s'), $fullpath, $mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->__errors)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of nested directories and files in each directory
|
||||
*
|
||||
* @param string $path the directory path to build the tree from
|
||||
* @param mixed $exceptions Array of files to exclude, defaults to excluding hidden files.
|
||||
* @param string $type either file or dir. null returns both files and directories
|
||||
* @return mixed array of nested directories and files in each directory
|
||||
*/
|
||||
public function tree($path, $exceptions = true, $type = null) {
|
||||
$original = $this->path;
|
||||
$path = rtrim($path, DS);
|
||||
if (!$this->cd($path)) {
|
||||
if ($type === null) {
|
||||
return array(array(), array());
|
||||
}
|
||||
return array();
|
||||
}
|
||||
$this->__files = array();
|
||||
$this->__directories = array($this->realpath($path));
|
||||
$directories = array();
|
||||
|
||||
if ($exceptions === false) {
|
||||
$exceptions = true;
|
||||
}
|
||||
while (!empty($this->__directories)) {
|
||||
$dir = array_pop($this->__directories);
|
||||
$this->__tree($dir, $exceptions);
|
||||
$directories[] = $dir;
|
||||
}
|
||||
|
||||
if ($type === null) {
|
||||
return array($directories, $this->__files);
|
||||
}
|
||||
if ($type === 'dir') {
|
||||
return $directories;
|
||||
}
|
||||
$this->cd($original);
|
||||
|
||||
return $this->__files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private method to list directories and files in each directory
|
||||
*
|
||||
* @param string $path The Path to read.
|
||||
* @param mixed $exceptions Array of files to exclude from the read that will be performed.
|
||||
* @access private
|
||||
*/
|
||||
function __tree($path, $exceptions) {
|
||||
$this->path = $path;
|
||||
list($dirs, $files) = $this->read(false, $exceptions, true);
|
||||
$this->__directories = array_merge($this->__directories, $dirs);
|
||||
$this->__files = array_merge($this->__files, $files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a directory structure recursively. Can be used to create
|
||||
* deep path structures like `/foo/bar/baz/shoe/horn`
|
||||
*
|
||||
* @param string $pathname The directory structure to create
|
||||
* @param integer $mode octal value 0755
|
||||
* @return boolean Returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
public function create($pathname, $mode = false) {
|
||||
if (is_dir($pathname) || empty($pathname)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$mode) {
|
||||
$mode = $this->mode;
|
||||
}
|
||||
|
||||
if (is_file($pathname)) {
|
||||
$this->__errors[] = sprintf(__('%s is a file'), $pathname);
|
||||
return false;
|
||||
}
|
||||
$pathname = rtrim($pathname, DS);
|
||||
$nextPathname = substr($pathname, 0, strrpos($pathname, DS));
|
||||
|
||||
if ($this->create($nextPathname, $mode)) {
|
||||
if (!file_exists($pathname)) {
|
||||
$old = umask(0);
|
||||
if (mkdir($pathname, $mode)) {
|
||||
umask($old);
|
||||
$this->__messages[] = sprintf(__('%s created'), $pathname);
|
||||
return true;
|
||||
} else {
|
||||
umask($old);
|
||||
$this->__errors[] = sprintf(__('%s NOT created'), $pathname);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size in bytes of this Folder and its contents.
|
||||
*
|
||||
* @param string $directory Path to directory
|
||||
* @return int size in bytes of current folder
|
||||
*/
|
||||
public function dirsize() {
|
||||
$size = 0;
|
||||
$directory = Folder::slashTerm($this->path);
|
||||
$stack = array($directory);
|
||||
$count = count($stack);
|
||||
for ($i = 0, $j = $count; $i < $j; ++$i) {
|
||||
if (is_file($stack[$i])) {
|
||||
$size += filesize($stack[$i]);
|
||||
} elseif (is_dir($stack[$i])) {
|
||||
$dir = dir($stack[$i]);
|
||||
if ($dir) {
|
||||
while (false !== ($entry = $dir->read())) {
|
||||
if ($entry === '.' || $entry === '..') {
|
||||
continue;
|
||||
}
|
||||
$add = $stack[$i] . $entry;
|
||||
|
||||
if (is_dir($stack[$i] . $entry)) {
|
||||
$add = Folder::slashTerm($add);
|
||||
}
|
||||
$stack[] = $add;
|
||||
}
|
||||
$dir->close();
|
||||
}
|
||||
}
|
||||
$j = count($stack);
|
||||
}
|
||||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively Remove directories if the system allows.
|
||||
*
|
||||
* @param string $path Path of directory to delete
|
||||
* @return boolean Success
|
||||
*/
|
||||
public function delete($path = null) {
|
||||
if (!$path) {
|
||||
$path = $this->pwd();
|
||||
}
|
||||
if (!$path) {
|
||||
return null;
|
||||
}
|
||||
$path = Folder::slashTerm($path);
|
||||
if (is_dir($path) === true) {
|
||||
$normalFiles = glob($path . '*');
|
||||
$hiddenFiles = glob($path . '\.?*');
|
||||
|
||||
$normalFiles = $normalFiles ? $normalFiles : array();
|
||||
$hiddenFiles = $hiddenFiles ? $hiddenFiles : array();
|
||||
|
||||
$files = array_merge($normalFiles, $hiddenFiles);
|
||||
if (is_array($files)) {
|
||||
foreach ($files as $file) {
|
||||
if (preg_match('/(\.|\.\.)$/', $file)) {
|
||||
continue;
|
||||
}
|
||||
if (is_file($file) === true) {
|
||||
if (@unlink($file)) {
|
||||
$this->__messages[] = sprintf(__('%s removed'), $file);
|
||||
} else {
|
||||
$this->__errors[] = sprintf(__('%s NOT removed'), $file);
|
||||
}
|
||||
} elseif (is_dir($file) === true && $this->delete($file) === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
$path = substr($path, 0, strlen($path) - 1);
|
||||
if (rmdir($path) === false) {
|
||||
$this->__errors[] = sprintf(__('%s NOT removed'), $path);
|
||||
return false;
|
||||
} else {
|
||||
$this->__messages[] = sprintf(__('%s removed'), $path);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive directory copy.
|
||||
*
|
||||
* ### Options
|
||||
*
|
||||
* - `to` The directory to copy to.
|
||||
* - `from` The directory to copy from, this will cause a cd() to occur, changing the results of pwd().
|
||||
* - `chmod` The mode to copy the files/directories with.
|
||||
* - `skip` Files/directories to skip.
|
||||
*
|
||||
* @param mixed $options Either an array of options (see above) or a string of the destination directory.
|
||||
* @return bool Success
|
||||
*/
|
||||
public function copy($options = array()) {
|
||||
if (!$this->pwd()) {
|
||||
return false;
|
||||
}
|
||||
$to = null;
|
||||
if (is_string($options)) {
|
||||
$to = $options;
|
||||
$options = array();
|
||||
}
|
||||
$options = array_merge(array('to' => $to, 'from' => $this->path, 'mode' => $this->mode, 'skip' => array()), $options);
|
||||
|
||||
$fromDir = $options['from'];
|
||||
$toDir = $options['to'];
|
||||
$mode = $options['mode'];
|
||||
|
||||
if (!$this->cd($fromDir)) {
|
||||
$this->__errors[] = sprintf(__('%s not found'), $fromDir);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_dir($toDir)) {
|
||||
$this->create($toDir, $mode);
|
||||
}
|
||||
|
||||
if (!is_writable($toDir)) {
|
||||
$this->__errors[] = sprintf(__('%s not writable'), $toDir);
|
||||
return false;
|
||||
}
|
||||
|
||||
$exceptions = array_merge(array('.', '..', '.svn'), $options['skip']);
|
||||
if ($handle = @opendir($fromDir)) {
|
||||
while (false !== ($item = readdir($handle))) {
|
||||
if (!in_array($item, $exceptions)) {
|
||||
$from = Folder::addPathElement($fromDir, $item);
|
||||
$to = Folder::addPathElement($toDir, $item);
|
||||
if (is_file($from)) {
|
||||
if (copy($from, $to)) {
|
||||
chmod($to, intval($mode, 8));
|
||||
touch($to, filemtime($from));
|
||||
$this->__messages[] = sprintf(__('%s copied to %s'), $from, $to);
|
||||
} else {
|
||||
$this->__errors[] = sprintf(__('%s NOT copied to %s'), $from, $to);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_dir($from) && !file_exists($to)) {
|
||||
$old = umask(0);
|
||||
if (mkdir($to, $mode)) {
|
||||
umask($old);
|
||||
$old = umask(0);
|
||||
chmod($to, $mode);
|
||||
umask($old);
|
||||
$this->__messages[] = sprintf(__('%s created'), $to);
|
||||
$options = array_merge($options, array('to'=> $to, 'from'=> $from));
|
||||
$this->copy($options);
|
||||
} else {
|
||||
$this->__errors[] = sprintf(__('%s not created'), $to);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($this->__errors)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive directory move.
|
||||
*
|
||||
* ### Options
|
||||
*
|
||||
* - `to` The directory to copy to.
|
||||
* - `from` The directory to copy from, this will cause a cd() to occur, changing the results of pwd().
|
||||
* - `chmod` The mode to copy the files/directories with.
|
||||
* - `skip` Files/directories to skip.
|
||||
*
|
||||
* @param array $options (to, from, chmod, skip)
|
||||
* @return boolean Success
|
||||
*/
|
||||
public function move($options) {
|
||||
$to = null;
|
||||
if (is_string($options)) {
|
||||
$to = $options;
|
||||
$options = (array)$options;
|
||||
}
|
||||
$options = array_merge(
|
||||
array('to' => $to, 'from' => $this->path, 'mode' => $this->mode, 'skip' => array()),
|
||||
$options
|
||||
);
|
||||
|
||||
if ($this->copy($options)) {
|
||||
if ($this->delete($options['from'])) {
|
||||
return (bool)$this->cd($options['to']);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* get messages from latest method
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function messages() {
|
||||
return $this->__messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* get error from latest method
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function errors() {
|
||||
return $this->__errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the real path (taking ".." and such into account)
|
||||
*
|
||||
* @param string $path Path to resolve
|
||||
* @return string The resolved path
|
||||
*/
|
||||
function realpath($path) {
|
||||
$path = str_replace('/', DS, trim($path));
|
||||
if (strpos($path, '..') === false) {
|
||||
if (!Folder::isAbsolute($path)) {
|
||||
$path = Folder::addPathElement($this->path, $path);
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
$parts = explode(DS, $path);
|
||||
$newparts = array();
|
||||
$newpath = '';
|
||||
if ($path[0] === DS) {
|
||||
$newpath = DS;
|
||||
}
|
||||
|
||||
while (($part = array_shift($parts)) !== NULL) {
|
||||
if ($part === '.' || $part === '') {
|
||||
continue;
|
||||
}
|
||||
if ($part === '..') {
|
||||
if (!empty($newparts)) {
|
||||
array_pop($newparts);
|
||||
continue;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$newparts[] = $part;
|
||||
}
|
||||
$newpath .= implode(DS, $newparts);
|
||||
|
||||
return Folder::slashTerm($newpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given $path ends in a slash (i.e. is slash-terminated).
|
||||
*
|
||||
* @param string $path Path to check
|
||||
* @return boolean true if path ends with slash, false otherwise
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
function isSlashTerm($path) {
|
||||
$lastChar = $path[strlen($path) - 1];
|
||||
return $lastChar === '/' || $lastChar === '\\';
|
||||
}
|
||||
}
|
570
lib/Cake/Utility/Inflector.php
Normal file
570
lib/Cake/Utility/Inflector.php
Normal file
|
@ -0,0 +1,570 @@
|
|||
<?php
|
||||
/**
|
||||
* Pluralize and singularize English words.
|
||||
*
|
||||
* Used by Cake's naming conventions throughout the framework.
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pluralize and singularize English words.
|
||||
*
|
||||
* Inflector pluralizes and singularizes English nouns.
|
||||
* Used by Cake's naming conventions throughout the framework.
|
||||
*
|
||||
* @package cake
|
||||
* @subpackage cake.cake.libs
|
||||
* @link http://book.cakephp.org/view/1478/Inflector
|
||||
*/
|
||||
class Inflector {
|
||||
|
||||
/**
|
||||
* Plural inflector rules
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_plural = array(
|
||||
'rules' => array(
|
||||
'/(s)tatus$/i' => '\1\2tatuses',
|
||||
'/(quiz)$/i' => '\1zes',
|
||||
'/^(ox)$/i' => '\1\2en',
|
||||
'/([m|l])ouse$/i' => '\1ice',
|
||||
'/(matr|vert|ind)(ix|ex)$/i' => '\1ices',
|
||||
'/(x|ch|ss|sh)$/i' => '\1es',
|
||||
'/([^aeiouy]|qu)y$/i' => '\1ies',
|
||||
'/(hive)$/i' => '\1s',
|
||||
'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
|
||||
'/sis$/i' => 'ses',
|
||||
'/([ti])um$/i' => '\1a',
|
||||
'/(p)erson$/i' => '\1eople',
|
||||
'/(m)an$/i' => '\1en',
|
||||
'/(c)hild$/i' => '\1hildren',
|
||||
'/(buffal|tomat)o$/i' => '\1\2oes',
|
||||
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/i' => '\1i',
|
||||
'/us$/i' => 'uses',
|
||||
'/(alias)$/i' => '\1es',
|
||||
'/(ax|cris|test)is$/i' => '\1es',
|
||||
'/s$/' => 's',
|
||||
'/^$/' => '',
|
||||
'/$/' => 's',
|
||||
),
|
||||
'uninflected' => array(
|
||||
'.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', 'people'
|
||||
),
|
||||
'irregular' => array(
|
||||
'atlas' => 'atlases',
|
||||
'beef' => 'beefs',
|
||||
'brother' => 'brothers',
|
||||
'child' => 'children',
|
||||
'corpus' => 'corpuses',
|
||||
'cow' => 'cows',
|
||||
'ganglion' => 'ganglions',
|
||||
'genie' => 'genies',
|
||||
'genus' => 'genera',
|
||||
'graffito' => 'graffiti',
|
||||
'hoof' => 'hoofs',
|
||||
'loaf' => 'loaves',
|
||||
'man' => 'men',
|
||||
'money' => 'monies',
|
||||
'mongoose' => 'mongooses',
|
||||
'move' => 'moves',
|
||||
'mythos' => 'mythoi',
|
||||
'niche' => 'niches',
|
||||
'numen' => 'numina',
|
||||
'occiput' => 'occiputs',
|
||||
'octopus' => 'octopuses',
|
||||
'opus' => 'opuses',
|
||||
'ox' => 'oxen',
|
||||
'penis' => 'penises',
|
||||
'person' => 'people',
|
||||
'sex' => 'sexes',
|
||||
'soliloquy' => 'soliloquies',
|
||||
'testis' => 'testes',
|
||||
'trilby' => 'trilbys',
|
||||
'turf' => 'turfs'
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Singular inflector rules
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_singular = array(
|
||||
'rules' => array(
|
||||
'/(s)tatuses$/i' => '\1\2tatus',
|
||||
'/^(.*)(menu)s$/i' => '\1\2',
|
||||
'/(quiz)zes$/i' => '\\1',
|
||||
'/(matr)ices$/i' => '\1ix',
|
||||
'/(vert|ind)ices$/i' => '\1ex',
|
||||
'/^(ox)en/i' => '\1',
|
||||
'/(alias)(es)*$/i' => '\1',
|
||||
'/(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/i' => '\1us',
|
||||
'/([ftw]ax)es/i' => '\1',
|
||||
'/(cris|ax|test)es$/i' => '\1is',
|
||||
'/(shoe|slave)s$/i' => '\1',
|
||||
'/(o)es$/i' => '\1',
|
||||
'/ouses$/' => 'ouse',
|
||||
'/([^a])uses$/' => '\1us',
|
||||
'/([m|l])ice$/i' => '\1ouse',
|
||||
'/(x|ch|ss|sh)es$/i' => '\1',
|
||||
'/(m)ovies$/i' => '\1\2ovie',
|
||||
'/(s)eries$/i' => '\1\2eries',
|
||||
'/([^aeiouy]|qu)ies$/i' => '\1y',
|
||||
'/([lr])ves$/i' => '\1f',
|
||||
'/(tive)s$/i' => '\1',
|
||||
'/(hive)s$/i' => '\1',
|
||||
'/(drive)s$/i' => '\1',
|
||||
'/([^fo])ves$/i' => '\1fe',
|
||||
'/(^analy)ses$/i' => '\1sis',
|
||||
'/(analy|ba|diagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
|
||||
'/([ti])a$/i' => '\1um',
|
||||
'/(p)eople$/i' => '\1\2erson',
|
||||
'/(m)en$/i' => '\1an',
|
||||
'/(c)hildren$/i' => '\1\2hild',
|
||||
'/(n)ews$/i' => '\1\2ews',
|
||||
'/eaus$/' => 'eau',
|
||||
'/^(.*us)$/' => '\\1',
|
||||
'/s$/i' => ''
|
||||
),
|
||||
'uninflected' => array(
|
||||
'.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox', '.*sheep', '.*ss'
|
||||
),
|
||||
'irregular' => array(
|
||||
'waves' => 'wave'
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Words that should not be inflected
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_uninflected = array(
|
||||
'Amoyese', 'bison', 'Borghese', 'bream', 'breeches', 'britches', 'buffalo', 'cantus',
|
||||
'carp', 'chassis', 'clippers', 'cod', 'coitus', 'Congoese', 'contretemps', 'corps',
|
||||
'debris', 'diabetes', 'djinn', 'eland', 'elk', 'equipment', 'Faroese', 'flounder',
|
||||
'Foochowese', 'gallows', 'Genevese', 'Genoese', 'Gilbertese', 'graffiti',
|
||||
'headquarters', 'herpes', 'hijinks', 'Hottentotese', 'information', 'innings',
|
||||
'jackanapes', 'Kiplingese', 'Kongoese', 'Lucchese', 'mackerel', 'Maltese', 'media',
|
||||
'mews', 'moose', 'mumps', 'Nankingese', 'news', 'nexus', 'Niasese',
|
||||
'Pekingese', 'Piedmontese', 'pincers', 'Pistoiese', 'pliers', 'Portuguese',
|
||||
'proceedings', 'rabies', 'rice', 'rhinoceros', 'salmon', 'Sarawakese', 'scissors',
|
||||
'sea[- ]bass', 'series', 'Shavese', 'shears', 'siemens', 'species', 'swine', 'testes',
|
||||
'trousers', 'trout','tuna', 'Vermontese', 'Wenchowese', 'whiting', 'wildebeest',
|
||||
'Yengeese'
|
||||
);
|
||||
|
||||
/**
|
||||
* Default map of accented and special characters to ASCII characters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_transliteration = array(
|
||||
'/ä|æ|ǽ/' => 'ae',
|
||||
'/ö|œ/' => 'oe',
|
||||
'/ü/' => 'ue',
|
||||
'/Ä/' => 'Ae',
|
||||
'/Ü/' => 'Ue',
|
||||
'/Ö/' => 'Oe',
|
||||
'/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
|
||||
'/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
|
||||
'/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
|
||||
'/ç|ć|ĉ|ċ|č/' => 'c',
|
||||
'/Ð|Ď|Đ/' => 'D',
|
||||
'/ð|ď|đ/' => 'd',
|
||||
'/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
|
||||
'/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e',
|
||||
'/Ĝ|Ğ|Ġ|Ģ/' => 'G',
|
||||
'/ĝ|ğ|ġ|ģ/' => 'g',
|
||||
'/Ĥ|Ħ/' => 'H',
|
||||
'/ĥ|ħ/' => 'h',
|
||||
'/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I',
|
||||
'/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i',
|
||||
'/Ĵ/' => 'J',
|
||||
'/ĵ/' => 'j',
|
||||
'/Ķ/' => 'K',
|
||||
'/ķ/' => 'k',
|
||||
'/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
|
||||
'/ĺ|ļ|ľ|ŀ|ł/' => 'l',
|
||||
'/Ñ|Ń|Ņ|Ň/' => 'N',
|
||||
'/ñ|ń|ņ|ň|ʼn/' => 'n',
|
||||
'/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
|
||||
'/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
|
||||
'/Ŕ|Ŗ|Ř/' => 'R',
|
||||
'/ŕ|ŗ|ř/' => 'r',
|
||||
'/Ś|Ŝ|Ş|Š/' => 'S',
|
||||
'/ś|ŝ|ş|š|ſ/' => 's',
|
||||
'/Ţ|Ť|Ŧ/' => 'T',
|
||||
'/ţ|ť|ŧ/' => 't',
|
||||
'/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
|
||||
'/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
|
||||
'/Ý|Ÿ|Ŷ/' => 'Y',
|
||||
'/ý|ÿ|ŷ/' => 'y',
|
||||
'/Ŵ/' => 'W',
|
||||
'/ŵ/' => 'w',
|
||||
'/Ź|Ż|Ž/' => 'Z',
|
||||
'/ź|ż|ž/' => 'z',
|
||||
'/Æ|Ǽ/' => 'AE',
|
||||
'/ß/'=> 'ss',
|
||||
'/IJ/' => 'IJ',
|
||||
'/ij/' => 'ij',
|
||||
'/Œ/' => 'OE',
|
||||
'/ƒ/' => 'f'
|
||||
);
|
||||
|
||||
/**
|
||||
* Method cache array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_cache = array();
|
||||
|
||||
/**
|
||||
* The initial state of Inflector so reset() works.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_initialState = array();
|
||||
|
||||
/**
|
||||
* Cache inflected values, and return if already available
|
||||
*
|
||||
* @param string $type Inflection type
|
||||
* @param string $key Original value
|
||||
* @param string $value Inflected value
|
||||
* @return string Inflected value, from cache
|
||||
*/
|
||||
protected static function _cache($type, $key, $value = false) {
|
||||
$key = '_' . $key;
|
||||
$type = '_' . $type;
|
||||
if ($value !== false) {
|
||||
self::$_cache[$type][$key] = $value;
|
||||
return $value;
|
||||
}
|
||||
if (!isset(self::$_cache[$type][$key])) {
|
||||
return false;
|
||||
}
|
||||
return self::$_cache[$type][$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears Inflectors inflected value caches. And resets the inflection
|
||||
* rules to the initial values.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function reset() {
|
||||
if (empty(self::$_initialState)) {
|
||||
self::$_initialState = get_class_vars('Inflector');
|
||||
return;
|
||||
}
|
||||
foreach (self::$_initialState as $key => $val) {
|
||||
if ($key != '_initialState') {
|
||||
self::${$key} = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds custom inflection $rules, of either 'plural', 'singular' or 'transliteration' $type.
|
||||
*
|
||||
* ### Usage:
|
||||
*
|
||||
* {{{
|
||||
* Inflector::rules('plural', array('/^(inflect)or$/i' => '\1ables'));
|
||||
* Inflector::rules('plural', array(
|
||||
* 'rules' => array('/^(inflect)ors$/i' => '\1ables'),
|
||||
* 'uninflected' => array('dontinflectme'),
|
||||
* 'irregular' => array('red' => 'redlings')
|
||||
* ));
|
||||
* Inflector::rules('transliteration', array('/å/' => 'aa'));
|
||||
* }}}
|
||||
*
|
||||
* @param string $type The type of inflection, either 'plural', 'singular' or 'transliteration'
|
||||
* @param array $rules Array of rules to be added.
|
||||
* @param boolean $reset If true, will unset default inflections for all
|
||||
* new rules that are being defined in $rules.
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public static function rules($type, $rules, $reset = false) {
|
||||
$var = '_' . $type;
|
||||
|
||||
switch ($type) {
|
||||
case 'transliteration':
|
||||
if ($reset) {
|
||||
self::$_transliteration = $rules;
|
||||
} else {
|
||||
self::$_transliteration = $rules + self::$_transliteration;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
foreach ($rules as $rule => $pattern) {
|
||||
if (is_array($pattern)) {
|
||||
if ($reset) {
|
||||
self::${$var}[$rule] = $pattern;
|
||||
} else {
|
||||
self::${$var}[$rule] = array_merge($pattern, self::${$var}[$rule]);
|
||||
}
|
||||
unset($rules[$rule], self::${$var}['cache' . ucfirst($rule)]);
|
||||
if (isset(self::${$var}['merged'][$rule])) {
|
||||
unset(self::${$var}['merged'][$rule]);
|
||||
}
|
||||
if ($type === 'plural') {
|
||||
self::$_cache['pluralize'] = self::$_cache['tableize'] = array();
|
||||
} elseif ($type === 'singular') {
|
||||
self::$_cache['singularize'] = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
self::${$var}['rules'] = array_merge($rules, self::${$var}['rules']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return $word in plural form.
|
||||
*
|
||||
* @param string $word Word in singular
|
||||
* @return string Word in plural
|
||||
* @access public
|
||||
* @link http://book.cakephp.org/view/1479/Class-methods
|
||||
*/
|
||||
public static function pluralize($word) {
|
||||
|
||||
if (isset(self::$_cache['pluralize'][$word])) {
|
||||
return self::$_cache['pluralize'][$word];
|
||||
}
|
||||
|
||||
if (!isset(self::$_plural['merged']['irregular'])) {
|
||||
self::$_plural['merged']['irregular'] = self::$_plural['irregular'];
|
||||
}
|
||||
|
||||
if (!isset(self::$_plural['merged']['uninflected'])) {
|
||||
self::$_plural['merged']['uninflected'] = array_merge(self::$_plural['uninflected'], self::$_uninflected);
|
||||
}
|
||||
|
||||
if (!isset(self::$_plural['cacheUninflected']) || !isset(self::$_plural['cacheIrregular'])) {
|
||||
self::$_plural['cacheUninflected'] = '(?:' . implode('|', self::$_plural['merged']['uninflected']) . ')';
|
||||
self::$_plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$_plural['merged']['irregular'])) . ')';
|
||||
}
|
||||
|
||||
if (preg_match('/(.*)\\b(' . self::$_plural['cacheIrregular'] . ')$/i', $word, $regs)) {
|
||||
self::$_cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$_plural['merged']['irregular'][strtolower($regs[2])], 1);
|
||||
return self::$_cache['pluralize'][$word];
|
||||
}
|
||||
|
||||
if (preg_match('/^(' . self::$_plural['cacheUninflected'] . ')$/i', $word, $regs)) {
|
||||
self::$_cache['pluralize'][$word] = $word;
|
||||
return $word;
|
||||
}
|
||||
|
||||
foreach (self::$_plural['rules'] as $rule => $replacement) {
|
||||
if (preg_match($rule, $word)) {
|
||||
self::$_cache['pluralize'][$word] = preg_replace($rule, $replacement, $word);
|
||||
return self::$_cache['pluralize'][$word];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return $word in singular form.
|
||||
*
|
||||
* @param string $word Word in plural
|
||||
* @return string Word in singular
|
||||
* @access public
|
||||
* @link http://book.cakephp.org/view/1479/Class-methods
|
||||
*/
|
||||
public static function singularize($word) {
|
||||
|
||||
if (isset(self::$_cache['singularize'][$word])) {
|
||||
return self::$_cache['singularize'][$word];
|
||||
}
|
||||
|
||||
if (!isset(self::$_singular['merged']['uninflected'])) {
|
||||
self::$_singular['merged']['uninflected'] = array_merge(
|
||||
self::$_singular['uninflected'],
|
||||
self::$_uninflected
|
||||
);
|
||||
}
|
||||
|
||||
if (!isset(self::$_singular['merged']['irregular'])) {
|
||||
self::$_singular['merged']['irregular'] = array_merge(
|
||||
self::$_singular['irregular'],
|
||||
array_flip(self::$_plural['irregular'])
|
||||
);
|
||||
}
|
||||
|
||||
if (!isset(self::$_singular['cacheUninflected']) || !isset(self::$_singular['cacheIrregular'])) {
|
||||
self::$_singular['cacheUninflected'] = '(?:' . join( '|', self::$_singular['merged']['uninflected']) . ')';
|
||||
self::$_singular['cacheIrregular'] = '(?:' . join( '|', array_keys(self::$_singular['merged']['irregular'])) . ')';
|
||||
}
|
||||
|
||||
if (preg_match('/(.*)\\b(' . self::$_singular['cacheIrregular'] . ')$/i', $word, $regs)) {
|
||||
self::$_cache['singularize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$_singular['merged']['irregular'][strtolower($regs[2])], 1);
|
||||
return self::$_cache['singularize'][$word];
|
||||
}
|
||||
|
||||
if (preg_match('/^(' . self::$_singular['cacheUninflected'] . ')$/i', $word, $regs)) {
|
||||
self::$_cache['singularize'][$word] = $word;
|
||||
return $word;
|
||||
}
|
||||
|
||||
foreach (self::$_singular['rules'] as $rule => $replacement) {
|
||||
if (preg_match($rule, $word)) {
|
||||
self::$_cache['singularize'][$word] = preg_replace($rule, $replacement, $word);
|
||||
return self::$_cache['singularize'][$word];
|
||||
}
|
||||
}
|
||||
self::$_cache['singularize'][$word] = $word;
|
||||
return $word;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given lower_case_and_underscored_word as a CamelCased word.
|
||||
*
|
||||
* @param string $lower_case_and_underscored_word Word to camelize
|
||||
* @return string Camelized word. LikeThis.
|
||||
* @access public
|
||||
* @link http://book.cakephp.org/view/1479/Class-methods
|
||||
*/
|
||||
public static function camelize($lowerCaseAndUnderscoredWord) {
|
||||
if (!($result = self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord))) {
|
||||
$result = str_replace(' ', '', Inflector::humanize($lowerCaseAndUnderscoredWord));
|
||||
self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord, $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given camelCasedWord as an underscored_word.
|
||||
*
|
||||
* @param string $camelCasedWord Camel-cased word to be "underscorized"
|
||||
* @return string Underscore-syntaxed version of the $camelCasedWord
|
||||
* @access public
|
||||
* @link http://book.cakephp.org/view/1479/Class-methods
|
||||
*/
|
||||
public static function underscore($camelCasedWord) {
|
||||
if (!($result = self::_cache(__FUNCTION__, $camelCasedWord))) {
|
||||
$result = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $camelCasedWord));
|
||||
self::_cache(__FUNCTION__, $camelCasedWord, $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given underscored_word_group as a Human Readable Word Group.
|
||||
* (Underscores are replaced by spaces and capitalized following words.)
|
||||
*
|
||||
* @param string $lower_case_and_underscored_word String to be made more readable
|
||||
* @return string Human-readable string
|
||||
* @access public
|
||||
* @link http://book.cakephp.org/view/1479/Class-methods
|
||||
*/
|
||||
public static function humanize($lowerCaseAndUnderscoredWord) {
|
||||
if (!($result = self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord))) {
|
||||
$result = ucwords(str_replace('_', ' ', $lowerCaseAndUnderscoredWord));
|
||||
self::_cache(__FUNCTION__, $lowerCaseAndUnderscoredWord, $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns corresponding table name for given model $className. ("people" for the model class "Person").
|
||||
*
|
||||
* @param string $className Name of class to get database table name for
|
||||
* @return string Name of the database table for given class
|
||||
* @access public
|
||||
* @link http://book.cakephp.org/view/1479/Class-methods
|
||||
*/
|
||||
public static function tableize($className) {
|
||||
if (!($result = self::_cache(__FUNCTION__, $className))) {
|
||||
$result = Inflector::pluralize(Inflector::underscore($className));
|
||||
self::_cache(__FUNCTION__, $className, $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Cake model class name ("Person" for the database table "people".) for given database table.
|
||||
*
|
||||
* @param string $tableName Name of database table to get class name for
|
||||
* @return string Class name
|
||||
* @access public
|
||||
* @link http://book.cakephp.org/view/1479/Class-methods
|
||||
*/
|
||||
public static function classify($tableName) {
|
||||
if (!($result = self::_cache(__FUNCTION__, $tableName))) {
|
||||
$result = Inflector::camelize(Inflector::singularize($tableName));
|
||||
self::_cache(__FUNCTION__, $tableName, $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns camelBacked version of an underscored string.
|
||||
*
|
||||
* @param string $string
|
||||
* @return string in variable form
|
||||
* @access public
|
||||
* @link http://book.cakephp.org/view/1479/Class-methods
|
||||
*/
|
||||
public static function variable($string) {
|
||||
if (!($result = self::_cache(__FUNCTION__, $string))) {
|
||||
$string2 = Inflector::camelize(Inflector::underscore($string));
|
||||
$replace = strtolower(substr($string2, 0, 1));
|
||||
$result = preg_replace('/\\w/', $replace, $string2, 1);
|
||||
self::_cache(__FUNCTION__, $string, $result);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with all spaces converted to underscores (by default), accented
|
||||
* characters converted to non-accented characters, and non word characters removed.
|
||||
*
|
||||
* @param string $string the string you want to slug
|
||||
* @param string $replacement will replace keys in map
|
||||
* @param array $map extra elements to map to the replacement
|
||||
* @deprecated $map param will be removed in future versions. Use Inflector::rules() instead
|
||||
* @return string
|
||||
* @access public
|
||||
* @link http://book.cakephp.org/view/1479/Class-methods
|
||||
*/
|
||||
public static function slug($string, $replacement = '_', $map = array()) {
|
||||
|
||||
if (is_array($replacement)) {
|
||||
$map = $replacement;
|
||||
$replacement = '_';
|
||||
}
|
||||
$quotedReplacement = preg_quote($replacement, '/');
|
||||
|
||||
$merge = array(
|
||||
'/[^\s\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}]/mu' => ' ',
|
||||
'/\\s+/' => $replacement,
|
||||
sprintf('/^[%s]+|[%s]+$/', $quotedReplacement, $quotedReplacement) => '',
|
||||
);
|
||||
|
||||
$map = $map + self::$_transliteration + $merge;
|
||||
return preg_replace(array_keys($map), array_values($map), $string);
|
||||
}
|
||||
}
|
||||
|
||||
// Store the initial state
|
||||
Inflector::reset();
|
Loading…
Add table
Add a link
Reference in a new issue