Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implemented feature to allow multiple counter caches per associated m…

…odel.
  • Loading branch information...
commit c3884f407f86d892cdd723c50571bbcf6a27f4ee 1 parent 54e1de9
@ADmad ADmad authored
View
80 lib/Cake/Model/Model.php
@@ -1532,45 +1532,59 @@ public function updateCounterCache($keys = array(), $created = false) {
$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 (!is_array($assoc['counterCache'])) {
+ if (isset($assoc['counterScope'])) {
+ $assoc['counterCache'] = array($assoc['counterCache'] => $assoc['counterScope']);
+ } else {
+ $assoc['counterCache'] = array($assoc['counterCache'] => array());
+ }
}
- if (!array_key_exists($foreignKey, $keys)) {
- $keys[$foreignKey] = $this->field($foreignKey);
- }
- $recursive = (isset($assoc['counterScope']) ? 0 : -1);
- $conditions = ($recursive === 0) ? (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])
- );
+ $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;
}
- }
- $conditions[$fkQuoted] = $keys[$foreignKey];
- if ($recursive === 0) {
- $conditions = array_merge($conditions, (array)$assoc['counterScope']);
- }
- $count = intval($this->find('count', compact('conditions', 'recursive')));
+ if (!array_key_exists($foreignKey, $keys)) {
+ $keys[$foreignKey] = $this->field($foreignKey);
+ }
+ $recursive = (empty($conditions) ? -1 : 0);
- $this->{$parent}->updateAll(
- array($assoc['counterCache'] => $count),
- array($this->{$parent}->escapeField() => $keys[$foreignKey])
- );
+ 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);
@ceeram Collaborator
ceeram added a note

What is this line doing?

@ADmad Collaborator
ADmad added a note

Your guess is good as mine, the commit was done 3 years ago :smile:

@jippi Collaborator
jippi added a note

worst memory ever @ADmad

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+ $count = intval($this->find('count', compact('conditions', 'recursive')));
+
+ $this->{$parent}->updateAll(
+ array($field => $count),
+ array($this->{$parent}->escapeField() => $keys[$foreignKey])
+ );
+ }
}
}
}
View
64 lib/Cake/Test/Case/Model/ModelWriteTest.php
@@ -469,6 +469,70 @@ public function testSaveWithCounterCacheScope() {
}
/**
+ * 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.
*
* @return void
View
8 lib/Cake/Test/Fixture/CounterCachePostFixture.php
@@ -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
7 lib/Cake/Test/Fixture/CounterCacheUserFixture.php
@@ -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),
);
}
@ceeram

What is this line doing?

@ADmad

Your guess is good as mine, the commit was done 3 years ago :smile:

@jippi

worst memory ever @ADmad

Please sign in to comment.
Something went wrong with that request. Please try again.