Permalink
Browse files

Implemented feature to allow multiple counter caches per associated m…

…odel.
  • Loading branch information...
1 parent 54e1de9 commit c3884f407f86d892cdd723c50571bbcf6a27f4ee @ADmad ADmad committed Aug 17, 2011
View
@@ -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

ceeram Apr 24, 2014

Member

What is this line doing?

@ADmad

ADmad Apr 25, 2014

Member

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

@jippi

jippi Apr 25, 2014

Member

worst memory ever @ADmad

+ }
+ $count = intval($this->find('count', compact('conditions', 'recursive')));
+
+ $this->{$parent}->updateAll(
+ array($field => $count),
+ array($this->{$parent}->escapeField() => $keys[$foreignKey])
+ );
+ }
}
}
}
@@ -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
@@ -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),
);
}
@@ -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),
);
}

0 comments on commit c3884f4

Please sign in to comment.