/all commands to pull [n] records from the live tables, where [n] is either --count or the default of 10'),
'short' => 'r',
'boolean' => true
))->epilog(__d('cake_console', 'Omitting all arguments and options will enter into an interactive mode.'));;
@@ -91,7 +91,7 @@ class FixtureTask extends BakeTask {
/**
* Execution method always used for tasks
- * Handles dispatching to interactive, named, or all processess.
+ * Handles dispatching to interactive, named, or all processeses.
*
* @return void
*/
@@ -137,7 +137,7 @@ class FixtureTask extends BakeTask {
protected function _interactive() {
$this->DbConfig->interactive = $this->Model->interactive = $this->interactive = true;
$this->hr();
- $this->out(sprintf("Bake Fixture\nPath: %s", $this->path));
+ $this->out(__d('cake_console', "Bake Fixture\nPath: %s", $this->path));
$this->hr();
if (!isset($this->connection)) {
@@ -254,7 +254,7 @@ class FixtureTask extends BakeTask {
$this->Template->set($vars);
$content = $this->Template->generate('classes', 'fixture');
- $this->out("\nBaking test fixture for $model...", 1, Shell::QUIET);
+ $this->out("\n" . __d('cake_console', 'Baking test fixture for %s...', $model), 1, Shell::QUIET);
$this->createFile($path . $filename, $content);
return $content;
}
diff --git a/lib/Cake/Console/Command/Task/ModelTask.php b/lib/Cake/Console/Command/Task/ModelTask.php
index a8aa79e68..70f6dff99 100644
--- a/lib/Cake/Console/Command/Task/ModelTask.php
+++ b/lib/Cake/Console/Command/Task/ModelTask.php
@@ -168,7 +168,7 @@ class ModelTask extends BakeTask {
*/
protected function _interactive() {
$this->hr();
- $this->out(sprintf("Bake Model\nPath: %s", $this->path));
+ $this->out(__d('cake_console', "Bake Model\nPath: %s", $this->path));
$this->hr();
$this->interactive = true;
@@ -215,7 +215,7 @@ class ModelTask extends BakeTask {
$this->hr();
$this->out(__d('cake_console', 'The following Model will be created:'));
$this->hr();
- $this->out("Name: " . $currentModelName);
+ $this->out(__d('cake_console', "Name: %s", $currentModelName));
if ($this->connection !== 'default') {
$this->out(__d('cake_console', "DB Config: %s", $this->connection));
@@ -561,7 +561,7 @@ class ModelTask extends BakeTask {
* Find the hasAndBelongsToMany relations and add them to associations list
*
* @param object $model Model instance being generated
- * @param array $associations Array of inprogress associations
+ * @param array $associations Array of in-progress associations
* @return array $associations with hasAndBelongsToMany added in.
*/
public function findHasAndBelongsToMany($model, $associations) {
@@ -738,7 +738,7 @@ class ModelTask extends BakeTask {
$path = $this->getPath();
$filename = $path . $name . '.php';
- $this->out("\nBaking model class for $name...", 1, Shell::QUIET);
+ $this->out("\n" . __d('cake_console', 'Baking model class for %s...', $name), 1, Shell::QUIET);
$this->createFile($filename, $out);
ClassRegistry::flush();
return $out;
diff --git a/lib/Cake/Console/Command/Task/PluginTask.php b/lib/Cake/Console/Command/Task/PluginTask.php
index 8c7f2ed50..e7d754048 100644
--- a/lib/Cake/Console/Command/Task/PluginTask.php
+++ b/lib/Cake/Console/Command/Task/PluginTask.php
@@ -185,10 +185,10 @@ class PluginTask extends Shell {
*/
public function getOptionParser() {
$parser = parent::getOptionParser();
- return $parser->description(
+ return $parser->description(__d('cake_console',
'Create the directory structure, AppModel and AppController classes for a new plugin. ' .
'Can create plugins in any of your bootstrapped plugin paths.'
- )->addArgument('name', array(
+ ))->addArgument('name', array(
'help' => __d('cake_console', 'CamelCased name of the plugin to create.')
));
diff --git a/lib/Cake/Console/Command/Task/ProjectTask.php b/lib/Cake/Console/Command/Task/ProjectTask.php
index 28e06b853..190f99819 100644
--- a/lib/Cake/Console/Command/Task/ProjectTask.php
+++ b/lib/Cake/Console/Command/Task/ProjectTask.php
@@ -357,7 +357,7 @@ class ProjectTask extends Shell {
}
if ($this->interactive) {
$this->hr();
- $this->out('You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/config/core.php to use prefix routing.');
+ $this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/config/core.php to use prefix routing.'));
$this->out(__d('cake_console', 'What would you like the prefix route to be?'));
$this->out(__d('cake_console', 'Example: www.example.com/admin/controller'));
while ($admin == '') {
@@ -365,7 +365,7 @@ class ProjectTask extends Shell {
}
if ($this->cakeAdmin($admin) !== true) {
$this->out(__d('cake_console', 'Unable to write to /app/config/core.php.'));
- $this->out('You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/config/core.php to use prefix routing.');
+ $this->out(__d('cake_console', 'You need to enable Configure::write(\'Routing.prefixes\',array(\'admin\')) in /app/config/core.php to use prefix routing.'));
$this->_stop();
}
return $admin . '_';
diff --git a/lib/Cake/Console/Command/Task/TestTask.php b/lib/Cake/Console/Command/Task/TestTask.php
index 014988c56..991c9d754 100644
--- a/lib/Cake/Console/Command/Task/TestTask.php
+++ b/lib/Cake/Console/Command/Task/TestTask.php
@@ -142,7 +142,7 @@ class TestTask extends BakeTask {
if ($this->plugin) {
$plugin = $this->plugin . '.';
}
- $this->out("\nBaking test case for $className $type...", 1, Shell::QUIET);
+ $this->out("\n" . __d('cake_console', 'Baking test case for %s %s ...', $className, $type), 1, Shell::QUIET);
$this->Template->set('fixtures', $this->_fixtures);
$this->Template->set('plugin', $plugin);
diff --git a/lib/Cake/Console/Command/Task/ViewTask.php b/lib/Cake/Console/Command/Task/ViewTask.php
index 03f6c4f3f..ab3bf784e 100644
--- a/lib/Cake/Console/Command/Task/ViewTask.php
+++ b/lib/Cake/Console/Command/Task/ViewTask.php
@@ -367,7 +367,7 @@ class ViewTask extends BakeTask {
if (empty($content)) {
return false;
}
- $this->out("\nBaking `$action` view file...", 1, Shell::QUIET);
+ $this->out("\n" . __d('cake_console', 'Baking `%s` view file...', $action), 1, Shell::QUIET);
$path = $this->getPath();
$filename = $path . $this->controllerPath . DS . Inflector::underscore($action) . '.ctp';
return $this->createFile($filename, $content);
diff --git a/lib/Cake/Console/Command/TestsuiteShell.php b/lib/Cake/Console/Command/TestsuiteShell.php
index 07d9cf4c9..0d4de9de8 100644
--- a/lib/Cake/Console/Command/TestsuiteShell.php
+++ b/lib/Cake/Console/Command/TestsuiteShell.php
@@ -41,8 +41,8 @@ class TestsuiteShell extends Shell {
public function getOptionParser() {
$parser = new ConsoleOptionParser($this->name);
$parser->description(array(
- 'The CakePHP Testsuite allows you to run test cases from the command line',
- 'If run with no command line arguments, a list of available core test cases will be shown'
+ __d('cake_console', 'The CakePHP Testsuite allows you to run test cases from the command line'),
+ __d('cake_console', 'If run with no command line arguments, a list of available core test cases will be shown')
))->addArgument('category', array(
'help' => __d('cake_console', 'app, core or name of a plugin.'),
'required' => true
@@ -157,7 +157,7 @@ class TestsuiteShell extends Shell {
}
/**
- * Initialization method installs Simpletest and loads all plugins
+ * Initialization method installs PHPUnit and loads all plugins
*
* @return void
*/
diff --git a/lib/Cake/Console/Command/UpgradeShell.php b/lib/Cake/Console/Command/UpgradeShell.php
new file mode 100644
index 000000000..0e645568c
--- /dev/null
+++ b/lib/Cake/Console/Command/UpgradeShell.php
@@ -0,0 +1,554 @@
+ 'Controller',
+ 'Component' => 'Controller/Component',
+ 'Model' => 'Model',
+ 'Behavior' => 'Model/Behavior',
+ 'Datasource' => 'Model/Datasource',
+ 'Dbo' => 'Model/Datasource/Database',
+ 'View' => 'View',
+ 'Helper' => 'View/Helper',
+ 'Shell' => 'Console/Command',
+ 'Task' => 'Console/Command/Task',
+ 'Case' => 'tests/Case',
+ 'Fixture' => 'tests/Fixture',
+ 'Error' => 'Lib/Error',
+ );
+
+/**
+ * Shell startup, prints info message about dry run.
+ *
+ * @return void
+ */
+ function startup() {
+ parent::startup();
+ if ($this->params['dry-run']) {
+ $this->out('Dry-run mode enabled!', 1, Shell::QUIET);
+ }
+ if ($this->params['git'] && !is_dir('.git')) {
+ $this->out('No git repository detected!', 1, Shell::QUIET);
+ }
+ }
+
+/**
+ * Run all upgrade steps one at a time
+ *
+ * @access public
+ * @return void
+ */
+ function all() {
+ foreach($this->OptionParser->subcommands() as $command) {
+ $name = $command->name();
+ if ($name === 'all') {
+ continue;
+ }
+ $this->out('Running ' . $name);
+ $this->$name();
+ }
+ }
+
+/**
+ * Move files and folders to their new homes
+ *
+ * Moves folders containing files which cannot necessarily be autodetected (libs and templates)
+ * and then looks for all php files except vendors, and moves them to where Cake 2.0 expects
+ * to find them.
+ *
+ * @access public
+ * @return void
+ */
+ function locations() {
+ $cwd = getcwd();
+
+ if (is_dir('plugins')) {
+
+ $Folder = new Folder('plugins');
+ list($plugins) = $Folder->read();
+ foreach($plugins as $plugin) {
+ chdir($cwd . DS . 'plugins' . DS . $plugin);
+ $this->locations();
+ }
+ $this->_files = array();
+ chdir($cwd);
+ }
+
+ $moves = array(
+ 'libs' => 'Lib',
+ 'vendors' . DS . 'shells' . DS . 'templates' => 'Console' . DS . 'templates',
+ );
+ foreach($moves as $old => $new) {
+ if (is_dir($old)) {
+ $this->out("Moving $old to $new");
+ if (!$this->params['dry-run']) {
+ $Folder = new Folder($old);
+ $Folder->move($new);
+ }
+ if ($this->params['git']) {
+ exec('git mv -f ' . escapeshellarg($old) . ' ' . escapeshellarg($new));
+ }
+ }
+ }
+ $sourceDirs = array(
+ '.' => array('recursive' => false),
+ 'Console',
+ 'Controller',
+ 'controllers',
+ 'Lib' => array('checkFolder' => false),
+ 'Model',
+ 'models',
+ 'tests',
+ 'View',
+ 'views',
+ 'vendors/shells',
+ );
+
+ $defaultOptions = array(
+ 'recursive' => true,
+ 'checkFolder' => true,
+ );
+ foreach($sourceDirs as $dir => $options) {
+ if (is_numeric($dir)) {
+ $dir = $options;
+ $options = array();
+ }
+ $options = array_merge($defaultOptions, $options);
+ $this->_movePhpFiles($dir, $options);
+ }
+ }
+
+/**
+ * Update helpers.
+ *
+ * - Converts helpers usage to new format.
+ *
+ * @return void
+ */
+ function helpers() {
+ $this->_paths = array_diff(App::path('views'), App::core('views'));
+
+ if (!empty($this->params['plugin'])) {
+ $this->_paths = array(App::pluginPath($this->params['plugin']) . 'views' . DS);
+ }
+
+ $patterns = array();
+ $helpers = App::objects('helper');
+ $plugins = App::objects('plugin');
+ $pluginHelpers = array();
+ foreach ($plugins as $plugin) {
+ $pluginHelpers = array_merge(
+ $pluginHelpers,
+ App::objects('helper', App::pluginPath($plugin) . DS . 'views' . DS . 'helpers' . DS, false)
+ );
+ }
+ $helpers = array_merge($pluginHelpers, $helpers);
+ foreach ($helpers as $helper) {
+ $oldHelper = strtolower(substr($helper, 0, 1)).substr($helper, 1);
+ $patterns[] = array(
+ "\${$oldHelper} to \$this->{$helper}",
+ "/\\\${$oldHelper}->/",
+ "\\\$this->{$helper}->"
+ );
+ }
+
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Update i18n.
+ *
+ * - Removes extra true param.
+ * - Add the echo to __*() calls that didn't need them before.
+ *
+ * @return void
+ */
+ function i18n() {
+ $this->_paths = array(
+ APP
+ );
+ if (!empty($this->params['plugin'])) {
+ $this->_paths = array(App::pluginPath($this->params['plugin']));
+ }
+
+ $patterns = array(
+ array(
+ '_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Upgrade the removed basics functions.
+ *
+ * - a(*) -> array(*)
+ * - e(*) -> echo *
+ * - ife(*, *, *) -> empty(*) ? * : *
+ * - a(*) -> array(*)
+ * - r(*, *, *) -> str_replace(*, *, *)
+ * - up(*) -> strtoupper(*)
+ * - low(*, *, *) -> strtolower(*)
+ * - getMicrotime() -> microtime(true)
+ *
+ * @return void
+ */
+ public function basics() {
+ $this->_paths = array(
+ APP
+ );
+ if (!empty($this->params['plugin'])) {
+ $this->_paths = array(App::pluginPath($this->params['plugin']));
+ }
+ $patterns = array(
+ array(
+ 'a(*) -> array(*)',
+ '/\ba\((.*)\)/',
+ 'array(\1)'
+ ),
+ array(
+ 'e(*) -> echo *',
+ '/\be\((.*)\)/',
+ 'echo \1'
+ ),
+ array(
+ 'ife(*, *, *) -> empty(*) ? * : *',
+ '/ife\((.*), (.*), (.*)\)/',
+ 'empty(\1) ? \2 : \3'
+ ),
+ array(
+ 'r(*, *, *) -> str_replace(*, *, *)',
+ '/\br\(/',
+ 'str_replace('
+ ),
+ array(
+ 'up(*) -> strtoupper(*)',
+ '/\bup\(/',
+ 'strtoupper('
+ ),
+ array(
+ 'low(*) -> strtolower(*)',
+ '/\blow\(/',
+ 'strtolower('
+ ),
+ array(
+ 'getMicrotime() -> microtime(true)',
+ '/getMicrotime\(\)/',
+ 'microtime(true)'
+ ),
+ );
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Update the properties moved to CakeRequest.
+ *
+ * @return void
+ */
+ public function request() {
+ $views = array_diff(App::path('views'), App::core('views'));
+ $controllers = array_diff(App::path('controllers'), App::core('controllers'), array(APP));
+ $components = array_diff(App::path('components'), App::core('components'));
+
+ $this->_paths = array_merge($views, $controllers, $components);
+
+ if (!empty($this->params['plugin'])) {
+ $pluginPath = App::pluginPath($this->params['plugin']);
+ $this->_paths = array(
+ $pluginPath . 'controllers' . DS,
+ $pluginPath . 'controllers' . DS . 'components' .DS,
+ $pluginPath . 'views' . DS,
+ );
+ }
+ $patterns = array(
+ array(
+ '$this->data -> $this->request->data',
+ '/(\$this->data\b(?!\())/',
+ '$this->request->data'
+ ),
+ array(
+ '$this->params -> $this->request->params',
+ '/(\$this->params\b(?!\())/',
+ '$this->request->params'
+ ),
+ array(
+ '$this->webroot -> $this->request->webroot',
+ '/(\$this->webroot\b(?!\())/',
+ '$this->request->webroot'
+ ),
+ array(
+ '$this->base -> $this->request->base',
+ '/(\$this->base\b(?!\())/',
+ '$this->request->base'
+ ),
+ array(
+ '$this->here -> $this->request->here',
+ '/(\$this->here\b(?!\())/',
+ '$this->request->here'
+ ),
+ array(
+ '$this->action -> $this->request->action',
+ '/(\$this->action\b(?!\())/',
+ '$this->request->action'
+ ),
+ );
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Update Configure::read() calls with no params.
+ *
+ * @return void
+ */
+ public function configure() {
+ $this->_paths = array(
+ APP
+ );
+ if (!empty($this->params['plugin'])) {
+ $this->_paths = array(App::pluginPath($this->params['plugin']));
+ }
+ $patterns = array(
+ array(
+ "Configure::read() -> Configure::read('debug')",
+ '/Configure::read\(\)/',
+ 'Configure::read(\'debug\')'
+ ),
+ );
+ $this->_filesRegexpUpdate($patterns);
+ }
+
+/**
+ * Move application php files to where they now should be
+ *
+ * Find all php files in the folder (honoring recursive) and determine where cake expects the file to be
+ * If the file is not exactly where cake expects it - move it.
+ *
+ * @param mixed $path
+ * @param mixed $options array(recursive, checkFolder)
+ * @access protected
+ * @return void
+ */
+ protected function _movePhpFiles($path, $options) {
+ if (!is_dir($path)) {
+ return;
+ }
+
+ $paths = $this->_paths;
+
+ $this->_paths = array($path);
+ $this->_files = array();
+ if ($options['recursive']) {
+ $this->_findFiles('php');
+ } else {
+ $this->_files = scandir($path);
+ foreach($this->_files as $i => $file) {
+ if (strlen($file) < 5 || substr($file, -4) !== '.php') {
+ unset($this->_files[$i]);
+ }
+ }
+ }
+
+ $cwd = getcwd();
+ foreach ($this->_files as &$file) {
+ $file = $cwd . DS . $file;
+
+ $contents = file_get_contents($file);
+ preg_match('@class (\S*) .*{@', $contents, $match);
+ if (!$match) {
+ continue;
+ }
+
+ $class = $match[1];
+
+ if (substr($class, 0, 3) === 'Dbo') {
+ $type = 'Dbo';
+ } else {
+ preg_match('@([A-Z][^A-Z]*)$@', $class, $match);
+ if ($match) {
+ $type = $match[1];
+ } else {
+ $type = 'unknown';
+ }
+ }
+
+ preg_match('@^.*[\\\/]plugins[\\\/](.*?)[\\\/]@', $file, $match);
+ $base = $cwd . DS;
+ $plugin = false;
+ if ($match) {
+ $base = $match[0];
+ $plugin = $match[1];
+ }
+
+ if ($options['checkFolder'] && !empty($this->_map[$type])) {
+ $folder = str_replace('/', DS, $this->_map[$type]);
+ $new = $base . $folder . DS . $class . '.php';
+ } else {
+ $new = dirname($file) . DS . $class . '.php';
+ }
+
+ if ($file === $new) {
+ continue;
+ }
+
+ $dir = dirname($new);
+ if (!is_dir($dir)) {
+ new Folder($dir, true);
+ }
+
+ $this->out('Moving ' . $file . ' to ' . $new, 1, Shell::VERBOSE);
+ if (!$this->params['dry-run']) {
+ if ($this->params['git']) {
+ exec('git mv -f ' . escapeshellarg($file) . ' ' . escapeshellarg($new));
+ } else {
+ rename($file, $new);
+ }
+ }
+ }
+
+ $this->_paths = $paths;
+ }
+
+/**
+ * Updates files based on regular expressions.
+ *
+ * @param array $patterns Array of search and replacement patterns.
+ * @return void
+ */
+ protected function _filesRegexpUpdate($patterns) {
+ $this->_findFiles($this->params['ext']);
+ foreach ($this->_files as $file) {
+ $this->out('Updating ' . $file . '...', 1, Shell::VERBOSE);
+ $this->_updateFile($file, $patterns);
+ }
+ }
+
+/**
+ * Searches the paths and finds files based on extension.
+ *
+ * @param string $extensions
+ * @return void
+ */
+ protected function _findFiles($extensions = '') {
+ foreach ($this->_paths as $path) {
+ if (!is_dir($path)) {
+ continue;
+ }
+ $files = array();
+ $Iterator = new RegexIterator(
+ new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)),
+ '/^.+\.(' . $extensions . ')$/i',
+ RegexIterator::MATCH
+ );
+ foreach ($Iterator as $file) {
+ if ($file->isFile()) {
+ $files[] = $file->getPathname();
+ }
+ }
+ $this->_files = array_merge($this->_files, $files);
+ }
+ }
+
+/**
+ * Update a single file.
+ *
+ * @param string $file The file to update
+ * @param array $patterns The replacement patterns to run.
+ * @return void
+ */
+ protected function _updateFile($file, $patterns) {
+ $contents = file_get_contents($file);
+
+ foreach ($patterns as $pattern) {
+ $this->out(' * Updating ' . $pattern[0], 1, Shell::VERBOSE);
+ $contents = preg_replace($pattern[1], $pattern[2], $contents);
+ }
+
+ $this->out('Done updating ' . $file, 1);
+ if (!$this->params['dry-run']) {
+ file_put_contents($file, $contents);
+ }
+ }
+
+/**
+ * get the option parser
+ *
+ * @return ConsoleOptionParser
+ */
+ function getOptionParser() {
+ $subcommandParser = array(
+ 'options' => array(
+ 'plugin' => array(
+ 'short' => 'p',
+ 'help' => __('The plugin to update. Only the specified plugin will be updated.'
+ )),
+ 'ext' => array(
+ 'short' => 'e',
+ 'help' => __('The extension(s) to search. A pipe delimited list, or a preg_match compatible subpattern'),
+ 'default' => 'php|ctp|thtml|inc|tpl'
+ ),
+ 'git'=> array(
+ 'help' => __('use git command for moving files around.'),
+ 'default' => 0
+ ),
+ 'dry-run'=> array(
+ 'short' => 'd',
+ 'help' => __('Dry run the update, no files will actually be modified.'),
+ 'boolean' => true
+ )
+ )
+ );
+
+ return parent::getOptionParser()
+ ->description("A shell to help automate upgrading from CakePHP 1.3 to 2.0. \n" .
+ "Be sure to have a backup of your application before running these commands.")
+ ->addSubcommand('all', array(
+ 'help' => 'Run all upgrade commands.',
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('locations', array(
+ 'help' => 'Move files and folders to their new homes.',
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('i18n', array(
+ 'help' => 'Update the i18n translation method calls.',
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('helpers', array(
+ 'help' => 'Update calls to helpers.',
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('basics', array(
+ 'help' => 'Update removed basics functions to PHP native functions.',
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('request', array(
+ 'help' => 'Update removed request access, and replace with $this->request.',
+ 'parser' => $subcommandParser
+ ))
+ ->addSubcommand('configure', array(
+ 'help' => "Update Configure::read() to Configure::read('debug')",
+ 'parser' => $subcommandParser
+ ));
+ }
+}
diff --git a/lib/Cake/Console/ConsoleErrorHandler.php b/lib/Cake/Console/ConsoleErrorHandler.php
index 9020bd1be..e381b225f 100644
--- a/lib/Cake/Console/ConsoleErrorHandler.php
+++ b/lib/Cake/Console/ConsoleErrorHandler.php
@@ -57,8 +57,7 @@ class ConsoleErrorHandler extends ErrorHandler {
*/
public static function handleException(Exception $exception) {
$stderr = self::getStderr();
- $stderr->write(sprintf(
- __d('cake_console', "Error: %s\n%s"),
+ $stderr->write(__d('cake_console', "Error: %s\n%s",
$exception->getMessage(),
$exception->getTraceAsString()
));
@@ -70,7 +69,7 @@ class ConsoleErrorHandler extends ErrorHandler {
* @param int $code Error code
* @param string $description Description of the error.
* @param string $file The file the error occurred in.
- * @param int $line The line the error ocurrred on.
+ * @param int $line The line the error occurred on.
* @param array $context The backtrace of the error.
* @return void
*/
diff --git a/lib/Cake/Console/ConsoleInputArgument.php b/lib/Cake/Console/ConsoleInputArgument.php
index 885ce2180..649c50866 100644
--- a/lib/Cake/Console/ConsoleInputArgument.php
+++ b/lib/Cake/Console/ConsoleInputArgument.php
@@ -55,7 +55,7 @@ class ConsoleInputArgument {
/**
* Make a new Input Argument
*
- * @param mixed $name The long name of the option, or an array with all the properites.
+ * @param mixed $name The long name of the option, or an array with all the properties.
* @param string $help The help text for this option
* @param boolean $required Whether this argument is required. Missing required args will trigger exceptions
* @param array $choices Valid choices for this option.
@@ -139,8 +139,8 @@ class ConsoleInputArgument {
return true;
}
if (!in_array($value, $this->_choices)) {
- throw new ConsoleException(sprintf(
- __d('cake_console', '"%s" is not a valid value for %s. Please use one of "%s"'),
+ throw new ConsoleException(
+ __d('cake_console', '"%s" is not a valid value for %s. Please use one of "%s"',
$value, $this->_name, implode(', ', $this->_choices)
));
}
diff --git a/lib/Cake/Console/ConsoleInputOption.php b/lib/Cake/Console/ConsoleInputOption.php
index 61497e5e4..25989be20 100644
--- a/lib/Cake/Console/ConsoleInputOption.php
+++ b/lib/Cake/Console/ConsoleInputOption.php
@@ -70,7 +70,7 @@ class ConsoleInputOption {
/**
* Make a new Input Option
*
- * @param mixed $name The long name of the option, or an array with all the properites.
+ * @param mixed $name The long name of the option, or an array with all the properties.
* @param string $short The short alias for this option
* @param string $help The help text for this option
* @param boolean $boolean Whether this option is a boolean option. Boolean options don't consume extra tokens
@@ -179,8 +179,8 @@ class ConsoleInputOption {
return true;
}
if (!in_array($value, $this->_choices)) {
- throw new ConsoleException(sprintf(
- __d('cake_console', '"%s" is not a valid value for --%s. Please use one of "%s"'),
+ throw new ConsoleException(
+ __d('cake_console', '"%s" is not a valid value for --%s. Please use one of "%s"',
$value, $this->_name, implode(', ', $this->_choices)
));
}
diff --git a/lib/Cake/Console/ConsoleInputSubcommand.php b/lib/Cake/Console/ConsoleInputSubcommand.php
index b2903aec2..fef324334 100644
--- a/lib/Cake/Console/ConsoleInputSubcommand.php
+++ b/lib/Cake/Console/ConsoleInputSubcommand.php
@@ -50,7 +50,7 @@ class ConsoleInputSubcommand {
/**
* Make a new Subcommand
*
- * @param mixed $name The long name of the subcommand, or an array with all the properites.
+ * @param mixed $name The long name of the subcommand, or an array with all the properties.
* @param string $help The help text for this option
* @param mixed $parser A parser for this subcommand. Either a ConsoleOptionParser, or an array that can be
* used with ConsoleOptionParser::buildFromArray()
diff --git a/lib/Cake/Console/ConsoleOptionParser.php b/lib/Cake/Console/ConsoleOptionParser.php
index 6c221502b..c73bec9c0 100644
--- a/lib/Cake/Console/ConsoleOptionParser.php
+++ b/lib/Cake/Console/ConsoleOptionParser.php
@@ -86,9 +86,9 @@ class ConsoleOptionParser {
*
* ### Options
*
- * Named arguments come in two forms, long and short. Long arguments are preceeded
+ * Named arguments come in two forms, long and short. Long arguments are preceded
* by two - and give a more verbose option name. i.e. `--version`. Short arguments are
- * preceeded by one - and are only one character long. They usually match with a long option,
+ * preceded by one - and are only one character long. They usually match with a long option,
* and provide a more terse alternative.
*
* ### Using Options
@@ -102,7 +102,7 @@ class ConsoleOptionParser {
*
* `cake myshell command --connection default --name=something`
*
- * Short options can be defined singally or in groups.
+ * Short options can be defined signally or in groups.
*
* `cake myshell command -cn`
*
@@ -127,7 +127,7 @@ class ConsoleOptionParser {
$this->addOption('help', array(
'short' => 'h',
- 'help' => 'Display this help.',
+ 'help' => __d('cake_console', 'Display this help.'),
'boolean' => true
));
@@ -330,7 +330,7 @@ class ConsoleOptionParser {
}
/**
- * Add multiple arugments at once. Take an array of arugment defintions.
+ * Add multiple arguments at once. Take an array of argument definitions.
* The keys are used as the argument names, and the values as params for the argument.
*
* @param array $args Array of arguments to add.
diff --git a/lib/Cake/Console/ConsoleOutput.php b/lib/Cake/Console/ConsoleOutput.php
index 7d41da4d7..3a9f205cd 100644
--- a/lib/Cake/Console/ConsoleOutput.php
+++ b/lib/Cake/Console/ConsoleOutput.php
@@ -17,10 +17,10 @@
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
/**
- * Object wrapper for outputing information from a shell application.
+ * Object wrapper for outputting information from a shell application.
* Can be connected to any stream resource that can be used with fopen()
*
- * Can generate colourized output on consoles that support it. There are a few
+ * Can generate colorized output on consoles that support it. There are a few
* built in styles
*
* - `error` Error messages.
@@ -37,7 +37,7 @@
*
* `$this->out('Overwrite: foo.php was overwritten.');`
*
- * This would create orange 'Overwrite:' text, while the rest of the text would remain the normal colour.
+ * This would create orange 'Overwrite:' text, while the rest of the text would remain the normal color.
* See ConsoleOutput::styles() to learn more about defining your own styles. Nested styles are not supported
* at this time.
*
@@ -55,7 +55,7 @@ class ConsoleOutput {
const PLAIN = 1;
/**
- * Colour output - Convert known tags in to ANSI color escape codes.
+ * Color output - Convert known tags in to ANSI color escape codes.
*/
const COLOR = 2;
@@ -79,7 +79,7 @@ class ConsoleOutput {
protected $_outputAs = self::COLOR;
/**
- * text colors used in coloured output.
+ * text colors used in colored output.
*
* @var array
*/
@@ -95,7 +95,7 @@ class ConsoleOutput {
);
/**
- * background colours used in coloured output.
+ * background colors used in colored output.
*
* @var array
*/
@@ -111,7 +111,7 @@ class ConsoleOutput {
);
/**
- * formatting options for coloured output
+ * formatting options for colored output
*
* @var string
*/
@@ -140,7 +140,7 @@ class ConsoleOutput {
/**
* Construct the output object.
*
- * Checks for a pretty console enviornment. Ansicon allows pretty consoles
+ * Checks for a pretty console environment. Ansicon allows pretty consoles
* on windows, and is supported.
*
* @param string $stream The identifier of the stream to write output to.
@@ -267,7 +267,7 @@ class ConsoleOutput {
/**
* Get/Set the output type to use. The output type how formatting tags are treated.
*
- * @param int $type The output type to use. Should be one of the class contstants.
+ * @param int $type The output type to use. Should be one of the class constants.
* @return mixed Either null or the value if getting.
*/
public function outputAs($type = null) {
diff --git a/lib/Cake/Console/HelpFormatter.php b/lib/Cake/Console/HelpFormatter.php
index 94a32af88..283d1ee30 100644
--- a/lib/Cake/Console/HelpFormatter.php
+++ b/lib/Cake/Console/HelpFormatter.php
@@ -23,7 +23,7 @@ App::uses('String', 'Utility');
* Generally not directly used. Using $parser->help($command, 'xml'); is usually
* how you would access help. Or via the `--help=xml` option on the command line.
*
- * Xml output is useful for intergration with other tools like IDE's or other build tools.
+ * Xml output is useful for integration with other tools like IDE's or other build tools.
*
* @package cake.console.libs
* @since CakePHP(tm) v 2.0
@@ -52,12 +52,12 @@ class HelpFormatter {
$out[] = String::wrap($description, $width);
$out[] = '';
}
- $out[] = 'Usage:';
+ $out[] = __d('cake_console', 'Usage:');
$out[] = $this->_generateUsage();
$out[] = '';
$subcommands = $parser->subcommands();
if (!empty($subcommands)) {
- $out[] = 'Subcommands:';
+ $out[] = __d('cake_console', 'Subcommands:');
$out[] = '';
$max = $this->_getMaxLength($subcommands) + 2;
foreach ($subcommands as $command) {
@@ -68,17 +68,14 @@ class HelpFormatter {
));
}
$out[] = '';
- $out[] = sprintf(
- __d('cake_console', 'To see help on a subcommand use `cake %s [subcommand] --help`'),
- $parser->command()
- );
+ $out[] = __d('cake_console', 'To see help on a subcommand use `cake %s [subcommand] --help`', $parser->command());
$out[] = '';
}
$options = $parser->options();
if (!empty($options)) {
$max = $this->_getMaxLength($options) + 8;
- $out[] = 'Options:';
+ $out[] = __d('cake_console', 'Options:');
$out[] = '';
foreach ($options as $option) {
$out[] = String::wrap($option->help($max), array(
@@ -93,7 +90,7 @@ class HelpFormatter {
$arguments = $parser->arguments();
if (!empty($arguments)) {
$max = $this->_getMaxLength($arguments) + 2;
- $out[] = 'Arguments:';
+ $out[] = __d('cake_console', 'Arguments:');
$out[] = '';
foreach ($arguments as $argument) {
$out[] = String::wrap($argument->help($max), array(
@@ -114,7 +111,7 @@ class HelpFormatter {
/**
* Generate the usage for a shell based on its arguments and options.
- * Usage strings favour short options over the long ones. and optional args will
+ * Usage strings favor short options over the long ones. and optional args will
* be indicated with []
*
* @return string
@@ -156,7 +153,7 @@ class HelpFormatter {
public function xml($string = true) {
$parser = $this->_parser;
$xml = new SimpleXmlElement('');
- $xml->addChild('commmand', $parser->command());
+ $xml->addChild('command', $parser->command());
$xml->addChild('description', $parser->description());
$xml->addChild('epilog', $parser->epilog());
diff --git a/lib/Cake/Console/Shell.php b/lib/Cake/Console/Shell.php
index 9ea899bb4..995ca3198 100644
--- a/lib/Cake/Console/Shell.php
+++ b/lib/Cake/Console/Shell.php
@@ -188,7 +188,7 @@ class Shell extends Object {
/**
* Starts up the Shell
* allows for checking and configuring prior to command or main execution
- * can be overriden in subclasses
+ * can be overridden in subclasses
*
*/
public function startup() {
@@ -201,10 +201,10 @@ class Shell extends Object {
*/
protected function _welcome() {
$this->out();
- $this->out('Welcome to CakePHP v' . Configure::version() . ' Console');
+ $this->out(__d('cake_console', 'Welcome to CakePHP %s Console', 'v' . Configure::version()));
$this->hr();
- $this->out('App : '. APP_DIR);
- $this->out('Path: '. APP_PATH);
+ $this->out(__d('cake_console', 'App : %s', APP_DIR));
+ $this->out(__d('cake_console', 'Path: %s', APP_PATH));
$this->hr();
}
@@ -220,7 +220,7 @@ class Shell extends Object {
if ($this->uses === null || $this->uses === false) {
return;
}
- App::import('Core', 'ClassRegistry');
+ App::uses('ClassRegistry', 'Utility');
if ($this->uses !== true && !empty($this->uses)) {
$uses = is_array($this->uses) ? $this->uses : array($this->uses);
@@ -296,7 +296,7 @@ class Shell extends Object {
*
* ### Usage:
*
- * With a string commmand:
+ * With a string command:
*
* `return $this->dispatchShell('schema create DbAcl');`
*
@@ -578,7 +578,7 @@ class Shell extends Object {
*/
public function clear() {
if (empty($this->params['noclear'])) {
- if ( DS === '/') {
+ if (DS === '/') {
passthru('clear');
} else {
passthru('cls');
@@ -600,7 +600,7 @@ class Shell extends Object {
if (is_file($path) && $this->interactive === true) {
$this->out(__d('cake_console', 'File `%s` exists', $path));
- $key = $this->in(__d('cake_console', 'Do you want to overwrite?'), array('y', 'n', 'q'), 'n');
+ $key = $this->in(__d('cake_console', 'Do you want to overwrite?'), array('y', 'n', 'q'), 'n');
if (strtolower($key) == 'q') {
$this->out(__d('cake_console', 'Quitting.'), 2);
@@ -636,13 +636,13 @@ class Shell extends Object {
if (@include 'PHPUnit' . DS . 'Autoload.php') {
return true;
}
- $prompt = 'PHPUnit is not installed. Do you want to bake unit test files anyway?';
+ $prompt = __d('cake_console', 'PHPUnit is not installed. Do you want to bake unit test files anyway?');
$unitTest = $this->in($prompt, array('y','n'), 'y');
$result = strtolower($unitTest) == 'y' || strtolower($unitTest) == 'yes';
if ($result) {
$this->out();
- $this->out('You can download PHPUnit from http://phpunit.de');
+ $this->out(__d('cake_console', 'You can download PHPUnit from %s', 'http://phpunit.de'));
}
return $result;
}
diff --git a/lib/Cake/Console/ShellDispatcher.php b/lib/Cake/Console/ShellDispatcher.php
index 465b6d303..f12550249 100644
--- a/lib/Cake/Console/ShellDispatcher.php
+++ b/lib/Cake/Console/ShellDispatcher.php
@@ -99,13 +99,13 @@ class ShellDispatcher {
*/
protected function _initEnvironment() {
if (!$this->__bootstrap()) {
- $message = "Unable to load CakePHP core.\nMake sure " . DS . 'cake' . DS . 'libs exists in ' . CAKE_CORE_INCLUDE_PATH;
+ $message = "Unable to load CakePHP core.\nMake sure " . DS . 'lib' . DS . 'Cake exists in ' . CAKE_CORE_INCLUDE_PATH;
throw new CakeException($message);
}
if (!isset($this->args[0]) || !isset($this->params['working'])) {
$message = "This file has been loaded incorrectly and cannot continue.\n" .
- "Please make sure that " . DIRECTORY_SEPARATOR . "cake" . DIRECTORY_SEPARATOR . "console is in your system path,\n" .
+ "Please make sure that " . DS . 'lib' . DS . 'Cake' . DS . "Console is in your system path,\n" .
"and check the cookbook for the correct usage of this command.\n" .
"(http://book.cakephp.org/)";
throw new CakeException($message);
diff --git a/lib/Cake/Controller/CakeErrorController.php b/lib/Cake/Controller/CakeErrorController.php
index 7fd3b46f4..bcfea2086 100644
--- a/lib/Cake/Controller/CakeErrorController.php
+++ b/lib/Cake/Controller/CakeErrorController.php
@@ -37,9 +37,9 @@ class CakeErrorController extends AppController {
function beforeRender() {
parent::beforeRender();
foreach ($this->viewVars as $key => $value) {
- if (!is_object($value)){
+ if (!is_object($value)){
$this->viewVars[$key] = h($value);
}
}
}
-}
\ No newline at end of file
+}
diff --git a/lib/Cake/Controller/Component/CookieComponent.php b/lib/Cake/Controller/Component/CookieComponent.php
index 83e6353ca..2ecbb40c9 100644
--- a/lib/Cake/Controller/Component/CookieComponent.php
+++ b/lib/Cake/Controller/Component/CookieComponent.php
@@ -282,8 +282,14 @@ class CookieComponent extends Component {
$this->read();
}
if (strpos($key, '.') === false) {
+ if (isset($this->_values[$key]) && is_array($this->_values[$key])) {
+ foreach ($this->_values[$key] as $idx => $val) {
+ $this->_delete("[$key][$idx]");
+ }
+ } else {
+ $this->_delete("[$key]");
+ }
unset($this->_values[$key]);
- $this->_delete("[$key]");
return;
}
$names = explode('.', $key, 2);
diff --git a/lib/Cake/Controller/Component/EmailComponent.php b/lib/Cake/Controller/Component/EmailComponent.php
index 2311f0d55..de3e1e095 100644
--- a/lib/Cake/Controller/Component/EmailComponent.php
+++ b/lib/Cake/Controller/Component/EmailComponent.php
@@ -19,7 +19,7 @@
App::uses('Component', 'Controller');
App::uses('Multibyte', 'I18n');
-App::uses('CakeEmail', 'Network');
+App::uses('CakeEmail', 'Network/Email');
/**
* EmailComponent
diff --git a/lib/Cake/Controller/Component/RequestHandlerComponent.php b/lib/Cake/Controller/Component/RequestHandlerComponent.php
index 52843d60b..b4db62b1e 100644
--- a/lib/Cake/Controller/Component/RequestHandlerComponent.php
+++ b/lib/Cake/Controller/Component/RequestHandlerComponent.php
@@ -34,7 +34,6 @@ class RequestHandlerComponent extends Component {
* The layout that will be switched to for Ajax requests
*
* @var string
- * @access public
* @see RequestHandler::setAjax()
*/
public $ajaxLayout = 'ajax';
@@ -43,7 +42,6 @@ class RequestHandlerComponent extends Component {
* Determines whether or not callbacks will be fired on this component
*
* @var boolean
- * @access public
*/
public $enabled = true;
@@ -51,7 +49,6 @@ class RequestHandlerComponent extends Component {
* Holds the reference to Controller::$request
*
* @var CakeRequest
- * @access public
*/
public $request;
@@ -59,35 +56,33 @@ class RequestHandlerComponent extends Component {
* Holds the reference to Controller::$response
*
* @var CakeResponse
- * @access public
*/
public $response;
-/**
- * The template to use when rendering the given content type.
- *
- * @var string
- * @access private
- */
- private $__renderType = null;
-
/**
* Contains the file extension parsed out by the Router
*
* @var string
- * @access public
* @see Router::parseExtensions()
*/
public $ext = null;
/**
- * Flag set when MIME types have been initialized
+ * The template to use when rendering the given content type.
*
- * @var boolean
- * @access private
- * @see RequestHandler::__initializeTypes()
+ * @var string
*/
- private $__typesInitialized = false;
+ private $__renderType = null;
+
+/**
+ * A mapping between extensions and deserializers for request bodies of that type.
+ * By default only JSON and XML are mapped, use RequestHandlerComponent::addInputType()
+ *
+ * @var array
+ */
+ private $__inputTypeMap = array(
+ 'json' => array('json_decode', true)
+ );
/**
* Constructor. Parses the accepted content types accepted by the client using HTTP_ACCEPT
@@ -96,14 +91,7 @@ class RequestHandlerComponent extends Component {
* @param array $settings Array of settings.
*/
function __construct(ComponentCollection $collection, $settings = array()) {
- $this->__acceptTypes = explode(',', env('HTTP_ACCEPT'));
-
- foreach ($this->__acceptTypes as $i => $type) {
- if (strpos($type, ';')) {
- $type = explode(';', $type);
- $this->__acceptTypes[$i] = $type[0];
- }
- }
+ $this->addInputType('xml', array(array($this, '_convertXml')));
parent::__construct($collection, $settings);
}
@@ -124,7 +112,7 @@ class RequestHandlerComponent extends Component {
if (isset($this->request->params['url']['ext'])) {
$this->ext = $this->request->params['url']['ext'];
}
- if (empty($this->ext)) {
+ if (empty($this->ext) || $this->ext == 'html') {
$accepts = $this->request->accepts();
$extensions = Router::extensions();
if (count($accepts) == 1) {
@@ -172,19 +160,34 @@ class RequestHandlerComponent extends Component {
$this->respondAs('html', array('charset' => Configure::read('App.encoding')));
}
- if ($this->requestedWith('xml')) {
- try {
- $xml = Xml::build(trim(file_get_contents('php://input')));
-
- if (isset($xml->data)) {
- $controller->data = Xml::toArray($xml->data);
- } else {
- $controller->data = Xml::toArray($xml);
- }
- } catch (Exception $e) {}
+ foreach ($this->__inputTypeMap as $type => $handler) {
+ if ($this->requestedWith($type)) {
+ $input = call_user_func_array(array($controller->request, 'input'), $handler);
+ $controller->request->data = $input;
+ }
}
}
+/**
+ * Helper method to parse xml input data, due to lack of anonymous functions
+ * this lives here.
+ *
+ * @param string $xml
+ * @return array Xml array data
+ * @access protected
+ */
+ public function _convertXml($xml) {
+ try {
+ $xml = Xml::build($xml);
+ if (isset($xml->data)) {
+ return Xml::toArray($xml->data);
+ }
+ return Xml::toArray($xml);
+ } catch (XmlException $e) {
+ return array();
+ }
+ }
+
/**
* Handles (fakes) redirects for Ajax requests using requestAction()
*
@@ -216,6 +219,7 @@ class RequestHandlerComponent extends Component {
* Returns true if the current HTTP request is Ajax, false otherwise
*
* @return boolean True if call is Ajax
+ * @deprecated use `$this->request->is('ajax')` instead.
*/
public function isAjax() {
return $this->request->is('ajax');
@@ -225,6 +229,7 @@ class RequestHandlerComponent extends Component {
* Returns true if the current HTTP request is coming from a Flash-based client
*
* @return boolean True if call is from Flash
+ * @deprecated use `$this->request->is('flash')` instead.
*/
public function isFlash() {
return $this->request->is('flash');
@@ -234,6 +239,7 @@ class RequestHandlerComponent extends Component {
* Returns true if the current request is over HTTPS, false otherwise.
*
* @return bool True if call is over HTTPS
+ * @deprecated use `$this->request->is('ssl')` instead.
*/
public function isSSL() {
return $this->request->is('ssl');
@@ -348,6 +354,7 @@ class RequestHandlerComponent extends Component {
* @param mixed $type The Content-type or array of Content-types assigned to the name,
* i.e. "text/html", or "application/xml"
* @return void
+ * @deprecated use `$this->response->type()` instead.
*/
public function setContent($name, $type = null) {
$this->response->type(array($name => $type));
@@ -367,7 +374,7 @@ class RequestHandlerComponent extends Component {
* Gets remote client IP
*
* @return string Client IP address
- * @deprecated use $this->request->clientIp() from your controller instead.
+ * @deprecated use $this->request->clientIp() from your, controller instead.
*/
public function getClientIP($safe = true) {
return $this->request->clientIp($safe);
@@ -641,4 +648,21 @@ class RequestHandlerComponent extends Component {
}
return null;
}
+
+/**
+ * Add a new mapped input type. Mapped input types are automatically
+ * converted by RequestHandlerComponent during the startup() callback.
+ *
+ * @param string $type The type alias being converted, ie. json
+ * @param array $handler The handler array for the type. The first index should
+ * be the handling callback, all other arguments should be additional parameters
+ * for the handler.
+ * @return void
+ */
+ public function addInputType($type, $handler) {
+ if (!is_array($handler) || !isset($handler[0]) || !is_callable($handler[0])) {
+ throw new CakeException(__d('cake_dev', 'You must give a handler callback.'));
+ }
+ $this->__inputTypeMap[$type] = $handler;
+ }
}
diff --git a/lib/Cake/Controller/Controller.php b/lib/Cake/Controller/Controller.php
index abc734905..615696803 100644
--- a/lib/Cake/Controller/Controller.php
+++ b/lib/Cake/Controller/Controller.php
@@ -336,6 +336,7 @@ class Controller extends Object {
/**
* Provides backwards compatibility to avoid problems with empty and isset to alias properties.
+ * Lazy loads models using the loadModel() method if declared in $uses
*
* @return void
*/
@@ -349,6 +350,27 @@ class Controller extends Object {
case 'params':
return true;
}
+
+ if (is_array($this->uses)) {
+ foreach ($this->uses as $modelClass) {
+ list($plugin, $class) = pluginSplit($modelClass, true);
+ if ($name === $class) {
+ if (!$plugin) {
+ $plugin = $this->plugin ? $this->plugin . '.' : null;
+ }
+ return $this->loadModel($modelClass);
+ }
+ }
+ }
+
+ if ($name === $this->modelClass) {
+ list($plugin, $class) = pluginSplit($name, true);
+ if (!$plugin) {
+ $plugin = $this->plugin ? $this->plugin . '.' : null;
+ }
+ return $this->loadModel($plugin . $this->modelClass);
+ }
+
return false;
}
@@ -372,6 +394,11 @@ class Controller extends Object {
case 'paginate':
return $this->Components->load('Paginator')->settings;
}
+
+ if (isset($this->{$name})) {
+ return $this->{$name};
+ }
+
return null;
}
@@ -493,25 +520,9 @@ class Controller extends Object {
public function constructClasses() {
$this->__mergeVars();
$this->Components->init($this);
-
- if ($this->uses !== null || ($this->uses !== array())) {
- if (empty($this->passedArgs) || !isset($this->passedArgs['0'])) {
- $id = false;
- } else {
- $id = $this->passedArgs['0'];
- }
- $plugin = $this->plugin ? $this->plugin . '.' : null;
-
- if ($this->uses === false) {
- $this->loadModel($plugin . $this->modelClass, $id);
- } elseif ($this->uses) {
- $uses = is_array($this->uses) ? $this->uses : array($this->uses);
- list($plugin, $modelClassName) = pluginSplit($uses[0]);
- $this->modelClass = $modelClassName;
- foreach ($uses as $modelClass) {
- $this->loadModel($modelClass);
- }
- }
+ if ($this->uses) {
+ $this->uses = (array) $this->uses;
+ list(, $this->modelClass) = pluginSplit(current($this->uses));
}
return true;
}
diff --git a/lib/Cake/Core/App.php b/lib/Cake/Core/App.php
index fb48d06e5..8a6aba93e 100644
--- a/lib/Cake/Core/App.php
+++ b/lib/Cake/Core/App.php
@@ -62,6 +62,27 @@
*/
class App {
+/**
+ * Append paths
+ *
+ * @constant APPEND
+ */
+ const APPEND = 'append';
+
+/**
+ * Prepend paths
+ *
+ * @constant PREPEND
+ */
+ const PREPEND = 'prepend';
+
+/**
+ * Reset paths instead of merging
+ *
+ * @constant RESET
+ */
+ const RESET = true;
+
/**
* List of object types and their properties
*
@@ -222,17 +243,17 @@ class App {
*
* `App::build(array(Model' => array('/a/full/path/to/models/'))); will setup a new search path for the Model package`
*
- * `App::build(array('Model' => array('/path/to/models/')), true); will setup the path as the only valid path for searching models`
+ * `App::build(array('Model' => array('/path/to/models/')), App::RESET); will setup the path as the only valid path for searching models`
*
- * `App::build(array('View/Helper' => array('/path/to/models/', '/another/path/))); will setup multiple search paths for helpers`
+ * `App::build(array('View/Helper' => array('/path/to/helpers/', '/another/path/))); will setup multiple search paths for helpers`
*
* If reset is set to true, all loaded plugins will be forgotten and they will be needed to be loaded again.
*
* @param array $paths associative array with package names as keys and a list of directories for new search paths
- * @param boolean $reset true will set paths, false merges paths [default] false
+ * @param mixed $mode App::RESET will set paths, App::APPEND with append paths, App::PREPEND will prepend paths, [default] App::PREPEND
* @return void
*/
- public static function build($paths = array(), $reset = false) {
+ public static function build($paths = array(), $mode = App::PREPEND) {
if (empty(self::$__packageFormat)) {
self::$__packageFormat = array(
'Model' => array(
@@ -298,7 +319,7 @@ class App {
);
}
- if ($reset == true) {
+ if ($mode === App::RESET) {
foreach ($paths as $type => $new) {
if (!empty(self::$legacy[$type])) {
$type = self::$legacy[$type];
@@ -331,7 +352,11 @@ class App {
}
if (!empty($paths[$type])) {
- $path = array_merge((array)$paths[$type], self::$__packages[$type]);
+ if ($mode === App::PREPEND) {
+ $path = array_merge((array)$paths[$type], self::$__packages[$type]);
+ } else {
+ $path = array_merge(self::$__packages[$type], (array)$paths[$type]);
+ }
} else {
$path = self::$__packages[$type];
}
@@ -385,9 +410,7 @@ class App {
* @return string full path to package
*/
public static function core($type) {
- if ($type) {
- return isset($paths[$type]) ? $paths[$type] : array(LIBS . $type . DS);
- }
+ return array(LIBS . str_replace('/', DS, $type) . DS);
}
/**
@@ -612,10 +635,10 @@ class App {
return true;
}
- $originalType = $type = strtolower($type);
- $specialPackage = in_array($type, array('file', 'vendor'));
- if (!$specialPackage && isset(self::$legacy[$type . 's'])) {
- $type = self::$legacy[$type . 's'];
+ $originalType = strtolower($type);
+ $specialPackage = in_array($originalType, array('file', 'vendor'));
+ if (!$specialPackage && isset(self::$legacy[$originalType . 's'])) {
+ $type = self::$legacy[$originalType . 's'];
}
list($plugin, $name) = pluginSplit($name);
if (!empty($plugin)) {
@@ -626,11 +649,11 @@ class App {
return self::_loadClass($name, $plugin, $type, $originalType, $parent);
}
- if ($type == 'file' && !empty($file)) {
+ if ($originalType == 'file' && !empty($file)) {
return self::_loadFile($name, $plugin, $search, $file, $return);
}
- if ($type == 'vendor') {
+ if ($originalType == 'vendor') {
return self::_loadVendor($name, $plugin, $file, $ext);
}
diff --git a/lib/Cake/Error/ErrorHandler.php b/lib/Cake/Error/ErrorHandler.php
index 6787e23f7..3bd2ef042 100644
--- a/lib/Cake/Error/ErrorHandler.php
+++ b/lib/Cake/Error/ErrorHandler.php
@@ -54,13 +54,13 @@ App::uses('AppController', 'Controller');
*
* This controller method is called instead of the default exception rendering. It receives the
* thrown exception as its only argument. You should implement your error handling in that method.
- * Using AppController::appError(), will superseed any configuration for Exception.renderer.
+ * Using AppController::appError(), will supersede any configuration for Exception.renderer.
*
* #### Using a custom renderer with `Exception.renderer`
*
* If you don't want to take control of the exception handling, but want to change how exceptions are
* rendered you can use `Exception.renderer` to choose a class to render exception pages. By default
- * `ExceptionRenderer` is used. Your custom exception renderer class should be placed in app/libs.
+ * `ExceptionRenderer` is used. Your custom exception renderer class should be placed in app/Lib/Error.
*
* Your custom renderer should expect an exception in its constructor, and implement a render method.
* Failing to do so will cause additional errors.
@@ -116,10 +116,12 @@ class ErrorHandler {
);
CakeLog::write(LOG_ERR, $message);
}
- if ($config['renderer'] !== 'ExceptionRenderer') {
- App::uses($config['renderer'], 'Error');
+ $renderer = $config['renderer'];
+ if ($renderer !== 'ExceptionRenderer') {
+ list($plugin, $renderer) = pluginSplit($renderer, true);
+ App::uses($renderer, $plugin . 'Error');
}
- $error = new $config['renderer']($exception);
+ $error = new $renderer($exception);
$error->render();
}
diff --git a/lib/Cake/Error/ExceptionRenderer.php b/lib/Cake/Error/ExceptionRenderer.php
index eb3fbfe95..fbd249925 100644
--- a/lib/Cake/Error/ExceptionRenderer.php
+++ b/lib/Cake/Error/ExceptionRenderer.php
@@ -184,7 +184,7 @@ class ExceptionRenderer {
$this->controller->set($error->getAttributes());
$this->_outputMessage($this->template);
} catch (Exception $e) {
- $this->_outputMessage('error500');
+ $this->_outputMessageSafe('error500');
}
}
@@ -235,4 +235,16 @@ class ExceptionRenderer {
$this->controller->afterFilter();
$this->controller->response->send();
}
+
+/**
+ * A safer way to render error messages, replaces all helpers, with basics
+ * and doesn't call component methods.
+ *
+ * @param string $template The template to render
+ */
+ protected function _outputMessageSafe($template) {
+ $this->controller->helpers = array('Form', 'Html', 'Session');
+ $this->controller->render($template);
+ $this->controller->response->send();
+ }
}
diff --git a/lib/Cake/Model/Behavior/TreeBehavior.php b/lib/Cake/Model/Behavior/TreeBehavior.php
index 032d9e1a9..b65cefac3 100644
--- a/lib/Cake/Model/Behavior/TreeBehavior.php
+++ b/lib/Cake/Model/Behavior/TreeBehavior.php
@@ -426,7 +426,7 @@ class TreeBehavior extends ModelBehavior {
*
* @param AppModel $Model Model instance
* @param mixed $id The ID of the record to move
- * @param mixed $number how many places to move the node or true to move to last position
+ * @param int|bool $number how many places to move the node or true to move to last position
* @return boolean true on success, false on failure
* @link http://book.cakephp.org/view/1352/moveDown
*/
@@ -484,7 +484,7 @@ class TreeBehavior extends ModelBehavior {
*
* @param AppModel $Model Model instance
* @param mixed $id The ID of the record to move
- * @param mixed $number how many places to move the node, or true to move to first position
+ * @param int|bool $number how many places to move the node, or true to move to first position
* @return boolean true on success, false on failure
* @link http://book.cakephp.org/view/1353/moveUp
*/
diff --git a/lib/Cake/Model/Datasource/Database/Mysql.php b/lib/Cake/Model/Datasource/Database/Mysql.php
index b7b9da0eb..72208f0a7 100644
--- a/lib/Cake/Model/Datasource/Database/Mysql.php
+++ b/lib/Cake/Model/Datasource/Database/Mysql.php
@@ -390,12 +390,21 @@ class Mysql extends DboSource {
if (empty($conditions)) {
$alias = $joins = false;
}
- $conditions = $this->conditions($this->defaultConditions($model, $conditions, $alias), true, true, $model);
+ $complexConditions = false;
+ foreach ((array)$conditions as $key => $value) {
+ if (strpos($key, $model->alias) === false) {
+ $complexConditions = true;
+ break;
+ }
+ }
+ if (!$complexConditions) {
+ $joins = false;
+ }
+ $conditions = $this->conditions($this->defaultConditions($model, $conditions, $alias), true, true, $model);
if ($conditions === false) {
return false;
}
-
if ($this->execute($this->renderStatement('delete', compact('alias', 'table', 'joins', 'conditions'))) === false) {
$model->onError();
return false;
diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php
index e46d77fff..8d3db098b 100644
--- a/lib/Cake/Model/Datasource/DboSource.php
+++ b/lib/Cake/Model/Datasource/DboSource.php
@@ -2650,7 +2650,7 @@ class DboSource extends DataSource {
}
if (strpos($key, '.')) {
- $key = preg_replace_callback('/([a-zA-Z0-9_]{1,})\\.([a-zA-Z0-9_]{1,})/', array(&$this, '__quoteMatchedField'), $key);
+ $key = preg_replace_callback('/([a-zA-Z0-9_-]{1,})\\.([a-zA-Z0-9_-]{1,})/', array(&$this, '__quoteMatchedField'), $key);
}
if (!preg_match('/\s/', $key) && strpos($key, '.') === false) {
$key = $this->name($key);
@@ -3146,4 +3146,4 @@ class DboSource extends DataSource {
return false;
}
-}
\ No newline at end of file
+}
diff --git a/lib/Cake/Network/CakeRequest.php b/lib/Cake/Network/CakeRequest.php
index 12dde4de8..28ddeff95 100644
--- a/lib/Cake/Network/CakeRequest.php
+++ b/lib/Cake/Network/CakeRequest.php
@@ -106,6 +106,15 @@ class CakeRequest implements ArrayAccess {
'webOS', 'Windows CE', 'Xiino'
))
);
+
+/**
+ * Copy of php://input. Since this stream can only be read once in most SAPI's
+ * keep a copy of it so users don't need to know about that detail.
+ *
+ * @var string
+ */
+ private $__input = '';
+
/**
* Constructor
*
@@ -133,28 +142,30 @@ class CakeRequest implements ArrayAccess {
/**
* process the post data and set what is there into the object.
+ * processed data is available at $this->data
*
* @return void
*/
protected function _processPost() {
- $this->params['form'] = $_POST;
+ $this->data = $_POST;
if (ini_get('magic_quotes_gpc') === '1') {
- $this->params['form'] = stripslashes_deep($this->params['form']);
+ $this->data = stripslashes_deep($this->data);
}
if (env('HTTP_X_HTTP_METHOD_OVERRIDE')) {
- $this->params['form']['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE');
+ $this->data['_method'] = env('HTTP_X_HTTP_METHOD_OVERRIDE');
}
- if (isset($this->params['form']['_method'])) {
+ if (isset($this->data['_method'])) {
if (!empty($_SERVER)) {
- $_SERVER['REQUEST_METHOD'] = $this->params['form']['_method'];
+ $_SERVER['REQUEST_METHOD'] = $this->data['_method'];
} else {
- $_ENV['REQUEST_METHOD'] = $this->params['form']['_method'];
+ $_ENV['REQUEST_METHOD'] = $this->data['_method'];
}
- unset($this->params['form']['_method']);
+ unset($this->data['_method']);
}
- if (isset($this->params['form']['data'])) {
- $this->data = $this->params['form']['data'];
- unset($this->params['form']['data']);
+ if (isset($this->data['data'])) {
+ $data = $this->data['data'];
+ unset($this->data['data']);
+ $this->data = Set::merge($this->data, $data);
}
}
@@ -480,7 +491,7 @@ class CakeRequest implements ArrayAccess {
* @return The current object, you can chain this method.
*/
public function addParams($params) {
- $this->params = array_merge($this->params, $params);
+ $this->params = array_merge($this->params, (array)$params);
return $this;
}
@@ -533,6 +544,14 @@ class CakeRequest implements ArrayAccess {
/**
* Get the HTTP method used for this request.
+ * There are a few ways to specify a method.
+ *
+ * - If your client supports it you can use native HTTP methods.
+ * - You can set the HTTP-X-Method-Override header.
+ * - You can submit an input with the name `_method`
+ *
+ * Any of these 3 approaches can be used to set the HTTP method used
+ * by CakePHP internally, and will effect the result of this method.
*
* @return string The name of the HTTP method used.
*/
@@ -662,6 +681,51 @@ class CakeRequest implements ArrayAccess {
return Set::classicExtract($this->data, $name);
}
+/**
+ * Read data from `php://stdin`. Useful when interacting with XML or JSON
+ * request body content.
+ *
+ * Getting input with a decoding function:
+ *
+ * `$this->request->input('json_decode');`
+ *
+ * Getting input using a decoding function, and additional params:
+ *
+ * `$this->request->input('Xml::build', array('return' => 'DOMDocument'));`
+ *
+ * Any additional parameters are applied to the callback in the order they are given.
+ *
+ * @param string $callback A decoding callback that will convert the string data to another
+ * representation. Leave empty to access the raw input data. You can also
+ * supply additional parameters for the decoding callback using var args, see above.
+ * @return The decoded/processed request data.
+ */
+ public function input($callback = null) {
+ $input = $this->_readStdin();
+ $args = func_get_args();
+ if (!empty($args)) {
+ $callback = array_shift($args);
+ array_unshift($args, $input);
+ return call_user_func_array($callback, $args);
+ }
+ return $input;
+ }
+
+/**
+ * Read data from php://stdin, mocked in tests.
+ *
+ * @return string contents of stdin
+ */
+ protected function _readStdin() {
+ if (empty($this->__input)) {
+ $fh = fopen('php://input', 'r');
+ $content = stream_get_contents($fh);
+ fclose($fh);
+ $this->__input = $content;
+ }
+ return $this->__input;
+ }
+
/**
* Array access read implementation
*
@@ -711,4 +775,4 @@ class CakeRequest implements ArrayAccess {
public function offsetUnset($name) {
unset($this->params[$name]);
}
-}
\ No newline at end of file
+}
diff --git a/lib/Cake/Network/CakeSocket.php b/lib/Cake/Network/CakeSocket.php
index 4d6c2c720..603a84ace 100644
--- a/lib/Cake/Network/CakeSocket.php
+++ b/lib/Cake/Network/CakeSocket.php
@@ -199,8 +199,14 @@ class CakeSocket {
return false;
}
}
-
- return fwrite($this->connection, $data, strlen($data));
+ $totalBytes = strlen($data);
+ for ($written = 0, $rv = 0; $written < $totalBytes; $written += $rv) {
+ $rv = fwrite($this->connection, substr($data, $written));
+ if ($rv === false || $rv === 0) {
+ return $written;
+ }
+ }
+ return $written;
}
/**
diff --git a/lib/Cake/Network/CakeEmail.php b/lib/Cake/Network/Email/CakeEmail.php
similarity index 98%
rename from lib/Cake/Network/CakeEmail.php
rename to lib/Cake/Network/Email/CakeEmail.php
index 21c1540a9..e2cf36e9b 100644
--- a/lib/Cake/Network/CakeEmail.php
+++ b/lib/Cake/Network/Email/CakeEmail.php
@@ -277,7 +277,7 @@ class CakeEmail {
* @param mixed $email
* @param string $name
* @return mixed
- * @thrown SocketException
+ * @throws SocketException
*/
public function from($email = null, $name = null) {
if ($email === null) {
@@ -292,7 +292,7 @@ class CakeEmail {
* @param mixed $email
* @param string $name
* @return mixed
- * @thrown SocketException
+ * @throws SocketException
*/
public function sender($email = null, $name = null) {
if ($email === null) {
@@ -307,7 +307,7 @@ class CakeEmail {
* @param mixed $email
* @param string $name
* @return mixed
- * @thrown SocketException
+ * @throws SocketException
*/
public function replyTo($email = null, $name = null) {
if ($email === null) {
@@ -322,7 +322,7 @@ class CakeEmail {
* @param mixed $email
* @param string $name
* @return mixed
- * @thrown SocketException
+ * @throws SocketException
*/
public function readReceipt($email = null, $name = null) {
if ($email === null) {
@@ -337,7 +337,7 @@ class CakeEmail {
* @param mixed $email
* @param string $name
* @return mixed
- * @thrown SocketException
+ * @throws SocketException
*/
public function returnPath($email = null, $name = null) {
if ($email === null) {
@@ -428,7 +428,7 @@ class CakeEmail {
* @param mixed $email
* @param mixed $name
* @return object $this
- * @thrown SocketException
+ * @throws SocketException
*/
protected function _setEmail($varName, $email, $name) {
if (!is_array($email)) {
@@ -463,7 +463,7 @@ class CakeEmail {
* @param string $name
* @param string $throwMessage
* @return object $this
- * @thrown SocketExpceiton
+ * @throws SocketExpceiton
*/
protected function _setEmailSingle($varName, $email, $name, $throwMessage) {
$current = $this->{$varName};
@@ -527,7 +527,7 @@ class CakeEmail {
*
* @param array Associative array containing headers to be set.
* @return object $this
- * @thrown SocketException
+ * @throws SocketException
*/
public function setHeaders($headers) {
if (!is_array($headers)) {
@@ -542,7 +542,7 @@ class CakeEmail {
*
* @param array $headers
* @return mixed $this
- * @thrown SocketException
+ * @throws SocketException
*/
public function addHeaders($headers) {
if (!is_array($headers)) {
@@ -720,7 +720,7 @@ class CakeEmail {
*
* @param string $format
* @return mixed
- * @thrown SocketException
+ * @throws SocketException
*/
public function emailFormat($format = null) {
if ($format === null) {
@@ -752,7 +752,7 @@ class CakeEmail {
* Return the transport class
*
* @return object
- * @thrown SocketException
+ * @throws SocketException
*/
public function transportClass() {
if ($this->_transportClass) {
@@ -775,7 +775,7 @@ class CakeEmail {
*
* @param mixed $message True to generate a new Message-ID, False to ignore (not send in email), String to set as Message-ID
* @return mixed
- * @thrown SocketException
+ * @throws SocketException
*/
public function messageId($message = null) {
if ($message === null) {
@@ -797,7 +797,7 @@ class CakeEmail {
*
* @param mixed $attachments String with the filename or array with filenames
* @return mixed
- * @thrown SocketException
+ * @throws SocketException
*/
public function attachments($attachments = null) {
if ($attachments === null) {
@@ -832,7 +832,7 @@ class CakeEmail {
*
* @param mixed $attachments String with the filename or array with filenames
* @return object $this
- * @thrown SocketException
+ * @throws SocketException
*/
public function addAttachments($attachments) {
$current = $this->_attachments;
@@ -885,7 +885,7 @@ class CakeEmail {
* Send an email using the specified content, template and layout
*
* @return boolean Success
- * @thrown SocketException
+ * @throws SocketException
*/
public function send($content = null) {
if (is_string($this->_config)) {
diff --git a/lib/Cake/Network/Email/SmtpTransport.php b/lib/Cake/Network/Email/SmtpTransport.php
index 5cf6674b9..4cd698e73 100644
--- a/lib/Cake/Network/Email/SmtpTransport.php
+++ b/lib/Cake/Network/Email/SmtpTransport.php
@@ -44,7 +44,7 @@ class SmtpTransport extends AbstractTransport {
*
* @params object $email CakeEmail
* @return boolean
- * @thrown SocketException
+ * @throws SocketException
*/
public function send(CakeEmail $email) {
$this->_cakeEmail = $email;
@@ -80,7 +80,7 @@ class SmtpTransport extends AbstractTransport {
* Connect to SMTP Server
*
* @return void
- * @thrown SocketException
+ * @throws SocketException
*/
protected function _connect() {
$this->_generateSocket();
@@ -112,7 +112,7 @@ class SmtpTransport extends AbstractTransport {
* Send authentication
*
* @return void
- * @thrown SocketException
+ * @throws SocketException
*/
protected function _auth() {
if (isset($this->_config['username']) && isset($this->_config['password'])) {
@@ -134,7 +134,7 @@ class SmtpTransport extends AbstractTransport {
* Send emails
*
* @return void
- * @thrown SocketException
+ * @throws SocketException
*/
protected function _sendRcpt() {
$from = $this->_cakeEmail->from();
@@ -153,7 +153,7 @@ class SmtpTransport extends AbstractTransport {
* Send Data
*
* @return void
- * @thrown SocketException
+ * @throws SocketException
*/
protected function _sendData() {
$this->_smtpSend('DATA', '354');
@@ -168,7 +168,7 @@ class SmtpTransport extends AbstractTransport {
* Disconnect
*
* @return void
- * @thrown SocketException
+ * @throws SocketException
*/
protected function _disconnect() {
$this->_smtpSend('QUIT', false);
@@ -179,7 +179,7 @@ class SmtpTransport extends AbstractTransport {
* Helper method to generate socket
*
* @return void
- * @thrown SocketException
+ * @throws SocketException
*/
protected function _generateSocket() {
$this->_socket = new CakeSocket($this->_config);
@@ -191,7 +191,7 @@ class SmtpTransport extends AbstractTransport {
* @param string $data data to be sent to SMTP server
* @param mixed $checkCode code to check for in server response, false to skip
* @return void
- * @thrown SocketException
+ * @throws SocketException
*/
function _smtpSend($data, $checkCode = '250') {
if (!is_null($data)) {
diff --git a/lib/Cake/Network/Http/HttpSocket.php b/lib/Cake/Network/Http/HttpSocket.php
index 9cee50af5..0c10bc05a 100644
--- a/lib/Cake/Network/Http/HttpSocket.php
+++ b/lib/Cake/Network/Http/HttpSocket.php
@@ -128,7 +128,7 @@ class HttpSocket extends CakeSocket {
* You can use a url string to set the url and use default configurations for
* all other options:
*
- * `$http = new HttpSockect('http://cakephp.org/');`
+ * `$http = new HttpSocket('http://cakephp.org/');`
*
* Or use an array to configure multiple options:
*
@@ -405,7 +405,7 @@ class HttpSocket extends CakeSocket {
*/
public function get($uri = null, $query = array(), $request = array()) {
if (!empty($query)) {
- $uri = $this->_parseUri($uri);
+ $uri = $this->_parseUri($uri, $this->config['request']['uri']);
if (isset($uri['query'])) {
$uri['query'] = array_merge($uri['query'], $query);
} else {
diff --git a/lib/Cake/Routing/Router.php b/lib/Cake/Routing/Router.php
index 3f63fd7bb..72caf98ab 100644
--- a/lib/Cake/Routing/Router.php
+++ b/lib/Cake/Routing/Router.php
@@ -543,9 +543,6 @@ class Router {
}
}
}
- if (empty($ext)) {
- $ext = 'html';
- }
}
return compact('ext', 'url');
}
diff --git a/lib/Cake/TestSuite/Fixture/CakeTestFixture.php b/lib/Cake/TestSuite/Fixture/CakeTestFixture.php
index a83854266..db29124ac 100644
--- a/lib/Cake/TestSuite/Fixture/CakeTestFixture.php
+++ b/lib/Cake/TestSuite/Fixture/CakeTestFixture.php
@@ -70,7 +70,7 @@ class CakeTestFixture {
public function init() {
if (isset($this->import) && (is_string($this->import) || is_array($this->import))) {
$import = array_merge(
- array('connection' => 'default', 'records' => false),
+ array('connection' => 'default', 'records' => false),
is_array($this->import) ? $this->import : array('model' => $this->import)
);
@@ -178,9 +178,15 @@ class CakeTestFixture {
if (!isset($this->_insert)) {
$values = array();
if (isset($this->records) && !empty($this->records)) {
+ $fields = array();
+ foreach($this->records as $record) {
+ $fields = array_merge($fields, array_keys(array_intersect_key($record, $this->fields)));
+ }
+ $fields = array_unique($fields);
+ $default = array_fill_keys($fields, null);
foreach ($this->records as $record) {
$fields = array_keys($record);
- $values[] = array_values($record);
+ $values[] = array_values(array_merge($default, $record));
}
return $db->insertMulti($this->table, $fields, $values);
}
@@ -188,6 +194,7 @@ class CakeTestFixture {
}
}
+
/**
* Truncates the current fixture. Can be overwritten by classes extending CakeFixture to trigger other events before / after
* truncate.
diff --git a/lib/Cake/Utility/ClassRegistry.php b/lib/Cake/Utility/ClassRegistry.php
index 5a523b07f..9c06507ab 100644
--- a/lib/Cake/Utility/ClassRegistry.php
+++ b/lib/Cake/Utility/ClassRegistry.php
@@ -68,12 +68,13 @@ class ClassRegistry {
}
/**
- * Loads a class, registers the object in the registry and returns instance of the object.
+ * Loads a class, registers the object in the registry and returns instance of the object. ClassRegistry::init()
+ * is used as a factory for models, and handle correct injecting of settings, that assist in testing.
*
* Examples
* Simple Use: Get a Post model instance ```ClassRegistry::init('Post');```
*
- * Exapanded: ```array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass');```
+ * Exapanded: ```array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model');```
*
* Model Classes can accept optional ```array('id' => $id, 'table' => $table, 'ds' => $ds, 'alias' => $alias);```
*
@@ -81,14 +82,14 @@ class ClassRegistry {
* no instance of the object will be returned
* {{{
* array(
- * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass'),
- * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass'),
- * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass')
+ * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model'),
+ * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model'),
+ * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model')
* );
* }}}
* @param mixed $class as a string or a single key => value array instance will be created,
* stored in the registry and returned.
- * @param string $type TypeOfClass
+ * @param string $type Only model is accepted as a valid value for $type.
* @return object instance of ClassName
*/
public static function &init($class, $type = null) {
diff --git a/lib/Cake/Utility/Debugger.php b/lib/Cake/Utility/Debugger.php
index 278d7cf24..ff14957ba 100644
--- a/lib/Cake/Utility/Debugger.php
+++ b/lib/Cake/Utility/Debugger.php
@@ -176,7 +176,6 @@ class Debugger {
if (!$instance || strtolower($class) != strtolower(get_class($instance[0]))) {
$instance[0] = new $class();
if (Configure::read('debug') > 0) {
- Configure::version(); // Make sure the core config is loaded
$instance[0]->helpPath = Configure::read('Cake.Debugger.HelpPath');
}
}
@@ -185,7 +184,6 @@ class Debugger {
if (!$instance) {
$instance[0] = new Debugger();
if (Configure::read('debug') > 0) {
- Configure::version(); // Make sure the core config is loaded
$instance[0]->helpPath = Configure::read('Cake.Debugger.HelpPath');
}
}
@@ -609,7 +607,7 @@ class Debugger {
$this->_outputFormat = 'js';
}
- $data['id'] = 'cakeErr' . count($this->errors);
+ $data['id'] = 'cakeErr' . uniqid();
$tpl = array_merge($this->_templates['base'], $this->_templates[$this->_outputFormat]);
$insert = array('context' => join("\n", $context), 'helpPath' => $this->helpPath) + $data;
diff --git a/lib/Cake/Utility/Sanitize.php b/lib/Cake/Utility/Sanitize.php
index 151fbb6ca..f521654f3 100644
--- a/lib/Cake/Utility/Sanitize.php
+++ b/lib/Cake/Utility/Sanitize.php
@@ -63,7 +63,7 @@ class Sanitize {
* @return string SQL safe string
*/
public static function escape($string, $connection = 'default') {
- $db =& ConnectionManager::getDataSource($connection);
+ $db = ConnectionManager::getDataSource($connection);
if (is_numeric($string) || $string === null || is_bool($string)) {
return $string;
}
@@ -266,9 +266,9 @@ class Sanitize {
public static function formatColumns($model) {
foreach ($model->data as $name => $values) {
if ($name == $model->alias) {
- $curModel =& $model;
+ $curModel = $model;
} elseif (isset($model->{$name}) && is_object($model->{$name}) && is_subclass_of($model->{$name}, 'Model')) {
- $curModel =& $model->{$name};
+ $curModel = $model->{$name};
} else {
$curModel = null;
}
@@ -278,7 +278,7 @@ class Sanitize {
$colType = $curModel->getColumnType($column);
if ($colType != null) {
- $db =& ConnectionManager::getDataSource($curModel->useDbConfig);
+ $db = ConnectionManager::getDataSource($curModel->useDbConfig);
$colData = $db->columns[$colType];
if (isset($colData['limit']) && strlen(strval($data)) > $colData['limit']) {
diff --git a/lib/Cake/Utility/Set.php b/lib/Cake/Utility/Set.php
index e1e896b2c..ed2905177 100644
--- a/lib/Cake/Utility/Set.php
+++ b/lib/Cake/Utility/Set.php
@@ -421,6 +421,13 @@ 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'])) {
$items = $context['item'][$token];
if (!is_array($items)) {
@@ -460,13 +467,6 @@ 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) {
diff --git a/lib/Cake/View/Helper.php b/lib/Cake/View/Helper.php
index 55e45f852..8f165ab0e 100644
--- a/lib/Cake/View/Helper.php
+++ b/lib/Cake/View/Helper.php
@@ -692,7 +692,7 @@ class Helper extends Object {
$result = $data[$habtmKey][$habtmKey];
} elseif (empty($result) && isset($data[$habtmKey]) && is_array($data[$habtmKey])) {
if (ClassRegistry::isKeySet($habtmKey)) {
- $model =& ClassRegistry::getObject($habtmKey);
+ $model = ClassRegistry::getObject($habtmKey);
$result = $this->__selectedArray($data[$habtmKey], $model->primaryKey);
}
}
diff --git a/lib/Cake/View/Helper/FormHelper.php b/lib/Cake/View/Helper/FormHelper.php
index b46f39c11..b4ecb758f 100644
--- a/lib/Cake/View/Helper/FormHelper.php
+++ b/lib/Cake/View/Helper/FormHelper.php
@@ -204,7 +204,7 @@ class FormHelper extends AppHelper {
$models = ClassRegistry::keys();
foreach ($models as $currentModel) {
if (ClassRegistry::isKeySet($currentModel)) {
- $currentObject =& ClassRegistry::getObject($currentModel);
+ $currentObject = ClassRegistry::getObject($currentModel);
if (is_a($currentObject, 'Model') && !empty($currentObject->validationErrors)) {
$this->validationErrors[Inflector::camelize($currentModel)] =& $currentObject->validationErrors;
}
@@ -695,7 +695,9 @@ class FormHelper extends AppHelper {
* ### Options
*
* See each field type method for more information. Any options that are part of
- * $attributes or $options for the different **type** methods can be included in `$options` for input().
+ * $attributes or $options for the different **type** methods can be included in `$options` for input().i
+ * Additionally, any unknown keys that are not in the list below, or part of the selected type's options
+ * will be treated as a regular html attribute for the generated input.
*
* - `type` - Force the type of widget you want. e.g. `type => 'select'`
* - `label` - Either a string label, or an array of options for the label. See FormHelper::label()
@@ -1498,14 +1500,16 @@ class FormHelper extends AppHelper {
'escape' => true,
'secure' => null,
'empty' => '',
- 'showParents' => false
+ 'showParents' => false,
+ 'hiddenField' => true
);
$escapeOptions = $this->_extractOption('escape', $attributes);
$secure = $this->_extractOption('secure', $attributes);
$showEmpty = $this->_extractOption('empty', $attributes);
$showParents = $this->_extractOption('showParents', $attributes);
- unset($attributes['escape'], $attributes['secure'], $attributes['empty'], $attributes['showParents']);
+ $hiddenField = $this->_extractOption('hiddenField', $attributes);
+ unset($attributes['escape'], $attributes['secure'], $attributes['empty'], $attributes['showParents'], $attributes['hiddenField']);
$attributes = $this->_initInputField($fieldName, array_merge(
(array)$attributes, array('secure' => false)
@@ -1520,19 +1524,25 @@ class FormHelper extends AppHelper {
unset($attributes['type']);
}
- if (isset($attributes) && array_key_exists('multiple', $attributes)) {
+ if (!isset($selected)) {
+ $selected = $attributes['value'];
+ }
+
+ if (!empty($attributes['multiple'])) {
$style = ($attributes['multiple'] === 'checkbox') ? 'checkbox' : null;
$template = ($style) ? 'checkboxmultiplestart' : 'selectmultiplestart';
$tag = $template;
- $hiddenAttributes = array(
- 'value' => '',
- 'id' => $attributes['id'] . ($style ? '' : '_'),
- 'secure' => false,
- 'name' => $attributes['name']
- );
- $select[] = $this->hidden(null, $hiddenAttributes);
+ if ($hiddenField) {
+ $hiddenAttributes = array(
+ 'value' => '',
+ 'id' => $attributes['id'] . ($style ? '' : '_'),
+ 'secure' => false,
+ 'name' => $attributes['name']
+ );
+ $select[] = $this->hidden(null, $hiddenAttributes);
+ }
} else {
- $tag = 'selectstart';
+ $tag = 'selectstart';
}
if (!empty($tag) || isset($template)) {
@@ -1809,7 +1819,7 @@ class FormHelper extends AppHelper {
$attributes['value'] = $meridian;
} else {
if (empty($value)) {
- if (!$attribues['empty']) {
+ if (!$attributes['empty']) {
$attributes['value'] = date('a');
}
} else {
diff --git a/lib/Cake/View/Helper/JsBaseEngineHelper.php b/lib/Cake/View/Helper/JsBaseEngineHelper.php
index ade4ca558..b3f14680f 100644
--- a/lib/Cake/View/Helper/JsBaseEngineHelper.php
+++ b/lib/Cake/View/Helper/JsBaseEngineHelper.php
@@ -27,13 +27,6 @@ App::uses('AppHelper', 'View/Helper');
* @package cake.view.helpers
*/
abstract class JsBaseEngineHelper extends AppHelper {
-/**
- * Determines whether native JSON extension is used for encoding. Set by object constructor.
- *
- * @var boolean
- * @access public
- */
- public $useNative = false;
/**
* The js snippet for the current selection.
@@ -76,7 +69,6 @@ abstract class JsBaseEngineHelper extends AppHelper {
*/
function __construct($View, $settings = array()) {
parent::__construct($View, $settings);
- $this->useNative = function_exists('json_encode');
}
/**
@@ -154,50 +146,7 @@ abstract class JsBaseEngineHelper extends AppHelper {
);
$options = array_merge($defaultOptions, $options);
- if (is_object($data)) {
- $data = get_object_vars($data);
- }
-
- $out = $keys = array();
- $numeric = true;
-
- if ($this->useNative && function_exists('json_encode')) {
- $rt = json_encode($data);
- } else {
- if (is_null($data)) {
- return 'null';
- }
- if (is_bool($data)) {
- return $data ? 'true' : 'false';
- }
- if (is_array($data)) {
- $keys = array_keys($data);
- }
-
- if (!empty($keys)) {
- $numeric = (array_values($keys) === array_keys(array_values($keys)));
- }
-
- foreach ($data as $key => $val) {
- if (is_array($val) || is_object($val)) {
- $val = $this->object($val);
- } else {
- $val = $this->value($val);
- }
- if (!$numeric) {
- $val = '"' . $this->value($key, false) . '":' . $val;
- }
- $out[] = $val;
- }
-
- if (!$numeric) {
- $rt = '{' . join(',', $out) . '}';
- } else {
- $rt = '[' . join(',', $out) . ']';
- }
- }
- $rt = $options['prefix'] . $rt . $options['postfix'];
- return $rt;
+ return $options['prefix'] . json_encode($data) . $options['postfix'];
}
/**
diff --git a/lib/Cake/View/Helper/TextHelper.php b/lib/Cake/View/Helper/TextHelper.php
index 4195c3ac0..b6f8c4afd 100644
--- a/lib/Cake/View/Helper/TextHelper.php
+++ b/lib/Cake/View/Helper/TextHelper.php
@@ -179,10 +179,10 @@ class TextHelper extends AppHelper {
$this->_linkOptions = $options;
$atom = '[a-z0-9!#$%&\'*+\/=?^_`{|}~-]';
return preg_replace_callback(
- '/(' . $atom . '+(?:\.' . $atom . '+)*@[a-z0-9-]+(?:\.[a-z0-9-]+)*)/i',
+ '/(' . $atom . '+(?:\.' . $atom . '+)*@[a-z0-9-]+(?:\.[a-z0-9-]+)+)/i',
array(&$this, '_linkEmails'),
$text
- );
+ );
}
/**
diff --git a/lib/Cake/View/Helper/TimeHelper.php b/lib/Cake/View/Helper/TimeHelper.php
index 64781b79e..7b2d5dae5 100644
--- a/lib/Cake/View/Helper/TimeHelper.php
+++ b/lib/Cake/View/Helper/TimeHelper.php
@@ -618,33 +618,33 @@ class TimeHelper extends AppHelper {
} else {
if ($years > 0) {
// years and months and days
- $relativeDate .= ($relativeDate ? ', ' : '') . $years . ' ' . __dn('cake', 'year', 'years', $years);
- $relativeDate .= $months > 0 ? ($relativeDate ? ', ' : '') . $months . ' ' . __dn('cake', 'month', 'months', $months) : '';
- $relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . $weeks . ' ' . __dn('cake', 'week', 'weeks', $weeks) : '';
- $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . $days . ' ' . __dn('cake', 'day', 'days', $days) : '';
+ $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d year', '%d years', $years, $years);
+ $relativeDate .= $months > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months) : '';
+ $relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : '';
+ $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
} elseif (abs($months) > 0) {
// months, weeks and days
- $relativeDate .= ($relativeDate ? ', ' : '') . $months . ' ' . __dn('cake', 'month', 'months', $months);
- $relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . $weeks . ' ' . __dn('cake', 'week', 'weeks', $weeks) : '';
- $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . $days . ' ' . __dn('cake', 'day', 'days', $days) : '';
+ $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d month', '%d months', $months, $months);
+ $relativeDate .= $weeks > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks) : '';
+ $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
} elseif (abs($weeks) > 0) {
// weeks and days
- $relativeDate .= ($relativeDate ? ', ' : '') . $weeks . ' ' . __dn('cake', 'week', 'weeks', $weeks);
- $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . $days . ' ' . __dn('cake', 'day', 'days', $days) : '';
+ $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d week', '%d weeks', $weeks, $weeks);
+ $relativeDate .= $days > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days) : '';
} elseif (abs($days) > 0) {
// days and hours
- $relativeDate .= ($relativeDate ? ', ' : '') . $days . ' ' . __dn('cake', 'day', 'days', $days);
- $relativeDate .= $hours > 0 ? ($relativeDate ? ', ' : '') . $hours . ' ' . __dn('cake', 'hour', 'hours', $hours) : '';
+ $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d day', '%d days', $days, $days);
+ $relativeDate .= $hours > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours) : '';
} elseif (abs($hours) > 0) {
// hours and minutes
- $relativeDate .= ($relativeDate ? ', ' : '') . $hours . ' ' . __dn('cake', 'hour', 'hours', $hours);
- $relativeDate .= $minutes > 0 ? ($relativeDate ? ', ' : '') . $minutes . ' ' . __dn('cake', 'minute', 'minutes', $minutes) : '';
+ $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d hour', '%d hours', $hours, $hours);
+ $relativeDate .= $minutes > 0 ? ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes) : '';
} elseif (abs($minutes) > 0) {
// minutes only
- $relativeDate .= ($relativeDate ? ', ' : '') . $minutes . ' ' . __dn('cake', 'minute', 'minutes', $minutes);
+ $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d minute', '%d minutes', $minutes, $minutes);
} else {
// seconds only
- $relativeDate .= ($relativeDate ? ', ' : '') . $seconds . ' ' . __dn('cake', 'second', 'seconds', $seconds);
+ $relativeDate .= ($relativeDate ? ', ' : '') . __dn('cake', '%d second', '%d seconds', $seconds, $seconds);
}
if (!$backwards) {
@@ -752,4 +752,4 @@ class TimeHelper extends AppHelper {
$format = $this->convertSpecifiers($format, $date);
return strftime($format, $date);
}
-}
\ No newline at end of file
+}
diff --git a/lib/Cake/View/elements/sql_dump.ctp b/lib/Cake/View/elements/sql_dump.ctp
index 5bc41ea10..4d6919203 100644
--- a/lib/Cake/View/elements/sql_dump.ctp
+++ b/lib/Cake/View/elements/sql_dump.ctp
@@ -25,7 +25,7 @@ if ($noLogs):
$logs = array();
foreach ($sources as $source):
- $db =& ConnectionManager::getDataSource($source);
+ $db = ConnectionManager::getDataSource($source);
if (!method_exists($db, 'getLog')):
continue;
endif;
diff --git a/lib/Cake/basics.php b/lib/Cake/basics.php
index 74f3690b3..4bea45d86 100644
--- a/lib/Cake/basics.php
+++ b/lib/Cake/basics.php
@@ -1,4 +1,5 @@
0) {
- $file = '';
- $line = '';
- if ($showFrom) {
- $calledFrom = debug_backtrace();
- $file = substr(str_replace(ROOT, '', $calledFrom[0]['file']), 1);
- $line = $calledFrom[0]['line'];
- }
- $html = << 0) {
+ $file = '';
+ $line = '';
+ if ($showFrom) {
+ $calledFrom = debug_backtrace();
+ $file = substr(str_replace(ROOT, '', $calledFrom[0]['file']), 1);
+ $line = $calledFrom[0]['line'];
+ }
+ $html = <<%s (line %s)
%s
@@ -94,32 +95,32 @@ HTML;
###########################
TEXT;
- $template = $html;
- if (php_sapi_name() == 'cli') {
- $template = $text;
- }
- if ($showHtml === null && $template !== $text) {
- $showHtml = true;
- }
- $var = print_r($var, true);
- if ($showHtml) {
- $var = str_replace(array('<', '>'), array('<', '>'), $var);
- }
- printf($template, $file, $line, $var);
+ $template = $html;
+ if (php_sapi_name() == 'cli') {
+ $template = $text;
}
+ if ($showHtml === null && $template !== $text) {
+ $showHtml = true;
+ }
+ $var = print_r($var, true);
+ if ($showHtml) {
+ $var = str_replace(array('<', '>'), array('<', '>'), $var);
+ }
+ printf($template, $file, $line, $var);
}
+}
if (!function_exists('sortByKey')) {
-/**
- * Sorts given $array by key $sortby.
- *
- * @param array $array Array to sort
- * @param string $sortby Sort by this key
- * @param string $order Sort order asc/desc (ascending or descending).
- * @param integer $type Type of sorting to perform
- * @return mixed Sorted array
- */
+ /**
+ * Sorts given $array by key $sortby.
+ *
+ * @param array $array Array to sort
+ * @param string $sortby Sort by this key
+ * @param string $order Sort order asc/desc (ascending or descending).
+ * @param integer $type Type of sorting to perform
+ * @return mixed Sorted array
+ */
function sortByKey(&$array, $sortby, $order = 'asc', $type = SORT_NUMERIC) {
if (!is_array($array)) {
return null;
@@ -151,28 +152,28 @@ if (!function_exists('sortByKey')) {
* @return string Wrapped text
* @link http://book.cakephp.org/view/1132/h
*/
- function h($text, $double = true, $charset = null) {
- if (is_array($text)) {
- $texts = array();
- foreach ($text as $k => $t) {
- $texts[$k] = h($t, $double, $charset);
- }
- return $texts;
+function h($text, $double = true, $charset = null) {
+ if (is_array($text)) {
+ $texts = array();
+ foreach ($text as $k => $t) {
+ $texts[$k] = h($t, $double, $charset);
}
-
- static $defaultCharset = false;
- if ($defaultCharset === false) {
- $defaultCharset = Configure::read('App.encoding');
- if ($defaultCharset === null) {
- $defaultCharset = 'UTF-8';
- }
- }
- if (is_string($double)) {
- $charset = $double;
- }
- return htmlspecialchars($text, ENT_QUOTES, ($charset) ? $charset : $defaultCharset, $double);
+ return $texts;
}
+ static $defaultCharset = false;
+ if ($defaultCharset === false) {
+ $defaultCharset = Configure::read('App.encoding');
+ if ($defaultCharset === null) {
+ $defaultCharset = 'UTF-8';
+ }
+ }
+ if (is_string($double)) {
+ $charset = $double;
+ }
+ return htmlspecialchars($text, ENT_QUOTES, ($charset) ? $charset : $defaultCharset, $double);
+}
+
/**
* Splits a dot syntax plugin name into its plugin and classname.
* If $name does not have a dot, then index 0 will be null.
@@ -184,16 +185,16 @@ if (!function_exists('sortByKey')) {
* @param string $plugin Optional default plugin to use if no plugin is found. Defaults to null.
* @return array Array with 2 indexes. 0 => plugin name, 1 => classname
*/
- function pluginSplit($name, $dotAppend = false, $plugin = null) {
- if (strpos($name, '.') !== false) {
- $parts = explode('.', $name, 2);
- if ($dotAppend) {
- $parts[0] .= '.';
- }
- return $parts;
+function pluginSplit($name, $dotAppend = false, $plugin = null) {
+ if (strpos($name, '.') !== false) {
+ $parts = explode('.', $name, 2);
+ if ($dotAppend) {
+ $parts[0] .= '.';
}
- return array($plugin, $name);
+ return $parts;
}
+ return array($plugin, $name);
+}
/**
* Print_r convenience function, which prints out tags around
@@ -203,13 +204,13 @@ if (!function_exists('sortByKey')) {
* @param array $var Variable to print out
* @link http://book.cakephp.org/view/1136/pr
*/
- function pr($var) {
- if (Configure::read('debug') > 0) {
- echo '';
- print_r($var);
- echo '
';
- }
+function pr($var) {
+ if (Configure::read('debug') > 0) {
+ echo '';
+ print_r($var);
+ echo '
';
}
+}
/**
* Merge a group of arrays
@@ -221,17 +222,17 @@ if (!function_exists('sortByKey')) {
* @return array All array parameters merged into one
* @link http://book.cakephp.org/view/1124/am
*/
- function am() {
- $r = array();
- $args = func_get_args();
- foreach ($args as $a) {
- if (!is_array($a)) {
- $a = array($a);
- }
- $r = array_merge($r, $a);
+function am() {
+ $r = array();
+ $args = func_get_args();
+ foreach ($args as $a) {
+ if (!is_array($a)) {
+ $a = array($a);
}
- return $r;
+ $r = array_merge($r, $a);
}
+ return $r;
+}
/**
* Gets an environment variable from available sources, and provides emulation
@@ -243,83 +244,105 @@ if (!function_exists('sortByKey')) {
* @return string Environment variable setting.
* @link http://book.cakephp.org/view/1130/env
*/
- function env($key) {
- if ($key === 'HTTPS') {
- if (isset($_SERVER['HTTPS'])) {
- return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
- }
- return (strpos(env('SCRIPT_URI'), 'https://') === 0);
+function env($key) {
+ if ($key === 'HTTPS') {
+ if (isset($_SERVER['HTTPS'])) {
+ return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
}
-
- if ($key === 'SCRIPT_NAME') {
- if (env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) {
- $key = 'SCRIPT_URL';
- }
- }
-
- $val = null;
- if (isset($_SERVER[$key])) {
- $val = $_SERVER[$key];
- } elseif (isset($_ENV[$key])) {
- $val = $_ENV[$key];
- } elseif (getenv($key) !== false) {
- $val = getenv($key);
- }
-
- if ($key === 'REMOTE_ADDR' && $val === env('SERVER_ADDR')) {
- $addr = env('HTTP_PC_REMOTE_ADDR');
- if ($addr !== null) {
- $val = $addr;
- }
- }
-
- if ($val !== null) {
- return $val;
- }
-
- switch ($key) {
- case 'SCRIPT_FILENAME':
- if (defined('SERVER_IIS') && SERVER_IIS === true) {
- return str_replace('\\\\', '\\', env('PATH_TRANSLATED'));
- }
- break;
- case 'DOCUMENT_ROOT':
- $name = env('SCRIPT_NAME');
- $filename = env('SCRIPT_FILENAME');
- $offset = 0;
- if (!strpos($name, '.php')) {
- $offset = 4;
- }
- return substr($filename, 0, strlen($filename) - (strlen($name) + $offset));
- break;
- case 'PHP_SELF':
- return str_replace(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME'));
- break;
- case 'CGI_MODE':
- return (PHP_SAPI === 'cgi');
- break;
- case 'HTTP_BASE':
- $host = env('HTTP_HOST');
- $parts = explode('.', $host);
- $count = count($parts);
-
- if ($count === 1) {
- return '.' . $host;
- } elseif ($count === 2) {
- return '.' . $host;
- } elseif ($count === 3) {
- $gTLD = array('aero', 'asia', 'biz', 'cat', 'com', 'coop', 'edu', 'gov', 'info', 'int', 'jobs', 'mil', 'mobi', 'museum', 'name', 'net', 'org', 'pro', 'tel', 'travel', 'xxx');
- if (in_array($parts[1], $gTLD)) {
- return '.' . $host;
- }
- }
- array_shift($parts);
- return '.' . implode('.', $parts);
- break;
- }
- return null;
+ return (strpos(env('SCRIPT_URI'), 'https://') === 0);
}
+ if ($key === 'SCRIPT_NAME') {
+ if (env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) {
+ $key = 'SCRIPT_URL';
+ }
+ }
+
+ $val = null;
+ if (isset($_SERVER[$key])) {
+ $val = $_SERVER[$key];
+ } elseif (isset($_ENV[$key])) {
+ $val = $_ENV[$key];
+ } elseif (getenv($key) !== false) {
+ $val = getenv($key);
+ }
+
+ if ($key === 'REMOTE_ADDR' && $val === env('SERVER_ADDR')) {
+ $addr = env('HTTP_PC_REMOTE_ADDR');
+ if ($addr !== null) {
+ $val = $addr;
+ }
+ }
+
+ if ($val !== null) {
+ return $val;
+ }
+
+ switch ($key) {
+ case 'SCRIPT_FILENAME':
+ if (defined('SERVER_IIS') && SERVER_IIS === true) {
+ return str_replace('\\\\', '\\', env('PATH_TRANSLATED'));
+ }
+ break;
+ case 'DOCUMENT_ROOT':
+ $name = env('SCRIPT_NAME');
+ $filename = env('SCRIPT_FILENAME');
+ $offset = 0;
+ if (!strpos($name, '.php')) {
+ $offset = 4;
+ }
+ return substr($filename, 0, strlen($filename) - (strlen($name) + $offset));
+ break;
+ case 'PHP_SELF':
+ return str_replace(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME'));
+ break;
+ case 'CGI_MODE':
+ return (PHP_SAPI === 'cgi');
+ break;
+ case 'HTTP_BASE':
+ $host = env('HTTP_HOST');
+ $parts = explode('.', $host);
+ $count = count($parts);
+
+ if ($count === 1) {
+ return '.' . $host;
+ } elseif ($count === 2) {
+ return '.' . $host;
+ } elseif ($count === 3) {
+ $gTLD = array(
+ 'aero',
+ 'asia',
+ 'biz',
+ 'cat',
+ 'com',
+ 'coop',
+ 'edu',
+ 'gov',
+ 'info',
+ 'int',
+ 'jobs',
+ 'mil',
+ 'mobi',
+ 'museum',
+ 'name',
+ 'net',
+ 'org',
+ 'pro',
+ 'tel',
+ 'travel',
+ 'xxx'
+ );
+ if (in_array($parts[1], $gTLD)) {
+ return '.' . $host;
+ }
+ }
+ array_shift($parts);
+ return '.' . implode('.', $parts);
+ break;
+ }
+ return null;
+}
+
/**
* Reads/writes temporary data to cache files or session.
*
@@ -330,47 +353,47 @@ if (!function_exists('sortByKey')) {
* @return mixed The contents of the temporary file.
* @deprecated Please use Cache::write() instead
*/
- function cache($path, $data = null, $expires = '+1 day', $target = 'cache') {
- if (Configure::read('Cache.disable')) {
- return null;
- }
- $now = time();
-
- if (!is_numeric($expires)) {
- $expires = strtotime($expires, $now);
- }
-
- switch (strtolower($target)) {
- case 'cache':
- $filename = CACHE . $path;
- break;
- case 'public':
- $filename = WWW_ROOT . $path;
- break;
- case 'tmp':
- $filename = TMP . $path;
- break;
- }
- $timediff = $expires - $now;
- $filetime = false;
-
- if (file_exists($filename)) {
- $filetime = @filemtime($filename);
- }
-
- if ($data === null) {
- if (file_exists($filename) && $filetime !== false) {
- if ($filetime + $timediff < $now) {
- @unlink($filename);
- } else {
- $data = @file_get_contents($filename);
- }
- }
- } elseif (is_writable(dirname($filename))) {
- @file_put_contents($filename, $data);
- }
- return $data;
+function cache($path, $data = null, $expires = '+1 day', $target = 'cache') {
+ if (Configure::read('Cache.disable')) {
+ return null;
}
+ $now = time();
+
+ if (!is_numeric($expires)) {
+ $expires = strtotime($expires, $now);
+ }
+
+ switch (strtolower($target)) {
+ case 'cache':
+ $filename = CACHE . $path;
+ break;
+ case 'public':
+ $filename = WWW_ROOT . $path;
+ break;
+ case 'tmp':
+ $filename = TMP . $path;
+ break;
+ }
+ $timediff = $expires - $now;
+ $filetime = false;
+
+ if (file_exists($filename)) {
+ $filetime = @filemtime($filename);
+ }
+
+ if ($data === null) {
+ if (file_exists($filename) && $filetime !== false) {
+ if ($filetime + $timediff < $now) {
+ @unlink($filename);
+ } else {
+ $data = @file_get_contents($filename);
+ }
+ }
+ } elseif (is_writable(dirname($filename))) {
+ @file_put_contents($filename, $data);
+ }
+ return $data;
+}
/**
* Used to delete files in the cache directories, or clear contents of cache directories
@@ -382,57 +405,57 @@ if (!function_exists('sortByKey')) {
* @param string $ext The file extension you are deleting
* @return true if files found and deleted false otherwise
*/
- function clearCache($params = null, $type = 'views', $ext = '.php') {
- if (is_string($params) || $params === null) {
- $params = preg_replace('/\/\//', '/', $params);
- $cache = CACHE . $type . DS . $params;
+function clearCache($params = null, $type = 'views', $ext = '.php') {
+ if (is_string($params) || $params === null) {
+ $params = preg_replace('/\/\//', '/', $params);
+ $cache = CACHE . $type . DS . $params;
- if (is_file($cache . $ext)) {
- @unlink($cache . $ext);
- return true;
- } elseif (is_dir($cache)) {
- $files = glob($cache . '*');
+ if (is_file($cache . $ext)) {
+ @unlink($cache . $ext);
+ return true;
+ } elseif (is_dir($cache)) {
+ $files = glob($cache . '*');
- if ($files === false) {
- return false;
- }
-
- foreach ($files as $file) {
- if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
- @unlink($file);
- }
- }
- return true;
- } else {
- $cache = array(
- CACHE . $type . DS . '*' . $params . $ext,
- CACHE . $type . DS . '*' . $params . '_*' . $ext
- );
- $files = array();
- while ($search = array_shift($cache)) {
- $results = glob($search);
- if ($results !== false) {
- $files = array_merge($files, $results);
- }
- }
- if (empty($files)) {
- return false;
- }
- foreach ($files as $file) {
- if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
- @unlink($file);
- }
- }
- return true;
+ if ($files === false) {
+ return false;
}
- } elseif (is_array($params)) {
- foreach ($params as $file) {
- clearCache($file, $type, $ext);
+
+ foreach ($files as $file) {
+ if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
+ @unlink($file);
+ }
+ }
+ return true;
+ } else {
+ $cache = array(
+ CACHE . $type . DS . '*' . $params . $ext,
+ CACHE . $type . DS . '*' . $params . '_*' . $ext
+ );
+ $files = array();
+ while ($search = array_shift($cache)) {
+ $results = glob($search);
+ if ($results !== false) {
+ $files = array_merge($files, $results);
+ }
+ }
+ if (empty($files)) {
+ return false;
+ }
+ foreach ($files as $file) {
+ if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
+ @unlink($file);
+ }
}
return true;
}
- return false;
+ } elseif (is_array($params)) {
+ foreach ($params as $file) {
+ clearCache($file, $type, $ext);
+ }
+ return true;
}
+ return false;
+}
/**
* Recursively strips slashes from all values in an array
@@ -441,16 +464,16 @@ if (!function_exists('sortByKey')) {
* @return mixed What is returned from calling stripslashes
* @link http://book.cakephp.org/view/1138/stripslashes_deep
*/
- function stripslashes_deep($values) {
- if (is_array($values)) {
- foreach ($values as $key => $value) {
- $values[$key] = stripslashes_deep($value);
- }
- } else {
- $values = stripslashes($values);
+function stripslashes_deep($values) {
+ if (is_array($values)) {
+ foreach ($values as $key => $value) {
+ $values[$key] = stripslashes_deep($value);
}
- return $values;
+ } else {
+ $values = stripslashes($values);
}
+ return $values;
+}
/**
* Returns a translated string if one is found; Otherwise, the submitted message.
@@ -460,21 +483,21 @@ if (!function_exists('sortByKey')) {
* @return mixed translated string
* @link http://book.cakephp.org/view/1121/__
*/
- function __($singular, $args = null) {
- if (!$singular) {
- return;
- }
-
- App::uses('I18n', 'I18n');
- $translated = I18n::translate($singular);
- if ($args === null) {
- return $translated;
- } elseif (!is_array($args)) {
- $args = array_slice(func_get_args(), 1);
- }
- return vsprintf($translated, $args);
+function __($singular, $args = null) {
+ if (!$singular) {
+ return;
}
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($singular);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 1);
+ }
+ return vsprintf($translated, $args);
+}
+
/**
* Returns correct plural form of message identified by $singular and $plural for count $count.
* Some languages have more than one form for plural messages dependent on the count.
@@ -485,21 +508,21 @@ if (!function_exists('sortByKey')) {
* @param mixed $args Array with arguments or multiple arguments in function
* @return mixed plural form of translated string
*/
- function __n($singular, $plural, $count, $args = null) {
- if (!$singular) {
- return;
- }
-
- App::uses('I18n', 'I18n');
- $translated = I18n::translate($singular, $plural, null, 6, $count);
- if ($args === null) {
- return $translated;
- } elseif (!is_array($args)) {
- $args = array_slice(func_get_args(), 3);
- }
- return vsprintf($translated, $args);
+function __n($singular, $plural, $count, $args = null) {
+ if (!$singular) {
+ return;
}
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($singular, $plural, null, 6, $count);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 3);
+ }
+ return vsprintf($translated, $args);
+}
+
/**
* Allows you to override the current domain for a single message lookup.
*
@@ -508,19 +531,19 @@ if (!function_exists('sortByKey')) {
* @param mixed $args Array with arguments or multiple arguments in function
* @return translated string
*/
- function __d($domain, $msg, $args = null) {
- if (!$msg) {
- return;
- }
- App::uses('I18n', 'I18n');
- $translated = I18n::translate($msg, null, $domain);
- if ($args === null) {
- return $translated;
- } elseif (!is_array($args)) {
- $args = array_slice(func_get_args(), 2);
- }
- return vsprintf($translated, $args);
+function __d($domain, $msg, $args = null) {
+ if (!$msg) {
+ return;
}
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($msg, null, $domain);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 2);
+ }
+ return vsprintf($translated, $args);
+}
/**
* Allows you to override the current domain for a single plural message lookup.
@@ -534,19 +557,19 @@ if (!function_exists('sortByKey')) {
* @param mixed $args Array with arguments or multiple arguments in function
* @return plural form of translated string
*/
- function __dn($domain, $singular, $plural, $count, $args = null) {
- if (!$singular) {
- return;
- }
- App::uses('I18n', 'I18n');
- $translated = I18n::translate($singular, $plural, $domain, 6, $count);
- if ($args === null) {
- return $translated;
- } elseif (!is_array($args)) {
- $args = array_slice(func_get_args(), 4);
- }
- return vsprintf($translated, $args);
+function __dn($domain, $singular, $plural, $count, $args = null) {
+ if (!$singular) {
+ return;
}
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($singular, $plural, $domain, 6, $count);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 4);
+ }
+ return vsprintf($translated, $args);
+}
/**
* Allows you to override the current domain for a single message lookup.
@@ -571,19 +594,19 @@ if (!function_exists('sortByKey')) {
* @param mixed $args Array with arguments or multiple arguments in function
* @return translated string
*/
- function __dc($domain, $msg, $category, $args = null) {
- if (!$msg) {
- return;
- }
- App::uses('I18n', 'I18n');
- $translated = I18n::translate($msg, null, $domain, $category);
- if ($args === null) {
- return $translated;
- } elseif (!is_array($args)) {
- $args = array_slice(func_get_args(), 3);
- }
- return vsprintf($translated, $args);
+function __dc($domain, $msg, $category, $args = null) {
+ if (!$msg) {
+ return;
}
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($msg, null, $domain, $category);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 3);
+ }
+ return vsprintf($translated, $args);
+}
/**
* Allows you to override the current domain for a single plural message lookup.
@@ -612,19 +635,19 @@ if (!function_exists('sortByKey')) {
* @param mixed $args Array with arguments or multiple arguments in function
* @return plural form of translated string
*/
- function __dcn($domain, $singular, $plural, $count, $category, $args = null) {
- if (!$singular) {
- return;
- }
- App::uses('I18n', 'I18n');
- $translated = I18n::translate($singular, $plural, $domain, $category, $count);
- if ($args === null) {
- return $translated;
- } elseif (!is_array($args)) {
- $args = array_slice(func_get_args(), 5);
- }
- return vsprintf($translated, $args);
+function __dcn($domain, $singular, $plural, $count, $category, $args = null) {
+ if (!$singular) {
+ return;
}
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($singular, $plural, $domain, $category, $count);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 5);
+ }
+ return vsprintf($translated, $args);
+}
/**
* The category argument allows a specific category of the locale settings to be used for fetching a message.
@@ -645,31 +668,31 @@ if (!function_exists('sortByKey')) {
* @param mixed $args Array with arguments or multiple arguments in function
* @return translated string
*/
- function __c($msg, $category, $args = null) {
- if (!$msg) {
- return;
- }
- App::uses('I18n', 'I18n');
- $translated = I18n::translate($msg, null, null, $category);
- if ($args === null) {
- return $translated;
- } elseif (!is_array($args)) {
- $args = array_slice(func_get_args(), 2);
- }
- return vsprintf($translated, $args);
+function __c($msg, $category, $args = null) {
+ if (!$msg) {
+ return;
}
+ App::uses('I18n', 'I18n');
+ $translated = I18n::translate($msg, null, null, $category);
+ if ($args === null) {
+ return $translated;
+ } elseif (!is_array($args)) {
+ $args = array_slice(func_get_args(), 2);
+ }
+ return vsprintf($translated, $args);
+}
/**
* Shortcut to Log::write.
*
* @param string $message Message to write to log
*/
- function LogError($message) {
- App::uses('CakeLog', 'Log');
- $bad = array("\n", "\r", "\t");
- $good = ' ';
- CakeLog::write('error', str_replace($bad, $good, $message));
- }
+function LogError($message) {
+ App::uses('CakeLog', 'Log');
+ $bad = array("\n", "\r", "\t");
+ $good = ' ';
+ CakeLog::write('error', str_replace($bad, $good, $message));
+}
/**
* Searches include path for files.
@@ -678,19 +701,19 @@ if (!function_exists('sortByKey')) {
* @return Full path to file if exists, otherwise false
* @link http://book.cakephp.org/view/1131/fileExistsInPath
*/
- function fileExistsInPath($file) {
- $paths = explode(PATH_SEPARATOR, ini_get('include_path'));
- foreach ($paths as $path) {
- $fullPath = $path . DS . $file;
+function fileExistsInPath($file) {
+ $paths = explode(PATH_SEPARATOR, ini_get('include_path'));
+ foreach ($paths as $path) {
+ $fullPath = $path . DS . $file;
- if (file_exists($fullPath)) {
- return $fullPath;
- } elseif (file_exists($file)) {
- return $file;
- }
+ if (file_exists($fullPath)) {
+ return $fullPath;
+ } elseif (file_exists($file)) {
+ return $file;
}
- return false;
}
+ return false;
+}
/**
* Convert forward slashes to underscores and removes first and last underscores in a string
@@ -699,9 +722,9 @@ if (!function_exists('sortByKey')) {
* @return string with underscore remove from start and end of string
* @link http://book.cakephp.org/view/1126/convertSlash
*/
- function convertSlash($string) {
- $string = trim($string, '/');
- $string = preg_replace('/\/\//', '/', $string);
- $string = str_replace('/', '_', $string);
- return $string;
- }
+function convertSlash($string) {
+ $string = trim($string, '/');
+ $string = preg_replace('/\/\//', '/', $string);
+ $string = str_replace('/', '_', $string);
+ return $string;
+}
diff --git a/lib/Cake/config/config.php b/lib/Cake/config/config.php
index 906fa844a..72e00d619 100644
--- a/lib/Cake/config/config.php
+++ b/lib/Cake/config/config.php
@@ -16,4 +16,5 @@
* @since CakePHP(tm) v 1.1.11.4062
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
-return $config['Cake.version'] = '2.0.0-dev';
+
+return $config['Cake.version'] = '2.0.0-dev';
\ No newline at end of file
diff --git a/lib/Cake/tests/Case/AllDatabaseTest.php b/lib/Cake/tests/Case/AllDatabaseTest.php
index d4f0ba82f..25b2bec84 100644
--- a/lib/Cake/tests/Case/AllDatabaseTest.php
+++ b/lib/Cake/tests/Case/AllDatabaseTest.php
@@ -40,7 +40,7 @@ class AllDatabaseTest extends PHPUnit_Framework_TestSuite {
'CakeSchema',
'ConnectionManager',
'Datasource' . DS . 'DboSource',
- 'Datasource' . DS . 'Database' . DS . 'MySql',
+ 'Datasource' . DS . 'Database' . DS . 'Mysql',
'Datasource' . DS . 'Database' . DS . 'Postgres',
'Datasource' . DS . 'Database' . DS . 'Sqlite'
);
diff --git a/lib/Cake/tests/Case/AllNetworkTest.php b/lib/Cake/tests/Case/AllNetworkTest.php
index c090c4349..c9d7c6b0b 100644
--- a/lib/Cake/tests/Case/AllNetworkTest.php
+++ b/lib/Cake/tests/Case/AllNetworkTest.php
@@ -35,6 +35,7 @@ class AllNetworkTest extends PHPUnit_Framework_TestSuite {
$suite = new CakeTestSuite('All Network related class tests');
$suite->addTestDirectory(CORE_TEST_CASES . DS . 'Network');
+ $suite->addTestDirectory(CORE_TEST_CASES . DS . 'Network' . DS . 'Email');
$suite->addTestDirectory(CORE_TEST_CASES . DS . 'Network' . DS . 'Http');
return $suite;
}
diff --git a/lib/Cake/tests/Case/Cache/CacheTest.php b/lib/Cake/tests/Case/Cache/CacheTest.php
index 238707361..147f519b2 100644
--- a/lib/Cake/tests/Case/Cache/CacheTest.php
+++ b/lib/Cake/tests/Case/Cache/CacheTest.php
@@ -235,7 +235,7 @@ class CacheTest extends CakeTestCase {
function testInitSettings() {
$initial = Cache::settings();
$override = array('engine' => 'File', 'path' => TMP . 'tests');
- Cache::config('default', $override);
+ Cache::config('for_test', $override);
$settings = Cache::settings();
$expecting = $override + $initial;
diff --git a/lib/Cake/tests/Case/Cache/Engine/FileEngineTest.php b/lib/Cake/tests/Case/Cache/Engine/FileEngineTest.php
index 5395ac025..d6b34648d 100644
--- a/lib/Cake/tests/Case/Cache/Engine/FileEngineTest.php
+++ b/lib/Cake/tests/Case/Cache/Engine/FileEngineTest.php
@@ -257,7 +257,7 @@ class FileEngineTest extends CakeTestCase {
$result = Cache::read('views.countries.something', 'file_test');
$this->assertEqual($result, 'here');
- $result = Cache::clear();
+ $result = Cache::clear(false, 'file_test');
$this->assertTrue($result);
}
diff --git a/lib/Cake/tests/Case/Console/Command/ApiShellTest.php b/lib/Cake/tests/Case/Console/Command/ApiShellTest.php
index 03576ddb7..045611ab3 100644
--- a/lib/Cake/tests/Case/Console/Command/ApiShellTest.php
+++ b/lib/Cake/tests/Case/Console/Command/ApiShellTest.php
@@ -82,7 +82,7 @@ class ApiShellTest extends CakeTestCase {
$this->Shell->expects($this->at(2))->method('out')->with($expected);
$this->Shell->args = array('controller');
- $this->Shell->paths['controller'] = LIBS . 'controller' . DS;
+ $this->Shell->paths['controller'] = LIBS . 'Controller' . DS;
$this->Shell->main();
}
}
diff --git a/lib/Cake/tests/Case/Console/Command/SchemaShellTest.php b/lib/Cake/tests/Case/Console/Command/SchemaShellTest.php
index ce48e0626..8eea33027 100644
--- a/lib/Cake/tests/Case/Console/Command/SchemaShellTest.php
+++ b/lib/Cake/tests/Case/Console/Command/SchemaShellTest.php
@@ -473,7 +473,7 @@ class SchemaShellTest extends CakeTestCase {
$this->Shell->expects($this->any())->method('in')->will($this->returnValue('y'));
$this->Shell->create();
- $db =& ConnectionManager::getDataSource('test');
+ $db = ConnectionManager::getDataSource('test');
$sources = $db->listSources();
$this->assertTrue(in_array($db->config['prefix'] . 'test_plugin_acos', $sources));
diff --git a/lib/Cake/tests/Case/Console/Command/Task/ExtractTaskTest.php b/lib/Cake/tests/Case/Console/Command/Task/ExtractTaskTest.php
index c401bbd09..346786da4 100644
--- a/lib/Cake/tests/Case/Console/Command/Task/ExtractTaskTest.php
+++ b/lib/Cake/tests/Case/Console/Command/Task/ExtractTaskTest.php
@@ -118,7 +118,6 @@ class ExtractTaskTest extends CakeTestCase {
$pattern = '/To change its layout, create: APP\/views\/layouts\/default\.ctp\./s';
$this->assertPattern($pattern, $result);
-
// extract.ctp
$pattern = '/\#: (\\\\|\/)extract\.ctp:6\n';
$pattern .= 'msgid "You have %d new message."\nmsgid_plural "You have %d new messages."/';
@@ -131,9 +130,15 @@ class ExtractTaskTest extends CakeTestCase {
$pattern = '/\#: (\\\\|\/)extract\.ctp:14\n';
$pattern .= '\#: (\\\\|\/)home\.ctp:99\n';
$pattern .= 'msgid "Editing this Page"\nmsgstr ""/';
-
$this->assertPattern($pattern, $result);
-
+
+ $pattern = '/\#: (\\\\|\/)extract\.ctp:17\nmsgid "';
+ $pattern .= 'Hot features!';
+ $pattern .= '\\\n - No Configuration: Set-up the database and let the magic begin';
+ $pattern .= '\\\n - Extremely Simple: Just look at the name...It\'s Cake';
+ $pattern .= '\\\n - Active, Friendly Community: Join us #cakephp on IRC. We\'d love to help you get started';
+ $pattern .= '"\nmsgstr ""/';
+ $this->assertPattern($pattern, $result);
// extract.ctp - reading the domain.pot
$result = file_get_contents($this->path . DS . 'domain.pot');
diff --git a/lib/Cake/tests/Case/Controller/Component/CookieComponentTest.php b/lib/Cake/tests/Case/Controller/Component/CookieComponentTest.php
index dd07e923c..b48bc3c9d 100644
--- a/lib/Cake/tests/Case/Controller/Component/CookieComponentTest.php
+++ b/lib/Cake/tests/Case/Controller/Component/CookieComponentTest.php
@@ -496,7 +496,23 @@ class CookieComponentTest extends CakeTestCase {
$this->assertNull($this->Cookie->read('value'));
}
-
+
+/**
+ * test that deleting a top level keys kills the child elements too.
+ *
+ * @return void
+ */
+ function testDeleteRemovesChildren() {
+ $_COOKIE['CakeTestCookie'] = array(
+ 'User' => array('email' => 'example@example.com', 'name' => 'mark'),
+ 'other' => 'value'
+ );
+ $this->assertEqual('mark', $this->Cookie->read('User.name'));
+
+ $this->Cookie->delete('User');
+ $this->assertNull($this->Cookie->read('User.email'));
+ $this->Cookie->destroy();
+ }
/**
* Helper method for generating old style encoded cookie values.
*
diff --git a/lib/Cake/tests/Case/Controller/Component/RequestHandlerComponentTest.php b/lib/Cake/tests/Case/Controller/Component/RequestHandlerComponentTest.php
index 047db025e..172488d7c 100644
--- a/lib/Cake/tests/Case/Controller/Component/RequestHandlerComponentTest.php
+++ b/lib/Cake/tests/Case/Controller/Component/RequestHandlerComponentTest.php
@@ -292,6 +292,7 @@ class RequestHandlerComponentTest extends CakeTestCase {
function testStartupCallback() {
$_SERVER['REQUEST_METHOD'] = 'PUT';
$_SERVER['CONTENT_TYPE'] = 'application/xml';
+ $this->Controller->request = $this->getMock('CakeRequest', array('_readStdin'));
$this->RequestHandler->startup($this->Controller);
$this->assertTrue(is_array($this->Controller->data));
$this->assertFalse(is_object($this->Controller->data));
@@ -305,11 +306,35 @@ class RequestHandlerComponentTest extends CakeTestCase {
function testStartupCallbackCharset() {
$_SERVER['REQUEST_METHOD'] = 'PUT';
$_SERVER['CONTENT_TYPE'] = 'application/xml; charset=UTF-8';
+ $this->Controller->request = $this->getMock('CakeRequest', array('_readStdin'));
$this->RequestHandler->startup($this->Controller);
$this->assertTrue(is_array($this->Controller->data));
$this->assertFalse(is_object($this->Controller->data));
}
+/**
+ * Test mapping a new type and having startup process it.
+ *
+ * @return void
+ */
+ function testStartupCustomTypeProcess() {
+ if (!function_exists('str_getcsv')) {
+ $this->markTestSkipped('Need "str_getcsv" for this test.');
+ }
+ $_SERVER['REQUEST_METHOD'] = 'POST';
+ $_SERVER['CONTENT_TYPE'] = 'text/csv';
+ $this->Controller->request = $this->getMock('CakeRequest', array('_readStdin'));
+ $this->Controller->request->expects($this->once())
+ ->method('_readStdin')
+ ->will($this->returnValue('"A","csv","string"'));
+ $this->RequestHandler->addInputType('csv', array('str_getcsv'));
+ $this->RequestHandler->startup($this->Controller);
+ $expected = array(
+ 'A', 'csv', 'string'
+ );
+ $this->assertEquals($expected, $this->Controller->request->data);
+ }
+
/**
* testNonAjaxRedirect method
*
@@ -774,4 +799,11 @@ class RequestHandlerComponentTest extends CakeTestCase {
$result = ob_get_clean();
}
+/**
+ * @expectedException CakeException
+ * @return void
+ */
+ function testAddInputTypeException() {
+ $this->RequestHandler->addInputType('csv', array('I am not callable'));
+ }
}
diff --git a/lib/Cake/tests/Case/Controller/ComponentTest.php b/lib/Cake/tests/Case/Controller/ComponentTest.php
index e1685c25e..c52f007bd 100644
--- a/lib/Cake/tests/Case/Controller/ComponentTest.php
+++ b/lib/Cake/tests/Case/Controller/ComponentTest.php
@@ -339,7 +339,6 @@ class ComponentTest extends CakeTestCase {
$this->assertInstanceOf('SomethingWithEmailComponent', $Controller->SomethingWithEmail);
$this->assertInstanceOf('EmailComponent', $Controller->SomethingWithEmail->Email);
- $this->assertInstanceOf('ComponentTestController', $Controller->SomethingWithEmail->Email->Controller);
}
}
diff --git a/lib/Cake/tests/Case/Controller/ControllerTest.php b/lib/Cake/tests/Case/Controller/ControllerTest.php
index 2a25a281b..9af38e2cb 100644
--- a/lib/Cake/tests/Case/Controller/ControllerTest.php
+++ b/lib/Cake/tests/Case/Controller/ControllerTest.php
@@ -470,16 +470,8 @@ class ControllerTest extends CakeTestCase {
$request = new CakeRequest('controller_posts/index');
$Controller = new Controller($request);
- $Controller->modelClass = 'ControllerPost';
- $Controller->passedArgs[] = '1';
- $Controller->constructClasses();
- $this->assertEqual($Controller->ControllerPost->id, 1);
-
- unset($Controller);
-
$Controller = new Controller($request);
$Controller->uses = array('ControllerPost', 'ControllerComment');
- $Controller->passedArgs[] = '1';
$Controller->constructClasses();
$this->assertTrue(is_a($Controller->ControllerPost, 'ControllerPost'));
$this->assertTrue(is_a($Controller->ControllerComment, 'ControllerComment'));
@@ -494,7 +486,6 @@ class ControllerTest extends CakeTestCase {
$Controller->uses = array('TestPlugin.TestPluginPost');
$Controller->constructClasses();
- $this->assertEqual($Controller->modelClass, 'TestPluginPost');
$this->assertTrue(isset($Controller->TestPluginPost));
$this->assertTrue(is_a($Controller->TestPluginPost, 'TestPluginPost'));
@@ -917,7 +908,7 @@ class ControllerTest extends CakeTestCase {
$this->assertTrue(in_array('ControllerPost', $appVars['uses']));
$this->assertNull($testVars['uses']);
- $this->assertFalse(isset($TestController->ControllerPost));
+ $this->assertFalse(property_exists($TestController, 'ControllerPost'));
$TestController = new ControllerCommentsController($request);
diff --git a/lib/Cake/tests/Case/Core/AppTest.php b/lib/Cake/tests/Case/Core/AppTest.php
index 16d44cc7f..3b40453d8 100644
--- a/lib/Cake/tests/Case/Core/AppTest.php
+++ b/lib/Cake/tests/Case/Core/AppTest.php
@@ -22,9 +22,7 @@ class AppImportTest extends CakeTestCase {
$this->assertEqual($expected, $old);
App::build(array('Model' => array('/path/to/models/')));
-
$new = App::path('Model');
-
$expected = array(
'/path/to/models/',
APP . 'Model' . DS,
@@ -32,6 +30,46 @@ class AppImportTest extends CakeTestCase {
);
$this->assertEqual($expected, $new);
+ App::build();
+ App::build(array('Model' => array('/path/to/models/')), App::PREPEND);
+ $new = App::path('Model');
+ $expected = array(
+ '/path/to/models/',
+ APP . 'Model' . DS,
+ APP . 'models' . DS
+ );
+ $this->assertEqual($expected, $new);
+
+ App::build();
+ App::build(array('Model' => array('/path/to/models/')), App::APPEND);
+ $new = App::path('Model');
+ $expected = array(
+ APP . 'Model' . DS,
+ APP . 'models' . DS,
+ '/path/to/models/'
+ );
+ $this->assertEqual($expected, $new);
+
+ App::build();
+ App::build(array(
+ 'Model' => array('/path/to/models/'),
+ 'Controller' => array('/path/to/controllers/'),
+ ), App::APPEND);
+ $new = App::path('Model');
+ $expected = array(
+ APP . 'Model' . DS,
+ APP . 'models' . DS,
+ '/path/to/models/'
+ );
+ $this->assertEqual($expected, $new);
+ $new = App::path('Controller');
+ $expected = array(
+ APP . 'Controller' . DS,
+ APP . 'controllers' . DS,
+ '/path/to/controllers/'
+ );
+ $this->assertEqual($expected, $new);
+
App::build(); //reset defaults
$defaults = App::path('Model');
$this->assertEqual($old, $defaults);
@@ -152,7 +190,7 @@ class AppImportTest extends CakeTestCase {
);
$this->assertEqual($expected, $old);
- App::build(array('Model' => array('/path/to/models/')), true);
+ App::build(array('Model' => array('/path/to/models/')), App::RESET);
$new = App::path('Model');
@@ -183,13 +221,13 @@ class AppImportTest extends CakeTestCase {
$this->assertEqual(array(LIBS . 'Controller' . DS), $controller);
$component = App::core('Controller/Component');
- $this->assertEqual(array(LIBS . 'Controller' . DS . 'Component' . DS), $component);
+ $this->assertEqual(array(LIBS . 'Controller' . DS . 'Component' . DS), str_replace('/', DS, $component));
$auth = App::core('Controller/Component/Auth');
- $this->assertEqual(array(LIBS . 'Controller' . DS . 'Component' . DS . 'Auth' . DS), $auth);
+ $this->assertEqual(array(LIBS . 'Controller' . DS . 'Component' . DS . 'Auth' . DS), str_replace('/', DS, $auth));
$datasource = App::core('Model/Datasource');
- $this->assertEqual(array(LIBS . 'Model' . DS . 'Datasource' . DS), $datasource);
+ $this->assertEqual(array(LIBS . 'Model' . DS . 'Datasource' . DS), str_replace('/', DS, $datasource));
}
/**
@@ -210,7 +248,7 @@ class AppImportTest extends CakeTestCase {
'View' => App::core('View'),
'Model' => App::core('Model'),
'View/Helper' => App::core('View/Helper'),
- ), true);
+ ), App::RESET);
$result = App::objects('behavior', null, false);
$this->assertTrue(in_array('TreeBehavior', $result));
$result = App::objects('Model/Behavior', null, false);
@@ -285,9 +323,11 @@ class AppImportTest extends CakeTestCase {
$this->assertTrue(in_array('TestPluginPersisterOne', $result));
$result = App::objects('TestPlugin.helper');
+ sort($result);
$expected = array('OtherHelperHelper', 'PluggedHelper', 'TestPluginApp');
$this->assertEquals($result, $expected);
$result = App::objects('TestPlugin.View/Helper');
+ sort($result);
$expected = array('OtherHelperHelper', 'PluggedHelper', 'TestPluginApp');
$this->assertEquals($result, $expected);
@@ -462,7 +502,7 @@ class AppImportTest extends CakeTestCase {
$result = App::import('Helper', 'TestPlugin.OtherHelper');
$this->assertTrue($result);
$this->assertTrue(class_exists('OtherHelperHelper'));
-
+
$result = App::import('Helper', 'TestPlugin.TestPluginApp');
$this->assertTrue($result);
$this->assertTrue(class_exists('TestPluginAppHelper'));
@@ -470,7 +510,7 @@ class AppImportTest extends CakeTestCase {
$result = App::import('Datasource', 'TestPlugin.TestSource');
$this->assertTrue($result);
$this->assertTrue(class_exists('TestSource'));
-
+
App::build();
}
@@ -621,7 +661,7 @@ class AppImportTest extends CakeTestCase {
App::build(array(
'plugins' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'plugins' . DS),
'vendors' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'vendors'. DS),
- ), true);
+ ), App::RESET);
ob_start();
$result = App::import('Vendor', 'css/TestAsset', array('ext' => 'css'));
@@ -677,7 +717,7 @@ class AppImportTest extends CakeTestCase {
App::build(array(
'libs' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'libs' . DS),
'plugins' => array(LIBS . 'tests' . DS . 'test_app' . DS . 'plugins' . DS)
- ), true);
+ ), App::RESET);
$this->assertFalse(class_exists('CustomLibClass', false));
App::uses('CustomLibClass', 'TestPlugin.Custom/Package');
diff --git a/lib/Cake/tests/Case/Core/ObjectTest.php b/lib/Cake/tests/Case/Core/ObjectTest.php
index a9729255d..8566057df 100644
--- a/lib/Cake/tests/Case/Core/ObjectTest.php
+++ b/lib/Cake/tests/Case/Core/ObjectTest.php
@@ -822,7 +822,6 @@ class ObjectTest extends CakeTestCase {
$this->assertEqual($result->url, 'request_action/params_pass');
$this->assertEqual($result['controller'], 'request_action');
$this->assertEqual($result['action'], 'params_pass');
- $this->assertEqual($result['form'], array());
$this->assertEqual($result['plugin'], null);
$result = $this->object->requestAction('/request_action/params_pass/sort:desc/limit:5');
diff --git a/lib/Cake/tests/Case/Error/ErrorHandlerTest.php b/lib/Cake/tests/Case/Error/ErrorHandlerTest.php
index 7fc875aea..9b119bdfe 100644
--- a/lib/Cake/tests/Case/Error/ErrorHandlerTest.php
+++ b/lib/Cake/tests/Case/Error/ErrorHandlerTest.php
@@ -37,8 +37,7 @@ class ErrorHandlerTest extends CakeTestCase {
function setUp() {
App::build(array(
'View' => array(
- LIBS . 'tests' . DS . 'test_app' . DS . 'views'. DS,
- LIBS . 'libs' . DS . 'view' . DS
+ LIBS . 'tests' . DS . 'test_app' . DS . 'View'. DS
)
), true);
Router::reload();
@@ -148,7 +147,7 @@ class ErrorHandlerTest extends CakeTestCase {
$result = file(LOGS . 'debug.log');
$this->assertEqual(count($result), 1);
$this->assertPattern(
- '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} Notice: Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
+ '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (Notice|Debug): Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
$result[0]
);
@unlink(LOGS . 'debug.log');
@@ -173,7 +172,7 @@ class ErrorHandlerTest extends CakeTestCase {
$result = file(LOGS . 'debug.log');
$this->assertPattern(
- '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} Notice: Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
+ '/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (Notice|Debug): Notice \(8\): Undefined variable:\s+out in \[.+ line \d+\]$/',
$result[0]
);
$this->assertPattern('/^Trace:/', $result[1]);
@@ -223,4 +222,23 @@ class ErrorHandlerTest extends CakeTestCase {
$this->assertPattern('/\#0.*ErrorHandlerTest->testHandleExceptionLog/', $log[1], 'Stack trace missing.');
}
+/**
+ * tests it is possible to load a plugin exception renderer
+ *
+ * @return void
+ */
+ function testLoadPluginHanlder() {
+ App::build(array(
+ 'plugins' => array(
+ LIBS . 'tests' . DS . 'test_app' . DS . 'plugins' . DS
+ )
+ ), true);
+ Configure::write('Exception.renderer', 'TestPlugin.TestPluginExceptionRenderer');
+ $error = new NotFoundException('Kaboom!');
+ ob_start();
+ ErrorHandler::handleException($error);
+ $result = ob_get_clean();
+ $this->assertEquals($result, 'Rendered by test plugin');
+ }
+
}
diff --git a/lib/Cake/tests/Case/Error/ExceptionRendererTest.php b/lib/Cake/tests/Case/Error/ExceptionRendererTest.php
index 3017f125b..7e56f7c9c 100644
--- a/lib/Cake/tests/Case/Error/ExceptionRendererTest.php
+++ b/lib/Cake/tests/Case/Error/ExceptionRendererTest.php
@@ -609,4 +609,32 @@ class ExceptionRendererTest extends CakeTestCase {
$this->assertPattern($pattern, $result);
}
}
+
+/**
+ * Test exceptions being raised when helpers are missing.
+ *
+ * @return void
+ */
+ function testMissingRenderSafe() {
+ $exception = new MissingHelperFileException(array('class' => 'Fail'));
+ $ExceptionRenderer = new ExceptionRenderer($exception);
+
+ $ExceptionRenderer->controller = $this->getMock('Controller');
+ $ExceptionRenderer->controller->helpers = array('Fail', 'Boom');
+ $ExceptionRenderer->controller->request = $this->getMock('CakeRequest');
+ $ExceptionRenderer->controller->expects($this->at(2))
+ ->method('render')
+ ->with('missingHelperFile')
+ ->will($this->throwException($exception));
+
+ $ExceptionRenderer->controller->expects($this->at(3))
+ ->method('render')
+ ->with('error500')
+ ->will($this->returnValue(true));
+
+ $ExceptionRenderer->controller->response = $this->getMock('CakeResponse');
+ $ExceptionRenderer->render();
+ sort($ExceptionRenderer->controller->helpers);
+ $this->assertEquals(array('Form', 'Html', 'Session'), $ExceptionRenderer->controller->helpers);
+ }
}
diff --git a/lib/Cake/tests/Case/I18n/I18nTest.php b/lib/Cake/tests/Case/I18n/I18nTest.php
index a5de7dd49..37dace724 100644
--- a/lib/Cake/tests/Case/I18n/I18nTest.php
+++ b/lib/Cake/tests/Case/I18n/I18nTest.php
@@ -55,7 +55,7 @@ class I18nTest extends CakeTestCase {
function testTranslationCaching() {
Configure::write('Config.language', 'cache_test_po');
- $i18n =& i18n::getInstance();
+ $i18n = i18n::getInstance();
// reset internally stored entries
I18n::clear();
diff --git a/lib/Cake/tests/Case/Model/Behavior/AclBehaviorTest.php b/lib/Cake/tests/Case/Model/Behavior/AclBehaviorTest.php
index a6f29cfe6..df8fb3f50 100644
--- a/lib/Cake/tests/Case/Model/Behavior/AclBehaviorTest.php
+++ b/lib/Cake/tests/Case/Model/Behavior/AclBehaviorTest.php
@@ -266,7 +266,7 @@ class AclBehaviorTest extends CakeTestCase {
* @access public
*/
function testSetupMulti() {
- $User =& new AclPerson();
+ $User = new AclPerson();
$this->assertTrue(isset($User->Behaviors->Acl->settings['AclPerson']));
$this->assertEqual($User->Behaviors->Acl->settings['AclPerson']['type'], 'both');
$this->assertTrue(is_object($User->Aro));
diff --git a/lib/Cake/tests/Case/Model/CakeSchemaTest.php b/lib/Cake/tests/Case/Model/CakeSchemaTest.php
index 12dab45b0..f2b17f212 100644
--- a/lib/Cake/tests/Case/Model/CakeSchemaTest.php
+++ b/lib/Cake/tests/Case/Model/CakeSchemaTest.php
@@ -209,7 +209,7 @@ class TestAppSchema extends CakeSchema {
*/
public $datatypes = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => 0, 'key' => 'primary'),
- 'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => '', 'collate' => null, 'comment' => null),
+ 'float_field' => array('type' => 'float', 'null' => false, 'length' => '5,2', 'default' => ''),
'bool' => array('type' => 'boolean', 'null' => false, 'default' => false),
'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => true)),
'tableParameters' => array()
diff --git a/lib/Cake/tests/Case/Model/Datasource/Database/MysqlTest.php b/lib/Cake/tests/Case/Model/Datasource/Database/MysqlTest.php
index 6ad8c1cda..5535cfd4a 100644
--- a/lib/Cake/tests/Case/Model/Datasource/Database/MysqlTest.php
+++ b/lib/Cake/tests/Case/Model/Datasource/Database/MysqlTest.php
@@ -147,6 +147,8 @@ class DboMysqlTest extends CakeTestCase {
* @return void
*/
function testLocalizedFloats() {
+ $this->skipIf(DS === '\\', 'The locale is not supported in Windows and affect the others tests.');
+
$restore = setlocale(LC_ALL, null);
setlocale(LC_ALL, 'de_DE');
diff --git a/lib/Cake/tests/Case/Model/ModelDeleteTest.php b/lib/Cake/tests/Case/Model/ModelDeleteTest.php
index 8ec9aaa1c..bbd356002 100644
--- a/lib/Cake/tests/Case/Model/ModelDeleteTest.php
+++ b/lib/Cake/tests/Case/Model/ModelDeleteTest.php
@@ -540,7 +540,7 @@ class ModelDeleteTest extends BaseModelTest {
*/
function testDeleteLinksWithPLuginJoinModel() {
$this->loadFixtures('Article', 'ArticlesTag', 'Tag');
- $Article =& new Article();
+ $Article = new Article();
$Article->unbindModel(array('hasAndBelongsToMany' => array('Tag')), false);
unset($Article->Tag, $Article->ArticleTags);
$Article->bindModel(array('hasAndBelongsToMany' => array(
diff --git a/lib/Cake/tests/Case/Model/ModelValidationTest.php b/lib/Cake/tests/Case/Model/ModelValidationTest.php
index 8cc48aa3f..2182637c8 100644
--- a/lib/Cake/tests/Case/Model/ModelValidationTest.php
+++ b/lib/Cake/tests/Case/Model/ModelValidationTest.php
@@ -565,7 +565,7 @@ class ModelValidationTest extends BaseModelTest {
);
$Something = new Something();
- $JoinThing =& $Something->JoinThing;
+ $JoinThing = $Something->JoinThing;
$JoinThing->validate = array('doomed' => array('rule' => 'notEmpty'));
@@ -618,7 +618,7 @@ class ModelValidationTest extends BaseModelTest {
)
);
$Something = new Something();
- $JoinThing =& $Something->JoinThing;
+ $JoinThing = $Something->JoinThing;
$JoinThing->validate = array('doomed' => array('rule' => 'notEmpty'));
$expectedError = array('doomed' => array('This field cannot be left blank'));
diff --git a/lib/Cake/tests/Case/Model/ModelWriteTest.php b/lib/Cake/tests/Case/Model/ModelWriteTest.php
index 466c703d8..2e942f636 100644
--- a/lib/Cake/tests/Case/Model/ModelWriteTest.php
+++ b/lib/Cake/tests/Case/Model/ModelWriteTest.php
@@ -3016,7 +3016,7 @@ class ModelWriteTest extends BaseModelTest {
$testDb = ConnectionManager::getDataSource('test');
$mock = $this->getMock('DboSource', array(), array(), 'MockTransactionAssociatedDboSource', false);
- $db =& ConnectionManager::create('mock_transaction_assoc', array(
+ $db = ConnectionManager::create('mock_transaction_assoc', array(
'datasource' => 'MockTransactionAssociatedDboSource',
));
$this->mockObjects[] = $db;
@@ -3824,12 +3824,24 @@ class ModelWriteTest extends BaseModelTest {
}
/**
- * testProductUpdateAllWithForeignKey
+ * test updateAll with empty values.
+ *
+ * @return void
+ */
+ function testUpdateAllEmptyValues() {
+ $this->loadFixtures('Author', 'Post');
+ $model = new Author();
+ $result = $model->updateAll(array('user' => '""'));
+ $this->assertTrue($result);
+ }
+
+/**
+ * testUpdateAllWithJoins
*
* @access public
* @return void
*/
- function testProductUpdateAll() {
+ function testUpdateAllWithJoins() {
$this->skipIf(
!$this->db instanceof Mysql,
'%s Currently, there is no way of doing joins in an update statement in postgresql or sqlite'
@@ -3874,12 +3886,12 @@ class ModelWriteTest extends BaseModelTest {
}
/**
- * testProductUpdateAllWithoutForeignKey
+ * testUpdateAllWithoutForeignKey
*
* @access public
* @return void
*/
- function testProductUpdateAllWithoutForeignKey() {
+ function testUpdateAllWithoutForeignKey() {
$this->skipIf(
!$this->db instanceof Mysql,
'%s Currently, there is no way of doing joins in an update statement in postgresql'
diff --git a/lib/Cake/tests/Case/Network/CakeRequestTest.php b/lib/Cake/tests/Case/Network/CakeRequestTest.php
index 65eb45042..ffb1febef 100644
--- a/lib/Cake/tests/Case/Network/CakeRequestTest.php
+++ b/lib/Cake/tests/Case/Network/CakeRequestTest.php
@@ -18,6 +18,7 @@
*/
App::uses('Dispatcher', 'Routing');
+App::uses('Xml', 'Utility');
App::uses('CakeRequest', 'Network');
class CakeRequestTestCase extends CakeTestCase {
@@ -33,6 +34,11 @@ class CakeRequestTestCase extends CakeTestCase {
$this->_post = $_POST;
$this->_files = $_FILES;
$this->_app = Configure::read('App');
+ $this->_case = null;
+ if (isset($_GET['case'])) {
+ $this->_case = $_GET['case'];
+ unset($_GET['case']);
+ }
Configure::write('App.baseUrl', false);
}
@@ -48,6 +54,9 @@ class CakeRequestTestCase extends CakeTestCase {
$_GET = $this->_get;
$_POST = $this->_post;
$_FILES = $this->_files;
+ if (!empty($this->_case)) {
+ $_GET['case'] = $this->_case;
+ }
Configure::write('App', $this->_app);
}
@@ -152,7 +161,7 @@ class CakeRequestTestCase extends CakeTestCase {
$_POST = array('one' => 1, 'two' => 'three');
$request = new CakeRequest('some/path');
- $this->assertEqual($request->params['form'], $_POST);
+ $this->assertEquals($_POST, $request->data);
}
/**
@@ -1173,7 +1182,7 @@ class CakeRequestTestCase extends CakeTestCase {
),
),
array(
- 'Apache - No rewrite, document root set above top level cake dir, reques root, no PATH_INFO',
+ 'Apache - No rewrite, document root set above top level cake dir, request root, no PATH_INFO',
array(
'App' => array(
'base' => false,
@@ -1426,6 +1435,59 @@ class CakeRequestTestCase extends CakeTestCase {
$this->assertEquals('/posts/base_path/1/name:value?test=value', $result);
}
+/**
+ * Test the input() method.
+ *
+ * @return void
+ */
+ function testInput() {
+ $request = $this->getMock('CakeRequest', array('_readStdin'));
+ $request->expects($this->once())->method('_readStdin')
+ ->will($this->returnValue('I came from stdin'));
+
+ $result = $request->input();
+ $this->assertEquals('I came from stdin', $result);
+ }
+
+/**
+ * Test input() decoding.
+ *
+ * @return void
+ */
+ function testInputDecode() {
+ $request = $this->getMock('CakeRequest', array('_readStdin'));
+ $request->expects($this->once())->method('_readStdin')
+ ->will($this->returnValue('{"name":"value"}'));
+
+ $result = $request->input('json_decode');
+ $this->assertEquals(array('name' => 'value'), (array)$result);
+ }
+
+/**
+ * Test input() decoding with additional arguments.
+ *
+ * @return void
+ */
+ function testInputDecodeExtraParams() {
+ $xml = <<
+
+ Test
+
+XML;
+
+ $request = $this->getMock('CakeRequest', array('_readStdin'));
+ $request->expects($this->once())->method('_readStdin')
+ ->will($this->returnValue($xml));
+
+ $result = $request->input('Xml::build', array('return' => 'domdocument'));
+ $this->assertInstanceOf('DOMDocument', $result);
+ $this->assertEquals(
+ 'Test',
+ $result->getElementsByTagName('title')->item(0)->childNodes->item(0)->wholeText
+ );
+ }
+
/**
* loadEnvironment method
*
@@ -1457,4 +1519,4 @@ class CakeRequestTestCase extends CakeTestCase {
}
}
-}
\ No newline at end of file
+}
diff --git a/lib/Cake/tests/Case/Network/CakeEmailTest.php b/lib/Cake/tests/Case/Network/Email/CakeEmailTest.php
similarity index 99%
rename from lib/Cake/tests/Case/Network/CakeEmailTest.php
rename to lib/Cake/tests/Case/Network/Email/CakeEmailTest.php
index d44a602b9..45c7b1443 100644
--- a/lib/Cake/tests/Case/Network/CakeEmailTest.php
+++ b/lib/Cake/tests/Case/Network/Email/CakeEmailTest.php
@@ -16,7 +16,7 @@
* @since CakePHP(tm) v 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
-App::uses('CakeEmail', 'Network');
+App::uses('CakeEmail', 'Network/Email');
/**
* Help to test CakeEmail
diff --git a/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php b/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php
index 49477968b..5b75da480 100644
--- a/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php
+++ b/lib/Cake/tests/Case/Network/Email/SmtpTransportTest.php
@@ -16,7 +16,7 @@
* @since CakePHP(tm) v 2.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
-App::uses('CakeEmail', 'Network');
+App::uses('CakeEmail', 'Network/Email');
App::uses('AbstractTransport', 'Network/Email');
App::uses('SmtpTransport', 'Network/Email');
@@ -211,8 +211,8 @@ class StmpProtocolTest extends CakeTestCase {
* @return void
*/
public function testSendData() {
- $this->getMock('CakeEmail', array('message'), array(), 'TestCakeEmail');
- $email = new TestCakeEmail();
+ $this->getMock('CakeEmail', array('message'), array(), 'SmtpCakeEmail');
+ $email = new SmtpCakeEmail();
$email->from('noreply@cakephp.org', 'CakePHP Test');
$email->to('cake@cakephp.org', 'CakePHP');
$email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso'));
@@ -225,10 +225,11 @@ class StmpProtocolTest extends CakeTestCase {
$data .= "To: CakePHP \r\n";
$data .= "Cc: Mark Story , Juan Basso \r\n";
$data .= "Bcc: phpnut@cakephp.org\r\n";
- $data .= "X-Mailer: CakePHP Email Component\r\n";
+ $data .= "X-Mailer: CakePHP Email\r\n";
$data .= "Date: " . date(DATE_RFC2822) . "\r\n";
$data .= "Message-ID: <4d9946cf-0a44-4907-88fe-1d0ccbdd56cb@localhost>\r\n";
$data .= "Subject: Testing SMTP\r\n";
+ $data .= "MIME-Version: 1.0\r\n";
$data .= "Content-Type: text/plain; charset=UTF-8\r\n";
$data .= "Content-Transfer-Encoding: 7bit\r\n";
$data .= "\r\n";
diff --git a/lib/Cake/tests/Case/Network/Http/HttpSocketTest.php b/lib/Cake/tests/Case/Network/Http/HttpSocketTest.php
index d0f46de52..259630c71 100644
--- a/lib/Cake/tests/Case/Network/Http/HttpSocketTest.php
+++ b/lib/Cake/tests/Case/Network/Http/HttpSocketTest.php
@@ -595,6 +595,34 @@ class HttpSocketTest extends CakeTestCase {
$this->assertFalse($this->Socket->connected);
}
+/**
+ * testRequestWithConstructor method
+ *
+ * @return void
+ */
+ public function testRequestWithConstructor() {
+ $request = array(
+ 'request' => array(
+ 'uri' => array(
+ 'scheme' => 'http',
+ 'host' => 'localhost',
+ 'port' => '5984',
+ 'user' => null,
+ 'pass' => null
+ )
+ )
+ );
+ $http = new MockHttpSocketRequests($request);
+
+ $expected = array('method' => 'GET', 'uri' => '/_test');
+ $http->expects($this->at(0))->method('request')->with($expected);
+ $http->get('/_test');
+
+ $expected = array('method' => 'GET', 'uri' => 'http://localhost:5984/_test?count=4');
+ $http->expects($this->at(0))->method('request')->with($expected);
+ $http->get('/_test', array('count' => 4));
+ }
+
/**
* testRequestWithResource
*
diff --git a/lib/Cake/tests/Case/Routing/DispatcherTest.php b/lib/Cake/tests/Case/Routing/DispatcherTest.php
index e86431a45..55e254409 100644
--- a/lib/Cake/tests/Case/Routing/DispatcherTest.php
+++ b/lib/Cake/tests/Case/Routing/DispatcherTest.php
@@ -585,8 +585,7 @@ class DispatcherTest extends CakeTestCase {
$Dispatcher = new Dispatcher();
$test = $Dispatcher->parseParams(new CakeRequest("/"));
- $this->assertFalse(empty($test['form']), "Parsed URL not returning post data");
- $this->assertEquals($test['form']['testdata'], "My Posted Content");
+ $this->assertEquals($test['data']['testdata'], "My Posted Content");
}
/**
@@ -868,7 +867,7 @@ class DispatcherTest extends CakeTestCase {
$expected = array(
'pass' => array('home'),
'named' => array('param'=> 'value', 'param2'=> 'value2'), 'plugin'=> 'my_plugin',
- 'controller'=> 'some_pages', 'action'=> 'display', 'form'=> array(),
+ 'controller'=> 'some_pages', 'action'=> 'display'
);
foreach ($expected as $key => $value) {
$this->assertEqual($result[$key], $value, 'Value mismatch ' . $key . ' %');
@@ -1000,7 +999,6 @@ class DispatcherTest extends CakeTestCase {
'action' => 'admin_index',
'prefix' => 'admin',
'admin' => true,
- 'form' => array(),
'return' => 1
);
foreach ($expected as $key => $value) {
@@ -1524,7 +1522,7 @@ class DispatcherTest extends CakeTestCase {
$dispatcher = new Dispatcher();
$result = $dispatcher->parseParams(new CakeRequest('/posts'));
- $expected = array('pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add', '[method]' => 'POST', 'form' => array());
+ $expected = array('pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add', '[method]' => 'POST');
foreach ($expected as $key => $value) {
$this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s');
}
@@ -1533,7 +1531,15 @@ class DispatcherTest extends CakeTestCase {
$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] = 'PUT';
$result = $dispatcher->parseParams(new CakeRequest('/posts/5'));
- $expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT', 'form' => array());
+ $expected = array(
+ 'pass' => array('5'),
+ 'named' => array(),
+ 'id' => '5',
+ 'plugin' => null,
+ 'controller' => 'posts',
+ 'action' => 'edit',
+ '[method]' => 'PUT'
+ );
foreach ($expected as $key => $value) {
$this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s');
}
@@ -1542,7 +1548,7 @@ class DispatcherTest extends CakeTestCase {
$_SERVER['REQUEST_METHOD'] = 'GET';
$result = $dispatcher->parseParams(new CakeRequest('/posts/5'));
- $expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'view', '[method]' => 'GET', 'form' => array());
+ $expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'view', '[method]' => 'GET');
foreach ($expected as $key => $value) {
$this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s');
}
@@ -1550,7 +1556,7 @@ class DispatcherTest extends CakeTestCase {
$_POST['_method'] = 'PUT';
$result = $dispatcher->parseParams(new CakeRequest('/posts/5'));
- $expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT', 'form' => array());
+ $expected = array('pass' => array('5'), 'named' => array(), 'id' => '5', 'plugin' => null, 'controller' => 'posts', 'action' => 'edit', '[method]' => 'PUT');
foreach ($expected as $key => $value) {
$this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s');
}
@@ -1563,7 +1569,7 @@ class DispatcherTest extends CakeTestCase {
$result = $dispatcher->parseParams(new CakeRequest('/posts'));
$expected = array(
'pass' => array(), 'named' => array(), 'plugin' => null, 'controller' => 'posts', 'action' => 'add',
- '[method]' => 'POST', 'form' => array('extra' => 'data'), 'data' => array('Post' => array('title' => 'New Post')),
+ '[method]' => 'POST', 'data' => array('extra' => 'data', 'Post' => array('title' => 'New Post')),
);
foreach ($expected as $key => $value) {
$this->assertEqual($result[$key], $value, 'Value mismatch for ' . $key . ' %s');
diff --git a/lib/Cake/tests/Case/Routing/RouterTest.php b/lib/Cake/tests/Case/Routing/RouterTest.php
index ac6f2fda6..67e058080 100644
--- a/lib/Cake/tests/Case/Routing/RouterTest.php
+++ b/lib/Cake/tests/Case/Routing/RouterTest.php
@@ -1275,7 +1275,7 @@ class RouterTest extends CakeTestCase {
$this->assertEqual($result, $expected);
$result = Router::parse('/posts.atom?hello=goodbye');
- $expected = array('plugin' => null, 'controller' => 'posts.atom', 'action' => 'index', 'pass' => array(), 'named' => array(), 'url' => array('ext' => 'html'));
+ $expected = array('plugin' => null, 'controller' => 'posts.atom', 'action' => 'index', 'pass' => array(), 'named' => array());
$this->assertEqual($result, $expected);
Router::reload();
@@ -2164,7 +2164,7 @@ class RouterTest extends CakeTestCase {
$expected = array(
'plugin' => null, 'controller' => false, 'action' => false,
- 'param1' => '1', 'param2' => '2', 'form' => array()
+ 'param1' => '1', 'param2' => '2'
);
$this->assertEqual(Router::getParams(), $expected);
$this->assertEqual(Router::getParam('controller'), false);
@@ -2175,7 +2175,7 @@ class RouterTest extends CakeTestCase {
$params = array('controller' => 'pages', 'action' => 'display');
Router::setRequestInfo(array($params, $paths));
- $expected = array('plugin' => null, 'controller' => 'pages', 'action' => 'display', 'form' => array());
+ $expected = array('plugin' => null, 'controller' => 'pages', 'action' => 'display');
$this->assertEqual(Router::getParams(), $expected);
$this->assertEqual(Router::getParams(true), $expected);
}
diff --git a/lib/Cake/tests/Case/TestSuite/CakeTestFixtureTest.php b/lib/Cake/tests/Case/TestSuite/CakeTestFixtureTest.php
index edfe8e888..551e7452a 100644
--- a/lib/Cake/tests/Case/TestSuite/CakeTestFixtureTest.php
+++ b/lib/Cake/tests/Case/TestSuite/CakeTestFixtureTest.php
@@ -64,6 +64,53 @@ class CakeTestFixtureTestFixture extends CakeTestFixture {
);
}
+/**
+ * StringFieldsTestFixture class
+ *
+ * @package cake
+ * @subpackage cake.cake.tests.cases.libs
+ */
+class StringsTestFixture extends CakeTestFixture {
+
+/**
+ * name Property
+ *
+ * @var string
+ */
+ var $name = 'Strings';
+
+/**
+ * table property
+ *
+ * @var string
+ */
+ var $table = 'strings';
+
+/**
+ * Fields array
+ *
+ * @var array
+ */
+ var $fields = array(
+ 'id' => array('type' => 'integer', 'key' => 'primary'),
+ 'name' => array('type' => 'string', 'length' => '255'),
+ 'email' => array('type' => 'string', 'length' => '255'),
+ 'age' => array('type' => 'integer', 'default' => 10)
+ );
+
+/**
+ * Records property
+ *
+ * @var array
+ */
+ var $records = array(
+ array('name' => 'Mark Doe', 'email' => 'mark.doe@email.com'),
+ array('name' => 'John Doe', 'email' => 'john.doe@email.com', 'age' => 20),
+ array('email' => 'jane.doe@email.com', 'name' => 'Jane Doe', 'age' => 30)
+ );
+}
+
+
/**
* CakeTestFixtureImportFixture class
*
@@ -120,6 +167,7 @@ class FixturePrefixTest extends Model {
public $useDbConfig = 'test';
}
+
/**
* Test case for CakeTestFixture
*
@@ -203,7 +251,7 @@ class CakeTestFixtureTest extends CakeTestCase {
$Fixture->init();
$this->assertEqual(array_keys($Fixture->fields), array('id', 'name', 'created'));
$this->assertEqual($Fixture->table, 'fixture_tests');
-
+
$keys = array_flip(ClassRegistry::keys());
$this->assertFalse(array_key_exists('fixtureimporttestmodel', $keys));
@@ -302,7 +350,7 @@ class CakeTestFixtureTest extends CakeTestCase {
}
/**
- * test that importing with records works. Make sure to try with postgres as its
+ * test that importing with records works. Make sure to try with postgres as its
* handling of aliases is a workaround at best.
*
* @return void
@@ -334,7 +382,7 @@ class CakeTestFixtureTest extends CakeTestCase {
$defaultDb->config = $defaultConfig;
- $Source->drop($newTestSuiteDb);
+ $Source->drop($newTestSuiteDb);
}
/**
@@ -364,11 +412,62 @@ class CakeTestFixtureTest extends CakeTestCase {
*/
function testInsert() {
$Fixture = new CakeTestFixtureTestFixture();
- $this->criticDb->expects($this->atLeastOnce())->method('insertMulti')->will($this->returnValue(true));
+ $this->criticDb->expects($this->atLeastOnce())
+ ->method('insertMulti')
+ ->will($this->returnCallback(array($this, '_insertCallback')));
+
+ $return = $Fixture->insert($this->criticDb);
+ $this->assertTrue(!empty($this->insertMulti));
+ $this->assertTrue($this->criticDb->fullDebug);
+ $this->assertTrue($return);
+ $this->assertEqual('fixture_tests', $this->insertMulti['table']);
+ $this->assertEqual(array('name', 'created'), $this->insertMulti['fields']);
+ $expected = array(
+ array('Gandalf', '2009-04-28 19:20:00'),
+ array('Captain Picard', '2009-04-28 19:20:00'),
+ array('Chewbacca', '2009-04-28 19:20:00')
+ );
+ $this->assertEqual($expected, $this->insertMulti['values']);
+ }
+
+/**
+ * Helper function to be used as callback and store the parameters of an insertMulti call
+ *
+ * @param string $table
+ * @param string $fields
+ * @param string $values
+ * @return boolean true
+ */
+ function _insertCallback($table, $fields, $values) {
+ $this->insertMulti['table'] = $table;
+ $this->insertMulti['fields'] = $fields;
+ $this->insertMulti['values'] = $values;
+ return true;
+ }
+
+/**
+ * test the insert method
+ *
+ * @access public
+ * @return void
+ */
+ function testInsertStrings() {
+ $Fixture = new StringsTestFixture();
+ $this->criticDb->expects($this->atLeastOnce())
+ ->method('insertMulti')
+ ->will($this->returnCallback(array($this, '_insertCallback')));
$return = $Fixture->insert($this->criticDb);
$this->assertTrue($this->criticDb->fullDebug);
$this->assertTrue($return);
+ $this->assertEqual('strings', $this->insertMulti['table']);
+ $this->assertEqual(array('email', 'name', 'age'), $this->insertMulti['fields']);
+ $expected = array(
+ array('Mark Doe', 'mark.doe@email.com', null),
+ array('John Doe', 'john.doe@email.com', 20),
+ array('Jane Doe', 'jane.doe@email.com', 30),
+ );
+ $this->assertEqual($expected, $this->insertMulti['values']);
}
/**
diff --git a/lib/Cake/tests/Case/Utility/DebuggerTest.php b/lib/Cake/tests/Case/Utility/DebuggerTest.php
index ac1d51b25..c9127ba71 100644
--- a/lib/Cake/tests/Case/Utility/DebuggerTest.php
+++ b/lib/Cake/tests/Case/Utility/DebuggerTest.php
@@ -145,9 +145,9 @@ class DebuggerTest extends CakeTestCase {
'pre' => array('class' => 'cake-debug'),
'a' => array(
'href' => "javascript:void(0);",
- 'onclick' => "document.getElementById('cakeErr9-trace').style.display = " .
- "(document.getElementById('cakeErr9-trace').style.display == 'none'" .
- " ? '' : 'none');"
+ 'onclick' => "preg:/document\.getElementById\('cakeErr[a-z0-9]+\-trace'\)\.style\.display = " .
+ "\(document\.getElementById\('cakeErr[a-z0-9]+\-trace'\)\.style\.display == 'none'" .
+ " \? '' \: 'none'\);/"
),
'b' => array(), 'Notice', '/b', ' (8)',
));
@@ -171,7 +171,7 @@ class DebuggerTest extends CakeTestCase {
'&line={:line}">{:path}, line {:line}'
));
$result = Debugger::trace();
- $this->assertPattern('/' . preg_quote('txmt://open?url=file:///', '/') . '/', $result);
+ $this->assertPattern('/' . preg_quote('txmt://open?url=file://', '/') . '(\/|[A-Z]:\\\\)' . '/', $result);
Debugger::output('xml', array(
'error' => '{:code}
{:file}{:line}' .
diff --git a/lib/Cake/tests/Case/Utility/SetTest.php b/lib/Cake/tests/Case/Utility/SetTest.php
index 59b83bf0a..233ad7a4f 100644
--- a/lib/Cake/tests/Case/Utility/SetTest.php
+++ b/lib/Cake/tests/Case/Utility/SetTest.php
@@ -957,6 +957,40 @@ class SetTest extends CakeTestCase {
$result = Set::extract('/ParentNode/name', $hasMany);
$expected = array('Second');
$this->assertEqual($result, $expected);
+
+ $data = array(
+ array(
+ 'Category' => array(
+ 'id' => 1,
+ 'name' => 'First'
+ ),
+ 0 => array(
+ 'value' => 50
+ )
+ ),
+ array(
+ 'Category' => array(
+ 'id' => 2,
+ 'name' => 'Second'
+ ),
+ 0 => array(
+ 'value' => 60
+ )
+ )
+ );
+ $expected = array(
+ array(
+ 'Category' => array(
+ 'id' => 1,
+ 'name' => 'First'
+ ),
+ 0 => array(
+ 'value' => 50
+ )
+ )
+ );
+ $result = Set::extract('/Category[id=1]/..', $data);
+ $this->assertEqual($result, $expected);
}
/**
diff --git a/lib/Cake/tests/Case/View/Helper/FormHelperTest.php b/lib/Cake/tests/Case/View/Helper/FormHelperTest.php
index a26a8fb4d..382e44efb 100644
--- a/lib/Cake/tests/Case/View/Helper/FormHelperTest.php
+++ b/lib/Cake/tests/Case/View/Helper/FormHelperTest.php
@@ -3451,6 +3451,26 @@ class FormHelperTest extends CakeTestCase {
'/select'
);
$this->assertTags($result, $expected);
+
+ $result = $this->Form->select(
+ 'Model.multi_field', $options, array('multiple' => false, 'value' => array(0, 1))
+ );
+ $expected = array(
+ 'select' => array(
+ 'name' => 'data[Model][multi_field]', 'id' => 'ModelMultiField'
+ ),
+ array('option' => array('value' => '0', 'selected' => 'selected')),
+ 'first',
+ '/option',
+ array('option' => array('value' => '1', 'selected' => 'selected')),
+ 'second',
+ '/option',
+ array('option' => array('value' => '2')),
+ 'third',
+ '/option',
+ '/select'
+ );
+ $this->assertTags($result, $expected);
}
/**
@@ -3844,6 +3864,61 @@ class FormHelperTest extends CakeTestCase {
);
$this->assertTags($result, $expected);
}
+/**
+ * testSelectHiddenFieldOmission method
+ *
+ * test that select() with 'hiddenField' => false omits the hidden field
+ *
+ * @access public
+ * @return void
+ */
+ function testSelectHiddenFieldOmission() {
+ $result = $this->Form->select('Model.multi_field',
+ array('first', 'second'),
+ array('multiple' => 'checkbox', 'hiddenField' => false, 'value' => null)
+ );
+ $expected = array(
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '0', 'id' => 'ModelMultiField0')),
+ array('label' => array('for' => 'ModelMultiField0')),
+ 'first',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1', 'id' => 'ModelMultiField1')),
+ array('label' => array('for' => 'ModelMultiField1')),
+ 'second',
+ '/label',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Model.multi_field', array(
+ 'options' => array('first', 'second'),
+ 'multiple' => 'checkbox',
+ 'hiddenField' => false
+ ));
+ $expected = array(
+ array('div' => array('class' => 'input select')),
+ array('label' => array('for' => 'ModelMultiField')),
+ 'Multi Field',
+ '/label',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '0', 'id' => 'ModelMultiField0')),
+ array('label' => array('for' => 'ModelMultiField0')),
+ 'first',
+ '/label',
+ '/div',
+ array('div' => array('class' => 'checkbox')),
+ array('input' => array('type' => 'checkbox', 'name' => 'data[Model][multi_field][]', 'value' => '1', 'id' => 'ModelMultiField1')),
+ array('label' => array('for' => 'ModelMultiField1')),
+ 'second',
+ '/label',
+ '/div',
+ '/div'
+ );
+ $this->assertTags($result, $expected);
+ }
/**
* test that select() with multiple = checkbox works with overriding name attribute.
diff --git a/lib/Cake/tests/Case/View/Helper/JsHelperTest.php b/lib/Cake/tests/Case/View/Helper/JsHelperTest.php
index 69d946054..7aa1bbaff 100644
--- a/lib/Cake/tests/Case/View/Helper/JsHelperTest.php
+++ b/lib/Cake/tests/Case/View/Helper/JsHelperTest.php
@@ -25,6 +25,12 @@ App::uses('FormHelper', 'View/Helper');
App::uses('View', 'View');
App::uses('ClassRegistry', 'Utility');
+class JsEncodingObject {
+ protected $_title = 'Old thing';
+
+ private $__noshow = 'Never ever';
+}
+
class OptionEngineHelper extends JsBaseEngineHelper {
protected $_optionMap = array(
'request' => array(
@@ -797,13 +803,18 @@ class JsBaseEngineTest extends CakeTestCase {
* @return void
*/
function testObject() {
- $this->JsEngine->useNative = false;
$object = array('title' => 'New thing', 'indexes' => array(5, 6, 7, 8));
$result = $this->JsEngine->object($object);
$expected = '{"title":"New thing","indexes":[5,6,7,8]}';
$this->assertEqual($result, $expected);
+ $object = new JsEncodingObject();
+ $object->title = 'New thing';
+ $object->indexes = array(5,6,7,8);
+ $result = $this->JsEngine->object($object);
+ $this->assertEqual($result, $expected);
+
$result = $this->JsEngine->object(array('default' => 0));
$expected = '{"default":0}';
$this->assertEqual($result, $expected);
@@ -842,70 +853,6 @@ class JsBaseEngineTest extends CakeTestCase {
$this->assertNoPattern('/.POSTFIX./', $result);
}
-/**
- * test compatibility of JsBaseEngineHelper::object() vs. json_encode()
- *
- * @return void
- */
- function testObjectAgainstJsonEncode() {
- $skip = $this->skipIf(!function_exists('json_encode'), 'json_encode() not found, comparison tests skipped. %s');
- if ($skip) {
- return;
- }
- $this->JsEngine->useNative = false;
- $data = array();
- $data['mystring'] = "simple string";
- $this->assertEqual(json_encode($data), $this->JsEngine->object($data));
-
- $data['mystring'] = "strïng with spécial chârs";
- $this->assertEqual(json_encode($data), $this->JsEngine->object($data));
-
- $data['mystring'] = "a two lines\nstring";
- $this->assertEqual(json_encode($data), $this->JsEngine->object($data));
-
- $data['mystring'] = "a \t tabbed \t string";
- $this->assertEqual(json_encode($data), $this->JsEngine->object($data));
-
- $data['mystring'] = "a \"double-quoted\" string";
- $this->assertEqual(json_encode($data), $this->JsEngine->object($data));
-
- $data['mystring'] = 'a \\"double-quoted\\" string';
- $this->assertEqual(json_encode($data), $this->JsEngine->object($data));
-
- unset($data['mystring']);
- $data[3] = array(1, 2, 3);
- $this->assertEqual(json_encode($data), $this->JsEngine->object($data));
-
- unset($data[3]);
- $data = array('mystring' => null, 'bool' => false, 'array' => array(1, 44, 66));
- $this->assertEqual(json_encode($data), $this->JsEngine->object($data));
- }
-
-/**
- * test that JSON made with JsBaseEngineHelper::object() against json_decode()
- *
- * @return void
- */
- function testObjectAgainstJsonDecode() {
- $skip = $this->skipIf(!function_exists('json_encode'), 'json_encode() not found, comparison tests skipped. %s');
- if ($skip) {
- return;
- }
- $this->JsEngine->useNative = false;
-
- $data = array("simple string");
- $result = $this->JsEngine->object($data);
- $this->assertEqual(json_decode($result), $data);
-
- $data = array('my "string"');
- $result = $this->JsEngine->object($data);
- $this->assertEqual(json_decode($result), $data);
-
- $data = array('my \\"string\\"');
- $result = $this->JsEngine->object($data);
- $this->assertEqual(json_decode($result), $data);
- }
-
/**
* test Mapping of options.
*
diff --git a/lib/Cake/tests/Case/View/Helper/TextHelperTest.php b/lib/Cake/tests/Case/View/Helper/TextHelperTest.php
index 7b64a2de2..f946945e6 100644
--- a/lib/Cake/tests/Case/View/Helper/TextHelperTest.php
+++ b/lib/Cake/tests/Case/View/Helper/TextHelperTest.php
@@ -314,6 +314,17 @@ class TextHelperTest extends CakeTestCase {
$this->assertPattern('#^' . $expected . '$#', $result);
}
+/**
+ * test invalid email addresses.
+ *
+ * @return void
+ */
+ function testAutoLinkEmailInvalid() {
+ $result = $this->Text->autoLinkEmails('this is a myaddress@gmx-de test');
+ $expected = 'this is a myaddress@gmx-de test';
+ $this->assertEqual($expected, $result);
+ }
+
/**
* testHighlightCaseInsensitivity method
*
diff --git a/lib/Cake/tests/Case/View/MediaViewTest.php b/lib/Cake/tests/Case/View/MediaViewTest.php
index 242ec16ea..d0f4be960 100644
--- a/lib/Cake/tests/Case/View/MediaViewTest.php
+++ b/lib/Cake/tests/Case/View/MediaViewTest.php
@@ -111,12 +111,14 @@ class MediaViewTest extends CakeTestCase {
}
/**
- * testRenderWithUnknownFileType method
+ * testRenderWithUnknownFileTypeGeneric method
*
* @access public
* @return void
*/
- function testRenderWithUnknownFileType() {
+ function testRenderWithUnknownFileTypeGeneric() {
+ $currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
+ $_SERVER['HTTP_USER_AGENT'] = 'Some generic browser';
$this->MediaView->viewVars = array(
'path' => LIBS . 'tests' . DS . 'test_app' . DS . 'config' . DS,
'id' => 'no_section.ini',
@@ -163,6 +165,139 @@ class MediaViewTest extends CakeTestCase {
$output = ob_get_clean();
$this->assertEqual("some_key = some_value\nbool_key = 1\n", $output);
$this->assertTrue($result !== false);
+ if ($currentUserAgent !== null) {
+ $_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
+ }
+ }
+
+/**
+ * testRenderWithUnknownFileTypeOpera method
+ *
+ * @access public
+ * @return void
+ */
+ function testRenderWithUnknownFileTypeOpera() {
+ $currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
+ $_SERVER['HTTP_USER_AGENT'] = 'Opera/9.80 (Windows NT 6.0; U; en) Presto/2.8.99 Version/11.10';
+ $this->MediaView->viewVars = array(
+ 'path' => LIBS . 'tests' . DS . 'test_app' . DS . 'config' . DS,
+ 'id' => 'no_section.ini',
+ 'extension' => 'ini',
+ );
+ $this->MediaView->expects($this->exactly(2))
+ ->method('_isActive')
+ ->will($this->returnValue(true));
+
+ $this->MediaView->response->expects($this->at(0))
+ ->method('type')
+ ->with('ini')
+ ->will($this->returnValue(false));
+
+ $this->MediaView->response->expects($this->at(1))
+ ->method('header')
+ ->with(array(
+ 'Date' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
+ 'Expires' => '0',
+ 'Cache-Control' => 'private, must-revalidate, post-check=0, pre-check=0',
+ 'Pragma' => 'no-cache'
+ ));
+
+ $this->MediaView->response->expects($this->at(2))
+ ->method('type')
+ ->with('application/octetstream')
+ ->will($this->returnValue(false));
+
+ $this->MediaView->response->expects($this->once())
+ ->method('download')
+ ->with('no_section.ini');
+
+ $this->MediaView->response->expects($this->at(4))
+ ->method('header')
+ ->with(array(
+ 'Accept-Ranges' => 'bytes'
+ ));
+
+ $this->MediaView->response->expects($this->at(5))
+ ->method('header')
+ ->with('Content-Length', 35);
+
+ $this->MediaView->response->expects($this->once())->method('send');
+ $this->MediaView->expects($this->once())->method('_clearBuffer');
+ $this->MediaView->expects($this->once())->method('_flushBuffer');
+
+ ob_start();
+ $result = $this->MediaView->render();
+ $output = ob_get_clean();
+ $this->assertEqual("some_key = some_value\nbool_key = 1\n", $output);
+ $this->assertTrue($result !== false);
+ if ($currentUserAgent !== null) {
+ $_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
+ }
+ }
+
+/**
+ * testRenderWithUnknownFileTypeIE method
+ *
+ * @access public
+ * @return void
+ */
+ function testRenderWithUnknownFileTypeIE() {
+ $currentUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
+ $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)';
+ $this->MediaView->viewVars = array(
+ 'path' => LIBS . 'tests' . DS . 'test_app' . DS . 'config' . DS,
+ 'id' => 'no_section.ini',
+ 'extension' => 'ini',
+ );
+ $this->MediaView->expects($this->exactly(2))
+ ->method('_isActive')
+ ->will($this->returnValue(true));
+
+ $this->MediaView->response->expects($this->at(0))
+ ->method('type')
+ ->with('ini')
+ ->will($this->returnValue(false));
+
+ $this->MediaView->response->expects($this->at(1))
+ ->method('header')
+ ->with(array(
+ 'Date' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
+ 'Expires' => '0',
+ 'Cache-Control' => 'private, must-revalidate, post-check=0, pre-check=0',
+ 'Pragma' => 'no-cache'
+ ));
+
+ $this->MediaView->response->expects($this->at(2))
+ ->method('type')
+ ->with('application/force-download')
+ ->will($this->returnValue(false));
+
+ $this->MediaView->response->expects($this->once())
+ ->method('download')
+ ->with('no_section.ini');
+
+ $this->MediaView->response->expects($this->at(4))
+ ->method('header')
+ ->with(array(
+ 'Accept-Ranges' => 'bytes'
+ ));
+
+ $this->MediaView->response->expects($this->at(5))
+ ->method('header')
+ ->with('Content-Length', 35);
+
+ $this->MediaView->response->expects($this->once())->method('send');
+ $this->MediaView->expects($this->once())->method('_clearBuffer');
+ $this->MediaView->expects($this->once())->method('_flushBuffer');
+
+ ob_start();
+ $result = $this->MediaView->render();
+ $output = ob_get_clean();
+ $this->assertEqual("some_key = some_value\nbool_key = 1\n", $output);
+ $this->assertTrue($result !== false);
+ if ($currentUserAgent !== null) {
+ $_SERVER['HTTP_USER_AGENT'] = $currentUserAgent;
+ }
}
/**
diff --git a/lib/Cake/tests/test_app/Controller/tests_apps_controller.php b/lib/Cake/tests/test_app/Controller/TestsAppsController.php
similarity index 100%
rename from lib/Cake/tests/test_app/Controller/tests_apps_controller.php
rename to lib/Cake/tests/test_app/Controller/TestsAppsController.php
diff --git a/lib/Cake/tests/test_app/Controller/tests_apps_posts_controller.php b/lib/Cake/tests/test_app/Controller/TestsAppsPostsController.php
similarity index 93%
rename from lib/Cake/tests/test_app/Controller/tests_apps_posts_controller.php
rename to lib/Cake/tests/test_app/Controller/TestsAppsPostsController.php
index af28f42c4..f5b6dc89e 100644
--- a/lib/Cake/tests/test_app/Controller/tests_apps_posts_controller.php
+++ b/lib/Cake/tests/test_app/Controller/TestsAppsPostsController.php
@@ -40,7 +40,7 @@ class TestsAppsPostsController extends AppController {
*
*/
function url_var() {
- $this->set('params', $this->params);
+ $this->set('params', $this->request->params);
$this->render('index');
}
@@ -49,7 +49,7 @@ class TestsAppsPostsController extends AppController {
*
*/
function post_var() {
- $this->set('data', $this->data);
+ $this->set('data', $this->request->data);
$this->render('index');
}
diff --git a/lib/Cake/tests/test_app/Lib/library.php b/lib/Cake/tests/test_app/Lib/Library.php
similarity index 100%
rename from lib/Cake/tests/test_app/Lib/library.php
rename to lib/Cake/tests/test_app/Lib/Library.php
diff --git a/lib/Cake/tests/test_app/Model/Behavior/persister_one_behavior.php b/lib/Cake/tests/test_app/Model/Behavior/PersisterOneBehaviorBehavior.php
similarity index 100%
rename from lib/Cake/tests/test_app/Model/Behavior/persister_one_behavior.php
rename to lib/Cake/tests/test_app/Model/Behavior/PersisterOneBehaviorBehavior.php
diff --git a/lib/Cake/tests/test_app/Model/Behavior/persister_two_behavior.php b/lib/Cake/tests/test_app/Model/Behavior/PersisterTwoBehaviorBehavior.php
similarity index 100%
rename from lib/Cake/tests/test_app/Model/Behavior/persister_two_behavior.php
rename to lib/Cake/tests/test_app/Model/Behavior/PersisterTwoBehaviorBehavior.php
diff --git a/lib/Cake/tests/test_app/Model/comment.php b/lib/Cake/tests/test_app/Model/Comment.php
similarity index 100%
rename from lib/Cake/tests/test_app/Model/comment.php
rename to lib/Cake/tests/test_app/Model/Comment.php
diff --git a/lib/Cake/tests/test_app/Model/Datasource/test2_other_source.php b/lib/Cake/tests/test_app/Model/Datasource/Test2OtherSource.php
similarity index 100%
rename from lib/Cake/tests/test_app/Model/Datasource/test2_other_source.php
rename to lib/Cake/tests/test_app/Model/Datasource/Test2OtherSource.php
diff --git a/lib/Cake/tests/test_app/Model/Datasource/test2_source.php b/lib/Cake/tests/test_app/Model/Datasource/Test2Source.php
similarity index 100%
rename from lib/Cake/tests/test_app/Model/Datasource/test2_source.php
rename to lib/Cake/tests/test_app/Model/Datasource/Test2Source.php
diff --git a/lib/Cake/tests/test_app/Model/persister_one.php b/lib/Cake/tests/test_app/Model/PersisterOne.php
similarity index 100%
rename from lib/Cake/tests/test_app/Model/persister_one.php
rename to lib/Cake/tests/test_app/Model/PersisterOne.php
diff --git a/lib/Cake/tests/test_app/Model/persister_two.php b/lib/Cake/tests/test_app/Model/PersisterTwo.php
similarity index 100%
rename from lib/Cake/tests/test_app/Model/persister_two.php
rename to lib/Cake/tests/test_app/Model/PersisterTwo.php
diff --git a/lib/Cake/tests/test_app/Model/post.php b/lib/Cake/tests/test_app/Model/Post.php
similarity index 100%
rename from lib/Cake/tests/test_app/Model/post.php
rename to lib/Cake/tests/test_app/Model/Post.php
diff --git a/lib/Cake/tests/test_app/View/Helper/banana.php b/lib/Cake/tests/test_app/View/Helper/BananaHelper.php
similarity index 100%
rename from lib/Cake/tests/test_app/View/Helper/banana.php
rename to lib/Cake/tests/test_app/View/Helper/BananaHelper.php
diff --git a/lib/Cake/tests/test_app/View/layouts/flash.ctp b/lib/Cake/tests/test_app/View/layouts/flash.ctp
index bed0624c4..1e9508609 100644
--- a/lib/Cake/tests/test_app/View/layouts/flash.ctp
+++ b/lib/Cake/tests/test_app/View/layouts/flash.ctp
@@ -22,7 +22,7 @@
Html->charset(); ?>
-
+