From 8c3ceff50d0bf8b7042954156300cec2b4382095 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 19 Dec 2010 12:58:07 -0500 Subject: [PATCH] Making paging.options only contain options that are not in the defaults. This replaces the many diffs that were calculated on each url generation between paging.options and paging.defaults. --- cake/libs/controller/components/paginator.php | 47 ++++++++++------ .../controller/components/paginator.test.php | 56 +++++-------------- 2 files changed, 44 insertions(+), 59 deletions(-) diff --git a/cake/libs/controller/components/paginator.php b/cake/libs/controller/components/paginator.php index a774e934e..e660276e3 100644 --- a/cake/libs/controller/components/paginator.php +++ b/cake/libs/controller/components/paginator.php @@ -184,14 +184,18 @@ class PaginatorComponent extends Component { } $results = $object->find($type, array_merge($parameters, $extra)); } + $defaults = $this->getDefaults($object->alias); + unset($defaults[0]); + $paging = array( - 'page' => $page, - 'current' => count($results), - 'count' => $count, - 'prevPage' => ($page > 1), - 'nextPage' => ($count > ($page * $limit)), - 'pageCount' => $pageCount, - 'options' => $options, + 'page' => $page, + 'current' => count($results), + 'count' => $count, + 'prevPage' => ($page > 1), + 'nextPage' => ($count > ($page * $limit)), + 'pageCount' => $pageCount, + 'order' => $order, + 'options' => Set::diff($options, $defaults), 'paramType' => $options['paramType'] ); if (!isset($this->Controller->request['paging'])) { @@ -275,15 +279,7 @@ class PaginatorComponent extends Component { * @return array Array of merged options. */ public function mergeOptions($alias, $whitelist = array()) { - if (isset($this->settings[$alias])) { - $defaults = $this->settings[$alias]; - } else { - $defaults = $this->settings; - } - $defaults = array_merge( - array('page' => 1, 'limit' => 20, 'maxLimit' => 100, 'paramType' => 'named'), - $defaults - ); + $defaults = $this->getDefaults($alias); switch ($defaults['paramType']) { case 'named': $request = $this->Controller->request->params['named']; @@ -302,6 +298,25 @@ class PaginatorComponent extends Component { return array_merge($defaults, $request); } +/** + * Get the default settings for a $model. If there are no settings for a specific model, the general settings + * will be used. + * + * @param string $alias Model name to get default settings for. + * @return array + */ + public function getDefaults($alias) { + if (isset($this->settings[$alias])) { + $defaults = $this->settings[$alias]; + } else { + $defaults = $this->settings; + } + return array_merge( + array('page' => 1, 'limit' => 20, 'maxLimit' => 100, 'paramType' => 'named'), + $defaults + ); + } + /** * Validate that the desired sorting can be performed on the $object. Only fields or * virtualFields can be sorted on. The direction param will also be sanitized. Lastly diff --git a/cake/tests/cases/libs/controller/components/paginator.test.php b/cake/tests/cases/libs/controller/components/paginator.test.php index ecb9f812f..9268d9615 100644 --- a/cake/tests/cases/libs/controller/components/paginator.test.php +++ b/cake/tests/cases/libs/controller/components/paginator.test.php @@ -285,8 +285,7 @@ class PaginatorTest extends CakeTestCase { $Controller->request->params['named'] = array('page' => '1 " onclick="alert(\'xss\');">'); $Controller->Paginator->settings = array('limit' => 1, 'maxLimit' => 10, 'paramType' => 'named'); $Controller->Paginator->paginate('PaginatorControllerPost'); - $this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['page'], 1, 'XSS exploit opened %s'); - $this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['options']['page'], 1, 'XSS exploit opened %s'); + $this->assertIdentical($Controller->params['paging']['PaginatorControllerPost']['page'], 1, 'XSS exploit opened'); $Controller->request->params['named'] = array(); $Controller->Paginator->settings = array('limit' => 0, 'maxLimit' => 10, 'paramType' => 'named'); @@ -405,43 +404,6 @@ class PaginatorTest extends CakeTestCase { $this->assertEqual($Controller->ControllerPaginateModel->extraCount, $expected); } -/** - * testPaginatePassedArgs method - * - * @return void - */ - public function testPaginatePassedArgs() { - $Controller = new PaginatorTestController($this->request); - $Controller->uses = array('PaginatorControllerPost'); - $Controller->request->params['pass'] = array('1', '2', '3'); - $Controller->params['url'] = array(); - $Controller->constructClasses(); - - $Controller->Paginator->settings = array( - 'fields' => array(), - 'order' => '', - 'limit' => 5, - 'page' => 1, - 'recursive' => -1, - 'maxLimit' => 10, - 'paramType' => 'named' - ); - $conditions = array(); - $Controller->Paginator->paginate('PaginatorControllerPost', $conditions); - - $expected = array( - 'fields' => array(), - 'order' => '', - 'limit' => 5, - 'maxLimit' => 10, - 'page' => 1, - 'recursive' => -1, - 'conditions' => array(), - 'paramType' => 'named' - ); - $this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['options'],$expected); - } - /** * Test that special paginate types are called and that the type param doesn't leak out into defaults or options. * @@ -456,13 +418,19 @@ class PaginatorTest extends CakeTestCase { $Controller->Paginator->settings = array( 'PaginatorControllerPost' => array( - 'popular', 'fields' => array('id', 'title'), 'maxLimit' => 10, 'paramType' => 'named' + 'popular', + 'fields' => array('id', 'title'), + 'maxLimit' => 10, + 'paramType' => 'named' ) ); $result = $Controller->Paginator->paginate('PaginatorControllerPost'); $this->assertEqual(Set::extract($result, '{n}.PaginatorControllerPost.id'), array(2, 3)); - $this->assertEqual($Controller->PaginatorControllerPost->lastQuery['conditions'], array('PaginatorControllerPost.id > ' => '1')); + $this->assertEqual( + $Controller->PaginatorControllerPost->lastQuery['conditions'], + array('PaginatorControllerPost.id > ' => '1') + ); $this->assertFalse(isset($Controller->params['paging']['PaginatorControllerPost']['options'][0])); } @@ -478,10 +446,12 @@ class PaginatorTest extends CakeTestCase { $Controller->params['url'] = array(); $Controller->constructClasses(); $Controller->Paginator->settings = array( - 'order' => 'PaginatorControllerPost.id DESC', 'maxLimit' => 10, 'paramType' => 'named' + 'order' => 'PaginatorControllerPost.id DESC', + 'maxLimit' => 10, + 'paramType' => 'named' ); $results = Set::extract($Controller->Paginator->paginate('PaginatorControllerPost'), '{n}.PaginatorControllerPost.id'); - $this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['options']['order'], 'PaginatorControllerPost.id DESC'); + $this->assertEqual($Controller->params['paging']['PaginatorControllerPost']['order'], 'PaginatorControllerPost.id DESC'); $this->assertEqual($results, array(3, 2, 1)); }