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.

This commit is contained in:
mark_story 2010-12-19 12:58:07 -05:00
parent 833bdbcc0b
commit 8c3ceff50d
2 changed files with 44 additions and 59 deletions

View file

@ -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

View file

@ -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));
}