mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
Merge branch '2.x' into 2.next
This commit is contained in:
commit
837741db66
33 changed files with 575 additions and 56 deletions
|
@ -6,6 +6,7 @@ php:
|
||||||
- 5.5
|
- 5.5
|
||||||
- 5.6
|
- 5.6
|
||||||
- 7.0
|
- 7.0
|
||||||
|
- 7.1
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- DB=mysql
|
- DB=mysql
|
||||||
|
@ -22,7 +23,7 @@ matrix:
|
||||||
- php: 5.4
|
- php: 5.4
|
||||||
env: DB=sqlite
|
env: DB=sqlite
|
||||||
|
|
||||||
- php: 5.4
|
- php: 7.0
|
||||||
env: PHPCS=1
|
env: PHPCS=1
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,9 @@ class PagesController extends AppController {
|
||||||
* Displays a view
|
* Displays a view
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws ForbiddenException When a directory traversal attempt.
|
||||||
* @throws NotFoundException When the view file could not be found
|
* @throws NotFoundException When the view file could not be found
|
||||||
* or MissingViewException in debug mode.
|
* or MissingViewException in debug mode.
|
||||||
*/
|
*/
|
||||||
public function display() {
|
public function display() {
|
||||||
$path = func_get_args();
|
$path = func_get_args();
|
||||||
|
@ -51,6 +52,9 @@ class PagesController extends AppController {
|
||||||
if (!$count) {
|
if (!$count) {
|
||||||
return $this->redirect('/');
|
return $this->redirect('/');
|
||||||
}
|
}
|
||||||
|
if (in_array('..', $path, true) || in_array('.', $path, true)) {
|
||||||
|
throw new ForbiddenException();
|
||||||
|
}
|
||||||
$page = $subpage = $title_for_layout = null;
|
$page = $subpage = $title_for_layout = null;
|
||||||
|
|
||||||
if (!empty($path[0])) {
|
if (!empty($path[0])) {
|
||||||
|
|
|
@ -9,4 +9,4 @@ build.dir = build
|
||||||
dist.dir = dist
|
dist.dir = dist
|
||||||
|
|
||||||
# Server
|
# Server
|
||||||
pirum.dir = /home/cakephp/www-live/pear.cakephp.org
|
pirum.dir = /var/lib/dokku/data/storage/pear
|
||||||
|
|
|
@ -213,10 +213,10 @@
|
||||||
-->
|
-->
|
||||||
<target name="distribute" depends="prepare" description="Upload pear packages to pear.cakephp.org">
|
<target name="distribute" depends="prepare" description="Upload pear packages to pear.cakephp.org">
|
||||||
<echo msg="Uploading tgz file to cakephp.org" />
|
<echo msg="Uploading tgz file to cakephp.org" />
|
||||||
<exec command="scp ${dist.dir}/${pear.package}.tgz cakephp@pear.cakephp.org:${pirum.dir}" dir="." checkreturn="true" />
|
<exec command="scp ${dist.dir}/${pear.package}.tgz root@new.cakephp.org:${pirum.dir}" dir="." checkreturn="true" />
|
||||||
|
|
||||||
<echo msg="Adding new release to pirum" />
|
<echo msg="Rebuilding pear.cakephp.org container" />
|
||||||
<exec command="ssh cakephp@pear.cakephp.org pirum add ${pirum.dir} ${pirum.dir}/${pear.package}.tgz" checkreturn="true" />
|
<exec command="ssh root@new.cakephp.org dokku ps:rebuild pear" checkreturn="true" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="codestyle" description="Check codestyle (human readable format)">
|
<target name="codestyle" description="Check codestyle (human readable format)">
|
||||||
|
|
|
@ -616,4 +616,18 @@ class Cache {
|
||||||
self::set(null, $config);
|
self::set(null, $config);
|
||||||
return $success;
|
return $success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the engine attached to a specific configuration name.
|
||||||
|
*
|
||||||
|
* @param string $config Optional string configuration name to get an engine for. Defaults to 'default'.
|
||||||
|
* @return null|CacheEngine Null if the engine has not been initialized or the engine.
|
||||||
|
*/
|
||||||
|
public static function engine($config = 'default') {
|
||||||
|
if (self::isInitialized($config)) {
|
||||||
|
return self::$_engines[$config];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ class CommandListShell extends AppShell {
|
||||||
$this->out(" -working: " . rtrim(APP, DS));
|
$this->out(" -working: " . rtrim(APP, DS));
|
||||||
$this->out(" -root: " . rtrim(ROOT, DS));
|
$this->out(" -root: " . rtrim(ROOT, DS));
|
||||||
$this->out(" -core: " . rtrim(CORE_PATH, DS));
|
$this->out(" -core: " . rtrim(CORE_PATH, DS));
|
||||||
|
$this->out(" -webroot: " . rtrim(WWW_ROOT, DS));
|
||||||
$this->out("");
|
$this->out("");
|
||||||
$this->out(__d('cake_console', "<info>Changing Paths:</info>"), 2);
|
$this->out(__d('cake_console', "<info>Changing Paths:</info>"), 2);
|
||||||
$this->out(__d('cake_console', "Your working path should be the same as your application path. To change your path use the '-app' param."));
|
$this->out(__d('cake_console', "Your working path should be the same as your application path. To change your path use the '-app' param."));
|
||||||
|
|
|
@ -129,12 +129,19 @@ class ShellDispatcher {
|
||||||
define('APP', $this->params['working'] . DS);
|
define('APP', $this->params['working'] . DS);
|
||||||
}
|
}
|
||||||
if (!defined('WWW_ROOT')) {
|
if (!defined('WWW_ROOT')) {
|
||||||
define('WWW_ROOT', APP . $this->params['webroot'] . DS);
|
if (!$this->_isAbsolutePath($this->params['webroot'])) {
|
||||||
|
$webroot = realpath(APP . $this->params['webroot']);
|
||||||
|
} else {
|
||||||
|
$webroot = $this->params['webroot'];
|
||||||
|
}
|
||||||
|
define('WWW_ROOT', $webroot . DS);
|
||||||
}
|
}
|
||||||
if (!defined('TMP') && !is_dir(APP . 'tmp')) {
|
if (!defined('TMP') && !is_dir(APP . 'tmp')) {
|
||||||
define('TMP', CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Console' . DS . 'Templates' . DS . 'skel' . DS . 'tmp' . DS);
|
define('TMP', CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Console' . DS . 'Templates' . DS . 'skel' . DS . 'tmp' . DS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// $boot is used by Cake/bootstrap.php file
|
||||||
|
$boot = file_exists(ROOT . DS . APP_DIR . DS . 'Config' . DS . 'bootstrap.php');
|
||||||
require CORE_PATH . 'Cake' . DS . 'bootstrap.php';
|
require CORE_PATH . 'Cake' . DS . 'bootstrap.php';
|
||||||
|
|
||||||
if (!file_exists(APP . 'Config' . DS . 'core.php')) {
|
if (!file_exists(APP . 'Config' . DS . 'core.php')) {
|
||||||
|
@ -305,25 +312,45 @@ class ShellDispatcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($params['app'][0] === '/' || preg_match('/([a-z])(:)/i', $params['app'], $matches)) {
|
if ($this->_isAbsolutePath($params['app'])) {
|
||||||
$params['root'] = dirname($params['app']);
|
$params['root'] = dirname($params['app']);
|
||||||
} elseif (strpos($params['app'], '/')) {
|
} elseif (strpos($params['app'], '/')) {
|
||||||
$params['root'] .= '/' . dirname($params['app']);
|
$params['root'] .= '/' . dirname($params['app']);
|
||||||
}
|
}
|
||||||
|
$isWindowsAppPath = $this->_isWindowsPath($params['app']);
|
||||||
$params['app'] = basename($params['app']);
|
$params['app'] = basename($params['app']);
|
||||||
$params['working'] = rtrim($params['root'], '/');
|
$params['working'] = rtrim($params['root'], '/');
|
||||||
if (!$isWin || !preg_match('/^[A-Z]:$/i', $params['app'])) {
|
if (!$isWin || !preg_match('/^[A-Z]:$/i', $params['app'])) {
|
||||||
$params['working'] .= '/' . $params['app'];
|
$params['working'] .= '/' . $params['app'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($matches[0]) || !empty($isWin)) {
|
if ($isWindowsAppPath || !empty($isWin)) {
|
||||||
$params = str_replace('/', '\\', $params);
|
$params = str_replace('/', '\\', $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->params = $params + $this->params;
|
$this->params = $params + $this->params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given path is absolute or relative.
|
||||||
|
*
|
||||||
|
* @param string $path absolute or relative path.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function _isAbsolutePath($path) {
|
||||||
|
return $path[0] === '/' || $this->_isWindowsPath($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given path is Window OS path.
|
||||||
|
*
|
||||||
|
* @param string $path absolute path.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function _isWindowsPath($path) {
|
||||||
|
return preg_match('/([a-z])(:)/i', $path) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses out the paths from from the argv
|
* Parses out the paths from from the argv
|
||||||
*
|
*
|
||||||
|
@ -332,7 +359,7 @@ class ShellDispatcher {
|
||||||
*/
|
*/
|
||||||
protected function _parsePaths($args) {
|
protected function _parsePaths($args) {
|
||||||
$parsed = array();
|
$parsed = array();
|
||||||
$keys = array('-working', '--working', '-app', '--app', '-root', '--root');
|
$keys = array('-working', '--working', '-app', '--app', '-root', '--root', '-webroot', '--webroot');
|
||||||
$args = (array)$args;
|
$args = (array)$args;
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
while (($index = array_search($key, $args)) !== false) {
|
while (($index = array_search($key, $args)) !== false) {
|
||||||
|
|
|
@ -32,6 +32,7 @@ class PagesController extends AppController {
|
||||||
* Displays a view
|
* Displays a view
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws ForbiddenException When a directory traversal attempt.
|
||||||
* @throws NotFoundException When the view file could not be found
|
* @throws NotFoundException When the view file could not be found
|
||||||
* or MissingViewException in debug mode.
|
* or MissingViewException in debug mode.
|
||||||
*/
|
*/
|
||||||
|
@ -42,6 +43,9 @@ class PagesController extends AppController {
|
||||||
if (!$count) {
|
if (!$count) {
|
||||||
return $this->redirect('/');
|
return $this->redirect('/');
|
||||||
}
|
}
|
||||||
|
if (in_array('..', $path, true) || in_array('.', $path, true)) {
|
||||||
|
throw new ForbiddenException();
|
||||||
|
}
|
||||||
$page = $subpage = $title_for_layout = null;
|
$page = $subpage = $title_for_layout = null;
|
||||||
|
|
||||||
if (!empty($path[0])) {
|
if (!empty($path[0])) {
|
||||||
|
|
|
@ -741,7 +741,7 @@ class AuthComponent extends Component {
|
||||||
$this->Session->delete('Auth.redirect');
|
$this->Session->delete('Auth.redirect');
|
||||||
|
|
||||||
if (Router::normalize($redir) === Router::normalize($this->loginAction)) {
|
if (Router::normalize($redir) === Router::normalize($this->loginAction)) {
|
||||||
$redir = $this->loginRedirect;
|
$redir = $this->loginRedirect ?: '/';
|
||||||
}
|
}
|
||||||
} elseif ($this->loginRedirect) {
|
} elseif ($this->loginRedirect) {
|
||||||
$redir = $this->loginRedirect;
|
$redir = $this->loginRedirect;
|
||||||
|
|
|
@ -283,8 +283,11 @@ class CookieComponent extends Component {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($names[1]) && is_array($this->_values[$this->name][$key])) {
|
if (!empty($names[1])) {
|
||||||
return Hash::get($this->_values[$this->name][$key], $names[1]);
|
if (is_array($this->_values[$this->name][$key])) {
|
||||||
|
return Hash::get($this->_values[$this->name][$key], $names[1]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return $this->_values[$this->name][$key];
|
return $this->_values[$this->name][$key];
|
||||||
}
|
}
|
||||||
|
@ -336,7 +339,7 @@ class CookieComponent extends Component {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$names = explode('.', $key, 2);
|
$names = explode('.', $key, 2);
|
||||||
if (isset($this->_values[$this->name][$names[0]])) {
|
if (isset($this->_values[$this->name][$names[0]]) && is_array($this->_values[$this->name][$names[0]])) {
|
||||||
$this->_values[$this->name][$names[0]] = Hash::remove($this->_values[$this->name][$names[0]], $names[1]);
|
$this->_values[$this->name][$names[0]] = Hash::remove($this->_values[$this->name][$names[0]], $names[1]);
|
||||||
}
|
}
|
||||||
$this->_delete('[' . implode('][', $names) . ']');
|
$this->_delete('[' . implode('][', $names) . ']');
|
||||||
|
|
|
@ -269,6 +269,7 @@ class L10n {
|
||||||
'hi' => array('language' => 'Hindi', 'locale' => 'hin', 'localeFallback' => 'hin', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
'hi' => array('language' => 'Hindi', 'locale' => 'hin', 'localeFallback' => 'hin', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
'hr' => array('language' => 'Croatian', 'locale' => 'hrv', 'localeFallback' => 'hrv', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
'hr' => array('language' => 'Croatian', 'locale' => 'hrv', 'localeFallback' => 'hrv', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
'hu' => array('language' => 'Hungarian', 'locale' => 'hun', 'localeFallback' => 'hun', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
'hu' => array('language' => 'Hungarian', 'locale' => 'hun', 'localeFallback' => 'hun', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
|
'hu-hu' => array('language' => 'Hungarian (Hungary)', 'locale' => 'hun', 'localeFallback' => 'hun', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
'hy' => array('language' => 'Armenian - Armenia', 'locale' => 'hye', 'localeFallback' => 'hye', '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'),
|
'id' => 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'),
|
'is' => array('language' => 'Icelandic', 'locale' => 'isl', 'localeFallback' => 'isl', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
|
@ -286,6 +287,7 @@ class L10n {
|
||||||
'li' => array('language' => 'Limburgish', 'locale' => 'lim', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
'li' => array('language' => 'Limburgish', 'locale' => 'lim', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
'lt' => array('language' => 'Lithuanian', 'locale' => 'lit', 'localeFallback' => 'lit', 'charset' => 'utf-8', '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'),
|
'lv' => array('language' => 'Latvian', 'locale' => 'lav', 'localeFallback' => 'lav', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
|
'lv-lv' => array('language' => 'Latvian (Latvia)', 'locale' => 'lav', 'localeFallback' => 'lav', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
'mk' => array('language' => 'FYRO Macedonian', 'locale' => 'mkd', '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'),
|
'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'),
|
'ms' => array('language' => 'Malaysian', 'locale' => 'msa', 'localeFallback' => 'msa', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
|
|
|
@ -39,13 +39,18 @@ class AclNode extends Model {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param bool|int|string|array $id Set this ID for this model on startup,
|
||||||
|
* can also be an array of options, see above.
|
||||||
|
* @param string $table Name of database table to use.
|
||||||
|
* @param string $ds DataSource connection name.
|
||||||
*/
|
*/
|
||||||
public function __construct() {
|
public function __construct($id = false, $table = null, $ds = null) {
|
||||||
$config = Configure::read('Acl.database');
|
$config = Configure::read('Acl.database');
|
||||||
if (isset($config)) {
|
if (isset($config)) {
|
||||||
$this->useDbConfig = $config;
|
$this->useDbConfig = $config;
|
||||||
}
|
}
|
||||||
parent::__construct();
|
parent::__construct($id, $table, $ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -112,11 +112,12 @@ class TreeBehavior extends ModelBehavior {
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function _setChildrenLevel(Model $Model, $id) {
|
protected function _setChildrenLevel(Model $Model, $id) {
|
||||||
$settings = $Model->Behaviors->Tree->settings[$Model->alias];
|
$settings = $this->settings[$Model->alias];
|
||||||
$primaryKey = $Model->primaryKey;
|
$primaryKey = $Model->primaryKey;
|
||||||
$depths = array($id => (int)$Model->data[$Model->alias][$settings['level']]);
|
$depths = array($id => (int)$Model->data[$Model->alias][$settings['level']]);
|
||||||
|
|
||||||
$children = $Model->children(
|
$children = $this->children(
|
||||||
|
$Model,
|
||||||
$id,
|
$id,
|
||||||
false,
|
false,
|
||||||
array($primaryKey, $settings['parent'], $settings['level']),
|
array($primaryKey, $settings['parent'], $settings['level']),
|
||||||
|
|
|
@ -51,17 +51,19 @@ class DboSource extends DataSource {
|
||||||
public $alias = 'AS ';
|
public $alias = 'AS ';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches result from query parsing operations. Cached results for both DboSource::name() and
|
* Caches result from query parsing operations. Cached results for both DboSource::name() and DboSource::fields()
|
||||||
* DboSource::conditions() will be stored here. Method caching uses `md5()`. If you have
|
* will be stored here.
|
||||||
* problems with collisions, set DboSource::$cacheMethods to false.
|
*
|
||||||
|
* Method caching uses `md5` (by default) to construct cache keys. If you have problems with collisions,
|
||||||
|
* try a different hashing algorithm by overriding DboSource::cacheMethodHasher or set DboSource::$cacheMethods to false.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
public static $methodCache = array();
|
public static $methodCache = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not to cache the results of DboSource::name() and DboSource::conditions()
|
* Whether or not to cache the results of DboSource::name() and DboSource::fields() into the memory cache.
|
||||||
* into the memory cache. Set to false to disable the use of the memory cache.
|
* Set to false to disable the use of the memory cache.
|
||||||
*
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
|
@ -786,10 +788,72 @@ class DboSource extends DataSource {
|
||||||
if ($value === null) {
|
if ($value === null) {
|
||||||
return (isset(static::$methodCache[$method][$key])) ? static::$methodCache[$method][$key] : null;
|
return (isset(static::$methodCache[$method][$key])) ? static::$methodCache[$method][$key] : null;
|
||||||
}
|
}
|
||||||
|
if (!$this->cacheMethodFilter($method, $key, $value)) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
$this->_methodCacheChange = true;
|
$this->_methodCacheChange = true;
|
||||||
return static::$methodCache[$method][$key] = $value;
|
return static::$methodCache[$method][$key] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters to apply to the results of `name` and `fields`. When the filter for a given method does not return `true`
|
||||||
|
* then the result is not added to the memory cache.
|
||||||
|
*
|
||||||
|
* Some examples:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* // For method fields, do not cache values that contain floats
|
||||||
|
* if ($method === 'fields') {
|
||||||
|
* $hasFloat = preg_grep('/(\d+)?\.\d+/', $value);
|
||||||
|
*
|
||||||
|
* return count($hasFloat) === 0;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* return true;
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* // For method name, do not cache values that have the name created
|
||||||
|
* if ($method === 'name') {
|
||||||
|
* return preg_match('/^`created`$/', $value) !== 1;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* return true;
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* // For method name, do not cache values that have the key 472551d38e1f8bbc78d7dfd28106166f
|
||||||
|
* if ($key === '472551d38e1f8bbc78d7dfd28106166f') {
|
||||||
|
* return false;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* return true;
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param string $method Name of the method being cached.
|
||||||
|
* @param string $key The key name for the cache operation.
|
||||||
|
* @param mixed $value The value to cache into memory.
|
||||||
|
* @return bool Whether or not to cache
|
||||||
|
*/
|
||||||
|
public function cacheMethodFilter($method, $key, $value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hashes a given value.
|
||||||
|
*
|
||||||
|
* Method caching uses `md5` (by default) to construct cache keys. If you have problems with collisions,
|
||||||
|
* try a different hashing algorithm or set DboSource::$cacheMethods to false.
|
||||||
|
*
|
||||||
|
* @param string $value Value to hash
|
||||||
|
* @return string Hashed value
|
||||||
|
* @see http://php.net/manual/en/function.hash-algos.php
|
||||||
|
* @see http://softwareengineering.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed
|
||||||
|
*/
|
||||||
|
public function cacheMethodHasher($value) {
|
||||||
|
return md5($value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a quoted name of $data for use in an SQL statement.
|
* Returns a quoted name of $data for use in an SQL statement.
|
||||||
* Strips fields out of SQL functions before quoting.
|
* Strips fields out of SQL functions before quoting.
|
||||||
|
@ -815,7 +879,7 @@ class DboSource extends DataSource {
|
||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
$cacheKey = md5($this->startQuote . $data . $this->endQuote);
|
$cacheKey = $this->cacheMethodHasher($this->startQuote . $data . $this->endQuote);
|
||||||
if ($return = $this->cacheMethod(__FUNCTION__, $cacheKey)) {
|
if ($return = $this->cacheMethod(__FUNCTION__, $cacheKey)) {
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
@ -2533,7 +2597,7 @@ class DboSource extends DataSource {
|
||||||
$Model->schemaName,
|
$Model->schemaName,
|
||||||
$Model->table
|
$Model->table
|
||||||
);
|
);
|
||||||
$cacheKey = md5(serialize($cacheKey));
|
$cacheKey = $this->cacheMethodHasher(serialize($cacheKey));
|
||||||
if ($return = $this->cacheMethod(__FUNCTION__, $cacheKey)) {
|
if ($return = $this->cacheMethod(__FUNCTION__, $cacheKey)) {
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -538,4 +538,65 @@ class CacheTest extends CakeTestCase {
|
||||||
$result = Cache::add('test_add_key', 'test data 2', 'default');
|
$result = Cache::add('test_add_key', 'test data 2', 'default');
|
||||||
$this->assertFalse($result);
|
$this->assertFalse($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test engine method.
|
||||||
|
*
|
||||||
|
* Success, default engine.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testEngineSuccess() {
|
||||||
|
$actual = Cache::engine();
|
||||||
|
$this->assertInstanceOf('CacheEngine', $actual);
|
||||||
|
|
||||||
|
$actual = Cache::engine('default');
|
||||||
|
$this->assertInstanceOf('CacheEngine', $actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test engine method.
|
||||||
|
*
|
||||||
|
* Success, memcached engine.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testEngineSuccessMemcached() {
|
||||||
|
$this->skipIf(!class_exists('Memcached'), 'Memcached is not installed or configured properly.');
|
||||||
|
|
||||||
|
// @codingStandardsIgnoreStart
|
||||||
|
$socket = @fsockopen('127.0.0.1', 11211, $errno, $errstr, 1);
|
||||||
|
// @codingStandardsIgnoreEnd
|
||||||
|
$this->skipIf(!$socket, 'Memcached is not running.');
|
||||||
|
fclose($socket);
|
||||||
|
|
||||||
|
Cache::config('memcached', array(
|
||||||
|
'engine' => 'Memcached',
|
||||||
|
'prefix' => 'cake_',
|
||||||
|
'duration' => 3600
|
||||||
|
));
|
||||||
|
|
||||||
|
$actual = Cache::engine('memcached');
|
||||||
|
$this->assertInstanceOf('MemcachedEngine', $actual);
|
||||||
|
|
||||||
|
$this->assertTrue($actual->add('test_add_key', 'test data', 10));
|
||||||
|
$this->assertFalse($actual->add('test_add_key', 'test data', 10));
|
||||||
|
$this->assertTrue($actual->delete('test_add_key'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test engine method.
|
||||||
|
*
|
||||||
|
* Failure.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testEngineFailure() {
|
||||||
|
$actual = Cache::engine('some_config_that_does_not_exist');
|
||||||
|
$this->assertNull($actual);
|
||||||
|
|
||||||
|
Configure::write('Cache.disable', true);
|
||||||
|
$actual = Cache::engine();
|
||||||
|
$this->assertNull($actual);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,9 +137,8 @@ class ShellDispatcherTest extends CakeTestCase {
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testParseParams() {
|
public function testParseParamsAppWorkingAbsolute() {
|
||||||
$Dispatcher = new TestShellDispatcher();
|
$Dispatcher = new TestShellDispatcher();
|
||||||
|
|
||||||
$params = array(
|
$params = array(
|
||||||
'/cake/1.2.x.x/cake/console/cake.php',
|
'/cake/1.2.x.x/cake/console/cake.php',
|
||||||
'bake',
|
'bake',
|
||||||
|
@ -156,7 +155,15 @@ class ShellDispatcherTest extends CakeTestCase {
|
||||||
);
|
);
|
||||||
$Dispatcher->parseParams($params);
|
$Dispatcher->parseParams($params);
|
||||||
$this->assertEquals($expected, $Dispatcher->params);
|
$this->assertEquals($expected, $Dispatcher->params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testParseParams method
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testParseParamsNone() {
|
||||||
|
$Dispatcher = new TestShellDispatcher();
|
||||||
$params = array('cake.php');
|
$params = array('cake.php');
|
||||||
$expected = array(
|
$expected = array(
|
||||||
'app' => 'app',
|
'app' => 'app',
|
||||||
|
@ -167,7 +174,15 @@ class ShellDispatcherTest extends CakeTestCase {
|
||||||
$Dispatcher->params = $Dispatcher->args = array();
|
$Dispatcher->params = $Dispatcher->args = array();
|
||||||
$Dispatcher->parseParams($params);
|
$Dispatcher->parseParams($params);
|
||||||
$this->assertEquals($expected, $Dispatcher->params);
|
$this->assertEquals($expected, $Dispatcher->params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testParseParams method
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testParseParamsApp() {
|
||||||
|
$Dispatcher = new TestShellDispatcher();
|
||||||
$params = array(
|
$params = array(
|
||||||
'cake.php',
|
'cake.php',
|
||||||
'-app',
|
'-app',
|
||||||
|
@ -182,7 +197,15 @@ class ShellDispatcherTest extends CakeTestCase {
|
||||||
$Dispatcher->params = $Dispatcher->args = array();
|
$Dispatcher->params = $Dispatcher->args = array();
|
||||||
$Dispatcher->parseParams($params);
|
$Dispatcher->parseParams($params);
|
||||||
$this->assertEquals($expected, $Dispatcher->params);
|
$this->assertEquals($expected, $Dispatcher->params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testParseParams method
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testParseParamsAppWorkingRelative() {
|
||||||
|
$Dispatcher = new TestShellDispatcher();
|
||||||
$params = array(
|
$params = array(
|
||||||
'./cake.php',
|
'./cake.php',
|
||||||
'bake',
|
'bake',
|
||||||
|
@ -191,17 +214,24 @@ class ShellDispatcherTest extends CakeTestCase {
|
||||||
'-working',
|
'-working',
|
||||||
'/cake/1.2.x.x/cake/console'
|
'/cake/1.2.x.x/cake/console'
|
||||||
);
|
);
|
||||||
|
|
||||||
$expected = array(
|
$expected = array(
|
||||||
'app' => 'new',
|
'app' => 'new',
|
||||||
'webroot' => 'webroot',
|
'webroot' => 'webroot',
|
||||||
'working' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH) . DS . 'new'),
|
'working' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH) . DS . 'new'),
|
||||||
'root' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH))
|
'root' => str_replace('\\', DS, dirname(CAKE_CORE_INCLUDE_PATH))
|
||||||
);
|
);
|
||||||
|
|
||||||
$Dispatcher->params = $Dispatcher->args = array();
|
$Dispatcher->params = $Dispatcher->args = array();
|
||||||
$Dispatcher->parseParams($params);
|
$Dispatcher->parseParams($params);
|
||||||
$this->assertEquals($expected, $Dispatcher->params);
|
$this->assertEquals($expected, $Dispatcher->params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testParseParams method
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testParseParams() {
|
||||||
|
$Dispatcher = new TestShellDispatcher();
|
||||||
|
|
||||||
$params = array(
|
$params = array(
|
||||||
'./console/cake.php',
|
'./console/cake.php',
|
||||||
|
|
|
@ -48,14 +48,15 @@ class ControllerAuthorizeTest extends CakeTestCase {
|
||||||
* testControllerTypeError
|
* testControllerTypeError
|
||||||
*
|
*
|
||||||
* @expectedException PHPUnit_Framework_Error
|
* @expectedException PHPUnit_Framework_Error
|
||||||
* @throws PHPUnit_Framework_Error
|
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws PHPUnit_Framework_Error
|
||||||
*/
|
*/
|
||||||
public function testControllerTypeError() {
|
public function testControllerTypeError() {
|
||||||
try {
|
try {
|
||||||
$this->auth->controller(new StdClass());
|
$this->auth->controller(new StdClass());
|
||||||
} catch (Throwable $t) {
|
$this->fail('No exception thrown');
|
||||||
throw new PHPUnit_Framework_Error($t);
|
} catch (TypeError $e) {
|
||||||
|
throw new PHPUnit_Framework_Error('Raised an error', 100, __FILE__, __LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1652,6 +1652,20 @@ class AuthComponentTest extends CakeTestCase {
|
||||||
Router::reload();
|
Router::reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that redirectUrl() returns '/' if loginRedirect is empty
|
||||||
|
* and Auth.redirect is the login page.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testRedirectUrlWithoutLoginRedirect() {
|
||||||
|
$this->Auth->loginRedirect = null;
|
||||||
|
$this->Auth->Session->write('Auth.redirect', '/users/login');
|
||||||
|
$this->Auth->request->addParams(Router::parse('/users/login'));
|
||||||
|
$result = $this->Auth->redirectUrl();
|
||||||
|
$this->assertEquals('/', $result);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test password hashing
|
* test password hashing
|
||||||
*
|
*
|
||||||
|
|
|
@ -153,6 +153,24 @@ class CookieComponentTest extends CakeTestCase {
|
||||||
$this->assertEquals($expected, $data);
|
$this->assertEquals($expected, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test read operations on corrupted cookie data.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testReadCorruptedCookieData() {
|
||||||
|
$this->Cookie->type('aes');
|
||||||
|
$this->Cookie->key = sha1('some bad key');
|
||||||
|
|
||||||
|
$data = $this->_implode(array('name' => 'jill', 'age' => 24));
|
||||||
|
// Corrupt the cookie data by slicing some bytes off.
|
||||||
|
$_COOKIE['CakeTestCookie'] = array(
|
||||||
|
'BadData' => substr(Security::encrypt($data, $this->Cookie->key), 0, -5)
|
||||||
|
);
|
||||||
|
$this->assertFalse($this->Cookie->check('BadData.name'), 'Key does not exist');
|
||||||
|
$this->assertNull($this->Cookie->read('BadData.name'), 'Key does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* testReadPlainCookieData
|
* testReadPlainCookieData
|
||||||
*
|
*
|
||||||
|
@ -169,6 +187,19 @@ class CookieComponentTest extends CakeTestCase {
|
||||||
$this->assertEquals($expected, $data);
|
$this->assertEquals($expected, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test read array keys from string data.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testReadNestedDataFromStrings() {
|
||||||
|
$_COOKIE['CakeTestCookie'] = array(
|
||||||
|
'User' => 'bad data'
|
||||||
|
);
|
||||||
|
$this->assertFalse($this->Cookie->check('User.name'), 'No key');
|
||||||
|
$this->assertNull($this->Cookie->read('User.name'), 'No key');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test read() after switching the cookie name.
|
* test read() after switching the cookie name.
|
||||||
*
|
*
|
||||||
|
@ -207,6 +238,7 @@ class CookieComponentTest extends CakeTestCase {
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testWriteWithFalseyValue() {
|
public function testWriteWithFalseyValue() {
|
||||||
|
$this->skipIf(!extension_loaded('mcrypt'), 'No Mcrypt, skipping.');
|
||||||
$this->Cookie->type('aes');
|
$this->Cookie->type('aes');
|
||||||
$this->Cookie->key = 'qSI232qs*&sXOw!adre@34SAv!@*(XSL#$%)asGb$@11~_+!@#HKis~#^';
|
$this->Cookie->key = 'qSI232qs*&sXOw!adre@34SAv!@*(XSL#$%)asGb$@11~_+!@#HKis~#^';
|
||||||
|
|
||||||
|
@ -451,6 +483,25 @@ class CookieComponentTest extends CakeTestCase {
|
||||||
$this->assertNull($data);
|
$this->assertNull($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test delete() on corrupted/truncated cookie data.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testDeleteCorruptedCookieData() {
|
||||||
|
$this->Cookie->type('aes');
|
||||||
|
$this->Cookie->key = sha1('some bad key');
|
||||||
|
|
||||||
|
$data = $this->_implode(array('name' => 'jill', 'age' => 24));
|
||||||
|
// Corrupt the cookie data by slicing some bytes off.
|
||||||
|
$_COOKIE['CakeTestCookie'] = array(
|
||||||
|
'BadData' => substr(Security::encrypt($data, $this->Cookie->key), 0, -5)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertNull($this->Cookie->delete('BadData.name'));
|
||||||
|
$this->assertNull($this->Cookie->read('BadData.name'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* testReadingCookieArray
|
* testReadingCookieArray
|
||||||
*
|
*
|
||||||
|
|
|
@ -75,4 +75,21 @@ class PagesControllerTest extends CakeTestCase {
|
||||||
$Pages = new PagesController(new CakeRequest(null, false), new CakeResponse());
|
$Pages = new PagesController(new CakeRequest(null, false), new CakeResponse());
|
||||||
$Pages->display('non_existing_page');
|
$Pages->display('non_existing_page');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test directory traversal protection
|
||||||
|
*
|
||||||
|
* @expectedException ForbiddenException
|
||||||
|
* @expectedExceptionCode 403
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testDirectoryTraversalProtection() {
|
||||||
|
App::build(array(
|
||||||
|
'View' => array(
|
||||||
|
CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS
|
||||||
|
)
|
||||||
|
));
|
||||||
|
$Pages = new PagesController(new CakeRequest(null, false), new CakeResponse());
|
||||||
|
$Pages->display('..', 'Posts', 'index');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -450,16 +450,16 @@ class ConfigureTest extends CakeTestCase {
|
||||||
* test reader() throwing exceptions on missing interface.
|
* test reader() throwing exceptions on missing interface.
|
||||||
*
|
*
|
||||||
* @expectedException PHPUnit_Framework_Error
|
* @expectedException PHPUnit_Framework_Error
|
||||||
* @throws PHPUnit_Framework_Error
|
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws PHPUnit_Framework_Error
|
||||||
*/
|
*/
|
||||||
public function testReaderExceptionOnIncorrectClass() {
|
public function testReaderExceptionOnIncorrectClass() {
|
||||||
$reader = new StdClass();
|
$reader = new StdClass();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Configure::config('test', $reader);
|
Configure::config('test', $reader);
|
||||||
} catch (Throwable $t) {
|
} catch (TypeError $e) {
|
||||||
throw new PHPUnit_Framework_Error($t);
|
throw new PHPUnit_Framework_Error('Raised an error', 100, __FILE__, __LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2909,14 +2909,15 @@ SQL;
|
||||||
* testDropSchemaNoSchema method
|
* testDropSchemaNoSchema method
|
||||||
*
|
*
|
||||||
* @expectedException PHPUnit_Framework_Error
|
* @expectedException PHPUnit_Framework_Error
|
||||||
* @throws PHPUnit_Framework_Error
|
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws PHPUnit_Framework_Error
|
||||||
*/
|
*/
|
||||||
public function testDropSchemaNoSchema() {
|
public function testDropSchemaNoSchema() {
|
||||||
try {
|
try {
|
||||||
$this->Dbo->dropSchema(null);
|
$this->Dbo->dropSchema(null);
|
||||||
} catch (Throwable $t) {
|
$this->fail('No exception');
|
||||||
throw new PHPUnit_Framework_Error($t);
|
} catch (TypeError $e) {
|
||||||
|
throw new PHPUnit_Framework_Error('Raised an error', 100, __FILE__, __LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,52 @@ class DboSecondTestSource extends DboSource {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DboThirdTestSource
|
||||||
|
*
|
||||||
|
* @package Cake.Test.Case.Model.Datasource
|
||||||
|
*/
|
||||||
|
class DboThirdTestSource extends DboSource {
|
||||||
|
|
||||||
|
public function connect($config = array()) {
|
||||||
|
$this->connected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cacheMethodHasher($value) {
|
||||||
|
return hash('sha1', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DboFourthTestSource
|
||||||
|
*
|
||||||
|
* @package Cake.Test.Case.Model.Datasource
|
||||||
|
*/
|
||||||
|
class DboFourthTestSource extends DboSource {
|
||||||
|
|
||||||
|
public function connect($config = array()) {
|
||||||
|
$this->connected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cacheMethodFilter($method, $key, $value) {
|
||||||
|
if ($method === 'name') {
|
||||||
|
if ($value === '`menus`') {
|
||||||
|
return false;
|
||||||
|
} elseif ($key === '1fca740733997f1ebbedacfc7678592a') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} elseif ($method === 'fields') {
|
||||||
|
$endsWithName = preg_grep('/`name`$/', $value);
|
||||||
|
|
||||||
|
return count($endsWithName) === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DboSourceTest class
|
* DboSourceTest class
|
||||||
*
|
*
|
||||||
|
@ -737,6 +783,106 @@ class DboSourceTest extends CakeTestCase {
|
||||||
$this->assertNull($result);
|
$this->assertNull($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that cacheMethodFilter does not filter by default.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testCacheMethodFilter() {
|
||||||
|
$method = 'name';
|
||||||
|
$key = '49d9207adfce6df1dd3ee8c30c434414';
|
||||||
|
$value = '`menus`';
|
||||||
|
$actual = $this->testDb->cacheMethodFilter($method, $key, $value);
|
||||||
|
|
||||||
|
$this->assertTrue($actual);
|
||||||
|
|
||||||
|
$method = 'fields';
|
||||||
|
$key = '2b57253ab1fffb3e95fa4f95299220b1';
|
||||||
|
$value = array("`Menu`.`id`", "`Menu`.`name`");
|
||||||
|
$actual = $this->testDb->cacheMethodFilter($method, $key, $value);
|
||||||
|
|
||||||
|
$this->assertTrue($actual);
|
||||||
|
|
||||||
|
$method = 'non-existing';
|
||||||
|
$key = '';
|
||||||
|
$value = '``';
|
||||||
|
$actual = $this->testDb->cacheMethodFilter($method, $key, $value);
|
||||||
|
|
||||||
|
$this->assertTrue($actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that cacheMethodFilter can be overridden to do actual filtering.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testCacheMethodFilterOverridden() {
|
||||||
|
$testDb = new DboFourthTestSource();
|
||||||
|
|
||||||
|
$method = 'name';
|
||||||
|
$key = '49d9207adfce6df1dd3ee8c30c434414';
|
||||||
|
$value = '`menus`';
|
||||||
|
$actual = $testDb->cacheMethodFilter($method, $key, $value);
|
||||||
|
|
||||||
|
$this->assertFalse($actual);
|
||||||
|
|
||||||
|
$method = 'name';
|
||||||
|
$key = '1fca740733997f1ebbedacfc7678592a';
|
||||||
|
$value = '`Menu`.`id`';
|
||||||
|
$actual = $testDb->cacheMethodFilter($method, $key, $value);
|
||||||
|
|
||||||
|
$this->assertFalse($actual);
|
||||||
|
|
||||||
|
$method = 'fields';
|
||||||
|
$key = '2b57253ab1fffb3e95fa4f95299220b1';
|
||||||
|
$value = array("`Menu`.`id`", "`Menu`.`name`");
|
||||||
|
$actual = $testDb->cacheMethodFilter($method, $key, $value);
|
||||||
|
|
||||||
|
$this->assertFalse($actual);
|
||||||
|
|
||||||
|
$method = 'name';
|
||||||
|
$key = 'd2bc458620afb092c61ab4383b7475e0';
|
||||||
|
$value = '`Menu`';
|
||||||
|
$actual = $testDb->cacheMethodFilter($method, $key, $value);
|
||||||
|
|
||||||
|
$this->assertTrue($actual);
|
||||||
|
|
||||||
|
$method = 'non-existing';
|
||||||
|
$key = '';
|
||||||
|
$value = '``';
|
||||||
|
$actual = $testDb->cacheMethodFilter($method, $key, $value);
|
||||||
|
|
||||||
|
$this->assertTrue($actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that cacheMethodHasher uses md5 by default.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testCacheMethodHasher() {
|
||||||
|
$name = 'Model.fieldlbqndkezcoapfgirmjsh';
|
||||||
|
$actual = $this->testDb->cacheMethodHasher($name);
|
||||||
|
$expected = '4a45dc9ed52f98c393d04ac424ee5078';
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that cacheMethodHasher can be overridden to use a different hashing algorithm.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testCacheMethodHasherOverridden() {
|
||||||
|
$testDb = new DboThirdTestSource();
|
||||||
|
|
||||||
|
$name = 'Model.fieldlbqndkezcoapfgirmjsh';
|
||||||
|
$actual = $testDb->cacheMethodHasher($name);
|
||||||
|
$expected = 'beb8b6469359285b7c2865dce0ef743feb16cb71';
|
||||||
|
|
||||||
|
$this->assertEquals($expected, $actual);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that rare collisions do not happen with method caching
|
* Test that rare collisions do not happen with method caching
|
||||||
*
|
*
|
||||||
|
|
|
@ -2224,14 +2224,15 @@ class ModelValidationTest extends BaseModelTest {
|
||||||
* Test that type hint exception is thrown
|
* Test that type hint exception is thrown
|
||||||
*
|
*
|
||||||
* @expectedException PHPUnit_Framework_Error
|
* @expectedException PHPUnit_Framework_Error
|
||||||
* @throws PHPUnit_Framework_Error
|
|
||||||
* @return void
|
* @return void
|
||||||
|
* @throws PHPUnit_Framework_Error
|
||||||
*/
|
*/
|
||||||
public function testValidatorTypehintException() {
|
public function testValidatorTypehintException() {
|
||||||
try {
|
try {
|
||||||
new ModelValidator('asdasds');
|
new ModelValidator('asdasds');
|
||||||
} catch (Throwable $t) {
|
$this->fail('No exeption raised');
|
||||||
throw new PHPUnit_Framework_Error($t);
|
} catch (TypeError $e) {
|
||||||
|
throw new PHPUnit_Framework_Error('Raised an error', 100, __FILE__, __LINE__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ class ClassRegistryTest extends CakeTestCase {
|
||||||
$this->assertSame($Tag, $TagCopy);
|
$this->assertSame($Tag, $TagCopy);
|
||||||
|
|
||||||
$NewTag = ClassRegistry::init(array('class' => 'RegisterArticleTag', 'alias' => 'NewTag'));
|
$NewTag = ClassRegistry::init(array('class' => 'RegisterArticleTag', 'alias' => 'NewTag'));
|
||||||
$this->assertInstanceOf('RegisterArticleTag', $Tag);
|
$this->assertInstanceOf('RegisterArticleTag', $NewTag);
|
||||||
|
|
||||||
$NewTagCopy = ClassRegistry::init(array('class' => 'RegisterArticleTag', 'alias' => 'NewTag'));
|
$NewTagCopy = ClassRegistry::init(array('class' => 'RegisterArticleTag', 'alias' => 'NewTag'));
|
||||||
|
|
||||||
|
@ -182,6 +182,35 @@ class ClassRegistryTest extends CakeTestCase {
|
||||||
$this->assertEquals('ParentCategory', $ParentCategory->alias);
|
$this->assertEquals('ParentCategory', $ParentCategory->alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that init() can make models with alias set properly
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testAddModelWithAlias() {
|
||||||
|
$tag = ClassRegistry::init(array('class' => 'RegisterArticleTag', 'alias' => 'NewTag'));
|
||||||
|
$this->assertInstanceOf('RegisterArticleTag', $tag);
|
||||||
|
$this->assertSame('NewTag', $tag->alias);
|
||||||
|
$this->assertSame('RegisterArticleTag', $tag->name);
|
||||||
|
|
||||||
|
$newTag = ClassRegistry::init(array('class' => 'RegisterArticleTag', 'alias' => 'OtherTag'));
|
||||||
|
$this->assertInstanceOf('RegisterArticleTag', $tag);
|
||||||
|
$this->assertSame('OtherTag', $newTag->alias);
|
||||||
|
$this->assertSame('RegisterArticleTag', $newTag->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that init() can make the Aco models with alias set properly
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testAddModelWithAliasAco() {
|
||||||
|
$aco = ClassRegistry::init(array('class' => 'Aco', 'alias' => 'CustomAco'));
|
||||||
|
$this->assertInstanceOf('Aco', $aco);
|
||||||
|
$this->assertSame('Aco', $aco->name);
|
||||||
|
$this->assertSame('CustomAco', $aco->alias);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* testClassRegistryFlush method
|
* testClassRegistryFlush method
|
||||||
*
|
*
|
||||||
|
|
|
@ -155,6 +155,24 @@ class DebuggerTest extends CakeTestCase {
|
||||||
$this->assertContains('$wrong = ''', $result[3], 'Context should be HTML escaped.');
|
$this->assertContains('$wrong = ''', $result[3], 'Context should be HTML escaped.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test encodes error messages
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testOutputEncodeDescription() {
|
||||||
|
set_error_handler('Debugger::showError');
|
||||||
|
$this->_restoreError = true;
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
$a = array();
|
||||||
|
$b = $a['<script>alert(1)</script>'];
|
||||||
|
$result = ob_get_clean();
|
||||||
|
|
||||||
|
$this->assertNotContains('<script>alert(1)', $result);
|
||||||
|
$this->assertContains('<script>alert(1)', $result);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that changes in output formats using Debugger::output() change the templates used.
|
* Tests that changes in output formats using Debugger::output() change the templates used.
|
||||||
*
|
*
|
||||||
|
|
|
@ -328,6 +328,7 @@ class SecurityTest extends CakeTestCase {
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testEncryptDecrypt() {
|
public function testEncryptDecrypt() {
|
||||||
|
$this->skipIf(!extension_loaded('mcrypt'), 'This test requires mcrypt to be installed');
|
||||||
$txt = 'The quick brown fox';
|
$txt = 'The quick brown fox';
|
||||||
$key = 'This key is longer than 32 bytes long.';
|
$key = 'This key is longer than 32 bytes long.';
|
||||||
$result = Security::encrypt($txt, $key);
|
$result = Security::encrypt($txt, $key);
|
||||||
|
@ -342,6 +343,7 @@ class SecurityTest extends CakeTestCase {
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testDecryptKeyFailure() {
|
public function testDecryptKeyFailure() {
|
||||||
|
$this->skipIf(!extension_loaded('mcrypt'), 'This test requires mcrypt to be installed');
|
||||||
$txt = 'The quick brown fox';
|
$txt = 'The quick brown fox';
|
||||||
$key = 'This key is longer than 32 bytes long.';
|
$key = 'This key is longer than 32 bytes long.';
|
||||||
Security::encrypt($txt, $key);
|
Security::encrypt($txt, $key);
|
||||||
|
@ -356,6 +358,7 @@ class SecurityTest extends CakeTestCase {
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testDecryptHmacFailure() {
|
public function testDecryptHmacFailure() {
|
||||||
|
$this->skipIf(!extension_loaded('mcrypt'), 'This test requires mcrypt to be installed');
|
||||||
$txt = 'The quick brown fox';
|
$txt = 'The quick brown fox';
|
||||||
$key = 'This key is quite long and works well.';
|
$key = 'This key is quite long and works well.';
|
||||||
$salt = 'this is a delicious salt!';
|
$salt = 'this is a delicious salt!';
|
||||||
|
@ -372,6 +375,7 @@ class SecurityTest extends CakeTestCase {
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testDecryptHmacSaltFailure() {
|
public function testDecryptHmacSaltFailure() {
|
||||||
|
$this->skipIf(!extension_loaded('mcrypt'), 'This test requires mcrypt to be installed');
|
||||||
$txt = 'The quick brown fox';
|
$txt = 'The quick brown fox';
|
||||||
$key = 'This key is quite long and works well.';
|
$key = 'This key is quite long and works well.';
|
||||||
$salt = 'this is a delicious salt!';
|
$salt = 'this is a delicious salt!';
|
||||||
|
@ -400,6 +404,7 @@ class SecurityTest extends CakeTestCase {
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testEncryptDecryptFalseyData() {
|
public function testEncryptDecryptFalseyData() {
|
||||||
|
$this->skipIf(!extension_loaded('mcrypt'), 'This test requires mcrypt to be installed');
|
||||||
$key = 'This is a key that is long enough to be ok.';
|
$key = 'This is a key that is long enough to be ok.';
|
||||||
|
|
||||||
$result = Security::encrypt('', $key);
|
$result = Security::encrypt('', $key);
|
||||||
|
|
|
@ -395,7 +395,15 @@ XML;
|
||||||
$obj = Xml::fromArray($xml, 'attributes');
|
$obj = Xml::fromArray($xml, 'attributes');
|
||||||
$xmlText = '<' . '?xml version="1.0" encoding="UTF-8"?><tags><tag id="1">defect</tag></tags>';
|
$xmlText = '<' . '?xml version="1.0" encoding="UTF-8"?><tags><tag id="1">defect</tag></tags>';
|
||||||
$this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
|
$this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test fromArray() with zero values.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testFromArrayZeroValue()
|
||||||
|
{
|
||||||
$xml = array(
|
$xml = array(
|
||||||
'tag' => array(
|
'tag' => array(
|
||||||
'@' => 0,
|
'@' => 0,
|
||||||
|
@ -406,6 +414,16 @@ XML;
|
||||||
$xmlText = <<<XML
|
$xmlText = <<<XML
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<tag test="A test">0</tag>
|
<tag test="A test">0</tag>
|
||||||
|
XML;
|
||||||
|
$this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
|
||||||
|
|
||||||
|
$xml = array(
|
||||||
|
'tag' => array('0')
|
||||||
|
);
|
||||||
|
$obj = Xml::fromArray($xml);
|
||||||
|
$xmlText = <<<XML
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<tag>0</tag>
|
||||||
XML;
|
XML;
|
||||||
$this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
|
$this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
|
||||||
}
|
}
|
||||||
|
|
|
@ -544,7 +544,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
|
||||||
* @param mixed $result
|
* @param mixed $result
|
||||||
* @param mixed $expected
|
* @param mixed $expected
|
||||||
* @param string $message the text to display if the assertion is not correct
|
* @param string $message the text to display if the assertion is not correct
|
||||||
* @deprecated 3.0.0 This is a compatiblity wrapper for 1.x. It will be removed in 3.0
|
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected static function assertEqual($result, $expected, $message = '') {
|
protected static function assertEqual($result, $expected, $message = '') {
|
||||||
|
@ -557,7 +557,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
|
||||||
* @param mixed $result
|
* @param mixed $result
|
||||||
* @param mixed $expected
|
* @param mixed $expected
|
||||||
* @param string $message the text to display if the assertion is not correct
|
* @param string $message the text to display if the assertion is not correct
|
||||||
* @deprecated 3.0.0 This is a compatiblity wrapper for 1.x. It will be removed in 3.0
|
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected static function assertNotEqual($result, $expected, $message = '') {
|
protected static function assertNotEqual($result, $expected, $message = '') {
|
||||||
|
@ -570,7 +570,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
|
||||||
* @param mixed $pattern a regular expression
|
* @param mixed $pattern a regular expression
|
||||||
* @param string $string the text to be matched
|
* @param string $string the text to be matched
|
||||||
* @param string $message the text to display if the assertion is not correct
|
* @param string $message the text to display if the assertion is not correct
|
||||||
* @deprecated 3.0.0 This is a compatiblity wrapper for 1.x. It will be removed in 3.0
|
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected static function assertPattern($pattern, $string, $message = '') {
|
protected static function assertPattern($pattern, $string, $message = '') {
|
||||||
|
@ -583,7 +583,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
|
||||||
* @param mixed $actual
|
* @param mixed $actual
|
||||||
* @param mixed $expected
|
* @param mixed $expected
|
||||||
* @param string $message the text to display if the assertion is not correct
|
* @param string $message the text to display if the assertion is not correct
|
||||||
* @deprecated 3.0.0 This is a compatiblity wrapper for 1.x. It will be removed in 3.0
|
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected static function assertIdentical($actual, $expected, $message = '') {
|
protected static function assertIdentical($actual, $expected, $message = '') {
|
||||||
|
@ -596,7 +596,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
|
||||||
* @param mixed $actual
|
* @param mixed $actual
|
||||||
* @param mixed $expected
|
* @param mixed $expected
|
||||||
* @param string $message the text to display if the assertion is not correct
|
* @param string $message the text to display if the assertion is not correct
|
||||||
* @deprecated 3.0.0 This is a compatiblity wrapper for 1.x. It will be removed in 3.0
|
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected static function assertNotIdentical($actual, $expected, $message = '') {
|
protected static function assertNotIdentical($actual, $expected, $message = '') {
|
||||||
|
@ -609,7 +609,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
|
||||||
* @param mixed $pattern a regular expression
|
* @param mixed $pattern a regular expression
|
||||||
* @param string $string the text to be matched
|
* @param string $string the text to be matched
|
||||||
* @param string $message the text to display if the assertion is not correct
|
* @param string $message the text to display if the assertion is not correct
|
||||||
* @deprecated 3.0.0 This is a compatiblity wrapper for 1.x. It will be removed in 3.0
|
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected static function assertNoPattern($pattern, $string, $message = '') {
|
protected static function assertNoPattern($pattern, $string, $message = '') {
|
||||||
|
@ -619,7 +619,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
|
||||||
/**
|
/**
|
||||||
* assert no errors
|
* assert no errors
|
||||||
*
|
*
|
||||||
* @deprecated 3.0.0 This is a compatiblity wrapper for 1.x. It will be removed in 3.0
|
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function assertNoErrors() {
|
protected function assertNoErrors() {
|
||||||
|
@ -630,7 +630,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
|
||||||
*
|
*
|
||||||
* @param mixed $expected the name of the Exception or error
|
* @param mixed $expected the name of the Exception or error
|
||||||
* @param string $message the text to display if the assertion is not correct
|
* @param string $message the text to display if the assertion is not correct
|
||||||
* @deprecated 3.0.0 This is a compatiblity wrapper for 1.x. It will be removed in 3.0
|
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function expectError($expected = false, $message = '') {
|
protected function expectError($expected = false, $message = '') {
|
||||||
|
@ -658,7 +658,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
|
||||||
* @param mixed $first
|
* @param mixed $first
|
||||||
* @param mixed $second
|
* @param mixed $second
|
||||||
* @param string $message the text to display if the assertion is not correct
|
* @param string $message the text to display if the assertion is not correct
|
||||||
* @deprecated 3.0.0 This is a compatiblity wrapper for 1.x. It will be removed in 3.0
|
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected static function assertReference(&$first, &$second, $message = '') {
|
protected static function assertReference(&$first, &$second, $message = '') {
|
||||||
|
@ -671,7 +671,7 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
|
||||||
* @param string $object
|
* @param string $object
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @param string $message
|
* @param string $message
|
||||||
* @deprecated 3.0.0 This is a compatiblity wrapper for 1.x. It will be removed in 3.0
|
* @deprecated 3.0.0 This is a compatibility wrapper for 1.x. It will be removed in 3.0
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected static function assertIsA($object, $type, $message = '') {
|
protected static function assertIsA($object, $type, $message = '') {
|
||||||
|
|
|
@ -774,6 +774,7 @@ class Debugger {
|
||||||
|
|
||||||
if (!empty($tpl['escapeContext'])) {
|
if (!empty($tpl['escapeContext'])) {
|
||||||
$context = h($context);
|
$context = h($context);
|
||||||
|
$data['description'] = h($data['description']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$infoData = compact('code', 'context', 'trace');
|
$infoData = compact('code', 'context', 'trace');
|
||||||
|
|
|
@ -171,7 +171,7 @@ class Security {
|
||||||
/**
|
/**
|
||||||
* Get random bytes from a secure source.
|
* Get random bytes from a secure source.
|
||||||
*
|
*
|
||||||
* This method will fall back to an insecure source an trigger a warning
|
* This method will fall back to an insecure source and trigger a warning,
|
||||||
* if it cannot find a secure source of random data.
|
* if it cannot find a secure source of random data.
|
||||||
*
|
*
|
||||||
* @param int $length The number of bytes you want.
|
* @param int $length The number of bytes you want.
|
||||||
|
|
|
@ -312,7 +312,7 @@ class Xml {
|
||||||
$childNS = $value['xmlns:'];
|
$childNS = $value['xmlns:'];
|
||||||
unset($value['xmlns:']);
|
unset($value['xmlns:']);
|
||||||
}
|
}
|
||||||
} elseif (!empty($value) || $value === 0) {
|
} elseif (!empty($value) || $value === 0 || $value === '0') {
|
||||||
$childValue = (string)$value;
|
$childValue = (string)$value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -564,7 +564,7 @@ class View extends CakeObject {
|
||||||
|
|
||||||
$type = $response->mapType($response->type());
|
$type = $response->mapType($response->type());
|
||||||
if (Configure::read('debug') > 0 && $type === 'html') {
|
if (Configure::read('debug') > 0 && $type === 'html') {
|
||||||
echo "<!-- Cached Render Time: " . round(microtime(true) - $timeStart, 4) . "s -->";
|
echo "<!-- Cached Render Time: " . round(microtime(true) - (int)$timeStart, 4) . "s -->";
|
||||||
}
|
}
|
||||||
$out = ob_get_clean();
|
$out = ob_get_clean();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue