Browse Source

Fix table callback argument types

Fixes docblocks and `Model.beforeFind` event argument types, and
adds a test to ensure that the callbacks receive the expected types
of arguments.
ndm2 11 years ago
parent
commit
0e2a3bc426
3 changed files with 83 additions and 3 deletions
  1. 6 1
      src/ORM/Query.php
  2. 2 2
      src/ORM/Table.php
  3. 75 0
      tests/TestCase/ORM/TableTest.php

+ 6 - 1
src/ORM/Query.php

@@ -14,6 +14,7 @@
  */
 namespace Cake\ORM;
 
+use ArrayObject;
 use Cake\Database\Query as DatabaseQuery;
 use Cake\Database\ValueBinder;
 use Cake\Datasource\QueryTrait;
@@ -603,7 +604,11 @@ class Query extends DatabaseQuery implements JsonSerializable
     {
         if (!$this->_beforeFindFired && $this->_type === 'select') {
             $table = $this->repository();
-            $table->dispatchEvent('Model.beforeFind', [$this, $this->_options, !$this->eagerLoaded()]);
+            $table->dispatchEvent('Model.beforeFind', [
+                $this,
+                new ArrayObject($this->_options),
+                !$this->eagerLoaded()
+            ]);
             $this->_beforeFindFired = true;
         }
     }

+ 2 - 2
src/ORM/Table.php

@@ -95,7 +95,7 @@ use RuntimeException;
  *   Fired before an entity is validated using the rules checker. By stopping this event,
  *   you can return the final value of the rules checking operation.
  *
- * - `afterRules(Event $event, Entity $entity,RulesChecker $rules, bool $result)`
+ * - `afterRules(Event $event, Entity $entity, ArrayObject $options, bool $result, string $operation)`
  *   Fired after the rules have been checked on the entity. By stopping this event,
  *   you can return the final value of the rules checking operation.
  *
@@ -1295,7 +1295,7 @@ class Table implements RepositoryInterface, EventListenerInterface
      * Performs the actual saving of an entity based on the passed options.
      *
      * @param \Cake\Datasource\EntityInterface $entity the entity to be saved
-     * @param array $options the options to use for the save operation
+     * @param \ArrayObject $options the options to use for the save operation
      * @return \Cake\Datasource\EntityInterface|bool
      * @throws \RuntimeException When an entity is missing some of the primary keys.
      */

+ 75 - 0
tests/TestCase/ORM/TableTest.php

@@ -14,13 +14,18 @@
  */
 namespace Cake\Test\TestCase\ORM;
 
+use ArrayObject;
 use Cake\Core\Configure;
 use Cake\Database\Expression\OrderByExpression;
 use Cake\Database\Expression\QueryExpression;
 use Cake\Database\TypeMap;
 use Cake\Datasource\ConnectionManager;
+use Cake\Event\Event;
 use Cake\Event\EventManager;
 use Cake\I18n\Time;
+use Cake\ORM\Entity;
+use Cake\ORM\Query;
+use Cake\ORM\RulesChecker;
 use Cake\ORM\Table;
 use Cake\ORM\TableRegistry;
 use Cake\TestSuite\TestCase;
@@ -3377,4 +3382,74 @@ class TableTest extends TestCase
         $data = ['username' => 'jose'];
         $this->assertEmpty($validator->errors($data));
     }
+
+    /**
+     * Tests that the callbacks receive the expected types of arguments.
+     *
+     * @return void
+     */
+    public function testCallbackArgumentTypes()
+    {
+        $table = TableRegistry::get('articles');
+        $eventManager = $table->eventManager();
+
+        $eventManager->attach(
+            function (Event $event, Query $query, ArrayObject $options, $primary) {
+                $this->assertTrue(is_bool($primary));
+            },
+            'Model.beforeFind'
+        );
+        $table->find()->first();
+
+        $eventManager->attach(
+            function (Event $event, Validator $validator, $name) {
+                $this->assertTrue(is_string($name));
+            },
+            'Model.buildValidator'
+        );
+        $table->validator();
+
+        $eventManager->attach(
+            function (Event $event, RulesChecker $rules) {
+            },
+            'Model.buildRules'
+        );
+        $eventManager->attach(
+            function (Event $event, Entity $entity, ArrayObject $options, $operation) {
+                $this->assertTrue(is_string($operation));
+            },
+            'Model.beforeRules'
+        );
+        $eventManager->attach(
+            function (Event $event, Entity $entity, ArrayObject $options, $result, $operation) {
+                $this->assertTrue(is_bool($result));
+                $this->assertTrue(is_string($operation));
+            },
+            'Model.afterRules'
+        );
+        $eventManager->attach(
+            function (Event $event, Entity $entity, ArrayObject $options) {
+            },
+            'Model.beforeSave'
+        );
+        $eventManager->attach(
+            function (Event $event, Entity $entity, ArrayObject $options) {
+            },
+            'Model.afterSave'
+        );
+        $entity = new Entity(['title' => 'Title']);
+        $this->assertNotFalse($table->save($entity));
+
+        $eventManager->attach(
+            function (Event $event, Entity $entity, ArrayObject $options) {
+            },
+            'Model.beforeDelete'
+        );
+        $eventManager->attach(
+            function (Event $event, Entity $entity, ArrayObject $options) {
+            },
+            'Model.afterDelete'
+        );
+        $this->assertTrue($table->delete($entity));
+    }
 }