ソースを参照

Not overwriting the limit clause if there is one already in the passed
query

Jose Lorenzo Rodriguez 12 年 前
コミット
1f6fe1d005

+ 5 - 9
src/Controller/Component/PaginatorComponent.php

@@ -128,7 +128,7 @@ class PaginatorComponent extends Component {
  *
  * Would paginate using the `find('popular')` method.
  *
- * @param Table $object The table to paginate.
+ * @param Cake\Datasource\RepositoryInterface|Cake\ORM\Query $object The table or query to paginate.
  * @param array $settings The settings/configuration used for pagination.
  * @return array Query results
  * @throws \Cake\Error\NotFoundException
@@ -154,7 +154,8 @@ class PaginatorComponent extends Component {
 			$query = $object->find($type);
 		}
 
-		$query->applyOptions($options);
+		$limit = $query->clause('limit');
+		$query->applyOptions(array_filter(compact('limit')) + $options);
 		$results = $query->all();
 		$numResults = count($results);
 		$count = $numResults ? $query->count() : 0;
@@ -169,12 +170,7 @@ class PaginatorComponent extends Component {
 		$page = max(min($page, $pageCount), 1);
 		$request = $this->_registry->getController()->request;
 
-		$order = $options['order'];
-		if (!is_array($options)) {
-			$order = (array)$order;
-		}
-
-		reset($order);
+		$order = (array)$options['order'];
 		$sortDefault = $directionDefault = false;
 		if (!empty($defaults['order']) && count($defaults['order']) == 1) {
 			$sortDefault = key($defaults['order']);
@@ -197,7 +193,7 @@ class PaginatorComponent extends Component {
 		);
 
 		if (!isset($request['paging'])) {
-			$request['paging'] = array();
+			$request['paging'] = [];
 		}
 		$request['paging'] = array_merge(
 			(array)$request['paging'],

+ 33 - 0
tests/TestCase/Controller/Component/PaginatorComponentTest.php

@@ -761,6 +761,39 @@ class PaginatorComponentTest extends TestCase {
 	}
 
 /**
+ * Tests that passing a query object with a limit clause set will not
+ * overwrite it with the passed defaults.
+ *
+ * @return void
+ */
+	public function testPaginateQueryWithLimit() {
+		$this->request->query = array('page' => '-1');
+		$settings = array(
+			'PaginatorPosts' => array(
+				'contain' => array('PaginatorAuthor'),
+				'maxLimit' => 10,
+				'limit' => 5,
+				'group' => 'PaginatorPosts.published',
+				'order' => array('PaginatorPosts.id' => 'ASC')
+			)
+		);
+		$table = $this->_getMockPosts(['find']);
+		$query = $this->_getMockFindQuery($table);
+		$query->limit(2);
+		$table->expects($this->never())->method('find');
+		$query->expects($this->once())
+			->method('applyOptions')
+			->with([
+				'contain' => ['PaginatorAuthor'],
+				'group' => 'PaginatorPosts.published',
+				'limit' => 2,
+				'order' => ['PaginatorPosts.id' => 'ASC'],
+				'page' => 1,
+			]);
+		$this->Paginator->paginate($query, $settings);
+	}
+
+/**
  * Helper method for making mocks.
  *
  * @param array $methods