Merge remote-tracking branch 'origin/2.0' into 2.0-api-doc

Conflicts:
	lib/Cake/Model/Model.php
	lib/Cake/View/Helper/CacheHelper.php
This commit is contained in:
Juan Basso 2011-08-20 01:47:27 -04:00
commit a1a049c700
13 changed files with 217 additions and 59 deletions

View file

@ -191,7 +191,28 @@ class MemcacheEngine extends CacheEngine {
* @return boolean True if the cache was successfully cleared, false otherwise
*/
public function clear($check) {
return $this->_Memcache->flush();
if ($check) {
return true;
}
foreach ($this->_Memcache->getExtendedStats('slabs') as $slabs) {
foreach (array_keys($slabs) as $slabId) {
if (!is_numeric($slabId)) {
continue;
}
foreach ($this->_Memcache->getExtendedStats('cachedump', $slabId) as $stats) {
if (!is_array($stats)) {
continue;
}
foreach (array_keys($stats) as $key) {
if (strpos($key, $this->settings['prefix']) === 0) {
$this->_Memcache->delete($key);
}
}
}
}
}
return true;
}
/**

View file

@ -333,7 +333,7 @@ class EmailComponent extends Component {
$lib->attachments($this->_formatAttachFiles());
}
$lib->transport($this->delivery);
$lib->transport(ucfirst($this->delivery));
if ($this->delivery === 'mail') {
$lib->config(array('eol' => $this->lineFeed, 'additionalParameters' => $this->additionalParams));
} elseif ($this->delivery === 'smtp') {

View file

@ -1759,45 +1759,59 @@ class Model extends Object {
$keys['old'] = isset($keys['old']) ? $keys['old'] : array();
foreach ($this->belongsTo as $parent => $assoc) {
$foreignKey = $assoc['foreignKey'];
$fkQuoted = $this->escapeField($assoc['foreignKey']);
if (!empty($assoc['counterCache'])) {
if ($assoc['counterCache'] === true) {
$assoc['counterCache'] = Inflector::underscore($this->alias) . '_count';
}
if (!$this->{$parent}->hasField($assoc['counterCache'])) {
continue;
}
if (!array_key_exists($foreignKey, $keys)) {
$keys[$foreignKey] = $this->field($foreignKey);
}
$recursive = (isset($assoc['counterScope']) ? 1 : -1);
$conditions = ($recursive == 1) ? (array)$assoc['counterScope'] : array();
if (isset($keys['old'][$foreignKey])) {
if ($keys['old'][$foreignKey] != $keys[$foreignKey]) {
$conditions[$fkQuoted] = $keys['old'][$foreignKey];
$count = intval($this->find('count', compact('conditions', 'recursive')));
$this->{$parent}->updateAll(
array($assoc['counterCache'] => $count),
array($this->{$parent}->escapeField() => $keys['old'][$foreignKey])
);
if (!is_array($assoc['counterCache'])) {
if (isset($assoc['counterScope'])) {
$assoc['counterCache'] = array($assoc['counterCache'] => $assoc['counterScope']);
} else {
$assoc['counterCache'] = array($assoc['counterCache'] => array());
}
}
$conditions[$fkQuoted] = $keys[$foreignKey];
if ($recursive == 1) {
$conditions = array_merge($conditions, (array)$assoc['counterScope']);
$foreignKey = $assoc['foreignKey'];
$fkQuoted = $this->escapeField($assoc['foreignKey']);
foreach ($assoc['counterCache'] as $field => $conditions) {
if (!is_string($field)) {
$field = Inflector::underscore($this->alias) . '_count';
}
if (!$this->{$parent}->hasField($field)) {
continue;
}
if ($conditions === true) {
$conditions = array();
} else {
$conditions = (array)$conditions;
}
if (!array_key_exists($foreignKey, $keys)) {
$keys[$foreignKey] = $this->field($foreignKey);
}
$recursive = (empty($conditions) ? -1 : 0);
if (isset($keys['old'][$foreignKey])) {
if ($keys['old'][$foreignKey] != $keys[$foreignKey]) {
$conditions[$fkQuoted] = $keys['old'][$foreignKey];
$count = intval($this->find('count', compact('conditions', 'recursive')));
$this->{$parent}->updateAll(
array($field => $count),
array($this->{$parent}->escapeField() => $keys['old'][$foreignKey])
);
}
}
$conditions[$fkQuoted] = $keys[$foreignKey];
if ($recursive === 0) {
$conditions = array_merge($conditions, (array)$conditions);
}
$count = intval($this->find('count', compact('conditions', 'recursive')));
$this->{$parent}->updateAll(
array($field => $count),
array($this->{$parent}->escapeField() => $keys[$foreignKey])
);
}
$count = intval($this->find('count', compact('conditions', 'recursive')));
$this->{$parent}->updateAll(
array($assoc['counterCache'] => $count),
array($this->{$parent}->escapeField() => $keys[$foreignKey])
);
}
}
}
@ -2180,15 +2194,25 @@ class Model extends Object {
$this->_deleteLinks($id);
$this->id = $id;
$updateCounterCache = false;
if (!empty($this->belongsTo)) {
foreach ($this->belongsTo as $parent => $assoc) {
if (!empty($assoc['counterCache'])) {
$updateCounterCache = true;
break;
}
}
$keys = $this->find('first', array(
'fields' => $this->_collectForeignKeys(),
'conditions' => array($this->alias . '.' . $this->primaryKey => $id)
'conditions' => array($this->alias . '.' . $this->primaryKey => $id),
'recursive' => -1,
'callbacks' => false
));
}
if ($db->delete($this, array($this->alias . '.' . $this->primaryKey => $id))) {
if (!empty($this->belongsTo)) {
if ($updateCounterCache) {
$this->updateCounterCache($keys[$this->alias]);
}
$this->Behaviors->trigger('afterDelete', array(&$this));
@ -2255,7 +2279,8 @@ class Model extends Object {
$records = $this->{$joinModel}->find('all', array(
'conditions' => array_merge(array($this->{$joinModel}->escapeField($data['foreignKey']) => $id)),
'fields' => $this->{$joinModel}->primaryKey,
'recursive' => -1
'recursive' => -1,
'callbacks' => false
));
if (!empty($records)) {
foreach ($records as $record) {

View file

@ -334,11 +334,24 @@ class MemcacheEngineTest extends CakeTestCase {
* @return void
*/
public function testClear() {
Cache::write('some_value', 'value', 'memcache');
Cache::config('memcache2', array(
'engine' => 'Memcache',
'prefix' => 'cake2_',
'duration' => 3600
));
Cache::write('some_value', 'cache1', 'memcache');
$result = Cache::clear(true, 'memcache');
$this->assertTrue($result);
$this->assertEquals('cache1', Cache::read('some_value', 'memcache'));
Cache::write('some_value', 'cache2', 'memcache2');
$result = Cache::clear(false, 'memcache');
$this->assertTrue($result);
$this->assertFalse(Cache::read('some_value', 'memcache'));
$this->assertEquals('cache2', Cache::read('some_value', 'memcache2'));
Cache::clear(false, 'memcache2');
}
/**
* test that a 0 duration can succesfully write.

View file

@ -458,7 +458,7 @@ class SecurityComponentTest extends CakeTestCase {
*
* @return void
*/
function testValidatePostNoSession() {
public function testValidatePostNoSession() {
$this->Controller->Security->startup($this->Controller);
$this->Controller->Session->delete('_Token');

View file

@ -457,6 +457,70 @@ class ModelWriteTest extends BaseModelTest {
$this->assertEquals($result['Syfile']['item_count'], 1);
}
/**
* Tests having multiple counter caches for an associated model
*
* @access public
* @return void
*/
public function testCounterCacheMultipleCaches() {
$this->loadFixtures('CounterCacheUser', 'CounterCachePost');
$User = new CounterCacheUser();
$Post = new CounterCachePost();
$Post->unbindModel(array('belongsTo' => array('User')), false);
$Post->bindModel(array(
'belongsTo' => array(
'User' => array(
'className' => 'CounterCacheUser',
'foreignKey' => 'user_id',
'counterCache' => array(
true,
'posts_published' => array('Post.published' => true)
)
)
)
), false);
// Count Increase
$user = $User->find('first', array(
'conditions' => array('id' => 66),
'recursive' => -1
));
$data = array('Post' => array(
'id' => 22,
'title' => 'New Post',
'user_id' => 66,
'published' => true
));
$Post->save($data);
$result = $User->find('first', array(
'conditions' => array('id' => 66),
'recursive' => -1
));
$this->assertEquals(3, $result[$User->alias]['post_count']);
$this->assertEquals(2, $result[$User->alias]['posts_published']);
// Count decrease
$Post->delete(1);
$result = $User->find('first', array(
'conditions' => array('id' => 66),
'recursive' => -1
));
$this->assertEquals(2, $result[$User->alias]['post_count']);
$this->assertEquals(2, $result[$User->alias]['posts_published']);
// Count update
$data = $Post->find('first', array(
'conditions' => array('id' => 1),
'recursive' => -1
));
$data[$Post->alias]['user_id'] = 301;
$Post->save($data);
$result = $User->find('all',array('order' => 'User.id'));
$this->assertEquals(2, $result[0]['User']['post_count']);
$this->assertEquals(1, $result[1]['User']['posts_published']);
}
/**
* test that beforeValidate returning false can abort saves.
*

View file

@ -317,8 +317,13 @@ class CacheHelperTest extends CakeTestCase {
@unlink($filename);
}
function testCacheCallbacks() {
/**
* Test that callback code is generated correctly.
*
* @return void
*/
public function testCacheCallbacks() {
$this->Controller->cache_parsing();
$this->Controller->params = array(
'controller' => 'cache_test',

View file

@ -799,7 +799,7 @@ class FormHelperTest extends CakeTestCase {
}
/**
* Tests correct generation of text fields for double and float fields
* Tests correct generation of number fields for double and float fields
*
* @return void
*/
@ -815,20 +815,39 @@ class FormHelperTest extends CakeTestCase {
$this->Form->create('Contact');
$result = $this->Form->input('foo');
$expected = array(
'div' => array('class' => 'input text'),
'div' => array('class' => 'input number'),
'label' => array('for' => 'ContactFoo'),
'Foo',
'/label',
array('input' => array(
'type' => 'text', 'name' => 'data[Contact][foo]',
'id' => 'ContactFoo'
'type' => 'number',
'name' => 'data[Contact][foo]',
'id' => 'ContactFoo',
'step' => 'any'
)),
'/div'
);
$this->assertTags($result, $expected);
$result = $this->Form->input('foo', array('step' => 0.5));
$expected = array(
'div' => array('class' => 'input number'),
'label' => array('for' => 'ContactFoo'),
'Foo',
'/label',
array('input' => array(
'type' => 'number',
'name' => 'data[Contact][foo]',
'id' => 'ContactFoo',
'step' => '0.5'
)),
'/div'
);
$this->assertTags($result, $expected);
}
/**
* Tests correct generation of text fields for double and float fields
* Tests correct generation of number fields for integer fields
*
* @access public
* @return void
@ -845,7 +864,7 @@ class FormHelperTest extends CakeTestCase {
$this->Form->create('Contact');
$result = $this->Form->input('foo');
$expected = array(
'div' => array('class' => 'input text'),
'div' => array('class' => 'input number'),
'label' => array('for' => 'ContactFoo'),
'Foo',
'/label',
@ -855,6 +874,7 @@ class FormHelperTest extends CakeTestCase {
)),
'/div'
);
$this->assertTags($result, $expected);
}
/**

View file

@ -30,11 +30,13 @@ class CounterCachePostFixture extends CakeTestFixture {
'id' => array('type' => 'integer', 'key' => 'primary'),
'title' => array('type' => 'string', 'length' => 255, 'null' => false),
'user_id' => array('type' => 'integer', 'null' => true),
'user_id' => array('type' => 'integer', 'null' => true),
'published' => array('type' => 'boolean', 'null' => false)
);
public $records = array(
array('id' => 1, 'title' => 'Rock and Roll', 'user_id' => 66),
array('id' => 2, 'title' => 'Music', 'user_id' => 66),
array('id' => 3, 'title' => 'Food', 'user_id' => 301),
array('id' => 1, 'title' => 'Rock and Roll', 'user_id' => 66, 'published' => false),
array('id' => 2, 'title' => 'Music', 'user_id' => 66, 'published' => true),
array('id' => 3, 'title' => 'Food', 'user_id' => 301, 'published' => true),
);
}

View file

@ -29,11 +29,12 @@ class CounterCacheUserFixture extends CakeTestFixture {
public $fields = array(
'id' => array('type' => 'integer', 'key' => 'primary'),
'name' => array('type' => 'string', 'length' => 255, 'null' => false),
'post_count' => array('type' => 'integer', 'null' => true)
'post_count' => array('type' => 'integer', 'null' => true),
'posts_published' => array('type' => 'integer', 'null' => true)
);
public $records = array(
array('id' => 66, 'name' => 'Alexander','post_count' => 2),
array('id' => 301, 'name' => 'Steven','post_count' => 1),
array('id' => 66, 'name' => 'Alexander', 'post_count' => 2, 'posts_published' => 1),
array('id' => 301, 'name' => 'Steven', 'post_count' => 1, 'posts_published' => 1),
);
}

View file

@ -1,2 +1,2 @@
<?php echo $xml->header(); ?>
<?php echo $content_for_layout; ?>
<?php echo '<?xml version="1.0" encoding="' . Configure::read('App.encoding') . '"?>'; ?>
<?php echo $content_for_layout; ?>

View file

@ -933,6 +933,13 @@ class FormHelper extends AppHelper {
if ($fieldKey == $primaryKey) {
$options['type'] = 'hidden';
}
if (
$options['type'] === 'number' &&
$type === 'float' &&
!isset($options['step'])
) {
$options['step'] = 'any';
}
}
if (preg_match('/_id$/', $fieldKey) && $options['type'] !== 'hidden') {
$options['type'] = 'select';

View file

@ -1,2 +1,2 @@
<?php echo $this->Xml->header(); ?>
<?php echo $content_for_layout; ?>
<?php echo '<?xml version="1.0" encoding="' . Configure::read('App.encoding') . '"?>'; ?>
<?php echo $content_for_layout; ?>