Browse Source

Allow countercache to skip updates sometimes.

Merge branch 'issue-11460' into 3.next, enabling lambda functions
to disable updates to counter values by returning `false`.

Refs #11460
Mark Story 8 years ago
parent
commit
66633f741d

+ 10 - 3
src/ORM/Behavior/CounterCacheBehavior.php

@@ -63,6 +63,7 @@ use RuntimeException;
  *
  * Counter cache using lambda function returning the count
  * This is equivalent to example #2
+ *
  * ```
  * [
  *     'Users' => [
@@ -77,6 +78,9 @@ use RuntimeException;
  * ]
  * ```
  *
+ * When using a lambda function you can return `false` to disable updating the counter value
+ * for the current operation.
+ *
  * Ignore updating the field if it is dirty
  * ```
  * [
@@ -238,8 +242,9 @@ class CounterCacheBehavior extends Behavior
             } else {
                 $count = $this->_getCount($config, $countConditions);
             }
-
-            $assoc->getTarget()->updateAll([$field => $count], $updateConditions);
+            if ($count !== false) {
+                $assoc->getTarget()->updateAll([$field => $count], $updateConditions);
+            }
 
             if (isset($updateOriginalConditions)) {
                 if (is_callable($config)) {
@@ -250,7 +255,9 @@ class CounterCacheBehavior extends Behavior
                 } else {
                     $count = $this->_getCount($config, $countOriginalConditions);
                 }
-                $assoc->getTarget()->updateAll([$field => $count], $updateOriginalConditions);
+                if ($count !== false) {
+                    $assoc->getTarget()->updateAll([$field => $count], $updateOriginalConditions);
+                }
             }
         }
     }

+ 31 - 0
tests/TestCase/ORM/Behavior/CounterCacheBehaviorTest.php

@@ -331,6 +331,37 @@ class CounterCacheBehaviorTest extends TestCase
     }
 
     /**
+     * Testing counter cache with lambda returning false
+     *
+     * @return void
+     */
+    public function testLambdaFalse()
+    {
+        $this->post->belongsTo('Users');
+
+        $table = $this->post;
+        $entity = $this->_getEntity();
+
+        $this->post->addBehavior('CounterCache', [
+            'Users' => [
+                'posts_published' => function (Event $orgEvent, EntityInterface $orgEntity, Table $orgTable) use ($entity, $table) {
+                    $this->assertSame($orgTable, $table);
+                    $this->assertSame($orgEntity, $entity);
+
+                    return false;
+                }
+            ]
+        ]);
+
+        $before = $this->_getUser();
+        $this->post->save($entity);
+        $after = $this->_getUser();
+
+        $this->assertEquals(1, $before->get('posts_published'));
+        $this->assertEquals(1, $after->get('posts_published'));
+    }
+
+    /**
      * Testing counter cache with lambda returning number and changing of related ID
      *
      * @return void