mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-19 02:56:15 +00:00
Merge branch '2.4' making 2.4 into the master branch.
Conflicts: lib/Cake/VERSION.txt
This commit is contained in:
commit
4f237e6a93
184 changed files with 5267 additions and 1671 deletions
|
@ -34,6 +34,6 @@ Get Support!
|
|||
|
||||
[Lighthouse](https://cakephp.lighthouseapp.com/) - Got issues? Please tell us!
|
||||
|
||||
[![Bake Status](https://secure.travis-ci.org/cakephp/cakephp.png?branch=master)](http://travis-ci.org/cakephp/cakephp)
|
||||
[![Bake Status](https://secure.travis-ci.org/cakephp/cakephp.png?branch=2.4)](http://travis-ci.org/cakephp/cakephp)
|
||||
|
||||
![Cake Power](https://raw.github.com/cakephp/cakephp/master/lib/Cake/Console/Templates/skel/webroot/img/cake.power.gif)
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
*/
|
||||
class DbAclSchema extends CakeSchema {
|
||||
|
||||
public $name = 'DbAcl';
|
||||
|
||||
public function before($event = array()) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,9 @@
|
|||
* - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you
|
||||
* should place the file for that class in app/Lib/Error. This class needs to implement a render method.
|
||||
* - `log` - boolean - Should Exceptions be logged?
|
||||
* - `skipLog` - array - list of exceptions to skip for logging. Exceptions that
|
||||
* extend one of the listed exceptions will also be skipped for logging.
|
||||
* Example: `'skipLog' => array('NotFoundException', 'UnauthorizedException')`
|
||||
*
|
||||
* @see ErrorHandler for more information on exception handling and configuration.
|
||||
*/
|
||||
|
@ -105,6 +108,33 @@
|
|||
*/
|
||||
//Configure::write('App.baseUrl', env('SCRIPT_NAME'));
|
||||
|
||||
/**
|
||||
* To configure CakePHP to use a particular domain URL
|
||||
* for any URL generation inside the application, set the following
|
||||
* configuration variable to the http(s) address to your domain. This
|
||||
* will override the automatic detection of full base URL and can be
|
||||
* useful when generating links from the CLI (e.g. sending emails)
|
||||
*/
|
||||
//Configure::write('App.fullBaseUrl', 'http://example.com');
|
||||
|
||||
/**
|
||||
* Web path to the public images directory under webroot.
|
||||
* If not set defaults to 'img/'
|
||||
*/
|
||||
//Configure::write('App.imageBaseUrl', 'img/');
|
||||
|
||||
/**
|
||||
* Web path to the CSS files directory under webroot.
|
||||
* If not set defaults to 'css/'
|
||||
*/
|
||||
//Configure::write('App.cssBaseUrl', 'css/');
|
||||
|
||||
/**
|
||||
* Web path to the js files directory under webroot.
|
||||
* If not set defaults to 'js/'
|
||||
*/
|
||||
//Configure::write('App.jsBaseUrl', 'js/');
|
||||
|
||||
/**
|
||||
* Uncomment the define below to use CakePHP prefix routes.
|
||||
*
|
||||
|
|
|
@ -52,6 +52,12 @@
|
|||
*
|
||||
* unix_socket =>
|
||||
* For MySQL to connect via socket specify the `unix_socket` parameter instead of `host` and `port`
|
||||
*
|
||||
* settings =>
|
||||
* Array of key/value pairs, on connection it executes SET statements for each pair
|
||||
* For MySQL : http://dev.mysql.com/doc/refman/5.6/en/set-statement.html
|
||||
* For Postgres : http://www.postgresql.org/docs/9.2/static/sql-set.html
|
||||
* For Sql Server : http://msdn.microsoft.com/en-us/library/ms190356.aspx
|
||||
*/
|
||||
class DATABASE_CONFIG {
|
||||
|
||||
|
|
|
@ -31,13 +31,6 @@ App::uses('AppController', 'Controller');
|
|||
*/
|
||||
class PagesController extends AppController {
|
||||
|
||||
/**
|
||||
* Controller name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name = 'Pages';
|
||||
|
||||
/**
|
||||
* This controller does not use a model
|
||||
*
|
||||
|
@ -50,6 +43,8 @@ class PagesController extends AppController {
|
|||
*
|
||||
* @param mixed What page to display
|
||||
* @return void
|
||||
* @throws NotFoundException When the view file could not be found
|
||||
* or MissingViewException in debug mode.
|
||||
*/
|
||||
public function display() {
|
||||
$path = func_get_args();
|
||||
|
@ -70,6 +65,14 @@ class PagesController extends AppController {
|
|||
$title_for_layout = Inflector::humanize($path[$count - 1]);
|
||||
}
|
||||
$this->set(compact('page', 'subpage', 'title_for_layout'));
|
||||
$this->render(implode('/', $path));
|
||||
|
||||
try {
|
||||
$this->render(implode('/', $path));
|
||||
} catch (MissingViewException $e) {
|
||||
if (Configure::read('debug')) {
|
||||
throw $e;
|
||||
}
|
||||
throw new NotFoundException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^(.*)$ index.php [QSA,L]
|
||||
RewriteRule ^ index.php [L]
|
||||
</IfModule>
|
||||
|
|
|
@ -51,6 +51,13 @@ class Cache {
|
|||
*/
|
||||
protected static $_config = array();
|
||||
|
||||
/**
|
||||
* Group to Config mapping
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_groups = array();
|
||||
|
||||
/**
|
||||
* Whether to reset the settings with the next call to Cache::set();
|
||||
*
|
||||
|
@ -130,6 +137,14 @@ class Cache {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!empty(self::$_config[$name]['groups'])) {
|
||||
foreach (self::$_config[$name]['groups'] as $group) {
|
||||
self::$_groups[$group][] = $name;
|
||||
sort(self::$_groups[$group]);
|
||||
self::$_groups[$group] = array_unique(self::$_groups[$group]);
|
||||
}
|
||||
}
|
||||
|
||||
$engine = self::$_config[$name]['engine'];
|
||||
|
||||
if (!isset(self::$_engines[$name])) {
|
||||
|
@ -159,7 +174,7 @@ class Cache {
|
|||
}
|
||||
$cacheClass = $class . 'Engine';
|
||||
if (!is_subclass_of($cacheClass, 'CacheEngine')) {
|
||||
throw new CacheException(__d('cake_dev', 'Cache engines must use CacheEngine as a base class.'));
|
||||
throw new CacheException(__d('cake_dev', 'Cache engines must use %s as a base class.', 'CacheEngine'));
|
||||
}
|
||||
self::$_engines[$name] = new $cacheClass();
|
||||
if (!self::$_engines[$name]->init($config)) {
|
||||
|
@ -498,4 +513,33 @@ class Cache {
|
|||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve group names to config mapping.
|
||||
*
|
||||
* {{{
|
||||
* Cache::config('daily', array(
|
||||
* 'duration' => '1 day', 'groups' => array('posts')
|
||||
* ));
|
||||
* Cache::config('weekly', array(
|
||||
* 'duration' => '1 week', 'groups' => array('posts', 'archive')
|
||||
* ));
|
||||
* $configs = Cache::groupConfigs('posts');
|
||||
* }}}
|
||||
*
|
||||
* $config will equal to `array('posts' => array('daily', 'weekly'))`
|
||||
*
|
||||
* @param string $group group name or null to retrieve all group mappings
|
||||
* @return array map of group and all configuration that has the same group
|
||||
* @throws CacheException
|
||||
*/
|
||||
public static function groupConfigs($group = null) {
|
||||
if ($group == null) {
|
||||
return self::$_groups;
|
||||
}
|
||||
if (isset(self::$_groups[$group])) {
|
||||
return array($group => self::$_groups[$group]);
|
||||
}
|
||||
throw new CacheException(__d('cake_dev', 'Invalid cache group %s', $group));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -336,7 +336,7 @@ class FileEngine extends CacheEngine {
|
|||
$dir = $this->settings['path'] . $groups;
|
||||
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0777, true);
|
||||
mkdir($dir, 0775, true);
|
||||
}
|
||||
$path = new SplFileInfo($dir . $key);
|
||||
|
||||
|
@ -369,6 +369,12 @@ class FileEngine extends CacheEngine {
|
|||
*/
|
||||
protected function _active() {
|
||||
$dir = new SplFileInfo($this->settings['path']);
|
||||
if (Configure::read('debug')) {
|
||||
$path = $dir->getPathname();
|
||||
if (!is_dir($path)) {
|
||||
mkdir($path, 0775, true);
|
||||
}
|
||||
}
|
||||
if ($this->_init && !($dir->isDir() && $dir->isWritable())) {
|
||||
$this->_init = false;
|
||||
trigger_error(__d('cake_dev', '%s is not writable', $this->settings['path']), E_USER_WARNING);
|
||||
|
|
|
@ -165,7 +165,7 @@ class MemcacheEngine extends CacheEngine {
|
|||
public function increment($key, $offset = 1) {
|
||||
if ($this->settings['compress']) {
|
||||
throw new CacheException(
|
||||
__d('cake_dev', 'Method increment() not implemented for compressed cache in %s', __CLASS__)
|
||||
__d('cake_dev', 'Method %s not implemented for compressed cache in %s', 'increment()', __CLASS__)
|
||||
);
|
||||
}
|
||||
return $this->_Memcache->increment($key, $offset);
|
||||
|
@ -182,7 +182,7 @@ class MemcacheEngine extends CacheEngine {
|
|||
public function decrement($key, $offset = 1) {
|
||||
if ($this->settings['compress']) {
|
||||
throw new CacheException(
|
||||
__d('cake_dev', 'Method decrement() not implemented for compressed cache in %s', __CLASS__)
|
||||
__d('cake_dev', 'Method %s not implemented for compressed cache in %s', 'decrement()', __CLASS__)
|
||||
);
|
||||
}
|
||||
return $this->_Memcache->decrement($key, $offset);
|
||||
|
|
|
@ -71,7 +71,7 @@ class PhpReader implements ConfigReaderInterface {
|
|||
|
||||
include $file;
|
||||
if (!isset($config)) {
|
||||
throw new ConfigureException(__d('cake_dev', 'No variable $config found in %s', $file));
|
||||
throw new ConfigureException(__d('cake_dev', 'No variable %s found in %s', '$config', $file));
|
||||
}
|
||||
return $config;
|
||||
}
|
||||
|
|
|
@ -245,6 +245,9 @@ class BakeShell extends AppShell {
|
|||
'help' => __d('cake_console', 'Database connection to use in conjunction with `bake all`.'),
|
||||
'short' => 'c',
|
||||
'default' => 'default'
|
||||
))->addOption('theme', array(
|
||||
'short' => 't',
|
||||
'help' => __d('cake_console', 'Theme to use when baking code.')
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ App::uses('AppShell', 'Console/Command');
|
|||
* Provides a very basic 'interactive' console for CakePHP apps.
|
||||
*
|
||||
* @package Cake.Console.Command
|
||||
* @deprecated Deprecated since version 2.4, will be removed in 3.0
|
||||
*/
|
||||
class ConsoleShell extends AppShell {
|
||||
|
||||
|
@ -43,6 +44,35 @@ class ConsoleShell extends AppShell {
|
|||
*/
|
||||
public $models = array();
|
||||
|
||||
/**
|
||||
* _finished
|
||||
*
|
||||
* This shell is perpetual, setting this property to true exits the process
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $_finished = false;
|
||||
|
||||
/**
|
||||
* _methodPatterns
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_methodPatterns = array(
|
||||
'help' => '/^(help|\?)/',
|
||||
'_exit' => '/^(quit|exit)/',
|
||||
'_models' => '/^models/i',
|
||||
'_bind' => '/^(\w+) bind (\w+) (\w+)/',
|
||||
'_unbind' => '/^(\w+) unbind (\w+) (\w+)/',
|
||||
'_find' => '/.+->find/',
|
||||
'_save' => '/.+->save/',
|
||||
'_columns' => '/^(\w+) columns/',
|
||||
'_routesReload' => '/^routes\s+reload/i',
|
||||
'_routesShow' => '/^routes\s+show/i',
|
||||
'_routeToString' => '/^route\s+(\(.*\))$/i',
|
||||
'_routeToArray' => '/^route\s+(.*)$/i',
|
||||
);
|
||||
|
||||
/**
|
||||
* Override startup of the Shell
|
||||
*
|
||||
|
@ -74,6 +104,11 @@ class ConsoleShell extends AppShell {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* getOptionParser
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getOptionParser() {
|
||||
$description = array(
|
||||
'The interactive console is a tool for testing parts of your',
|
||||
|
@ -163,191 +198,289 @@ class ConsoleShell extends AppShell {
|
|||
* @return void
|
||||
*/
|
||||
public function main($command = null) {
|
||||
while (true) {
|
||||
$this->_finished = false;
|
||||
while (!$this->_finished) {
|
||||
if (empty($command)) {
|
||||
$command = trim($this->in(''));
|
||||
}
|
||||
switch (true) {
|
||||
case $command == 'help':
|
||||
$this->help();
|
||||
break;
|
||||
case $command == 'quit':
|
||||
case $command == 'exit':
|
||||
return true;
|
||||
case $command == 'models':
|
||||
$this->out(__d('cake_console', 'Model classes:'));
|
||||
$this->hr();
|
||||
foreach ($this->models as $model) {
|
||||
$this->out(" - {$model}");
|
||||
}
|
||||
break;
|
||||
case preg_match("/^(\w+) bind (\w+) (\w+)/", $command, $tmp):
|
||||
foreach ($tmp as $data) {
|
||||
$data = strip_tags($data);
|
||||
$data = str_replace($this->badCommandChars, "", $data);
|
||||
}
|
||||
|
||||
$modelA = $tmp[1];
|
||||
$association = $tmp[2];
|
||||
$modelB = $tmp[3];
|
||||
$method = $this->_method($command);
|
||||
|
||||
if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations)) {
|
||||
$this->{$modelA}->bindModel(array($association => array($modelB => array('className' => $modelB))), false);
|
||||
$this->out(__d('cake_console', "Created %s association between %s and %s",
|
||||
$association, $modelA, $modelB));
|
||||
} else {
|
||||
$this->out(__d('cake_console', "Please verify you are using valid models and association types"));
|
||||
}
|
||||
break;
|
||||
case preg_match("/^(\w+) unbind (\w+) (\w+)/", $command, $tmp):
|
||||
foreach ($tmp as $data) {
|
||||
$data = strip_tags($data);
|
||||
$data = str_replace($this->badCommandChars, "", $data);
|
||||
}
|
||||
|
||||
$modelA = $tmp[1];
|
||||
$association = $tmp[2];
|
||||
$modelB = $tmp[3];
|
||||
|
||||
// Verify that there is actually an association to unbind
|
||||
$currentAssociations = $this->{$modelA}->getAssociated();
|
||||
$validCurrentAssociation = false;
|
||||
|
||||
foreach ($currentAssociations as $model => $currentAssociation) {
|
||||
if ($model == $modelB && $association == $currentAssociation) {
|
||||
$validCurrentAssociation = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations) && $validCurrentAssociation) {
|
||||
$this->{$modelA}->unbindModel(array($association => array($modelB)));
|
||||
$this->out(__d('cake_console', "Removed %s association between %s and %s",
|
||||
$association, $modelA, $modelB));
|
||||
} else {
|
||||
$this->out(__d('cake_console', "Please verify you are using valid models, valid current association, and valid association types"));
|
||||
}
|
||||
break;
|
||||
case (strpos($command, "->find") > 0):
|
||||
// Remove any bad info
|
||||
$command = strip_tags($command);
|
||||
$command = str_replace($this->badCommandChars, "", $command);
|
||||
|
||||
// Do we have a valid model?
|
||||
list($modelToCheck, $tmp) = explode('->', $command);
|
||||
|
||||
if ($this->_isValidModel($modelToCheck)) {
|
||||
$findCommand = "\$data = \$this->$command;";
|
||||
//@codingStandardsIgnoreStart
|
||||
@eval($findCommand);
|
||||
//@codingStandardsIgnoreEnd
|
||||
|
||||
if (is_array($data)) {
|
||||
foreach ($data as $idx => $results) {
|
||||
if (is_numeric($idx)) { // findAll() output
|
||||
foreach ($results as $modelName => $result) {
|
||||
$this->out("$modelName");
|
||||
|
||||
foreach ($result as $field => $value) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $field2 => $value2) {
|
||||
$this->out("\t$field2: $value2");
|
||||
}
|
||||
|
||||
$this->out();
|
||||
} else {
|
||||
$this->out("\t$field: $value");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // find() output
|
||||
$this->out($idx);
|
||||
|
||||
foreach ($results as $field => $value) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $field2 => $value2) {
|
||||
$this->out("\t$field2: $value2");
|
||||
}
|
||||
|
||||
$this->out();
|
||||
} else {
|
||||
$this->out("\t$field: $value");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->out();
|
||||
$this->out(__d('cake_console', "No result set found"));
|
||||
}
|
||||
} else {
|
||||
$this->out(__d('cake_console', "%s is not a valid model", $modelToCheck));
|
||||
}
|
||||
|
||||
break;
|
||||
case (strpos($command, '->save') > 0):
|
||||
// Validate the model we're trying to save here
|
||||
$command = strip_tags($command);
|
||||
$command = str_replace($this->badCommandChars, "", $command);
|
||||
list($modelToSave, $tmp) = explode("->", $command);
|
||||
|
||||
if ($this->_isValidModel($modelToSave)) {
|
||||
// Extract the array of data we are trying to build
|
||||
list(, $data) = explode("->save", $command);
|
||||
$data = preg_replace('/^\(*(array)?\(*(.+?)\)*$/i', '\\2', $data);
|
||||
$saveCommand = "\$this->{$modelToSave}->save(array('{$modelToSave}' => array({$data})));";
|
||||
//@codingStandardsIgnoreStart
|
||||
@eval($saveCommand);
|
||||
//@codingStandardsIgnoreEnd
|
||||
$this->out(__d('cake_console', 'Saved record for %s', $modelToSave));
|
||||
}
|
||||
break;
|
||||
case preg_match("/^(\w+) columns/", $command, $tmp):
|
||||
$modelToCheck = strip_tags(str_replace($this->badCommandChars, "", $tmp[1]));
|
||||
|
||||
if ($this->_isValidModel($modelToCheck)) {
|
||||
// Get the column info for this model
|
||||
$fieldsCommand = "\$data = \$this->{$modelToCheck}->getColumnTypes();";
|
||||
//@codingStandardsIgnoreStart
|
||||
@eval($fieldsCommand);
|
||||
//@codingStandardsIgnoreEnd
|
||||
|
||||
if (is_array($data)) {
|
||||
foreach ($data as $field => $type) {
|
||||
$this->out("\t{$field}: {$type}");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->out(__d('cake_console', "Please verify that you selected a valid model"));
|
||||
}
|
||||
break;
|
||||
case preg_match("/^routes\s+reload/i", $command, $tmp):
|
||||
if (!$this->_loadRoutes()) {
|
||||
$this->err(__d('cake_console', "There was an error loading the routes config. Please check that the file exists and is free of parse errors."));
|
||||
break;
|
||||
}
|
||||
$this->out(__d('cake_console', "Routes configuration reloaded, %d routes connected", count(Router::$routes)));
|
||||
break;
|
||||
case preg_match("/^routes\s+show/i", $command, $tmp):
|
||||
$this->out(print_r(Hash::combine(Router::$routes, '{n}.template', '{n}.defaults'), true));
|
||||
break;
|
||||
case (preg_match("/^route\s+(\(.*\))$/i", $command, $tmp) == true):
|
||||
//@codingStandardsIgnoreStart
|
||||
if ($url = eval('return array' . $tmp[1] . ';')) {
|
||||
//@codingStandardsIgnoreEnd
|
||||
$this->out(Router::url($url));
|
||||
}
|
||||
break;
|
||||
case preg_match("/^route\s+(.*)/i", $command, $tmp):
|
||||
$this->out(var_export(Router::parse($tmp[1]), true));
|
||||
break;
|
||||
default:
|
||||
$this->out(__d('cake_console', "Invalid command"));
|
||||
$this->out();
|
||||
if ($method) {
|
||||
$this->$method($command);
|
||||
} else {
|
||||
$this->out(__d('cake_console', "Invalid command"));
|
||||
$this->out();
|
||||
}
|
||||
$command = '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the method to process the current command
|
||||
*
|
||||
* @param string $command
|
||||
* @return string or false
|
||||
*/
|
||||
protected function _method($command) {
|
||||
foreach ($this->_methodPatterns as $method => $pattern) {
|
||||
if (preg_match($pattern, $command)) {
|
||||
return $method;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the finiished property so that the loop in main method ends
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _exit() {
|
||||
$this->_finished = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all models
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _models() {
|
||||
$this->out(__d('cake_console', 'Model classes:'));
|
||||
$this->hr();
|
||||
foreach ($this->models as $model) {
|
||||
$this->out(" - {$model}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind an association
|
||||
*
|
||||
* @param mixed $command
|
||||
* @return void
|
||||
*/
|
||||
protected function _bind($command) {
|
||||
preg_match($this->_methodPatterns[__FUNCTION__], $command, $tmp);
|
||||
|
||||
foreach ($tmp as $data) {
|
||||
$data = strip_tags($data);
|
||||
$data = str_replace($this->badCommandChars, "", $data);
|
||||
}
|
||||
|
||||
$modelA = $tmp[1];
|
||||
$association = $tmp[2];
|
||||
$modelB = $tmp[3];
|
||||
|
||||
if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations)) {
|
||||
$this->{$modelA}->bindModel(array($association => array($modelB => array('className' => $modelB))), false);
|
||||
$this->out(__d('cake_console', "Created %s association between %s and %s",
|
||||
$association, $modelA, $modelB));
|
||||
} else {
|
||||
$this->out(__d('cake_console', "Please verify you are using valid models and association types"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbind an association
|
||||
*
|
||||
* @param mixed $command
|
||||
* @return void
|
||||
*/
|
||||
protected function _unbind($command) {
|
||||
preg_match($this->_methodPatterns[__FUNCTION__], $command, $tmp);
|
||||
|
||||
foreach ($tmp as $data) {
|
||||
$data = strip_tags($data);
|
||||
$data = str_replace($this->badCommandChars, "", $data);
|
||||
}
|
||||
|
||||
$modelA = $tmp[1];
|
||||
$association = $tmp[2];
|
||||
$modelB = $tmp[3];
|
||||
|
||||
// Verify that there is actually an association to unbind
|
||||
$currentAssociations = $this->{$modelA}->getAssociated();
|
||||
$validCurrentAssociation = false;
|
||||
|
||||
foreach ($currentAssociations as $model => $currentAssociation) {
|
||||
if ($model == $modelB && $association == $currentAssociation) {
|
||||
$validCurrentAssociation = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_isValidModel($modelA) && $this->_isValidModel($modelB) && in_array($association, $this->associations) && $validCurrentAssociation) {
|
||||
$this->{$modelA}->unbindModel(array($association => array($modelB)));
|
||||
$this->out(__d('cake_console', "Removed %s association between %s and %s",
|
||||
$association, $modelA, $modelB));
|
||||
} else {
|
||||
$this->out(__d('cake_console', "Please verify you are using valid models, valid current association, and valid association types"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a find
|
||||
*
|
||||
* @param mixed $command
|
||||
* @return void
|
||||
*/
|
||||
protected function _find($command) {
|
||||
$command = strip_tags($command);
|
||||
$command = str_replace($this->badCommandChars, "", $command);
|
||||
|
||||
// Do we have a valid model?
|
||||
list($modelToCheck, $tmp) = explode('->', $command);
|
||||
|
||||
if ($this->_isValidModel($modelToCheck)) {
|
||||
$findCommand = "\$data = \$this->$command;";
|
||||
//@codingStandardsIgnoreStart
|
||||
@eval($findCommand);
|
||||
//@codingStandardsIgnoreEnd
|
||||
|
||||
if (is_array($data)) {
|
||||
foreach ($data as $idx => $results) {
|
||||
if (is_numeric($idx)) { // findAll() output
|
||||
foreach ($results as $modelName => $result) {
|
||||
$this->out("$modelName");
|
||||
|
||||
foreach ($result as $field => $value) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $field2 => $value2) {
|
||||
$this->out("\t$field2: $value2");
|
||||
}
|
||||
|
||||
$this->out();
|
||||
} else {
|
||||
$this->out("\t$field: $value");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // find() output
|
||||
$this->out($idx);
|
||||
|
||||
foreach ($results as $field => $value) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $field2 => $value2) {
|
||||
$this->out("\t$field2: $value2");
|
||||
}
|
||||
|
||||
$this->out();
|
||||
} else {
|
||||
$this->out("\t$field: $value");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->out();
|
||||
$this->out(__d('cake_console', "No result set found"));
|
||||
}
|
||||
} else {
|
||||
$this->out(__d('cake_console', "%s is not a valid model", $modelToCheck));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save a record
|
||||
*
|
||||
* @param mixed $command
|
||||
* @return void
|
||||
*/
|
||||
protected function _save($command) {
|
||||
// Validate the model we're trying to save here
|
||||
$command = strip_tags($command);
|
||||
$command = str_replace($this->badCommandChars, "", $command);
|
||||
list($modelToSave, $tmp) = explode("->", $command);
|
||||
|
||||
if ($this->_isValidModel($modelToSave)) {
|
||||
// Extract the array of data we are trying to build
|
||||
list(, $data) = explode("->save", $command);
|
||||
$data = preg_replace('/^\(*(array)?\(*(.+?)\)*$/i', '\\2', $data);
|
||||
$saveCommand = "\$this->{$modelToSave}->save(array('{$modelToSave}' => array({$data})));";
|
||||
//@codingStandardsIgnoreStart
|
||||
@eval($saveCommand);
|
||||
//@codingStandardsIgnoreEnd
|
||||
$this->out(__d('cake_console', 'Saved record for %s', $modelToSave));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the columns for a model
|
||||
*
|
||||
* @param mixed $command
|
||||
* @return void
|
||||
*/
|
||||
protected function _columns($command) {
|
||||
preg_match($this->_methodPatterns[__FUNCTION__], $command, $tmp);
|
||||
|
||||
$modelToCheck = strip_tags(str_replace($this->badCommandChars, "", $tmp[1]));
|
||||
|
||||
if ($this->_isValidModel($modelToCheck)) {
|
||||
// Get the column info for this model
|
||||
$fieldsCommand = "\$data = \$this->{$modelToCheck}->getColumnTypes();";
|
||||
//@codingStandardsIgnoreStart
|
||||
@eval($fieldsCommand);
|
||||
//@codingStandardsIgnoreEnd
|
||||
|
||||
if (is_array($data)) {
|
||||
foreach ($data as $field => $type) {
|
||||
$this->out("\t{$field}: {$type}");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->out(__d('cake_console', "Please verify that you selected a valid model"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload route definitions
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _routesReload() {
|
||||
if (!$this->_loadRoutes()) {
|
||||
return $this->err(__d('cake_console', "There was an error loading the routes config. Please check that the file exists and is free of parse errors."));
|
||||
}
|
||||
$this->out(__d('cake_console', "Routes configuration reloaded, %d routes connected", count(Router::$routes)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show all routes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _routesShow() {
|
||||
$this->out(print_r(Hash::combine(Router::$routes, '{n}.template', '{n}.defaults'), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an array url and show the equivalent url as a string
|
||||
*
|
||||
* @param mixed $command
|
||||
* @return void
|
||||
*/
|
||||
protected function _routeToString($command) {
|
||||
preg_match($this->_methodPatterns[__FUNCTION__], $command, $tmp);
|
||||
|
||||
//@codingStandardsIgnoreStart
|
||||
if ($url = eval('return array' . $tmp[1] . ';')) {
|
||||
//@codingStandardsIgnoreEnd
|
||||
$this->out(Router::url($url));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string url and show as an array
|
||||
*
|
||||
* @param mixed $command
|
||||
* @return void
|
||||
*/
|
||||
protected function _routeToArray($command) {
|
||||
preg_match($this->_methodPatterns[__FUNCTION__], $command, $tmp);
|
||||
|
||||
$this->out(var_export(Router::parse($tmp[1]), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the specified model is included in the list of available models
|
||||
*
|
||||
|
|
|
@ -153,6 +153,13 @@ class SchemaShell extends AppShell {
|
|||
|
||||
Configure::write('Cache.disable', $cacheDisable);
|
||||
|
||||
if (!empty($this->params['exclude']) && !empty($content)) {
|
||||
$excluded = String::tokenize($this->params['exclude']);
|
||||
foreach ($excluded as $table) {
|
||||
unset($content['tables'][$table]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($snapshot === true) {
|
||||
$fileName = rtrim($this->params['file'], '.php');
|
||||
$Folder = new Folder($this->Schema->path);
|
||||
|
@ -228,10 +235,9 @@ class SchemaShell extends AppShell {
|
|||
if ($File->write($contents)) {
|
||||
$this->out(__d('cake_console', 'SQL dump file created in %s', $File->pwd()));
|
||||
return $this->_stop();
|
||||
} else {
|
||||
$this->err(__d('cake_console', 'SQL dump could not be created'));
|
||||
return $this->_stop();
|
||||
}
|
||||
$this->err(__d('cake_console', 'SQL dump could not be created'));
|
||||
return $this->_stop();
|
||||
}
|
||||
$this->out($contents);
|
||||
return $contents;
|
||||
|
@ -365,10 +371,18 @@ class SchemaShell extends AppShell {
|
|||
|
||||
if (empty($table)) {
|
||||
foreach ($compare as $table => $changes) {
|
||||
$contents[$table] = $db->alterSchema(array($table => $changes), $table);
|
||||
if (isset($compare[$table]['create'])) {
|
||||
$contents[$table] = $db->createSchema($Schema, $table);
|
||||
} else {
|
||||
$contents[$table] = $db->alterSchema(array($table => $compare[$table]), $table);
|
||||
}
|
||||
}
|
||||
} elseif (isset($compare[$table])) {
|
||||
$contents[$table] = $db->alterSchema(array($table => $compare[$table]), $table);
|
||||
if (isset($compare[$table]['create'])) {
|
||||
$contents[$table] = $db->createSchema($Schema, $table);
|
||||
} else {
|
||||
$contents[$table] = $db->alterSchema(array($table => $compare[$table]), $table);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($contents)) {
|
||||
|
@ -479,6 +493,9 @@ class SchemaShell extends AppShell {
|
|||
$write = array(
|
||||
'help' => __d('cake_console', 'Write the dumped SQL to a file.')
|
||||
);
|
||||
$exclude = array(
|
||||
'help' => __d('cake_console', 'Tables to exclude as comma separated list.')
|
||||
);
|
||||
|
||||
$parser = parent::getOptionParser();
|
||||
$parser->description(
|
||||
|
@ -492,7 +509,7 @@ class SchemaShell extends AppShell {
|
|||
))->addSubcommand('generate', array(
|
||||
'help' => __d('cake_console', 'Reads from --connection and writes to --path. Generate snapshots with -s'),
|
||||
'parser' => array(
|
||||
'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'snapshot', 'force', 'models'),
|
||||
'options' => compact('plugin', 'path', 'file', 'name', 'connection', 'snapshot', 'force', 'models', 'exclude'),
|
||||
'arguments' => array(
|
||||
'snapshot' => array('help' => __d('cake_console', 'Generate a snapshot.'))
|
||||
)
|
||||
|
|
|
@ -122,7 +122,7 @@ class ServerShell extends AppShell {
|
|||
*/
|
||||
public function main() {
|
||||
if (version_compare(PHP_VERSION, '5.4.0') < 0) {
|
||||
$this->out(__d('cake_console', '<warning>This command is available on PHP5.4 or above</warning>'));
|
||||
$this->out(__d('cake_console', '<warning>This command is available on %s or above</warning>', 'PHP5.4'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -480,6 +480,12 @@ class ControllerTask extends BakeTask {
|
|||
))->addOption('connection', array(
|
||||
'short' => 'c',
|
||||
'help' => __d('cake_console', 'The connection the controller\'s model is on.')
|
||||
))->addOption('theme', array(
|
||||
'short' => 't',
|
||||
'help' => __d('cake_console', 'Theme to use when baking code.')
|
||||
))->addOption('force', array(
|
||||
'short' => 'f',
|
||||
'help' => __d('cake_console', 'Force overwriting existing files without prompting.')
|
||||
))->addSubcommand('all', array(
|
||||
'help' => __d('cake_console', 'Bake all controllers with CRUD methods.')
|
||||
))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));
|
||||
|
|
|
@ -83,8 +83,18 @@ class FixtureTask extends BakeTask {
|
|||
))->addOption('plugin', array(
|
||||
'help' => __d('cake_console', 'CamelCased name of the plugin to bake fixtures for.'),
|
||||
'short' => 'p',
|
||||
))->addOption('schema', array(
|
||||
'help' => __d('cake_console', 'Importing schema for fixtures rather than hardcoding it.'),
|
||||
'short' => 's',
|
||||
'boolean' => true
|
||||
))->addOption('theme', array(
|
||||
'short' => 't',
|
||||
'help' => __d('cake_console', 'Theme to use when baking code.')
|
||||
))->addOption('force', array(
|
||||
'short' => 'f',
|
||||
'help' => __d('cake_console', 'Force overwriting existing files without prompting.')
|
||||
))->addOption('records', array(
|
||||
'help' => __d('cake_console', 'Used with --count and <name>/all commands to pull [n] records from the live tables, where [n] is either --count or the default of 10'),
|
||||
'help' => __d('cake_console', 'Used with --count and <name>/all commands to pull [n] records from the live tables, where [n] is either --count or the default of 10.'),
|
||||
'short' => 'r',
|
||||
'boolean' => true
|
||||
))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));
|
||||
|
@ -124,9 +134,14 @@ class FixtureTask extends BakeTask {
|
|||
$this->interactive = false;
|
||||
$this->Model->interactive = false;
|
||||
$tables = $this->Model->listAll($this->connection, false);
|
||||
|
||||
foreach ($tables as $table) {
|
||||
$model = $this->_modelName($table);
|
||||
$this->bake($model);
|
||||
$importOptions = array();
|
||||
if (!empty($this->params['schema'])) {
|
||||
$importOptions['schema'] = $model;
|
||||
}
|
||||
$this->bake($model, false, $importOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,11 +173,20 @@ class FixtureTask extends BakeTask {
|
|||
*/
|
||||
public function importOptions($modelName) {
|
||||
$options = array();
|
||||
$doSchema = $this->in(__d('cake_console', 'Would you like to import schema for this fixture?'), array('y', 'n'), 'n');
|
||||
if ($doSchema === 'y') {
|
||||
|
||||
if (!empty($this->params['schema'])) {
|
||||
$options['schema'] = $modelName;
|
||||
} else {
|
||||
$doSchema = $this->in(__d('cake_console', 'Would you like to import schema for this fixture?'), array('y', 'n'), 'n');
|
||||
if ($doSchema === 'y') {
|
||||
$options['schema'] = $modelName;
|
||||
}
|
||||
}
|
||||
if (!empty($this->params['records'])) {
|
||||
$doRecords = 'y';
|
||||
} else {
|
||||
$doRecords = $this->in(__d('cake_console', 'Would you like to use record importing for this fixture?'), array('y', 'n'), 'n');
|
||||
}
|
||||
$doRecords = $this->in(__d('cake_console', 'Would you like to use record importing for this fixture?'), array('y', 'n'), 'n');
|
||||
if ($doRecords === 'y') {
|
||||
$options['records'] = true;
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ class ModelTask extends BakeTask {
|
|||
* @param array $options Array of options to use for the selections. indexes must start at 0
|
||||
* @param string $prompt Prompt to use for options list.
|
||||
* @param integer $default The default option for the given prompt.
|
||||
* @return integer result of user choice.
|
||||
* @return integer Result of user choice.
|
||||
*/
|
||||
public function inOptions($options, $prompt = null, $default = null) {
|
||||
$valid = false;
|
||||
|
@ -347,7 +347,7 @@ class ModelTask extends BakeTask {
|
|||
* @return array $validate Array of user selected validations.
|
||||
*/
|
||||
public function doValidation($model) {
|
||||
if (!is_object($model)) {
|
||||
if (!$model instanceof Model) {
|
||||
return false;
|
||||
}
|
||||
$fields = $model->schema();
|
||||
|
@ -490,10 +490,10 @@ class ModelTask extends BakeTask {
|
|||
* Handles associations
|
||||
*
|
||||
* @param Model $model
|
||||
* @return array $associations
|
||||
* @return array Associations
|
||||
*/
|
||||
public function doAssociations($model) {
|
||||
if (!is_object($model)) {
|
||||
if (!$model instanceof Model) {
|
||||
return false;
|
||||
}
|
||||
if ($this->interactive === true) {
|
||||
|
@ -538,12 +538,36 @@ class ModelTask extends BakeTask {
|
|||
return $associations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles behaviors
|
||||
*
|
||||
* @param Model $model
|
||||
* @return array Behaviors
|
||||
*/
|
||||
public function doActsAs($model) {
|
||||
if (!$model instanceof Model) {
|
||||
return false;
|
||||
}
|
||||
$behaviors = array();
|
||||
$fields = $model->schema(true);
|
||||
if (empty($fields)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if (isset($fields['lft']) && $fields['lft']['type'] === 'integer' &&
|
||||
isset($fields['rght']) && $fields['rght']['type'] === 'integer' &&
|
||||
isset($fields['parent_id'])) {
|
||||
$behaviors[] = 'Tree';
|
||||
}
|
||||
return $behaviors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find belongsTo relations and add them to the associations list.
|
||||
*
|
||||
* @param Model $model Model instance of model being generated.
|
||||
* @param array $associations Array of in progress associations
|
||||
* @return array $associations with belongsTo added in.
|
||||
* @return array Associations with belongsTo added in.
|
||||
*/
|
||||
public function findBelongsTo(Model $model, $associations) {
|
||||
$fieldNames = array_keys($model->schema(true));
|
||||
|
@ -572,7 +596,7 @@ class ModelTask extends BakeTask {
|
|||
*
|
||||
* @param Model $model Model instance being generated
|
||||
* @param array $associations Array of in progress associations
|
||||
* @return array $associations with hasOne and hasMany added in.
|
||||
* @return array Associations with hasOne and hasMany added in.
|
||||
*/
|
||||
public function findHasOneAndMany(Model $model, $associations) {
|
||||
$foreignKey = $this->_modelKey($model->name);
|
||||
|
@ -615,7 +639,7 @@ class ModelTask extends BakeTask {
|
|||
*
|
||||
* @param Model $model Model instance being generated
|
||||
* @param array $associations Array of in-progress associations
|
||||
* @return array $associations with hasAndBelongsToMany added in.
|
||||
* @return array Associations with hasAndBelongsToMany added in.
|
||||
*/
|
||||
public function findHasAndBelongsToMany(Model $model, $associations) {
|
||||
$foreignKey = $this->_modelKey($model->name);
|
||||
|
@ -747,7 +771,7 @@ class ModelTask extends BakeTask {
|
|||
/**
|
||||
* Finds all possible keys to use on custom associations.
|
||||
*
|
||||
* @return array array of tables and possible keys
|
||||
* @return array Array of tables and possible keys
|
||||
*/
|
||||
protected function _generatePossibleKeys() {
|
||||
$possible = array();
|
||||
|
@ -771,11 +795,12 @@ class ModelTask extends BakeTask {
|
|||
* @return string
|
||||
*/
|
||||
public function bake($name, $data = array()) {
|
||||
if (is_object($name)) {
|
||||
if ($name instanceof Model) {
|
||||
if (!$data) {
|
||||
$data = array();
|
||||
$data['associations'] = $this->doAssociations($name);
|
||||
$data['validate'] = $this->doValidation($name);
|
||||
$data['actsAs'] = $this->doActsAs($name);
|
||||
}
|
||||
$data['primaryKey'] = $name->primaryKey;
|
||||
$data['useTable'] = $name->table;
|
||||
|
@ -784,8 +809,10 @@ class ModelTask extends BakeTask {
|
|||
} else {
|
||||
$data['name'] = $name;
|
||||
}
|
||||
|
||||
$defaults = array(
|
||||
'associations' => array(),
|
||||
'actsAs' => array(),
|
||||
'validate' => array(),
|
||||
'primaryKey' => 'id',
|
||||
'useTable' => null,
|
||||
|
@ -920,7 +947,7 @@ class ModelTask extends BakeTask {
|
|||
* Forces the user to specify the model he wants to bake, and returns the selected model name.
|
||||
*
|
||||
* @param string $useDbConfig Database config name
|
||||
* @return string the model name
|
||||
* @return string The model name
|
||||
*/
|
||||
public function getName($useDbConfig = null) {
|
||||
$this->listAll($useDbConfig);
|
||||
|
@ -965,9 +992,15 @@ class ModelTask extends BakeTask {
|
|||
))->addOption('plugin', array(
|
||||
'short' => 'p',
|
||||
'help' => __d('cake_console', 'Plugin to bake the model into.')
|
||||
))->addOption('theme', array(
|
||||
'short' => 't',
|
||||
'help' => __d('cake_console', 'Theme to use when baking code.')
|
||||
))->addOption('connection', array(
|
||||
'short' => 'c',
|
||||
'help' => __d('cake_console', 'The connection the model table is on.')
|
||||
))->addOption('force', array(
|
||||
'short' => 'f',
|
||||
'help' => __d('cake_console', 'Force overwriting existing files without prompting.')
|
||||
))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));
|
||||
}
|
||||
|
||||
|
|
|
@ -117,8 +117,8 @@ class ProjectTask extends AppShell {
|
|||
}
|
||||
$success = $this->corePath($path, $hardCode) === true;
|
||||
if ($success) {
|
||||
$this->out(__d('cake_console', ' * CAKE_CORE_INCLUDE_PATH set to %s in webroot/index.php', CAKE_CORE_INCLUDE_PATH));
|
||||
$this->out(__d('cake_console', ' * CAKE_CORE_INCLUDE_PATH set to %s in webroot/test.php', CAKE_CORE_INCLUDE_PATH));
|
||||
$this->out(__d('cake_console', ' * CAKE_CORE_INCLUDE_PATH set to %s in %s', CAKE_CORE_INCLUDE_PATH, 'webroot/index.php'));
|
||||
$this->out(__d('cake_console', ' * CAKE_CORE_INCLUDE_PATH set to %s in %s', CAKE_CORE_INCLUDE_PATH, 'webroot/test.php'));
|
||||
} else {
|
||||
$this->err(__d('cake_console', 'Unable to set CAKE_CORE_INCLUDE_PATH, you should change it in %s', $path . 'webroot' . DS . 'index.php'));
|
||||
$success = false;
|
||||
|
@ -435,6 +435,9 @@ class ProjectTask extends AppShell {
|
|||
))->addOption('empty', array(
|
||||
'boolean' => true,
|
||||
'help' => __d('cake_console', 'Create empty files in each of the directories. Good if you are using git')
|
||||
))->addOption('theme', array(
|
||||
'short' => 't',
|
||||
'help' => __d('cake_console', 'Theme to use when baking code.')
|
||||
))->addOption('skel', array(
|
||||
'default' => current(App::core('Console')) . 'Templates' . DS . 'skel',
|
||||
'help' => __d('cake_console', 'The directory layout to use for the new application skeleton. Defaults to cake/Console/Templates/skel of CakePHP used to create the project.')
|
||||
|
|
|
@ -563,9 +563,15 @@ class TestTask extends BakeTask {
|
|||
)
|
||||
))->addArgument('name', array(
|
||||
'help' => __d('cake_console', 'An existing class to bake tests for.')
|
||||
))->addOption('theme', array(
|
||||
'short' => 't',
|
||||
'help' => __d('cake_console', 'Theme to use when baking code.')
|
||||
))->addOption('plugin', array(
|
||||
'short' => 'p',
|
||||
'help' => __d('cake_console', 'CamelCased name of the plugin to bake tests for.')
|
||||
))->addOption('force', array(
|
||||
'short' => 'f',
|
||||
'help' => __d('cake_console', 'Force overwriting existing files without prompting.')
|
||||
))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));
|
||||
}
|
||||
|
||||
|
|
|
@ -434,9 +434,15 @@ class ViewTask extends BakeTask {
|
|||
))->addOption('admin', array(
|
||||
'help' => __d('cake_console', 'Set to only bake views for a prefix in Routing.prefixes'),
|
||||
'boolean' => true
|
||||
))->addOption('theme', array(
|
||||
'short' => 't',
|
||||
'help' => __d('cake_console', 'Theme to use when baking code.')
|
||||
))->addOption('connection', array(
|
||||
'short' => 'c',
|
||||
'help' => __d('cake_console', 'The connection the connected model is on.')
|
||||
))->addOption('force', array(
|
||||
'short' => 'f',
|
||||
'help' => __d('cake_console', 'Force overwriting existing files without prompting.')
|
||||
))->addSubcommand('all', array(
|
||||
'help' => __d('cake_console', 'Bake all CRUD action views for all controllers. Requires models and controllers to exist.')
|
||||
))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));
|
||||
|
|
|
@ -42,8 +42,7 @@ class TestsuiteShell extends TestShell {
|
|||
$parser = parent::getOptionParser();
|
||||
$parser->description(array(
|
||||
__d('cake_console', 'The CakePHP Testsuite allows you to run test cases from the command line'),
|
||||
__d('cake_console', '<warning>This shell is for backwards-compatibility only</warning>'),
|
||||
__d('cake_console', 'use the test shell instead')
|
||||
__d('cake_console', "<warning>This shell is for backwards-compatibility only</warning>\nuse the test shell instead"),
|
||||
));
|
||||
|
||||
return $parser;
|
||||
|
|
|
@ -95,7 +95,7 @@ class ConsoleErrorHandler {
|
|||
/**
|
||||
* Wrapper for exit(), used for testing.
|
||||
*
|
||||
* @param int $code The exit code.
|
||||
* @param integer $code The exit code.
|
||||
* @return void
|
||||
*/
|
||||
protected function _stop($code = 0) {
|
||||
|
|
|
@ -50,4 +50,16 @@ class ConsoleInput {
|
|||
return fgets($this->_input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if data is available on the stream
|
||||
*
|
||||
* @param integer $timeout An optional time to wait for data
|
||||
* @return bool True for data available, false otherwise
|
||||
*/
|
||||
public function dataAvailable($timeout = 0) {
|
||||
$readFds = array($this->_input);
|
||||
$readyFds = stream_select($readFds, $writeFds, $errorFds, $timeout);
|
||||
return ($readyFds > 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -141,6 +141,7 @@ class ConsoleOutput {
|
|||
'success' => array('text' => 'green'),
|
||||
'comment' => array('text' => 'blue'),
|
||||
'question' => array('text' => 'magenta'),
|
||||
'notice' => array('text' => 'cyan')
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,6 +24,7 @@ App::uses('ConsoleInputSubcommand', 'Console');
|
|||
App::uses('ConsoleOptionParser', 'Console');
|
||||
App::uses('ClassRegistry', 'Utility');
|
||||
App::uses('File', 'Utility');
|
||||
App::uses('ClassRegistry', 'Utility');
|
||||
|
||||
/**
|
||||
* Base class for command-line utilities for automating programmer chores.
|
||||
|
@ -120,6 +121,13 @@ class Shell extends Object {
|
|||
*/
|
||||
public $uses = array();
|
||||
|
||||
/**
|
||||
* This shell's primary model class name, the first model in the $uses property
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $modelClass = null;
|
||||
|
||||
/**
|
||||
* Task Collection for the command, used to create Tasks.
|
||||
*
|
||||
|
@ -178,7 +186,7 @@ class Shell extends Object {
|
|||
if ($this->tasks !== null && $this->tasks !== false) {
|
||||
$this->_mergeVars(array('tasks'), $parent, true);
|
||||
}
|
||||
if ($this->uses !== null && $this->uses !== false) {
|
||||
if (!empty($this->uses)) {
|
||||
$this->_mergeVars(array('uses'), $parent, false);
|
||||
}
|
||||
}
|
||||
|
@ -224,31 +232,66 @@ class Shell extends Object {
|
|||
}
|
||||
|
||||
/**
|
||||
* If $uses = true
|
||||
* Loads AppModel file and constructs AppModel class
|
||||
* makes $this->AppModel available to subclasses
|
||||
* If public $uses is an array of models will load those models
|
||||
* If $uses is an array load each of the models in the array
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function _loadModels() {
|
||||
if (empty($this->uses)) {
|
||||
return false;
|
||||
if (is_array($this->uses)) {
|
||||
list(, $this->modelClass) = pluginSplit(current($this->uses));
|
||||
foreach ($this->uses as $modelClass) {
|
||||
$this->loadModel($modelClass);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy loads models using the loadModel() method if declared in $uses
|
||||
*
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
public function __isset($name) {
|
||||
if (is_array($this->uses)) {
|
||||
foreach ($this->uses as $modelClass) {
|
||||
list(, $class) = pluginSplit($modelClass);
|
||||
if ($name === $class) {
|
||||
return $this->loadModel($modelClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and instantiates models required by this shell.
|
||||
*
|
||||
* @param string $modelClass Name of model class to load
|
||||
* @param mixed $id Initial ID the instanced model class should have
|
||||
* @return mixed true when single model found and instance created, error returned if model not found.
|
||||
* @throws MissingModelException if the model class cannot be found.
|
||||
*/
|
||||
public function loadModel($modelClass = null, $id = null) {
|
||||
if ($modelClass === null) {
|
||||
$modelClass = $this->modelClass;
|
||||
}
|
||||
|
||||
$uses = is_array($this->uses) ? $this->uses : array($this->uses);
|
||||
|
||||
$modelClassName = $uses[0];
|
||||
if (strpos($uses[0], '.') !== false) {
|
||||
list($plugin, $modelClassName) = explode('.', $uses[0]);
|
||||
}
|
||||
$this->modelClass = $modelClassName;
|
||||
|
||||
foreach ($uses as $modelClass) {
|
||||
list($plugin, $modelClass) = pluginSplit($modelClass, true);
|
||||
$this->{$modelClass} = ClassRegistry::init($plugin . $modelClass);
|
||||
$this->uses = ($this->uses) ? (array)$this->uses : array();
|
||||
if (!in_array($modelClass, $this->uses)) {
|
||||
$this->uses[] = $modelClass;
|
||||
}
|
||||
|
||||
list($plugin, $modelClass) = pluginSplit($modelClass, true);
|
||||
if (!isset($this->modelClass)) {
|
||||
$this->modelClass = $modelClass;
|
||||
}
|
||||
|
||||
$this->{$modelClass} = ClassRegistry::init(array(
|
||||
'class' => $plugin . $modelClass, 'alias' => $modelClass, 'id' => $id
|
||||
));
|
||||
if (!$this->{$modelClass}) {
|
||||
throw new MissingModelException($modelClass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -650,7 +693,7 @@ class Shell extends Object {
|
|||
|
||||
$this->out();
|
||||
|
||||
if (is_file($path) && $this->interactive === true) {
|
||||
if (is_file($path) && empty($this->params['force']) && $this->interactive === true) {
|
||||
$this->out(__d('cake_console', '<warning>File `%s` exists</warning>', $path));
|
||||
$key = $this->in(__d('cake_console', 'Do you want to overwrite?'), array('y', 'n', 'q'), 'n');
|
||||
|
||||
|
@ -835,12 +878,12 @@ class Shell extends Object {
|
|||
return;
|
||||
}
|
||||
CakeLog::config('stdout', array(
|
||||
'engine' => 'ConsoleLog',
|
||||
'engine' => 'Console',
|
||||
'types' => array('notice', 'info'),
|
||||
'stream' => $this->stdout,
|
||||
));
|
||||
CakeLog::config('stderr', array(
|
||||
'engine' => 'ConsoleLog',
|
||||
'engine' => 'Console',
|
||||
'types' => array('emergency', 'alert', 'critical', 'error', 'warning', 'debug'),
|
||||
'stream' => $this->stderr,
|
||||
));
|
||||
|
|
|
@ -145,7 +145,9 @@ class ShellDispatcher {
|
|||
$this->setErrorHandlers();
|
||||
|
||||
if (!defined('FULL_BASE_URL')) {
|
||||
define('FULL_BASE_URL', 'http://localhost');
|
||||
$url = Configure::read('App.fullBaseUrl');
|
||||
define('FULL_BASE_URL', $url ? $url : 'http://localhost');
|
||||
Configure::write('App.fullBaseUrl', FULL_BASE_URL);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -50,8 +50,17 @@ class TaskCollection extends ObjectCollection {
|
|||
}
|
||||
|
||||
/**
|
||||
* Loads/constructs a task. Will return the instance in the collection
|
||||
* if it already exists.
|
||||
* Loads/constructs a task. Will return the instance in the registry if it already exists.
|
||||
*
|
||||
* You can alias your task as an existing task by setting the 'className' key, i.e.,
|
||||
* {{{
|
||||
* public $tasks = array(
|
||||
* 'DbConfig' => array(
|
||||
* 'className' => 'Bakeplus.DbConfigure'
|
||||
* );
|
||||
* );
|
||||
* }}}
|
||||
* All calls to the `DbConfig` task would use `DbConfigure` found in the `Bakeplus` plugin instead.
|
||||
*
|
||||
* @param string $task Task name to load
|
||||
* @param array $settings Settings for the task.
|
||||
|
@ -59,26 +68,33 @@ class TaskCollection extends ObjectCollection {
|
|||
* @throws MissingTaskException when the task could not be found
|
||||
*/
|
||||
public function load($task, $settings = array()) {
|
||||
if (is_array($settings) && isset($settings['className'])) {
|
||||
$alias = $task;
|
||||
$task = $settings['className'];
|
||||
}
|
||||
list($plugin, $name) = pluginSplit($task, true);
|
||||
|
||||
if (isset($this->_loaded[$name])) {
|
||||
return $this->_loaded[$name];
|
||||
if (!isset($alias)) {
|
||||
$alias = $name;
|
||||
}
|
||||
|
||||
if (isset($this->_loaded[$alias])) {
|
||||
return $this->_loaded[$alias];
|
||||
}
|
||||
$taskClass = $name . 'Task';
|
||||
App::uses($taskClass, $plugin . 'Console/Command/Task');
|
||||
|
||||
$exists = class_exists($taskClass);
|
||||
if (!$exists) {
|
||||
throw new MissingTaskException(array(
|
||||
'class' => $taskClass
|
||||
'class' => $taskClass,
|
||||
'plugin' => substr($plugin, 0, -1)
|
||||
));
|
||||
}
|
||||
|
||||
$this->_loaded[$name] = new $taskClass(
|
||||
$this->_loaded[$alias] = new $taskClass(
|
||||
$this->_Shell->stdout, $this->_Shell->stderr, $this->_Shell->stdin
|
||||
);
|
||||
return $this->_loaded[$name];
|
||||
return $this->_loaded[$alias];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -74,6 +74,16 @@ if ($displayField): ?>
|
|||
|
||||
<?php endif;
|
||||
|
||||
if (!empty($actsAs)): ?>
|
||||
/**
|
||||
* Behaviors
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $actsAs = array(<?php echo "\n\t"; foreach ($actsAs as $behavior): echo "\t"; var_export($behavior); echo ",\n\t"; endforeach; ?>);
|
||||
|
||||
<?php endif;
|
||||
|
||||
if (!empty($validate)):
|
||||
echo "/**\n * Validation rules\n *\n * @var array\n */\n";
|
||||
echo "\tpublic \$validate = array(\n";
|
||||
|
|
|
@ -6,18 +6,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Config.Schema
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -28,8 +19,6 @@
|
|||
*/
|
||||
class DbAclSchema extends CakeSchema {
|
||||
|
||||
public $name = 'DbAcl';
|
||||
|
||||
public function before($event = array()) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -6,18 +6,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Config.Schema
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,18 +6,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Config.Schema
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
@ -5,17 +5,9 @@
|
|||
; *
|
||||
; * PHP 5
|
||||
; *
|
||||
; * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
; * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
; *
|
||||
; * Licensed under The MIT License
|
||||
; * Redistributions of files must retain the above copyright notice.
|
||||
; *
|
||||
; * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
; * @link http://cakephp.org CakePHP(tm) Project
|
||||
; * @package app.Config
|
||||
; * @since CakePHP(tm) v 0.10.0.1076
|
||||
; * @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
; */
|
||||
|
||||
; acl.ini.php - Cake ACL Configuration
|
||||
|
|
|
@ -6,18 +6,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Config
|
||||
* @since CakePHP(tm) v 2.1
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,18 +10,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Config
|
||||
* @since CakePHP(tm) v 0.10.8.2117
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
// Setup a 'default' cache configuration for use in the application.
|
||||
|
@ -98,12 +89,12 @@ Configure::write('Dispatcher.filters', array(
|
|||
*/
|
||||
App::uses('CakeLog', 'Log');
|
||||
CakeLog::config('debug', array(
|
||||
'engine' => 'FileLog',
|
||||
'engine' => 'File',
|
||||
'types' => array('notice', 'info', 'debug'),
|
||||
'file' => 'debug',
|
||||
));
|
||||
CakeLog::config('error', array(
|
||||
'engine' => 'FileLog',
|
||||
'engine' => 'File',
|
||||
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
|
||||
'file' => 'error',
|
||||
));
|
||||
|
|
|
@ -6,18 +6,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Config
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -70,6 +61,9 @@
|
|||
* - `renderer` - string - The class responsible for rendering uncaught exceptions. If you choose a custom class you
|
||||
* should place the file for that class in app/Lib/Error. This class needs to implement a render method.
|
||||
* - `log` - boolean - Should Exceptions be logged?
|
||||
* - `skipLog` - array - list of exceptions to skip for logging. Exceptions that
|
||||
* extend one of the listed exceptions will also be skipped for logging.
|
||||
* Example: `'skipLog' => array('NotFoundException', 'UnauthorizedException')`
|
||||
*
|
||||
* @see ErrorHandler for more information on exception handling and configuration.
|
||||
*/
|
||||
|
@ -105,6 +99,33 @@
|
|||
*/
|
||||
//Configure::write('App.baseUrl', env('SCRIPT_NAME'));
|
||||
|
||||
/**
|
||||
* To configure CakePHP to use a particular domain URL
|
||||
* for any URL generation inside the application, set the following
|
||||
* configuration variable to the http(s) address to your domain. This
|
||||
* will override the automatic detection of full base URL and can be
|
||||
* useful when generating links from the CLI (e.g. sending emails)
|
||||
*/
|
||||
//Configure::write('App.fullBaseUrl', 'http://example.com');
|
||||
|
||||
/**
|
||||
* Web path to the public images directory under webroot.
|
||||
* If not set defaults to 'img/'
|
||||
*/
|
||||
//Configure::write('App.imageBaseUrl', 'img/');
|
||||
|
||||
/**
|
||||
* Web path to the CSS files directory under webroot.
|
||||
* If not set defaults to 'css/'
|
||||
*/
|
||||
//Configure::write('App.cssBaseUrl', 'css/');
|
||||
|
||||
/**
|
||||
* Web path to the js files directory under webroot.
|
||||
* If not set defaults to 'js/'
|
||||
*/
|
||||
//Configure::write('App.jsBaseUrl', 'js/');
|
||||
|
||||
/**
|
||||
* Uncomment the define below to use CakePHP prefix routes.
|
||||
*
|
||||
|
|
|
@ -6,18 +6,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Config
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -25,7 +16,7 @@
|
|||
* You can specify multiple configurations for production, development and testing.
|
||||
*
|
||||
* datasource => The name of a supported datasource; valid options are as follows:
|
||||
* Database/Mysql - MySQL 4 & 5,
|
||||
* Database/Mysql - MySQL 4 & 5,
|
||||
* Database/Sqlite - SQLite (PHP5 only),
|
||||
* Database/Postgres - PostgreSQL 7 and higher,
|
||||
* Database/Sqlserver - Microsoft SQL Server 2005 and higher
|
||||
|
|
|
@ -6,18 +6,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Config
|
||||
* @since CakePHP(tm) v 2.0.0
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -25,7 +16,7 @@
|
|||
* You can specify multiple configurations for production, development and testing.
|
||||
*
|
||||
* transport => The name of a supported transport; valid options are as follows:
|
||||
* Mail - Send using PHP mail function
|
||||
* Mail - Send using PHP mail function
|
||||
* Smtp - Send using SMTP
|
||||
* Debug - Do not send the email, just return the result
|
||||
*
|
||||
|
|
|
@ -8,18 +8,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Config
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,17 +4,8 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @since CakePHP(tm) v 2.0
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Shell', 'Console');
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
:: @link http://cakephp.org CakePHP(tm) Project
|
||||
:: @package app.Console
|
||||
:: @since CakePHP(tm) v 2.0
|
||||
:: @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
::
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Console
|
||||
* @since CakePHP(tm) v 2.0
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
$ds = DIRECTORY_SEPARATOR;
|
||||
|
|
|
@ -7,18 +7,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Controller
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Controller', 'Controller');
|
||||
|
|
|
@ -6,18 +6,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Controller
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('AppController', 'Controller');
|
||||
|
@ -32,13 +23,6 @@ App::uses('AppController', 'Controller');
|
|||
*/
|
||||
class PagesController extends AppController {
|
||||
|
||||
/**
|
||||
* Controller name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name = 'Pages';
|
||||
|
||||
/**
|
||||
* This controller does not use a model
|
||||
*
|
||||
|
@ -51,6 +35,8 @@ class PagesController extends AppController {
|
|||
*
|
||||
* @param mixed What page to display
|
||||
* @return void
|
||||
* @throws NotFoundException When the view file could not be found
|
||||
* or MissingViewException in debug mode.
|
||||
*/
|
||||
public function display() {
|
||||
$path = func_get_args();
|
||||
|
@ -71,6 +57,14 @@ class PagesController extends AppController {
|
|||
$title_for_layout = Inflector::humanize($path[$count - 1]);
|
||||
}
|
||||
$this->set(compact('page', 'subpage', 'title_for_layout'));
|
||||
$this->render(implode('/', $path));
|
||||
|
||||
try {
|
||||
$this->render(implode('/', $path));
|
||||
} catch (MissingViewException $e) {
|
||||
if (Configure::read('debug')) {
|
||||
throw $e;
|
||||
}
|
||||
throw new NotFoundException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,18 +7,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Model
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Model', 'Model');
|
||||
|
|
|
@ -3,18 +3,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.View.Errors
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<h2><?php echo $name; ?></h2>
|
||||
|
|
|
@ -3,18 +3,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.View.Errors
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<h2><?php echo $name; ?></h2>
|
||||
|
|
|
@ -7,18 +7,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.View.Helper
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('Helper', 'View');
|
||||
|
|
|
@ -3,18 +3,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.View.Layouts.Email.html
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
|
||||
|
|
|
@ -3,18 +3,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.View.Layouts
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<?php echo $this->fetch('content'); ?>
|
||||
|
|
|
@ -3,18 +3,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.View.Layouts
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
$cakeDescription = __d('cake_dev', 'CakePHP: the rapid development php framework');
|
||||
|
|
|
@ -3,18 +3,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.View.Layouts
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
$cakeDescription = __d('cake_dev', 'CakePHP: the rapid development php framework');
|
||||
|
|
|
@ -3,18 +3,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.View.Layouts
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
|
|
|
@ -3,18 +3,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.View.Pages
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
if (!Configure::read('debug')):
|
||||
|
@ -68,11 +59,11 @@ endif;
|
|||
$settings = Cache::settings();
|
||||
if (!empty($settings)):
|
||||
echo '<span class="notice success">';
|
||||
echo __d('cake_dev', 'The %s is being used for core caching. To change the config edit APP/Config/core.php ', '<em>'. $settings['engine'] . 'Engine</em>');
|
||||
echo __d('cake_dev', 'The %s is being used for core caching. To change the config edit %s', '<em>'. $settings['engine'] . 'Engine</em>', 'APP/Config/core.php');
|
||||
echo '</span>';
|
||||
else:
|
||||
echo '<span class="notice">';
|
||||
echo __d('cake_dev', 'Your cache is NOT working. Please check the settings in APP/Config/core.php');
|
||||
echo __d('cake_dev', 'Your cache is NOT working. Please check the settings in %s', 'APP/Config/core.php');
|
||||
echo '</span>';
|
||||
endif;
|
||||
?>
|
||||
|
@ -89,7 +80,7 @@ endif;
|
|||
echo '<span class="notice">';
|
||||
echo __d('cake_dev', 'Your database configuration file is NOT present.');
|
||||
echo '<br/>';
|
||||
echo __d('cake_dev', 'Rename APP/Config/database.php.default to APP/Config/database.php');
|
||||
echo __d('cake_dev', 'Rename %s to %s', 'APP/Config/database.php.default', 'APP/Config/database.php');
|
||||
echo '</span>';
|
||||
endif;
|
||||
?>
|
||||
|
@ -132,7 +123,7 @@ if (isset($filePresent)):
|
|||
echo '<p><span class="notice">';
|
||||
echo __d('cake_dev', 'PCRE has not been compiled with Unicode support.');
|
||||
echo '<br/>';
|
||||
echo __d('cake_dev', 'Recompile PCRE with Unicode support by adding <code>--enable-unicode-properties</code> when configuring');
|
||||
echo __d('cake_dev', 'Recompile PCRE with Unicode support by adding %s when configuring', '<code>--enable-unicode-properties</code>');
|
||||
echo '</span></p>';
|
||||
}
|
||||
?>
|
||||
|
@ -156,9 +147,10 @@ if (isset($filePresent)):
|
|||
<h3><?php echo __d('cake_dev', 'Editing this Page'); ?></h3>
|
||||
<p>
|
||||
<?php
|
||||
echo __d('cake_dev', 'To change the content of this page, edit: APP/View/Pages/home.ctp.<br />
|
||||
To change its layout, edit: APP/View/Layouts/default.ctp.<br />
|
||||
You can also add some CSS styles for your pages at: APP/webroot/css.');
|
||||
echo __d('cake_dev', 'To change the content of this page, edit: %s.<br />
|
||||
To change its layout, edit: %s.<br />
|
||||
You can also add some CSS styles for your pages at: %s.',
|
||||
'APP/View/Pages/home.ctp', 'APP/View/Layouts/default.ctp', 'APP/webroot/css');
|
||||
?>
|
||||
</p>
|
||||
|
||||
|
|
|
@ -2,18 +2,9 @@
|
|||
/**
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^(.*)$ index.php [QSA,L]
|
||||
RewriteRule ^ index.php [L]
|
||||
</IfModule>
|
||||
|
|
|
@ -6,18 +6,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.webroot
|
||||
* @since CakePHP(tm) v 0.2.9
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,18 +4,9 @@
|
|||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://book.cakephp.org/2.0/en/development/testing.html
|
||||
* @package app.webroot
|
||||
* @since CakePHP(tm) v 1.2.0.4433
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
set_time_limit(0);
|
||||
|
|
|
@ -31,13 +31,6 @@ App::uses('AppController', 'Controller');
|
|||
*/
|
||||
class CakeErrorController extends AppController {
|
||||
|
||||
/**
|
||||
* Controller name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name = 'CakeError';
|
||||
|
||||
/**
|
||||
* Uses Property
|
||||
*
|
||||
|
|
|
@ -156,10 +156,10 @@ class AclComponent extends Component {
|
|||
* @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @deprecated
|
||||
* @deprecated Will be removed in 3.0.
|
||||
*/
|
||||
public function grant($aro, $aco, $action = "*") {
|
||||
trigger_error(__d('cake_dev', 'AclComponent::grant() is deprecated, use allow() instead'), E_USER_WARNING);
|
||||
trigger_error(__d('cake_dev', '%s is deprecated, use %s instead', 'AclComponent::grant()', 'allow()'), E_USER_WARNING);
|
||||
return $this->_Instance->allow($aro, $aco, $action);
|
||||
}
|
||||
|
||||
|
@ -170,10 +170,10 @@ class AclComponent extends Component {
|
|||
* @param array|string|Model $aco ACO The controlled object identifier. See `AclNode::node()` for possible formats
|
||||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success
|
||||
* @deprecated
|
||||
* @deprecated Will be removed in 3.0.
|
||||
*/
|
||||
public function revoke($aro, $aco, $action = "*") {
|
||||
trigger_error(__d('cake_dev', 'AclComponent::revoke() is deprecated, use deny() instead'), E_USER_WARNING);
|
||||
trigger_error(__d('cake_dev', '%s is deprecated, use %s instead', 'AclComponent::revoke()', 'deny()'), E_USER_WARNING);
|
||||
return $this->_Instance->deny($aro, $aco, $action);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
/**
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @since CakePHP(tm) v 2.4.0
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract password hashing class
|
||||
*
|
||||
* @package Cake.Controller.Component.Auth
|
||||
*/
|
||||
abstract class AbstractPasswordHasher {
|
||||
|
||||
/**
|
||||
* Configurations for this object. Settings passed from authenticator class to
|
||||
* the constructor are merged with this property.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $config Array of config.
|
||||
*/
|
||||
public function __construct($config = array()) {
|
||||
$this->config($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get/Set the config
|
||||
*
|
||||
* @param array $config Sets config, if null returns existing config
|
||||
* @return array Returns configs
|
||||
*/
|
||||
public function config($config = null) {
|
||||
if (is_array($config)) {
|
||||
$this->_config = array_merge($this->_config, $config);
|
||||
}
|
||||
return $this->_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates password hash.
|
||||
*
|
||||
* @param string|array $password Plain text password to hash or array of data
|
||||
* required to generate password hash.
|
||||
* @return string Password hash
|
||||
*/
|
||||
abstract public function hash($password);
|
||||
|
||||
/**
|
||||
* Check hash. Generate hash from user provided password string or data array
|
||||
* and check against existing hash.
|
||||
*
|
||||
* @param string|array $password Plain text password to hash or data array.
|
||||
* @param string Existing hashed password.
|
||||
* @return boolean True if hashes match else false.
|
||||
*/
|
||||
abstract public function check($password, $hashedPassword);
|
||||
|
||||
}
|
|
@ -33,6 +33,9 @@ abstract class BaseAuthenticate {
|
|||
* i.e. `array('User.is_active' => 1).`
|
||||
* - `recursive` The value of the recursive key passed to find(). Defaults to 0.
|
||||
* - `contain` Extra models to contain and store in session.
|
||||
* - `passwordHasher` Password hasher class. Can be a string specifying class name
|
||||
* or an array containing `className` key, any other keys will be passed as
|
||||
* settings to the class. Defaults to 'Simple'.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
|
@ -45,6 +48,7 @@ abstract class BaseAuthenticate {
|
|||
'scope' => array(),
|
||||
'recursive' => 0,
|
||||
'contain' => null,
|
||||
'passwordHasher' => 'Simple'
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -54,6 +58,13 @@ abstract class BaseAuthenticate {
|
|||
*/
|
||||
protected $_Collection;
|
||||
|
||||
/**
|
||||
* Password hasher instance.
|
||||
*
|
||||
* @var AbstractPasswordHasher
|
||||
*/
|
||||
protected $_passwordHasher;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
@ -68,56 +79,96 @@ abstract class BaseAuthenticate {
|
|||
/**
|
||||
* Find a user record using the standard options.
|
||||
*
|
||||
* The $conditions parameter can be a (string)username or an array containing conditions for Model::find('first'). If
|
||||
* the password field is not included in the conditions the password will be returned.
|
||||
* The $username parameter can be a (string)username or an array containing
|
||||
* conditions for Model::find('first'). If the $password param is not provided
|
||||
* the password field will be present in returned array.
|
||||
*
|
||||
* @param Mixed $conditions The username/identifier, or an array of find conditions.
|
||||
* @param Mixed $password The password, only use if passing as $conditions = 'username'.
|
||||
* @return Mixed Either false on failure, or an array of user data.
|
||||
* Input passwords will be hashed even when a user doesn't exist. This
|
||||
* helps mitigate timing attacks that are attempting to find valid usernames.
|
||||
*
|
||||
* @param string|array $username The username/identifier, or an array of find conditions.
|
||||
* @param string $password The password, only used if $username param is string.
|
||||
* @return boolean|array Either false on failure, or an array of user data.
|
||||
*/
|
||||
protected function _findUser($conditions, $password = null) {
|
||||
protected function _findUser($username, $password = null) {
|
||||
$userModel = $this->settings['userModel'];
|
||||
list(, $model) = pluginSplit($userModel);
|
||||
$fields = $this->settings['fields'];
|
||||
|
||||
if (!is_array($conditions)) {
|
||||
if (!$password) {
|
||||
return false;
|
||||
}
|
||||
$username = $conditions;
|
||||
if (is_array($username)) {
|
||||
$conditions = $username;
|
||||
} else {
|
||||
$conditions = array(
|
||||
$model . '.' . $fields['username'] => $username,
|
||||
$model . '.' . $fields['password'] => $this->_password($password),
|
||||
$model . '.' . $fields['username'] => $username
|
||||
);
|
||||
}
|
||||
|
||||
if (!empty($this->settings['scope'])) {
|
||||
$conditions = array_merge($conditions, $this->settings['scope']);
|
||||
}
|
||||
|
||||
$result = ClassRegistry::init($userModel)->find('first', array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => $this->settings['recursive'],
|
||||
'contain' => $this->settings['contain'],
|
||||
));
|
||||
if (empty($result) || empty($result[$model])) {
|
||||
if (empty($result[$model])) {
|
||||
$this->passwordHasher()->hash($password);
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = $result[$model];
|
||||
if (
|
||||
isset($conditions[$model . '.' . $fields['password']]) ||
|
||||
isset($conditions[$fields['password']])
|
||||
) {
|
||||
if ($password) {
|
||||
if (!$this->passwordHasher()->check($password, $user[$fields['password']])) {
|
||||
return false;
|
||||
}
|
||||
unset($user[$fields['password']]);
|
||||
}
|
||||
|
||||
unset($result[$model]);
|
||||
return array_merge($user, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return password hasher object
|
||||
*
|
||||
* @return AbstractPasswordHasher Password hasher instance
|
||||
* @throws CakeException If password hasher class not found or
|
||||
* it does not extend AbstractPasswordHasher
|
||||
*/
|
||||
public function passwordHasher() {
|
||||
if ($this->_passwordHasher) {
|
||||
return $this->_passwordHasher;
|
||||
}
|
||||
|
||||
$config = array();
|
||||
if (is_string($this->settings['passwordHasher'])) {
|
||||
$class = $this->settings['passwordHasher'];
|
||||
} else {
|
||||
$class = $this->settings['passwordHasher']['className'];
|
||||
$config = $this->settings['passwordHasher'];
|
||||
unset($config['className']);
|
||||
}
|
||||
list($plugin, $class) = pluginSplit($class, true);
|
||||
$className = $class . 'PasswordHasher';
|
||||
App::uses($className, $plugin . 'Controller/Component/Auth');
|
||||
if (!class_exists($className)) {
|
||||
throw new CakeException(__d('cake_dev', 'Password hasher class "%s" was not found.', $class));
|
||||
}
|
||||
if (!is_subclass_of($className, 'AbstractPasswordHasher')) {
|
||||
throw new CakeException(__d('cake_dev', 'Password hasher must extend AbstractPasswordHasher class.'));
|
||||
}
|
||||
$this->_passwordHasher = new $className($config);
|
||||
return $this->_passwordHasher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash the plain text password so that it matches the hashed/encrypted password
|
||||
* in the datasource.
|
||||
*
|
||||
* @param string $password The plain text password.
|
||||
* @return string The hashed form of the password.
|
||||
* @deprecated Since 2.4. Use a PasswordHasher class instead.
|
||||
*/
|
||||
protected function _password($password) {
|
||||
return Security::hash($password, null, true);
|
||||
|
@ -156,4 +207,15 @@ abstract class BaseAuthenticate {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle unauthenticated access attempt.
|
||||
*
|
||||
* @param CakeRequest $request A request object.
|
||||
* @param CakeResponse $response A response object.
|
||||
* @return mixed Either true to indicate the unauthenticated request has been
|
||||
* dealt with and no more action is required by AuthComponent or void (default).
|
||||
*/
|
||||
public function unauthenticated(CakeRequest $request, CakeResponse $response) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,31 +43,6 @@ App::uses('BaseAuthenticate', 'Controller/Component/Auth');
|
|||
*/
|
||||
class BasicAuthenticate extends BaseAuthenticate {
|
||||
|
||||
/**
|
||||
* Settings for this object.
|
||||
*
|
||||
* - `fields` The fields to use to identify a user by.
|
||||
* - `userModel` The model name of the User, defaults to User.
|
||||
* - `scope` Additional conditions to use when looking up and authenticating users,
|
||||
* i.e. `array('User.is_active' => 1).`
|
||||
* - `recursive` The value of the recursive key passed to find(). Defaults to 0.
|
||||
* - `contain` Extra models to contain and store in session.
|
||||
* - `realm` The realm authentication is for. Defaults the server name.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $settings = array(
|
||||
'fields' => array(
|
||||
'username' => 'username',
|
||||
'password' => 'password'
|
||||
),
|
||||
'userModel' => 'User',
|
||||
'scope' => array(),
|
||||
'recursive' => 0,
|
||||
'contain' => null,
|
||||
'realm' => '',
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor, completes configuration for basic authentication.
|
||||
*
|
||||
|
@ -82,23 +57,15 @@ class BasicAuthenticate extends BaseAuthenticate {
|
|||
}
|
||||
|
||||
/**
|
||||
* Authenticate a user using basic HTTP auth. Will use the configured User model and attempt a
|
||||
* login using basic HTTP auth.
|
||||
* Authenticate a user using HTTP auth. Will use the configured User model and attempt a
|
||||
* login using HTTP auth.
|
||||
*
|
||||
* @param CakeRequest $request The request to authenticate with.
|
||||
* @param CakeResponse $response The response to add headers to.
|
||||
* @return mixed Either false on failure, or an array of user data on success.
|
||||
*/
|
||||
public function authenticate(CakeRequest $request, CakeResponse $response) {
|
||||
$result = $this->getUser($request);
|
||||
|
||||
if (empty($result)) {
|
||||
$response->header($this->loginHeaders());
|
||||
$response->statusCode(401);
|
||||
$response->send();
|
||||
return false;
|
||||
}
|
||||
return $result;
|
||||
return $this->getUser($request);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,6 +84,20 @@ class BasicAuthenticate extends BaseAuthenticate {
|
|||
return $this->_findUser($username, $pass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an unauthenticated access attempt by sending appropriate login headers
|
||||
*
|
||||
* @param CakeRequest $request A request object.
|
||||
* @param CakeResponse $response A response object.
|
||||
* @return void
|
||||
* @throws UnauthorizedException
|
||||
*/
|
||||
public function unauthenticated(CakeRequest $request, CakeResponse $response) {
|
||||
$Exception = new UnauthorizedException();
|
||||
$Exception->responseHeader(array($this->loginHeaders()));
|
||||
throw $Exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the login headers
|
||||
*
|
||||
|
|
|
@ -34,46 +34,22 @@ App::uses('FormAuthenticate', 'Controller/Component/Auth');
|
|||
* For initial password hashing/creation see Security::hash(). Other than how the password is initially hashed,
|
||||
* BlowfishAuthenticate works exactly the same way as FormAuthenticate.
|
||||
*
|
||||
* @package Cake.Controller.Component.Auth
|
||||
* @package Cake.Controller.Component.Auth
|
||||
* @since CakePHP(tm) v 2.3
|
||||
* @see AuthComponent::$authenticate
|
||||
* @see AuthComponent::$authenticate
|
||||
* @deprecated Since 2.4. Just use FormAuthenticate with 'passwordHasher' setting set to 'Blowfish'
|
||||
*/
|
||||
class BlowfishAuthenticate extends FormAuthenticate {
|
||||
|
||||
/**
|
||||
* Authenticates the identity contained in a request. Will use the `settings.userModel`, and `settings.fields`
|
||||
* to find POST data that is used to find a matching record in the`settings.userModel`. Will return false if
|
||||
* there is no post data, either username or password is missing, or if the scope conditions have not been met.
|
||||
* Constructor. Sets default passwordHasher to Blowfish
|
||||
*
|
||||
* @param CakeRequest $request The request that contains login information.
|
||||
* @param CakeResponse $response Unused response object.
|
||||
* @return mixed False on login failure. An array of User data on success.
|
||||
* @param ComponentCollection $collection The Component collection used on this request.
|
||||
* @param array $settings Array of settings to use.
|
||||
*/
|
||||
public function authenticate(CakeRequest $request, CakeResponse $response) {
|
||||
$userModel = $this->settings['userModel'];
|
||||
list(, $model) = pluginSplit($userModel);
|
||||
|
||||
$fields = $this->settings['fields'];
|
||||
if (!$this->_checkFields($request, $model, $fields)) {
|
||||
return false;
|
||||
}
|
||||
$user = $this->_findUser(
|
||||
array(
|
||||
$model . '.' . $fields['username'] => $request->data[$model][$fields['username']],
|
||||
)
|
||||
);
|
||||
if (!$user) {
|
||||
return false;
|
||||
}
|
||||
$password = Security::hash(
|
||||
$request->data[$model][$fields['password']],
|
||||
'blowfish',
|
||||
$user[$fields['password']]
|
||||
);
|
||||
if ($password === $user[$fields['password']]) {
|
||||
unset($user[$fields['password']]);
|
||||
return $user;
|
||||
}
|
||||
return false;
|
||||
public function __construct(ComponentCollection $collection, $settings) {
|
||||
$this->settings['passwordHasher'] = 'Blowfish';
|
||||
parent::__construct($collection, $settings);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
/**
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @since CakePHP(tm) v 2.4.0
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
App::uses('AbstractPasswordHasher', 'Controller/Component/Auth');
|
||||
App::uses('Security', 'Utility');
|
||||
|
||||
/**
|
||||
* Blowfish password hashing class.
|
||||
*
|
||||
* @package Cake.Controller.Component.Auth
|
||||
*/
|
||||
class BlowfishPasswordHasher extends AbstractPasswordHasher {
|
||||
|
||||
/**
|
||||
* Generates password hash.
|
||||
*
|
||||
* @param string $password Plain text password to hash.
|
||||
* @return string Password hash
|
||||
*/
|
||||
public function hash($password) {
|
||||
return Security::hash($password, 'blowfish', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check hash. Generate hash for user provided password and check against existing hash.
|
||||
*
|
||||
* @param string $password Plain text password to hash.
|
||||
* @param string Existing hashed password.
|
||||
* @return boolean True if hashes match else false.
|
||||
*/
|
||||
public function check($password, $hashedPassword) {
|
||||
return $hashedPassword === Security::hash($password, 'blowfish', $hashedPassword);
|
||||
}
|
||||
|
||||
}
|
|
@ -48,7 +48,7 @@ class ControllerAuthorize extends BaseAuthorize {
|
|||
public function controller(Controller $controller = null) {
|
||||
if ($controller) {
|
||||
if (!method_exists($controller, 'isAuthorized')) {
|
||||
throw new CakeException(__d('cake_dev', '$controller does not implement an isAuthorized() method.'));
|
||||
throw new CakeException(__d('cake_dev', '$controller does not implement an %s method.', 'isAuthorized()'));
|
||||
}
|
||||
}
|
||||
return parent::controller($controller);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
|
||||
App::uses('BasicAuthenticate', 'Controller/Component/Auth');
|
||||
|
||||
/**
|
||||
* Digest Authentication adapter for AuthComponent.
|
||||
|
@ -55,7 +55,7 @@ App::uses('BaseAuthenticate', 'Controller/Component/Auth');
|
|||
* @package Cake.Controller.Component.Auth
|
||||
* @since 2.0
|
||||
*/
|
||||
class DigestAuthenticate extends BaseAuthenticate {
|
||||
class DigestAuthenticate extends BasicAuthenticate {
|
||||
|
||||
/**
|
||||
* Settings for this object.
|
||||
|
@ -86,7 +86,8 @@ class DigestAuthenticate extends BaseAuthenticate {
|
|||
'realm' => '',
|
||||
'qop' => 'auth',
|
||||
'nonce' => '',
|
||||
'opaque' => ''
|
||||
'opaque' => '',
|
||||
'passwordHasher' => 'Simple',
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -97,9 +98,6 @@ class DigestAuthenticate extends BaseAuthenticate {
|
|||
*/
|
||||
public function __construct(ComponentCollection $collection, $settings) {
|
||||
parent::__construct($collection, $settings);
|
||||
if (empty($this->settings['realm'])) {
|
||||
$this->settings['realm'] = env('SERVER_NAME');
|
||||
}
|
||||
if (empty($this->settings['nonce'])) {
|
||||
$this->settings['nonce'] = uniqid('');
|
||||
}
|
||||
|
@ -108,26 +106,6 @@ class DigestAuthenticate extends BaseAuthenticate {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate a user using Digest HTTP auth. Will use the configured User model and attempt a
|
||||
* login using Digest HTTP auth.
|
||||
*
|
||||
* @param CakeRequest $request The request to authenticate with.
|
||||
* @param CakeResponse $response The response to add headers to.
|
||||
* @return mixed Either false on failure, or an array of user data on success.
|
||||
*/
|
||||
public function authenticate(CakeRequest $request, CakeResponse $response) {
|
||||
$user = $this->getUser($request);
|
||||
|
||||
if (empty($user)) {
|
||||
$response->header($this->loginHeaders());
|
||||
$response->statusCode(401);
|
||||
$response->send();
|
||||
return false;
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user based on information in the request. Used by cookie-less auth for stateless clients.
|
||||
*
|
||||
|
@ -139,7 +117,11 @@ class DigestAuthenticate extends BaseAuthenticate {
|
|||
if (empty($digest)) {
|
||||
return false;
|
||||
}
|
||||
$user = $this->_findUser($digest['username']);
|
||||
|
||||
list(, $model) = pluginSplit($this->settings['userModel']);
|
||||
$user = $this->_findUser(array(
|
||||
$model . '.' . $this->settings['fields']['username'] => $digest['username']
|
||||
));
|
||||
if (empty($user)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -151,34 +133,6 @@ class DigestAuthenticate extends BaseAuthenticate {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a user record using the standard options.
|
||||
*
|
||||
* @param string $username The username/identifier.
|
||||
* @param string $password Unused password, digest doesn't require passwords.
|
||||
* @return Mixed Either false on failure, or an array of user data.
|
||||
*/
|
||||
protected function _findUser($username, $password = null) {
|
||||
$userModel = $this->settings['userModel'];
|
||||
list(, $model) = pluginSplit($userModel);
|
||||
$fields = $this->settings['fields'];
|
||||
|
||||
$conditions = array(
|
||||
$model . '.' . $fields['username'] => $username,
|
||||
);
|
||||
if (!empty($this->settings['scope'])) {
|
||||
$conditions = array_merge($conditions, $this->settings['scope']);
|
||||
}
|
||||
$result = ClassRegistry::init($userModel)->find('first', array(
|
||||
'conditions' => $conditions,
|
||||
'recursive' => $this->settings['recursive']
|
||||
));
|
||||
if (empty($result) || empty($result[$model])) {
|
||||
return false;
|
||||
}
|
||||
return $result[$model];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the digest headers from the request/environment.
|
||||
*
|
||||
|
|
55
lib/Cake/Controller/Component/Auth/SimplePasswordHasher.php
Normal file
55
lib/Cake/Controller/Component/Auth/SimplePasswordHasher.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/**
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @since CakePHP(tm) v 2.4.0
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
App::uses('AbstractPasswordHasher', 'Controller/Component/Auth');
|
||||
App::uses('Security', 'Utility');
|
||||
|
||||
/**
|
||||
* Simple password hashing class.
|
||||
*
|
||||
* @package Cake.Controller.Component.Auth
|
||||
*/
|
||||
class SimplePasswordHasher extends AbstractPasswordHasher {
|
||||
|
||||
/**
|
||||
* Config for this object.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config = array('hashType' => null);
|
||||
|
||||
/**
|
||||
* Generates password hash.
|
||||
*
|
||||
* @param string $password Plain text password to hash.
|
||||
* @return string Password hash
|
||||
*/
|
||||
public function hash($password) {
|
||||
return Security::hash($password, $this->_config['hashType'], true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check hash. Generate hash for user provided password and check against existing hash.
|
||||
*
|
||||
* @param string $password Plain text password to hash.
|
||||
* @param string Existing hashed password.
|
||||
* @return boolean True if hashes match else false.
|
||||
*/
|
||||
public function check($password, $hashedPassword) {
|
||||
return $hashedPassword === $this->hash($password);
|
||||
}
|
||||
|
||||
}
|
|
@ -157,8 +157,9 @@ class AuthComponent extends Component {
|
|||
);
|
||||
|
||||
/**
|
||||
* The session key name where the record of the current user is stored. If
|
||||
* unspecified, it will be "Auth.User".
|
||||
* The session key name where the record of the current user is stored. Default
|
||||
* key is "Auth.User". If you are using only stateless authenticators set this
|
||||
* to false to ensure session is not started.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
@ -188,7 +189,7 @@ class AuthComponent extends Component {
|
|||
* Normally, if a user is redirected to the $loginAction page, the location they
|
||||
* were redirected from will be stored in the session so that they can be
|
||||
* redirected back after a successful login. If this session value is not
|
||||
* set, the user will be redirected to the page specified in $loginRedirect.
|
||||
* set, redirectUrl() method will return the url specified in $loginRedirect.
|
||||
*
|
||||
* @var mixed
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#AuthComponent::$loginRedirect
|
||||
|
@ -210,7 +211,7 @@ class AuthComponent extends Component {
|
|||
* Error to display when user attempts to access an object or action to which they do not have
|
||||
* access.
|
||||
*
|
||||
* @var string
|
||||
* @var string|bool Error message or boolean false to suppress flash message
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#AuthComponent::$authError
|
||||
*/
|
||||
public $authError = null;
|
||||
|
@ -294,43 +295,13 @@ class AuthComponent extends Component {
|
|||
if (!$this->_setDefaults()) {
|
||||
return false;
|
||||
}
|
||||
$request = $controller->request;
|
||||
|
||||
$url = '';
|
||||
|
||||
if (isset($request->url)) {
|
||||
$url = $request->url;
|
||||
}
|
||||
$url = Router::normalize($url);
|
||||
$loginAction = Router::normalize($this->loginAction);
|
||||
|
||||
if ($loginAction != $url && in_array($action, array_map('strtolower', $this->allowedActions))) {
|
||||
return true;
|
||||
}
|
||||
if ($loginAction == $url) {
|
||||
if (empty($request->data)) {
|
||||
if (!$this->Session->check('Auth.redirect') && env('HTTP_REFERER')) {
|
||||
$referer = $request->referer(true);
|
||||
$this->Session->write('Auth.redirect', $referer);
|
||||
}
|
||||
}
|
||||
if ($this->_isAllowed($controller)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$this->_getUser()) {
|
||||
if (!$request->is('ajax')) {
|
||||
$this->flash($this->authError);
|
||||
$this->Session->write('Auth.redirect', $request->here(false));
|
||||
$controller->redirect($loginAction);
|
||||
return false;
|
||||
}
|
||||
if (!empty($this->ajaxLogin)) {
|
||||
$controller->viewPath = 'Elements';
|
||||
echo $controller->render($this->ajaxLogin, $this->RequestHandler->ajaxLayout);
|
||||
$this->_stop();
|
||||
return false;
|
||||
}
|
||||
$controller->redirect(null, 403);
|
||||
return $this->_unauthenticated($controller);
|
||||
}
|
||||
|
||||
if (empty($this->authorize) || $this->isAuthorized($this->user())) {
|
||||
|
@ -340,12 +311,95 @@ class AuthComponent extends Component {
|
|||
return $this->_unauthorized($controller);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether current action is accessible without authentication.
|
||||
*
|
||||
* @param Controller $controller A reference to the instantiating controller object
|
||||
* @return boolean True if action is accessible without authentication else false
|
||||
*/
|
||||
protected function _isAllowed(Controller $controller) {
|
||||
$action = strtolower($controller->request->params['action']);
|
||||
if (in_array($action, array_map('strtolower', $this->allowedActions))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles unauthenticated access attempt. First the `unathenticated()` method
|
||||
* of the last authenticator in the chain will be called. The authenticator can
|
||||
* handle sending response or redirection as appropriate and return `true` to
|
||||
* indicate no furthur action is necessary. If authenticator returns null this
|
||||
* method redirects user to login action. If it's an ajax request and
|
||||
* $ajaxLogin is specified that element is rendered else a 403 http status code
|
||||
* is returned.
|
||||
*
|
||||
* @param Controller $controller A reference to the controller object.
|
||||
* @return boolean True if current action is login action else false.
|
||||
*/
|
||||
protected function _unauthenticated(Controller $controller) {
|
||||
if (empty($this->_authenticateObjects)) {
|
||||
$this->constructAuthenticate();
|
||||
}
|
||||
$auth = $this->_authenticateObjects[count($this->_authenticateObjects) - 1];
|
||||
if ($auth->unauthenticated($this->request, $this->response)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->_isLoginAction($controller)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$controller->request->is('ajax')) {
|
||||
$this->flash($this->authError);
|
||||
$this->Session->write('Auth.redirect', $controller->request->here(false));
|
||||
$controller->redirect($this->loginAction);
|
||||
return false;
|
||||
}
|
||||
if (!empty($this->ajaxLogin)) {
|
||||
$controller->viewPath = 'Elements';
|
||||
echo $controller->render($this->ajaxLogin, $this->RequestHandler->ajaxLayout);
|
||||
$this->_stop();
|
||||
return false;
|
||||
}
|
||||
$controller->redirect(null, 403);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes $loginAction and checks if current request url is same as login
|
||||
* action. If current url is same as login action, referrer url is saved in session
|
||||
* which is later accessible using redirectUrl().
|
||||
*
|
||||
* @param Controller $controller A reference to the controller object.
|
||||
* @return boolean True if current action is login action else false.
|
||||
*/
|
||||
protected function _isLoginAction(Controller $controller) {
|
||||
$url = '';
|
||||
if (isset($controller->request->url)) {
|
||||
$url = $controller->request->url;
|
||||
}
|
||||
$url = Router::normalize($url);
|
||||
$loginAction = Router::normalize($this->loginAction);
|
||||
|
||||
if ($loginAction == $url) {
|
||||
if (empty($controller->request->data)) {
|
||||
if (!$this->Session->check('Auth.redirect') && env('HTTP_REFERER')) {
|
||||
$this->Session->write('Auth.redirect', $controller->referer(null, true));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle unauthorized access attempt
|
||||
*
|
||||
* @param Controller $controller A reference to the controller object
|
||||
* @return boolean Returns false
|
||||
* @throws ForbiddenException
|
||||
* @see AuthComponent::$unauthorizedRedirect
|
||||
*/
|
||||
protected function _unauthorized(Controller $controller) {
|
||||
if ($this->unauthorizedRedirect === false) {
|
||||
|
@ -369,7 +423,7 @@ class AuthComponent extends Component {
|
|||
/**
|
||||
* Attempts to introspect the correct values for object properties.
|
||||
*
|
||||
* @return boolean
|
||||
* @return boolean True
|
||||
*/
|
||||
protected function _setDefaults() {
|
||||
$defaults = array(
|
||||
|
@ -377,7 +431,7 @@ class AuthComponent extends Component {
|
|||
'authError' => __d('cake', 'You are not authorized to access that location.')
|
||||
);
|
||||
foreach ($defaults as $key => $value) {
|
||||
if (empty($this->{$key})) {
|
||||
if (!isset($this->{$key}) || $this->{$key} === true) {
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
}
|
||||
|
@ -441,7 +495,7 @@ class AuthComponent extends Component {
|
|||
throw new CakeException(__d('cake_dev', 'Authorization adapter "%s" was not found.', $class));
|
||||
}
|
||||
if (!method_exists($className, 'authorize')) {
|
||||
throw new CakeException(__d('cake_dev', 'Authorization objects must implement an authorize method.'));
|
||||
throw new CakeException(__d('cake_dev', 'Authorization objects must implement an %s method.', 'authorize()'));
|
||||
}
|
||||
$settings = array_merge($global, (array)$settings);
|
||||
$this->_authorizeObjects[] = new $className($this->_Collection, $settings);
|
||||
|
@ -593,13 +647,12 @@ class AuthComponent extends Component {
|
|||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#accessing-the-logged-in-user
|
||||
*/
|
||||
public static function user($key = null) {
|
||||
if (empty(self::$_user) && !CakeSession::check(self::$sessionKey)) {
|
||||
return null;
|
||||
}
|
||||
if (!empty(self::$_user)) {
|
||||
$user = self::$_user;
|
||||
} else {
|
||||
} elseif (self::$sessionKey && CakeSession::check(self::$sessionKey)) {
|
||||
$user = CakeSession::read(self::$sessionKey);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
if ($key === null) {
|
||||
return $user;
|
||||
|
@ -616,8 +669,10 @@ class AuthComponent extends Component {
|
|||
protected function _getUser() {
|
||||
$user = $this->user();
|
||||
if ($user) {
|
||||
$this->Session->delete('Auth.redirect');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (empty($this->_authenticateObjects)) {
|
||||
$this->constructAuthenticate();
|
||||
}
|
||||
|
@ -628,6 +683,7 @@ class AuthComponent extends Component {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -728,7 +784,7 @@ class AuthComponent extends Component {
|
|||
throw new CakeException(__d('cake_dev', 'Authentication adapter "%s" was not found.', $class));
|
||||
}
|
||||
if (!method_exists($className, 'authenticate')) {
|
||||
throw new CakeException(__d('cake_dev', 'Authentication objects must implement an authenticate method.'));
|
||||
throw new CakeException(__d('cake_dev', 'Authentication objects must implement an %s method.', 'authenticate()'));
|
||||
}
|
||||
$settings = array_merge($global, (array)$settings);
|
||||
$this->_authenticateObjects[] = new $className($this->_Collection, $settings);
|
||||
|
@ -744,24 +800,12 @@ class AuthComponent extends Component {
|
|||
*
|
||||
* @param string $password Password to hash
|
||||
* @return string Hashed password
|
||||
* @link http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#hashing-passwords
|
||||
* @deprecated Since 2.4. Use Security::hash() directly or a password hasher object.
|
||||
*/
|
||||
public static function password($password) {
|
||||
return Security::hash($password, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Component shutdown. If user is logged in, wipe out redirect.
|
||||
*
|
||||
* @param Controller $controller Instantiating controller
|
||||
* @return void
|
||||
*/
|
||||
public function shutdown(Controller $controller) {
|
||||
if ($this->loggedIn()) {
|
||||
$this->Session->delete('Auth.redirect');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not the current user has data in the session, and is considered logged in.
|
||||
*
|
||||
|
@ -778,6 +822,9 @@ class AuthComponent extends Component {
|
|||
* @return void
|
||||
*/
|
||||
public function flash($message) {
|
||||
if ($message === false) {
|
||||
return;
|
||||
}
|
||||
$this->Session->setFlash($message, $this->flash['element'], $this->flash['params'], $this->flash['key']);
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,9 @@ class RequestHandlerComponent extends Component {
|
|||
* Compares the accepted types and configured extensions.
|
||||
* If there is one common type, that is assigned as the ext/content type
|
||||
* for the response.
|
||||
* Type with the highest weight will be set. If the highest weight has more
|
||||
* then one type matching the extensions, the order in which extensions are specified
|
||||
* determines which type will be set.
|
||||
*
|
||||
* If html is one of the preferred types, no content type will be set, this
|
||||
* is to avoid issues with browsers that prefer html and several other content types.
|
||||
|
@ -155,13 +158,19 @@ class RequestHandlerComponent extends Component {
|
|||
if (empty($accept)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$accepts = $this->response->mapType($this->request->parseAccept());
|
||||
$preferedTypes = current($accepts);
|
||||
if (array_intersect($preferedTypes, array('html', 'xhtml'))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$extensions = Router::extensions();
|
||||
$preferred = array_shift($accept);
|
||||
$preferredTypes = $this->response->mapType($preferred);
|
||||
if (!in_array('xhtml', $preferredTypes) && !in_array('html', $preferredTypes)) {
|
||||
$similarTypes = array_intersect($extensions, $preferredTypes);
|
||||
if (count($similarTypes) === 1) {
|
||||
$this->ext = array_shift($similarTypes);
|
||||
foreach ($accepts as $types) {
|
||||
$ext = array_intersect($extensions, $types);
|
||||
if ($ext) {
|
||||
$this->ext = current($ext);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ class ComponentCollection extends ObjectCollection implements CakeEventListener
|
|||
* @throws MissingComponentException when the component could not be found
|
||||
*/
|
||||
public function load($component, $settings = array()) {
|
||||
if (is_array($settings) && isset($settings['className'])) {
|
||||
if (isset($settings['className'])) {
|
||||
$alias = $component;
|
||||
$component = $settings['className'];
|
||||
}
|
||||
|
|
|
@ -705,7 +705,7 @@ class Controller extends Object implements CakeEventListener {
|
|||
*
|
||||
* @return array Associative array of the HTTP codes as keys, and the message
|
||||
* strings as values, or null of the given $code does not exist.
|
||||
* @deprecated Use CakeResponse::httpCodes();
|
||||
* @deprecated Since 2.4. Will be removed in 3.0. Use CakeResponse::httpCodes().
|
||||
*/
|
||||
public function httpCodes($code = null) {
|
||||
return $this->response->httpCodes($code);
|
||||
|
@ -820,7 +820,7 @@ class Controller extends Object implements CakeEventListener {
|
|||
*
|
||||
* @param string $status The header message that is being set.
|
||||
* @return void
|
||||
* @deprecated Use CakeResponse::header()
|
||||
* @deprecated Will be removed in 3.0. Use CakeResponse::header().
|
||||
*/
|
||||
public function header($status) {
|
||||
$this->response->header($status);
|
||||
|
@ -978,7 +978,7 @@ class Controller extends Object implements CakeEventListener {
|
|||
*
|
||||
* @return void
|
||||
* @link http://book.cakephp.org/2.0/en/controllers.html#Controller::disableCache
|
||||
* @deprecated Use CakeResponse::disableCache()
|
||||
* @deprecated Will be removed in 3.0. Use CakeResponse::disableCache().
|
||||
*/
|
||||
public function disableCache() {
|
||||
$this->response->disableCache();
|
||||
|
@ -995,6 +995,7 @@ class Controller extends Object implements CakeEventListener {
|
|||
* @param string $layout Layout you want to use, defaults to 'flash'
|
||||
* @return void
|
||||
* @link http://book.cakephp.org/2.0/en/controllers.html#Controller::flash
|
||||
* @deprecated Will be removed in 3.0. Use Session::setFlash().
|
||||
*/
|
||||
public function flash($message, $url, $pause = 1, $layout = 'flash') {
|
||||
$this->autoRender = false;
|
||||
|
@ -1015,7 +1016,7 @@ class Controller extends Object implements CakeEventListener {
|
|||
* @param boolean $exclusive If true, and $op is an array, fields not included in $op will not be
|
||||
* included in the returned conditions
|
||||
* @return array An array of model conditions
|
||||
* @deprecated Will be removed in 3.0
|
||||
* @deprecated Will be removed in 3.0.
|
||||
*/
|
||||
public function postConditions($data = array(), $op = null, $bool = 'AND', $exclusive = false) {
|
||||
if (!is_array($data) || empty($data)) {
|
||||
|
@ -1072,7 +1073,7 @@ class Controller extends Object implements CakeEventListener {
|
|||
* @param array $whitelist List of allowed options for paging
|
||||
* @return array Model query results
|
||||
* @link http://book.cakephp.org/2.0/en/controllers.html#Controller::paginate
|
||||
* @deprecated Use PaginatorComponent instead
|
||||
* @deprecated Will be removed in 3.0. Use PaginatorComponent instead.
|
||||
*/
|
||||
public function paginate($object = null, $scope = array(), $whitelist = array()) {
|
||||
return $this->Components->load('Paginator', $this->paginate)->paginate($object, $scope, $whitelist);
|
||||
|
@ -1146,7 +1147,7 @@ class Controller extends Object implements CakeEventListener {
|
|||
* @param string $method
|
||||
* @return boolean
|
||||
* @see Controller::beforeScaffold()
|
||||
* @deprecated
|
||||
* @deprecated Will be removed in 3.0.
|
||||
*/
|
||||
protected function _beforeScaffold($method) {
|
||||
return $this->beforeScaffold($method);
|
||||
|
@ -1169,7 +1170,7 @@ class Controller extends Object implements CakeEventListener {
|
|||
* @param string $method
|
||||
* @return boolean
|
||||
* @see Controller::afterScaffoldSave()
|
||||
* @deprecated
|
||||
* @deprecated Will be removed in 3.0.
|
||||
*/
|
||||
protected function _afterScaffoldSave($method) {
|
||||
return $this->afterScaffoldSave($method);
|
||||
|
@ -1192,7 +1193,7 @@ class Controller extends Object implements CakeEventListener {
|
|||
* @param string $method
|
||||
* @return boolean
|
||||
* @see Controller::afterScaffoldSaveError()
|
||||
* @deprecated
|
||||
* @deprecated Will be removed in 3.0.
|
||||
*/
|
||||
protected function _afterScaffoldSaveError($method) {
|
||||
return $this->afterScaffoldSaveError($method);
|
||||
|
@ -1217,7 +1218,7 @@ class Controller extends Object implements CakeEventListener {
|
|||
* @param string $method
|
||||
* @return boolean
|
||||
* @see Controller::scaffoldError()
|
||||
* @deprecated
|
||||
* @deprecated Will be removed in 3.0.
|
||||
*/
|
||||
protected function _scaffoldError($method) {
|
||||
return $this->scaffoldError($method);
|
||||
|
|
|
@ -67,16 +67,14 @@ class Configure {
|
|||
*/
|
||||
public static function bootstrap($boot = true) {
|
||||
if ($boot) {
|
||||
self::write('App', array(
|
||||
'base' => false,
|
||||
'baseUrl' => false,
|
||||
'dir' => APP_DIR,
|
||||
'webroot' => WEBROOT_DIR,
|
||||
'www_root' => WWW_ROOT
|
||||
));
|
||||
self::_appDefaults();
|
||||
|
||||
if (!include APP . 'Config' . DS . 'core.php') {
|
||||
trigger_error(__d('cake_dev', "Can't find application core file. Please create %score.php, and make sure it is readable by PHP.", APP . 'Config' . DS), E_USER_ERROR);
|
||||
trigger_error(__d('cake_dev',
|
||||
"Can't find application core file. Please create %s, and make sure it is readable by PHP.",
|
||||
APP . 'Config' . DS . 'core.php'),
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
App::init();
|
||||
App::$bootstrapping = false;
|
||||
|
@ -92,7 +90,11 @@ class Configure {
|
|||
self::_setErrorHandlers($error, $exception);
|
||||
|
||||
if (!include APP . 'Config' . DS . 'bootstrap.php') {
|
||||
trigger_error(__d('cake_dev', "Can't find application bootstrap file. Please create %sbootstrap.php, and make sure it is readable by PHP.", APP . 'Config' . DS), E_USER_ERROR);
|
||||
trigger_error(__d('cake_dev',
|
||||
"Can't find application bootstrap file. Please create %s, and make sure it is readable by PHP.",
|
||||
APP . 'Config' . DS . 'bootstrap.php'),
|
||||
E_USER_ERROR
|
||||
);
|
||||
}
|
||||
restore_error_handler();
|
||||
|
||||
|
@ -109,6 +111,20 @@ class Configure {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set app's default configs
|
||||
* @return void
|
||||
*/
|
||||
protected static function _appDefaults() {
|
||||
self::write('App', (array)self::read('App') + array(
|
||||
'base' => false,
|
||||
'baseUrl' => false,
|
||||
'dir' => APP_DIR,
|
||||
'webroot' => WEBROOT_DIR,
|
||||
'www_root' => WWW_ROOT
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to store a dynamic variable in Configure.
|
||||
*
|
||||
|
@ -128,7 +144,8 @@ class Configure {
|
|||
* }}}
|
||||
*
|
||||
* @link http://book.cakephp.org/2.0/en/development/configuration.html#Configure::write
|
||||
* @param array $config Name of var to write
|
||||
* @param string|array $config The key to write, can be a dot notation value.
|
||||
* Alternatively can be an array containing key(s) and value(s).
|
||||
* @param mixed $value Value to set for var
|
||||
* @return boolean True if write was successful
|
||||
*/
|
||||
|
@ -323,7 +340,7 @@ class Configure {
|
|||
throw new ConfigureException(__d('cake_dev', 'There is no "%s" adapter.', $config));
|
||||
}
|
||||
if (!method_exists($reader, 'dump')) {
|
||||
throw new ConfigureException(__d('cake_dev', 'The "%s" adapter, does not have a dump() method.', $config));
|
||||
throw new ConfigureException(__d('cake_dev', 'The "%s" adapter, does not have a %s method.', $config, 'dump()'));
|
||||
}
|
||||
$values = self::$_values;
|
||||
if (!empty($keys) && is_array($keys)) {
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
|
||||
App::uses('CakeLog', 'Log');
|
||||
App::uses('Dispatcher', 'Routing');
|
||||
App::uses('Router', 'Routing');
|
||||
App::uses('Set', 'Utility');
|
||||
App::uses('CakeLog', 'Log');
|
||||
|
||||
/**
|
||||
* Object class provides a few generic methods used in several subclasses.
|
||||
|
@ -86,8 +88,8 @@ class Object {
|
|||
$data = isset($extra['data']) ? $extra['data'] : null;
|
||||
unset($extra['data']);
|
||||
|
||||
if (is_string($url) && strpos($url, FULL_BASE_URL) === 0) {
|
||||
$url = Router::normalize(str_replace(FULL_BASE_URL, '', $url));
|
||||
if (is_string($url) && strpos($url, Router::fullBaseUrl()) === 0) {
|
||||
$url = Router::normalize(str_replace(Router::fullBaseUrl(), '', $url));
|
||||
}
|
||||
if (is_string($url)) {
|
||||
$request = new CakeRequest($url);
|
||||
|
@ -148,17 +150,16 @@ class Object {
|
|||
* Convenience method to write a message to CakeLog. See CakeLog::write()
|
||||
* for more information on writing to logs.
|
||||
*
|
||||
* @param string $msg Log message.
|
||||
* @param integer|string $type Type of message being written. Either a valid
|
||||
* LOG_* constant or a string matching the recognized levels.
|
||||
* @return boolean Success of log write.
|
||||
* @see CakeLog::write()
|
||||
* @param string $msg Log message
|
||||
* @param integer $type Error type constant. Defined in app/Config/core.php.
|
||||
* @return boolean Success of log write
|
||||
*/
|
||||
public function log($msg, $type = LOG_ERR) {
|
||||
public function log($msg, $type = LOG_ERR, $scope = null) {
|
||||
if (!is_string($msg)) {
|
||||
$msg = print_r($msg, true);
|
||||
}
|
||||
return CakeLog::write($type, $msg);
|
||||
|
||||
return CakeLog::write($type, $msg, $scope);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -110,9 +110,8 @@ class ErrorHandler {
|
|||
*/
|
||||
public static function handleException(Exception $exception) {
|
||||
$config = Configure::read('Exception');
|
||||
if (!empty($config['log'])) {
|
||||
CakeLog::write(LOG_ERR, self::_getMessage($exception));
|
||||
}
|
||||
self::_log($exception, $config);
|
||||
|
||||
$renderer = isset($config['renderer']) ? $config['renderer'] : 'ExceptionRenderer';
|
||||
if ($renderer !== 'ExceptionRenderer') {
|
||||
list($plugin, $renderer) = pluginSplit($renderer, true);
|
||||
|
@ -159,6 +158,28 @@ class ErrorHandler {
|
|||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles exception logging
|
||||
*
|
||||
* @param Exception $exception
|
||||
* @param array $config
|
||||
* @return boolean
|
||||
*/
|
||||
protected static function _log(Exception $exception, $config) {
|
||||
if (empty($config['log'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($config['skipLog'])) {
|
||||
foreach ((array)$config['skipLog'] as $class) {
|
||||
if ($exception instanceof $class) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CakeLog::write(LOG_ERR, self::_getMessage($exception));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set as the default error handler by CakePHP. Use Configure::write('Error.handler', $callback), to use your own
|
||||
* error handling methods. This function will use Debugger to display errors when debug > 0. And
|
||||
|
|
|
@ -39,7 +39,7 @@ class CakeBaseException extends RuntimeException {
|
|||
* @param string|array $header. An array of header strings or a single header string
|
||||
* - an associative array of "header name" => "header value"
|
||||
* - an array of string headers is also accepted
|
||||
* @param string $value. The header value.
|
||||
* @param string $value The header value.
|
||||
* @return array
|
||||
* @see CakeResponse::header()
|
||||
*/
|
||||
|
@ -78,7 +78,7 @@ class BadRequestException extends HttpException {
|
|||
* Constructor
|
||||
*
|
||||
* @param string $message If no message is given 'Bad Request' will be the message
|
||||
* @param int $code Status code, defaults to 400
|
||||
* @param integer $code Status code, defaults to 400
|
||||
*/
|
||||
public function __construct($message = null, $code = 400) {
|
||||
if (empty($message)) {
|
||||
|
@ -100,7 +100,7 @@ class UnauthorizedException extends HttpException {
|
|||
* Constructor
|
||||
*
|
||||
* @param string $message If no message is given 'Unauthorized' will be the message
|
||||
* @param int $code Status code, defaults to 401
|
||||
* @param integer $code Status code, defaults to 401
|
||||
*/
|
||||
public function __construct($message = null, $code = 401) {
|
||||
if (empty($message)) {
|
||||
|
@ -122,7 +122,7 @@ class ForbiddenException extends HttpException {
|
|||
* Constructor
|
||||
*
|
||||
* @param string $message If no message is given 'Forbidden' will be the message
|
||||
* @param int $code Status code, defaults to 403
|
||||
* @param integer $code Status code, defaults to 403
|
||||
*/
|
||||
public function __construct($message = null, $code = 403) {
|
||||
if (empty($message)) {
|
||||
|
@ -144,7 +144,7 @@ class NotFoundException extends HttpException {
|
|||
* Constructor
|
||||
*
|
||||
* @param string $message If no message is given 'Not Found' will be the message
|
||||
* @param int $code Status code, defaults to 404
|
||||
* @param integer $code Status code, defaults to 404
|
||||
*/
|
||||
public function __construct($message = null, $code = 404) {
|
||||
if (empty($message)) {
|
||||
|
@ -166,7 +166,7 @@ class MethodNotAllowedException extends HttpException {
|
|||
* Constructor
|
||||
*
|
||||
* @param string $message If no message is given 'Method Not Allowed' will be the message
|
||||
* @param int $code Status code, defaults to 405
|
||||
* @param integer $code Status code, defaults to 405
|
||||
*/
|
||||
public function __construct($message = null, $code = 405) {
|
||||
if (empty($message)) {
|
||||
|
@ -188,7 +188,7 @@ class InternalErrorException extends HttpException {
|
|||
* Constructor
|
||||
*
|
||||
* @param string $message If no message is given 'Internal Server Error' will be the message
|
||||
* @param int $code Status code, defaults to 500
|
||||
* @param integer $code Status code, defaults to 500
|
||||
*/
|
||||
public function __construct($message = null, $code = 500) {
|
||||
if (empty($message)) {
|
||||
|
@ -230,7 +230,7 @@ class CakeException extends CakeBaseException {
|
|||
*
|
||||
* @param string|array $message Either the string of the error message, or an array of attributes
|
||||
* that are made available in the view, and sprintf()'d into CakeException::$_messageTemplate
|
||||
* @param int $code The code of the error, is also the HTTP status code for the error.
|
||||
* @param integer $code The code of the error, is also the HTTP status code for the error.
|
||||
*/
|
||||
public function __construct($message, $code = 500) {
|
||||
if (is_array($message)) {
|
||||
|
|
|
@ -39,7 +39,7 @@ class L10n {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public $languagePath = array('eng');
|
||||
public $languagePath = array('en_us', 'eng');
|
||||
|
||||
/**
|
||||
* ISO 639-3 for current locale
|
||||
|
@ -56,9 +56,11 @@ class L10n {
|
|||
public $locale = 'en_us';
|
||||
|
||||
/**
|
||||
* Default ISO 639-3 language.
|
||||
* Default language.
|
||||
*
|
||||
* DEFAULT_LANGUAGE is defined in an application this will be set as a fall back
|
||||
* If config value 'Config.language' is set in an application this will be set
|
||||
* as a fall back else if DEFAULT_LANGUAGE it defined it will be used.
|
||||
* Constant DEFAULT_LANGUAGE has been deprecated in 2.4
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
|
@ -78,13 +80,6 @@ class L10n {
|
|||
*/
|
||||
public $direction = 'ltr';
|
||||
|
||||
/**
|
||||
* Set to true if a locale is found
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $found = false;
|
||||
|
||||
/**
|
||||
* Maps ISO 639-3 to I10n::_l10nCatalog
|
||||
* The terminological codes (first one per language) should be used if possible.
|
||||
|
@ -138,6 +133,8 @@ class L10n {
|
|||
/* Irish */ 'gle' => 'ga',
|
||||
/* Italian */ 'ita' => 'it',
|
||||
/* Japanese */ 'jpn' => 'ja',
|
||||
/* Kazakh */ 'kaz' => 'kk',
|
||||
/* Kalaallisut (Greenlandic) */ 'kal' => 'kl',
|
||||
/* Korean */ 'kor' => 'ko',
|
||||
/* Latvian */ 'lav' => 'lv',
|
||||
/* Lithuanian */ 'lit' => 'lt',
|
||||
|
@ -155,7 +152,7 @@ class L10n {
|
|||
/* Romanian */ 'ron' => 'ro',
|
||||
/* Romanian - bibliographic */ 'rum' => 'ro',
|
||||
/* Russian */ 'rus' => 'ru',
|
||||
/* Sami (Lappish) */ 'smi' => 'sz',
|
||||
/* Sami */ 'sme' => 'se',
|
||||
/* Serbian */ 'srp' => 'sr',
|
||||
/* Slovak */ 'slk' => 'sk',
|
||||
/* Slovak - bibliographic */ 'slo' => 'sk',
|
||||
|
@ -219,8 +216,7 @@ class L10n {
|
|||
'de-de' => array('language' => 'German (Germany)', 'locale' => 'de_de', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'de-li' => array('language' => 'German (Liechtenstein)', 'locale' => 'de_li', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'de-lu' => array('language' => 'German (Luxembourg)', 'locale' => 'de_lu', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'e' => array('language' => 'Greek', 'locale' => 'gre', 'localeFallback' => 'gre', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'el' => array('language' => 'Greek', 'locale' => 'gre', 'localeFallback' => 'gre', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'el' => array('language' => 'Greek', 'locale' => 'ell', 'localeFallback' => 'ell', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'en' => array('language' => 'English', 'locale' => 'eng', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'en-au' => array('language' => 'English (Australian)', 'locale' => 'en_au', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'en-bz' => array('language' => 'English (Belize)', 'locale' => 'en_bz', 'localeFallback' => 'eng', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
|
@ -254,7 +250,7 @@ class L10n {
|
|||
'es-ve' => array('language' => 'Spanish (Venezuela)', 'locale' => 'es_ve', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'et' => array('language' => 'Estonian', 'locale' => 'est', 'localeFallback' => 'est', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'eu' => array('language' => 'Basque', 'locale' => 'eus', 'localeFallback' => 'eus', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'fa' => array('language' => 'Farsi', 'locale' => 'per', 'localeFallback' => 'per', 'charset' => 'utf-8', 'direction' => 'rtl'),
|
||||
'fa' => array('language' => 'Farsi', 'locale' => 'fas', 'localeFallback' => 'fas', 'charset' => 'utf-8', 'direction' => 'rtl'),
|
||||
'fi' => array('language' => 'Finnish', 'locale' => 'fin', 'localeFallback' => 'fin', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'fo' => array('language' => 'Faeroese', 'locale' => 'fao', 'localeFallback' => 'fao', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'fr' => array('language' => 'French (Standard)', 'locale' => 'fra', 'localeFallback' => 'fra', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
|
@ -273,28 +269,27 @@ class L10n {
|
|||
'hu' => array('language' => 'Hungarian', 'locale' => 'hun', 'localeFallback' => 'hun', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'hy' => array('language' => 'Armenian - Armenia', 'locale' => 'hye', 'localeFallback' => 'hye', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'id' => array('language' => 'Indonesian', 'locale' => 'ind', 'localeFallback' => 'ind', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'in' => array('language' => 'Indonesian', 'locale' => 'ind', 'localeFallback' => 'ind', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'is' => array('language' => 'Icelandic', 'locale' => 'isl', 'localeFallback' => 'isl', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'it' => array('language' => 'Italian', 'locale' => 'ita', 'localeFallback' => 'ita', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'it-ch' => array('language' => 'Italian (Swiss) ', 'locale' => 'it_ch', 'localeFallback' => 'ita', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'ja' => array('language' => 'Japanese', 'locale' => 'jpn', 'localeFallback' => 'jpn', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'kk' => array('language' => 'Kazakh', 'locale' => 'kaz', 'localeFallback' => 'kaz', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'kl' => array('language' => 'Kalaallisut (Greenlandic)', 'locale' => 'kal', 'localeFallback' => 'kal', 'charset' => 'kl', 'direction' => 'ltr'),
|
||||
'ko' => array('language' => 'Korean', 'locale' => 'kor', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr'),
|
||||
'ko-kp' => array('language' => 'Korea (North)', 'locale' => 'ko_kp', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr'),
|
||||
'ko-kr' => array('language' => 'Korea (South)', 'locale' => 'ko_kr', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr'),
|
||||
'koi8-r' => array('language' => 'Russian', 'locale' => 'koi8_r', 'localeFallback' => 'rus', 'charset' => 'koi8-r', 'direction' => 'ltr'),
|
||||
'lt' => array('language' => 'Lithuanian', 'locale' => 'lit', 'localeFallback' => 'lit', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'lv' => array('language' => 'Latvian', 'locale' => 'lav', 'localeFallback' => 'lav', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'mk' => array('language' => 'FYRO Macedonian', 'locale' => 'mk', 'localeFallback' => 'mkd', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'mk' => array('language' => 'FYRO Macedonian', 'locale' => 'mkd', 'localeFallback' => 'mkd', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'mk-mk' => array('language' => 'Macedonian', 'locale' => 'mk_mk', 'localeFallback' => 'mkd', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'ms' => array('language' => 'Malaysian', 'locale' => 'msa', 'localeFallback' => 'msa', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'mt' => array('language' => 'Maltese', 'locale' => 'mlt', 'localeFallback' => 'mlt', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'n' => array('language' => 'Dutch (Standard)', 'locale' => 'nld', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'nb' => array('language' => 'Norwegian Bokmal', 'locale' => 'nob', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'nl' => array('language' => 'Dutch (Standard)', 'locale' => 'nld', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'nl-be' => array('language' => 'Dutch (Belgium)', 'locale' => 'nl_be', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'nn' => array('language' => 'Norwegian Nynorsk', 'locale' => 'nno', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'no' => array('language' => 'Norwegian', 'locale' => 'nor', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'p' => array('language' => 'Polish', 'locale' => 'pol', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'pl' => array('language' => 'Polish', 'locale' => 'pol', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'pt' => array('language' => 'Portuguese (Portugal)', 'locale' => 'por', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'pt-br' => array('language' => 'Portuguese (Brazil)', 'locale' => 'pt_br', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
|
@ -310,8 +305,7 @@ class L10n {
|
|||
'sr' => array('language' => 'Serbian', 'locale' => 'srp', 'localeFallback' => 'srp', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'sv' => array('language' => 'Swedish', 'locale' => 'swe', 'localeFallback' => 'swe', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'sv-fi' => array('language' => 'Swedish (Finland)', 'locale' => 'sv_fi', 'localeFallback' => 'swe', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'sx' => array('language' => 'Sutu', 'locale' => 'sx', 'localeFallback' => 'sx', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'sz' => array('language' => 'Sami (Lappish)', 'locale' => 'smi', 'localeFallback' => 'smi', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'se' => array('language' => 'Sami', 'locale' => 'sme', 'localeFallback' => 'sme', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'th' => array('language' => 'Thai', 'locale' => 'tha', 'localeFallback' => 'tha', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'tn' => array('language' => 'Tswana', 'locale' => 'tsn', 'localeFallback' => 'tsn', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'tr' => array('language' => 'Turkish', 'locale' => 'tur', 'localeFallback' => 'tur', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
|
@ -338,6 +332,10 @@ class L10n {
|
|||
if (defined('DEFAULT_LANGUAGE')) {
|
||||
$this->default = DEFAULT_LANGUAGE;
|
||||
}
|
||||
$default = Configure::read('Config.language');
|
||||
if ($default) {
|
||||
$this->default = $default;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -361,44 +359,44 @@ class L10n {
|
|||
|
||||
/**
|
||||
* Sets the class vars to correct values for $language.
|
||||
* If $language is null it will use the DEFAULT_LANGUAGE if defined
|
||||
* If $language is null it will use the L10n::$default if defined
|
||||
*
|
||||
* @param string $language Language (if null will use DEFAULT_LANGUAGE if defined)
|
||||
* @param string $language Language (if null will use L10n::$default if defined)
|
||||
* @return mixed
|
||||
*/
|
||||
protected function _setLanguage($language = null) {
|
||||
$langKey = null;
|
||||
if ($language !== null && isset($this->_l10nMap[$language]) && isset($this->_l10nCatalog[$this->_l10nMap[$language]])) {
|
||||
$langKey = $this->_l10nMap[$language];
|
||||
} elseif ($language !== null && isset($this->_l10nCatalog[$language])) {
|
||||
$langKey = $language;
|
||||
} elseif (defined('DEFAULT_LANGUAGE')) {
|
||||
$langKey = $language = DEFAULT_LANGUAGE;
|
||||
$catalog = false;
|
||||
if ($language !== null) {
|
||||
$catalog = $this->catalog($language);
|
||||
}
|
||||
|
||||
if ($langKey !== null && isset($this->_l10nCatalog[$langKey])) {
|
||||
$this->language = $this->_l10nCatalog[$langKey]['language'];
|
||||
$this->languagePath = array(
|
||||
$this->_l10nCatalog[$langKey]['locale'],
|
||||
$this->_l10nCatalog[$langKey]['localeFallback']
|
||||
);
|
||||
if (!$catalog && $this->default) {
|
||||
$language = $this->default;
|
||||
$catalog = $this->catalog($language);
|
||||
}
|
||||
|
||||
if ($catalog) {
|
||||
$this->language = $catalog['language'];
|
||||
$this->languagePath = array_unique(array(
|
||||
$catalog['locale'],
|
||||
$catalog['localeFallback']
|
||||
));
|
||||
$this->lang = $language;
|
||||
$this->locale = $this->_l10nCatalog[$langKey]['locale'];
|
||||
$this->charset = $this->_l10nCatalog[$langKey]['charset'];
|
||||
$this->direction = $this->_l10nCatalog[$langKey]['direction'];
|
||||
} else {
|
||||
$this->locale = $catalog['locale'];
|
||||
$this->charset = $catalog['charset'];
|
||||
$this->direction = $catalog['direction'];
|
||||
} elseif ($language) {
|
||||
$this->lang = $language;
|
||||
$this->languagePath = array($language);
|
||||
}
|
||||
|
||||
if ($this->default) {
|
||||
if (isset($this->_l10nMap[$this->default]) && isset($this->_l10nCatalog[$this->_l10nMap[$this->default]])) {
|
||||
$this->languagePath[] = $this->_l10nCatalog[$this->_l10nMap[$this->default]]['localeFallback'];
|
||||
} elseif (isset($this->_l10nCatalog[$this->default])) {
|
||||
$this->languagePath[] = $this->_l10nCatalog[$this->default]['localeFallback'];
|
||||
if ($this->default && $language !== $this->default) {
|
||||
$catalog = $this->catalog($this->default);
|
||||
$fallback = $catalog['localeFallback'];
|
||||
if (!in_array($fallback, $this->languagePath)) {
|
||||
$this->languagePath[] = $fallback;
|
||||
}
|
||||
}
|
||||
$this->found = true;
|
||||
|
||||
if (Configure::read('Config.language') === null) {
|
||||
Configure::write('Config.language', $this->lang);
|
||||
|
@ -420,7 +418,8 @@ class L10n {
|
|||
if (isset($this->_l10nCatalog[$langKey])) {
|
||||
$this->_setLanguage($langKey);
|
||||
return true;
|
||||
} elseif (strpos($langKey, '-') !== false) {
|
||||
}
|
||||
if (strpos($langKey, '-') !== false) {
|
||||
$langKey = substr($langKey, 0, 2);
|
||||
if (isset($this->_l10nCatalog[$langKey])) {
|
||||
$this->_setLanguage($langKey);
|
||||
|
@ -447,10 +446,12 @@ class L10n {
|
|||
}
|
||||
}
|
||||
return $result;
|
||||
} elseif (is_string($mixed)) {
|
||||
}
|
||||
if (is_string($mixed)) {
|
||||
if (strlen($mixed) === 2 && in_array($mixed, $this->_l10nMap)) {
|
||||
return array_search($mixed, $this->_l10nMap);
|
||||
} elseif (isset($this->_l10nMap[$mixed])) {
|
||||
}
|
||||
if (isset($this->_l10nMap[$mixed])) {
|
||||
return $this->_l10nMap[$mixed];
|
||||
}
|
||||
return false;
|
||||
|
@ -474,10 +475,12 @@ class L10n {
|
|||
}
|
||||
}
|
||||
return $result;
|
||||
} elseif (is_string($language)) {
|
||||
}
|
||||
if (is_string($language)) {
|
||||
if (isset($this->_l10nCatalog[$language])) {
|
||||
return $this->_l10nCatalog[$language];
|
||||
} elseif (isset($this->_l10nMap[$language]) && isset($this->_l10nCatalog[$this->_l10nMap[$language]])) {
|
||||
}
|
||||
if (isset($this->_l10nMap[$language]) && isset($this->_l10nCatalog[$this->_l10nMap[$language]])) {
|
||||
return $this->_l10nCatalog[$this->_l10nMap[$language]];
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -34,7 +34,7 @@ App::uses('LogEngineCollection', 'Log');
|
|||
* A sample configuration would look like:
|
||||
*
|
||||
* {{{
|
||||
* CakeLog::config('my_log', array('engine' => 'FileLog'));
|
||||
* CakeLog::config('my_log', array('engine' => 'File'));
|
||||
* }}}
|
||||
*
|
||||
* See the documentation on CakeLog::config() for more detail.
|
||||
|
@ -133,7 +133,7 @@ class CakeLog {
|
|||
*
|
||||
* {{{
|
||||
* CakeLog::config('second_file', array(
|
||||
* 'engine' => 'FileLog',
|
||||
* 'engine' => 'File',
|
||||
* 'path' => '/var/logs/my_app/'
|
||||
* ));
|
||||
* }}}
|
||||
|
@ -378,7 +378,7 @@ class CakeLog {
|
|||
*/
|
||||
protected static function _autoConfig() {
|
||||
self::$_Collection->load('default', array(
|
||||
'engine' => 'FileLog',
|
||||
'engine' => 'File',
|
||||
'path' => LOGS,
|
||||
));
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
App::uses('BaseLog', 'Log/Engine');
|
||||
App::uses('Hash', 'Utility');
|
||||
App::uses('CakeNumber', 'Utility');
|
||||
|
||||
/**
|
||||
* File Storage stream for Logging. Writes logs to different files
|
||||
|
@ -29,6 +30,22 @@ App::uses('Hash', 'Utility');
|
|||
*/
|
||||
class FileLog extends BaseLog {
|
||||
|
||||
/**
|
||||
* Default configuration values
|
||||
*
|
||||
* @var array
|
||||
* @see FileLog::__construct()
|
||||
*/
|
||||
protected $_defaults = array(
|
||||
'path' => LOGS,
|
||||
'file' => null,
|
||||
'types' => null,
|
||||
'scopes' => array(),
|
||||
'rotate' => 10,
|
||||
'size' => 10485760, // 10MB
|
||||
'mask' => null,
|
||||
);
|
||||
|
||||
/**
|
||||
* Path to save log files on.
|
||||
*
|
||||
|
@ -36,6 +53,20 @@ class FileLog extends BaseLog {
|
|||
*/
|
||||
protected $_path = null;
|
||||
|
||||
/**
|
||||
* Log file name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_file = null;
|
||||
|
||||
/**
|
||||
* Max file size, used for log file rotation.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_size = null;
|
||||
|
||||
/**
|
||||
* Constructs a new File Logger.
|
||||
*
|
||||
|
@ -43,25 +74,55 @@ class FileLog extends BaseLog {
|
|||
*
|
||||
* - `types` string or array, levels the engine is interested in
|
||||
* - `scopes` string or array, scopes the engine is interested in
|
||||
* - `file` log file name
|
||||
* - `path` the path to save logs on.
|
||||
* - `file` Log file name
|
||||
* - `path` The path to save logs on.
|
||||
* - `size` Used to implement basic log file rotation. If log file size
|
||||
* reaches specified size the existing file is renamed by appending timestamp
|
||||
* to filename and new log file is created. Can be integer bytes value or
|
||||
* human reabable string values like '10MB', '100KB' etc.
|
||||
* - `rotate` Log files are rotated specified times before being removed.
|
||||
* If value is 0, old versions are removed rather then rotated.
|
||||
* - `mask` A mask is applied when log files are created. Left empty no chmod
|
||||
* is made.
|
||||
*
|
||||
* @param array $options Options for the FileLog, see above.
|
||||
*/
|
||||
public function __construct($config = array()) {
|
||||
$config = Hash::merge($this->_defaults, $config);
|
||||
parent::__construct($config);
|
||||
$config = Hash::merge(array(
|
||||
'path' => LOGS,
|
||||
'file' => null,
|
||||
'types' => null,
|
||||
'scopes' => array(),
|
||||
), $this->_config);
|
||||
$config = $this->config($config);
|
||||
$this->_path = $config['path'];
|
||||
$this->_file = $config['file'];
|
||||
if (!empty($this->_file) && substr($this->_file, -4) !== '.log') {
|
||||
$this->_file .= '.log';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets protected properties based on config provided
|
||||
*
|
||||
* @param array $config Engine configuration
|
||||
* @return array
|
||||
*/
|
||||
public function config($config = array()) {
|
||||
parent::config($config);
|
||||
|
||||
if (!empty($config['path'])) {
|
||||
$this->_path = $config['path'];
|
||||
}
|
||||
if (Configure::read('debug') && !is_dir($this->_path)) {
|
||||
mkdir($this->_path, 0775, true);
|
||||
}
|
||||
|
||||
if (!empty($config['file'])) {
|
||||
$this->_file = $config['file'];
|
||||
if (substr($this->_file, -4) !== '.log') {
|
||||
$this->_file .= '.log';
|
||||
}
|
||||
}
|
||||
if (!empty($config['size'])) {
|
||||
if (is_numeric($config['size'])) {
|
||||
$this->_size = (int)$config['size'];
|
||||
} else {
|
||||
$this->_size = CakeNumber::fromReadableSize($config['size']);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_config;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,19 +133,85 @@ class FileLog extends BaseLog {
|
|||
* @return boolean success of write.
|
||||
*/
|
||||
public function write($type, $message) {
|
||||
$output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $message . "\n";
|
||||
$filename = $this->_getFilename($type);
|
||||
if (!empty($this->_size)) {
|
||||
$this->_rotateFile($filename);
|
||||
}
|
||||
|
||||
$pathname = $this->_path . $filename;
|
||||
if (empty($this->_config['mask'])) {
|
||||
return file_put_contents($pathname, $output, FILE_APPEND);
|
||||
}
|
||||
|
||||
$exists = file_exists($pathname);
|
||||
$result = file_put_contents($pathname, $output, FILE_APPEND);
|
||||
static $selfError = false;
|
||||
if (!$selfError && !$exists && !chmod($pathname, (int)$this->_config['mask'])) {
|
||||
$selfError = true;
|
||||
trigger_error(__d(
|
||||
'cake_dev', 'Could not apply permission mask "%s" on log file "%s"',
|
||||
array($this->_config['mask'], $pathname)), E_USER_WARNING);
|
||||
$selfError = false;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filename
|
||||
* @param string $type The type of log.
|
||||
* @return string File name
|
||||
*/
|
||||
protected function _getFilename($type) {
|
||||
$debugTypes = array('notice', 'info', 'debug');
|
||||
|
||||
if (!empty($this->_file)) {
|
||||
$filename = $this->_path . $this->_file;
|
||||
} elseif ($type === 'error' || $type === 'warning') {
|
||||
$filename = $this->_path . 'error.log';
|
||||
$filename = $this->_file;
|
||||
} elseif ($type == 'error' || $type == 'warning') {
|
||||
$filename = 'error.log';
|
||||
} elseif (in_array($type, $debugTypes)) {
|
||||
$filename = $this->_path . 'debug.log';
|
||||
$filename = 'debug.log';
|
||||
} else {
|
||||
$filename = $this->_path . $type . '.log';
|
||||
$filename = $type . '.log';
|
||||
}
|
||||
$output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $message . "\n";
|
||||
return file_put_contents($filename, $output, FILE_APPEND);
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate log file if size specified in config is reached.
|
||||
* Also if `rotate` count is reached oldest file is removed.
|
||||
*
|
||||
* @param string $filename Log file name
|
||||
* @return mixed True if rotated successfully or false in case of error.
|
||||
* Void if file doesn't need to be rotated.
|
||||
*/
|
||||
protected function _rotateFile($filename) {
|
||||
$filepath = $this->_path . $filename;
|
||||
if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
|
||||
clearstatcache(true, $filepath);
|
||||
} else {
|
||||
clearstatcache();
|
||||
}
|
||||
|
||||
if (!file_exists($filepath) ||
|
||||
filesize($filepath) < $this->_size
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->_config['rotate'] === 0) {
|
||||
return unlink($filepath);
|
||||
}
|
||||
|
||||
if ($this->_config['rotate']) {
|
||||
$files = glob($filepath . '.*');
|
||||
if (count($files) === $this->_config['rotate']) {
|
||||
unlink(array_shift($files));
|
||||
}
|
||||
}
|
||||
|
||||
return rename($filepath, $filepath . '.' . time());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
164
lib/Cake/Log/Engine/SyslogLog.php
Normal file
164
lib/Cake/Log/Engine/SyslogLog.php
Normal file
|
@ -0,0 +1,164 @@
|
|||
<?php
|
||||
/**
|
||||
* Syslog logger engine for CakePHP
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
|
||||
* @package Cake.Log.Engine
|
||||
* @since CakePHP(tm) v 2.4
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
App::uses('BaseLog', 'Log/Engine');
|
||||
|
||||
/**
|
||||
* Syslog stream for Logging. Writes logs to the system logger
|
||||
*
|
||||
* @package Cake.Log.Engine
|
||||
*/
|
||||
class SyslogLog extends BaseLog {
|
||||
|
||||
/**
|
||||
*
|
||||
* By default messages are formatted as:
|
||||
* type: message
|
||||
*
|
||||
* To override the log format (e.g. to add your own info) define the format key when configuring
|
||||
* this logger
|
||||
*
|
||||
* If you wish to include a prefix to all messages, for instance to identify the
|
||||
* application or the web server, then use the prefix option. Please keep in mind
|
||||
* the prefix is shared by all streams using syslog, as it is dependent of
|
||||
* the running process. For a local prefix, to be used only by one stream, you
|
||||
* can use the format key.
|
||||
*
|
||||
* ## Example:
|
||||
*
|
||||
* {{{
|
||||
* CakeLog::config('error', array(
|
||||
* 'engine' => 'Syslog',
|
||||
* 'types' => array('emergency', 'alert', 'critical', 'error'),
|
||||
* 'format' => "%s: My-App - %s",
|
||||
* 'prefix' => 'Web Server 01'
|
||||
* ));
|
||||
* }}}
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_defaults = array(
|
||||
'format' => '%s: %s',
|
||||
'flag' => LOG_ODELAY,
|
||||
'prefix' => '',
|
||||
'facility' => LOG_USER
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* Used to map the string names back to their LOG_* constants
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_priorityMap = array(
|
||||
'emergency' => LOG_EMERG,
|
||||
'alert' => LOG_ALERT,
|
||||
'critical' => LOG_CRIT,
|
||||
'error' => LOG_ERR,
|
||||
'warning' => LOG_WARNING,
|
||||
'notice' => LOG_NOTICE,
|
||||
'info' => LOG_INFO,
|
||||
'debug' => LOG_DEBUG
|
||||
);
|
||||
|
||||
/**
|
||||
* Whether the logger connection is open or not
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_open = false;
|
||||
|
||||
/**
|
||||
* Make sure the configuration contains the format parameter, by default it uses
|
||||
* the error number and the type as a prefix to the message
|
||||
*
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct($config = array()) {
|
||||
$config += $this->_defaults;
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a message to syslog
|
||||
*
|
||||
* Map the $type back to a LOG_ constant value, split multi-line messages into multiple
|
||||
* log messages, pass all messages through the format defined in the configuration
|
||||
*
|
||||
* @param string $type The type of log you are making.
|
||||
* @param string $message The message you want to log.
|
||||
* @return boolean success of write.
|
||||
*/
|
||||
public function write($type, $message) {
|
||||
if (!$this->_open) {
|
||||
$config = $this->_config;
|
||||
$this->_open($config['prefix'], $config['flag'], $config['facility']);
|
||||
$this->_open = true;
|
||||
}
|
||||
|
||||
$priority = LOG_DEBUG;
|
||||
if (isset($this->_priorityMap[$type])) {
|
||||
$priority = $this->_priorityMap[$type];
|
||||
}
|
||||
|
||||
$messages = explode("\n", $message);
|
||||
foreach ($messages as $message) {
|
||||
$message = sprintf($this->_config['format'], $type, $message);
|
||||
$this->_write($priority, $message);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the call to openlog() in order to run unit tests on it. This function
|
||||
* will initialize the connection to the system logger
|
||||
*
|
||||
* @param string $ident the prefix to add to all messages logged
|
||||
* @param integer $options the options flags to be used for logged messages
|
||||
* @param integer $facility the stream or facility to log to
|
||||
* @return void
|
||||
*/
|
||||
protected function _open($ident, $options, $facility) {
|
||||
openlog($ident, $options, $facility);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the call to syslog() in order to run unit tests on it. This function
|
||||
* will perform the actual write in the system logger
|
||||
*
|
||||
* @param integer $priority
|
||||
* @param string $message
|
||||
* @return bool
|
||||
*/
|
||||
protected function _write($priority, $message) {
|
||||
return syslog($priority, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the logger connection
|
||||
*
|
||||
* @return void
|
||||
**/
|
||||
public function __destruct() {
|
||||
closelog();
|
||||
}
|
||||
|
||||
}
|
|
@ -42,9 +42,9 @@ class LogEngineCollection extends ObjectCollection {
|
|||
$className = $this->_getLogger($loggerName);
|
||||
$logger = new $className($options);
|
||||
if (!$logger instanceof CakeLogInterface) {
|
||||
throw new CakeLogException(sprintf(
|
||||
__d('cake_dev', 'logger class %s does not implement a write method.'), $loggerName
|
||||
));
|
||||
throw new CakeLogException(
|
||||
__d('cake_dev', 'logger class %s does not implement a %s method.', $loggerName, 'write()')
|
||||
);
|
||||
}
|
||||
$this->_loaded[$name] = $logger;
|
||||
if ($enable) {
|
||||
|
@ -63,7 +63,9 @@ class LogEngineCollection extends ObjectCollection {
|
|||
*/
|
||||
protected static function _getLogger($loggerName) {
|
||||
list($plugin, $loggerName) = pluginSplit($loggerName, true);
|
||||
|
||||
if (substr($loggerName, -3) !== 'Log') {
|
||||
$loggerName .= 'Log';
|
||||
}
|
||||
App::uses($loggerName, $plugin . 'Log/Engine');
|
||||
if (!class_exists($loggerName)) {
|
||||
throw new CakeLogException(__d('cake_dev', 'Could not load class %s', $loggerName));
|
||||
|
|
|
@ -65,7 +65,7 @@ class AclBehavior extends ModelBehavior {
|
|||
$model->{$type} = ClassRegistry::init($type);
|
||||
}
|
||||
if (!method_exists($model, 'parentNode')) {
|
||||
trigger_error(__d('cake_dev', 'Callback parentNode() not defined in %s', $model->alias), E_USER_WARNING);
|
||||
trigger_error(__d('cake_dev', 'Callback %s not defined in %s', 'parentNode()', $model->alias), E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -628,19 +628,8 @@ class TreeBehavior extends ModelBehavior {
|
|||
$Model->updateAll(array($Model->escapeField($parent) => $missingParentAction), array($Model->escapeField($Model->primaryKey) => array_flip($missingParents)));
|
||||
}
|
||||
}
|
||||
$count = 1;
|
||||
foreach ($Model->find('all', array('conditions' => $scope, 'fields' => array($Model->primaryKey), 'order' => $left)) as $array) {
|
||||
$lft = $count++;
|
||||
$rght = $count++;
|
||||
$Model->create(false);
|
||||
$Model->id = $array[$Model->alias][$Model->primaryKey];
|
||||
$Model->save(array($left => $lft, $right => $rght), array('callbacks' => false, 'validate' => false));
|
||||
}
|
||||
foreach ($Model->find('all', array('conditions' => $scope, 'fields' => array($Model->primaryKey, $parent), 'order' => $left)) as $array) {
|
||||
$Model->create(false);
|
||||
$Model->id = $array[$Model->alias][$Model->primaryKey];
|
||||
$this->_setParent($Model, $array[$Model->alias][$parent]);
|
||||
}
|
||||
|
||||
$this->_recoverByParentId($Model);
|
||||
} else {
|
||||
$db = ConnectionManager::getDataSource($Model->useDbConfig);
|
||||
foreach ($Model->find('all', array('conditions' => $scope, 'fields' => array($Model->primaryKey, $parent), 'order' => $left)) as $array) {
|
||||
|
@ -655,6 +644,77 @@ class TreeBehavior extends ModelBehavior {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* _recoverByParentId
|
||||
*
|
||||
* Recursive helper function used by recover
|
||||
*
|
||||
* @param Model $Model
|
||||
* @param integer $counter
|
||||
* @param mixed $parentId
|
||||
* @return integer $counter
|
||||
*/
|
||||
protected function _recoverByParentId(Model $Model, $counter = 1, $parentId = null) {
|
||||
$params = array(
|
||||
'conditions' => array(
|
||||
$this->settings[$Model->alias]['parent'] => $parentId
|
||||
),
|
||||
'fields' => array($Model->primaryKey),
|
||||
'page' => 1,
|
||||
'limit' => 100,
|
||||
'order' => array($Model->primaryKey)
|
||||
);
|
||||
|
||||
$scope = $this->settings[$Model->alias]['scope'];
|
||||
if ($scope && ($scope !== '1 = 1' && $scope !== true)) {
|
||||
$conditions[] = $scope;
|
||||
}
|
||||
|
||||
$children = $Model->find('all', $params);
|
||||
$hasChildren = (bool)$children;
|
||||
|
||||
if (!is_null($parentId)) {
|
||||
if ($hasChildren) {
|
||||
$Model->updateAll(
|
||||
array($this->settings[$Model->alias]['left'] => $counter),
|
||||
array($Model->escapeField() => $parentId)
|
||||
);
|
||||
$counter++;
|
||||
} else {
|
||||
$Model->updateAll(
|
||||
array(
|
||||
$this->settings[$Model->alias]['left'] => $counter,
|
||||
$this->settings[$Model->alias]['right'] => $counter + 1
|
||||
),
|
||||
array($Model->escapeField() => $parentId)
|
||||
);
|
||||
$counter += 2;
|
||||
}
|
||||
}
|
||||
|
||||
while ($children) {
|
||||
foreach ($children as $row) {
|
||||
$counter = $this->_recoverByParentId($Model, $counter, $row[$Model->alias][$Model->primaryKey]);
|
||||
}
|
||||
|
||||
if (count($children) !== $params['limit']) {
|
||||
break;
|
||||
}
|
||||
$params['page']++;
|
||||
$children = $Model->find('all', $params);
|
||||
}
|
||||
|
||||
if (!is_null($parentId) && $hasChildren) {
|
||||
$Model->updateAll(
|
||||
array($this->settings[$Model->alias]['right'] => $counter),
|
||||
array($Model->escapeField() => $parentId)
|
||||
);
|
||||
$counter++;
|
||||
}
|
||||
|
||||
return $counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorder method.
|
||||
*
|
||||
|
@ -729,10 +789,9 @@ class TreeBehavior extends ModelBehavior {
|
|||
if ($node[$right] == $node[$left] + 1) {
|
||||
if ($delete) {
|
||||
return $Model->delete($id);
|
||||
} else {
|
||||
$Model->id = $id;
|
||||
return $Model->saveField($parent, null);
|
||||
}
|
||||
$Model->id = $id;
|
||||
return $Model->saveField($parent, null);
|
||||
} elseif ($node[$parent]) {
|
||||
list($parentNode) = array_values($Model->find('first', array(
|
||||
'conditions' => array($scope, $Model->escapeField() => $node[$parent]),
|
||||
|
|
|
@ -76,7 +76,7 @@ class BehaviorCollection extends ObjectCollection implements CakeEventListener {
|
|||
* @param string $behavior
|
||||
* @param array $config
|
||||
* @return void
|
||||
* @deprecated Replaced with load()
|
||||
* @deprecated Will be removed in 3.0. Replaced with load().
|
||||
*/
|
||||
public function attach($behavior, $config = array()) {
|
||||
return $this->load($behavior, $config);
|
||||
|
@ -103,7 +103,7 @@ class BehaviorCollection extends ObjectCollection implements CakeEventListener {
|
|||
* @throws MissingBehaviorException when a behavior could not be found.
|
||||
*/
|
||||
public function load($behavior, $config = array()) {
|
||||
if (is_array($config) && isset($config['className'])) {
|
||||
if (isset($config['className'])) {
|
||||
$alias = $behavior;
|
||||
$behavior = $config['className'];
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ class BehaviorCollection extends ObjectCollection implements CakeEventListener {
|
|||
*
|
||||
* @param string $name Name of behavior
|
||||
* @return void
|
||||
* @deprecated Use unload instead.
|
||||
* @deprecated Will be removed in 3.0. Use unload instead.
|
||||
*/
|
||||
public function detach($name) {
|
||||
return $this->unload($name);
|
||||
|
@ -228,7 +228,7 @@ class BehaviorCollection extends ObjectCollection implements CakeEventListener {
|
|||
$method = $this->hasMethod($method, true);
|
||||
|
||||
if ($strict && empty($method)) {
|
||||
trigger_error(__d('cake_dev', "BehaviorCollection::dispatchMethod() - Method %s not found in any attached behavior", $method), E_USER_WARNING);
|
||||
trigger_error(__d('cake_dev', '%s - Method %s not found in any attached behavior', 'BehaviorCollection::dispatchMethod()', $method), E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
if (empty($method)) {
|
||||
|
|
|
@ -476,7 +476,7 @@ class CakeSchema extends Object {
|
|||
continue;
|
||||
}
|
||||
if (!array_key_exists($table, $old)) {
|
||||
$tables[$table]['add'] = $fields;
|
||||
$tables[$table]['create'] = $fields;
|
||||
} else {
|
||||
$diff = $this->_arrayDiffAssoc($fields, $old[$table]);
|
||||
if (!empty($diff)) {
|
||||
|
|
|
@ -132,7 +132,7 @@ class CakeSession {
|
|||
self::$time = time();
|
||||
|
||||
$checkAgent = Configure::read('Session.checkAgent');
|
||||
if (($checkAgent === true || $checkAgent === null) && env('HTTP_USER_AGENT')) {
|
||||
if (env('HTTP_USER_AGENT')) {
|
||||
self::$_userAgent = md5(env('HTTP_USER_AGENT') . Configure::read('Security.salt'));
|
||||
}
|
||||
self::_setPath($base);
|
||||
|
@ -486,10 +486,7 @@ class CakeSession {
|
|||
if (!empty($sessionConfig['ini']) && is_array($sessionConfig['ini'])) {
|
||||
foreach ($sessionConfig['ini'] as $setting => $value) {
|
||||
if (ini_set($setting, $value) === false) {
|
||||
throw new CakeSessionException(sprintf(
|
||||
__d('cake_dev', 'Unable to configure the session, setting %s failed.'),
|
||||
$setting
|
||||
));
|
||||
throw new CakeSessionException(__d('cake_dev', 'Unable to configure the session, setting %s failed.', $setting));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,6 +130,15 @@ class Mysql extends DboSource {
|
|||
/**
|
||||
* Connects to the database using options in the given configuration array.
|
||||
*
|
||||
* MySQL supports a few additional options that other drivers do not:
|
||||
*
|
||||
* - `unix_socket` Set to the path of the MySQL sock file. Can be used in place
|
||||
* of host + port.
|
||||
* - `ssl_key` SSL key file for connecting via SSL. Must be combined with `ssl_cert`.
|
||||
* - `ssl_cert` The SSL certificate to use when connecting via SSL. Must be
|
||||
* combined with `ssl_key`.
|
||||
* - `ssl_ca` The certificate authority for SSL connections.
|
||||
*
|
||||
* @return boolean True if the database could be connected, else false
|
||||
* @throws MissingConnectionException
|
||||
*/
|
||||
|
@ -146,7 +155,13 @@ class Mysql extends DboSource {
|
|||
if (!empty($config['encoding'])) {
|
||||
$flags[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $config['encoding'];
|
||||
}
|
||||
|
||||
if (!empty($config['ssl_key']) && !empty($config['ssl_cert'])) {
|
||||
$flags[PDO::MYSQL_ATTR_SSL_KEY] = $config['ssl_key'];
|
||||
$flags[PDO::MYSQL_ATTR_SSL_CERT] = $config['ssl_cert'];
|
||||
}
|
||||
if (!empty($config['ssl_ca'])) {
|
||||
$flags[PDO::MYSQL_ATTR_SSL_CA] = $config['ssl_ca'];
|
||||
}
|
||||
if (empty($config['unix_socket'])) {
|
||||
$dsn = "mysql:host={$config['host']};port={$config['port']};dbname={$config['database']}";
|
||||
} else {
|
||||
|
@ -161,6 +176,11 @@ class Mysql extends DboSource {
|
|||
$flags
|
||||
);
|
||||
$this->connected = true;
|
||||
if (!empty($config['settings'])) {
|
||||
foreach ($config['settings'] as $key => $value) {
|
||||
$this->_execute("SET $key=$value");
|
||||
}
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
throw new MissingConnectionException(array(
|
||||
'class' => get_class($this),
|
||||
|
|
|
@ -131,6 +131,11 @@ class Postgres extends DboSource {
|
|||
if (!empty($config['schema'])) {
|
||||
$this->_execute('SET search_path TO ' . $config['schema']);
|
||||
}
|
||||
if (!empty($config['settings'])) {
|
||||
foreach ($config['settings'] as $key => $value) {
|
||||
$this->_execute("SET $key TO $value");
|
||||
}
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
throw new MissingConnectionException(array(
|
||||
'class' => get_class($this),
|
||||
|
|
|
@ -135,6 +135,11 @@ class Sqlserver extends DboSource {
|
|||
$flags
|
||||
);
|
||||
$this->connected = true;
|
||||
if (!empty($config['settings'])) {
|
||||
foreach ($config['settings'] as $key => $value) {
|
||||
$this->_execute("SET $key $value");
|
||||
}
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
throw new MissingConnectionException(array(
|
||||
'class' => get_class($this),
|
||||
|
|
|
@ -898,7 +898,7 @@ class DboSource extends DataSource {
|
|||
if (PHP_SAPI !== 'cli') {
|
||||
$controller = null;
|
||||
$View = new View($controller, false);
|
||||
$View->set('logs', array($this->configKeyName => $log));
|
||||
$View->set('sqlLogs', array($this->configKeyName => $log));
|
||||
echo $View->element('sql_dump', array('_forced_from_dbo_' => true));
|
||||
} else {
|
||||
foreach ($log['log'] as $k => $i) {
|
||||
|
@ -2489,7 +2489,7 @@ class DboSource extends DataSource {
|
|||
$keys = array_keys($value);
|
||||
if ($keys === array_values($keys)) {
|
||||
$count = count($value);
|
||||
if ($count === 1 && !preg_match("/\s+NOT$/", $key)) {
|
||||
if ($count === 1 && !preg_match('/\s+(?:NOT|\!=)$/', $key)) {
|
||||
$data = $this->_quoteFields($key) . ' = (';
|
||||
if ($quoteValues) {
|
||||
if (is_object($model)) {
|
||||
|
|
|
@ -1497,6 +1497,17 @@ class Model extends Object implements CakeEventListener {
|
|||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is a convenient wrapper class to create(false) and, as the name suggests, clears the id, data, and validation errors.
|
||||
*
|
||||
* @return always boolean TRUE upon success
|
||||
* @see Model::create()
|
||||
*/
|
||||
public function clear() {
|
||||
$this->create(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of fields from the database, and sets the current model
|
||||
* data (Model::$data) with the record found.
|
||||
|
@ -1575,7 +1586,8 @@ class Model extends Object implements CakeEventListener {
|
|||
* @param mixed $value Value of the field
|
||||
* @param boolean|array $validate Either a boolean, or an array.
|
||||
* If a boolean, indicates whether or not to validate before saving.
|
||||
* If an array, allows control of 'validate' and 'callbacks' options.
|
||||
* If an array, allows control of 'validate', 'callbacks' and 'counterCache' options.
|
||||
* See Model::save() for details of each options.
|
||||
* @return boolean See Model::save()
|
||||
* @see Model::save()
|
||||
* @link http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-savefield-string-fieldname-string-fieldvalue-validate-false
|
||||
|
@ -1604,13 +1616,17 @@ class Model extends Object implements CakeEventListener {
|
|||
* - fieldList: An array of fields you want to allow for saving.
|
||||
* - callbacks: Set to false to disable callbacks. Using 'before' or 'after'
|
||||
* will enable only those callbacks.
|
||||
* - `counterCache`: Boolean to control updating of counter caches (if any)
|
||||
*
|
||||
* @param array $fieldList List of fields to allow to be saved
|
||||
* @return mixed On success Model::$data if its not empty or true, false on failure
|
||||
* @link http://book.cakephp.org/2.0/en/models/saving-your-data.html
|
||||
*/
|
||||
public function save($data = null, $validate = true, $fieldList = array()) {
|
||||
$defaults = array('validate' => true, 'fieldList' => array(), 'callbacks' => true);
|
||||
$defaults = array(
|
||||
'validate' => true, 'fieldList' => array(),
|
||||
'callbacks' => true, 'counterCache' => true
|
||||
);
|
||||
$_whitelist = $this->whitelist;
|
||||
$fields = array();
|
||||
|
||||
|
@ -1749,7 +1765,7 @@ class Model extends Object implements CakeEventListener {
|
|||
}
|
||||
}
|
||||
|
||||
if ($success && !empty($this->belongsTo)) {
|
||||
if ($success && $options['counterCache'] && !empty($this->belongsTo)) {
|
||||
$this->updateCounterCache($cache, $created);
|
||||
}
|
||||
}
|
||||
|
@ -2030,7 +2046,9 @@ class Model extends Object implements CakeEventListener {
|
|||
* 'AssociatedModel' => array('field', 'otherfield')
|
||||
* )
|
||||
* }}}
|
||||
* - `deep`: see saveMany/saveAssociated
|
||||
* - `deep`: See saveMany/saveAssociated
|
||||
* - `callbacks`: See Model::save()
|
||||
* - `counterCache`: See Model::save()
|
||||
*
|
||||
* @param array $data Record data to save. This can be either a numerically-indexed array (for saving multiple
|
||||
* records of the same type), or an array indexed by association name.
|
||||
|
@ -2066,6 +2084,8 @@ class Model extends Object implements CakeEventListener {
|
|||
* Should be set to false if database/table does not support transactions.
|
||||
* - `fieldList`: Equivalent to the $fieldList parameter in Model::save()
|
||||
* - `deep`: If set to true, all associated data will be saved as well.
|
||||
* - `callbacks`: See Model::save()
|
||||
* - `counterCache`: See Model::save()
|
||||
*
|
||||
* @param array $data Record data to save. This should be a numerically-indexed array
|
||||
* @param array $options Options to use when saving record data, See $options above.
|
||||
|
@ -2179,6 +2199,8 @@ class Model extends Object implements CakeEventListener {
|
|||
* )
|
||||
* }}}
|
||||
* - `deep`: If set to true, not only directly associated data is saved, but deeper nested associated data as well.
|
||||
* - `callbacks`: See Model::save()
|
||||
* - `counterCache`: See Model::save()
|
||||
*
|
||||
* @param array $data Record data to save. This should be an array indexed by association name.
|
||||
* @param array $options Options to use when saving record data, See $options above.
|
||||
|
@ -2697,6 +2719,34 @@ class Model extends Object implements CakeEventListener {
|
|||
return null;
|
||||
}
|
||||
|
||||
return $this->_readDataSource($type, $query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from the datasource
|
||||
*
|
||||
* Model::_readDataSource() is used by all find() calls to read from the data source and can be overloaded to allow
|
||||
* caching of datasource calls.
|
||||
*
|
||||
* {{{
|
||||
* protected function _readDataSource($type, $query) {
|
||||
* $cacheName = md5(json_encode($query));
|
||||
* $cache = Cache::read($cacheName, 'cache-config-name');
|
||||
* if ($cache !== false) {
|
||||
* return $cache;
|
||||
* }
|
||||
*
|
||||
* $results = parent::_readDataSource($type, $query);
|
||||
* Cache::write($cacheName, $results, 'cache-config-name');
|
||||
* return $results;
|
||||
* }
|
||||
* }}}
|
||||
*
|
||||
* @param string $type Type of find operation (all / first / count / neighbors / list / threaded)
|
||||
* @param array $query Option fields (conditions / fields / joins / limit / offset / order / page / group / callbacks)
|
||||
* @return array
|
||||
*/
|
||||
protected function _readDataSource($type, $query) {
|
||||
$results = $this->getDataSource()->read($this, $query);
|
||||
$this->resetAssociations();
|
||||
|
||||
|
@ -2706,10 +2756,6 @@ class Model extends Object implements CakeEventListener {
|
|||
|
||||
$this->findQueryType = null;
|
||||
|
||||
if ($type === 'all') {
|
||||
return $results;
|
||||
}
|
||||
|
||||
if ($this->findMethods[$type] === true) {
|
||||
return $this->{'_find' . ucfirst($type)}('after', $query, $results);
|
||||
}
|
||||
|
@ -2732,7 +2778,7 @@ class Model extends Object implements CakeEventListener {
|
|||
(array)$query
|
||||
);
|
||||
|
||||
if ($type !== 'all' && $this->findMethods[$type] === true) {
|
||||
if ($this->findMethods[$type] === true) {
|
||||
$query = $this->{'_find' . ucfirst($type)}('before', $query);
|
||||
}
|
||||
|
||||
|
@ -2760,6 +2806,23 @@ class Model extends Object implements CakeEventListener {
|
|||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the before/after filter logic for find('all') operations. Only called by Model::find().
|
||||
*
|
||||
* @param string $state Either "before" or "after"
|
||||
* @param array $query
|
||||
* @param array $results
|
||||
* @return array
|
||||
* @see Model::find()
|
||||
*/
|
||||
protected function _findAll($state, $query, $results = array()) {
|
||||
if ($state === 'before') {
|
||||
return $query;
|
||||
} elseif ($state === 'after') {
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the before/after filter logic for find('first') operations. Only called by Model::find().
|
||||
*
|
||||
|
|
|
@ -26,13 +26,6 @@ App::uses('AppModel', 'Model');
|
|||
*/
|
||||
class Permission extends AppModel {
|
||||
|
||||
/**
|
||||
* Model name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name = 'Permission';
|
||||
|
||||
/**
|
||||
* Explicitly disable in-memory query caching
|
||||
*
|
||||
|
@ -81,7 +74,7 @@ class Permission extends AppModel {
|
|||
* @param string $action Action (defaults to *)
|
||||
* @return boolean Success (true if ARO has access to action in ACO, false otherwise)
|
||||
*/
|
||||
public function check($aro, $aco, $action = "*") {
|
||||
public function check($aro, $aco, $action = '*') {
|
||||
if (!$aro || !$aco) {
|
||||
return false;
|
||||
}
|
||||
|
@ -91,17 +84,29 @@ class Permission extends AppModel {
|
|||
$acoPath = $this->Aco->node($aco);
|
||||
|
||||
if (!$aroPath || !$acoPath) {
|
||||
trigger_error(__d('cake_dev', "DbAcl::check() - Failed ARO/ACO node lookup in permissions check. Node references:\nAro: ") . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING);
|
||||
trigger_error(__d('cake_dev',
|
||||
"%s - Failed ARO/ACO node lookup in permissions check. Node references:\nAro: %s\nAco: %s",
|
||||
'DbAcl::check()',
|
||||
print_r($aro, true),
|
||||
print_r($aco, true)),
|
||||
E_USER_WARNING
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$acoPath) {
|
||||
trigger_error(__d('cake_dev', "DbAcl::check() - Failed ACO node lookup in permissions check. Node references:\nAro: ") . print_r($aro, true) . "\nAco: " . print_r($aco, true), E_USER_WARNING);
|
||||
trigger_error(__d('cake_dev',
|
||||
"%s - Failed ACO node lookup in permissions check. Node references:\nAro: %s\nAco: %s",
|
||||
'DbAcl::check()',
|
||||
print_r($aro, true),
|
||||
print_r($aco, true)),
|
||||
E_USER_WARNING
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($action !== '*' && !in_array('_' . $action, $permKeys)) {
|
||||
trigger_error(__d('cake_dev', "ACO permissions key %s does not exist in DbAcl::check()", $action), E_USER_NOTICE);
|
||||
trigger_error(__d('cake_dev', "ACO permissions key %s does not exist in %s", $action, 'DbAcl::check()'), E_USER_NOTICE);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -166,20 +171,20 @@ class Permission extends AppModel {
|
|||
* @return boolean Success
|
||||
* @throws AclException on Invalid permission key.
|
||||
*/
|
||||
public function allow($aro, $aco, $actions = "*", $value = 1) {
|
||||
public function allow($aro, $aco, $actions = '*', $value = 1) {
|
||||
$perms = $this->getAclLink($aro, $aco);
|
||||
$permKeys = $this->getAcoKeys($this->schema());
|
||||
$save = array();
|
||||
|
||||
if (!$perms) {
|
||||
trigger_error(__d('cake_dev', 'DbAcl::allow() - Invalid node'), E_USER_WARNING);
|
||||
trigger_error(__d('cake_dev', '%s - Invalid node', 'DbAcl::allow()'), E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
if (isset($perms[0])) {
|
||||
$save = $perms[0][$this->alias];
|
||||
}
|
||||
|
||||
if ($actions === "*") {
|
||||
if ($actions === '*') {
|
||||
$save = array_combine($permKeys, array_pad(array(), count($permKeys), $value));
|
||||
} else {
|
||||
if (!is_array($actions)) {
|
||||
|
|
|
@ -238,7 +238,7 @@ class CakeRequest implements ArrayAccess {
|
|||
if ($qPosition !== false && strpos($_SERVER['REQUEST_URI'], '://') > $qPosition) {
|
||||
$uri = $_SERVER['REQUEST_URI'];
|
||||
} else {
|
||||
$uri = substr($_SERVER['REQUEST_URI'], strlen(FULL_BASE_URL));
|
||||
$uri = substr($_SERVER['REQUEST_URI'], strlen(Configure::read('App.fullBaseUrl')));
|
||||
}
|
||||
} elseif (isset($_SERVER['PHP_SELF']) && isset($_SERVER['SCRIPT_NAME'])) {
|
||||
$uri = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['PHP_SELF']);
|
||||
|
@ -424,10 +424,7 @@ class CakeRequest implements ArrayAccess {
|
|||
$ref = $forwarded;
|
||||
}
|
||||
|
||||
$base = '';
|
||||
if (defined('FULL_BASE_URL')) {
|
||||
$base = FULL_BASE_URL . $this->webroot;
|
||||
}
|
||||
$base = Configure::read('App.fullBaseUrl') . $this->webroot;
|
||||
if (!empty($ref) && !empty($base)) {
|
||||
if ($local && strpos($ref, $base) === 0) {
|
||||
$ref = substr($ref, strlen($base));
|
||||
|
@ -485,14 +482,21 @@ class CakeRequest implements ArrayAccess {
|
|||
}
|
||||
|
||||
/**
|
||||
* Check whether or not a Request is a certain type. Uses the built in detection rules
|
||||
* as well as additional rules defined with CakeRequest::addDetector(). Any detector can be called
|
||||
* Check whether or not a Request is a certain type.
|
||||
*
|
||||
* Uses the built in detection rules as well as additional rules
|
||||
* defined with CakeRequest::addDetector(). Any detector can be called
|
||||
* as `is($type)` or `is$Type()`.
|
||||
*
|
||||
* @param string $type The type of request you want to check.
|
||||
* @param string|array $type The type of request you want to check. If an array
|
||||
* this method will return true if the request matches any type.
|
||||
* @return boolean Whether or not the request is the type you are checking.
|
||||
*/
|
||||
public function is($type) {
|
||||
if (is_array($type)) {
|
||||
$result = array_map(array($this, 'is'), $type);
|
||||
return count(array_filter($result)) > 0;
|
||||
}
|
||||
$type = strtolower($type);
|
||||
if (!isset($this->_detectors[$type])) {
|
||||
return false;
|
||||
|
@ -521,6 +525,22 @@ class CakeRequest implements ArrayAccess {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a request matches all the given types.
|
||||
*
|
||||
* Allows you to test multiple types and union the results.
|
||||
* See CakeRequest::is() for how to add additional types and the
|
||||
* built-in types.
|
||||
*
|
||||
* @param array $types The types to check.
|
||||
* @return boolean Success.
|
||||
* @see CakeRequest::is()
|
||||
*/
|
||||
public function isAll(array $types) {
|
||||
$result = array_filter(array_map(array($this, 'is'), $types));
|
||||
return count($result) === count($types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new detector to the list of detectors that a request can use.
|
||||
* There are several different formats and types of detectors that can be set.
|
||||
|
@ -825,6 +845,20 @@ class CakeRequest implements ArrayAccess {
|
|||
return Hash::get($this->data, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely access the values in $this->params.
|
||||
*
|
||||
* @param string $name The name of the parameter to get.
|
||||
* @return mixed The value of the provided parameter. Will
|
||||
* return false if the parameter doesn't exist or is falsey.
|
||||
*/
|
||||
public function param($name) {
|
||||
if (!isset($this->params[$name])) {
|
||||
return false;
|
||||
}
|
||||
return $this->params[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from `php://input`. Useful when interacting with XML or JSON
|
||||
* request body content.
|
||||
|
|
|
@ -416,8 +416,10 @@ class CakeResponse {
|
|||
$this->_setContent();
|
||||
$this->_setContentLength();
|
||||
$this->_setContentType();
|
||||
foreach ($this->_headers as $header => $value) {
|
||||
$this->_sendHeader($header, $value);
|
||||
foreach ($this->_headers as $header => $values) {
|
||||
foreach ((array)$values as $value) {
|
||||
$this->_sendHeader($header, $value);
|
||||
}
|
||||
}
|
||||
if ($this->_file) {
|
||||
$this->_sendFile($this->_file, $this->_fileRange);
|
||||
|
@ -556,34 +558,42 @@ class CakeResponse {
|
|||
* @param string|array $header. An array of header strings or a single header string
|
||||
* - an associative array of "header name" => "header value" is also accepted
|
||||
* - an array of string headers is also accepted
|
||||
* @param string $value. The header value.
|
||||
* @param string|array $value. The header value(s)
|
||||
* @return array list of headers to be sent
|
||||
*/
|
||||
public function header($header = null, $value = null) {
|
||||
if ($header === null) {
|
||||
return $this->_headers;
|
||||
}
|
||||
if (is_array($header)) {
|
||||
foreach ($header as $h => $v) {
|
||||
if (is_numeric($h)) {
|
||||
$this->header($v);
|
||||
continue;
|
||||
}
|
||||
$this->_headers[$h] = trim($v);
|
||||
$headers = is_array($header) ? $header : array($header => $value);
|
||||
foreach ($headers as $header => $value) {
|
||||
if (is_numeric($header)) {
|
||||
list($header, $value) = array($value, null);
|
||||
}
|
||||
return $this->_headers;
|
||||
if (is_null($value)) {
|
||||
list($header, $value) = explode(':', $header, 2);
|
||||
}
|
||||
$this->_headers[$header] = is_array($value) ? array_map('trim', $value) : trim($value);
|
||||
}
|
||||
|
||||
if ($value !== null) {
|
||||
$this->_headers[$header] = $value;
|
||||
return $this->_headers;
|
||||
}
|
||||
|
||||
list($header, $value) = explode(':', $header, 2);
|
||||
$this->_headers[$header] = trim($value);
|
||||
return $this->_headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acccessor for the location header.
|
||||
*
|
||||
* Get/Set the Location header value.
|
||||
* @param null|string $url Either null to get the current location, or a string to set one.
|
||||
* @return string|null When setting the location null will be returned. When reading the location
|
||||
* a string of the current location header value (if any) will be returned.
|
||||
*/
|
||||
public function location($url = null) {
|
||||
if ($url === null) {
|
||||
$headers = $this->header();
|
||||
return isset($headers['Location']) ? $headers['Location'] : null;
|
||||
}
|
||||
$this->header('Location', $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Buffers the response message to be sent
|
||||
* if $content is null the current buffer is returned
|
||||
|
@ -602,7 +612,7 @@ class CakeResponse {
|
|||
* Sets the HTTP status code to be sent
|
||||
* if $code is null the current code is returned
|
||||
*
|
||||
* @param integer $code
|
||||
* @param integer $code the HTTP status code
|
||||
* @return integer current status code
|
||||
* @throws CakeException When an unknown status code is reached.
|
||||
*/
|
||||
|
@ -619,31 +629,47 @@ class CakeResponse {
|
|||
/**
|
||||
* Queries & sets valid HTTP response codes & messages.
|
||||
*
|
||||
* @param integer|array $code If $code is an integer, then the corresponding code/message is
|
||||
* returned if it exists, null if it does not exist. If $code is an array,
|
||||
* then the 'code' and 'message' keys of each nested array are added to the default
|
||||
* HTTP codes. Example:
|
||||
* @param integer|array $code If $code is an integer, then the corresponding code/message is
|
||||
* returned if it exists, null if it does not exist. If $code is an array, then the
|
||||
* keys are used as codes and the values as messages to add to the default HTTP
|
||||
* codes. The codes must be integers greater than 99 and less than 1000. Keep in
|
||||
* mind that the HTTP specification outlines that status codes begin with a digit
|
||||
* between 1 and 5, which defines the class of response the client is to expect.
|
||||
* Example:
|
||||
*
|
||||
* httpCodes(404); // returns array(404 => 'Not Found')
|
||||
*
|
||||
* httpCodes(array(
|
||||
* 701 => 'Unicorn Moved',
|
||||
* 800 => 'Unexpected Minotaur'
|
||||
* 381 => 'Unicorn Moved',
|
||||
* 555 => 'Unexpected Minotaur'
|
||||
* )); // sets these new values, and returns true
|
||||
*
|
||||
* httpCodes(array(
|
||||
* 0 => 'Nothing Here',
|
||||
* -1 => 'Reverse Infinity',
|
||||
* 12345 => 'Universal Password',
|
||||
* 'Hello' => 'World'
|
||||
* )); // throws an exception due to invalid codes
|
||||
*
|
||||
* For more on HTTP status codes see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1
|
||||
*
|
||||
* @return mixed associative array of the HTTP codes as keys, and the message
|
||||
* strings as values, or null of the given $code does not exist.
|
||||
* @throws CakeException If an attempt is made to add an invalid status code
|
||||
*/
|
||||
public function httpCodes($code = null) {
|
||||
if (empty($code)) {
|
||||
return $this->_statusCodes;
|
||||
}
|
||||
|
||||
if (is_array($code)) {
|
||||
$codes = array_keys($code);
|
||||
$min = min($codes);
|
||||
if (!is_int($min) || $min < 100 || max($codes) > 999) {
|
||||
throw new CakeException(__d('cake_dev', 'Invalid status code'));
|
||||
}
|
||||
$this->_statusCodes = $code + $this->_statusCodes;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isset($this->_statusCodes[$code])) {
|
||||
return null;
|
||||
}
|
||||
|
@ -724,9 +750,7 @@ class CakeResponse {
|
|||
}
|
||||
|
||||
foreach ($this->_mimeTypes as $alias => $types) {
|
||||
if (is_array($types) && in_array($ctype, $types)) {
|
||||
return $alias;
|
||||
} elseif (is_string($types) && $types == $ctype) {
|
||||
if (in_array($ctype, (array)$types)) {
|
||||
return $alias;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ class CakeSocket {
|
|||
*
|
||||
* Instead we need to handle those errors manually.
|
||||
*
|
||||
* @param int $code
|
||||
* @param integer $code
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
|
|
|
@ -318,6 +318,14 @@ class CakeEmail {
|
|||
'ISO-2022-JP-MS' => 'ISO-2022-JP'
|
||||
);
|
||||
|
||||
/**
|
||||
* Regex for email validation
|
||||
* If null, it will use built in regex
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_emailPattern = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
@ -521,6 +529,20 @@ class CakeEmail {
|
|||
return $this->headerCharset = $charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* EmailPattern setter/getter
|
||||
*
|
||||
* @param string $regex for email address validation
|
||||
* @return string|CakeEmail
|
||||
*/
|
||||
public function emailPattern($regex = null) {
|
||||
if ($regex === null) {
|
||||
return $this->_emailPattern;
|
||||
}
|
||||
$this->_emailPattern = $regex;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set email
|
||||
*
|
||||
|
@ -532,7 +554,7 @@ class CakeEmail {
|
|||
*/
|
||||
protected function _setEmail($varName, $email, $name) {
|
||||
if (!is_array($email)) {
|
||||
if (!Validation::email($email)) {
|
||||
if (!Validation::email($email, false, $this->_emailPattern)) {
|
||||
throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $email));
|
||||
}
|
||||
if ($name === null) {
|
||||
|
@ -546,7 +568,7 @@ class CakeEmail {
|
|||
if (is_int($key)) {
|
||||
$key = $value;
|
||||
}
|
||||
if (!Validation::email($key)) {
|
||||
if (!Validation::email($key, false, $this->_emailPattern)) {
|
||||
throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $key));
|
||||
}
|
||||
$list[$key] = $value;
|
||||
|
@ -586,7 +608,7 @@ class CakeEmail {
|
|||
*/
|
||||
protected function _addEmail($varName, $email, $name) {
|
||||
if (!is_array($email)) {
|
||||
if (!Validation::email($email)) {
|
||||
if (!Validation::email($email, false, $this->_emailPattern)) {
|
||||
throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $email));
|
||||
}
|
||||
if ($name === null) {
|
||||
|
@ -600,7 +622,7 @@ class CakeEmail {
|
|||
if (is_int($key)) {
|
||||
$key = $value;
|
||||
}
|
||||
if (!Validation::email($key)) {
|
||||
if (!Validation::email($key, false, $this->_emailPattern)) {
|
||||
throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $key));
|
||||
}
|
||||
$list[$key] = $value;
|
||||
|
@ -884,7 +906,7 @@ class CakeEmail {
|
|||
if (!class_exists($transportClassname)) {
|
||||
throw new SocketException(__d('cake_dev', 'Class "%s" not found.', $transportClassname));
|
||||
} elseif (!method_exists($transportClassname, 'send')) {
|
||||
throw new SocketException(__d('cake_dev', 'The "%s" do not have send method.', $transportClassname));
|
||||
throw new SocketException(__d('cake_dev', 'The "%s" does not have a %s method.', $transportClassname, 'send()'));
|
||||
}
|
||||
|
||||
return $this->_transportClass = new $transportClassname();
|
||||
|
@ -953,6 +975,15 @@ class CakeEmail {
|
|||
* 'contentDisposition' => false
|
||||
* ));
|
||||
* }}}
|
||||
*
|
||||
* Attach a file from string and specify additional properties:
|
||||
*
|
||||
* {{{
|
||||
* $email->attachments(array('custom_name.png' => array(
|
||||
* 'data' => file_get_contents('path/to/file'),
|
||||
* 'mimetype' => 'image/png'
|
||||
* ));
|
||||
* }}}
|
||||
*
|
||||
* The `contentId` key allows you to specify an inline attachment. In your email text, you
|
||||
* can use `<img src="cid:abc123" />` to display the image inline.
|
||||
|
@ -974,14 +1005,21 @@ class CakeEmail {
|
|||
$fileInfo = array('file' => $fileInfo);
|
||||
}
|
||||
if (!isset($fileInfo['file'])) {
|
||||
throw new SocketException(__d('cake_dev', 'File not specified.'));
|
||||
}
|
||||
$fileInfo['file'] = realpath($fileInfo['file']);
|
||||
if ($fileInfo['file'] === false || !file_exists($fileInfo['file'])) {
|
||||
throw new SocketException(__d('cake_dev', 'File not found: "%s"', $fileInfo['file']));
|
||||
}
|
||||
if (is_int($name)) {
|
||||
$name = basename($fileInfo['file']);
|
||||
if (!isset($fileInfo['data'])) {
|
||||
throw new SocketException(__d('cake_dev', 'No file or data specified.'));
|
||||
}
|
||||
if (is_int($name)) {
|
||||
throw new SocketException(__d('cake_dev', 'No filename specified.'));
|
||||
}
|
||||
$fileInfo['data'] = chunk_split(base64_encode($fileInfo['data']), 76, "\r\n");
|
||||
} else {
|
||||
$fileInfo['file'] = realpath($fileInfo['file']);
|
||||
if ($fileInfo['file'] === false || !file_exists($fileInfo['file'])) {
|
||||
throw new SocketException(__d('cake_dev', 'File not found: "%s"', $fileInfo['file']));
|
||||
}
|
||||
if (is_int($name)) {
|
||||
$name = basename($fileInfo['file']);
|
||||
}
|
||||
}
|
||||
if (!isset($fileInfo['mimetype'])) {
|
||||
$fileInfo['mimetype'] = 'application/octet-stream';
|
||||
|
@ -1074,11 +1112,21 @@ class CakeEmail {
|
|||
|
||||
$contents = $this->transportClass()->send($this);
|
||||
if (!empty($this->_config['log'])) {
|
||||
$level = LOG_DEBUG;
|
||||
$config = array(
|
||||
'level' => LOG_DEBUG,
|
||||
'scope' => 'email'
|
||||
);
|
||||
if ($this->_config['log'] !== true) {
|
||||
$level = $this->_config['log'];
|
||||
if (!is_array($this->_config['log'])) {
|
||||
$this->_config['log'] = array('level' => $this->_config['log']);
|
||||
}
|
||||
$config = array_merge($config, $this->_config['log']);
|
||||
}
|
||||
CakeLog::write($level, PHP_EOL . $contents['headers'] . PHP_EOL . $contents['message']);
|
||||
CakeLog::write(
|
||||
$config['level'],
|
||||
PHP_EOL . $contents['headers'] . PHP_EOL . $contents['message'],
|
||||
$config['scope']
|
||||
);
|
||||
}
|
||||
return $contents;
|
||||
}
|
||||
|
@ -1149,7 +1197,7 @@ class CakeEmail {
|
|||
$simpleMethods = array(
|
||||
'from', 'sender', 'to', 'replyTo', 'readReceipt', 'returnPath', 'cc', 'bcc',
|
||||
'messageId', 'domain', 'subject', 'viewRender', 'viewVars', 'attachments',
|
||||
'transport', 'emailFormat', 'theme', 'helpers'
|
||||
'transport', 'emailFormat', 'theme', 'helpers', 'emailPattern'
|
||||
);
|
||||
foreach ($simpleMethods as $method) {
|
||||
if (isset($config[$method])) {
|
||||
|
@ -1206,6 +1254,7 @@ class CakeEmail {
|
|||
$this->headerCharset = null;
|
||||
$this->_attachments = array();
|
||||
$this->_config = array();
|
||||
$this->_emailPattern = null;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -1376,7 +1425,7 @@ class CakeEmail {
|
|||
if (!empty($fileInfo['contentId'])) {
|
||||
continue;
|
||||
}
|
||||
$data = $this->_readFile($fileInfo['file']);
|
||||
$data = isset($fileInfo['data']) ? $fileInfo['data'] : $this->_readFile($fileInfo['file']);
|
||||
|
||||
$msg[] = '--' . $boundary;
|
||||
$msg[] = 'Content-Type: ' . $fileInfo['mimetype'];
|
||||
|
@ -1421,7 +1470,7 @@ class CakeEmail {
|
|||
if (empty($fileInfo['contentId'])) {
|
||||
continue;
|
||||
}
|
||||
$data = $this->_readFile($fileInfo['file']);
|
||||
$data = isset($fileInfo['data']) ? $fileInfo['data'] : $this->_readFile($fileInfo['file']);
|
||||
|
||||
$msg[] = '--' . $boundary;
|
||||
$msg[] = 'Content-Type: ' . $fileInfo['mimetype'];
|
||||
|
|
|
@ -96,6 +96,7 @@ class HttpSocket extends CakeSocket {
|
|||
'port' => 80,
|
||||
'timeout' => 30,
|
||||
'ssl_verify_peer' => true,
|
||||
'ssl_allow_self_signed' => false,
|
||||
'ssl_verify_depth' => 5,
|
||||
'ssl_verify_host' => true,
|
||||
'request' => array(
|
||||
|
@ -495,6 +496,19 @@ class HttpSocket extends CakeSocket {
|
|||
return $this->request($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Issues a PATCH request to the specified URI, query, and request.
|
||||
*
|
||||
* @param string|array $uri URI to request, See HttpSocket::_parseUri()
|
||||
* @param array $data Array of PATCH data keys and values.
|
||||
* @param array $request An indexed array with indexes such as 'method' or uri
|
||||
* @return mixed Result of request
|
||||
*/
|
||||
public function patch($uri = null, $data = array(), $request = array()) {
|
||||
$request = Hash::merge(array('method' => 'PATCH', 'uri' => $uri, 'body' => $data), $request);
|
||||
return $this->request($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Issues a DELETE request to the specified URI, query, and request.
|
||||
*
|
||||
|
@ -590,7 +604,7 @@ class HttpSocket extends CakeSocket {
|
|||
throw new SocketException(__d('cake_dev', 'Unknown authentication method.'));
|
||||
}
|
||||
if (!method_exists($authClass, 'authentication')) {
|
||||
throw new SocketException(sprintf(__d('cake_dev', 'The %s do not support authentication.'), $authClass));
|
||||
throw new SocketException(__d('cake_dev', 'The %s does not support authentication.', $authClass));
|
||||
}
|
||||
call_user_func_array("$authClass::authentication", array($this, &$this->_auth[$method]));
|
||||
}
|
||||
|
@ -619,7 +633,7 @@ class HttpSocket extends CakeSocket {
|
|||
throw new SocketException(__d('cake_dev', 'Unknown authentication method for proxy.'));
|
||||
}
|
||||
if (!method_exists($authClass, 'proxyAuthentication')) {
|
||||
throw new SocketException(sprintf(__d('cake_dev', 'The %s do not support proxy authentication.'), $authClass));
|
||||
throw new SocketException(__d('cake_dev', 'The %s does not support proxy authentication.', $authClass));
|
||||
}
|
||||
call_user_func_array("$authClass::proxyAuthentication", array($this, &$this->_proxy));
|
||||
}
|
||||
|
|
|
@ -56,6 +56,14 @@ class Router {
|
|||
*/
|
||||
public static $initialized = false;
|
||||
|
||||
/**
|
||||
* Contains the base string that will be applied to all generated URLs
|
||||
* For example `https://example.com`
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $_fullBaseUrl;
|
||||
|
||||
/**
|
||||
* List of action prefixes used in connected routes.
|
||||
* Includes admin prefix
|
||||
|
@ -551,7 +559,8 @@ class Router {
|
|||
$url = '/' . $url;
|
||||
}
|
||||
if (strpos($url, '?') !== false) {
|
||||
$url = substr($url, 0, strpos($url, '?'));
|
||||
list($url, $queryParameters) = explode('?', $url, 2);
|
||||
parse_str($queryParameters, $queryParameters);
|
||||
}
|
||||
|
||||
extract(self::_parseExtension($url));
|
||||
|
@ -572,6 +581,10 @@ class Router {
|
|||
if (!empty($ext) && !isset($out['ext'])) {
|
||||
$out['ext'] = $ext;
|
||||
}
|
||||
|
||||
if (!empty($queryParameters) && !isset($out['?'])) {
|
||||
$out['?'] = $queryParameters;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
@ -759,7 +772,7 @@ class Router {
|
|||
* cake relative URLs are required when using requestAction.
|
||||
* - `?` - Takes an array of query string parameters
|
||||
* - `#` - Allows you to set URL hash fragments.
|
||||
* - `full_base` - If true the `FULL_BASE_URL` constant will be prepended to generated URLs.
|
||||
* - `full_base` - If true the `Router::fullBaseUrl()` value will be prepended to generated URLs.
|
||||
*
|
||||
* @param string|array $url Cake-relative URL, like "/products/edit/92" or "/presidents/elect/4"
|
||||
* or an array specifying any of the following: 'controller', 'action',
|
||||
|
@ -796,8 +809,8 @@ class Router {
|
|||
|
||||
if (empty($url)) {
|
||||
$output = isset($path['here']) ? $path['here'] : '/';
|
||||
if ($full && defined('FULL_BASE_URL')) {
|
||||
$output = FULL_BASE_URL . $output;
|
||||
if ($full) {
|
||||
$output = self::fullBaseUrl() . $output;
|
||||
}
|
||||
return $output;
|
||||
} elseif (is_array($url)) {
|
||||
|
@ -860,7 +873,7 @@ class Router {
|
|||
$output = self::_handleNoRoute($url);
|
||||
}
|
||||
} else {
|
||||
if (preg_match('/:\/\/|^(javascript|mailto|tel|sms):|^\#/i', $url)) {
|
||||
if (preg_match('/^([a-z][a-z0-9.+\-]+:|:?\/\/|[#?])/i', $url)) {
|
||||
return $url;
|
||||
}
|
||||
if (substr($url, 0, 1) === '/') {
|
||||
|
@ -878,12 +891,12 @@ class Router {
|
|||
$output .= Inflector::underscore($params['controller']) . '/' . $url;
|
||||
}
|
||||
}
|
||||
$protocol = preg_match('#^[a-z][a-z0-9+-.]*\://#i', $output);
|
||||
$protocol = preg_match('#^[a-z][a-z0-9+\-.]*\://#i', $output);
|
||||
if ($protocol === 0) {
|
||||
$output = str_replace('//', '/', $base . '/' . $output);
|
||||
|
||||
if ($full && defined('FULL_BASE_URL')) {
|
||||
$output = FULL_BASE_URL . $output;
|
||||
if ($full) {
|
||||
$output = self::fullBaseUrl() . $output;
|
||||
}
|
||||
if (!empty($extension)) {
|
||||
$output = rtrim($output, '/');
|
||||
|
@ -892,6 +905,32 @@ class Router {
|
|||
return $output . $extension . self::queryString($q, array(), $escape) . $frag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the full base url that will be used as a prefix for generating
|
||||
* fully qualified URLs for this application. If not parameters are passed,
|
||||
* the currently configured value is returned.
|
||||
*
|
||||
* ## Note:
|
||||
*
|
||||
* If you change the configuration value ``App.fullBaseUrl`` during runtime
|
||||
* and expect the router to produce links using the new setting, you are
|
||||
* required to call this method passing such value again.
|
||||
*
|
||||
* @param string $base the prefix for URLs generated containing the domain.
|
||||
* For example: ``http://example.com``
|
||||
* @return string
|
||||
*/
|
||||
public static function fullBaseUrl($base = null) {
|
||||
if ($base !== null) {
|
||||
self::$_fullBaseUrl = $base;
|
||||
Configure::write('App.fullBaseUrl', $base);
|
||||
}
|
||||
if (empty(self::$_fullBaseUrl)) {
|
||||
self::$_fullBaseUrl = Configure::read('App.fullBaseUrl');
|
||||
}
|
||||
return self::$_fullBaseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* A special fallback method that handles URL arrays that cannot match
|
||||
* any defined routes.
|
||||
|
|
|
@ -703,8 +703,9 @@ class BasicsTest extends CakeTestCase {
|
|||
########## DEBUG ##########
|
||||
'this-is-a-test'
|
||||
###########################
|
||||
|
||||
EXPECTED;
|
||||
$expected = sprintf($expectedText, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 8);
|
||||
$expected = sprintf($expectedText, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 9);
|
||||
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
|
@ -766,9 +767,10 @@ EXPECTED;
|
|||
########## DEBUG ##########
|
||||
'<div>this-is-a-test</div>'
|
||||
###########################
|
||||
|
||||
EXPECTED;
|
||||
if (php_sapi_name() === 'cli') {
|
||||
$expected = sprintf($expectedText, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 17);
|
||||
$expected = sprintf($expectedText, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 18);
|
||||
} else {
|
||||
$expected = sprintf($expectedHtml, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 19);
|
||||
}
|
||||
|
@ -790,9 +792,10 @@ EXPECTED;
|
|||
########## DEBUG ##########
|
||||
'<div>this-is-a-test</div>'
|
||||
###########################
|
||||
|
||||
EXPECTED;
|
||||
if (php_sapi_name() === 'cli') {
|
||||
$expected = sprintf($expectedText, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 17);
|
||||
$expected = sprintf($expectedText, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 18);
|
||||
} else {
|
||||
$expected = sprintf($expectedHtml, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 19);
|
||||
}
|
||||
|
@ -806,8 +809,9 @@ EXPECTED;
|
|||
########## DEBUG ##########
|
||||
'<div>this-is-a-test</div>'
|
||||
###########################
|
||||
|
||||
EXPECTED;
|
||||
$expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 8);
|
||||
$expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 9);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
ob_start();
|
||||
|
@ -818,8 +822,9 @@ EXPECTED;
|
|||
########## DEBUG ##########
|
||||
'<div>this-is-a-test</div>'
|
||||
###########################
|
||||
|
||||
EXPECTED;
|
||||
$expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 8);
|
||||
$expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 9);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
ob_start();
|
||||
|
@ -830,8 +835,9 @@ EXPECTED;
|
|||
########## DEBUG ##########
|
||||
'<div>this-is-a-test</div>'
|
||||
###########################
|
||||
|
||||
EXPECTED;
|
||||
$expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 8);
|
||||
$expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 9);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
ob_start();
|
||||
|
@ -842,8 +848,9 @@ EXPECTED;
|
|||
########## DEBUG ##########
|
||||
false
|
||||
###########################
|
||||
|
||||
EXPECTED;
|
||||
$expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 8);
|
||||
$expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 9);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
|
@ -853,6 +860,7 @@ EXPECTED;
|
|||
* @return void
|
||||
*/
|
||||
public function testPr() {
|
||||
$this->skipIf(php_sapi_name() == 'cli', 'Skipping web test in cli mode');
|
||||
ob_start();
|
||||
pr('this is a test');
|
||||
$result = ob_get_clean();
|
||||
|
@ -866,6 +874,26 @@ EXPECTED;
|
|||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test pr()
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPrCli() {
|
||||
$this->skipIf(php_sapi_name() != 'cli', 'Skipping cli test in web mode');
|
||||
ob_start();
|
||||
pr('this is a test');
|
||||
$result = ob_get_clean();
|
||||
$expected = "\nthis is a test\n";
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
ob_start();
|
||||
pr(array('this' => 'is', 'a' => 'test'));
|
||||
$result = ob_get_clean();
|
||||
$expected = "\nArray\n(\n [this] => is\n [a] => test\n)\n\n";
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test stripslashes_deep()
|
||||
*
|
||||
|
|
|
@ -48,6 +48,9 @@ class CacheTest extends CakeTestCase {
|
|||
*/
|
||||
public function tearDown() {
|
||||
parent::tearDown();
|
||||
Cache::drop('latest');
|
||||
Cache::drop('page');
|
||||
Cache::drop('archive');
|
||||
Configure::write('Cache.disable', $this->_cacheDisable);
|
||||
Cache::config('default', $this->_defaultCacheConfig['settings']);
|
||||
}
|
||||
|
@ -129,6 +132,10 @@ class CacheTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testInvalidConfig() {
|
||||
// In debug mode it would auto create the folder.
|
||||
$debug = Configure::read('debug');
|
||||
Configure::write('debug', 0);
|
||||
|
||||
Cache::config('invalid', array(
|
||||
'engine' => 'File',
|
||||
'duration' => '+1 year',
|
||||
|
@ -138,6 +145,8 @@ class CacheTest extends CakeTestCase {
|
|||
'random' => 'wii'
|
||||
));
|
||||
Cache::read('Test', 'invalid');
|
||||
|
||||
Configure::write('debug', $debug);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -237,6 +246,67 @@ class CacheTest extends CakeTestCase {
|
|||
Cache::config('sessions', $_cacheConfigSessions['settings']);
|
||||
}
|
||||
|
||||
/**
|
||||
* testGroupConfigs method
|
||||
*/
|
||||
public function testGroupConfigs() {
|
||||
Cache::config('latest', array(
|
||||
'duration' => 300,
|
||||
'engine' => 'File',
|
||||
'groups' => array(
|
||||
'posts', 'comments',
|
||||
),
|
||||
));
|
||||
|
||||
$expected = array(
|
||||
'posts' => array('latest'),
|
||||
'comments' => array('latest'),
|
||||
);
|
||||
$result = Cache::groupConfigs();
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = Cache::groupConfigs('posts');
|
||||
$this->assertEquals(array('posts' => array('latest')), $result);
|
||||
|
||||
Cache::config('page', array(
|
||||
'duration' => 86400,
|
||||
'engine' => 'File',
|
||||
'groups' => array(
|
||||
'posts', 'archive'
|
||||
),
|
||||
));
|
||||
|
||||
$result = Cache::groupConfigs();
|
||||
$expected = array(
|
||||
'posts' => array('latest', 'page'),
|
||||
'comments' => array('latest'),
|
||||
'archive' => array('page'),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = Cache::groupConfigs('archive');
|
||||
$this->assertEquals(array('archive' => array('page')), $result);
|
||||
|
||||
Cache::config('archive', array(
|
||||
'duration' => 86400 * 30,
|
||||
'engine' => 'File',
|
||||
'groups' => array(
|
||||
'posts', 'archive', 'comments',
|
||||
),
|
||||
));
|
||||
|
||||
$result = Cache::groupConfigs('archive');
|
||||
$this->assertEquals(array('archive' => array('archive', 'page')), $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testGroupConfigsThrowsException method
|
||||
* @expectedException CacheException
|
||||
*/
|
||||
public function testGroupConfigsThrowsException() {
|
||||
Cache::groupConfigs('bogus');
|
||||
}
|
||||
|
||||
/**
|
||||
* test that configured returns an array of the currently configured cache
|
||||
* settings
|
||||
|
|
|
@ -381,20 +381,19 @@ class FileEngineTest extends CakeTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* check that FileEngine generates an error when a configured Path does not exist.
|
||||
* check that FileEngine does not generate an error when a configured Path does not exist in debug mode.
|
||||
*
|
||||
* @expectedException PHPUnit_Framework_Error_Warning
|
||||
* @return void
|
||||
*/
|
||||
public function testErrorWhenPathDoesNotExist() {
|
||||
$this->skipIf(is_dir(TMP . 'tests' . DS . 'file_failure'), 'Cannot run test directory exists.');
|
||||
public function testPathDoesNotExist() {
|
||||
$this->skipIf(is_dir(TMP . 'tests' . DS . 'autocreate'), 'Cannot run if test directory exists.');
|
||||
|
||||
Cache::config('failure', array(
|
||||
Cache::config('autocreate', array(
|
||||
'engine' => 'File',
|
||||
'path' => TMP . 'tests' . DS . 'file_failure'
|
||||
'path' => TMP . 'tests' . DS . 'autocreate'
|
||||
));
|
||||
|
||||
Cache::drop('failure');
|
||||
Cache::drop('autocreate');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue