Merge branch '2.0' into 2.0-api-doc
Conflicts: lib/Cake/Test/Case/View/Helper/CacheHelperTest.php lib/Cake/Utility/Debugger.php
|
@ -247,7 +247,6 @@
|
|||
* 'serialize' => true, [optional]
|
||||
* ));
|
||||
*
|
||||
*
|
||||
* APC (http://pecl.php.net/package/APC)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
|
@ -263,12 +262,11 @@
|
|||
* 'engine' => 'Xcache', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* 'user' => 'user', //user from xcache.admin.user settings
|
||||
* 'password' => 'password', //plaintext password (xcache.admin.pass)
|
||||
* 'password' => 'password', //plaintext password (xcache.admin.pass)
|
||||
* ));
|
||||
*
|
||||
*
|
||||
* Memcache (http://www.danga.com/memcached/)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
|
@ -281,9 +279,16 @@
|
|||
* ), //[optional]
|
||||
* 'persistent' => true, // [optional] set this to false for non-persistent connections
|
||||
* 'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory)
|
||||
* 'persistent' => true, // [optional] set this to false for non-persistent connections
|
||||
* ));
|
||||
*
|
||||
* Wincache (http://php.net/wincache)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
* 'engine' => 'Wincache', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* ));
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -315,7 +320,7 @@ Cache::config('_cake_core_', array(
|
|||
));
|
||||
|
||||
/**
|
||||
* Configure the cache for model, and datasource caches. This cache configuration
|
||||
* Configure the cache for model and datasource caches. This cache configuration
|
||||
* is used to store schema descriptions, and table listings in connections.
|
||||
*/
|
||||
Cache::config('_cake_model_', array(
|
||||
|
|
|
@ -66,6 +66,7 @@ class DATABASE_CONFIG {
|
|||
'password' => 'password',
|
||||
'database' => 'database_name',
|
||||
'prefix' => '',
|
||||
//'encoding' => 'utf8',
|
||||
);
|
||||
|
||||
public $test = array(
|
||||
|
@ -76,5 +77,6 @@ class DATABASE_CONFIG {
|
|||
'password' => 'password',
|
||||
'database' => 'test_database_name',
|
||||
'prefix' => '',
|
||||
//'encoding' => 'utf8',
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
/**
|
||||
* Command-line code generation utility to automate programmer chores.
|
||||
*
|
||||
* Shell dispatcher class
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
|
@ -15,10 +13,29 @@
|
|||
*
|
||||
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.console
|
||||
* @since CakePHP(tm) v 1.2.0.5012
|
||||
* @package app.Console
|
||||
* @since CakePHP(tm) v 2.0
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
require_once(dirname(dirname(dirname(__FILE__))) . DIRECTORY_SEPARATOR . 'lib'. DIRECTORY_SEPARATOR . 'Cake' . DIRECTORY_SEPARATOR . 'Console' . DIRECTORY_SEPARATOR . 'ShellDispatcher.php');
|
||||
$ds = DIRECTORY_SEPARATOR;
|
||||
$dispatcher = 'Cake' . $ds . 'Console' . $ds . 'ShellDispatcher.php';
|
||||
$found = false;
|
||||
$paths = explode(PATH_SEPARATOR, ini_get('include_path'));
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (file_exists($path . $ds . $dispatcher)) {
|
||||
$found = $path;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found && function_exists('ini_set')) {
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
ini_set('include_path', $root . $ds. 'lib' . PATH_SEPARATOR . ini_get('include_path'));
|
||||
}
|
||||
|
||||
if (!include($dispatcher)) {
|
||||
trigger_error('Could not locate CakePHP core files.', E_USER_ERROR);
|
||||
}
|
||||
unset($paths, $path, $found, $dispatcher, $root, $ds);
|
||||
|
||||
return ShellDispatcher::run($argv);
|
||||
|
|
|
@ -44,13 +44,19 @@
|
|||
if (!defined('APP_DIR')) {
|
||||
define('APP_DIR', basename(dirname(dirname(__FILE__))));
|
||||
}
|
||||
|
||||
/**
|
||||
* The absolute path to the "cake" directory, WITHOUT a trailing DS.
|
||||
*
|
||||
* Un-comment this line to specify a fixed path to CakePHP.
|
||||
* This should point at the directory containg `Cake`.
|
||||
*
|
||||
* For ease of development CakePHP uses PHP's include_path. If you
|
||||
* cannot modify your include_path set this value.
|
||||
*
|
||||
* Leaving this constant undefined will result in it being defined in Cake/bootstrap.php
|
||||
*/
|
||||
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
|
||||
define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');
|
||||
}
|
||||
//define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');
|
||||
|
||||
/**
|
||||
* Editing below this line should NOT be necessary.
|
||||
|
@ -63,11 +69,20 @@
|
|||
if (!defined('WWW_ROOT')) {
|
||||
define('WWW_ROOT', dirname(__FILE__) . DS);
|
||||
}
|
||||
if (!defined('CORE_PATH')) {
|
||||
define('APP_PATH', ROOT . DS . APP_DIR . DS);
|
||||
define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
|
||||
|
||||
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
|
||||
if (function_exists('ini_set')) {
|
||||
ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
|
||||
}
|
||||
if (!include('Cake' . DS . 'bootstrap.php')) {
|
||||
$failed = true;
|
||||
}
|
||||
} else {
|
||||
if (!include(CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php')) {
|
||||
$failed = true;
|
||||
}
|
||||
}
|
||||
if (!include(CORE_PATH . 'Cake' . DS . 'bootstrap.php')) {
|
||||
if (!empty($failed)) {
|
||||
trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,13 +44,16 @@ ini_set('display_errors', 1);
|
|||
if (!defined('APP_DIR')) {
|
||||
define('APP_DIR', basename(dirname(dirname(__FILE__))));
|
||||
}
|
||||
|
||||
/**
|
||||
* The absolute path to the "Cake" directory, WITHOUT a trailing DS.
|
||||
*
|
||||
* For ease of development CakePHP uses PHP's include_path. If you
|
||||
* need to cannot modify your include_path, you can set this path.
|
||||
*
|
||||
* Leaving this constant undefined will result in it being defined in Cake/bootstrap.php
|
||||
*/
|
||||
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
|
||||
define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');
|
||||
}
|
||||
//define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');
|
||||
|
||||
/**
|
||||
* Editing below this line should not be necessary.
|
||||
|
@ -63,11 +66,20 @@ if (!defined('WEBROOT_DIR')) {
|
|||
if (!defined('WWW_ROOT')) {
|
||||
define('WWW_ROOT', dirname(__FILE__) . DS);
|
||||
}
|
||||
if (!defined('CORE_PATH')) {
|
||||
define('APP_PATH', ROOT . DS . APP_DIR . DS);
|
||||
define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
|
||||
|
||||
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
|
||||
if (function_exists('ini_set')) {
|
||||
ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
|
||||
}
|
||||
if (!include('Cake' . DS . 'bootstrap.php')) {
|
||||
$failed = true;
|
||||
}
|
||||
} else {
|
||||
if (!include(CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php')) {
|
||||
$failed = true;
|
||||
}
|
||||
}
|
||||
if (!include(CORE_PATH . 'Cake' . DS . 'bootstrap.php')) {
|
||||
if (!empty($failed)) {
|
||||
trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,10 +37,4 @@
|
|||
define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the include path or define app and core path
|
||||
*/
|
||||
define('APP_PATH', ROOT . DS . APP_DIR . DS);
|
||||
define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
|
||||
|
||||
require APP_DIR . DS . WEBROOT_DIR . DS . 'index.php';
|
||||
|
|
|
@ -82,7 +82,7 @@ class Cache {
|
|||
*
|
||||
* `Cache::config('default');`
|
||||
*
|
||||
* There are 4 built-in caching engines:
|
||||
* There are 5 built-in caching engines:
|
||||
*
|
||||
* - `FileEngine` - Uses simple files to store content. Poor performance, but good for
|
||||
* storing large objects, or things that are not IO sensitive.
|
||||
|
@ -90,6 +90,7 @@ class Cache {
|
|||
* - `MemcacheEngine` - Uses the PECL::Memcache extension and Memcached for storage.
|
||||
* Fast reads/writes, and benefits from memcache being distributed.
|
||||
* - `XcacheEngine` - Uses the Xcache extension, an alternative to APC.
|
||||
* - `WincacheEngine` - Uses Windows Cache Extension for PHP. Supports wincache 1.1.0 and higher.
|
||||
*
|
||||
* The following keys are used in core cache engines:
|
||||
*
|
||||
|
|
|
@ -121,19 +121,24 @@ class FileEngine extends CacheEngine {
|
|||
}
|
||||
}
|
||||
|
||||
if ($this->settings['lock']) {
|
||||
$this->_File->flock(LOCK_EX);
|
||||
}
|
||||
|
||||
$expires = time() + $duration;
|
||||
$contents = $expires . $lineBreak . $data . $lineBreak;
|
||||
$success = $this->_File->ftruncate(0) && $this->_File->fwrite($contents);
|
||||
|
||||
if (!$handle = fopen($this->_File->getPathName(), 'c')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->settings['lock']) {
|
||||
$this->_File->flock(LOCK_UN);
|
||||
flock($handle, LOCK_EX);
|
||||
}
|
||||
$this->_File = null;
|
||||
|
||||
$success = ftruncate($handle, 0) && fwrite($handle, $contents) && fflush($handle);
|
||||
|
||||
if ($this->settings['lock']) {
|
||||
flock($handle, LOCK_UN);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
return $success;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ class CommandListShell extends Shell {
|
|||
if (empty($this->params['xml'])) {
|
||||
$this->out(__d('cake_console', "<info>Current Paths:</info>"), 2);
|
||||
$this->out(" -app: ". APP_DIR);
|
||||
$this->out(" -working: " . rtrim(APP_PATH, DS));
|
||||
$this->out(" -working: " . rtrim(APP, DS));
|
||||
$this->out(" -root: " . rtrim(ROOT, DS));
|
||||
$this->out(" -core: " . rtrim(CORE_PATH, DS));
|
||||
$this->out("");
|
||||
|
|
|
@ -390,7 +390,12 @@ class ExtractTask extends Shell {
|
|||
|
||||
foreach ($rules as $rule => $validateProp) {
|
||||
if (isset($validateProp['message'])) {
|
||||
$this->_strings[$domain][$validateProp['message']][$file][] = 'validation for field ' . $field;
|
||||
if (is_array($validateProp['message'])) {
|
||||
$message = $validateProp['message'][0];
|
||||
} else {
|
||||
$message = $validateProp['message'];
|
||||
}
|
||||
$this->_strings[$domain][$message][$file][] = 'validation for field ' . $field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -507,7 +512,7 @@ class ExtractTask extends Shell {
|
|||
$output .= "\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n\n";
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the strings from the position forward
|
||||
*
|
||||
|
|
|
@ -50,8 +50,9 @@ class ProjectTask extends Shell {
|
|||
|
||||
while (!$project) {
|
||||
$prompt = __d('cake_console', "What is the path to the project you want to bake?");
|
||||
$project = $this->in($prompt, null, APP_PATH . 'myapp');
|
||||
$project = $this->in($prompt, null, APP . 'myapp');
|
||||
}
|
||||
|
||||
|
||||
if ($project && !Folder::isAbsolute($project) && isset($_SERVER['PWD'])) {
|
||||
$project = $_SERVER['PWD'] . DS . $project;
|
||||
|
@ -97,20 +98,24 @@ class ProjectTask extends Shell {
|
|||
$success = false;
|
||||
}
|
||||
|
||||
$this->out(__d('cake_console', 'The value for CAKE_CORE_INCLUDE_PATH can be hardcoded set to %s in webroot/index.php', CAKE_CORE_INCLUDE_PATH));
|
||||
$this->out(__d('cake_console', '<warning>If you hard code it, the project will possibly run only in your computer.</warning>'));
|
||||
$setConstants = $this->in(__d('cake_console', 'Do you want to set CAKE_CORE_INCLUDE_PATH in webroot/index.php?'), array('y', 'n'), 'n');
|
||||
if (strtolower($setConstants) === 'y') {
|
||||
if ($this->corePath($path) === true) {
|
||||
$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', ' * <warning>Remember to check these values after moving to production server</warning>'));
|
||||
} 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;
|
||||
}
|
||||
$hardCode = false;
|
||||
if ($this->cakeOnIncludePath()) {
|
||||
$this->out(__d('cake_console', '<info>CakePHP is on your `include_path`. CAKE_CORE_INCLUDE_PATH will be set, but commented out.</info>'));
|
||||
} else {
|
||||
$this->out(__d('cake_console', '<warning>Please make sure your cake core is accessible, if you have problems edit CAKE_CORE_INCLUDE_PATH in webroot/index.php</warning>'));
|
||||
$this->out(__d('cake_console', '<warning>CakePHP is not on your `include_path`, CAKE_CORE_INCLUDE_PATH will be hard coded.</warning>'));
|
||||
$this->out(__d('cake_console', 'You can fix this by adding CakePHP to your `include_path`.'));
|
||||
$hardCode = true;
|
||||
}
|
||||
$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));
|
||||
} 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;
|
||||
}
|
||||
if ($success && $hardCode) {
|
||||
$this->out(__d('cake_console', ' * <warning>Remember to check these values after moving to production server</warning>'));
|
||||
}
|
||||
|
||||
$Folder = new Folder($path);
|
||||
|
@ -128,6 +133,21 @@ class ProjectTask extends Shell {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks PHP's include_path for CakePHP.
|
||||
*
|
||||
* @return bool Indicates whether or not CakePHP exists on include_path
|
||||
*/
|
||||
public function cakeOnIncludePath() {
|
||||
$paths = explode(PATH_SEPARATOR, ini_get('include_path'));
|
||||
foreach ($paths as $path) {
|
||||
if (file_exists($path . DS . 'Cake' . DS . 'bootstrap.php')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a skeleton template of a Cake application,
|
||||
* and if not found asks the user for a path. When there is a path
|
||||
|
@ -226,8 +246,8 @@ class ProjectTask extends Shell {
|
|||
$File = new File($path . 'Console' . DS . 'cake.php');
|
||||
$contents = $File->read();
|
||||
if (preg_match('/(__CAKE_PATH__)/', $contents, $match)) {
|
||||
$path = CAKE . 'Console' . DS;
|
||||
$replacement = "'" . str_replace(DS, "' . DIRECTORY_SEPARATOR . '", $path) . "'";
|
||||
$root = strpos(CAKE_CORE_INCLUDE_PATH, '/') === 0 ? " \$ds . '" : "'";
|
||||
$replacement = $root . str_replace(DS, "' . \$ds . '", trim(CAKE_CORE_INCLUDE_PATH, DS)) . "'";
|
||||
$result = str_replace($match[0], $replacement, $contents);
|
||||
if ($File->write($result)) {
|
||||
return true;
|
||||
|
@ -284,36 +304,49 @@ class ProjectTask extends Shell {
|
|||
* Generates and writes CAKE_CORE_INCLUDE_PATH
|
||||
*
|
||||
* @param string $path Project path
|
||||
* @param bool $hardCode Wether or not define calls should be hardcoded.
|
||||
* @return boolean Success
|
||||
*/
|
||||
public function corePath($path) {
|
||||
public function corePath($path, $hardCode = true) {
|
||||
if (dirname($path) !== CAKE_CORE_INCLUDE_PATH) {
|
||||
$File = new File($path . 'webroot' . DS . 'index.php');
|
||||
$contents = $File->read();
|
||||
if (preg_match('/([\s]*define\(\'CAKE_CORE_INCLUDE_PATH\',[\s\'A-z0-9\.]*\);)/', $contents, $match)) {
|
||||
$root = strpos(CAKE_CORE_INCLUDE_PATH, '/') === 0 ? " DS . '" : "'";
|
||||
$result = str_replace($match[0], "\n\t\tdefine('CAKE_CORE_INCLUDE_PATH', " . $root . str_replace(DS, "' . DS . '", trim(CAKE_CORE_INCLUDE_PATH, DS)) . "');", $contents);
|
||||
if (!$File->write($result)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$filename = $path . 'webroot' . DS . 'index.php';
|
||||
if (!$this->_replaceCorePath($filename, $hardCode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$File = new File($path . 'webroot' . DS . 'test.php');
|
||||
$contents = $File->read();
|
||||
if (preg_match('/([\s]*define\(\'CAKE_CORE_INCLUDE_PATH\',[\s\'A-z0-9\.]*\);)/', $contents, $match)) {
|
||||
$result = str_replace($match[0], "\n\t\tdefine('CAKE_CORE_INCLUDE_PATH', " . $root . str_replace(DS, "' . DS . '", trim(CAKE_CORE_INCLUDE_PATH, DS)) . "');", $contents);
|
||||
if (!$File->write($result)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$filename = $path . 'webroot' . DS . 'test.php';
|
||||
if (!$this->_replaceCorePath($filename, $hardCode)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the __CAKE_PATH__ placeholder in the template files.
|
||||
*
|
||||
* @param string $filename The filename to operate on.
|
||||
* @param boolean $hardCode Whether or not the define should be uncommented.
|
||||
* @retun bool Success
|
||||
*/
|
||||
protected function _replaceCorePath($filename, $hardCode) {
|
||||
$contents = file_get_contents($filename);
|
||||
|
||||
$root = strpos(CAKE_CORE_INCLUDE_PATH, '/') === 0 ? " DS . '" : "'";
|
||||
$corePath = $root . str_replace(DS, "' . DS . '", trim(CAKE_CORE_INCLUDE_PATH, DS)) . "'";
|
||||
|
||||
$result = str_replace('__CAKE_PATH__', $corePath, $contents, $count);
|
||||
if ($hardCode) {
|
||||
$result = str_replace('//define(\'CAKE_CORE', 'define(\'CAKE_CORE', $result);
|
||||
}
|
||||
if (!file_put_contents($filename, $result)) {
|
||||
return false;
|
||||
}
|
||||
if ($count == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables Configure::read('Routing.prefixes') in /app/Config/core.php
|
||||
*
|
||||
|
|
|
@ -104,6 +104,10 @@ class UpgradeShell extends Shell {
|
|||
public function locations() {
|
||||
$cwd = getcwd();
|
||||
|
||||
if (!empty($this->params['plugin'])) {
|
||||
chdir(App::pluginPath($this->params['plugin']));
|
||||
}
|
||||
|
||||
if (is_dir('plugins')) {
|
||||
|
||||
$Folder = new Folder('plugins');
|
||||
|
|
|
@ -89,6 +89,11 @@ class ConsoleInputOption {
|
|||
$this->_default = $default;
|
||||
$this->_choices = $choices;
|
||||
}
|
||||
if (strlen($this->_short) > 1) {
|
||||
throw new ConsoleException(
|
||||
__d('cake_console', 'Short options must be one letter.')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -41,7 +41,8 @@ App::uses('HelpFormatter', 'Console');
|
|||
*
|
||||
* Options can be defined with both long and short forms. By using `$parser->addOption()`
|
||||
* you can define new options. The name of the option is used as its long form, and you
|
||||
* can supply an additional short form, with the `short` option.
|
||||
* can supply an additional short form, with the `short` option. Short options should
|
||||
* only be one letter long. Using more than one letter for a short option will raise an exception.
|
||||
*
|
||||
* Calling options can be done using syntax similar to most *nix command line tools. Long options
|
||||
* cane either include an `=` or leave it out.
|
||||
|
@ -52,6 +53,15 @@ App::uses('HelpFormatter', 'Console');
|
|||
*
|
||||
* `cake myshell command -cn`
|
||||
*
|
||||
* Short options can be combined into groups as seen above. Each letter in a group
|
||||
* will be treated as a separate option. The previous example is equivalent to:
|
||||
*
|
||||
* `cake myshell command -c -n`
|
||||
*
|
||||
* Short options can also accept values:
|
||||
*
|
||||
* `cake myshell command -c default`
|
||||
*
|
||||
* ### Positional arguments
|
||||
*
|
||||
* If no positional arguments are defined, all of them will be parsed. If you define positional
|
||||
|
@ -116,6 +126,13 @@ class ConsoleOptionParser {
|
|||
*/
|
||||
protected $_subcommands = array();
|
||||
|
||||
/**
|
||||
* Command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_command = '';
|
||||
|
||||
/**
|
||||
* Construct an OptionParser so you can define its behavior
|
||||
*
|
||||
|
@ -124,7 +141,7 @@ class ConsoleOptionParser {
|
|||
* this to false will prevent the addition of `--verbose` & `--quiet` options.
|
||||
*/
|
||||
public function __construct($command = null, $defaultOptions = true) {
|
||||
$this->_command = $command;
|
||||
$this->command($command);
|
||||
|
||||
$this->addOption('help', array(
|
||||
'short' => 'h',
|
||||
|
@ -206,7 +223,7 @@ class ConsoleOptionParser {
|
|||
*/
|
||||
public function command($text = null) {
|
||||
if ($text !== null) {
|
||||
$this->_command = $text;
|
||||
$this->_command = Inflector::underscore($text);
|
||||
return $this;
|
||||
}
|
||||
return $this->_command;
|
||||
|
@ -563,7 +580,7 @@ class ConsoleOptionParser {
|
|||
$option = $this->_options[$name];
|
||||
$isBoolean = $option->isBoolean();
|
||||
$nextValue = $this->_nextToken();
|
||||
if (!$isBoolean && !empty($nextValue) && $nextValue{0} != '-') {
|
||||
if (!$isBoolean && !empty($nextValue) && !$this->_optionExists($nextValue)) {
|
||||
array_shift($this->_tokens);
|
||||
$value = $nextValue;
|
||||
} elseif ($isBoolean) {
|
||||
|
@ -577,6 +594,23 @@ class ConsoleOptionParser {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check to see if $name has an option (short/long) defined for it.
|
||||
*
|
||||
* @param string $name The name of the option.
|
||||
* @return boolean
|
||||
*/
|
||||
protected function _optionExists($name) {
|
||||
if (substr($name, 0, 2) === '--') {
|
||||
return isset($this->_options[substr($name, 2)]);
|
||||
}
|
||||
if ($name{0} === '-' && $name{1} !== '-') {
|
||||
return isset($this->_shortOptions[$name{1}]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an argument, and ensure that the argument doesn't exceed the number of arguments
|
||||
* and that the argument is a valid choice.
|
||||
|
|
|
@ -29,6 +29,20 @@ App::uses('String', 'Utility');
|
|||
* @since CakePHP(tm) v 2.0
|
||||
*/
|
||||
class HelpFormatter {
|
||||
/**
|
||||
* The maximum number of arguments shown when generating usage.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_maxArgs = 6;
|
||||
|
||||
/**
|
||||
* The maximum number of options shown when generating usage.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_maxOptions = 6;
|
||||
|
||||
/**
|
||||
* Build the help formatter for a an OptionParser
|
||||
*
|
||||
|
@ -122,12 +136,22 @@ class HelpFormatter {
|
|||
if (!empty($subcommands)) {
|
||||
$usage[] = '[subcommand]';
|
||||
}
|
||||
$options = array();
|
||||
foreach ($this->_parser->options() as $option) {
|
||||
$usage[] = $option->usage();
|
||||
$options[] = $option->usage();
|
||||
}
|
||||
if (count($options) > $this->_maxOptions){
|
||||
$options = array('[options]');
|
||||
}
|
||||
$usage = array_merge($usage, $options);
|
||||
$args = array();
|
||||
foreach ($this->_parser->arguments() as $argument) {
|
||||
$usage[] = $argument->usage();
|
||||
$args[] = $argument->usage();
|
||||
}
|
||||
if (count($args) > $this->_maxArgs) {
|
||||
$args = array('[arguments]');
|
||||
}
|
||||
$usage = array_merge($usage, $args);
|
||||
return implode(' ', $usage);
|
||||
}
|
||||
|
||||
|
|
|
@ -204,7 +204,7 @@ class Shell extends Object {
|
|||
$this->out(__d('cake_console', '<info>Welcome to CakePHP %s Console</info>', 'v' . Configure::version()));
|
||||
$this->hr();
|
||||
$this->out(__d('cake_console', 'App : %s', APP_DIR));
|
||||
$this->out(__d('cake_console', 'Path: %s', APP_PATH));
|
||||
$this->out(__d('cake_console', 'Path: %s', APP));
|
||||
$this->hr();
|
||||
}
|
||||
|
||||
|
@ -386,7 +386,7 @@ class Shell extends Object {
|
|||
$format = 'text';
|
||||
if (!empty($this->args[0]) && $this->args[0] == 'xml') {
|
||||
$format = 'xml';
|
||||
$this->output->outputAs(ConsoleOutput::RAW);
|
||||
$this->stdout->outputAs(ConsoleOutput::RAW);
|
||||
} else {
|
||||
$this->_welcome();
|
||||
}
|
||||
|
|
|
@ -122,15 +122,15 @@ class ShellDispatcher {
|
|||
private function __bootstrap() {
|
||||
define('ROOT', $this->params['root']);
|
||||
define('APP_DIR', $this->params['app']);
|
||||
define('APP_PATH', $this->params['working'] . DS);
|
||||
define('WWW_ROOT', APP_PATH . $this->params['webroot'] . DS);
|
||||
define('APP', $this->params['working'] . DS);
|
||||
define('WWW_ROOT', APP . $this->params['webroot'] . DS);
|
||||
if (!is_dir(ROOT . DS . APP_DIR . DS . 'tmp')) {
|
||||
define('TMP', CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Console' . DS . 'Templates' . DS . 'skel' . DS . 'tmp' . DS);
|
||||
}
|
||||
$boot = file_exists(ROOT . DS . APP_DIR . DS . 'Config' . DS . 'bootstrap.php');
|
||||
require CORE_PATH . 'Cake' . DS . 'bootstrap.php';
|
||||
|
||||
if (!file_exists(APP_PATH . 'Config' . DS . 'core.php')) {
|
||||
if (!file_exists(APP . 'Config' . DS . 'core.php')) {
|
||||
include_once CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Console' . DS . 'Templates' . DS . 'skel' . DS . 'Config' . DS . 'core.php';
|
||||
App::build();
|
||||
}
|
||||
|
|
|
@ -247,7 +247,6 @@
|
|||
* 'serialize' => true, [optional]
|
||||
* ));
|
||||
*
|
||||
*
|
||||
* APC (http://pecl.php.net/package/APC)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
|
@ -263,12 +262,11 @@
|
|||
* 'engine' => 'Xcache', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* 'user' => 'user', //user from xcache.admin.user settings
|
||||
* 'password' => 'password', //plaintext password (xcache.admin.pass)
|
||||
* 'password' => 'password', //plaintext password (xcache.admin.pass)
|
||||
* ));
|
||||
*
|
||||
*
|
||||
* Memcache (http://www.danga.com/memcached/)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
|
@ -281,9 +279,16 @@
|
|||
* ), //[optional]
|
||||
* 'persistent' => true, // [optional] set this to false for non-persistent connections
|
||||
* 'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory)
|
||||
* 'persistent' => true, // [optional] set this to false for non-persistent connections
|
||||
* ));
|
||||
*
|
||||
* Wincache (http://php.net/wincache)
|
||||
*
|
||||
* Cache::config('default', array(
|
||||
* 'engine' => 'Wincache', //[required]
|
||||
* 'duration'=> 3600, //[optional]
|
||||
* 'probability'=> 100, //[optional]
|
||||
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string
|
||||
* ));
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -315,7 +320,7 @@ Cache::config('_cake_core_', array(
|
|||
));
|
||||
|
||||
/**
|
||||
* Configure the cache for model, and datasource caches. This cache configuration
|
||||
* Configure the cache for model and datasource caches. This cache configuration
|
||||
* is used to store schema descriptions, and table listings in connections.
|
||||
*/
|
||||
Cache::config('_cake_model_', array(
|
||||
|
|
|
@ -66,6 +66,7 @@ class DATABASE_CONFIG {
|
|||
'password' => 'password',
|
||||
'database' => 'database_name',
|
||||
'prefix' => '',
|
||||
//'encoding' => 'utf8',
|
||||
);
|
||||
|
||||
public $test = array(
|
||||
|
@ -76,5 +77,6 @@ class DATABASE_CONFIG {
|
|||
'password' => 'password',
|
||||
'database' => 'test_database_name',
|
||||
'prefix' => '',
|
||||
//'encoding' => 'utf8',
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
/**
|
||||
* Command-line code generation utility to automate programmer chores.
|
||||
*
|
||||
* Shell dispatcher class
|
||||
*
|
||||
* PHP 5
|
||||
*
|
||||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||||
|
@ -16,9 +14,28 @@
|
|||
* @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||||
* @link http://cakephp.org CakePHP(tm) Project
|
||||
* @package app.Console
|
||||
* @since CakePHP(tm) v 1.2.0.5012
|
||||
* @since CakePHP(tm) v 2.0
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
require_once(__CAKE_PATH__ . 'ShellDispatcher.php');
|
||||
$ds = DIRECTORY_SEPARATOR;
|
||||
$dispatcher = 'Cake' . $ds . 'Console' . $ds . 'ShellDispatcher.php';
|
||||
$found = false;
|
||||
$paths = explode(PATH_SEPARATOR, ini_get('include_path'));
|
||||
|
||||
foreach ($paths as $path) {
|
||||
if (file_exists($path . $ds . $dispatcher)) {
|
||||
$found = $path;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found && function_exists('ini_set')) {
|
||||
$root = dirname(dirname(dirname(__FILE__)));
|
||||
ini_set('include_path', __CAKE_PATH__ . PATH_SEPARATOR . ini_get('include_path'));
|
||||
}
|
||||
|
||||
if (!include($dispatcher)) {
|
||||
trigger_error('Could not locate CakePHP core files.', E_USER_ERROR);
|
||||
}
|
||||
unset($paths, $path, $found, $dispatcher, $root, $ds);
|
||||
|
||||
return ShellDispatcher::run($argv);
|
||||
|
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 496 B After Width: | Height: | Size: 496 B |
Before Width: | Height: | Size: 783 B After Width: | Height: | Size: 783 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
@ -44,13 +44,19 @@
|
|||
if (!defined('APP_DIR')) {
|
||||
define('APP_DIR', basename(dirname(dirname(__FILE__))));
|
||||
}
|
||||
|
||||
/**
|
||||
* The absolute path to the "cake" directory, WITHOUT a trailing DS.
|
||||
*
|
||||
* Un-comment this line to specify a fixed path to CakePHP.
|
||||
* This should point at the directory containg `Cake`.
|
||||
*
|
||||
* For ease of development CakePHP uses PHP's include_path. If you
|
||||
* need to squeeze a bit more performance you can set this path.
|
||||
*
|
||||
* Leaving this constant undefined will result in it being defined in Cake/bootstrap.php
|
||||
*/
|
||||
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
|
||||
define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');
|
||||
}
|
||||
//define('CAKE_CORE_INCLUDE_PATH', __CAKE_PATH__);
|
||||
|
||||
/**
|
||||
* Editing below this line should NOT be necessary.
|
||||
|
@ -63,11 +69,17 @@
|
|||
if (!defined('WWW_ROOT')) {
|
||||
define('WWW_ROOT', dirname(__FILE__) . DS);
|
||||
}
|
||||
if (!defined('CORE_PATH')) {
|
||||
define('APP_PATH', ROOT . DS . APP_DIR . DS);
|
||||
define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
|
||||
|
||||
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
|
||||
if (!include('Cake' . DS . 'bootstrap.php')) {
|
||||
$failed = true;
|
||||
}
|
||||
} else {
|
||||
if (!include(CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php')) {
|
||||
$failed = true;
|
||||
}
|
||||
}
|
||||
if (!include(CORE_PATH . 'Cake' . DS . 'bootstrap.php')) {
|
||||
if (!empty($failed)) {
|
||||
trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
|
||||
}
|
||||
|
||||
|
@ -76,5 +88,6 @@
|
|||
}
|
||||
|
||||
App::uses('Dispatcher', 'Routing');
|
||||
|
||||
$Dispatcher = new Dispatcher();
|
||||
$Dispatcher->dispatch(new CakeRequest(), new CakeResponse(array('charset' => Configure::read('App.encoding'))));
|
||||
|
|
|
@ -44,13 +44,16 @@ ini_set('display_errors', 1);
|
|||
if (!defined('APP_DIR')) {
|
||||
define('APP_DIR', basename(dirname(dirname(__FILE__))));
|
||||
}
|
||||
|
||||
/**
|
||||
* The absolute path to the "Cake" directory, WITHOUT a trailing DS.
|
||||
*
|
||||
* For ease of development CakePHP uses PHP's include_path. If you
|
||||
* need to cannot modify your include_path, you can set this path.
|
||||
*
|
||||
* Leaving this constant undefined will result in it being defined in Cake/bootstrap.php
|
||||
*/
|
||||
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
|
||||
define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . 'lib');
|
||||
}
|
||||
//define('CAKE_CORE_INCLUDE_PATH', __CAKE_PATH__);
|
||||
|
||||
/**
|
||||
* Editing below this line should not be necessary.
|
||||
|
@ -63,11 +66,17 @@ if (!defined('WEBROOT_DIR')) {
|
|||
if (!defined('WWW_ROOT')) {
|
||||
define('WWW_ROOT', dirname(__FILE__) . DS);
|
||||
}
|
||||
if (!defined('CORE_PATH')) {
|
||||
define('APP_PATH', ROOT . DS . APP_DIR . DS);
|
||||
define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
|
||||
|
||||
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
|
||||
if (!include('Cake' . DS . 'bootstrap.php')) {
|
||||
$failed = true;
|
||||
}
|
||||
} else {
|
||||
if (!include(CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php')) {
|
||||
$failed = true;
|
||||
}
|
||||
}
|
||||
if (!include(CORE_PATH . 'Cake' . DS . 'bootstrap.php')) {
|
||||
if (!empty($failed)) {
|
||||
trigger_error("CakePHP core could not be found. Check the value of CAKE_CORE_INCLUDE_PATH in APP/webroot/index.php. It should point to the directory containing your " . DS . "cake core directory and your " . DS . "vendors root directory.", E_USER_ERROR);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,6 @@
|
|||
* @since CakePHP(tm) v 1.2.0.5012
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR. 'ShellDispatcher.php');
|
||||
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ShellDispatcher.php');
|
||||
|
||||
return ShellDispatcher::run($argv);
|
||||
|
|
|
@ -192,17 +192,17 @@ class SecurityComponent extends Component {
|
|||
$this->_authRequired($controller);
|
||||
|
||||
$isPost = ($this->request->is('post') || $this->request->is('put'));
|
||||
$isRequestAction = (
|
||||
$isNotRequestAction = (
|
||||
!isset($controller->request->params['requested']) ||
|
||||
$controller->request->params['requested'] != 1
|
||||
);
|
||||
|
||||
if ($isPost && $isRequestAction && $this->validatePost) {
|
||||
if ($isPost && $isNotRequestAction && $this->validatePost) {
|
||||
if ($this->_validatePost($controller) === false) {
|
||||
return $this->blackHole($controller, 'auth');
|
||||
}
|
||||
}
|
||||
if ($isPost && $this->csrfCheck) {
|
||||
if ($isPost && $isNotRequestAction && $this->csrfCheck) {
|
||||
if ($this->_validateCsrf($controller) === false) {
|
||||
return $this->blackHole($controller, 'csrf');
|
||||
}
|
||||
|
@ -499,7 +499,7 @@ class SecurityComponent extends Component {
|
|||
$token['csrfTokens'] = $this->_expireTokens($tokenData['csrfTokens']);
|
||||
}
|
||||
}
|
||||
if ($this->csrfCheck && ($this->csrfUseOnce || empty($tokenData['csrfTokens'])) ) {
|
||||
if ($this->csrfCheck && ($this->csrfUseOnce || empty($token['csrfTokens'])) ) {
|
||||
$token['csrfTokens'][$authKey] = strtotime($this->csrfExpires);
|
||||
}
|
||||
if ($this->csrfCheck && $this->csrfUseOnce == false) {
|
||||
|
|
|
@ -504,7 +504,7 @@ class Controller extends Object {
|
|||
|
||||
if (!$privateAction && !empty($prefixes)) {
|
||||
if (empty($request->params['prefix']) && strpos($request->params['action'], '_') > 0) {
|
||||
list($prefix, $action) = explode('_', $request->params['action']);
|
||||
list($prefix) = explode('_', $request->params['action']);
|
||||
$privateAction = in_array($prefix, $prefixes);
|
||||
}
|
||||
}
|
||||
|
@ -890,7 +890,7 @@ class Controller extends Object {
|
|||
$currentObject = ClassRegistry::getObject($currentModel);
|
||||
if (is_a($currentObject, 'Model')) {
|
||||
$className = get_class($currentObject);
|
||||
list($plugin, $package) = pluginSplit(App::location($className));
|
||||
list($plugin) = pluginSplit(App::location($className));
|
||||
$this->request->params['models'][$currentObject->alias] = compact('plugin', 'className');
|
||||
$View->validationErrors[$currentObject->alias] =& $currentObject->validationErrors;
|
||||
}
|
||||
|
|
|
@ -322,7 +322,7 @@ class Configure {
|
|||
*/
|
||||
public static function version() {
|
||||
if (!isset(self::$_values['Cake']['version'])) {
|
||||
require(CAKE . 'Config' . DS . 'config.php');
|
||||
require CAKE . 'Config' . DS . 'config.php';
|
||||
self::write($config);
|
||||
}
|
||||
return self::$_values['Cake']['version'];
|
||||
|
|
|
@ -85,7 +85,9 @@ class Object {
|
|||
}
|
||||
|
||||
$dispatcher = new Dispatcher();
|
||||
return $dispatcher->dispatch($request, new CakeResponse(), $extra);
|
||||
$result = $dispatcher->dispatch($request, new CakeResponse(), $extra);
|
||||
Router::popRequest();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -42,6 +42,19 @@
|
|||
* using CakeLogs's methods. If you don't configure any adapters, and write to the logs
|
||||
* a default FileLog will be autoconfigured for you.
|
||||
*
|
||||
* ### Configuring Log adapters
|
||||
*
|
||||
* You can configure log adapters in your applications `bootstrap.php` file. A sample configuration
|
||||
* would look like:
|
||||
*
|
||||
* `CakeLog::config('my_log', array('engine' => 'FileLog'));`
|
||||
*
|
||||
* See the documentation on CakeLog::config() for more detail.
|
||||
*
|
||||
* ### Writing to the log
|
||||
*
|
||||
* You write to the logs using CakeLog::write(). See its documentation for more information.
|
||||
*
|
||||
* @package Cake.Log
|
||||
*/
|
||||
class CakeLog {
|
||||
|
@ -69,11 +82,7 @@ class CakeLog {
|
|||
*
|
||||
* Will configure a FileLog instance to use the specified path. All options that are not `engine`
|
||||
* are passed onto the logging adapter, and handled there. Any class can be configured as a logging
|
||||
* adapter as long as it implements a `write` method with the following signature.
|
||||
*
|
||||
* `write($type, $message)`
|
||||
*
|
||||
* For an explaination of these parameters, see CakeLog::write()
|
||||
* adapter as long as it implements the methods in CakeLogInterface.
|
||||
*
|
||||
* @param string $key The keyname for this logger, used to remove the logger later.
|
||||
* @param array $config Array of configuration information for the logger
|
||||
|
@ -191,7 +200,7 @@ class CakeLog {
|
|||
if (empty(self::$_streams)) {
|
||||
self::_autoConfig();
|
||||
}
|
||||
foreach (self::$_streams as $key => $logger) {
|
||||
foreach (self::$_streams as $logger) {
|
||||
$logger->write($type, $message);
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -75,7 +75,7 @@ class AclBehavior extends ModelBehavior {
|
|||
if (empty($type)) {
|
||||
$type = $this->__typeMaps[$this->settings[$model->name]['type']];
|
||||
if (is_array($type)) {
|
||||
trigger_error(__('AclBehavior is setup with more then one type, please specify type parameter for node()', true), E_USER_WARNING);
|
||||
trigger_error(__d('cake_dev', 'AclBehavior is setup with more then one type, please specify type parameter for node()'), E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -219,7 +219,7 @@ class TreeBehavior extends ModelBehavior {
|
|||
|
||||
if ($id === null) {
|
||||
return $Model->find('count', array('conditions' => $scope));
|
||||
} elseif (isset($Model->data[$Model->alias][$left]) && isset($Model->data[$Model->alias][$right])) {
|
||||
} elseif ($Model->id === $id && isset($Model->data[$Model->alias][$left]) && isset($Model->data[$Model->alias][$right])) {
|
||||
$data = $Model->data[$Model->alias];
|
||||
} else {
|
||||
$data = $Model->find('first', array('conditions' => array($scope, $Model->escapeField() => $id), 'recursive' => $recursive));
|
||||
|
|
|
@ -299,7 +299,7 @@ class Postgres extends DboSource {
|
|||
* and if 1, sequences are not modified
|
||||
* @return boolean SQL TRUNCATE TABLE statement, false if not applicable.
|
||||
*/
|
||||
public function truncate($table, $reset = true) {
|
||||
function truncate($table, $reset = 0) {
|
||||
$table = $this->fullTableName($table, false);
|
||||
if (!isset($this->_sequenceMap[$table])) {
|
||||
$cache = $this->cacheSources;
|
||||
|
@ -307,8 +307,9 @@ class Postgres extends DboSource {
|
|||
$this->describe($table);
|
||||
$this->cacheSources = $cache;
|
||||
}
|
||||
if (parent::truncate($table)) {
|
||||
if (isset($this->_sequenceMap[$table]) && $reset) {
|
||||
if ($this->execute('DELETE FROM ' . $this->fullTableName($table))) {
|
||||
$table = $this->fullTableName($table, false);
|
||||
if (isset($this->_sequenceMap[$table]) && $reset !== 1) {
|
||||
foreach ($this->_sequenceMap[$table] as $field => $sequence) {
|
||||
$this->_execute("ALTER SEQUENCE \"{$sequence}\" RESTART WITH 1");
|
||||
}
|
||||
|
|
|
@ -1385,6 +1385,9 @@ class Model extends Object {
|
|||
if ($success && $count > 0) {
|
||||
if (!empty($this->data)) {
|
||||
$success = $this->data;
|
||||
if ($created) {
|
||||
$this->data[$this->alias][$this->primaryKey] = $this->id;
|
||||
}
|
||||
}
|
||||
if ($options['callbacks'] === true || $options['callbacks'] === 'after') {
|
||||
$this->Behaviors->trigger('afterSave', array(&$this, $created, $options));
|
||||
|
@ -2235,7 +2238,7 @@ class Model extends Object {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
@ -2282,10 +2285,14 @@ class Model extends Object {
|
|||
$query['order'] = false;
|
||||
return $query;
|
||||
} elseif ($state === 'after') {
|
||||
if (isset($results[0][0]['count'])) {
|
||||
return intval($results[0][0]['count']);
|
||||
} elseif (isset($results[0][$this->alias]['count'])) {
|
||||
return intval($results[0][$this->alias]['count']);
|
||||
foreach (array(0, $this->alias) as $key) {
|
||||
if (isset($results[0][$key]['count'])) {
|
||||
if (count($results) > 1) {
|
||||
return intval(array_sum(Set::extract('/' . $key . '/count', $results)));
|
||||
} else {
|
||||
return intval($results[0][$key]['count']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -2715,6 +2722,13 @@ class Model extends Object {
|
|||
} else {
|
||||
$validator['message'] = __d($validationDomain, $message);
|
||||
}
|
||||
} elseif (is_array($validator['message'])) {
|
||||
if (count($validator['message']) > 1) {
|
||||
$args = array_slice($validator['message'], 1);
|
||||
} else {
|
||||
$args = $validator['rule'];
|
||||
}
|
||||
$validator['message'] = __d($validationDomain, $validator['message'][0], $args);
|
||||
}
|
||||
$this->invalidate($fieldName, $validator['message']);
|
||||
|
||||
|
|
|
@ -612,7 +612,7 @@ class CakeRequest implements ArrayAccess {
|
|||
$acceptTypes = explode(',', $this->header('accept'));
|
||||
foreach ($acceptTypes as $i => $accepted) {
|
||||
if (strpos($accepted, ';') !== false) {
|
||||
list($accepted, $prefValue) = explode(';', $accepted);
|
||||
list($accepted) = explode(';', $accepted);
|
||||
$acceptTypes[$i] = $accepted;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -571,7 +571,6 @@ class CakeResponse {
|
|||
if (is_array($ctype)) {
|
||||
return array_map(array($this, 'mapType'), $ctype);
|
||||
}
|
||||
$keys = array_keys($this->_mimeTypes);
|
||||
|
||||
foreach ($this->_mimeTypes as $alias => $types) {
|
||||
if (is_array($types) && in_array($ctype, $types)) {
|
||||
|
|
|
@ -148,7 +148,7 @@ class CakeRoute {
|
|||
}
|
||||
$names[] = $name;
|
||||
}
|
||||
if (preg_match('#\/\*$#', $route, $m)) {
|
||||
if (preg_match('#\/\*$#', $route)) {
|
||||
$parsed = preg_replace('#/\\\\\*$#', '(?:/(?P<_args_>.*))?', $parsed);
|
||||
$this->_greedy = true;
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ class CakeRoute {
|
|||
if ((!isset($this->options['named']) || !empty($this->options['named'])) && $separatorIsPresent) {
|
||||
list($key, $val) = explode($namedConfig['separator'], $param, 2);
|
||||
$hasRule = isset($rules[$key]);
|
||||
$passIt = (!$hasRule && !$greedy) || ($hasRule && !$this->_matchNamed($key, $val, $rules[$key], $context));
|
||||
$passIt = (!$hasRule && !$greedy) || ($hasRule && !$this->_matchNamed($val, $rules[$key], $context));
|
||||
if ($passIt) {
|
||||
$pass[] = $param;
|
||||
} else {
|
||||
|
@ -306,13 +306,12 @@ class CakeRoute {
|
|||
* Return true if a given named $param's $val matches a given $rule depending on $context. Currently implemented
|
||||
* rule types are controller, action and match that can be combined with each other.
|
||||
*
|
||||
* @param string $param The name of the named parameter
|
||||
* @param string $val The value of the named parameter
|
||||
* @param array $rule The rule(s) to apply, can also be a match string
|
||||
* @param string $context An array with additional context information (controller / action)
|
||||
* @return boolean
|
||||
*/
|
||||
protected function _matchNamed($param, $val, $rule, $context) {
|
||||
protected function _matchNamed($val, $rule, $context) {
|
||||
if ($rule === true || $rule === false) {
|
||||
return $rule;
|
||||
}
|
||||
|
@ -504,4 +503,4 @@ class CakeRoute {
|
|||
return $out;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -513,6 +513,9 @@ class Router {
|
|||
* parameters as the current request parameters that are merged with url arrays
|
||||
* created later in the request.
|
||||
*
|
||||
* Nested requests will create a stack of requests. You can remove requests using
|
||||
* Router::popRequest(). This is done automatically when using Object::requestAction().
|
||||
*
|
||||
* Will accept either a CakeRequest object or an array of arrays. Support for
|
||||
* accepting arrays may be removed in the future.
|
||||
*
|
||||
|
@ -531,6 +534,17 @@ class Router {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops a request off of the request stack. Used when doing requestAction
|
||||
*
|
||||
* @return CakeRequest The request removed from the stack.
|
||||
* @see Router::setRequestInfo()
|
||||
* @see Object::requestAction()
|
||||
*/
|
||||
public static function popRequest() {
|
||||
return array_pop(self::$_requests);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the either the current request object, or the first one.
|
||||
*
|
||||
|
@ -671,12 +685,7 @@ class Router {
|
|||
|
||||
$path = array('base' => null);
|
||||
if (!empty(self::$_requests)) {
|
||||
$currentRequest = self::$_requests[count(self::$_requests) - 1];
|
||||
if (!empty($currentRequest->params['requested'])) {
|
||||
$request = self::$_requests[0];
|
||||
} else {
|
||||
$request = $currentRequest;
|
||||
}
|
||||
$request = self::$_requests[count(self::$_requests) - 1];
|
||||
$params = $request->params;
|
||||
$path = array('base' => $request->base, 'here' => $request->here);
|
||||
}
|
||||
|
|
|
@ -293,6 +293,9 @@ class ExtractTaskTest extends CakeTestCase {
|
|||
$pattern = '#msgid "Post title is required"#';
|
||||
$this->assertPattern($pattern, $result);
|
||||
|
||||
$pattern = '#msgid "You may enter up to %s chars \(minimum is %s chars\)"#';
|
||||
$this->assertPattern($pattern, $result);
|
||||
|
||||
$pattern = '#msgid "Post body is required"#';
|
||||
$this->assertPattern($pattern, $result);
|
||||
|
||||
|
|
|
@ -118,37 +118,42 @@ class ProjectTaskTest extends CakeTestCase {
|
|||
$path = $this->Task->args[0] = TMP . 'tests' . DS . 'bake_test_app';
|
||||
$this->Task->params['skel'] = CAKE . 'Console' . DS . 'Templates' . DS . 'skel';
|
||||
$this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
|
||||
$this->Task->expects($this->at(3))->method('in')->will($this->returnValue('n'));
|
||||
$this->Task->execute();
|
||||
|
||||
$this->assertTrue(is_dir($this->Task->args[0]), 'No project dir');
|
||||
$file = new File($path . DS . 'webroot' . DS . 'index.php');
|
||||
$contents = $file->read();
|
||||
$this->assertPattern('/define\(\'CAKE_CORE_INCLUDE_PATH\', ROOT/', $contents);
|
||||
$this->assertRegExp('/define\(\'CAKE_CORE_INCLUDE_PATH\', .*?DS/', $contents);
|
||||
$file = new File($path . DS . 'webroot' . DS . 'test.php');
|
||||
$contents = $file->read();
|
||||
$this->assertPattern('/define\(\'CAKE_CORE_INCLUDE_PATH\', ROOT/', $contents);
|
||||
$this->assertRegExp('/define\(\'CAKE_CORE_INCLUDE_PATH\', .*?DS/', $contents);
|
||||
}
|
||||
|
||||
/**
|
||||
* test bake with setting CAKE_CORE_INCLUDE_PATH in webroot/index.php
|
||||
* test bake with CakePHP on the include path. The constants should remain commented out.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testExecuteWithSettingIncludePath() {
|
||||
public function testExecuteWithCakeOnIncludePath() {
|
||||
if (!function_exists('ini_set')) {
|
||||
$this->markTestAsSkipped('Not access to ini_set, cannot proceed.');
|
||||
}
|
||||
$restore = ini_get('include_path');
|
||||
ini_set('include_path', CAKE_CORE_INCLUDE_PATH . PATH_SEPARATOR . $restore);
|
||||
|
||||
$path = $this->Task->args[0] = TMP . 'tests' . DS . 'bake_test_app';
|
||||
$this->Task->params['skel'] = CAKE . 'Console' . DS . 'Templates' . DS . 'skel';
|
||||
$this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
|
||||
$this->Task->expects($this->at(3))->method('in')->will($this->returnValue('y'));
|
||||
$this->Task->execute();
|
||||
|
||||
$this->assertTrue(is_dir($this->Task->args[0]), 'No project dir');
|
||||
$file = new File($path . DS . 'webroot' . DS . 'index.php');
|
||||
$contents = $file->read();
|
||||
$this->assertNoPattern('/define\(\'CAKE_CORE_INCLUDE_PATH\', ROOT/', $contents);
|
||||
$file = new File($path . DS . 'webroot' . DS . 'test.php');
|
||||
$contents = $file->read();
|
||||
$this->assertNoPattern('/define\(\'CAKE_CORE_INCLUDE_PATH\', ROOT/', $contents);
|
||||
$contents = file_get_contents($path . DS . 'webroot' . DS . 'index.php');
|
||||
$this->assertRegExp('#//define\(\'CAKE_CORE_INCLUDE_PATH#', $contents);
|
||||
|
||||
$contents = file_get_contents($path . DS . 'webroot' . DS . 'test.php');
|
||||
$this->assertRegExp('#//define\(\'CAKE_CORE_INCLUDE_PATH#', $contents);
|
||||
|
||||
ini_set('include_path', $restore);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -139,6 +139,18 @@ class ConsoleOptionParserTest extends CakeTestCase {
|
|||
$this->assertEquals(array('test' => 'value', 'help' => false), $result[0], 'Short parameter did not parse out');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that adding an option using a two letter short value causes an exception.
|
||||
* As they will not parse correctly.
|
||||
*
|
||||
* @expectedException ConsoleException
|
||||
* @return void
|
||||
*/
|
||||
public function testAddOptionShortOneLetter() {
|
||||
$parser = new ConsoleOptionParser('test', false);
|
||||
$parser->addOption('test', array('short' => 'te'));
|
||||
}
|
||||
|
||||
/**
|
||||
* test adding and using boolean options.
|
||||
*
|
||||
|
@ -255,6 +267,21 @@ class ConsoleOptionParserTest extends CakeTestCase {
|
|||
$result = $parser->parse(array('--name', 'jimmy'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that option values can start with -
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testOptionWithValueStartingWithMinus() {
|
||||
$parser = new ConsoleOptionParser('test', false);
|
||||
$parser->addOption('name')
|
||||
->addOption('age');
|
||||
|
||||
$result = $parser->parse(array('--name', '-foo', '--age', 'old'));
|
||||
$expected = array('name' => '-foo', 'age' => 'old', 'help' => false);
|
||||
$this->assertEquals($expected, $result[0], 'Option values starting with "-" are broken.');
|
||||
}
|
||||
|
||||
/**
|
||||
* test positional argument parsing.
|
||||
*
|
||||
|
@ -496,6 +523,16 @@ TEXT;
|
|||
$this->assertEquals('factory', $parser->command());
|
||||
}
|
||||
|
||||
/**
|
||||
* test that command() inflects the command name.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCommandInflection() {
|
||||
$parser = new ConsoleOptionParser('CommandLine');
|
||||
$this->assertEquals('command_line', $parser->command());
|
||||
}
|
||||
|
||||
/**
|
||||
* test that parse() takes a subcommand argument, and that the subcommand parser
|
||||
* is used.
|
||||
|
@ -529,4 +566,4 @@ TEXT;
|
|||
$this->assertEquals($expected, $result, 'Sub parser did not parse request.');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -210,6 +210,54 @@ TEXT;
|
|||
$this->assertEquals($expected, $result, 'Help does not match');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a long set of options doesn't make useless output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHelpWithLotsOfOptions() {
|
||||
$parser = new ConsoleOptionParser('mycommand', false);
|
||||
$parser
|
||||
->addOption('test', array('help' => 'A test option.'))
|
||||
->addOption('test2', array('help' => 'A test option.'))
|
||||
->addOption('test3', array('help' => 'A test option.'))
|
||||
->addOption('test4', array('help' => 'A test option.'))
|
||||
->addOption('test5', array('help' => 'A test option.'))
|
||||
->addOption('test6', array('help' => 'A test option.'))
|
||||
->addOption('test7', array('help' => 'A test option.'))
|
||||
->addArgument('model', array('help' => 'The model to make.', 'required' => true))
|
||||
->addArgument('other_longer', array('help' => 'Another argument.'));
|
||||
|
||||
$formatter = new HelpFormatter($parser);
|
||||
$result = $formatter->text();
|
||||
$expected = 'cake mycommand [options] <model> [<other_longer>]';
|
||||
$this->assertContains($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a long set of arguments doesn't make useless output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHelpWithLotsOfArguments() {
|
||||
$parser = new ConsoleOptionParser('mycommand', false);
|
||||
$parser
|
||||
->addArgument('test', array('help' => 'A test option.'))
|
||||
->addArgument('test2', array('help' => 'A test option.'))
|
||||
->addArgument('test3', array('help' => 'A test option.'))
|
||||
->addArgument('test4', array('help' => 'A test option.'))
|
||||
->addArgument('test5', array('help' => 'A test option.'))
|
||||
->addArgument('test6', array('help' => 'A test option.'))
|
||||
->addArgument('test7', array('help' => 'A test option.'))
|
||||
->addArgument('model', array('help' => 'The model to make.', 'required' => true))
|
||||
->addArgument('other_longer', array('help' => 'Another argument.'));
|
||||
|
||||
$formatter = new HelpFormatter($parser);
|
||||
$result = $formatter->text();
|
||||
$expected = 'cake mycommand [-h] [arguments]';
|
||||
$this->assertContains($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test help() with options and arguments that have choices.
|
||||
*
|
||||
|
@ -437,4 +485,4 @@ TEXT;
|
|||
$result = $formatter->xml(false);
|
||||
$this->assertInstanceOf('SimpleXmlElement', $result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -453,6 +453,25 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
$this->assertTrue($this->Controller->Security->validatePost($this->Controller));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that validatePost fails if you are missing the session information.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function testValidatePostNoSession() {
|
||||
$this->Controller->Security->startup($this->Controller);
|
||||
$this->Controller->Session->delete('_Token');
|
||||
|
||||
$key = $this->Controller->params['_Token']['key'];
|
||||
$fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877%3AModel.valid';
|
||||
|
||||
$this->Controller->data = array(
|
||||
'Model' => array('username' => 'nate', 'password' => 'foo', 'valid' => '0'),
|
||||
'_Token' => compact('key', 'fields')
|
||||
);
|
||||
$this->assertFalse($this->Controller->Security->validatePost($this->Controller));
|
||||
}
|
||||
|
||||
/**
|
||||
* test that validatePost fails if any of its required fields are missing.
|
||||
*
|
||||
|
@ -1036,6 +1055,23 @@ class SecurityComponentTest extends CakeTestCase {
|
|||
$this->assertTrue($this->Controller->Security->Session->check('_Token'), '_Token was deleted by blackHole %s');
|
||||
}
|
||||
|
||||
/**
|
||||
* test that csrf checks are skipped for request action.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCsrfSkipRequestAction() {
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
|
||||
$this->Security->validatePost = false;
|
||||
$this->Security->csrfCheck = true;
|
||||
$this->Security->csrfExpires = '+10 minutes';
|
||||
$this->Controller->request->params['requested'] = 1;
|
||||
$this->Security->startup($this->Controller);
|
||||
|
||||
$this->assertFalse($this->Controller->failed, 'fail() was called.');
|
||||
}
|
||||
|
||||
/**
|
||||
* test setting
|
||||
*
|
||||
|
|
|
@ -441,12 +441,14 @@ class ObjectTest extends CakeTestCase {
|
|||
'views' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
|
||||
'controllers' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Controller' . DS)
|
||||
), true);
|
||||
$this->assertNull(Router::getRequest(), 'request stack should be empty.');
|
||||
|
||||
$result = $this->object->requestAction('');
|
||||
$this->assertFalse($result);
|
||||
|
||||
$result = $this->object->requestAction('/request_action/test_request_action');
|
||||
$expected = 'This is a test';
|
||||
$this->assertEqual($expected, $result);;
|
||||
$this->assertEqual($expected, $result);
|
||||
|
||||
$result = $this->object->requestAction('/request_action/another_ra_test/2/5');
|
||||
$expected = 7;
|
||||
|
@ -466,6 +468,8 @@ class ObjectTest extends CakeTestCase {
|
|||
$result = $this->object->requestAction('/request_action/normal_request_action');
|
||||
$expected = 'Hello World';
|
||||
$this->assertEqual($expected, $result);
|
||||
|
||||
$this->assertNull(Router::getRequest(), 'requests were not popped off the stack, this will break url generation');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -65,6 +65,7 @@ class TreeBehaviorAfterTest extends CakeTestCase {
|
|||
|
||||
$expected = array('AfterTree' => array('name' => 'Six and One Half Changed in AfterTree::afterSave() but not in database', 'parent_id' => 6, 'lft' => 11, 'rght' => 12));
|
||||
$result = $this->Tree->save(array('AfterTree' => array('name' => 'Six and One Half', 'parent_id' => 6)));
|
||||
$expected['AfterTree']['id'] = $this->Tree->id;
|
||||
$this->assertEqual($expected, $result);
|
||||
|
||||
$expected = array('AfterTree' => array('name' => 'Six and One Half', 'parent_id' => 6, 'lft' => 11, 'rght' => 12, 'id' => 8));
|
||||
|
|
|
@ -1078,6 +1078,11 @@ class TreeBehaviorNumberTest extends CakeTestCase {
|
|||
|
||||
$total = $this->Tree->childCount();
|
||||
$this->assertEqual($total, 6);
|
||||
|
||||
$this->Tree->read(null, $data[$modelClass]['id']);
|
||||
$id = $this->Tree->field('id', array($modelClass . '.name' => '1.2'));
|
||||
$total = $this->Tree->childCount($id);
|
||||
$this->assertEqual($total, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -862,16 +862,24 @@ class BehaviorCollectionTest extends CakeTestCase {
|
|||
|
||||
$Sample->Behaviors->attach('Test', array('beforeSave' => 'off'));
|
||||
$Sample->create();
|
||||
$this->assertIdentical($Sample->save($record), $record);
|
||||
$result = $Sample->save($record);
|
||||
$expected = $record;
|
||||
$expected['Sample']['id'] = $Sample->id;
|
||||
$this->assertIdentical($result, $expected);
|
||||
|
||||
$Sample->Behaviors->attach('Test', array('beforeSave' => 'test'));
|
||||
$Sample->create();
|
||||
$this->assertIdentical($Sample->save($record), $record);
|
||||
$result = $Sample->save($record);
|
||||
$expected = $record;
|
||||
$expected['Sample']['id'] = $Sample->id;
|
||||
$this->assertIdentical($result, $expected);
|
||||
|
||||
$Sample->Behaviors->attach('Test', array('beforeSave' => 'modify'));
|
||||
$expected = Set::insert($record, 'Sample.name', 'sample99 modified before');
|
||||
$Sample->create();
|
||||
$this->assertIdentical($Sample->save($record), $expected);
|
||||
$result = $Sample->save($record);
|
||||
$expected['Sample']['id'] = $Sample->id;
|
||||
$this->assertIdentical($result, $expected);
|
||||
|
||||
$Sample->Behaviors->disable('Test');
|
||||
$this->assertIdentical($Sample->save($record), $record);
|
||||
|
@ -879,20 +887,30 @@ class BehaviorCollectionTest extends CakeTestCase {
|
|||
$Sample->Behaviors->attach('Test', array('beforeSave' => 'off', 'afterSave' => 'on'));
|
||||
$expected = Set::merge($record, array('Sample' => array('aftersave' => 'modified after on create')));
|
||||
$Sample->create();
|
||||
$this->assertIdentical($Sample->save($record), $expected);
|
||||
$result = $Sample->save($record);
|
||||
$expected['Sample']['id'] = $Sample->id;
|
||||
$this->assertEqual($result, $expected);
|
||||
|
||||
$Sample->Behaviors->attach('Test', array('beforeSave' => 'modify', 'afterSave' => 'modify'));
|
||||
$expected = Set::merge($record, array('Sample' => array('name' => 'sample99 modified before modified after on create')));
|
||||
$Sample->create();
|
||||
$this->assertIdentical($Sample->save($record), $expected);
|
||||
$result = $Sample->save($record);
|
||||
$expected['Sample']['id'] = $Sample->id;
|
||||
$this->assertIdentical($result, $expected);
|
||||
|
||||
$Sample->Behaviors->attach('Test', array('beforeSave' => 'off', 'afterSave' => 'test'));
|
||||
$Sample->create();
|
||||
$this->assertIdentical($Sample->save($record), $record);
|
||||
$expected = $record;
|
||||
$result = $Sample->save($record);
|
||||
$expected['Sample']['id'] = $Sample->id;
|
||||
$this->assertIdentical($result, $expected);
|
||||
|
||||
$Sample->Behaviors->attach('Test', array('afterSave' => 'test2'));
|
||||
$Sample->create();
|
||||
$this->assertIdentical($Sample->save($record), $record);
|
||||
$expected = $record;
|
||||
$result = $Sample->save($record);
|
||||
$expected['Sample']['id'] = $Sample->id;
|
||||
$this->assertIdentical($result, $expected);
|
||||
|
||||
$Sample->Behaviors->attach('Test', array('beforeFind' => 'off', 'afterFind' => 'off'));
|
||||
$Sample->recursive = -1;
|
||||
|
@ -996,7 +1014,7 @@ class BehaviorCollectionTest extends CakeTestCase {
|
|||
$Apple->validate['color'] = 'validateField';
|
||||
|
||||
$result = $Apple->save(array('name' => 'Genetically Modified Apple', 'color' => 'Orange'));
|
||||
$this->assertEqual(array_keys($result['Apple']), array('name', 'color', 'modified', 'created'));
|
||||
$this->assertEqual(array_keys($result['Apple']), array('name', 'color', 'modified', 'created', 'id'));
|
||||
|
||||
$Apple->create();
|
||||
$result = $Apple->save(array('name' => 'Regular Apple', 'color' => 'Red'));
|
||||
|
|
|
@ -277,10 +277,10 @@ class AclNodeTest extends CakeTestCase {
|
|||
$this->assertEqual($expected, $result);
|
||||
|
||||
$result = Set::extract($Aco->node('Controller2/action3'), '{n}.DbAcoTest.id');
|
||||
$this->assertFalse($result);
|
||||
$this->assertNull($result);
|
||||
|
||||
$result = Set::extract($Aco->node('Controller2/action3/record5'), '{n}.DbAcoTest.id');
|
||||
$this->assertFalse($result);
|
||||
$this->assertNull($result);
|
||||
|
||||
$result = $Aco->node('');
|
||||
$this->assertEqual($result, null);
|
||||
|
|
|
@ -382,7 +382,7 @@ class ModelReadTest extends BaseModelTest {
|
|||
*/
|
||||
public function testRecursiveUnbind() {
|
||||
$this->skipIf($this->db instanceof Sqlserver, 'The test of testRecursiveUnbind test is not compatible with SQL Server, because it check for time columns.');
|
||||
|
||||
|
||||
$this->loadFixtures('Apple', 'Sample');
|
||||
$TestModel = new Apple();
|
||||
$TestModel->recursive = 2;
|
||||
|
@ -3635,7 +3635,7 @@ class ModelReadTest extends BaseModelTest {
|
|||
*/
|
||||
public function testFindCombinedRelations() {
|
||||
$this->skipIf($this->db instanceof Sqlserver, 'The test of testRecursiveUnbind test is not compatible with SQL Server, because it check for time columns.');
|
||||
|
||||
|
||||
$this->loadFixtures('Apple', 'Sample');
|
||||
$TestModel = new Apple();
|
||||
|
||||
|
@ -6567,7 +6567,7 @@ class ModelReadTest extends BaseModelTest {
|
|||
* @return void
|
||||
*/
|
||||
public function testFindCount() {
|
||||
$this->loadFixtures('User', 'Project');
|
||||
$this->loadFixtures('User', 'Article');
|
||||
|
||||
$TestModel = new User();
|
||||
$this->db->getLog(false, true);
|
||||
|
@ -6583,6 +6583,10 @@ class ModelReadTest extends BaseModelTest {
|
|||
$log = $this->db->getLog();
|
||||
$this->assertTrue(isset($log['log'][0]['query']));
|
||||
$this->assertNoPattern('/ORDER\s+BY/', $log['log'][0]['query']);
|
||||
|
||||
$Article = new Article();
|
||||
$result = $Article->find('count', array('group' => 'Article.user_id'));
|
||||
$this->assertEqual($result, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -679,4 +679,35 @@ class ModelValidationTest extends BaseModelTest {
|
|||
$this->assertEquals($TestModel->validationErrors, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test placeholder replacement when validation message is an array
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testValidationMessageAsArray() {
|
||||
$TestModel = new ValidationTest1();
|
||||
$TestModel->create(array('title' => 'foo'));
|
||||
$TestModel->validate = array(
|
||||
'title' => array(
|
||||
'minLength' => array(
|
||||
'rule' => array('minLength', 6),
|
||||
'message' => array('Minimum length allowed is %d chars'),
|
||||
'last' => false
|
||||
),
|
||||
'between' => array(
|
||||
'rule' => array('between', 5, 15),
|
||||
'message' => array('You may enter up to %s chars (minimum is %s chars)', 14, 6)
|
||||
)
|
||||
)
|
||||
);
|
||||
$TestModel->invalidFields();
|
||||
$expected = array(
|
||||
'title' => array(
|
||||
'Minimum length allowed is 6 chars',
|
||||
'You may enter up to 14 chars (minimum is 6 chars)'
|
||||
)
|
||||
);
|
||||
$this->assertEquals($TestModel->validationErrors, $expected);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,8 +55,9 @@ class ModelWriteTest extends BaseModelTest {
|
|||
'updated' => '2008-01-03 10:56:44'
|
||||
);
|
||||
$result = $TestModel->JoinAsJoinB->save($data);
|
||||
$this->assertEquals($result, array('JoinAsJoinB' => $data));
|
||||
$lastInsertId = $TestModel->JoinAsJoinB->getLastInsertID();
|
||||
$data['id'] = $lastInsertId;
|
||||
$this->assertEquals($result, array('JoinAsJoinB' => $data));
|
||||
$this->assertTrue($lastInsertId != null);
|
||||
|
||||
$result = $TestModel->JoinAsJoinB->findById(1);
|
||||
|
@ -5227,4 +5228,23 @@ class ModelWriteTest extends BaseModelTest {
|
|||
setlocale(LC_ALL, $restore);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test returned array contains primary key when save creates a new record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPkInReturnArrayForCreate() {
|
||||
$this->loadFixtures('Article');
|
||||
$TestModel = new Article();
|
||||
|
||||
$data = array('Article' => array(
|
||||
'user_id' => '1',
|
||||
'title' => 'Fourth Article',
|
||||
'body' => 'Fourth Article Body',
|
||||
'published' => 'Y'
|
||||
));
|
||||
$result = $TestModel->save($data);
|
||||
$this->assertIdentical($result['Article']['id'], $TestModel->id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2271,6 +2271,35 @@ class RouterTest extends CakeTestCase {
|
|||
$this->assertEqual($result->webroot, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that Router::url() uses the first request
|
||||
*/
|
||||
public function testUrlWithRequestAction() {
|
||||
$firstRequest = new CakeRequest('/posts/index');
|
||||
$firstRequest->addParams(array(
|
||||
'plugin' => null,
|
||||
'controller' => 'posts',
|
||||
'action' => 'index'
|
||||
))->addPaths(array('base' => ''));
|
||||
|
||||
$secondRequest = new CakeRequest('/posts/index');
|
||||
$secondRequest->addParams(array(
|
||||
'requested' => 1,
|
||||
'plugin' => null,
|
||||
'controller' => 'comments',
|
||||
'action' => 'listing'
|
||||
))->addPaths(array('base' => ''));
|
||||
|
||||
Router::setRequestInfo($firstRequest);
|
||||
Router::setRequestInfo($secondRequest);
|
||||
|
||||
$result = Router::url(array('base' => false));
|
||||
$this->assertEquals('/comments/listing', $result, 'with second requests, the last should win.');
|
||||
|
||||
Router::popRequest();
|
||||
$result = Router::url(array('base' => false));
|
||||
$this->assertEquals('/posts', $result, 'with second requests, the last should win.');
|
||||
}
|
||||
/**
|
||||
* test that a route object returning a full url is not modified.
|
||||
*
|
||||
|
|
|
@ -98,6 +98,10 @@ class ControllerTestCaseTestController extends AppController {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get a testable concrete class of the test subject
|
||||
*/
|
||||
class TestingControllerTestCase extends ControllerTestCase {}
|
||||
|
||||
/**
|
||||
* ControllerTestCaseTest
|
||||
|
@ -127,7 +131,7 @@ class ControllerTestCaseTest extends CakeTestCase {
|
|||
'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
|
||||
));
|
||||
CakePlugin::loadAll();
|
||||
$this->Case = new ControllerTestCase();
|
||||
$this->Case = new TestingControllerTestCase();
|
||||
Router::reload();
|
||||
}
|
||||
|
||||
|
|
|
@ -244,7 +244,12 @@ class SanitizeTest extends CakeTestCase {
|
|||
$string = "This sentence \t\t\t has lots of \n\n white\nspace \rthat \r\n needs to be \t \n trimmed.";
|
||||
$expected = "This sentence has lots of whitespace that needs to be trimmed.";
|
||||
$result = Sanitize::stripWhitespace($string);
|
||||
$this->assertEqual($expected, $result);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$text = 'I love ßá†ö√ letters.';
|
||||
$result = Sanitize::stripWhitespace($text);
|
||||
$expected = 'I love ßá†ö√ letters.';
|
||||
$this->assertEqual($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -948,7 +948,7 @@ class SetTest extends CakeTestCase {
|
|||
);
|
||||
$result = Set::extract('/ParentNode/name', $hasMany);
|
||||
$expected = array('Second');
|
||||
$this->assertEqual($expected, $result);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
|
@ -982,7 +982,33 @@ class SetTest extends CakeTestCase {
|
|||
)
|
||||
);
|
||||
$result = Set::extract('/Category[id=1]/..', $data);
|
||||
$this->assertEqual($expected, $result);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
'ChildNode' => array('id' => 1),
|
||||
array('name' => 'Item 1')
|
||||
),
|
||||
array(
|
||||
'ChildNode' => array('id' => 2),
|
||||
array('name' => 'Item 2')
|
||||
),
|
||||
);
|
||||
|
||||
$expected = array(
|
||||
'Item 1',
|
||||
'Item 2'
|
||||
);
|
||||
$result = Set::extract('/0/name', $data);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$data = array(
|
||||
array('A1', 'B1'),
|
||||
array('A2', 'B2')
|
||||
);
|
||||
$expected = array('A1', 'A2');
|
||||
$result = Set::extract('/0', $data);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1582,6 +1608,25 @@ class SetTest extends CakeTestCase {
|
|||
$result = Set::extract($a, 'articles.{n}.Article.title');
|
||||
$expected = array('Article 1', 'Article 2', 'Article 3');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$a = new ArrayObject();
|
||||
$a['articles'] = array(
|
||||
array('Article' => array('id' => 1, 'title' => 'Article 1')),
|
||||
array('Article' => array('id' => 2, 'title' => 'Article 2')),
|
||||
array('Article' => array('id' => 3, 'title' => 'Article 3'))
|
||||
);
|
||||
|
||||
$result = Set::extract($a, 'articles.{n}.Article.id');
|
||||
$expected = array(1, 2, 3);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = Set::extract($a, 'articles.{n}.Article.title');
|
||||
$expected = array('Article 1', 'Article 2', 'Article 3');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = Set::extract($a, 'articles.0.Article.title');
|
||||
$expected = 'Article 1';
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -317,6 +317,37 @@ class CacheHelperTest extends CakeTestCase {
|
|||
|
||||
@unlink($filename);
|
||||
}
|
||||
|
||||
function testCacheCallbacks() {
|
||||
$this->Controller->cache_parsing();
|
||||
$this->Controller->params = array(
|
||||
'controller' => 'cache_test',
|
||||
'action' => 'cache_parsing',
|
||||
'url' => array(),
|
||||
'pass' => array(),
|
||||
'named' => array()
|
||||
);
|
||||
$this->Controller->cacheAction = array(
|
||||
'cache_parsing' => array(
|
||||
'duration' => 21600,
|
||||
'callbacks' => true
|
||||
)
|
||||
);
|
||||
$this->Controller->here = '/cacheTest/cache_parsing';
|
||||
$this->Controller->action = 'cache_parsing';
|
||||
|
||||
$View = new View($this->Controller);
|
||||
$result = $View->render('index');
|
||||
|
||||
$filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
|
||||
$this->assertTrue(file_exists($filename));
|
||||
|
||||
$contents = file_get_contents($filename);
|
||||
|
||||
$this->assertPattern('/\$controller->startupProcess\(\);/', $contents);
|
||||
|
||||
@unlink($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* test cacheAction set to a boolean
|
||||
|
@ -551,10 +582,17 @@ class CacheHelperTest extends CakeTestCase {
|
|||
* This test must be uncommented/fixed in next release (1.2+)
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
public function testCacheEmptySections () {
|
||||
*/
|
||||
public function testCacheEmptySections() {
|
||||
$this->Controller->cache_parsing();
|
||||
$this->Controller->cacheAction = array('cacheTest' => 21600);
|
||||
$this->Controller->params = array(
|
||||
'controller' => 'cacheTest',
|
||||
'action' => 'cache_empty_sections',
|
||||
'url' => array(),
|
||||
'pass' => array(),
|
||||
'named' => array()
|
||||
);
|
||||
$this->Controller->cacheAction = array('cache_empty_sections' => 21600);
|
||||
$this->Controller->here = '/cacheTest/cache_empty_sections';
|
||||
$this->Controller->action = 'cache_empty_sections';
|
||||
$this->Controller->layout = 'cache_empty_sections';
|
||||
|
@ -562,7 +600,7 @@ class CacheHelperTest extends CakeTestCase {
|
|||
|
||||
$View = new View($this->Controller);
|
||||
$result = $View->render('cache_empty_sections');
|
||||
$this->assertNoPattern('/cake:nocache/', $result);
|
||||
$this->assertNoPattern('/nocache/', $result);
|
||||
$this->assertNoPattern('/php echo/', $result);
|
||||
$this->assertPattern(
|
||||
'@</title>\s*</head>\s*' .
|
||||
|
@ -574,19 +612,18 @@ class CacheHelperTest extends CakeTestCase {
|
|||
$filename = CACHE . 'views' . DS . 'cachetest_cache_empty_sections.php';
|
||||
$this->assertTrue(file_exists($filename));
|
||||
$contents = file_get_contents($filename);
|
||||
$this->assertNoPattern('/cake:nocache/', $contents);
|
||||
$this->assertNoPattern('/nocache/', $contents);
|
||||
$this->assertPattern(
|
||||
'@<head>\s*<title>Posts</title>\s*' .
|
||||
"<\?php \$x = 1; \?>\s*" .
|
||||
'<\?php \$x \= 1; \?>\s*' .
|
||||
'</head>\s*' .
|
||||
'<body>\s*' .
|
||||
"<\?php \$x\+\+; \?>\s*" .
|
||||
"<\?php \$x\+\+; \?>\s*" .
|
||||
'<\?php \$x\+\+; \?>\s*' .
|
||||
'<\?php \$x\+\+; \?>\s*' .
|
||||
'View Content\s*' .
|
||||
"<\?php \$y = 1; \?>\s*" .
|
||||
"<\?php echo 'cached count is:' . \$x; \?>\s*" .
|
||||
'<\?php \$y = 1; \?>\s*' .
|
||||
'<\?php echo \'cached count is: \' . \$x; \?>\s*' .
|
||||
'@', $contents);
|
||||
@unlink($filename);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -91,7 +91,8 @@ class Contact extends CakeTestModel {
|
|||
'password' => array('type' => 'string', 'null' => '', 'default' => '', 'length' => '255'),
|
||||
'published' => array('type' => 'date', 'null' => true, 'default' => null, 'length' => null),
|
||||
'created' => array('type' => 'date', 'null' => '1', 'default' => '', 'length' => ''),
|
||||
'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null)
|
||||
'updated' => array('type' => 'datetime', 'null' => '1', 'default' => '', 'length' => null),
|
||||
'age' => array('type' => 'integer', 'null' => '', 'default' => '', 'length' => null)
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -825,6 +826,36 @@ class FormHelperTest extends CakeTestCase {
|
|||
'/div'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests correct generation of text fields for double and float fields
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function testTextFieldTypeNumberGenerationForIntegers() {
|
||||
$model = ClassRegistry::getObject('Contact');
|
||||
$model->setSchema(array('foo' => array(
|
||||
'type' => 'integer',
|
||||
'null' => false,
|
||||
'default' => null,
|
||||
'length' => null
|
||||
)));
|
||||
|
||||
$this->Form->create('Contact');
|
||||
$result = $this->Form->input('foo');
|
||||
$expected = array(
|
||||
'div' => array('class' => 'input text'),
|
||||
'label' => array('for' => 'ContactFoo'),
|
||||
'Foo',
|
||||
'/label',
|
||||
array('input' => array(
|
||||
'type' => 'number', 'name' => 'data[Contact][foo]',
|
||||
'id' => 'ContactFoo'
|
||||
)),
|
||||
'/div'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* testFormSecurityMultipleFields method
|
||||
|
@ -1596,7 +1627,7 @@ class FormHelperTest extends CakeTestCase {
|
|||
'label' => array('for'),
|
||||
'Balance',
|
||||
'/label',
|
||||
'input' => array('name', 'type' => 'text', 'maxlength' => 8, 'id'),
|
||||
'input' => array('name', 'type' => 'number', 'maxlength' => 8, 'id'),
|
||||
'/div',
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
|
@ -2400,6 +2431,8 @@ class FormHelperTest extends CakeTestCase {
|
|||
'*/div',
|
||||
array('div' => array('class' => 'input datetime')),
|
||||
'*/div',
|
||||
array('div' => array('class' => 'input number')),
|
||||
'*/div',
|
||||
array('div' => array('class' => 'input select')),
|
||||
'*/div',
|
||||
);
|
||||
|
@ -2423,6 +2456,8 @@ class FormHelperTest extends CakeTestCase {
|
|||
'*/div',
|
||||
array('div' => array('class' => 'input datetime')),
|
||||
'*/div',
|
||||
array('div' => array('class' => 'input number')),
|
||||
'*/div',
|
||||
array('div' => array('class' => 'input select')),
|
||||
'*/div',
|
||||
);
|
||||
|
@ -2447,6 +2482,8 @@ class FormHelperTest extends CakeTestCase {
|
|||
'*/div',
|
||||
array('div' => array('class' => 'input datetime')),
|
||||
'*/div',
|
||||
array('div' => array('class' => 'input number')),
|
||||
'*/div',
|
||||
array('div' => array('class' => 'input select')),
|
||||
'*/div',
|
||||
'/fieldset'
|
||||
|
@ -2471,6 +2508,8 @@ class FormHelperTest extends CakeTestCase {
|
|||
'*/div',
|
||||
array('div' => array('class' => 'input datetime')),
|
||||
'*/div',
|
||||
array('div' => array('class' => 'input number')),
|
||||
'*/div',
|
||||
array('div' => array('class' => 'input select')),
|
||||
'*/div',
|
||||
);
|
||||
|
@ -2498,6 +2537,8 @@ class FormHelperTest extends CakeTestCase {
|
|||
'*/div',
|
||||
array('div' => array('class' => 'input datetime')),
|
||||
'*/div',
|
||||
array('div' => array('class' => 'input number')),
|
||||
'*/div',
|
||||
array('div' => array('class' => 'input select')),
|
||||
'*/div',
|
||||
'/fieldset'
|
||||
|
@ -2526,6 +2567,8 @@ class FormHelperTest extends CakeTestCase {
|
|||
'*/div',
|
||||
array('div' => array('class' => 'input datetime')),
|
||||
'*/div',
|
||||
array('div' => array('class' => 'input number')),
|
||||
'*/div',
|
||||
array('div' => array('class' => 'input select')),
|
||||
'*/div',
|
||||
'/fieldset'
|
||||
|
@ -4582,13 +4625,14 @@ class FormHelperTest extends CakeTestCase {
|
|||
);
|
||||
$this->assertTags($result, $expected);
|
||||
|
||||
$selected = strtotime('2008-10-26 10:33:00');
|
||||
$selected = strtotime('2008-10-26 12:33:00');
|
||||
$result = $this->Form->dateTime('Model.field', 'DMY', '12', array('value' => $selected));
|
||||
$this->assertPattern('/<option[^<>]+value="2008"[^<>]+selected="selected"[^>]*>2008<\/option>/', $result);
|
||||
$this->assertPattern('/<option[^<>]+value="10"[^<>]+selected="selected"[^>]*>10<\/option>/', $result);
|
||||
$this->assertPattern('/<option[^<>]+value="10"[^<>]+selected="selected"[^>]*>October<\/option>/', $result);
|
||||
$this->assertPattern('/<option[^<>]+value="26"[^<>]+selected="selected"[^>]*>26<\/option>/', $result);
|
||||
$this->assertPattern('/<option[^<>]+value="10"[^<>]+selected="selected"[^>]*>10<\/option>/', $result);
|
||||
$this->assertPattern('/<option[^<>]+value="12"[^<>]+selected="selected"[^>]*>12<\/option>/', $result);
|
||||
$this->assertPattern('/<option[^<>]+value="33"[^<>]+selected="selected"[^>]*>33<\/option>/', $result);
|
||||
$this->assertPattern('/<option[^<>]+value="pm"[^<>]+selected="selected"[^>]*>pm<\/option>/', $result);
|
||||
|
||||
$this->Form->create('Contact');
|
||||
$result = $this->Form->input('published');
|
||||
|
@ -5552,6 +5596,35 @@ class FormHelperTest extends CakeTestCase {
|
|||
$this->assertTrue(strpos($result, '<input type="hidden" name="data[extra]" value="value"/>') !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that postButton adds _Token fields.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSecurePostButton() {
|
||||
$this->Form->request->params['_Token'] = array('key' => 'testkey');
|
||||
|
||||
$result = $this->Form->postButton('Delete', '/posts/delete/1');
|
||||
$expected = array(
|
||||
'form' => array(
|
||||
'method' => 'post', 'action' => '/posts/delete/1', 'accept-charset' => 'utf-8',
|
||||
'style' => 'display:none;'
|
||||
),
|
||||
array('div' => array('style' => 'display:none;')),
|
||||
array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
|
||||
array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/')),
|
||||
'/div',
|
||||
'button' => array('type' => 'submit'),
|
||||
'Delete',
|
||||
'/button',
|
||||
array('div' => array('style' => 'display:none;')),
|
||||
array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/')),
|
||||
array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/')),
|
||||
'/div',
|
||||
'/form',
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
}
|
||||
/**
|
||||
* testPostLink method
|
||||
*
|
||||
|
@ -5564,9 +5637,7 @@ class FormHelperTest extends CakeTestCase {
|
|||
'method' => 'post', 'action' => '/posts/delete/1',
|
||||
'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
|
||||
),
|
||||
'div' => array('style' => 'display:none;'),
|
||||
'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
|
||||
'/div',
|
||||
'/form',
|
||||
'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'),
|
||||
'Delete',
|
||||
|
@ -5579,9 +5650,7 @@ class FormHelperTest extends CakeTestCase {
|
|||
'method' => 'post', 'action' => '/posts/delete/1',
|
||||
'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
|
||||
),
|
||||
'div' => array('style' => 'display:none;'),
|
||||
'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
|
||||
'/div',
|
||||
'/form',
|
||||
'a' => array('href' => '#', 'onclick' => 'preg:/if \(confirm\('Confirm\?'\)\) \{ document\.post_\w+\.submit\(\); \} event\.returnValue = false; return false;/'),
|
||||
'Delete',
|
||||
|
@ -5589,7 +5658,35 @@ class FormHelperTest extends CakeTestCase {
|
|||
));
|
||||
|
||||
$result = $this->Form->postLink('Delete', '/posts/delete', array('data' => array('id' => 1)));
|
||||
$this->assertTrue(strpos($result, '<input type="hidden" name="data[id]" value="1"/>') !== false);
|
||||
$this->assertContains('<input type="hidden" name="data[id]" value="1"/>', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that postLink adds _Token fields.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSecurePostLink() {
|
||||
$this->Form->request->params['_Token'] = array('key' => 'testkey');
|
||||
|
||||
$result = $this->Form->postLink('Delete', '/posts/delete/1');
|
||||
$expected = array(
|
||||
'form' => array(
|
||||
'method' => 'post', 'action' => '/posts/delete/1',
|
||||
'name' => 'preg:/post_\w+/', 'id' => 'preg:/post_\w+/', 'style' => 'display:none;'
|
||||
),
|
||||
array('input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST')),
|
||||
array('input' => array('type' => 'hidden', 'name' => 'data[_Token][key]', 'value' => 'testkey', 'id' => 'preg:/Token\d+/')),
|
||||
'div' => array('style' => 'display:none;'),
|
||||
array('input' => array('type' => 'hidden', 'name' => 'data[_Token][fields]', 'value' => 'preg:/[\w\d%]+/', 'id' => 'preg:/TokenFields\d+/')),
|
||||
array('input' => array('type' => 'hidden', 'name' => 'data[_Token][unlocked]', 'value' => '', 'id' => 'preg:/TokenUnlocked\d+/')),
|
||||
'/div',
|
||||
'/form',
|
||||
'a' => array('href' => '#', 'onclick' => 'preg:/document\.post_\w+\.submit\(\); event\.returnValue = false; return false;/'),
|
||||
'Delete',
|
||||
'/a'
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7170,6 +7267,12 @@ class FormHelperTest extends CakeTestCase {
|
|||
'input' => array('type' => 'text', 'name' => 'data[User][query]', 'id' => 'UserQuery', 'value' => 'test')
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
|
||||
$result = $this->Form->input('User.website', array('type' => 'url', 'value' => 'http://domain.tld', 'div' => false, 'label' => false));
|
||||
$expected = array(
|
||||
'input' => array('type' => 'url', 'name' => 'data[User][website]', 'id' => 'UserWebsite', 'value' => 'http://domain.tld')
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -601,6 +601,12 @@ class HtmlHelperTest extends CakeTestCase {
|
|||
);
|
||||
$this->assertTags($result, $expected);
|
||||
|
||||
$result = $this->Html->script('http://example.com/test.json');
|
||||
$expected = array(
|
||||
'script' => array('type' => 'text/javascript', 'src' => 'http://example.com/test.json')
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
|
||||
$result = $this->Html->script('/plugin/js/jquery-1.3.2.js?someparam=foo');
|
||||
$expected = array(
|
||||
'script' => array('type' => 'text/javascript', 'src' => '/plugin/js/jquery-1.3.2.js?someparam=foo')
|
||||
|
|
|
@ -452,8 +452,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
$this->Paginator->request->params['paging']['Article']['page'] = 1;
|
||||
$result = $this->Paginator->next('Next');
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/admin/users/index/page:2', 'class' => 'next', 'rel' => 'next'),
|
||||
'span' => array('class' => 'next'),
|
||||
'a' => array('href' => '/admin/users/index/page:2', 'rel' => 'next'),
|
||||
'Next',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -553,8 +553,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
|
||||
$result = $this->Paginator->next('next', array('url' => $options));
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/members/posts/index/page:3', 'class' => 'next', 'rel' => 'next'),
|
||||
'span' => array('class' => 'next'),
|
||||
'a' => array('href' => '/members/posts/index/page:3', 'rel' => 'next'),
|
||||
'next',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -563,8 +563,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
|
||||
$result = $this->Paginator->prev('prev', array('url' => $options));
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/members/posts/index/page:1', 'class' => 'prev', 'rel' => 'prev'),
|
||||
'span' => array('class' => 'prev'),
|
||||
'a' => array('href' => '/members/posts/index/page:1', 'rel' => 'prev'),
|
||||
'prev',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -688,8 +688,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
|
||||
$result = $this->Paginator->next('Next');
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/articles/index/2/page:2/foo:bar', 'class' => 'next', 'rel' => 'next'),
|
||||
'span' => array('class' => 'next'),
|
||||
'a' => array('href' => '/articles/index/2/page:2/foo:bar', 'rel' => 'next'),
|
||||
'Next',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -737,8 +737,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
$this->Paginator->request->params['paging']['Client']['prevPage'] = true;
|
||||
$result = $this->Paginator->prev('<< Previous', null, null, array('class' => 'disabled'));
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/index/page:1', 'class' => 'prev', 'rel' => 'prev'),
|
||||
'span' => array('class' => 'prev'),
|
||||
'a' => array('href' => '/index/page:1', 'rel' => 'prev'),
|
||||
'<< Previous',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -747,8 +747,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
|
||||
$result = $this->Paginator->next('Next');
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/index/page:3', 'class' => 'next', 'rel' => 'next'),
|
||||
'span' => array('class' => 'next'),
|
||||
'a' => array('href' => '/index/page:3', 'rel' => 'next'),
|
||||
'Next',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -757,8 +757,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
|
||||
$result = $this->Paginator->next('Next', array('tag' => 'li'));
|
||||
$expected = array(
|
||||
'<li',
|
||||
'a' => array('href' => '/index/page:3', 'class' => 'next', 'rel' => 'next'),
|
||||
'li' => array('class' => 'next'),
|
||||
'a' => array('href' => '/index/page:3', 'rel' => 'next'),
|
||||
'Next',
|
||||
'/a',
|
||||
'/li'
|
||||
|
@ -767,8 +767,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
|
||||
$result = $this->Paginator->prev('<< Previous', array('escape' => true));
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/index/page:1', 'class' => 'prev', 'rel' => 'prev'),
|
||||
'span' => array('class' => 'prev'),
|
||||
'a' => array('href' => '/index/page:1', 'rel' => 'prev'),
|
||||
'<< Previous',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -777,8 +777,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
|
||||
$result = $this->Paginator->prev('<< Previous', array('escape' => false));
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/index/page:1', 'class' => 'prev', 'rel' => 'prev'),
|
||||
'span' => array('class' => 'prev'),
|
||||
'a' => array('href' => '/index/page:1', 'rel' => 'prev'),
|
||||
'preg:/<< Previous/',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -845,10 +845,9 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
$this->Paginator->request->params['paging']['Client']['prevPage'] = true;
|
||||
$result = $this->Paginator->prev('<< Previous', null, null, array('class' => 'disabled'));
|
||||
$expected = array(
|
||||
'<span',
|
||||
'span' => array('class' => 'prev'),
|
||||
'a' => array(
|
||||
'href' => '/index/page:1/limit:3/sort:Client.name/direction:DESC',
|
||||
'class' => 'prev',
|
||||
'rel' => 'prev'
|
||||
),
|
||||
'<< Previous',
|
||||
|
@ -859,10 +858,9 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
|
||||
$result = $this->Paginator->next('Next');
|
||||
$expected = array(
|
||||
'<span',
|
||||
'span' => array('class' => 'next'),
|
||||
'a' => array(
|
||||
'href' => '/index/page:3/limit:3/sort:Client.name/direction:DESC',
|
||||
'class' => 'next',
|
||||
'rel' => 'next'
|
||||
),
|
||||
'Next',
|
||||
|
@ -890,8 +888,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
);
|
||||
$result = $this->Paginator->prev('Prev');
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/index/page:1/limit:10', 'class' => 'prev', 'rel' => 'prev'),
|
||||
'span' => array('class' => 'prev'),
|
||||
'a' => array('href' => '/index/page:1/limit:10', 'rel' => 'prev'),
|
||||
'Prev',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -912,8 +910,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
$this->Paginator->options(array('url' => array(12, 'page' => 3)));
|
||||
$result = $this->Paginator->prev('Prev', array('url' => array('foo' => 'bar')));
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/index/12/page:1/limit:10/foo:bar', 'class' => 'prev', 'rel' => 'prev'),
|
||||
'span' => array('class' => 'prev'),
|
||||
'a' => array('href' => '/index/12/page:1/limit:10/foo:bar', 'rel' => 'prev'),
|
||||
'Prev',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -952,8 +950,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
|
||||
$result = $this->Paginator->next('Next >>', array('escape' => false));
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/index/page:2', 'class' => 'next', 'rel' => 'next'),
|
||||
'span' => array('class' => 'next'),
|
||||
'a' => array('href' => '/index/page:2', 'rel' => 'next'),
|
||||
'preg:/Next >>/',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -998,8 +996,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
);
|
||||
$result = $this->Paginator->next('Next', array('model' => 'Client'));
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/index/page:2', 'class' => 'next', 'rel' => 'next'),
|
||||
'span' => array('class' => 'next'),
|
||||
'a' => array('href' => '/index/page:2', 'rel' => 'next'),
|
||||
'Next',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -1522,15 +1520,15 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
'paramType' => 'named'
|
||||
)
|
||||
);
|
||||
$result = $this->Paginator->numbers();
|
||||
$result = $this->Paginator->numbers(array('class' => 'page-link'));
|
||||
$expected = array(
|
||||
array('span' => array()), array('a' => array('href' => '/index/page:1/sort:Client.name/direction:DESC')), '1', '/a', '/span',
|
||||
array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:1/sort:Client.name/direction:DESC')), '1', '/a', '/span',
|
||||
' | ',
|
||||
array('span' => array('class' => 'current')), '2', '/span',
|
||||
array('span' => array('class' => 'current page-link')), '2', '/span',
|
||||
' | ',
|
||||
array('span' => array()), array('a' => array('href' => '/index/page:3/sort:Client.name/direction:DESC')), '3', '/a', '/span',
|
||||
array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:3/sort:Client.name/direction:DESC')), '3', '/a', '/span',
|
||||
' | ',
|
||||
array('span' => array()), array('a' => array('href' => '/index/page:4/sort:Client.name/direction:DESC')), '4', '/a', '/span',
|
||||
array('span' => array('class' => 'page-link')), array('a' => array('href' => '/index/page:4/sort:Client.name/direction:DESC')), '4', '/a', '/span',
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
|
||||
|
@ -1760,9 +1758,9 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testFirstAndLastTag() {
|
||||
$result = $this->Paginator->first('<<', array('tag' => 'li'));
|
||||
$result = $this->Paginator->first('<<', array('tag' => 'li', 'class' => 'first'));
|
||||
$expected = array(
|
||||
'<li',
|
||||
'li' => array('class' => 'first'),
|
||||
'a' => array('href' => '/index/page:1', 'rel' => 'first'),
|
||||
'<<',
|
||||
'/a',
|
||||
|
@ -1770,15 +1768,14 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
);
|
||||
$this->assertTags($result, $expected);
|
||||
|
||||
$result = $this->Paginator->last(2, array('tag' => 'li'));
|
||||
|
||||
$result = $this->Paginator->last(2, array('tag' => 'li', 'class' => 'last'));
|
||||
$expected = array(
|
||||
'...',
|
||||
'<li',
|
||||
'li' => array('class' => 'last'),
|
||||
array('a' => array('href' => '/index/page:6')), '6', '/a',
|
||||
'/li',
|
||||
' | ',
|
||||
'<li',
|
||||
array('li' => array('class' => 'last')),
|
||||
array('a' => array('href' => '/index/page:7')), '7', '/a',
|
||||
'/li',
|
||||
);
|
||||
|
@ -2132,10 +2129,9 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
|
||||
$result = $this->Paginator->next('Next');
|
||||
$expected = array(
|
||||
'<span',
|
||||
'span' => array('class' => 'next'),
|
||||
'a' => array(
|
||||
'href' => '/officespace/accounts/index/page:2/sort:Article.title/direction:asc',
|
||||
'class' => 'next',
|
||||
'rel' => 'next'
|
||||
),
|
||||
'Next',
|
||||
|
@ -2230,8 +2226,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
|
||||
$result = $this->Paginator->next('Next');
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/?page=3', 'class' => 'next', 'rel' => 'next'),
|
||||
'span' => array('class' => 'next'),
|
||||
'a' => array('href' => '/?page=3', 'rel' => 'next'),
|
||||
'Next',
|
||||
'/a',
|
||||
'/span'
|
||||
|
@ -2240,8 +2236,8 @@ class PaginatorHelperTest extends CakeTestCase {
|
|||
|
||||
$result = $this->Paginator->prev('Prev');
|
||||
$expected = array(
|
||||
'<span',
|
||||
'a' => array('href' => '/?page=1', 'class' => 'prev', 'rel' => 'prev'),
|
||||
'span' => array('class' => 'prev'),
|
||||
'a' => array('href' => '/?page=1', 'rel' => 'prev'),
|
||||
'Prev',
|
||||
'/a',
|
||||
'/span'
|
||||
|
|
|
@ -27,10 +27,16 @@ class PersisterOne extends AppModel {
|
|||
public $hasMany = array('Comment', 'TestPlugin.TestPluginComment');
|
||||
public $validate = array(
|
||||
'title' => array(
|
||||
'rule' => array('custom', '.*'),
|
||||
'allowEmpty' => true,
|
||||
'required' => false,
|
||||
'message' => 'Post title is required'
|
||||
'custom' => array(
|
||||
'rule' => array('custom', '.*'),
|
||||
'allowEmpty' => true,
|
||||
'required' => false,
|
||||
'message' => 'Post title is required'
|
||||
),
|
||||
'between' => array(
|
||||
'rule' => array('between', 5, 15),
|
||||
'message' => array('You may enter up to %s chars (minimum is %s chars)', 14, 6)
|
||||
)
|
||||
),
|
||||
'body' => array(
|
||||
'first_rule' => array(
|
||||
|
|
|
@ -98,7 +98,7 @@ class InterceptContentHelper extends Helper {
|
|||
*
|
||||
* @package Cake.TestSuite
|
||||
*/
|
||||
class ControllerTestCase extends CakeTestCase {
|
||||
abstract class ControllerTestCase extends CakeTestCase {
|
||||
|
||||
/**
|
||||
* The controller to test in testAction
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* @since CakePHP(tm) v 2.0
|
||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
require_once dirname(__FILE__) . '/base_coverage_report.php';
|
||||
App::uses('BaseCoverageReport', 'TestSuite/Coverage');
|
||||
|
||||
PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
|
||||
|
||||
|
@ -56,4 +56,4 @@ class TextCoverageReport extends BaseCoverageReport {
|
|||
return "$filename : $percentCovered%\n";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
include_once dirname(__FILE__) . DS . 'cake_base_reporter.php';
|
||||
App::uses('CakeBaseReporter', 'TestSuite/Reporter');
|
||||
App::uses('TextCoverageReport', 'TestSuite/Coverage');
|
||||
|
||||
PHP_CodeCoverage_Filter::getInstance()->addFileToBlacklist(__FILE__, 'DEFAULT');
|
||||
|
||||
|
@ -91,7 +92,7 @@ class CakeTextReporter extends CakeBaseReporter {
|
|||
echo 'Peak memory: ' . number_format(memory_get_peak_usage()) . " bytes\n";
|
||||
|
||||
if (isset($this->params['codeCoverage']) && $this->params['codeCoverage']) {
|
||||
$coverage = $result->getCodeCoverageInformation();
|
||||
$coverage = $result->getCodeCoverage()->getSummary();
|
||||
echo $this->paintCoverage($coverage);
|
||||
}
|
||||
}
|
||||
|
@ -184,8 +185,6 @@ class CakeTextReporter extends CakeBaseReporter {
|
|||
* @return string
|
||||
*/
|
||||
public function paintCoverage($coverage) {
|
||||
$file = dirname(dirname(__FILE__)) . '/coverage/text_coverage_report.php';
|
||||
include $file;
|
||||
$reporter = new TextCoverageReport($coverage, $this);
|
||||
echo $reporter->report();
|
||||
}
|
||||
|
|
|
@ -186,13 +186,14 @@ class Debugger {
|
|||
}
|
||||
|
||||
/**
|
||||
* Formats and outputs the contents of the supplied variable.
|
||||
* Recursively formats and outputs the contents of the supplied variable.
|
||||
*
|
||||
*
|
||||
* @param mixed $var the variable to dump
|
||||
* @return void
|
||||
* @see Debugger::exportVar()
|
||||
* @link http://book.cakephp.org/view/1191/Using-the-Debugger-Class
|
||||
*/
|
||||
*/
|
||||
public static function dump($var) {
|
||||
pr(self::exportVar($var));
|
||||
}
|
||||
|
@ -396,12 +397,22 @@ class Debugger {
|
|||
}
|
||||
|
||||
/**
|
||||
* Grabs an excerpt from a file and highlights a given line of code
|
||||
* Grabs an excerpt from a file and highlights a given line of code.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* `Debugger::excerpt('/path/to/file', 100, 4);`
|
||||
*
|
||||
* The above would return an array of 8 items. The 4th item would be the provided line,
|
||||
* and would be wrapped in `<span class="code-highlight"></span>`. All of the lines
|
||||
* are processed with highlight_string() as well, so they have basic PHP syntax highlighting
|
||||
* applied.
|
||||
*
|
||||
* @param string $file Absolute path to a PHP file
|
||||
* @param integer $line Line number to highlight
|
||||
* @param integer $context Number of lines of context to extract above and below $line
|
||||
* @return array Set of lines highlighted
|
||||
* @see http://php.net/highlight_string
|
||||
* @link http://book.cakephp.org/view/1191/Using-the-Debugger-Class
|
||||
*/
|
||||
public static function excerpt($file, $line, $context = 2) {
|
||||
|
@ -431,6 +442,20 @@ class Debugger {
|
|||
/**
|
||||
* Converts a variable to a string for debug output.
|
||||
*
|
||||
* *Note:* The following keys will have their contents replaced with
|
||||
* `*****`:
|
||||
*
|
||||
* - password
|
||||
* - login
|
||||
* - host
|
||||
* - database
|
||||
* - port
|
||||
* - prefix
|
||||
* - schema
|
||||
*
|
||||
* This is done to protect database credentials, which could be accidentally
|
||||
* shown in an error message if CakePHP is deployed in development mode.
|
||||
*
|
||||
* @param string $var Variable to convert
|
||||
* @param integer $recursion
|
||||
* @return string Variable as a formatted string
|
||||
|
|
|
@ -360,7 +360,7 @@ class Folder {
|
|||
if (@chmod($fullpath, intval($mode, 8))) {
|
||||
$this->__messages[] = __d('cake_dev', '%s changed to %s', $fullpath, $mode);
|
||||
} else {
|
||||
$this->__errors[] = __d('cake_deverloper', '%s NOT changed to %s', $fullpath, $mode);
|
||||
$this->__errors[] = __d('cake_dev', '%s NOT changed to %s', $fullpath, $mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ class Sanitize {
|
|||
*/
|
||||
public static function stripWhitespace($str) {
|
||||
$r = preg_replace('/[\n\r\t]+/', '', $str);
|
||||
return preg_replace('/\s{2,}/', ' ', $r);
|
||||
return preg_replace('/\s{2,}/u', ' ', $r);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -129,27 +129,6 @@ class Set {
|
|||
return Set::__map($val, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array value of $array. If $array is null, it will return
|
||||
* the current array Set holds. If it is an object of type Set, it
|
||||
* will return its value. If it is another object, its object variables.
|
||||
* If it is anything else but an array, it will return an array whose first
|
||||
* element is $array.
|
||||
*
|
||||
* @param mixed $array Data from where to get the array.
|
||||
* @return array Array from $array.
|
||||
*/
|
||||
private function __array($array) {
|
||||
if (empty($array)) {
|
||||
$array = array();
|
||||
} elseif (is_object($array)) {
|
||||
$array = get_object_vars($array);
|
||||
} elseif (!is_array($array)) {
|
||||
$array = array($array);
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the given value as an object. If $value is an object,
|
||||
* it returns $value. Otherwise it maps $value as an object of
|
||||
|
@ -420,14 +399,9 @@ class Set {
|
|||
'key' => $key,
|
||||
'item' => array_keys($context['item']),
|
||||
);
|
||||
} elseif (($key === $token || (ctype_digit($token) && $key == $token) || $token === '.')) {
|
||||
$context['trace'][] = $key;
|
||||
$matches[] = array(
|
||||
'trace' => $context['trace'],
|
||||
'key' => $key,
|
||||
'item' => $context['item'],
|
||||
);
|
||||
} elseif (is_array($context['item']) && array_key_exists($token, $context['item'])) {
|
||||
} elseif (is_array($context['item'])
|
||||
&& array_key_exists($token, $context['item'])
|
||||
&& !(strval($key) === strval($token) && count($tokens) == 1 && $tokens[0] === '.')) {
|
||||
$items = $context['item'][$token];
|
||||
if (!is_array($items)) {
|
||||
$items = array($items);
|
||||
|
@ -466,6 +440,13 @@ class Set {
|
|||
'item' => $item,
|
||||
);
|
||||
}
|
||||
} elseif ($key === $token || (ctype_digit($token) && $key == $token) || $token === '.') {
|
||||
$context['trace'][] = $key;
|
||||
$matches[] = array(
|
||||
'trace' => $context['trace'],
|
||||
'key' => $key,
|
||||
'item' => $context['item'],
|
||||
);
|
||||
}
|
||||
}
|
||||
if ($conditions) {
|
||||
|
@ -586,12 +567,13 @@ class Set {
|
|||
return $data;
|
||||
}
|
||||
if (is_object($data)) {
|
||||
$data = get_object_vars($data);
|
||||
if (!($data instanceof ArrayAccess || $data instanceof Traversable)) {
|
||||
$data = get_object_vars($data);
|
||||
}
|
||||
}
|
||||
if (!is_array($data)) {
|
||||
return $data;
|
||||
if (empty($data)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_string($path) && strpos($path, '{') !== false) {
|
||||
$path = String::tokenize($path, '.', '{', '}');
|
||||
} elseif (is_string($path)) {
|
||||
|
@ -898,7 +880,9 @@ class Set {
|
|||
}
|
||||
|
||||
if (is_object($data)) {
|
||||
$data = get_object_vars($data);
|
||||
if (!($data instanceof ArrayAccess || $data instanceof Traversable)) {
|
||||
$data = get_object_vars($data);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($path1)) {
|
||||
|
|
|
@ -55,7 +55,7 @@ class CacheHelper extends AppHelper {
|
|||
public function afterRender($viewFile) {
|
||||
$caching = (($this->_View->cacheAction != false)) && (Configure::read('Cache.check') === true);
|
||||
if ($caching) {
|
||||
$this->cache($viewFile, $this->_View->output, false);
|
||||
$this->_View->output = $this->cache($viewFile, $this->_View->output, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,11 +68,18 @@ class CacheHelper extends AppHelper {
|
|||
public function afterLayout($layoutFile) {
|
||||
$caching = (($this->_View->cacheAction != false)) && (Configure::read('Cache.check') === true);
|
||||
if ($caching) {
|
||||
$this->cache($layoutFile, $this->_View->output, true);
|
||||
$this->_View->output = $this->cache($layoutFile, $this->_View->output, true);
|
||||
}
|
||||
$this->_View->output = preg_replace('/<!--\/?nocache-->/', '', $this->_View->output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Counter used for counting nocache section tags.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $_counter = 0;
|
||||
|
||||
/**
|
||||
* Main method used to cache a view
|
||||
*
|
||||
|
@ -120,10 +127,13 @@ class CacheHelper extends AppHelper {
|
|||
}
|
||||
|
||||
if ($cacheTime != '' && $cacheTime > 0) {
|
||||
$out = preg_replace_callback('/<!--nocache-->/', array($this, '_replaceSection'), $out);
|
||||
|
||||
$this->_parseFile($file, $out);
|
||||
if ($cache === true) {
|
||||
$cached = $this->_parseOutput($out);
|
||||
$this->_writeFile($cached, $cacheTime, $useCallbacks);
|
||||
$out = $this->_stripTags($out);
|
||||
}
|
||||
return $out;
|
||||
} else {
|
||||
|
@ -144,7 +154,7 @@ class CacheHelper extends AppHelper {
|
|||
} elseif ($file = fileExistsInPath($file)) {
|
||||
$file = file_get_contents($file);
|
||||
}
|
||||
preg_match_all('/(<!--nocache-->(?<=<!--nocache-->)[\\s\\S]*?(?=<!--\/nocache-->)<!--\/nocache-->)/i', $cache, $outputResult, PREG_PATTERN_ORDER);
|
||||
preg_match_all('/(<!--nocache:\d{3}-->(?<=<!--nocache:\d{3}-->)[\\s\\S]*?(?=<!--\/nocache-->)<!--\/nocache-->)/i', $cache, $outputResult, PREG_PATTERN_ORDER);
|
||||
preg_match_all('/(?<=<!--nocache-->)([\\s\\S]*?)(?=<!--\/nocache-->)/i', $file, $fileResult, PREG_PATTERN_ORDER);
|
||||
$fileResult = $fileResult[0];
|
||||
$outputResult = $outputResult[0];
|
||||
|
@ -171,6 +181,30 @@ class CacheHelper extends AppHelper {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Munges the output from a view with cache tags, and numbers the sections.
|
||||
* This helps solve issues with empty/duplicate content.
|
||||
*
|
||||
* @param string $content The content to munge.
|
||||
* @return string The content with cake:nocache tags replaced.
|
||||
*/
|
||||
function _replaceSection($matches) {
|
||||
$this->_counter += 1;
|
||||
return sprintf('<!--nocache:%03d-->', $this->_counter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip cake:nocache tags from a string. Since View::render()
|
||||
* only removes un-numbered nocache tags, remove all the numbered ones.
|
||||
* This is the complement to _replaceSection.
|
||||
*
|
||||
* @param string $content String to remove tags from.
|
||||
* @return string String with tags removed.
|
||||
*/
|
||||
function _stripTags($content) {
|
||||
return preg_replace('#<!--/?nocache(\:\d{3})?-->#', '', $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the output and replace cache tags
|
||||
*
|
||||
|
|
|
@ -198,7 +198,7 @@ class FormHelper extends AppHelper {
|
|||
}
|
||||
|
||||
if ($key === 'key') {
|
||||
return $this->fieldset[$model]['key'];
|
||||
return $this->fieldset[$model]['key'] = $object->primaryKey;
|
||||
}
|
||||
|
||||
if ($key === 'fields') {
|
||||
|
@ -437,18 +437,7 @@ class FormHelper extends AppHelper {
|
|||
$htmlAttributes = array_merge($options, $htmlAttributes);
|
||||
|
||||
$this->fields = array();
|
||||
if (!empty($this->request->params['_Token'])) {
|
||||
$append .= $this->hidden('_Token.key', array(
|
||||
'value' => $this->request->params['_Token']['key'], 'id' => 'Token' . mt_rand(),
|
||||
'secure' => self::SECURE_SKIP
|
||||
));
|
||||
|
||||
if (!empty($this->request['_Token']['unlockedFields'])) {
|
||||
foreach ((array)$this->request['_Token']['unlockedFields'] as $unlocked) {
|
||||
$this->_unlockedFields[] = $unlocked;
|
||||
}
|
||||
}
|
||||
}
|
||||
$append .= $this->_csrfField();
|
||||
|
||||
if (!empty($append)) {
|
||||
$append = $this->Html->useTag('block', ' style="display:none;"', $append);
|
||||
|
@ -460,6 +449,27 @@ class FormHelper extends AppHelper {
|
|||
return $this->Html->useTag('form', $action, $htmlAttributes) . $append;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a CSRF input if the _Token is present.
|
||||
* Used to secure forms in conjunction with SecurityComponent
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _csrfField() {
|
||||
if (empty($this->request->params['_Token'])) {
|
||||
return '';
|
||||
}
|
||||
if (!empty($this->request['_Token']['unlockedFields'])) {
|
||||
foreach ((array)$this->request['_Token']['unlockedFields'] as $unlocked) {
|
||||
$this->_unlockedFields[] = $unlocked;
|
||||
}
|
||||
}
|
||||
return $this->hidden('_Token.key', array(
|
||||
'value' => $this->request->params['_Token']['key'], 'id' => 'Token' . mt_rand(),
|
||||
'secure' => self::SECURE_SKIP
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes an HTML form, cleans up values set by FormHelper::create(), and writes hidden
|
||||
* input fields where appropriate.
|
||||
|
@ -911,7 +921,8 @@ class FormHelper extends AppHelper {
|
|||
'string' => 'text', 'datetime' => 'datetime',
|
||||
'boolean' => 'checkbox', 'timestamp' => 'datetime',
|
||||
'text' => 'textarea', 'time' => 'time',
|
||||
'date' => 'date', 'float' => 'text'
|
||||
'date' => 'date', 'float' => 'number',
|
||||
'integer' => 'number'
|
||||
);
|
||||
|
||||
if (isset($this->map[$type])) {
|
||||
|
@ -1065,6 +1076,9 @@ class FormHelper extends AppHelper {
|
|||
case 'textarea':
|
||||
$input = $this->textarea($fieldName, $options + array('cols' => '30', 'rows' => '6'));
|
||||
break;
|
||||
case 'url':
|
||||
$input = $this->text($fieldName, array('type' => 'url') + $options);
|
||||
break;
|
||||
default:
|
||||
$input = $this->{$type}($fieldName, $options);
|
||||
}
|
||||
|
@ -1497,13 +1511,18 @@ class FormHelper extends AppHelper {
|
|||
$formName = uniqid('post_');
|
||||
$formUrl = $this->url($url);
|
||||
$out = $this->Html->useTag('form', $formUrl, array('name' => $formName, 'id' => $formName, 'style' => 'display:none;', 'method' => 'post'));
|
||||
$out .= $this->Html->useTag('block', ' style="display:none;"', $this->Html->useTag('hidden', '_method', ' value="POST"'));
|
||||
$out .= $this->Html->useTag('hidden', '_method', ' value="POST"');
|
||||
$out .= $this->_csrfField();
|
||||
|
||||
$fields = array();
|
||||
if (isset($options['data']) && is_array($options['data'])) {
|
||||
foreach ($options['data'] as $key => $value) {
|
||||
$fields[$key] = $value;
|
||||
$out .= $this->hidden($key, array('value' => $value, 'id' => false));
|
||||
}
|
||||
unset($options['data']);
|
||||
}
|
||||
$out .= $this->secure($fields);
|
||||
$out .= $this->Html->useTag('formend');
|
||||
|
||||
$url = '#';
|
||||
|
@ -2063,6 +2082,8 @@ class FormHelper extends AppHelper {
|
|||
if (($time[0] > 12) && $timeFormat == '12') {
|
||||
$time[0] = $time[0] - 12;
|
||||
$meridian = 'pm';
|
||||
} elseif ($time[0] == '12' && $timeFormat == '12') {
|
||||
$meridian = 'pm';
|
||||
} elseif ($time[0] == '00' && $timeFormat == '12') {
|
||||
$time[0] = 12;
|
||||
} elseif ($time[0] >= 12) {
|
||||
|
|
|
@ -152,7 +152,16 @@ class HtmlHelper extends AppHelper {
|
|||
);
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
* Constructor
|
||||
*
|
||||
* ### Settings
|
||||
*
|
||||
* - `configFile` A file containing an array of tags you wish to redefine.
|
||||
*
|
||||
* ### Customizing tag sets
|
||||
*
|
||||
* Using the `configFile` option you can redefine the tag HtmlHelper will use.
|
||||
* The file named should be compatible with HtmlHelper::loadConfig().
|
||||
*
|
||||
* @param View $View The View this helper is being attached to.
|
||||
* @param array $settings Configuration settings for the helper.
|
||||
|
@ -349,6 +358,20 @@ class HtmlHelper extends AppHelper {
|
|||
/**
|
||||
* Creates a link element for CSS stylesheets.
|
||||
*
|
||||
* ### Usage
|
||||
*
|
||||
* Include one CSS file:
|
||||
*
|
||||
* `echo $this->Html->css('styles.css');`
|
||||
*
|
||||
* Include multiple CSS files:
|
||||
*
|
||||
* `echo $this->Html->css(array('one.css', 'two.css'));`
|
||||
*
|
||||
* Add the stylesheet to the `$scripts_for_layout` layout var:
|
||||
*
|
||||
* `$this->Html->css('styles.css', null, array('inline' => false));`
|
||||
*
|
||||
* ### Options
|
||||
*
|
||||
* - `inline` If set to false, the generated tag appears in the head tag of the layout. Defaults to true
|
||||
|
@ -418,7 +441,20 @@ class HtmlHelper extends AppHelper {
|
|||
* If the filename is prefixed with "/", the path will be relative to the base path of your
|
||||
* application. Otherwise, the path will be relative to your JavaScript path, usually webroot/js.
|
||||
*
|
||||
* Can include one or many Javascript files.
|
||||
*
|
||||
* ### Usage
|
||||
*
|
||||
* Include one script file:
|
||||
*
|
||||
* `echo $this->Html->script('styles.js');`
|
||||
*
|
||||
* Include multiple script files:
|
||||
*
|
||||
* `echo $this->Html->script(array('one.js', 'two.js'));`
|
||||
*
|
||||
* Add the script file to the `$scripts_for_layout` layout var:
|
||||
*
|
||||
* `$this->Html->script('styles.js', null, array('inline' => false));`
|
||||
*
|
||||
* ### Options
|
||||
*
|
||||
|
@ -900,7 +936,39 @@ class HtmlHelper extends AppHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Load Html configs
|
||||
* Load Html tag configuration.
|
||||
*
|
||||
* Loads a file from APP/Config that contains tag data. By default the file is expected
|
||||
* to be compatible with PhpReader:
|
||||
*
|
||||
* `$this->Html->loadConfig('tags.php');`
|
||||
*
|
||||
* tags.php could look like:
|
||||
*
|
||||
* {{{
|
||||
* $tags = array(
|
||||
* 'meta' => '<meta %s>'
|
||||
* );
|
||||
* }}}
|
||||
*
|
||||
* If you wish to store tag definitions in another format you can give an array
|
||||
* containing the file name, and reader class name:
|
||||
*
|
||||
* `$this->Html->loadConfig(array('tags.ini', 'ini'));`
|
||||
*
|
||||
* Its expected that the `tags` index will exist from any configuration file that is read.
|
||||
* You can also specify the path to read the configuration file from, if APP/Config is not
|
||||
* where the file is.
|
||||
*
|
||||
* `$this->Html->loadConfig('tags.php', APP . 'Lib' . DS);`
|
||||
*
|
||||
* Configuration files can define the following sections:
|
||||
*
|
||||
* - `tags` The tags to replace.
|
||||
* - `minimizedAttributes` The attributes that are represented like `disabled="disabled"`
|
||||
* - `docTypes` Additional doctypes to use.
|
||||
* - `attributeFormat` Format for long attributes e.g. `'%s="%s"'`
|
||||
* - `minimizedAttributeFormat` Format for minimized attributes e.g. `'%s="%s"'`
|
||||
*
|
||||
* @param mixed $configFile String with the config file (load using PhpReader) or an array with file and reader name
|
||||
* @param string $path Path with config file
|
||||
|
|
|
@ -461,7 +461,7 @@ class PaginatorHelper extends AppHelper {
|
|||
$url = array_merge(array('page' => $paging['page'] + ($which == 'Prev' ? $step * -1 : $step)), $url);
|
||||
|
||||
if ($this->{$check}($model)) {
|
||||
return $this->Html->tag($tag, $this->link($title, $url, array_merge($options, compact('escape', 'class'))));
|
||||
return $this->Html->tag($tag, $this->link($title, $url, array_merge($options, compact('escape'))), compact('class'));
|
||||
} else {
|
||||
unset($options['rel']);
|
||||
return $this->Html->tag($tag, $title, array_merge($options, compact('escape', 'class')));
|
||||
|
@ -644,7 +644,7 @@ class PaginatorHelper extends AppHelper {
|
|||
}
|
||||
|
||||
$defaults = array(
|
||||
'tag' => 'span', 'before' => null, 'after' => null, 'model' => $this->defaultModel(),
|
||||
'tag' => 'span', 'before' => null, 'after' => null, 'model' => $this->defaultModel(), 'class' => null,
|
||||
'modulus' => '8', 'separator' => ' | ', 'first' => null, 'last' => null, 'ellipsis' => '...',
|
||||
);
|
||||
$options += $defaults;
|
||||
|
@ -659,7 +659,7 @@ class PaginatorHelper extends AppHelper {
|
|||
extract($options);
|
||||
unset($options['tag'], $options['before'], $options['after'], $options['model'],
|
||||
$options['modulus'], $options['separator'], $options['first'], $options['last'],
|
||||
$options['ellipsis']
|
||||
$options['ellipsis'], $options['class']
|
||||
);
|
||||
|
||||
$out = '';
|
||||
|
@ -680,32 +680,36 @@ class PaginatorHelper extends AppHelper {
|
|||
if ($first && $start > 1) {
|
||||
$offset = ($start <= (int)$first) ? $start - 1 : $first;
|
||||
if ($offset < $start - 1) {
|
||||
$out .= $this->first($offset, array('tag' => $tag, 'separator' => $separator, 'ellipsis' => $ellipsis));
|
||||
$out .= $this->first($offset, compact('tag', 'separator', 'ellipsis', 'class'));
|
||||
} else {
|
||||
$out .= $this->first($offset, array('tag' => $tag, 'after' => $separator, 'separator' => $separator));
|
||||
$out .= $this->first($offset, compact('tag', 'separator', 'class') + array('after' => $separator));
|
||||
}
|
||||
}
|
||||
|
||||
$out .= $before;
|
||||
|
||||
for ($i = $start; $i < $params['page']; $i++) {
|
||||
$out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options))
|
||||
$out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'))
|
||||
. $separator;
|
||||
}
|
||||
|
||||
$out .= $this->Html->tag($tag, $params['page'], array('class' => 'current'));
|
||||
$currentClass = 'current';
|
||||
if ($class) {
|
||||
$currentClass .= ' ' . $class;
|
||||
}
|
||||
$out .= $this->Html->tag($tag, $params['page'], array('class' => $currentClass));
|
||||
if ($i != $params['pageCount']) {
|
||||
$out .= $separator;
|
||||
}
|
||||
|
||||
$start = $params['page'] + 1;
|
||||
for ($i = $start; $i < $end; $i++) {
|
||||
$out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options))
|
||||
$out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'))
|
||||
. $separator;
|
||||
}
|
||||
|
||||
if ($end != $params['page']) {
|
||||
$out .= $this->Html->tag($tag, $this->link($i, array('page' => $end), $options));
|
||||
$out .= $this->Html->tag($tag, $this->link($i, array('page' => $end), $options), compact('class'));
|
||||
}
|
||||
|
||||
$out .= $after;
|
||||
|
@ -713,9 +717,9 @@ class PaginatorHelper extends AppHelper {
|
|||
if ($last && $end < $params['pageCount']) {
|
||||
$offset = ($params['pageCount'] < $end + (int)$last) ? $params['pageCount'] - $end : $last;
|
||||
if ($offset <= $last && $params['pageCount'] - $end > $offset) {
|
||||
$out .= $this->last($offset, array('tag' => $tag, 'separator' => $separator, 'ellipsis' => $ellipsis));
|
||||
$out .= $this->last($offset, compact('tag', 'separator', 'ellipsis', 'class'));
|
||||
} else {
|
||||
$out .= $this->last($offset, array('tag' => $tag, 'before' => $separator, 'separator' => $separator));
|
||||
$out .= $this->last($offset, compact('tag', 'separator', 'class') + array('before' => $separator));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -724,9 +728,13 @@ class PaginatorHelper extends AppHelper {
|
|||
|
||||
for ($i = 1; $i <= $params['pageCount']; $i++) {
|
||||
if ($i == $params['page']) {
|
||||
$out .= $this->Html->tag($tag, $i, array('class' => 'current'));
|
||||
$currentClass = 'current';
|
||||
if ($class) {
|
||||
$currentClass .= ' ' . $class;
|
||||
}
|
||||
$out .= $this->Html->tag($tag, $i, array('class' => $currentClass));
|
||||
} else {
|
||||
$out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options));
|
||||
$out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'));
|
||||
}
|
||||
if ($i != $params['pageCount']) {
|
||||
$out .= $separator;
|
||||
|
@ -771,7 +779,8 @@ class PaginatorHelper extends AppHelper {
|
|||
'after' => null,
|
||||
'model' => $this->defaultModel(),
|
||||
'separator' => ' | ',
|
||||
'ellipsis' => '...'
|
||||
'ellipsis' => '...',
|
||||
'class' => null
|
||||
),
|
||||
(array)$options);
|
||||
|
||||
|
@ -782,7 +791,7 @@ class PaginatorHelper extends AppHelper {
|
|||
return false;
|
||||
}
|
||||
extract($options);
|
||||
unset($options['tag'], $options['after'], $options['model'], $options['separator'], $options['ellipsis']);
|
||||
unset($options['tag'], $options['after'], $options['model'], $options['separator'], $options['ellipsis'], $options['class']);
|
||||
|
||||
$out = '';
|
||||
|
||||
|
@ -791,7 +800,7 @@ class PaginatorHelper extends AppHelper {
|
|||
$after = $ellipsis;
|
||||
}
|
||||
for ($i = 1; $i <= $first; $i++) {
|
||||
$out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options));
|
||||
$out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'));
|
||||
if ($i != $first) {
|
||||
$out .= $separator;
|
||||
}
|
||||
|
@ -799,7 +808,7 @@ class PaginatorHelper extends AppHelper {
|
|||
$out .= $after;
|
||||
} elseif ($params['page'] > 1 && is_string($first)) {
|
||||
$options += array('rel' => 'first');
|
||||
$out = $this->Html->tag($tag, $this->link($first, array('page' => 1), $options))
|
||||
$out = $this->Html->tag($tag, $this->link($first, array('page' => 1), $options), compact('class'))
|
||||
. $after;
|
||||
}
|
||||
return $out;
|
||||
|
@ -836,6 +845,7 @@ class PaginatorHelper extends AppHelper {
|
|||
'model' => $this->defaultModel(),
|
||||
'separator' => ' | ',
|
||||
'ellipsis' => '...',
|
||||
'class' => null
|
||||
),
|
||||
(array)$options);
|
||||
|
||||
|
@ -847,7 +857,7 @@ class PaginatorHelper extends AppHelper {
|
|||
}
|
||||
|
||||
extract($options);
|
||||
unset($options['tag'], $options['before'], $options['model'], $options['separator'], $options['ellipsis']);
|
||||
unset($options['tag'], $options['before'], $options['model'], $options['separator'], $options['ellipsis'], $options['class']);
|
||||
|
||||
$out = '';
|
||||
$lower = $params['pageCount'] - $last + 1;
|
||||
|
@ -857,7 +867,7 @@ class PaginatorHelper extends AppHelper {
|
|||
$before = $ellipsis;
|
||||
}
|
||||
for ($i = $lower; $i <= $params['pageCount']; $i++) {
|
||||
$out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options));
|
||||
$out .= $this->Html->tag($tag, $this->link($i, array('page' => $i), $options), compact('class'));
|
||||
if ($i != $params['pageCount']) {
|
||||
$out .= $separator;
|
||||
}
|
||||
|
@ -866,8 +876,8 @@ class PaginatorHelper extends AppHelper {
|
|||
} elseif ($params['page'] < $params['pageCount'] && is_string($last)) {
|
||||
$options += array('rel' => 'last');
|
||||
$out = $before . $this->Html->tag(
|
||||
$tag, $this->link($last, array('page' => $params['pageCount']), $options
|
||||
));
|
||||
$tag, $this->link($last, array('page' => $params['pageCount']), $options), compact('class')
|
||||
);
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
|
|
@ -23,18 +23,17 @@ if (!defined('E_DEPRECATED')) {
|
|||
}
|
||||
error_reporting(E_ALL & ~E_DEPRECATED);
|
||||
|
||||
/**
|
||||
* If the index.php file is used instead of an .htaccess file
|
||||
* or if the user can not set the web root to use the public
|
||||
* directory we will define ROOT there, otherwise we set it
|
||||
* here.
|
||||
*/
|
||||
if (!defined('ROOT')) {
|
||||
define('ROOT', '../');
|
||||
}
|
||||
if (!defined('WEBROOT_DIR')) {
|
||||
define('WEBROOT_DIR', 'webroot');
|
||||
}
|
||||
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
|
||||
define('CAKE_CORE_INCLUDE_PATH', dirname(dirname(__FILE__)));
|
||||
}
|
||||
|
||||
if (!defined('CORE_PATH')) {
|
||||
define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
|
||||
}
|
||||
|
||||
if (!defined('WEBROOT_DIR')) {
|
||||
define('WEBROOT_DIR', 'webroot');
|
||||
}
|
||||
|
||||
/**
|
||||
* Path to the cake directory.
|
||||
|
|