Merge branch 'master' into 2.5

Conflicts:
	CONTRIBUTING.md
	lib/Cake/Model/Model.php
	lib/Cake/VERSION.txt
This commit is contained in:
ADmad 2013-10-30 02:34:09 +05:30
commit d9ca148499
73 changed files with 688 additions and 539 deletions

View file

@ -63,11 +63,11 @@ Check the [cakephp-codesniffer](https://github.com/cakephp/cakephp-codesniffer)
repository to setup the CakePHP standard. The README contains installation info repository to setup the CakePHP standard. The README contains installation info
for the sniff and phpcs. for the sniff and phpcs.
# Additional Resources # Additional Resources
* [CakePHP coding standards](http://book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html) * [CakePHP coding standards](http://book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html)
* [Existing issues](https://github.com/cakephp/cakephp/issues) * [Existing issues](https://github.com/cakephp/cakephp/issues)
* [Development Roadmaps](https://github.com/cakephp/cakephp/wiki#roadmaps)
* [General GitHub documentation](https://help.github.com/) * [General GitHub documentation](https://help.github.com/)
* [GitHub pull request documentation](https://help.github.com/send-pull-requests/) * [GitHub pull request documentation](https://help.github.com/send-pull-requests/)
* #cakephp IRC channel on freenode.org * #cakephp IRC channel on freenode.org

View file

@ -36,6 +36,8 @@ Get Support!
[GitHub Issues](https://github.com/cakephp/cakephp/issues) - Got issues? Please tell us! [GitHub Issues](https://github.com/cakephp/cakephp/issues) - Got issues? Please tell us!
[Roadmaps](https://github.com/cakephp/cakephp/wiki#roadmaps) - Want to contribute? Get involved!
[![Bake Status](https://secure.travis-ci.org/cakephp/cakephp.png?branch=master)](http://travis-ci.org/cakephp/cakephp) [![Bake Status](https://secure.travis-ci.org/cakephp/cakephp.png?branch=master)](http://travis-ci.org/cakephp/cakephp)
![Cake Power](https://raw.github.com/cakephp/cakephp/master/lib/Cake/Console/Templates/skel/webroot/img/cake.power.gif) ![Cake Power](https://raw.github.com/cakephp/cakephp/master/lib/Cake/Console/Templates/skel/webroot/img/cake.power.gif)

View file

@ -1,9 +1,5 @@
<?php <?php
/** /**
* This is core configuration file.
*
* Use it to configure core behaviour of CakePHP.
*
* PHP 5 * PHP 5
* *
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org) * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
@ -18,8 +14,11 @@
* @package app.Config * @package app.Config
* @since CakePHP(tm) v 0.2.9 * @since CakePHP(tm) v 0.2.9
* @license http://www.opensource.org/licenses/mit-license.php MIT License * @license http://www.opensource.org/licenses/mit-license.php MIT License
* */
/**
* Database configuration class. * Database configuration class.
*
* You can specify multiple configurations for production, development and testing. * You can specify multiple configurations for production, development and testing.
* *
* datasource => The name of a supported datasource; valid options are as follows: * datasource => The name of a supported datasource; valid options are as follows:
@ -43,7 +42,8 @@
* on a per-table basis with the Model::$tablePrefix property. * on a per-table basis with the Model::$tablePrefix property.
* *
* schema => * schema =>
* For Postgres/Sqlserver specifies which schema you would like to use the tables in. Postgres defaults to 'public'. For Sqlserver, it defaults to empty and use * For Postgres/Sqlserver specifies which schema you would like to use the tables in.
* Postgres defaults to 'public'. For Sqlserver, it defaults to empty and use
* the connected user's default schema (typically 'dbo'). * the connected user's default schema (typically 'dbo').
* *
* encoding => * encoding =>

View file

@ -1,9 +1,5 @@
<?php <?php
/** /**
* This is email configuration file.
*
* Use it to configure email transports of CakePHP.
*
* PHP 5 * PHP 5
* *
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org) * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
@ -18,6 +14,12 @@
* @package app.Config * @package app.Config
* @since CakePHP(tm) v 2.0.0 * @since CakePHP(tm) v 2.0.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License * @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
/**
* This is email configuration file.
*
* Use it to configure email transports of CakePHP.
* *
* Email configuration class. * Email configuration class.
* You can specify multiple configurations for production, development and testing. * You can specify multiple configurations for production, development and testing.

View file

@ -18,6 +18,7 @@
* @since CakePHP(tm) v 2.0 * @since CakePHP(tm) v 2.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License * @license http://www.opensource.org/licenses/mit-license.php MIT License
*/ */
$ds = DIRECTORY_SEPARATOR; $ds = DIRECTORY_SEPARATOR;
$dispatcher = 'Cake' . $ds . 'Console' . $ds . 'ShellDispatcher.php'; $dispatcher = 'Cake' . $ds . 'Console' . $ds . 'ShellDispatcher.php';
@ -29,7 +30,7 @@ if (function_exists('ini_set')) {
ini_set('include_path', $root . $ds . 'lib' . PATH_SEPARATOR . ini_get('include_path')); ini_set('include_path', $root . $ds . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
} }
if (!include ($dispatcher)) { if (!include $dispatcher) {
trigger_error('Could not locate CakePHP core files.', E_USER_ERROR); trigger_error('Could not locate CakePHP core files.', E_USER_ERROR);
} }
unset($paths, $path, $dispatcher, $root, $ds); unset($paths, $path, $dispatcher, $root, $ds);

View file

@ -144,7 +144,7 @@ if (isset($filePresent)):
echo '<span class="notice">'; echo '<span class="notice">';
echo __d('cake_dev', 'DebugKit is not installed. It will help you inspect and debug different aspects of your application.'); echo __d('cake_dev', 'DebugKit is not installed. It will help you inspect and debug different aspects of your application.');
echo '<br/>'; echo '<br/>';
echo __d('cake_dev', 'You can install it from %s', $this->Html->link('github', 'https://github.com/cakephp/debug_kit')); echo __d('cake_dev', 'You can install it from %s', $this->Html->link('GitHub', 'https://github.com/cakephp/debug_kit'));
echo '</span>'; echo '</span>';
endif; endif;
?> ?>
@ -194,7 +194,7 @@ You can also add some CSS styles for your pages at: %s.',
</ul> </ul>
</p> </p>
<h3><?php echo __d('cake_dev', 'More about Cake'); ?></h3> <h3><?php echo __d('cake_dev', 'More about CakePHP'); ?></h3>
<p> <p>
<?php echo __d('cake_dev', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?> <?php echo __d('cake_dev', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?>
</p> </p>
@ -203,24 +203,32 @@ You can also add some CSS styles for your pages at: %s.',
</p> </p>
<ul> <ul>
<li><a href="http://cakefoundation.org/"><?php echo __d('cake_dev', 'Cake Software Foundation'); ?> </a> <li><a href="http://cakephp.org">CakePHP</a>
<ul><li><?php echo __d('cake_dev', 'Promoting development related to CakePHP'); ?></li></ul></li>
<li><a href="http://www.cakephp.org">CakePHP</a>
<ul><li><?php echo __d('cake_dev', 'The Rapid Development Framework'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'The Rapid Development Framework'); ?></li></ul></li>
<li><a href="http://book.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Documentation'); ?> </a> <li><a href="http://book.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Documentation'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Your Rapid Development Cookbook'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'Your Rapid Development Cookbook'); ?></li></ul></li>
<li><a href="http://api.cakephp.org"><?php echo __d('cake_dev', 'CakePHP API'); ?> </a> <li><a href="http://api.cakephp.org"><?php echo __d('cake_dev', 'CakePHP API'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Quick Reference'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'Quick API Reference'); ?></li></ul></li>
<li><a href="http://bakery.cakephp.org"><?php echo __d('cake_dev', 'The Bakery'); ?> </a> <li><a href="http://bakery.cakephp.org"><?php echo __d('cake_dev', 'The Bakery'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Everything CakePHP'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'Everything CakePHP'); ?></li></ul></li>
<li><a href="http://plugins.cakephp.org"><?php echo __d('cake_dev', 'CakePHP plugins repo'); ?> </a> <li><a href="http://plugins.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Plugins'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'A comprehensive list of all CakePHP plugins created by the community'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'A comprehensive list of all CakePHP plugins created by the community'); ?></li></ul></li>
<li><a href="http://community.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Community Center'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Everything related to the CakePHP community in one place'); ?></li></ul></li>
<li><a href="https://groups.google.com/group/cake-php"><?php echo __d('cake_dev', 'CakePHP Google Group'); ?> </a> <li><a href="https://groups.google.com/group/cake-php"><?php echo __d('cake_dev', 'CakePHP Google Group'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Community mailing list'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'Community mailing list'); ?></li></ul></li>
<li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a> <li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a>
<ul><li><?php echo __d('cake_dev', 'Live chat about CakePHP'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'Live chat about CakePHP'); ?></li></ul></li>
<li><a href="https://github.com/cakephp/"><?php echo __d('cake_dev', 'CakePHP Code'); ?> </a> <li><a href="https://github.com/cakephp/"><?php echo __d('cake_dev', 'CakePHP Code'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'For the Development of CakePHP Git repository, Downloads'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'Find the CakePHP code on GitHub and contribute to the framework'); ?></li></ul></li>
<li><a href="https://cakephp.lighthouseapp.com/"><?php echo __d('cake_dev', 'CakePHP Lighthouse'); ?> </a> <li><a href="https://github.com/cakephp/cakephp/issues"><?php echo __d('cake_dev', 'CakePHP Issues'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'CakePHP Tickets, Wiki pages, Roadmap'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'CakePHP Issues'); ?></li></ul></li>
<li><a href="https://github.com/cakephp/cakephp/wiki#roadmaps"><?php echo __d('cake_dev', 'CakePHP Roadmaps'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'CakePHP Roadmaps'); ?></li></ul></li>
<li><a href="http://training.cakephp.org"><?php echo __d('cake_dev', 'Training'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Join a live session and get skilled with the framework'); ?></li></ul></li>
<li><a href="http://cakefest.org"><?php echo __d('cake_dev', 'CakeFest'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Don\'t miss our annual CakePHP conference'); ?></li></ul></li>
<li><a href="http://cakefoundation.org"><?php echo __d('cake_dev', 'Cake Software Foundation'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Promoting development related to CakePHP'); ?></li></ul></li>
</ul> </ul>

View file

@ -78,7 +78,7 @@ if (!defined('WWW_ROOT')) {
} }
// for built-in server // for built-in server
if (php_sapi_name() == 'cli-server') { if (php_sapi_name() === 'cli-server') {
if ($_SERVER['REQUEST_URI'] !== '/' && file_exists(WWW_ROOT . $_SERVER['PHP_SELF'])) { if ($_SERVER['REQUEST_URI'] !== '/' && file_exists(WWW_ROOT . $_SERVER['PHP_SELF'])) {
return false; return false;
} }
@ -89,11 +89,11 @@ if (!defined('CAKE_CORE_INCLUDE_PATH')) {
if (function_exists('ini_set')) { if (function_exists('ini_set')) {
ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path')); ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
} }
if (!include ('Cake' . DS . 'bootstrap.php')) { if (!include 'Cake' . DS . 'bootstrap.php') {
$failed = true; $failed = true;
} }
} else { } else {
if (!include (CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php')) { if (!include CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php') {
$failed = true; $failed = true;
} }
} }

View file

@ -79,11 +79,11 @@ if (!defined('CAKE_CORE_INCLUDE_PATH')) {
if (function_exists('ini_set')) { if (function_exists('ini_set')) {
ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path')); ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
} }
if (!include ('Cake' . DS . 'bootstrap.php')) { if (!include 'Cake' . DS . 'bootstrap.php') {
$failed = true; $failed = true;
} }
} else { } else {
if (!include (CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php')) { if (!include CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php') {
$failed = true; $failed = true;
} }
} }

View file

@ -145,9 +145,9 @@
<dirroles key="Cake/Console/Templates/default">php</dirroles> <dirroles key="Cake/Console/Templates/default">php</dirroles>
<dirroles key="Cake/View">php</dirroles> <dirroles key="Cake/View">php</dirroles>
<release> <release>
<install as="cake" name="bin/cake" />
<install as="cake.php" name="bin/cake.php" />
<install as="cake.bat" name="bin/cake.bat" /> <install as="cake.bat" name="bin/cake.bat" />
<install as="cake.php" name="bin/cake.php" />
<install as="cake" name="bin/cake" />
</release> </release>
<exceptions key="Cake/VERSION.txt">php</exceptions> <exceptions key="Cake/VERSION.txt">php</exceptions>
<exceptions key="Cake/LICENSE.txt">php</exceptions> <exceptions key="Cake/LICENSE.txt">php</exceptions>

View file

@ -533,7 +533,7 @@ class Cache {
* @throws CacheException * @throws CacheException
*/ */
public static function groupConfigs($group = null) { public static function groupConfigs($group = null) {
if ($group == null) { if ($group === null) {
return self::$_groups; return self::$_groups;
} }
if (isset(self::$_groups[$group])) { if (isset(self::$_groups[$group])) {

View file

@ -44,7 +44,7 @@ class FileEngine extends CacheEngine {
* *
* - path = absolute path to cache directory, default => CACHE * - path = absolute path to cache directory, default => CACHE
* - prefix = string prefix for filename, default => cake_ * - prefix = string prefix for filename, default => cake_
* - lock = enable file locking on write, default => false * - lock = enable file locking on write, default => true
* - serialize = serialize the data, default => true * - serialize = serialize the data, default => true
* *
* @var array * @var array

View file

@ -91,7 +91,7 @@ class AclShell extends AppShell {
$this->args = null; $this->args = null;
return $this->DbConfig->execute(); return $this->DbConfig->execute();
} }
require_once (APP . 'Config' . DS . 'database.php'); require_once APP . 'Config' . DS . 'database.php';
if (!in_array($this->command, array('initdb'))) { if (!in_array($this->command, array('initdb'))) {
$collection = new ComponentCollection(); $collection = new ComponentCollection();

View file

@ -67,12 +67,12 @@ class SchemaShell extends AppShell {
$name = $this->params['name'] = $splitName; $name = $this->params['name'] = $splitName;
} }
if ($name && empty($this->params['file'])) { $defaultFile = 'schema.php';
$this->params['file'] = Inflector::underscore($name);
}
if (empty($this->params['file'])) { if (empty($this->params['file'])) {
$this->params['file'] = 'schema.php'; $this->params['file'] = $defaultFile;
}
if ($name && $this->params['file'] === $defaultFile) {
$this->params['file'] = Inflector::underscore($name);
} }
if (strpos($this->params['file'], '.php') === false) { if (strpos($this->params['file'], '.php') === false) {
$this->params['file'] .= '.php'; $this->params['file'] .= '.php';

View file

@ -438,6 +438,8 @@ class ModelTask extends BakeTask {
$guess = $methods['notEmpty']; $guess = $methods['notEmpty'];
} elseif ($metaData['type'] === 'integer') { } elseif ($metaData['type'] === 'integer') {
$guess = $methods['numeric']; $guess = $methods['numeric'];
} elseif ($metaData['type'] === 'float') {
$guess = $methods['numeric'];
} elseif ($metaData['type'] === 'boolean') { } elseif ($metaData['type'] === 'boolean') {
$guess = $methods['boolean']; $guess = $methods['boolean'];
} elseif ($metaData['type'] === 'date') { } elseif ($metaData['type'] === 'date') {

View file

@ -45,7 +45,7 @@ Cache::config('default', array('engine' => 'File'));
*/ */
/** /**
* Custom Inflector rules, can be set to correctly pluralize or singularize table, model, controller names or whatever other * Custom Inflector rules can be set to correctly pluralize or singularize table, model, controller names or whatever other
* string is passed to the inflection functions * string is passed to the inflection functions
* *
* Inflector::rules('singular', array('rules' => array(), 'irregular' => array(), 'uninflected' => array())); * Inflector::rules('singular', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
@ -55,7 +55,7 @@ Cache::config('default', array('engine' => 'File'));
/** /**
* Plugins need to be loaded manually, you can either load them one by one or all of them in a single call * Plugins need to be loaded manually, you can either load them one by one or all of them in a single call
* Uncomment one of the lines below, as you need. make sure you read the documentation on CakePlugin to use more * Uncomment one of the lines below, as you need. Make sure you read the documentation on CakePlugin to use more
* advanced ways of loading plugins * advanced ways of loading plugins
* *
* CakePlugin::loadAll(); // Loads all plugins at once * CakePlugin::loadAll(); // Loads all plugins at once
@ -64,7 +64,7 @@ Cache::config('default', array('engine' => 'File'));
*/ */
/** /**
* You can attach event listeners to the request lifecycle as Dispatcher Filter . By Default CakePHP bundles two filters: * You can attach event listeners to the request lifecycle as Dispatcher Filter . By default CakePHP bundles two filters:
* *
* - AssetDispatcher filter will serve your asset files (css, images, js, etc) from your themes and plugins * - AssetDispatcher filter will serve your asset files (css, images, js, etc) from your themes and plugins
* - CacheDispatcher filter will read the Cache.check configure variable and try to serve cached content generated from controllers * - CacheDispatcher filter will read the Cache.check configure variable and try to serve cached content generated from controllers

View file

@ -1,9 +1,5 @@
<?php <?php
/** /**
* This is core configuration file.
*
* Use it to configure core behaviour of Cake.
*
* PHP 5 * PHP 5
* *
* @link http://cakephp.org CakePHP(tm) Project * @link http://cakephp.org CakePHP(tm) Project
@ -45,6 +41,12 @@
* *
* unix_socket => * unix_socket =>
* For MySQL to connect via socket specify the `unix_socket` parameter instead of `host` and `port` * For MySQL to connect via socket specify the `unix_socket` parameter instead of `host` and `port`
* settings =>
* Array of key/value pairs, on connection it executes SET statements for each pair
* For MySQL : http://dev.mysql.com/doc/refman/5.6/en/set-statement.html
* For Postgres : http://www.postgresql.org/docs/9.2/static/sql-set.html
* For Sql Server : http://msdn.microsoft.com/en-us/library/ms190356.aspx
*/ */
class DATABASE_CONFIG { class DATABASE_CONFIG {

View file

@ -29,7 +29,7 @@ if (function_exists('ini_set')) {
ini_set('include_path', $root . PATH_SEPARATOR . __CAKE_PATH__ . PATH_SEPARATOR . ini_get('include_path')); ini_set('include_path', $root . PATH_SEPARATOR . __CAKE_PATH__ . PATH_SEPARATOR . ini_get('include_path'));
} }
if (!include ($dispatcher)) { if (!include $dispatcher) {
trigger_error('Could not locate CakePHP core files.', E_USER_ERROR); trigger_error('Could not locate CakePHP core files.', E_USER_ERROR);
} }
unset($paths, $path, $dispatcher, $root, $ds); unset($paths, $path, $dispatcher, $root, $ds);

View file

@ -14,9 +14,9 @@
<?php echo $this->Html->charset(); ?> <?php echo $this->Html->charset(); ?>
<title><?php echo $page_title; ?></title> <title><?php echo $page_title; ?></title>
<?php if (Configure::read('debug') == 0) { ?> <?php if (Configure::read('debug') == 0): ?>
<meta http-equiv="Refresh" content="<?php echo $pause; ?>;url=<?php echo $url; ?>"/> <meta http-equiv="Refresh" content="<?php echo $pause; ?>;url=<?php echo $url; ?>"/>
<?php } ?> <?php endif ?>
<style><!-- <style><!--
P { text-align:center; font:bold 1.1em sans-serif } P { text-align:center; font:bold 1.1em sans-serif }
A { color:#444; text-decoration:none } A { color:#444; text-decoration:none }

View file

@ -1,14 +1,13 @@
<?php <?php
if (!isset($channel)) { if (!isset($channel)):
$channel = array(); $channel = array();
} endif;
if (!isset($channel['title'])) { if (!isset($channel['title'])):
$channel['title'] = $title_for_layout; $channel['title'] = $title_for_layout;
} endif;
echo $this->Rss->document( echo $this->Rss->document(
$this->Rss->channel( $this->Rss->channel(
array(), $channel, $this->fetch('content') array(), $channel, $this->fetch('content')
) )
); );
?>

View file

@ -144,7 +144,7 @@ if (isset($filePresent)):
echo '<span class="notice">'; echo '<span class="notice">';
echo __d('cake_dev', 'DebugKit is not installed. It will help you inspect and debug different aspects of your application.'); echo __d('cake_dev', 'DebugKit is not installed. It will help you inspect and debug different aspects of your application.');
echo '<br/>'; echo '<br/>';
echo __d('cake_dev', 'You can install it from %s', $this->Html->link('github', 'https://github.com/cakephp/debug_kit')); echo __d('cake_dev', 'You can install it from %s', $this->Html->link('GitHub', 'https://github.com/cakephp/debug_kit'));
echo '</span>'; echo '</span>';
endif; endif;
?> ?>
@ -194,7 +194,7 @@ You can also add some CSS styles for your pages at: %s.',
</ul> </ul>
</p> </p>
<h3><?php echo __d('cake_dev', 'More about Cake'); ?></h3> <h3><?php echo __d('cake_dev', 'More about CakePHP'); ?></h3>
<p> <p>
<?php echo __d('cake_dev', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?> <?php echo __d('cake_dev', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?>
</p> </p>
@ -203,24 +203,32 @@ You can also add some CSS styles for your pages at: %s.',
</p> </p>
<ul> <ul>
<li><a href="http://cakefoundation.org/"><?php echo __d('cake_dev', 'Cake Software Foundation'); ?> </a> <li><a href="http://cakephp.org">CakePHP</a>
<ul><li><?php echo __d('cake_dev', 'Promoting development related to CakePHP'); ?></li></ul></li>
<li><a href="http://www.cakephp.org">CakePHP</a>
<ul><li><?php echo __d('cake_dev', 'The Rapid Development Framework'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'The Rapid Development Framework'); ?></li></ul></li>
<li><a href="http://book.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Documentation'); ?> </a> <li><a href="http://book.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Documentation'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Your Rapid Development Cookbook'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'Your Rapid Development Cookbook'); ?></li></ul></li>
<li><a href="http://api.cakephp.org"><?php echo __d('cake_dev', 'CakePHP API'); ?> </a> <li><a href="http://api.cakephp.org"><?php echo __d('cake_dev', 'CakePHP API'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Quick Reference'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'Quick API Reference'); ?></li></ul></li>
<li><a href="http://bakery.cakephp.org"><?php echo __d('cake_dev', 'The Bakery'); ?> </a> <li><a href="http://bakery.cakephp.org"><?php echo __d('cake_dev', 'The Bakery'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Everything CakePHP'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'Everything CakePHP'); ?></li></ul></li>
<li><a href="http://plugins.cakephp.org"><?php echo __d('cake_dev', 'CakePHP plugins repo'); ?> </a> <li><a href="http://plugins.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Plugins'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'A comprehensive list of all CakePHP plugins created by the community'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'A comprehensive list of all CakePHP plugins created by the community'); ?></li></ul></li>
<li><a href="http://community.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Community Center'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Everything related to the CakePHP community in one place'); ?></li></ul></li>
<li><a href="https://groups.google.com/group/cake-php"><?php echo __d('cake_dev', 'CakePHP Google Group'); ?> </a> <li><a href="https://groups.google.com/group/cake-php"><?php echo __d('cake_dev', 'CakePHP Google Group'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Community mailing list'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'Community mailing list'); ?></li></ul></li>
<li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a> <li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a>
<ul><li><?php echo __d('cake_dev', 'Live chat about CakePHP'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'Live chat about CakePHP'); ?></li></ul></li>
<li><a href="https://github.com/cakephp/"><?php echo __d('cake_dev', 'CakePHP Code'); ?> </a> <li><a href="https://github.com/cakephp/"><?php echo __d('cake_dev', 'CakePHP Code'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'For the Development of CakePHP Git repository, Downloads'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'Find the CakePHP code on GitHub and contribute to the framework'); ?></li></ul></li>
<li><a href="https://cakephp.lighthouseapp.com/"><?php echo __d('cake_dev', 'CakePHP Lighthouse'); ?> </a> <li><a href="https://github.com/cakephp/cakephp/issues"><?php echo __d('cake_dev', 'CakePHP Issues'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'CakePHP Tickets, Wiki pages, Roadmap'); ?></li></ul></li> <ul><li><?php echo __d('cake_dev', 'CakePHP Issues'); ?></li></ul></li>
<li><a href="https://github.com/cakephp/cakephp/wiki#roadmaps"><?php echo __d('cake_dev', 'CakePHP Roadmaps'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'CakePHP Roadmaps'); ?></li></ul></li>
<li><a href="http://training.cakephp.org"><?php echo __d('cake_dev', 'Training'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Join a live session and get skilled with the framework'); ?></li></ul></li>
<li><a href="http://cakefest.org"><?php echo __d('cake_dev', 'CakeFest'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Don\'t miss our annual CakePHP conference'); ?></li></ul></li>
<li><a href="http://cakefoundation.org"><?php echo __d('cake_dev', 'Cake Software Foundation'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Promoting development related to CakePHP'); ?></li></ul></li>
</ul> </ul>

View file

@ -80,11 +80,11 @@ if (!defined('CAKE_CORE_INCLUDE_PATH')) {
if (function_exists('ini_set')) { if (function_exists('ini_set')) {
ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path')); ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
} }
if (!include ('Cake' . DS . 'bootstrap.php')) { if (!include 'Cake' . DS . 'bootstrap.php') {
$failed = true; $failed = true;
} }
} else { } else {
if (!include (CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php')) { if (!include CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php') {
$failed = true; $failed = true;
} }
} }

View file

@ -70,11 +70,11 @@ if (!defined('CAKE_CORE_INCLUDE_PATH')) {
if (function_exists('ini_set')) { if (function_exists('ini_set')) {
ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path')); ini_set('include_path', ROOT . DS . 'lib' . PATH_SEPARATOR . ini_get('include_path'));
} }
if (!include ('Cake' . DS . 'bootstrap.php')) { if (!include 'Cake' . DS . 'bootstrap.php') {
$failed = true; $failed = true;
} }
} else { } else {
if (!include (CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php')) { if (!include CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'bootstrap.php') {
$failed = true; $failed = true;
} }
} }

View file

@ -174,7 +174,7 @@ class AuthComponent extends Component {
protected static $_user = array(); protected static $_user = array();
/** /**
* An URL (defined as a string or array) to the controller action that handles * A URL (defined as a string or array) to the controller action that handles
* logins. Defaults to `/users/login`. * logins. Defaults to `/users/login`.
* *
* @var mixed * @var mixed
@ -220,7 +220,7 @@ class AuthComponent extends Component {
* Controls handling of unauthorized access. * Controls handling of unauthorized access.
* - For default value `true` unauthorized user is redirected to the referrer URL * - For default value `true` unauthorized user is redirected to the referrer URL
* or AuthComponent::$loginRedirect or '/'. * or AuthComponent::$loginRedirect or '/'.
* - If set to a string or array the value is used as an URL to redirect to. * - If set to a string or array the value is used as a URL to redirect to.
* - If set to false a ForbiddenException exception is thrown instead of redirecting. * - If set to false a ForbiddenException exception is thrown instead of redirecting.
* *
* @var mixed * @var mixed
@ -699,7 +699,7 @@ class AuthComponent extends Component {
/** /**
* Get the URL a user should be redirected to upon login. * Get the URL a user should be redirected to upon login.
* *
* Pass an URL in to set the destination a user should be redirected to upon * Pass a URL in to set the destination a user should be redirected to upon
* logging in. * logging in.
* *
* If no parameter is passed, gets the authentication redirect URL. The URL * If no parameter is passed, gets the authentication redirect URL. The URL

View file

@ -232,17 +232,27 @@ class CookieComponent extends Component {
} }
foreach ($key as $name => $value) { foreach ($key as $name => $value) {
if (strpos($name, '.') === false) { $names = array($name);
$this->_values[$this->name][$name] = $value; if (strpos($name, '.') !== false) {
$this->_write("[$name]", $value);
} else {
$names = explode('.', $name, 2); $names = explode('.', $name, 2);
if (!isset($this->_values[$this->name][$names[0]])) {
$this->_values[$this->name][$names[0]] = array();
} }
$this->_values[$this->name][$names[0]] = Hash::insert($this->_values[$this->name][$names[0]], $names[1], $value); $firstName = $names[0];
$this->_write('[' . implode('][', $names) . ']', $value); $isMultiValue = (is_array($value) || count($names) > 1);
if (!isset($this->_values[$this->name][$firstName]) && $isMultiValue) {
$this->_values[$this->name][$firstName] = array();
} }
if (count($names) > 1) {
$this->_values[$this->name][$firstName] = Hash::insert(
$this->_values[$this->name][$firstName],
$names[1],
$value
);
} else {
$this->_values[$this->name][$firstName] = $value;
}
$this->_write('[' . $firstName . ']', $this->_values[$this->name][$firstName]);
} }
$this->_encrypted = true; $this->_encrypted = true;
} }
@ -299,11 +309,17 @@ class CookieComponent extends Component {
* Delete a cookie value * Delete a cookie value
* *
* Optional [Name.], required key * Optional [Name.], required key
* $this->Cookie->read('Name.key); * $this->Cookie->delete('Name.key);
* *
* You must use this method before any output is sent to the browser. * You must use this method before any output is sent to the browser.
* Failure to do so will result in header already sent errors. * Failure to do so will result in header already sent errors.
* *
* This method will delete both the top level and 2nd level cookies set.
* For example assuming that $name = App, deleting `User` will delete
* both `App[User]` and any other cookie values like `App[User][email]`
* This is done to clean up cookie storage from before 2.4.3, where cookies
* were stored inconsistently.
*
* @param string $key Key of the value to be deleted * @param string $key Key of the value to be deleted
* @return void * @return void
* @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::delete * @link http://book.cakephp.org/2.0/en/core-libraries/components/cookie.html#CookieComponent::delete

View file

@ -551,7 +551,7 @@ class CakeSchema extends Object {
continue; continue;
} }
$correspondingValue = $array2[$key]; $correspondingValue = $array2[$key];
if (is_null($value) !== is_null($correspondingValue)) { if (($value === null) !== ($correspondingValue === null)) {
$difference[$key] = $value; $difference[$key] = $value;
continue; continue;
} }

View file

@ -605,7 +605,7 @@ class Sqlserver extends DboSource {
* @param Model $model * @param Model $model
* @param array $queryData * @param array $queryData
* @param integer $recursive * @param integer $recursive
* @return array Array of resultset rows, or false if no rows matched * @return array|false Array of resultset rows, or false if no rows matched
*/ */
public function read(Model $model, $queryData = array(), $recursive = null) { public function read(Model $model, $queryData = array(), $recursive = null) {
$results = parent::read($model, $queryData, $recursive); $results = parent::read($model, $queryData, $recursive);

View file

@ -663,7 +663,8 @@ class DboSource extends DataSource {
if ($cache && ($cached = $this->getQueryCache($sql, $params)) !== false) { if ($cache && ($cached = $this->getQueryCache($sql, $params)) !== false) {
return $cached; return $cached;
} }
if ($result = $this->execute($sql, array(), $params)) { $result = $this->execute($sql, array(), $params);
if ($result) {
$out = array(); $out = array();
if ($this->hasResult()) { if ($this->hasResult()) {
@ -1072,7 +1073,7 @@ class DboSource extends DataSource {
} }
} }
$query = trim($this->generateAssociationQuery($model, null, null, null, null, $queryData, false, $null)); $query = $this->generateAssociationQuery($model, null, null, null, null, $queryData, false, $null);
$resultSet = $this->fetchAll($query, $model->cacheQueries); $resultSet = $this->fetchAll($query, $model->cacheQueries);
@ -1404,7 +1405,7 @@ class DboSource extends DataSource {
if (isset($merge[$association])) { if (isset($merge[$association])) {
$data[$association] = $merge[$association][0]; $data[$association] = $merge[$association][0];
} else { } else {
if (count($merge[0][$association]) > 1) { if (!empty($merge[0][$association])) {
foreach ($merge[0] as $assoc => $data2) { foreach ($merge[0] as $assoc => $data2) {
if ($assoc !== $association) { if ($assoc !== $association) {
$merge[0][$association][$assoc] = $data2; $merge[0][$association][$assoc] = $data2;
@ -1755,19 +1756,19 @@ class DboSource extends DataSource {
switch (strtolower($type)) { switch (strtolower($type)) {
case 'select': case 'select':
return "SELECT {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$group} {$order} {$limit}"; return trim("SELECT {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$group} {$order} {$limit}");
case 'create': case 'create':
return "INSERT INTO {$table} ({$fields}) VALUES ({$values})"; return "INSERT INTO {$table} ({$fields}) VALUES ({$values})";
case 'update': case 'update':
if (!empty($alias)) { if (!empty($alias)) {
$aliases = "{$this->alias}{$alias} {$joins} "; $aliases = "{$this->alias}{$alias} {$joins} ";
} }
return "UPDATE {$table} {$aliases}SET {$fields} {$conditions}"; return trim("UPDATE {$table} {$aliases}SET {$fields} {$conditions}");
case 'delete': case 'delete':
if (!empty($alias)) { if (!empty($alias)) {
$aliases = "{$this->alias}{$alias} {$joins} "; $aliases = "{$this->alias}{$alias} {$joins} ";
} }
return "DELETE {$alias} FROM {$table} {$aliases}{$conditions}"; return trim("DELETE {$alias} FROM {$table} {$aliases}{$conditions}");
case 'schema': case 'schema':
foreach (array('columns', 'indexes', 'tableParameters') as $var) { foreach (array('columns', 'indexes', 'tableParameters') as $var) {
if (is_array(${$var})) { if (is_array(${$var})) {

View file

@ -665,7 +665,8 @@ class Model extends Object implements CakeEventListener {
* Would create a model attached to the posts table on connection2. Dynamic model creation is useful * Would create a model attached to the posts table on connection2. Dynamic model creation is useful
* when you want a model object that contains no associations or attached behaviors. * when you want a model object that contains no associations or attached behaviors.
* *
* @param integer|string|array $id Set this ID for this model on startup, can also be an array of options, see above. * @param boolean|integer|string|array $id Set this ID for this model on startup,
* can also be an array of options, see above.
* @param string $table Name of database table to use. * @param string $table Name of database table to use.
* @param string $ds DataSource connection name. * @param string $ds DataSource connection name.
*/ */
@ -989,30 +990,32 @@ class Model extends Object implements CakeEventListener {
*/ */
protected function _createLinks() { protected function _createLinks() {
foreach ($this->_associations as $type) { foreach ($this->_associations as $type) {
if (!is_array($this->{$type})) { $association =& $this->{$type};
$this->{$type} = explode(',', $this->{$type});
foreach ($this->{$type} as $i => $className) { if (!is_array($association)) {
$association = explode(',', $association);
foreach ($association as $i => $className) {
$className = trim($className); $className = trim($className);
unset ($this->{$type}[$i]); unset ($association[$i]);
$this->{$type}[$className] = array(); $association[$className] = array();
} }
} }
if (!empty($this->{$type})) { if (!empty($association)) {
foreach ($this->{$type} as $assoc => $value) { foreach ($association as $assoc => $value) {
$plugin = null; $plugin = null;
if (is_numeric($assoc)) { if (is_numeric($assoc)) {
unset($this->{$type}[$assoc]); unset($association[$assoc]);
$assoc = $value; $assoc = $value;
$value = array(); $value = array();
if (strpos($assoc, '.') !== false) { if (strpos($assoc, '.') !== false) {
list($plugin, $assoc) = pluginSplit($assoc, true); list($plugin, $assoc) = pluginSplit($assoc, true);
$this->{$type}[$assoc] = array('className' => $plugin . $assoc); $association[$assoc] = array('className' => $plugin . $assoc);
} else { } else {
$this->{$type}[$assoc] = $value; $association[$assoc] = $value;
} }
} }
@ -1068,9 +1071,10 @@ class Model extends Object implements CakeEventListener {
protected function _generateAssociation($type, $assocKey) { protected function _generateAssociation($type, $assocKey) {
$class = $assocKey; $class = $assocKey;
$dynamicWith = false; $dynamicWith = false;
$assoc =& $this->{$type}[$assocKey];
foreach ($this->_associationKeys[$type] as $key) { foreach ($this->_associationKeys[$type] as $key) {
if (!isset($this->{$type}[$assocKey][$key]) || $this->{$type}[$assocKey][$key] === null) { if (!isset($assoc[$key]) || $assoc[$key] === null) {
$data = ''; $data = '';
switch ($key) { switch ($key) {
@ -1087,7 +1091,7 @@ class Model extends Object implements CakeEventListener {
break; break;
case 'with': case 'with':
$data = Inflector::camelize(Inflector::singularize($this->{$type}[$assocKey]['joinTable'])); $data = Inflector::camelize(Inflector::singularize($assoc['joinTable']));
$dynamicWith = true; $dynamicWith = true;
break; break;
@ -1106,11 +1110,11 @@ class Model extends Object implements CakeEventListener {
break; break;
} }
$this->{$type}[$assocKey][$key] = $data; $assoc[$key] = $data;
} }
if ($dynamicWith) { if ($dynamicWith) {
$this->{$type}[$assocKey]['dynamicWith'] = true; $assoc['dynamicWith'] = true;
} }
} }
} }
@ -1182,17 +1186,16 @@ class Model extends Object implements CakeEventListener {
} }
foreach ($data as $modelName => $fieldSet) { foreach ($data as $modelName => $fieldSet) {
if (is_array($fieldSet)) { if (!is_array($fieldSet)) {
foreach ($fieldSet as $fieldName => $fieldValue) { continue;
if (isset($this->validationErrors[$fieldName])) {
unset($this->validationErrors[$fieldName]);
} }
if ($modelName === $this->alias) { foreach ($fieldSet as $fieldName => $fieldValue) {
if ($fieldName === $this->primaryKey) { unset($this->validationErrors[$fieldName]);
if ($modelName === $this->alias && $fieldName === $this->primaryKey) {
$this->id = $fieldValue; $this->id = $fieldValue;
} }
}
if (is_array($fieldValue) || is_object($fieldValue)) { if (is_array($fieldValue) || is_object($fieldValue)) {
$fieldValue = $this->deconstruct($fieldName, $fieldValue); $fieldValue = $this->deconstruct($fieldName, $fieldValue);
@ -1201,7 +1204,6 @@ class Model extends Object implements CakeEventListener {
$this->data[$modelName][$fieldName] = $fieldValue; $this->data[$modelName][$fieldName] = $fieldValue;
} }
} }
}
return $data; return $data;
} }
@ -1554,7 +1556,7 @@ class Model extends Object implements CakeEventListener {
/** /**
* This function is a convenient wrapper class to create(false) and, as the name suggests, clears the id, data, and validation errors. * This function is a convenient wrapper class to create(false) and, as the name suggests, clears the id, data, and validation errors.
* *
* @return always boolean TRUE upon success * @return boolean Always true upon success
* @see Model::create() * @see Model::create()
*/ */
public function clear() { public function clear() {
@ -1746,12 +1748,15 @@ class Model extends Object implements CakeEventListener {
$now = time(); $now = time();
foreach ($dateFields as $updateCol) { foreach ($dateFields as $updateCol) {
if ($this->hasField($updateCol) && !in_array($updateCol, $fields)) { if (in_array($updateCol, $fields) || !$this->hasField($updateCol)) {
continue;
}
$default = array('formatter' => 'date'); $default = array('formatter' => 'date');
$colType = array_merge($default, $db->columns[$this->getColumnType($updateCol)]); $colType = array_merge($default, $db->columns[$this->getColumnType($updateCol)]);
if (!array_key_exists('format', $colType)) {
$time = $now; $time = $now;
} else { if (array_key_exists('format', $colType)) {
$time = call_user_func($colType['formatter'], $colType['format']); $time = call_user_func($colType['formatter'], $colType['format']);
} }
@ -1760,7 +1765,6 @@ class Model extends Object implements CakeEventListener {
} }
$this->set($updateCol, $time); $this->set($updateCol, $time);
} }
}
if ($options['callbacks'] === true || $options['callbacks'] === 'before') { if ($options['callbacks'] === true || $options['callbacks'] === 'before') {
$event = new CakeEvent('Model.beforeSave', $this, array($options)); $event = new CakeEvent('Model.beforeSave', $this, array($options));
@ -1785,8 +1789,7 @@ class Model extends Object implements CakeEventListener {
$v = $v[$n]; $v = $v[$n];
} }
$joined[$n] = $v; $joined[$n] = $v;
} else { } elseif ($n === $this->alias) {
if ($n === $this->alias) {
foreach (array('created', 'updated', 'modified') as $field) { foreach (array('created', 'updated', 'modified') as $field) {
if (array_key_exists($field, $v) && empty($v[$field])) { if (array_key_exists($field, $v) && empty($v[$field])) {
unset($v[$field]); unset($v[$field]);
@ -1800,7 +1803,6 @@ class Model extends Object implements CakeEventListener {
} }
} }
} }
}
$count = count($fields); $count = count($fields);
@ -1892,35 +1894,42 @@ class Model extends Object implements CakeEventListener {
*/ */
protected function _saveMulti($joined, $id, $db) { protected function _saveMulti($joined, $id, $db) {
foreach ($joined as $assoc => $data) { foreach ($joined as $assoc => $data) {
if (isset($this->hasAndBelongsToMany[$assoc])) { if (!isset($this->hasAndBelongsToMany[$assoc])) {
list($join) = $this->joinModel($this->hasAndBelongsToMany[$assoc]['with']); continue;
}
if ($with = $this->hasAndBelongsToMany[$assoc]['with']) { $habtm = $this->hasAndBelongsToMany[$assoc];
$withModel = is_array($with) ? key($with) : $with;
list($join) = $this->joinModel($habtm['with']);
$Model = $this->{$join};
if (!empty($habtm['with'])) {
$withModel = is_array($habtm['with']) ? key($habtm['with']) : $habtm['with'];
list(, $withModel) = pluginSplit($withModel); list(, $withModel) = pluginSplit($withModel);
$dbMulti = $this->{$withModel}->getDataSource(); $dbMulti = $this->{$withModel}->getDataSource();
} else { } else {
$dbMulti = $db; $dbMulti = $db;
} }
$isUUID = !empty($this->{$join}->primaryKey) && $this->{$join}->_isUUIDField($this->{$join}->primaryKey); $isUUID = !empty($Model->primaryKey) && $Model->_isUUIDField($Model->primaryKey);
$newData = $newValues = $newJoins = array(); $newData = $newValues = $newJoins = array();
$primaryAdded = false; $primaryAdded = false;
$fields = array( $fields = array(
$dbMulti->name($this->hasAndBelongsToMany[$assoc]['foreignKey']), $dbMulti->name($habtm['foreignKey']),
$dbMulti->name($this->hasAndBelongsToMany[$assoc]['associationForeignKey']) $dbMulti->name($habtm['associationForeignKey'])
); );
$idField = $db->name($this->{$join}->primaryKey); $idField = $db->name($Model->primaryKey);
if ($isUUID && !in_array($idField, $fields)) { if ($isUUID && !in_array($idField, $fields)) {
$fields[] = $idField; $fields[] = $idField;
$primaryAdded = true; $primaryAdded = true;
} }
foreach ((array)$data as $row) { foreach ((array)$data as $row) {
if ((is_string($row) && (strlen($row) === 36 || strlen($row) === 16)) || is_numeric($row)) { if ((is_string($row) && (strlen($row) == 36 || strlen($row) == 16)) || is_numeric($row)) {
$newJoins[] = $row; $newJoins[] = $row;
$values = array($id, $row); $values = array($id, $row);
@ -1930,35 +1939,35 @@ class Model extends Object implements CakeEventListener {
$newValues[$row] = $values; $newValues[$row] = $values;
unset($values); unset($values);
} elseif (isset($row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) { } elseif (isset($row[$habtm['associationForeignKey']])) {
if (!empty($row[$this->{$join}->primaryKey])) { if (!empty($row[$Model->primaryKey])) {
$newJoins[] = $row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']]; $newJoins[] = $row[$habtm['associationForeignKey']];
} }
$newData[] = $row; $newData[] = $row;
} elseif (isset($row[$join]) && isset($row[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) { } elseif (isset($row[$join]) && isset($row[$join][$habtm['associationForeignKey']])) {
if (!empty($row[$join][$this->{$join}->primaryKey])) { if (!empty($row[$join][$Model->primaryKey])) {
$newJoins[] = $row[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']]; $newJoins[] = $row[$join][$habtm['associationForeignKey']];
} }
$newData[] = $row[$join]; $newData[] = $row[$join];
} }
} }
$keepExisting = $this->hasAndBelongsToMany[$assoc]['unique'] === 'keepExisting'; $keepExisting = $habtm['unique'] === 'keepExisting';
if ($this->hasAndBelongsToMany[$assoc]['unique']) { if ($habtm['unique']) {
$conditions = array( $conditions = array(
$join . '.' . $this->hasAndBelongsToMany[$assoc]['foreignKey'] => $id $join . '.' . $habtm['foreignKey'] => $id
); );
if (!empty($this->hasAndBelongsToMany[$assoc]['conditions'])) { if (!empty($habtm['conditions'])) {
$conditions = array_merge($conditions, (array)$this->hasAndBelongsToMany[$assoc]['conditions']); $conditions = array_merge($conditions, (array)$habtm['conditions']);
} }
$associationForeignKey = $this->{$join}->alias . '.' . $this->hasAndBelongsToMany[$assoc]['associationForeignKey']; $associationForeignKey = $Model->alias . '.' . $habtm['associationForeignKey'];
$links = $this->{$join}->find('all', array( $links = $Model->find('all', array(
'conditions' => $conditions, 'conditions' => $conditions,
'recursive' => empty($this->hasAndBelongsToMany[$assoc]['conditions']) ? -1 : 0, 'recursive' => empty($habtm['conditions']) ? -1 : 0,
'fields' => $associationForeignKey, 'fields' => $associationForeignKey,
)); ));
@ -1970,28 +1979,28 @@ class Model extends Object implements CakeEventListener {
$conditions[$associationForeignKey] = $oldLinks; $conditions[$associationForeignKey] = $oldLinks;
} }
$dbMulti->delete($this->{$join}, $conditions); $dbMulti->delete($Model, $conditions);
} }
} }
if (!empty($newData)) { if (!empty($newData)) {
foreach ($newData as $data) { foreach ($newData as $data) {
$data[$this->hasAndBelongsToMany[$assoc]['foreignKey']] = $id; $data[$habtm['foreignKey']] = $id;
if (empty($data[$this->{$join}->primaryKey])) { if (empty($data[$Model->primaryKey])) {
$this->{$join}->create(); $Model->create();
} }
$this->{$join}->save($data); $Model->save($data);
} }
} }
if (!empty($newValues)) { if (!empty($newValues)) {
if ($keepExisting && !empty($links)) { if ($keepExisting && !empty($links)) {
foreach ($links as $link) { foreach ($links as $link) {
$oldJoin = $link[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']]; $oldJoin = $link[$join][$habtm['associationForeignKey']];
if (!in_array($oldJoin, $newJoins)) { if (!in_array($oldJoin, $newJoins)) {
$conditions[$associationForeignKey] = $oldJoin; $conditions[$associationForeignKey] = $oldJoin;
$db->delete($this->{$join}, $conditions); $db->delete($Model, $conditions);
} else { } else {
unset($newValues[$oldJoin]); unset($newValues[$oldJoin]);
} }
@ -2001,8 +2010,7 @@ class Model extends Object implements CakeEventListener {
} }
if (!empty($newValues)) { if (!empty($newValues)) {
$dbMulti->insertMulti($this->{$join}, $fields, $newValues); $dbMulti->insertMulti($Model, $fields, $newValues);
}
} }
} }
} }
@ -2021,7 +2029,12 @@ class Model extends Object implements CakeEventListener {
$keys['old'] = isset($keys['old']) ? $keys['old'] : array(); $keys['old'] = isset($keys['old']) ? $keys['old'] : array();
foreach ($this->belongsTo as $parent => $assoc) { foreach ($this->belongsTo as $parent => $assoc) {
if (!empty($assoc['counterCache'])) { if (empty($assoc['counterCache'])) {
continue;
}
$Model = $this->{$parent};
if (!is_array($assoc['counterCache'])) { if (!is_array($assoc['counterCache'])) {
if (isset($assoc['counterScope'])) { if (isset($assoc['counterScope'])) {
$assoc['counterCache'] = array($assoc['counterCache'] => $assoc['counterScope']); $assoc['counterCache'] = array($assoc['counterCache'] => $assoc['counterScope']);
@ -2038,7 +2051,7 @@ class Model extends Object implements CakeEventListener {
$field = Inflector::underscore($this->alias) . '_count'; $field = Inflector::underscore($this->alias) . '_count';
} }
if (!$this->{$parent}->hasField($field)) { if (!$Model->hasField($field)) {
continue; continue;
} }
@ -2054,17 +2067,15 @@ class Model extends Object implements CakeEventListener {
$recursive = (empty($conditions) ? -1 : 0); $recursive = (empty($conditions) ? -1 : 0);
if (isset($keys['old'][$foreignKey])) { if (isset($keys['old'][$foreignKey]) && $keys['old'][$foreignKey] != $keys[$foreignKey]) {
if ($keys['old'][$foreignKey] != $keys[$foreignKey]) {
$conditions[$fkQuoted] = $keys['old'][$foreignKey]; $conditions[$fkQuoted] = $keys['old'][$foreignKey];
$count = intval($this->find('count', compact('conditions', 'recursive'))); $count = intval($this->find('count', compact('conditions', 'recursive')));
$this->{$parent}->updateAll( $Model->updateAll(
array($field => $count), array($field => $count),
array($this->{$parent}->escapeField() => $keys['old'][$foreignKey]) array($Model->escapeField() => $keys['old'][$foreignKey])
); );
} }
}
$conditions[$fkQuoted] = $keys[$foreignKey]; $conditions[$fkQuoted] = $keys[$foreignKey];
@ -2074,14 +2085,13 @@ class Model extends Object implements CakeEventListener {
$count = intval($this->find('count', compact('conditions', 'recursive'))); $count = intval($this->find('count', compact('conditions', 'recursive')));
$this->{$parent}->updateAll( $Model->updateAll(
array($field => $count), array($field => $count),
array($this->{$parent}->escapeField() => $keys[$foreignKey]) array($Model->escapeField() => $keys[$foreignKey])
); );
} }
} }
} }
}
/** /**
* Helper method for `Model::updateCounterCache()`. Checks the fields to be updated for * Helper method for `Model::updateCounterCache()`. Checks the fields to be updated for
@ -2343,15 +2353,20 @@ class Model extends Object implements CakeEventListener {
$return = array(); $return = array();
$validates = true; $validates = true;
foreach ($data as $association => $values) { foreach ($data as $association => $values) {
$notEmpty = !empty($values[$association]) || (!isset($values[$association]) && !empty($values)); $isEmpty = empty($values) || (isset($values[$association]) && empty($values[$association]));
if (isset($associations[$association]) && $associations[$association] === 'belongsTo' && $notEmpty) { if ($isEmpty || !isset($associations[$association]) || $associations[$association] !== 'belongsTo') {
$validates = $this->{$association}->create(null) !== null; continue;
}
$Model = $this->{$association};
$validates = $Model->create(null) !== null;
$saved = false; $saved = false;
if ($validates) { if ($validates) {
if ($options['deep']) { if ($options['deep']) {
$saved = $this->{$association}->saveAssociated($values, array_merge($options, array('atomic' => false))); $saved = $Model->saveAssociated($values, array_merge($options, array('atomic' => false)));
} else { } else {
$saved = $this->{$association}->save($values, array_merge($options, array('atomic' => false))); $saved = $Model->save($values, array_merge($options, array('atomic' => false)));
} }
$validates = ($saved === true || (is_array($saved) && !in_array(false, $saved, true))); $validates = ($saved === true || (is_array($saved) && !in_array(false, $saved, true)));
} }
@ -2359,18 +2374,17 @@ class Model extends Object implements CakeEventListener {
if ($validates) { if ($validates) {
$key = $this->belongsTo[$association]['foreignKey']; $key = $this->belongsTo[$association]['foreignKey'];
if (isset($data[$this->alias])) { if (isset($data[$this->alias])) {
$data[$this->alias][$key] = $this->{$association}->id; $data[$this->alias][$key] = $Model->id;
} else { } else {
$data = array_merge(array($key => $this->{$association}->id), $data, array($key => $this->{$association}->id)); $data = array_merge(array($key => $Model->id), $data, array($key => $Model->id));
} }
$options = $this->_addToWhiteList($key, $options); $options = $this->_addToWhiteList($key, $options);
} else { } else {
$validationErrors[$association] = $this->{$association}->validationErrors; $validationErrors[$association] = $Model->validationErrors;
} }
$return[$association] = $validates; $return[$association] = $validates;
} }
}
if ($validates && !($this->create(null) !== null && $this->save($data, $options))) { if ($validates && !($this->create(null) !== null && $this->save($data, $options))) {
$validationErrors[$this->alias] = $this->validationErrors; $validationErrors[$this->alias] = $this->validationErrors;
@ -2383,8 +2397,13 @@ class Model extends Object implements CakeEventListener {
break; break;
} }
$notEmpty = !empty($values[$association]) || (!isset($values[$association]) && !empty($values)); $isEmpty = empty($values) || (isset($values[$association]) && empty($values[$association]));
if (isset($associations[$association]) && $notEmpty) { if ($isEmpty || !isset($associations[$association])) {
continue;
}
$Model = $this->{$association};
$type = $associations[$association]; $type = $associations[$association];
$key = $this->{$type}[$association]['foreignKey']; $key = $this->{$type}[$association]['foreignKey'];
switch ($type) { switch ($type) {
@ -2395,21 +2414,21 @@ class Model extends Object implements CakeEventListener {
$values = array_merge(array($key => $this->id), $values, array($key => $this->id)); $values = array_merge(array($key => $this->id), $values, array($key => $this->id));
} }
$validates = $this->{$association}->create(null) !== null; $validates = $Model->create(null) !== null;
$saved = false; $saved = false;
if ($validates) { if ($validates) {
$options = $this->{$association}->_addToWhiteList($key, $options); $options = $Model->_addToWhiteList($key, $options);
if ($options['deep']) { if ($options['deep']) {
$saved = $this->{$association}->saveAssociated($values, array_merge($options, array('atomic' => false))); $saved = $Model->saveAssociated($values, array_merge($options, array('atomic' => false)));
} else { } else {
$saved = $this->{$association}->save($values, $options); $saved = $Model->save($values, $options);
} }
} }
$validates = ($validates && ($saved === true || (is_array($saved) && !in_array(false, $saved, true)))); $validates = ($validates && ($saved === true || (is_array($saved) && !in_array(false, $saved, true))));
if (!$validates) { if (!$validates) {
$validationErrors[$association] = $this->{$association}->validationErrors; $validationErrors[$association] = $Model->validationErrors;
} }
$return[$association] = $validates; $return[$association] = $validates;
@ -2423,10 +2442,10 @@ class Model extends Object implements CakeEventListener {
} }
} }
$options = $this->{$association}->_addToWhiteList($key, $options); $options = $Model->_addToWhiteList($key, $options);
$_return = $this->{$association}->saveMany($values, array_merge($options, array('atomic' => false))); $_return = $Model->saveMany($values, array_merge($options, array('atomic' => false)));
if (in_array(false, $_return, true)) { if (in_array(false, $_return, true)) {
$validationErrors[$association] = $this->{$association}->validationErrors; $validationErrors[$association] = $Model->validationErrors;
$validates = false; $validates = false;
} }
@ -2434,7 +2453,6 @@ class Model extends Object implements CakeEventListener {
break; break;
} }
} }
}
$this->validationErrors = $validationErrors; $this->validationErrors = $validationErrors;
if (isset($validationErrors[$this->alias])) { if (isset($validationErrors[$this->alias])) {
@ -2477,10 +2495,7 @@ class Model extends Object implements CakeEventListener {
return $options; return $options;
} }
if (!empty($options['fieldList']) && if (!empty($options['fieldList']) && is_array($options['fieldList']) && Hash::dimensions($options['fieldList']) < 2) {
is_array($options['fieldList']) &&
Hash::dimensions($options['fieldList']) < 2
) {
$options['fieldList'][] = $key; $options['fieldList'][] = $key;
} }
@ -2606,29 +2621,29 @@ class Model extends Object implements CakeEventListener {
continue; continue;
} }
$model = $this->{$assoc}; $Model = $this->{$assoc};
if ($data['foreignKey'] === false && $data['conditions'] && in_array($this->name, $model->getAssociated('belongsTo'))) { if ($data['foreignKey'] === false && $data['conditions'] && in_array($this->name, $Model->getAssociated('belongsTo'))) {
$model->recursive = 0; $Model->recursive = 0;
$conditions = array($this->escapeField(null, $this->name) => $id); $conditions = array($this->escapeField(null, $this->name) => $id);
} else { } else {
$model->recursive = -1; $Model->recursive = -1;
$conditions = array($model->escapeField($data['foreignKey']) => $id); $conditions = array($Model->escapeField($data['foreignKey']) => $id);
if ($data['conditions']) { if ($data['conditions']) {
$conditions = array_merge((array)$data['conditions'], $conditions); $conditions = array_merge((array)$data['conditions'], $conditions);
} }
} }
if (isset($data['exclusive']) && $data['exclusive']) { if (isset($data['exclusive']) && $data['exclusive']) {
$model->deleteAll($conditions); $Model->deleteAll($conditions);
} else { } else {
$records = $model->find('all', array( $records = $Model->find('all', array(
'conditions' => $conditions, 'fields' => $model->primaryKey 'conditions' => $conditions, 'fields' => $Model->primaryKey
)); ));
if (!empty($records)) { if (!empty($records)) {
foreach ($records as $record) { foreach ($records as $record) {
$model->delete($record[$model->alias][$model->primaryKey]); $Model->delete($record[$Model->alias][$Model->primaryKey]);
} }
} }
} }
@ -2648,16 +2663,17 @@ class Model extends Object implements CakeEventListener {
protected function _deleteLinks($id) { protected function _deleteLinks($id) {
foreach ($this->hasAndBelongsToMany as $data) { foreach ($this->hasAndBelongsToMany as $data) {
list(, $joinModel) = pluginSplit($data['with']); list(, $joinModel) = pluginSplit($data['with']);
$records = $this->{$joinModel}->find('all', array( $Model = $this->{$joinModel};
'conditions' => array($this->{$joinModel}->escapeField($data['foreignKey']) => $id), $records = $Model->find('all', array(
'fields' => $this->{$joinModel}->primaryKey, 'conditions' => array($Model->escapeField($data['foreignKey']) => $id),
'fields' => $Model->primaryKey,
'recursive' => -1, 'recursive' => -1,
'callbacks' => false 'callbacks' => false
)); ));
if (!empty($records)) { if (!empty($records)) {
foreach ($records as $record) { foreach ($records as $record) {
$this->{$joinModel}->delete($record[$this->{$joinModel}->alias][$this->{$joinModel}->primaryKey]); $Model->delete($record[$Model->alias][$Model->primaryKey]);
} }
} }
} }
@ -3304,7 +3320,7 @@ class Model extends Object implements CakeEventListener {
* *
* Additionally it populates the validationErrors property of the model with the same array. * Additionally it populates the validationErrors property of the model with the same array.
* *
* @param string $options An optional array of custom options to be made available in the beforeValidate callback * @param array|string $options An optional array of custom options to be made available in the beforeValidate callback
* @return array Array of invalid fields and their error messages * @return array Array of invalid fields and their error messages
* @see Model::validates() * @see Model::validates()
*/ */
@ -3671,25 +3687,29 @@ class Model extends Object implements CakeEventListener {
* *
* @param string $type If null this deletes cached views if Cache.check is true * @param string $type If null this deletes cached views if Cache.check is true
* Will be used to allow deleting query cache also * Will be used to allow deleting query cache also
* @return boolean true on delete * @return mixed True on delete, null otherwise
*/ */
protected function _clearCache($type = null) { protected function _clearCache($type = null) {
if ($type !== null || Configure::read('Cache.check') !== true) { if ($type !== null || Configure::read('Cache.check') !== true) {
return; return;
} }
$assoc[] = strtolower(Inflector::pluralize($this->alias)); $pluralized = Inflector::pluralize($this->alias);
$assoc[] = Inflector::underscore(Inflector::pluralize($this->alias)); $assoc = array(
strtolower($pluralized),
Inflector::underscore($pluralized)
);
foreach ($this->_associations as $association) { foreach ($this->_associations as $association) {
foreach ($this->$association as $className) { foreach ($this->{$association} as $className) {
$pluralized = strtolower(Inflector::pluralize($className['className'])); $pluralizedAssociation = Inflector::pluralize($className['className']);
if (!in_array($pluralized, $assoc)) { if (!in_array(strtolower($pluralizedAssociation), $assoc)) {
$assoc[] = $pluralized; $assoc = array_merge($assoc, array(
$assoc[] = Inflector::underscore(Inflector::pluralize($className['className'])); strtolower($pluralizedAssociation),
Inflector::underscore($pluralizedAssociation)
));
} }
} }
} }
$assoc = array_unique($assoc); clearCache(array_unique($assoc));
clearCache($assoc);
return true; return true;
} }

View file

@ -141,7 +141,7 @@ class ModelValidator implements ArrayAccess, IteratorAggregate, Countable {
if (!empty($options['deep']) && isset($data[$model->alias])) { if (!empty($options['deep']) && isset($data[$model->alias])) {
$recordData = $data[$model->alias]; $recordData = $data[$model->alias];
unset($data[$model->alias]); unset($data[$model->alias]);
$data = array_merge($data, $recordData); $data += $recordData;
} }
$associations = $model->getAssociated(); $associations = $model->getAssociated();

View file

@ -300,6 +300,7 @@ class CakeResponse {
'webapp' => 'application/x-web-app-manifest+json', 'webapp' => 'application/x-web-app-manifest+json',
'vcf' => 'text/x-vcard', 'vcf' => 'text/x-vcard',
'vtt' => 'text/vtt', 'vtt' => 'text/vtt',
'mkv' => 'video/x-matroska',
); );
/** /**
@ -1281,7 +1282,7 @@ class CakeResponse {
$agent = env('HTTP_USER_AGENT'); $agent = env('HTTP_USER_AGENT');
if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent)) { if (preg_match('%Opera(/| )([0-9].[0-9]{1,2})%', $agent)) {
$contentType = 'application/octetstream'; $contentType = 'application/octet-stream';
} elseif (preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) { } elseif (preg_match('/MSIE ([0-9].[0-9]{1,2})/', $agent)) {
$contentType = 'application/force-download'; $contentType = 'application/force-download';
} }
@ -1296,6 +1297,7 @@ class CakeResponse {
} }
$this->download($name); $this->download($name);
$this->header('Accept-Ranges', 'bytes'); $this->header('Accept-Ranges', 'bytes');
$this->header('Content-Transfer-Encoding', 'binary');
$httpRange = env('HTTP_RANGE'); $httpRange = env('HTTP_RANGE');
if (isset($httpRange)) { if (isset($httpRange)) {
@ -1373,6 +1375,7 @@ class CakeResponse {
$bufferSize = 8192; $bufferSize = 8192;
set_time_limit(0); set_time_limit(0);
session_write_close();
while (!feof($file->handle)) { while (!feof($file->handle)) {
if (!$this->_isActive()) { if (!$this->_isActive()) {
$file->close(); $file->close();

View file

@ -42,9 +42,10 @@ class MailTransport extends AbstractTransport {
unset($headers['To']); unset($headers['To']);
$headers = $this->_headersToString($headers, $eol); $headers = $this->_headersToString($headers, $eol);
$message = implode($eol, $email->message()); $message = implode($eol, $email->message());
$subject = str_replace(array("\r", "\n"), '', $email->subject());
$params = isset($this->_config['additionalParameters']) ? $this->_config['additionalParameters'] : null; $params = isset($this->_config['additionalParameters']) ? $this->_config['additionalParameters'] : null;
$this->_mail($to, $email->subject(), $message, $headers, $params); $this->_mail($to, $subject, $message, $headers, $params);
return array('headers' => $headers, 'message' => $message); return array('headers' => $headers, 'message' => $message);
} }

View file

@ -134,7 +134,7 @@ class HttpSocket extends CakeSocket {
/** /**
* Build an HTTP Socket using the specified configuration. * Build an HTTP Socket using the specified configuration.
* *
* You can use an URL string to set the URL and use default configurations for * You can use a URL string to set the URL and use default configurations for
* all other options: * all other options:
* *
* `$http = new HttpSocket('http://cakephp.org/');` * `$http = new HttpSocket('http://cakephp.org/');`
@ -464,7 +464,7 @@ class HttpSocket extends CakeSocket {
/** /**
* Issues a POST request to the specified URI, query, and request. * Issues a POST request to the specified URI, query, and request.
* *
* `post()` can be used to post simple data arrays to an URL: * `post()` can be used to post simple data arrays to a URL:
* *
* {{{ * {{{
* $response = $http->post('http://example.com', array( * $response = $http->post('http://example.com', array(
@ -545,7 +545,7 @@ class HttpSocket extends CakeSocket {
* *
* Would return `/search?q=socket`. * Would return `/search?q=socket`.
* *
* @param string|array Either a string or array of URL options to create an URL with. * @param string|array Either a string or array of URL options to create a URL with.
* @param string $uriTemplate A template string to use for URL formatting. * @param string $uriTemplate A template string to use for URL formatting.
* @return mixed Either false on failure or a string containing the composed URL. * @return mixed Either false on failure or a string containing the composed URL.
*/ */

View file

@ -192,9 +192,7 @@ class Dispatcher implements CakeEventListener {
if ($render && $controller->autoRender) { if ($render && $controller->autoRender) {
$response = $controller->render(); $response = $controller->render();
} elseif (!($result instanceof CakeResponse) && } elseif (!($result instanceof CakeResponse) && $response->body() === null) {
$response->body() === null
) {
$response->body($result); $response->body($result);
} }
$controller->shutdownProcess(); $controller->shutdownProcess();

View file

@ -369,9 +369,9 @@ class CakeRoute {
} }
/** /**
* Apply persistent parameters to an URL array. Persistent parameters are a special * Apply persistent parameters to a URL array. Persistent parameters are a special
* key used during route creation to force route parameters to persist when omitted from * key used during route creation to force route parameters to persist when omitted from
* an URL array. * a URL array.
* *
* @param array $url The array to apply persistent parameters to. * @param array $url The array to apply persistent parameters to.
* @param array $params An array of persistent values to replace persistent ones. * @param array $params An array of persistent values to replace persistent ones.
@ -390,7 +390,7 @@ class CakeRoute {
} }
/** /**
* Check if an URL array matches this route instance. * Check if a URL array matches this route instance.
* *
* If the URL matches the route parameters and settings, then * If the URL matches the route parameters and settings, then
* return a generated string URL. If the URL doesn't match the route parameters, false will be returned. * return a generated string URL. If the URL doesn't match the route parameters, false will be returned.
@ -485,7 +485,7 @@ class CakeRoute {
} }
/** /**
* Converts a matching route array into an URL string. * Converts a matching route array into a URL string.
* *
* Composes the string URL using the template * Composes the string URL using the template
* used to create the route. * used to create the route.

View file

@ -41,7 +41,7 @@ class RedirectRoute extends CakeRoute {
public $redirect; public $redirect;
/** /**
* Flag for disabling exit() when this route parses an URL. * Flag for disabling exit() when this route parses a URL.
* *
* @var boolean * @var boolean
*/ */

View file

@ -80,7 +80,7 @@ class Router {
protected static $_parseExtensions = false; protected static $_parseExtensions = false;
/** /**
* List of valid extensions to parse from an URL. If null, any extension is allowed. * List of valid extensions to parse from a URL. If null, any extension is allowed.
* *
* @var array * @var array
*/ */
@ -278,7 +278,7 @@ class Router {
* - `pass` is used to define which of the routed parameters should be shifted into the pass array. Adding a * - `pass` is used to define which of the routed parameters should be shifted into the pass array. Adding a
* parameter to pass will remove it from the regular route array. Ex. `'pass' => array('slug')` * parameter to pass will remove it from the regular route array. Ex. `'pass' => array('slug')`
* - `persist` is used to define which route parameters should be automatically included when generating * - `persist` is used to define which route parameters should be automatically included when generating
* new URLs. You can override persistent parameters by redefining them in an URL or remove them by * new URLs. You can override persistent parameters by redefining them in a URL or remove them by
* setting the parameter to `false`. Ex. `'persist' => array('lang')` * setting the parameter to `false`. Ex. `'persist' => array('lang')`
* - `routeClass` is used to extend and change how individual routes parse requests and handle reverse routing, * - `routeClass` is used to extend and change how individual routes parse requests and handle reverse routing,
* via a custom routing class. Ex. `'routeClass' => 'SlugRoute'` * via a custom routing class. Ex. `'routeClass' => 'SlugRoute'`
@ -359,7 +359,7 @@ class Router {
* `Router::redirect('/home/*', array('controller' => 'posts', 'action' => 'view'), array('persist' => true));` * `Router::redirect('/home/*', array('controller' => 'posts', 'action' => 'view'), array('persist' => true));`
* *
* Redirects /home/* to /posts/view and passes the parameters to /posts/view. Using an array as the * Redirects /home/* to /posts/view and passes the parameters to /posts/view. Using an array as the
* redirect destination allows you to use other routes to define where an URL string should be redirected to. * redirect destination allows you to use other routes to define where a URL string should be redirected to.
* *
* `Router::redirect('/posts/*', 'http://google.com', array('status' => 302));` * `Router::redirect('/posts/*', 'http://google.com', array('status' => 302));`
* *
@ -595,7 +595,7 @@ class Router {
} }
/** /**
* Parses a file extension out of an URL, if Router::parseExtensions() is enabled. * Parses a file extension out of a URL, if Router::parseExtensions() is enabled.
* *
* @param string $url * @param string $url
* @return array Returns an array containing the altered URL and the parsed extension. * @return array Returns an array containing the altered URL and the parsed extension.
@ -764,7 +764,7 @@ class Router {
/** /**
* Finds URL for specified action. * Finds URL for specified action.
* *
* Returns an URL pointing to a combination of controller and action. Param * Returns a URL pointing to a combination of controller and action. Param
* $url can be: * $url can be:
* *
* - Empty - the method will find address to actual controller/action. * - Empty - the method will find address to actual controller/action.
@ -944,7 +944,7 @@ class Router {
* A special fallback method that handles URL arrays that cannot match * A special fallback method that handles URL arrays that cannot match
* any defined routes. * any defined routes.
* *
* @param array $url An URL that didn't match any routes * @param array $url A URL that didn't match any routes
* @return string A generated URL for the array * @return string A generated URL for the array
* @see Router::url() * @see Router::url()
*/ */
@ -1091,7 +1091,7 @@ class Router {
} }
/** /**
* Normalizes an URL for purposes of comparison. * Normalizes a URL for purposes of comparison.
* *
* Will strip the base path off and replace any double /'s. * Will strip the base path off and replace any double /'s.
* It will not unify the casing and underscoring of the input value. * It will not unify the casing and underscoring of the input value.

View file

@ -149,7 +149,7 @@ class ExtractTaskTest extends CakeTestCase {
$this->assertRegExp($pattern, $result); $this->assertRegExp($pattern, $result);
$pattern = '/\#: (\\\\|\/)extract\.ctp:14\n'; $pattern = '/\#: (\\\\|\/)extract\.ctp:14\n';
$pattern .= '\#: (\\\\|\/)home\.ctp:83\n'; $pattern .= '\#: (\\\\|\/)home\.ctp:68\n';
$pattern .= 'msgid "Editing this Page"\nmsgstr ""/'; $pattern .= 'msgid "Editing this Page"\nmsgstr ""/';
$this->assertRegExp($pattern, $result); $this->assertRegExp($pattern, $result);

View file

@ -327,6 +327,44 @@ class CookieComponentTest extends CakeTestCase {
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);
} }
/**
* Test that writing mixed arrays results in the correct data.
*
* @return void
*/
public function testWriteMixedArray() {
$this->Cookie->encrypt = false;
$this->Cookie->write('User', array('name' => 'mark'), false);
$this->Cookie->write('User.email', 'mark@example.com', false);
$expected = array(
'name' => $this->Cookie->name . '[User]',
'value' => '{"name":"mark","email":"mark@example.com"}',
'path' => '/',
'domain' => '',
'secure' => false,
'httpOnly' => false
);
$result = $this->Controller->response->cookie($this->Cookie->name . '[User]');
unset($result['expire']);
$this->assertEquals($expected, $result);
$this->Cookie->write('User.email', 'mark@example.com', false);
$this->Cookie->write('User', array('name' => 'mark'), false);
$expected = array(
'name' => $this->Cookie->name . '[User]',
'value' => '{"name":"mark"}',
'path' => '/',
'domain' => '',
'secure' => false,
'httpOnly' => false
);
$result = $this->Controller->response->cookie($this->Cookie->name . '[User]');
unset($result['expire']);
$this->assertEquals($expected, $result);
}
/** /**
* testReadingCookieValue * testReadingCookieValue
* *

View file

@ -682,6 +682,65 @@ class ContainableBehaviorTest extends CakeTestCase {
); );
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);
$this->Article->contain(array('User' => array('id', 'ArticleFeatured')));
$result = $this->Article->find('all', array('recursive' => 2));
$expected = array(
array(
'Article' => array(
'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
),
'User' => array(
'id' => 1,
'ArticleFeatured' => array(
array(
'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
),
array(
'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
)
)
)
),
array(
'Article' => array(
'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
),
'User' => array(
'id' => 3,
'ArticleFeatured' => array(
array(
'id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body',
'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'
)
)
)
),
array(
'Article' => array(
'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
),
'User' => array(
'id' => 1,
'ArticleFeatured' => array(
array(
'id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body',
'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'
),
array(
'id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body',
'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'
)
)
)
)
);
$this->assertEquals($expected, $result);
$this->Article->contain(array('User' => array('ArticleFeatured', 'Comment'))); $this->Article->contain(array('User' => array('ArticleFeatured', 'Comment')));
$result = $this->Article->find('all', array('recursive' => 2)); $result = $this->Article->find('all', array('recursive' => 2));
$expected = array( $expected = array(

View file

@ -1206,7 +1206,7 @@ class MysqlTest extends CakeTestCase {
$this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $result); $this->assertRegExp('/^SELECT\s+`TestModel4`\.`id`, `TestModel4`\.`name`, `TestModel4`\.`created`, `TestModel4`\.`updated`, `TestModel4Parent`\.`id`, `TestModel4Parent`\.`name`, `TestModel4Parent`\.`created`, `TestModel4Parent`\.`updated`\s+/', $result);
$this->assertRegExp('/FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4Parent`/', $result); $this->assertRegExp('/FROM\s+\S+`test_model4` AS `TestModel4`\s+LEFT JOIN\s+\S+`test_model4` AS `TestModel4Parent`/', $result);
$this->assertRegExp('/\s+ON\s+\(`TestModel4`.`parent_id` = `TestModel4Parent`.`id`\)\s+WHERE/', $result); $this->assertRegExp('/\s+ON\s+\(`TestModel4`.`parent_id` = `TestModel4Parent`.`id`\)\s+WHERE/', $result);
$this->assertRegExp('/\s+WHERE\s+1 = 1\s+$/', $result); $this->assertRegExp('/\s+WHERE\s+1 = 1$/', $result);
$params['assocData']['type'] = 'INNER'; $params['assocData']['type'] = 'INNER';
$this->Model->belongsTo['TestModel4Parent']['type'] = 'INNER'; $this->Model->belongsTo['TestModel4Parent']['type'] = 'INNER';

View file

@ -1132,6 +1132,10 @@ class CakeResponseTest extends CakeTestCase {
->with('Accept-Ranges', 'bytes'); ->with('Accept-Ranges', 'bytes');
$response->expects($this->at(3)) $response->expects($this->at(3))
->method('header')
->with('Content-Transfer-Encoding', 'binary');
$response->expects($this->at(4))
->method('header') ->method('header')
->with('Content-Length', 35); ->with('Content-Length', 35);
@ -1181,7 +1185,7 @@ class CakeResponseTest extends CakeTestCase {
$response->expects($this->at(1)) $response->expects($this->at(1))
->method('type') ->method('type')
->with('application/octetstream') ->with('application/octet-stream')
->will($this->returnValue(false)); ->will($this->returnValue(false));
$response->expects($this->once()) $response->expects($this->once())
@ -1193,6 +1197,10 @@ class CakeResponseTest extends CakeTestCase {
->with('Accept-Ranges', 'bytes'); ->with('Accept-Ranges', 'bytes');
$response->expects($this->at(4)) $response->expects($this->at(4))
->method('header')
->with('Content-Transfer-Encoding', 'binary');
$response->expects($this->at(5))
->method('header') ->method('header')
->with('Content-Length', 35); ->with('Content-Length', 35);
@ -1253,6 +1261,10 @@ class CakeResponseTest extends CakeTestCase {
->with('Accept-Ranges', 'bytes'); ->with('Accept-Ranges', 'bytes');
$response->expects($this->at(4)) $response->expects($this->at(4))
->method('header')
->with('Content-Transfer-Encoding', 'binary');
$response->expects($this->at(5))
->method('header') ->method('header')
->with('Content-Length', 35); ->with('Content-Length', 35);
@ -1455,6 +1467,10 @@ class CakeResponseTest extends CakeTestCase {
->with('Accept-Ranges', 'bytes'); ->with('Accept-Ranges', 'bytes');
$response->expects($this->at(3)) $response->expects($this->at(3))
->method('header')
->with('Content-Transfer-Encoding', 'binary');
$response->expects($this->at(4))
->method('header') ->method('header')
->with(array( ->with(array(
'Content-Length' => $length, 'Content-Length' => $length,
@ -1506,6 +1522,10 @@ class CakeResponseTest extends CakeTestCase {
->with('Accept-Ranges', 'bytes'); ->with('Accept-Ranges', 'bytes');
$response->expects($this->at(3)) $response->expects($this->at(3))
->method('header')
->with('Content-Transfer-Encoding', 'binary');
$response->expects($this->at(4))
->method('header') ->method('header')
->with(array( ->with(array(
'Content-Length' => 18, 'Content-Length' => 18,
@ -1557,6 +1577,10 @@ class CakeResponseTest extends CakeTestCase {
->with('Accept-Ranges', 'bytes'); ->with('Accept-Ranges', 'bytes');
$response->expects($this->at(3)) $response->expects($this->at(3))
->method('header')
->with('Content-Transfer-Encoding', 'binary');
$response->expects($this->at(4))
->method('header') ->method('header')
->with(array( ->with(array(
'Content-Range' => 'bytes 0-37/38', 'Content-Range' => 'bytes 0-37/38',

View file

@ -69,7 +69,7 @@ class MailTransportTest extends CakeTestCase {
$data .= "Content-Transfer-Encoding: 8bit"; $data .= "Content-Transfer-Encoding: 8bit";
$subject = '=?UTF-8?B?Rm/DuCBCw6VyIELDqXogRm/DuCBCw6VyIELDqXogRm/DuCBCw6VyIELDqXog?='; $subject = '=?UTF-8?B?Rm/DuCBCw6VyIELDqXogRm/DuCBCw6VyIELDqXogRm/DuCBCw6VyIELDqXog?=';
$subject .= "\r\n" . ' =?UTF-8?B?Rm/DuCBCw6VyIELDqXo=?='; $subject .= ' =?UTF-8?B?Rm/DuCBCw6VyIELDqXo=?=';
$this->MailTransport->expects($this->once())->method('_mail') $this->MailTransport->expects($this->once())->method('_mail')
->with( ->with(
'CakePHP <cake@cakephp.org>', 'CakePHP <cake@cakephp.org>',

View file

@ -396,7 +396,7 @@ class FileTest extends CakeTestCase {
public function testWrite() { public function testWrite() {
if (!$tmpFile = $this->_getTmpFile()) { if (!$tmpFile = $this->_getTmpFile()) {
return false; return false;
}; }
if (file_exists($tmpFile)) { if (file_exists($tmpFile)) {
unlink($tmpFile); unlink($tmpFile);
} }
@ -426,7 +426,7 @@ class FileTest extends CakeTestCase {
public function testAppend() { public function testAppend() {
if (!$tmpFile = $this->_getTmpFile()) { if (!$tmpFile = $this->_getTmpFile()) {
return false; return false;
}; }
if (file_exists($tmpFile)) { if (file_exists($tmpFile)) {
unlink($tmpFile); unlink($tmpFile);
} }

View file

@ -120,6 +120,9 @@ class InflectorTest extends CakeTestCase {
$this->assertEquals(Inflector::singularize('objectives'), 'objective'); $this->assertEquals(Inflector::singularize('objectives'), 'objective');
$this->assertEquals(Inflector::singularize('archives'), 'archive'); $this->assertEquals(Inflector::singularize('archives'), 'archive');
$this->assertEquals(Inflector::singularize('briefs'), 'brief'); $this->assertEquals(Inflector::singularize('briefs'), 'brief');
$this->assertEquals(Inflector::singularize('quotas'), 'quota');
$this->assertEquals(Inflector::singularize('curves'), 'curve');
$this->assertEquals(Inflector::singularize('body_curves'), 'body_curve');
$this->assertEquals(Inflector::singularize(''), ''); $this->assertEquals(Inflector::singularize(''), '');
} }
@ -181,6 +184,9 @@ class InflectorTest extends CakeTestCase {
$this->assertEquals(Inflector::pluralize('foot'), 'feet'); $this->assertEquals(Inflector::pluralize('foot'), 'feet');
$this->assertEquals(Inflector::pluralize('objective'), 'objectives'); $this->assertEquals(Inflector::pluralize('objective'), 'objectives');
$this->assertEquals(Inflector::pluralize('brief'), 'briefs'); $this->assertEquals(Inflector::pluralize('brief'), 'briefs');
$this->assertEquals(Inflector::pluralize('quota'), 'quotas');
$this->assertEquals(Inflector::pluralize('curve'), 'curves');
$this->assertEquals(Inflector::pluralize('body_curve'), 'body_curves');
$this->assertEquals(Inflector::pluralize(''), ''); $this->assertEquals(Inflector::pluralize(''), '');
} }

View file

@ -219,6 +219,17 @@ class JqueryEngineHelperTest extends CakeTestCase {
)); ));
$expected = '$.ajax({beforeSend:function (XMLHttpRequest) {doBefore}, data:$("#someId").serialize(), success:function (data, textStatus) {doFoo}, type:"post", url:"\\/people\\/edit\\/1"});'; $expected = '$.ajax({beforeSend:function (XMLHttpRequest) {doBefore}, data:$("#someId").serialize(), success:function (data, textStatus) {doFoo}, type:"post", url:"\\/people\\/edit\\/1"});';
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);
$result = $this->Jquery->request('/people/edit/1', array(
'success' => 'doFoo',
'xhr' => 'return jQuery.ajaxSettings.xhr();',
'async' => true,
'method' => 'post',
'dataExpression' => true,
'data' => '$("#someId").serialize()',
));
$expected = '$.ajax({async:true, data:$("#someId").serialize(), success:function (data, textStatus) {doFoo}, type:"post", url:"\/people\/edit\/1", xhr:function () {return jQuery.ajaxSettings.xhr();}});';
$this->assertEquals($expected, $result);
} }
/** /**

View file

@ -1515,6 +1515,20 @@ class ViewTest extends CakeTestCase {
$this->assertEquals('In second', $this->View->fetch('second')); $this->assertEquals('In second', $this->View->fetch('second'));
} }
/**
* Test that starting the same block twice throws an exception
*
* @expectedException CakeException
* @return void
*/
public function testStartBlocksTwice() {
$this->View->start('first');
echo 'In first ';
$this->View->start('second');
echo 'In second';
$this->View->start('first');
}
/** /**
* Test that an exception gets thrown when you leave a block open at the end * Test that an exception gets thrown when you leave a block open at the end
* of a view. * of a view.

View file

@ -1,8 +1,3 @@
<?php
App::uses('Debugger', 'Utility');
?>
<h2><?php echo __d('cake_dev', 'Release Notes for CakePHP %s.', Configure::version()); ?></h2>
<a href="http://cakephp.org/changelogs/1.3.6"><?php echo __d('cake_dev', 'Read the changelog'); ?> </a>
<p> <p>
<?php <?php
if (is_writable(TMP)): if (is_writable(TMP)):
@ -70,78 +65,8 @@ if (isset($filePresent)):
?> ?>
</p> </p>
<?php endif; ?> <?php endif; ?>
<?php
App::uses('Validation', 'Utility');
if (!Validation::alphaNumeric('cakephp')) {
echo '<p><span class="notice">';
__('PCRE has not been compiled with Unicode support.');
echo '<br/>';
__('Recompile PCRE with Unicode support by adding <code>--enable-unicode-properties</code> when configuring');
echo '</span></p>';
}
?>
<h3><?php echo __d('cake_dev', 'Editing this Page'); ?></h3> <h3><?php echo __d('cake_dev', 'Editing this Page'); ?></h3>
<p>
<?php <?php
echo __d('cake_dev', 'To change the content of this page, create: APP/views/pages/home.ctp.<br /> echo __d('cake_dev', 'To change the content of this page, create: APP/views/pages/home.ctp.<br />
To change its layout, create: APP/views/layouts/default.ctp.<br /> To change its layout, create: APP/views/layouts/default.ctp.<br />
You can also add some CSS styles for your pages at: APP/webroot/css.'); You can also add some CSS styles for your pages at: APP/webroot/css.');
?>
</p>
<h3><?php echo __d('cake_dev', 'Getting Started'); ?></h3>
<p>
<?php
echo $this->Html->link(
sprintf('<strong>%s</strong> %s', __d('cake_dev', 'New'), __d('cake_dev', 'CakePHP 1.3 Docs')),
'http://book.cakephp.org/view/875/x1-3-Collection',
array('target' => '_blank', 'escape' => false)
);
?>
</p>
<p>
<?php
echo $this->Html->link(
__d('cake_dev', 'The 15 min Blog Tutorial'),
'http://book.cakephp.org/view/1528/Blog',
array('target' => '_blank', 'escape' => false)
);
?>
</p>
<h3><?php echo __d('cake_dev', 'More about Cake'); ?></h3>
<p>
<?php echo __d('cake_dev', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?>
</p>
<p>
<?php echo __d('cake_dev', 'Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility.'); ?>
</p>
<ul>
<li><a href="http://cakefoundation.org/"><?php echo __d('cake_dev', 'Cake Software Foundation'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Promoting development related to CakePHP'); ?></li></ul></li>
<li><a href="http://www.cakephp.org"><?php echo __d('cake_dev', 'CakePHP'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'The Rapid Development Framework'); ?></li></ul></li>
<li><a href="http://book.cakephp.org"><?php echo __d('cake_dev', 'CakePHP Documentation'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Your Rapid Development Cookbook'); ?></li></ul></li>
<li><a href="http://api.cakephp.org"><?php echo __d('cake_dev', 'CakePHP API'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Quick Reference'); ?></li></ul></li>
<li><a href="http://bakery.cakephp.org"><?php echo __d('cake_dev', 'The Bakery'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Everything CakePHP'); ?></li></ul></li>
<li><a href="http://live.cakephp.org"><?php echo __d('cake_dev', 'The Show'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'The Show is a live and archived internet radio broadcast CakePHP-related topics and answer questions live via IRC, Skype, and telephone.'); ?></li></ul></li>
<li><a href="http://groups.google.com/group/cake-php"><?php echo __d('cake_dev', 'CakePHP Google Group'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Community mailing list'); ?></li></ul></li>
<li><a href="irc://irc.freenode.net/cakephp">irc.freenode.net #cakephp</a>
<ul><li><?php echo __d('cake_dev', 'Live chat about CakePHP'); ?></li></ul></li>
<li><a href="https://github.com/cakephp/"><?php echo __d('cake_dev', 'CakePHP Code'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'For the Development of CakePHP Git repository, Downloads'); ?></li></ul></li>
<li><a href="https://cakephp.lighthouseapp.com/"><?php echo __d('cake_dev', 'CakePHP Lighthouse'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'CakePHP Tickets, Wiki pages, Roadmap'); ?></li></ul></li>
<li><a href="http://www.cakeforge.org"><?php echo __d('cake_dev', 'CakeForge'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Open Development for CakePHP'); ?></li></ul></li>
<li><a href="http://astore.amazon.com/cakesoftwaref-20/"><?php echo __d('cake_dev', 'Book Store'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Recommended Software Books'); ?></li></ul></li>
<li><a href="http://www.cafepress.com/cakefoundation"><?php echo __d('cake_dev', 'CakePHP gear'); ?> </a>
<ul><li><?php echo __d('cake_dev', 'Get your own CakePHP gear - Doughnate to Cake'); ?></li></ul></li>
</ul>

View file

@ -91,7 +91,7 @@ if (!empty($filePresent)):
<a href="http://www-128.ibm.com/developerworks/edu/os-dw-os-php-cake1.html"><?php echo __d('cake', 'Cook up Web sites fast with CakePHP'); ?></a><br /> <a href="http://www-128.ibm.com/developerworks/edu/os-dw-os-php-cake1.html"><?php echo __d('cake', 'Cook up Web sites fast with CakePHP'); ?></a><br />
<a href="http://www-128.ibm.com/developerworks/edu/os-dw-os-php-wiki1.html"><?php echo __d('cake', 'Create an interactive production wiki using PHP'); ?></a> <a href="http://www-128.ibm.com/developerworks/edu/os-dw-os-php-wiki1.html"><?php echo __d('cake', 'Create an interactive production wiki using PHP'); ?></a>
</p> </p>
<h2><?php echo __d('cake', 'More about Cake'); ?></h2> <h2><?php echo __d('cake', 'More about CakePHP'); ?></h2>
<p> <p>
<?php echo __d('cake', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?> <?php echo __d('cake', 'CakePHP is a rapid development framework for PHP which uses commonly known design patterns like Active Record, Association Data Mapping, Front Controller and MVC.'); ?>
</p> </p>

View file

@ -593,7 +593,7 @@ class Hash {
} }
/** /**
* Expand/unflattens an string to an array * Expands a flat array to a nested array.
* *
* For example, unflattens an array that was collapsed with `Hash::flatten()` * For example, unflattens an array that was collapsed with `Hash::flatten()`
* into a multi-dimensional array. So, `array('0.Foo.Bar' => 'Far')` becomes * into a multi-dimensional array. So, `array('0.Foo.Bar' => 'Far')` becomes

View file

@ -129,8 +129,8 @@ class Inflector {
'/(tive)s$/i' => '\1', '/(tive)s$/i' => '\1',
'/(hive)s$/i' => '\1', '/(hive)s$/i' => '\1',
'/(drive)s$/i' => '\1', '/(drive)s$/i' => '\1',
'/([lre])ves$/i' => '\1f', '/([le])ves$/i' => '\1f',
'/([^fo])ves$/i' => '\1fe', '/([^rfo])ves$/i' => '\1fe',
'/(^analy)ses$/i' => '\1sis', '/(^analy)ses$/i' => '\1sis',
'/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis', '/(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
'/([ti])a$/i' => '\1um', '/([ti])a$/i' => '\1um',
@ -148,7 +148,6 @@ class Inflector {
'irregular' => array( 'irregular' => array(
'foes' => 'foe', 'foes' => 'foe',
'waves' => 'wave', 'waves' => 'wave',
'curves' => 'curve'
) )
); );

View file

@ -81,7 +81,7 @@ class Xml {
* is disabled by default for security reasons. * is disabled by default for security reasons.
* - If using array as input, you can pass `options` from Xml::fromArray. * - If using array as input, you can pass `options` from Xml::fromArray.
* *
* @param string|array $input XML string, a path to a file, an URL or an array * @param string|array $input XML string, a path to a file, a URL or an array
* @param array $options The options to use * @param array $options The options to use
* @return SimpleXMLElement|DOMDocument SimpleXMLElement or DOMDocument * @return SimpleXMLElement|DOMDocument SimpleXMLElement or DOMDocument
* @throws XmlException * @throws XmlException

View file

@ -196,6 +196,7 @@ class Helper extends Object {
* *
* @param string $name Name of the property being accessed. * @param string $name Name of the property being accessed.
* @return mixed Helper or property found at $name * @return mixed Helper or property found at $name
* @deprecated Accessing request properties through this method is deprecated and will be removed in 3.0.
*/ */
public function __get($name) { public function __get($name) {
if (isset($this->_helperMap[$name]) && !isset($this->{$name})) { if (isset($this->_helperMap[$name]) && !isset($this->{$name})) {
@ -224,6 +225,7 @@ class Helper extends Object {
* @param string $name Name of the property being accessed. * @param string $name Name of the property being accessed.
* @param mixed $value * @param mixed $value
* @return void * @return void
* @deprecated This method will be removed in 3.0
*/ */
public function __set($name, $value) { public function __set($name, $value) {
switch ($name) { switch ($name) {
@ -243,7 +245,7 @@ class Helper extends Object {
/** /**
* Finds URL for specified action. * Finds URL for specified action.
* *
* Returns an URL pointing at the provided parameters. * Returns a URL pointing at the provided parameters.
* *
* @param string|array $url Either a relative string url like `/products/view/23` or * @param string|array $url Either a relative string url like `/products/view/23` or
* an array of URL parameters. Using an array for URLs will allow you to leverage * an array of URL parameters. Using an array for URLs will allow you to leverage
@ -339,7 +341,7 @@ class Helper extends Object {
} }
/** /**
* Encodes an URL for use in HTML attributes. * Encodes a URL for use in HTML attributes.
* *
* @param string $url The URL to encode. * @param string $url The URL to encode.
* @return string The URL encoded for both URL & HTML contexts. * @return string The URL encoded for both URL & HTML contexts.
@ -404,6 +406,7 @@ class Helper extends Object {
* *
* @param string|array $output Either an array of strings to clean or a single string to clean. * @param string|array $output Either an array of strings to clean or a single string to clean.
* @return string|array cleaned content for output * @return string|array cleaned content for output
* @deprecated This method will be removed in 3.0
*/ */
public function clean($output) { public function clean($output) {
$this->_reset(); $this->_reset();

View file

@ -297,7 +297,7 @@ class FormHelper extends AppHelper {
* *
* - `type` Form method defaults to POST * - `type` Form method defaults to POST
* - `action` The controller action the form submits to, (optional). * - `action` The controller action the form submits to, (optional).
* - `url` The URL the form submits to. Can be a string or an URL array. If you use 'url' * - `url` The URL the form submits to. Can be a string or a URL array. If you use 'url'
* you should leave 'action' undefined. * you should leave 'action' undefined.
* - `default` Allows for the creation of Ajax forms. Set this to false to prevent the default event handler. * - `default` Allows for the creation of Ajax forms. Set this to false to prevent the default event handler.
* Will create an onsubmit attribute if it doesn't not exist. If it does, default action suppression * Will create an onsubmit attribute if it doesn't not exist. If it does, default action suppression

View file

@ -271,7 +271,7 @@ class JqueryEngineHelper extends JsBaseEngineHelper {
$options['success'] = $success; $options['success'] = $success;
unset($options['update']); unset($options['update']);
} }
$callbacks = array('success', 'error', 'beforeSend', 'complete'); $callbacks = array('success', 'error', 'beforeSend', 'complete', 'xhr');
if (!empty($options['dataExpression'])) { if (!empty($options['dataExpression'])) {
$callbacks[] = 'data'; $callbacks[] = 'data';
unset($options['dataExpression']); unset($options['dataExpression']);

View file

@ -67,7 +67,7 @@ abstract class JsBaseEngineHelper extends AppHelper {
} }
/** /**
* Redirects to an URL. Creates a window.location modification snippet * Redirects to a URL. Creates a window.location modification snippet
* that can be used to trigger 'redirects' from JavaScript. * that can be used to trigger 'redirects' from JavaScript.
* *
* @param string|array $url URL * @param string|array $url URL

View file

@ -68,6 +68,7 @@ class NumberHelper extends AppHelper {
/** /**
* Call methods from CakeNumber utility class * Call methods from CakeNumber utility class
* @return mixed Whatever is returned by called method, or false on failure
*/ */
public function __call($method, $params) { public function __call($method, $params) {
return call_user_func_array(array($this->_engine, $method), $params); return call_user_func_array(array($this->_engine, $method), $params);

View file

@ -83,6 +83,7 @@ class TextHelper extends AppHelper {
/** /**
* Call methods from String utility class * Call methods from String utility class
* @return mixed Whatever is returned by called method, or false on failure
*/ */
public function __call($method, $params) { public function __call($method, $params) {
return call_user_func_array(array($this->_engine, $method), $params); return call_user_func_array(array($this->_engine, $method), $params);

View file

@ -117,6 +117,7 @@ class TimeHelper extends AppHelper {
/** /**
* Call methods from CakeTime utility class * Call methods from CakeTime utility class
* @return mixed Whatever is returned by called method, or false on failure
*/ */
public function __call($method, $params) { public function __call($method, $params) {
return call_user_func_array(array($this->_engine, $method), $params); return call_user_func_array(array($this->_engine, $method), $params);

View file

@ -539,7 +539,7 @@ class View extends Object {
public function renderCache($filename, $timeStart) { public function renderCache($filename, $timeStart) {
$response = $this->response; $response = $this->response;
ob_start(); ob_start();
include ($filename); include $filename;
$type = $response->mapType($response->type()); $type = $response->mapType($response->type());
if (Configure::read('debug') > 0 && $type === 'html') { if (Configure::read('debug') > 0 && $type === 'html') {

View file

@ -72,9 +72,13 @@ class ViewBlock {
* using View::get(); * using View::get();
* *
* @param string $name The name of the block to capture for. * @param string $name The name of the block to capture for.
* @throws CakeException When starting a block twice
* @return void * @return void
*/ */
public function start($name) { public function start($name) {
if (in_array($name, $this->_active)) {
throw new CakeException(__("A view block with the name '%s' is already/still open.", $name));
}
$this->_active[] = $name; $this->_active[] = $name;
ob_start(); ob_start();
} }

View file

@ -125,22 +125,22 @@ TEXT;
if (!function_exists('sortByKey')) { if (!function_exists('sortByKey')) {
/** /**
* Sorts given $array by key $sortby. * Sorts given $array by key $sortBy.
* *
* @param array $array Array to sort * @param array $array Array to sort
* @param string $sortby Sort by this key * @param string $sortBy Sort by this key
* @param string $order Sort order asc/desc (ascending or descending). * @param string $order Sort order asc/desc (ascending or descending).
* @param integer $type Type of sorting to perform * @param integer $type Type of sorting to perform
* @return mixed Sorted array * @return mixed Sorted array
* @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#sortByKey * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#sortByKey
*/ */
function sortByKey(&$array, $sortby, $order = 'asc', $type = SORT_NUMERIC) { function sortByKey(&$array, $sortBy, $order = 'asc', $type = SORT_NUMERIC) {
if (!is_array($array)) { if (!is_array($array)) {
return null; return null;
} }
foreach ($array as $key => $val) { foreach ($array as $key => $val) {
$sa[$key] = $val[$sortby]; $sa[$key] = $val[$sortBy];
} }
if ($order === 'asc') { if ($order === 'asc') {