Merge branch 'merger' into 2.0

This commit is contained in:
mark_story 2011-10-01 22:38:39 -04:00
commit aa8965d3f3
16 changed files with 192 additions and 28 deletions

View file

@ -327,7 +327,7 @@ class ViewTask extends BakeTask {
$this->hr();
$this->out(__d('cake_console', 'Controller Name: %s', $this->controllerName));
$this->out(__d('cake_console', 'Action Name: %s', $action));
$this->out(__d('cake_console', 'Path: %s', $this->params['app'] . DS . $this->controllerName . DS . Inflector::underscore($action) . ".ctp"));
$this->out(__d('cake_console', 'Path: %s', $this->params['app'] . DS . 'View' . DS . $this->controllerName . DS . Inflector::underscore($action) . ".ctp"));
$this->hr();
$looksGood = $this->in(__d('cake_console', 'Look okay?'), array('y','n'), 'y');
if (strtolower($looksGood) == 'y') {

View file

@ -1488,7 +1488,7 @@ class DboSource extends DataSource {
$query += array('order' => $assocData['order'], 'limit' => $assocData['limit']);
} else {
$join = array(
'table' => $this->fullTableName($linkModel),
'table' => $linkModel,
'alias' => $association,
'type' => isset($assocData['type']) ? $assocData['type'] : 'LEFT',
'conditions' => trim($this->conditions($conditions, true, false, $model))
@ -1527,7 +1527,7 @@ class DboSource extends DataSource {
$joinKeys = array($assocData['foreignKey'], $assocData['associationForeignKey']);
list($with, $joinFields) = $model->joinModel($assocData['with'], $joinKeys);
$joinTbl = $this->fullTableName($model->{$with});
$joinTbl = $model->{$with};
$joinAlias = $joinTbl;
if (is_array($joinFields) && !empty($joinFields)) {
@ -1537,8 +1537,8 @@ class DboSource extends DataSource {
$joinFields = array();
}
} else {
$joinTbl = $this->fullTableName($assocData['joinTable']);
$joinAlias = $joinTbl;
$joinTbl = $assocData['joinTable'];
$joinAlias = $this->fullTableName($assocData['joinTable']);
}
$query = array(
'conditions' => $assocData['conditions'],
@ -1622,6 +1622,9 @@ class DboSource extends DataSource {
if (!empty($data['conditions'])) {
$data['conditions'] = trim($this->conditions($data['conditions'], true, false));
}
if (!empty($data['table'])) {
$data['table'] = $this->fullTableName($data['table']);
}
return $this->renderJoinStatement($data);
}
@ -1904,7 +1907,7 @@ class DboSource extends DataSource {
if (isset($model->{$assoc}) && $model->useDbConfig == $model->{$assoc}->useDbConfig && $model->{$assoc}->getDataSource()) {
$assocData = $model->getAssociated($assoc);
$join[] = $this->buildJoinStatement(array(
'table' => $this->fullTableName($model->{$assoc}),
'table' => $model->{$assoc},
'alias' => $assoc,
'type' => isset($assocData['type']) ? $assocData['type'] : 'LEFT',
'conditions' => trim($this->conditions(

View file

@ -626,7 +626,7 @@ class CakeEmail {
}
if ($this->_messageId !== false) {
if ($this->_messageId === true) {
$headers['Message-ID'] = '<' . String::UUID() . '@' . env('HTTP_HOST') . '>';
$headers['Message-ID'] = '<' . str_replace('-', '', String::UUID()) . '@' . env('HTTP_HOST') . '>';
} else {
$headers['Message-ID'] = $this->_messageId;
}
@ -639,9 +639,6 @@ class CakeEmail {
$headers['MIME-Version'] = '1.0';
if (!empty($this->_attachments)) {
$headers['Content-Type'] = 'multipart/mixed; boundary="' . $this->_boundary . '"';
$headers[] = 'This part of the E-mail should never be seen. If';
$headers[] = 'you are reading this, consider upgrading your e-mail';
$headers[] = 'client to a MIME-compatible client.';
} elseif ($this->_emailFormat === 'text') {
$headers['Content-Type'] = 'text/plain; charset=' . $this->charset;
} elseif ($this->_emailFormat === 'html') {

View file

@ -852,7 +852,7 @@ HTMLBLOC;
$this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
$result = DebugCompTransport::$lastEmail;
$this->assertPattern('/Message-ID: \<[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}@' . env('HTTP_HOST') . '\>\n/', $result);
$this->assertPattern('/Message-ID: \<[a-f0-9]{8}[a-f0-9]{4}[a-f0-9]{4}[a-f0-9]{4}[a-f0-9]{12}@' . env('HTTP_HOST') . '\>\n/', $result);
$this->Controller->EmailTest->messageId = '<22091985.998877@example.com>';

View file

@ -3503,6 +3503,41 @@ class ContainableBehaviorTest extends CakeTestCase {
$this->assertEqual($expected, $this->Article->hasAndBelongsToMany);
}
/**
* test that bindModel and unbindModel work with find() calls in between.
*/
function testBindMultipleTimesWithFind() {
$binding = array(
'hasOne' => array(
'ArticlesTag' => array(
'foreignKey' => false,
'type' => 'INNER',
'conditions' => array(
'ArticlesTag.article_id = Article.id'
)
),
'Tag' => array(
'type' => 'INNER',
'foreignKey' => false,
'conditions' => array(
'ArticlesTag.tag_id = Tag.id'
)
)
)
);
$this->Article->unbindModel(array('hasAndBelongsToMany' => array('Tag')));
$this->Article->bindModel($binding);
$result = $this->Article->find('all', array('limit' => 1, 'contain' => array('ArticlesTag', 'Tag')));
$this->Article->unbindModel(array('hasAndBelongsToMany' => array('Tag')));
$this->Article->bindModel($binding);
$result = $this->Article->find('all', array('limit' => 1, 'contain' => array('ArticlesTag', 'Tag')));
$associated = $this->Article->getAssociated();
$this->assertEqual('hasAndBelongsToMany', $associated['Tag']);
$this->assertFalse(isset($associated['ArticleTag']));
}
/**
* test that autoFields doesn't splice in fields from other databases.
*

View file

@ -978,6 +978,7 @@ class MysqlTest extends CakeTestCase {
'offset' => array(),
'group' => array()
);
$queryData['joins'][0]['table'] = $this->Dbo->fullTableName($queryData['joins'][0]['table']);
$this->assertEqual($queryData, $expected);
$result = $this->Dbo->generateAssociationQuery($this->Model, $null, null, null, null, $queryData, false, $null);

View file

@ -237,6 +237,44 @@ class ModelIntegrationTest extends BaseModelTest {
$this->assertFalse(isset($TestModel->Behaviors->Tree));
}
/**
* testFindWithJoinsOption method
*
* @access public
* @return void
*/
function testFindWithJoinsOption() {
$this->loadFixtures('Article', 'User');
$TestUser =& new User();
$options = array (
'fields' => array(
'user',
'Article.published',
),
'joins' => array (
array (
'table' => 'articles',
'alias' => 'Article',
'type' => 'LEFT',
'conditions' => array(
'User.id = Article.user_id',
),
),
),
'group' => array('User.user'),
'recursive' => -1,
);
$result = $TestUser->find('all', $options);
$expected = array(
array('User' => array('user' => 'garrett'), 'Article' => array('published' => '')),
array('User' => array('user' => 'larry'), 'Article' => array('published' => 'Y')),
array('User' => array('user' => 'mariano'), 'Article' => array('published' => 'Y')),
array('User' => array('user' => 'nate'), 'Article' => array('published' => ''))
);
$this->assertEqual($result, $expected);
}
/**
* Tests cross database joins. Requires $test and $test2 to both be set in DATABASE_CONFIG
* NOTE: When testing on MySQL, you must set 'persistent' => false on *both* database connections,

View file

@ -4750,7 +4750,7 @@ class ModelReadTest extends BaseModelTest {
*
* @return void
*/
public function bindWithCustomPrimaryKey() {
public function testBindWithCustomPrimaryKey() {
$this->loadFixtures('Story', 'StoriesTag', 'Tag');
$Model = ClassRegistry::init('StoriesTag');
$Model->bindModel(array(
@ -5234,7 +5234,7 @@ class ModelReadTest extends BaseModelTest {
'group' => null,
'joins' => array(array(
'alias' => 'ArticlesTag',
'table' => $this->db->fullTableName('articles_tags'),
'table' => 'articles_tags',
'conditions' => array(
array("ArticlesTag.article_id" => '{$__cakeID__$}'),
array("ArticlesTag.tag_id" => $this->db->identifier('Tag.id'))

View file

@ -399,9 +399,11 @@ class InflectorTest extends CakeTestCase {
$this->assertEquals('Banazzz', Inflector::singularize('Bananas'), 'Was inflected with old rules.');
Inflector::rules('plural', array(
'rules' => array('/(.*)na$/i' => '\1zzz')
'rules' => array('/(.*)na$/i' => '\1zzz'),
'irregular' => array('corpus' => 'corpora')
));
$this->assertEqual('Banazzz', Inflector::pluralize('Banana'), 'Was inflected with old rules.');
$this->assertEqual(Inflector::pluralize('Banana'), 'Banazzz', 'Was inflected with old rules.');
$this->assertEqual(Inflector::pluralize('corpus'), 'corpora', 'Was inflected with old irregular form.');
}
/**

View file

@ -1424,6 +1424,8 @@ class ValidationTest extends CakeTestCase {
$this->assertTrue(Validation::time('12:01am'));
$this->assertTrue(Validation::time('12:01pm'));
$this->assertTrue(Validation::time('1pm'));
$this->assertTrue(Validation::time('1 pm'));
$this->assertTrue(Validation::time('1 PM'));
$this->assertTrue(Validation::time('01:00'));
$this->assertFalse(Validation::time('1:00'));
$this->assertTrue(Validation::time('1:00pm'));

View file

@ -1048,6 +1048,20 @@ class FormHelperTest extends CakeTestCase {
$this->assertTags($result, $expected);
}
/**
* Test form security with Model.field.0 style inputs
*
* @return void
*/
function testFormSecurityArrayFields() {
$key = 'testKey';
$this->Form->request->params['_Token']['key'] = $key;
$this->Form->create('Address');
$this->Form->input('Address.primary.1');
$this->assertEqual('Address.primary', $this->Form->fields[0]);
}
/**
* testFormSecurityMultipleInputDisabledFields method
*
@ -1416,6 +1430,62 @@ class FormHelperTest extends CakeTestCase {
$this->assertTags($result, $expected);
}
/**
* testEmptyErrorValidation method
*
* test validation error div when validation message is an empty string
*
* @access public
* @return void
*/
function testEmptyErrorValidation() {
$this->Form->validationErrors['Contact']['password'] = '';
$result = $this->Form->input('Contact.password');
$expected = array(
'div' => array('class' => 'input password error'),
'label' => array('for' => 'ContactPassword'),
'Password',
'/label',
'input' => array(
'type' => 'password', 'name' => 'data[Contact][password]',
'id' => 'ContactPassword', 'class' => 'form-error'
),
array('div' => array('class' => 'error-message')),
array(),
'/div',
'/div'
);
$this->assertTags($result, $expected);
}
/**
* testEmptyInputErrorValidation method
*
* test validation error div when validation message is overriden by an empty string when calling input()
*
* @access public
* @return void
*/
function testEmptyInputErrorValidation() {
$this->Form->validationErrors['Contact']['password'] = 'Please provide a password';
$result = $this->Form->input('Contact.password', array('error' => ''));
$expected = array(
'div' => array('class' => 'input password error'),
'label' => array('for' => 'ContactPassword'),
'Password',
'/label',
'input' => array(
'type' => 'password', 'name' => 'data[Contact][password]',
'id' => 'ContactPassword', 'class' => 'form-error'
),
array('div' => array('class' => 'error-message')),
array(),
'/div',
'/div'
);
$this->assertTags($result, $expected);
}
/**
* testFormValidationAssociated method
*

View file

@ -319,7 +319,11 @@ class Inflector {
if ($reset) {
self::${$var}[$rule] = $pattern;
} else {
if ($rule === 'uninflected') {
self::${$var}[$rule] = array_merge($pattern, self::${$var}[$rule]);
} else {
self::${$var}[$rule] = $pattern + self::${$var}[$rule];
}
}
unset($rules[$rule], self::${$var}['cache' . ucfirst($rule)]);
if (isset(self::${$var}['merged'][$rule])) {
@ -332,7 +336,7 @@ class Inflector {
}
}
}
self::${$var}['rules'] = array_merge($rules, self::${$var}['rules']);
self::${$var}['rules'] = $rules + self::${$var}['rules'];
break;
}
}

View file

@ -356,7 +356,7 @@ class Validation {
* @return boolean Success
*/
public static function time($check) {
return self::_check($check, '%^((0?[1-9]|1[012])(:[0-5]\d){0,2}([AP]M|[ap]m))$|^([01]\d|2[0-3])(:[0-5]\d){0,2}$%');
return self::_check($check, '%^((0?[1-9]|1[012])(:[0-5]\d){0,2} ?([AP]M|[ap]m))$|^([01]\d|2[0-3])(:[0-5]\d){0,2}$%');
}
/**

View file

@ -18,4 +18,3 @@
// +--------------------------------------------------------------------------------------------+ //
////////////////////////////////////////////////////////////////////////////////////////////////////
2.0.0-RC2

View file

@ -621,7 +621,7 @@ class Helper extends Object {
$entity = $this->entity();
if (!empty($data) && !empty($entity)) {
$result = Set::extract($data, implode('.', $entity));
$result = Set::extract(implode('.', $entity), $data);
}
$habtmKey = $this->field();
@ -666,7 +666,7 @@ class Helper extends Object {
$options = $this->_name($options);
$options = $this->value($options);
$options = $this->domId($options);
if ($this->tagIsInvalid()) {
if ($this->tagIsInvalid() !== false) {
$options = $this->addClass($options, 'form-error');
}
return $options;

View file

@ -271,18 +271,24 @@ class FormHelper extends AppHelper {
* Returns false if given form field described by the current entity has no errors.
* Otherwise it returns the validation message
*
* @return boolean True on errors.
* @return mixed Either false when there or no errors, or the error
* string. The error string could be ''.
*/
public function tagIsInvalid() {
$entity = $this->entity();
$model = array_shift($entity);
$errors = array();
if (!empty($entity) && isset($this->validationErrors[$model])) {
return Set::classicExtract($this->validationErrors[$model], join('.', $entity));
$errors = $this->validationErrors[$model];
}
if (!empty($entity)) {
if (!empty($entity) && empty($errors)) {
$errors = $this->_introspectModel($model, 'errors');
return ($errors) ? Set::classicExtract($errors, join('.', $entity)) : false;
}
if (empty($errors)) {
return false;
}
$error = Set::classicExtract($errors, join('.', $entity));
return $error === null ? false : $error;
}
/**
@ -598,6 +604,11 @@ class FormHelper extends AppHelper {
}
}
$last = end($field);
if (is_numeric($last) || empty($last)) {
array_pop($field);
}
$field = implode('.', $field);
if ($lock) {
@ -645,7 +656,9 @@ class FormHelper extends AppHelper {
$defaults = array('wrap' => true, 'class' => 'error-message', 'escape' => true);
$options = array_merge($defaults, $options);
$this->setEntity($field);
if (!$error = $this->tagIsInvalid()) {
$error = $this->tagIsInvalid();
if ($error === false) {
return null;
}
if (is_array($text)) {
@ -664,7 +677,7 @@ class FormHelper extends AppHelper {
$text = $tmp;
}
if ($text != null) {
if ($text !== null) {
$error = $text;
}
if (is_array($error)) {