Browse Source

Merge pull request #5151 from dakota/3.0-count-beforefind

Fixes #5150
José Lorenzo Rodríguez 11 years ago
parent
commit
1c78d45cc7
2 changed files with 63 additions and 3 deletions
  1. 15 3
      src/ORM/Query.php
  2. 48 0
      tests/TestCase/ORM/QueryTest.php

+ 15 - 3
src/ORM/Query.php

@@ -481,7 +481,7 @@ class Query extends DatabaseQuery implements JsonSerializable {
 	}
 
 /**
- * Creates a copy of this current query and resets some state.
+ * Creates a copy of this current query, triggers beforeFind and resets some state.
  *
  * The following state will be cleared:
  *
@@ -499,6 +499,7 @@ class Query extends DatabaseQuery implements JsonSerializable {
  */
 	public function cleanCopy() {
 		$query = clone $this;
+		$query->triggerBeforeFind();
 		$query->autoFields(false);
 		$query->limit(null);
 		$query->order([], true);
@@ -610,14 +611,25 @@ class Query extends DatabaseQuery implements JsonSerializable {
 	}
 
 /**
- * {@inheritDoc}
+ * Trigger the beforeFind event on the query's repository object.
+ *
+ * Will not trigger more than once, and only for select queries.
+ *
+ * @return void
  */
-	public function sql(ValueBinder $binder = null) {
+	public function triggerBeforeFind() {
 		if (!$this->_beforeFindFired && $this->_type === 'select') {
 			$table = $this->repository();
 			$table->dispatchEvent('Model.beforeFind', [$this, $this->_options, !$this->eagerLoaded()]);
 			$this->_beforeFindFired = true;
 		}
+	}
+
+/**
+ * {@inheritDoc}
+ */
+	public function sql(ValueBinder $binder = null) {
+		$this->triggerBeforeFind();
 
 		$this->_transformQuery();
 		$sql = parent::sql($binder);

+ 48 - 0
tests/TestCase/ORM/QueryTest.php

@@ -1327,6 +1327,26 @@ class QueryTest extends TestCase {
 	}
 
 /**
+ * test count with a beforeFind.
+ *
+ * @return void
+ */
+	public function testCountBeforeFind() {
+		$table = TableRegistry::get('Articles');
+		$table->hasMany('Comments');
+		$table->eventManager()
+			->attach(function ($event, $query) {
+				$query
+					->limit(1)
+					->order(['Articles.title' => 'DESC']);
+			}, 'Model.beforeFind');
+
+		$query = $table->find();
+		$result = $query->count();
+		$this->assertSame(3, $result);
+	}
+
+/**
  * Test that count() returns correct results with group by.
  *
  * @return void
@@ -2120,6 +2140,34 @@ class QueryTest extends TestCase {
 	}
 
 /**
+ * test that cleanCopy makes a cleaned up clone with a beforeFind.
+ *
+ * @return void
+ */
+	public function testCleanCopyBeforeFind() {
+		$table = TableRegistry::get('Articles');
+		$table->hasMany('Comments');
+		$table->eventManager()
+			->attach(function ($event, $query) {
+				$query
+					->limit(5)
+					->order(['Articles.title' => 'DESC']);
+			}, 'Model.beforeFind');
+
+		$query = $table->find();
+		$query->offset(10)
+			->limit(1)
+			->order(['Articles.id' => 'DESC'])
+			->contain(['Comments']);
+		$copy = $query->cleanCopy();
+
+		$this->assertNotSame($copy, $query);
+		$this->assertNull($copy->clause('offset'));
+		$this->assertNull($copy->clause('limit'));
+		$this->assertNull($copy->clause('order'));
+	}
+
+/**
  * Test that finder options sent through via contain are sent to custom finder.
  *
  * @return void