Merge branch 'master' into 2.4

Conflicts:
	lib/Cake/VERSION.txt
This commit is contained in:
mark_story 2013-03-04 21:55:29 -05:00
commit 4b13e0a5f2
22 changed files with 168 additions and 74 deletions

View file

@ -90,7 +90,7 @@ if (!empty($failed)) {
}
if (Configure::read('debug') < 1) {
die(__d('cake_dev', 'Debug setting does not allow access to this url.'));
throw new NotFoundException(__d('cake_dev', 'Debug setting does not allow access to this url.'));
}
require_once CAKE . 'TestSuite' . DS . 'CakeTestSuiteDispatcher.php';

View file

@ -127,7 +127,7 @@ abstract class CacheEngine {
/**
* Clears all values belonging to a group. Is upt to the implementing engine
* to decide whether actually deete the keys or just simulate it to acheive
* to decide whether actually delete the keys or just simulate it to achieve
* the same result.
*
* @param string $groups name of the group to be cleared

View file

@ -312,7 +312,7 @@ class SchemaShell extends AppShell {
* @param string $table
* @return void
*/
protected function _create($Schema, $table = null) {
protected function _create(CakeSchema $Schema, $table = null) {
$db = ConnectionManager::getDataSource($this->Schema->connection);
$drop = $create = array();
@ -402,7 +402,7 @@ class SchemaShell extends AppShell {
* @param CakeSchema $Schema
* @return void
*/
protected function _run($contents, $event, &$Schema) {
protected function _run($contents, $event, CakeSchema $Schema) {
if (empty($contents)) {
$this->err(__d('cake_console', 'Sql could not be run'));
return;

View file

@ -178,14 +178,6 @@ class ExtractTask extends AppShell {
$this->_extractCore = strtolower($response) === 'y';
}
if ($this->_extractCore) {
$this->_paths[] = CAKE;
$this->_exclude = array_merge($this->_exclude, array(
CAKE . 'Test',
CAKE . 'Console' . DS . 'Templates'
));
}
if (!empty($this->params['exclude-plugins']) && $this->_isExtractingApp()) {
$this->_exclude = array_merge($this->_exclude, App::path('plugins'));
}
@ -197,6 +189,14 @@ class ExtractTask extends AppShell {
$this->_validationDomain = $this->params['validation-domain'];
}
if ($this->_extractCore) {
$this->_paths[] = CAKE;
$this->_exclude = array_merge($this->_exclude, array(
CAKE . 'Test',
CAKE . 'Console' . DS . 'Templates'
));
}
if (isset($this->params['output'])) {
$this->_output = $this->params['output'];
} elseif (isset($this->params['plugin'])) {

View file

@ -299,6 +299,7 @@ class FixtureTask extends BakeTask {
if (empty($fieldInfo['type'])) {
continue;
}
$insert = '';
switch ($fieldInfo['type']) {
case 'integer':
case 'float':

View file

@ -90,7 +90,7 @@ if (!empty($failed)) {
}
if (Configure::read('debug') < 1) {
die(__d('cake_dev', 'Debug setting does not allow access to this url.'));
throw new NotFoundException(__d('cake_dev', 'Debug setting does not allow access to this url.'));
}
require_once CAKE . 'TestSuite' . DS . 'CakeTestSuiteDispatcher.php';

View file

@ -158,7 +158,7 @@ class Component extends Object {
* @param integer $status The status code of the redirect
* @param boolean $exit Will the script exit.
* @return array|void Either an array or null.
* @link @link http://book.cakephp.org/2.0/en/controllers/components.html#Component::beforeRedirect
* @link http://book.cakephp.org/2.0/en/controllers/components.html#Component::beforeRedirect
*/
public function beforeRedirect(Controller $controller, $url, $status = null, $exit = true) {
}

View file

@ -411,6 +411,8 @@ class AuthComponent extends Component {
}
/**
* Check if the provided user is authorized for the request.
*
* Uses the configured Authorization adapters to check whether or not a user is authorized.
* Each adapter will be checked in sequence, if any of them return true, then the user will
* be authorized for the request.
@ -532,7 +534,9 @@ class AuthComponent extends Component {
}
/**
* Maps action names to CRUD operations. Used for controller-based authentication. Make sure
* Maps action names to CRUD operations.
*
* Used for controller-based authentication. Make sure
* to configure the authorize property before calling this method. As it delegates $map to all the
* attached authorize objects.
*
@ -551,7 +555,9 @@ class AuthComponent extends Component {
}
/**
* Log a user in. If a $user is provided that data will be stored as the logged in user. If `$user` is empty or not
* Log a user in.
*
* If a $user is provided that data will be stored as the logged in user. If `$user` is empty or not
* specified, the request will be used to identify a user. If the identification was successful,
* the user record is written to the session key specified in AuthComponent::$sessionKey. Logging in
* will also change the session id in order to help mitigate session replays.
@ -574,11 +580,13 @@ class AuthComponent extends Component {
}
/**
* Logs a user out, and returns the login action to redirect to.
* Triggers the logout() method of all the authenticate objects, so they can perform
* custom logout logic. AuthComponent will remove the session data, so
* there is no need to do that in an authentication object. Logging out
* will also renew the session id. This helps mitigate issues with session replays.
* Log a user out.
*
* Returns the login action to redirect to. Triggers the logout() method of
* all the authenticate objects, so they can perform custom logout logic.
* AuthComponent will remove the session data, so there is no need to do that
* in an authentication object. Logging out will also renew the session id.
* This helps mitigate issues with session replays.
*
* @return string AuthComponent::$logoutRedirect
* @see AuthComponent::$logoutRedirect
@ -661,6 +669,8 @@ class AuthComponent extends Component {
}
/**
* Get the URL a use should be redirected to upon login.
*
* If no parameter is passed, gets the authentication redirect URL. Pass a url in to
* set the destination a user should be redirected to upon logging in. Will fallback to
* AuthComponent::$loginRedirect if there is no stored redirect value.

View file

@ -1096,7 +1096,9 @@ class Controller extends Object implements CakeEventListener {
/**
* The beforeRedirect method is invoked when the controller's redirect method is called but before any
* further action. If this method returns false the controller will not continue on to redirect the request.
* further action.
*
* If this method returns false the controller will not continue on to redirect the request.
* The $url, $status and $exit variables have same meaning as for the controller's method. You can also
* return a string which will be interpreted as the url to redirect to or return associative array with
* key 'url' and optionally 'status' and 'exit'.

View file

@ -160,7 +160,7 @@ class Configure {
* Configure::read('Name.key'); will return only the value of Configure::Name[key]
* }}}
*
* @linkhttp://book.cakephp.org/2.0/en/development/configuration.html#Configure::read
* @link http://book.cakephp.org/2.0/en/development/configuration.html#Configure::read
* @param string $var Variable to obtain. Use '.' to access array elements.
* @return mixed value stored in configure, or null.
*/

View file

@ -227,7 +227,7 @@ class ErrorHandler {
}
if (ob_get_level()) {
ob_clean();
ob_end_clean();
}
if (Configure::read('debug')) {

View file

@ -626,7 +626,7 @@ class CakeSchema extends Object {
unset($value['limit']);
}
if (isset($value['default']) && ($value['default'] === '' || $value['default'] === false)) {
if (isset($value['default']) && ($value['default'] === '' || ($value['default'] === false && $value['type'] !== 'boolean'))) {
unset($value['default']);
}
if (empty($value['length'])) {

View file

@ -1634,6 +1634,7 @@ class Model extends Object implements CakeEventListener {
$this->set($data);
if (empty($this->data) && !$this->hasField(array('created', 'updated', 'modified'))) {
$this->whitelist = $_whitelist;
return false;
}
@ -2624,19 +2625,20 @@ class Model extends Object implements CakeEventListener {
/**
* Queries the datasource and returns a result set array.
*
* Also used to perform notation finds, where the first argument is type of find operation to perform
* Used to perform find operations, where the first argument is type of find operation to perform
* (all / first / count / neighbors / list / threaded),
* second parameter options for finding ( indexed array, including: 'conditions', 'limit',
* 'recursive', 'page', 'fields', 'offset', 'order')
* 'recursive', 'page', 'fields', 'offset', 'order', 'callbacks')
*
* Eg:
* {{{
* find('all', array(
* 'conditions' => array('name' => 'Thomas Anderson'),
* 'fields' => array('name', 'email'),
* 'order' => 'field3 DESC',
* 'recursive' => 2,
* 'group' => 'type'
* $model->find('all', array(
* 'conditions' => array('name' => 'Thomas Anderson'),
* 'fields' => array('name', 'email'),
* 'order' => 'field3 DESC',
* 'recursive' => 2,
* 'group' => 'type',
* 'callbacks' => false,
* ));
* }}}
*
@ -2645,32 +2647,43 @@ class Model extends Object implements CakeEventListener {
* joins that should be part of the query.
*
* {{{
* find('all', array(
* 'conditions' => array('name' => 'Thomas Anderson'),
* 'joins' => array(
* array(
* 'alias' => 'Thought',
* 'table' => 'thoughts',
* 'type' => 'LEFT',
* 'conditions' => '`Thought`.`person_id` = `Person`.`id`'
* )
* )
* $model->find('all', array(
* 'conditions' => array('name' => 'Thomas Anderson'),
* 'joins' => array(
* array(
* 'alias' => 'Thought',
* 'table' => 'thoughts',
* 'type' => 'LEFT',
* 'conditions' => '`Thought`.`person_id` = `Person`.`id`'
* )
* )
* ));
* }}}
*
* ### Disabling callbacks
*
* The `callbacks` key allows you to disable or specify the callbacks that should be run. To
* disable beforeFind & afterFind callbacks set `'callbacks' => false` in your options. You can
* also set the callbacks option to 'before' or 'after' to enable only the specified callback.
*
* ### Adding new find types
*
* Behaviors and find types can also define custom finder keys which are passed into find().
* See the documentation for custom find types
* (http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#creating-custom-find-types)
* for how to implement custom find types.
*
* Specifying 'fields' for notation 'list':
*
* - If no fields are specified, then 'id' is used for key and 'model->displayField' is used for value.
* - If a single field is specified, 'id' is used for key and specified field is used for value.
* - If three fields are specified, they are used (in order) for key, value and group.
* - Otherwise, first and second fields are used for key and value.
* - If no fields are specified, then 'id' is used for key and 'model->displayField' is used for value.
* - If a single field is specified, 'id' is used for key and specified field is used for value.
* - If three fields are specified, they are used (in order) for key, value and group.
* - Otherwise, first and second fields are used for key and value.
*
* Note: find(list) + database views have issues with MySQL 5.0. Try upgrading to MySQL 5.1 if you
* have issues with database views.
* Note: find(list) + database views have issues with MySQL 5.0. Try upgrading to MySQL 5.1 if you
* have issues with database views.
*
* Note: find(count) has its own return values.
* Note: find(count) has its own return values.
*
* @param string $type Type of find operation (all / first / count / neighbors / list / threaded)
* @param array $query Option fields (conditions / fields / joins / limit / offset / order / page / group / callbacks)

View file

@ -103,7 +103,9 @@ class CakeRoute {
}
/**
* Compiles the route's regular expression. Modifies defaults property so all necessary keys are set
* Compiles the route's regular expression.
*
* Modifies defaults property so all necessary keys are set
* and populates $this->names with the named routing elements.
*
* @return array Returns a string regular expression of the compiled route.
@ -117,8 +119,10 @@ class CakeRoute {
}
/**
* Builds a route regular expression. Uses the template, defaults and options
* properties to compile a regular expression that can be used to parse request strings.
* Builds a route regular expression.
*
* Uses the template, defaults and options properties to compile a
* regular expression that can be used to parse request strings.
*
* @return void
*/
@ -172,6 +176,7 @@ class CakeRoute {
/**
* Checks to see if the given URL can be parsed by this route.
*
* If the route can be parsed an array of parameters will be returned; if not
* false will be returned. String urls are parsed if they match a routes regular expression.
*
@ -324,8 +329,10 @@ class CakeRoute {
}
/**
* Return true if a given named $param's $val matches a given $rule depending on $context. Currently implemented
* rule types are controller, action and match that can be combined with each other.
* Check if a named parameter matches the current rules.
*
* Return true if a given named $param's $val matches a given $rule depending on $context.
* Currently implemented rule types are controller, action and match that can be combined with each other.
*
* @param string $val The value of the named parameter
* @param array $rule The rule(s) to apply, can also be a match string
@ -379,7 +386,9 @@ class CakeRoute {
}
/**
* Attempt to match a url array. If the url matches the route parameters and settings, then
* Check if a url array matches this route instance.
*
* 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.
* This method handles the reverse routing or conversion of url arrays into string urls.
*
@ -472,7 +481,9 @@ class CakeRoute {
}
/**
* Converts a matching route array into a url string. Composes the string url using the template
* Converts a matching route array into a url string.
*
* Composes the string url using the template
* used to create the route.
*
* @param array $params The params to convert to a string url.

View file

@ -1008,9 +1008,11 @@ class Router {
}
/**
* Reverses a parsed parameter array into a string. Works similarly to Router::url(), but
* Since parsed URL's contain additional 'pass' and 'named' as well as 'url.url' keys.
* Those keys need to be specially handled in order to reverse a params array into a string url.
* Reverses a parsed parameter array into a string.
*
* Works similarly to Router::url(), but since parsed URL's contain additional
* 'pass' and 'named' as well as 'url.url' keys. Those keys need to be specially
* handled in order to reverse a params array into a string url.
*
* This will strip out 'autoRender', 'bare', 'requested', and 'return' param names as those
* are used for CakePHP internals and should not normally be part of an output url.
@ -1043,9 +1045,10 @@ class Router {
}
/**
* Normalizes a URL for purposes of comparison. Will strip the base path off
* and replace any double /'s. It will not unify the casing and underscoring
* of the input value.
* Normalizes a URL for purposes of comparison.
*
* Will strip the base path off and replace any double /'s.
* It will not unify the casing and underscoring of the input value.
*
* @param array|string $url URL to normalize Either an array or a string url.
* @return string Normalized URL
@ -1115,8 +1118,9 @@ class Router {
}
/**
* Instructs the router to parse out file extensions from the URL. For example,
* http://example.com/posts.rss would yield an file extension of "rss".
* Instructs the router to parse out file extensions from the URL.
*
* For example, http://example.com/posts.rss would yield an file extension of "rss".
* The file extension itself is made available in the controller as
* `$this->params['ext']`, and is used by the RequestHandler component to
* automatically switch to alternate layouts and templates, and load helpers
@ -1139,6 +1143,7 @@ class Router {
/**
* Get the list of extensions that can be parsed by Router.
*
* To initially set extensions use `Router::parseExtensions()`
* To add more see `setExtensions()`
*
@ -1154,6 +1159,7 @@ class Router {
/**
* Set/add valid extensions.
*
* To have the extensions parsed you still need to call `Router::parseExtensions()`
*
* @param array $extensions List of extensions to be added as valid extension

View file

@ -495,8 +495,11 @@ class SchemaShellTest extends CakeTestCase {
);
$this->Shell->args = array('SchemaShellTest', 'articles');
$this->Shell->startup();
$this->Shell->expects($this->any())->method('in')->will($this->returnValue('y'));
$this->Shell->expects($this->once())->method('_run')
$this->Shell->expects($this->any())
->method('in')
->will($this->returnValue('y'));
$this->Shell->expects($this->once())
->method('_run')
->with($this->arrayHasKey('articles'), 'update', $this->isInstanceOf('CakeSchema'));
$this->Shell->update();

View file

@ -252,14 +252,16 @@ class ErrorHandlerTest extends CakeTestCase {
/**
* test handleFatalError generating a page.
*
* These tests start two buffers as handleFatalError blows the outer one up.
*
* @return void
*/
public function testHandleFatalErrorPage() {
$this->skipIf(file_exists(APP . 'app_error.php'), 'App error exists cannot run.');
$originalDebugLevel = Configure::read('debug');
$line = __LINE__;
ob_start();
ob_start();
Configure::write('debug', 1);
ErrorHandler::handleFatalError(E_ERROR, 'Something wrong', __FILE__, $line);
@ -268,6 +270,7 @@ class ErrorHandlerTest extends CakeTestCase {
$this->assertContains(__FILE__, $result, 'filename missing.');
$this->assertContains((string)$line, $result, 'line missing.');
ob_start();
ob_start();
Configure::write('debug', 0);
ErrorHandler::handleFatalError(E_ERROR, 'Something wrong', __FILE__, $line);
@ -275,8 +278,6 @@ class ErrorHandlerTest extends CakeTestCase {
$this->assertNotContains('Something wrong', $result, 'message must not appear.');
$this->assertNotContains(__FILE__, $result, 'filename must not appear.');
$this->assertContains('An Internal Error Has Occurred', $result);
Configure::write('debug', $originalDebugLevel);
}
/**

View file

@ -275,6 +275,22 @@ class ModelWriteTest extends BaseModelTest {
Configure::write('Cache.disable', $_back['disable']);
}
/**
* test that save() resets whitelist on failed save
*/
public function testSaveFieldListResetsWhitelistOnFailedSave() {
$this->loadFixtures('Bidding');
$model = new Bidding();
$whitelist = array('title');
$model->whitelist = $whitelist;
$result = $model->save(
array(),
array('fieldList' => array('body'))
);
$this->assertFalse($result);
$this->assertEquals($whitelist, $model->whitelist);
}
/**
* testSaveWithCounterCache method
*

View file

@ -6287,6 +6287,29 @@ class FormHelperTest extends CakeTestCase {
$this->assertContains('data[Contact][published][year]', $result);
}
/**
* testYearAutoExpandRange method
*
* @return void
*/
public function testYearAutoExpandRange() {
$this->Form->request->data['User']['birthday'] = '1930-10-10';
$result = $this->Form->year('User.birthday');
preg_match_all('/<option value="([\d]+)"/', $result, $matches);
$result = $matches[1];
$expected = range(date('Y') + 20, 1930);
$this->assertEquals($result, $expected);
$this->Form->request->data['Project']['release'] = '2050-10-10';
$result = $this->Form->year('Project.release');
preg_match_all('/<option value="([\d]+)"/', $result, $matches);
$result = $matches[1];
$expected = range(2050, date('Y') - 20);
$this->assertEquals($result, $expected);
}
/**
* testTextArea method
*

View file

@ -283,7 +283,11 @@ class CakeTestFixture {
$nested = $db->useNestedTransactions;
$db->useNestedTransactions = false;
$result = $db->insertMulti($this->table, $fields, $values);
if ($this->primaryKey && in_array($this->fields[$this->primaryKey]['type'], array('integer', 'biginteger'))) {
if (
$this->primaryKey &&
isset($this->fields[$this->primaryKey]['type']) &&
in_array($this->fields[$this->primaryKey]['type'], array('integer', 'biginteger'))
) {
$db->resetSequence($this->table, $this->primaryKey);
}
$db->useNestedTransactions = $nested;

View file

@ -819,10 +819,8 @@ class Validation {
*/
protected static function _check($check, $regex) {
if (is_string($regex) && preg_match($regex, $check)) {
self::$errors[] = false;
return true;
} else {
self::$errors[] = true;
return false;
}
}

View file

@ -2127,7 +2127,7 @@ class FormHelper extends AppHelper {
} elseif ($attributes['value'] === false) {
$attributes['value'] = null;
}
$yearOptions = array('min' => $minYear, 'max' => $maxYear, 'order' => 'desc');
$yearOptions = array('value' => $attributes['value'], 'min' => $minYear, 'max' => $maxYear, 'order' => 'desc');
if (isset($attributes['orderYear'])) {
$yearOptions['order'] = $attributes['orderYear'];
unset($attributes['orderYear']);
@ -2764,6 +2764,12 @@ class FormHelper extends AppHelper {
if ($min > $max) {
list($min, $max) = array($max, $min);
}
if (!empty($options['value']) && (int)$options['value'] < $min) {
$min = (int)$options['value'];
} elseif (!empty($options['value']) && (int)$options['value'] > $max) {
$max = (int)$options['value'];
}
for ($i = $min; $i <= $max; $i++) {
$data[$i] = $i;
}