Skip to content

Commit

Permalink
Add Query::page()
Browse files Browse the repository at this point in the history
This method is a simpler to use version of limit + offset which also
provides some backwards compatibility with older versions + find() that
was in them.
  • Loading branch information
markstory committed Nov 21, 2013
1 parent e85784d commit d0b1025
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Cake/Controller/Component/PaginatorComponent.php
Expand Up @@ -136,7 +136,7 @@ public function paginate($object, array $settings = []) {
$alias = $object->alias();

$options = $this->mergeOptions($alias, $settings);
$options = $this->validateSort($object, $options, $whitelist);
$options = $this->validateSort($object, $options);
$options = $this->checkLimit($options);

$conditions = $fields = $limit = $page = null;
Expand Down
23 changes: 23 additions & 0 deletions Cake/Database/Query.php
Expand Up @@ -1066,6 +1066,28 @@ public function orHaving($conditions, $types = []) {
return $this;
}

/**
* Set the page of results you want.
*
* This method provides an easier to use interface to set the limit + offset
* in the record set you want as results. If empty the limit will default to
* the existing limit clause, and if that too is empty, then `25` will be used.
*
* Pages should start at 1.
*
* @param integer $num The page number you want.
* @reutrn Query
*/
public function page($page) {
$limit = $this->clause('limit');
if ($limit === null) {
$limit = 25;
$this->limit($limit);
}
$this->offset(($page - 1) * $limit);
return $this;
}

/**
* Sets the number of records that should be retrieved from database,
* accepts an integer or an expression object that evaluates to an integer.
Expand Down Expand Up @@ -1094,6 +1116,7 @@ public function limit($num) {
* Sets the number of records that should be skipped from the original result set
* This is commonly used for paginating large results. Accepts an integer or an
* expression object that evaluates to an integer.
*
* In some databases, this operation might not be supported or will require
* the query to be transformed in order to limit the result set size.
*
Expand Down
30 changes: 17 additions & 13 deletions Cake/ORM/Query.php
Expand Up @@ -495,25 +495,26 @@ public function aliasFields($fields, $defaultAlias = null) {
* ## Example:
*
* {{{
* $query->applyOptions([
* 'fields' => ['id', 'name'],
* 'conditions' => [
* 'created >=' => '2013-01-01'
* ],
* 'limit' => 10
* ]);
* $query->applyOptions([
* 'fields' => ['id', 'name'],
* 'conditions' => [
* 'created >=' => '2013-01-01'
* ],
* 'limit' => 10
* ]);
* }}}
*
* Is equivalent to:
*
* {{{
* $query
* ->select(['id', 'name'])
* ->where(['created >=' => '2013-01-01'])
* ->limit(10)
* $query
* ->select(['id', 'name'])
* ->where(['created >=' => '2013-01-01'])
* ->limit(10)
* }}}
*
* @param array $options list of query clauses to apply new parts to. Accepts:
*
* - fields: Maps to the select method
* - conditions: Maps to the where method
* - limit: Maps to the limit method
Expand All @@ -523,19 +524,22 @@ public function aliasFields($fields, $defaultAlias = null) {
* - having: Maps to the having method
* - contain: Maps to the contain options for eager loading
* - join: Maps to the join method
* - join: Maps to the page method
*
* @return Cake\ORM\Query
*/
public function applyOptions(array $options) {
$valid = [
'fields' => 'select',
'conditions' => 'where',
'limit' => 'limit',
'join' => 'join',
'order' => 'order',
'limit' => 'limit',
'offset' => 'offset',
'group' => 'group',
'having' => 'having',
'contain' => 'contain',
'join' => 'join'
'page' => 'page',
];

foreach ($options as $option => $values) {
Expand Down
Expand Up @@ -150,7 +150,7 @@ public function testPaginateExtraParams() {
public function testPaginateCustomFinder() {
$settings = array(
'PaginatorPosts' => array(
'popular',
'findType' => 'popular',
'fields' => array('id', 'title'),
'maxLimit' => 10,
)
Expand Down
34 changes: 32 additions & 2 deletions Cake/Test/TestCase/Database/QueryTest.php
Expand Up @@ -1201,7 +1201,7 @@ public function testSelectAndHaving() {
* Tests selecting rows using a limit clause
*
* @return void
**/
*/
public function testSelectLimit() {
$query = new Query($this->connection);
$result = $query->select('id')->from('articles')->limit(1)->execute();
Expand All @@ -1221,7 +1221,7 @@ public function testSelectLimit() {
* Tests selecting rows combining a limit and offset clause
*
* @return void
**/
*/
public function testSelectOffset() {
$query = new Query($this->connection);
$result = $query->select('id')->from('comments')
Expand Down Expand Up @@ -1252,6 +1252,36 @@ public function testSelectOffset() {
$this->assertEquals(['id' => 1], $result->fetch('assoc'));
}

/**
* Test selecting rows using the page() method.
*
* @return void
*/
public function testSelectPage() {
$query = new Query($this->connection);
$result = $query->select('id')->from('comments')
->limit(1)
->page(1)->execute();

$this->assertEquals(0, $query->clause('offset'));
$this->assertCount(1, $result);
$this->assertEquals(['id' => 1], $result->fetch('assoc'));

$result = $query->page(2)->execute();
$this->assertEquals(1, $query->clause('offset'));
$this->assertCount(1, $result);
$this->assertEquals(['id' => 2], $result->fetch('assoc'));

$query = new Query($this->connection);
$query->select('id')->from('comments')->page(1);
$this->assertEquals(25, $query->clause('limit'));
$this->assertEquals(0, $query->clause('offset'));

$query->select('id')->from('comments')->page(2);
$this->assertEquals(25, $query->clause('limit'));
$this->assertEquals(25, $query->clause('offset'));
}

/**
* Tests that Query objects can be included inside the select clause
* and be used as a normal field, including binding any passed parameter
Expand Down

0 comments on commit d0b1025

Please sign in to comment.