Adding fixes for pagination on associated models.

Corrected dot notation use in Controller::paginate();

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@7286 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
phpnut 2008-06-27 06:25:08 +00:00
parent 7ad1790ea2
commit 022ffa3f4f
8 changed files with 117 additions and 78 deletions

View file

@ -1018,9 +1018,7 @@ class App extends Object {
* @access private
*/
function __overload($type, $name) {
$overload = array('Model', 'Helper');
if (in_array($type, $overload) && low($name) != 'schema') {
if (($type ==='Model' || $type === 'Helper') && strtolower($name) != 'schema') {
Overloadable::overload($name);
}
}

View file

@ -20,7 +20,7 @@
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
* @package cake
* @subpackage cake.cake
* @subpackage cake.cake.libs.controller
* @since CakePHP(tm) v 0.2.9
* @version $Revision$
* @modifiedby $LastChangedBy$
@ -35,7 +35,7 @@
* will inherit them.
*
* @package cake
* @subpackage cake.cake
* @subpackage cake.cake.libs.controller
*/
class AppController extends Controller {
}

View file

@ -919,19 +919,21 @@ class Controller extends Object {
}
if (!empty($options['order']) && is_array($options['order'])) {
$alias = $object->alias ;
$key = $field = key($options['order']);
if (strpos($key, '.') !== false) {
$field = array_pop(explode('.', $key));
}
if (strpos($key, '.') !== false) {
list($alias, $field) = explode('.', $key);
}
$value = $options['order'][$key];
unset($options['order'][$key]);
if ($object->hasField($field)) {
$options['order'][$object->alias . '.' . $field] = $value;
if (isset($object->{$alias}) && $object->{$alias}->hasField($field)) {
$options['order'][$alias . '.' . $field] = $value;
} elseif ($object->hasField($field)) {
$options['order'][$alias . '.' . $field] = $value;
}
}
$vars = array('fields', 'order', 'limit', 'page', 'recursive');
$keys = array_keys($options);
$count = count($keys);
@ -946,13 +948,13 @@ class Controller extends Object {
unset($options[$keys[$i]]);
}
}
$conditions = $fields = $order = $limit = $page = $recursive = null;
if (!isset($defaults['conditions'])) {
$defaults['conditions'] = array();
}
extract($options = array_merge(array('page' => 1, 'limit' => 20), $defaults, $options));
if (is_array($scope) && !empty($scope)) {
$conditions = array_merge($conditions, $scope);
} elseif (is_string($scope)) {
@ -962,10 +964,12 @@ class Controller extends Object {
$recursive = $object->recursive;
}
$type = 'all';
if (isset($defaults[0])) {
$type = array_shift($defaults);
}
$extra = array_diff_key($defaults, compact('conditions', 'fields', 'order', 'limit', 'page', 'recursive'));
if (method_exists($object, 'paginateCount')) {
$count = $object->paginateCount($conditions, $recursive);
} else {
@ -1002,13 +1006,11 @@ class Controller extends Object {
'defaults' => array_merge(array('limit' => 20, 'step' => 1), $defaults),
'options' => $options
);
$this->params['paging'][$object->alias] = $paging;
if (!in_array('Paginator', $this->helpers) && !array_key_exists('Paginator', $this->helpers)) {
$this->helpers[] = 'Paginator';
}
return $results;
}
/**

View file

@ -20,7 +20,7 @@
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
* @package cake
* @subpackage cake.cake
* @subpackage cake.cake.libs.model
* @since CakePHP(tm) v 0.2.9
* @version $Revision$
* @modifiedby $LastChangedBy$
@ -35,7 +35,7 @@
* Add your application-wide methods to the class, your models will inherit them.
*
* @package cake
* @subpackage cake.cake
* @subpackage cake.cake.libs.model
*/
class AppModel extends Model {
}

View file

@ -17,7 +17,7 @@
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
* @package cake
* @subpackage cake.cake.libs
* @subpackage cake.cake.libs.model
* @since CakePHP(tm) v 1.2.0.5550
* @version $Revision$
* @modifiedby $LastChangedBy$
@ -28,8 +28,8 @@ App::import('Model', 'ConnectionManager');
/**
* Base Class for Schema management
*
* @package cake.libs
* @subpackage cake.libs
* @package cake
* @subpackage ccake.cake.libs.model
*/
class CakeSchema extends Object {
/**

View file

@ -1114,5 +1114,4 @@ class Set extends Object {
return $sorted;
}
}
?>

View file

@ -140,6 +140,9 @@ class PaginatorHelper extends AppHelper {
}
if (isset($options['sort']) && !empty($options['sort'])) {
if (preg_match('/(?:\w+\.)?(\w+)/', $options['sort'], $result) && isset($result[1])) {
return $result[1];
}
return $options['sort'];
} elseif (isset($options['order']) && is_array($options['order'])) {
return preg_replace('/.*\./', '', key($options['order']));
@ -219,16 +222,20 @@ class PaginatorHelper extends AppHelper {
$key = $title;
$title = __(Inflector::humanize(preg_replace('/_id$/', '', $title)), true);
}
$dir = 'asc';
$model = null;
if (strpos($key, '.') !== false) {
list($model, $key) = explode('.', $key);
$model = $model . '.';
}
if ($this->sortKey($options['model']) == $key && $this->sortDir($options['model']) == 'asc') {
$dir = 'desc';
}
if (is_array($title) && array_key_exists($dir, $title)) {
$title = $title[$dir];
}
$url = array_merge(array('sort' => $key, 'direction' => $dir), $url, array('order' => null));
$url = array_merge(array('sort' => $model . $key, 'direction' => $dir), $url, array('order' => null));
return $this->link($title, $url, $options);
}
/**

View file

@ -37,7 +37,7 @@ uses('view'.DS.'helpers'.DS.'app_helper', 'view'.DS.'helper', 'view'.DS.'helpers
class PaginatorTest extends UnitTestCase {
/**
* setUp method
*
*
* @access public
* @return void
*/
@ -74,7 +74,7 @@ class PaginatorTest extends UnitTestCase {
}
/**
* testHasPrevious method
*
*
* @access public
* @return void
*/
@ -86,7 +86,7 @@ class PaginatorTest extends UnitTestCase {
}
/**
* testHasNext method
*
*
* @access public
* @return void
*/
@ -98,7 +98,7 @@ class PaginatorTest extends UnitTestCase {
}
/**
* testDisabledLink method
*
*
* @access public
* @return void
*/
@ -108,7 +108,7 @@ class PaginatorTest extends UnitTestCase {
$result = $this->Paginator->next('Next', array(), true);
$expected = '<div>Next</div>';
$this->assertEqual($result, $expected);
$this->Paginator->params['paging']['Article']['prevPage'] = false;
$result = $this->Paginator->prev('prev', array('update'=> 'theList', 'indicator'=> 'loading', 'url'=> array('controller' => 'posts')), null, array('class' => 'disabled', 'tag' => 'span'));
$expected = '<span class="disabled">prev</span>';
@ -116,7 +116,7 @@ class PaginatorTest extends UnitTestCase {
}
/**
* testSortLinks method
*
*
* @access public
* @return void
*/
@ -148,15 +148,48 @@ class PaginatorTest extends UnitTestCase {
$result = $this->Paginator->sort(array('asc' => 'ascending', 'desc' => 'descending'), 'title');
$this->assertPattern('/\/accounts\/index\/param\/page:1\/sort:title\/direction:desc">descending<\/a>$/', $result);
}
/**
* testSortLinksUsingDotNotation method
*
* @access public
* @return void
*/
function testSortLinksUsingDotNotation() {
Router::reload();
Router::parse('/');
Router::setRequestInfo(array(
array('plugin' => null, 'controller' => 'accounts', 'action' => 'index', 'pass' => array(), 'form' => array(), 'url' => array('url' => 'accounts/', 'mod_rewrite' => 'true'), 'bare' => 0),
array('plugin' => null, 'controller' => null, 'action' => null, 'base' => '/officespace', 'here' => '/officespace/accounts/', 'webroot' => '/officespace/', 'passedArgs' => array())
));
$this->Paginator->params['paging']['Article']['options']['order'] = array('Article.title' => 'desc');
$this->Paginator->params['paging']['named'] = array(
'page' => 1,
'sort' => 'Artist.title',
'direction' => 'desc'
);
$result = $this->Paginator->sort('Title','Article.title');
$this->assertPattern('/\/accounts\/index\/page:1\/sort:Article.title\/direction:asc">Title<\/a>$/', $result);
$this->Paginator->params['paging']['named'] = array(
'page' => 1,
'sort' => 'Artist.title',
'direction' => 'asc'
);
$this->Paginator->params['paging']['Article']['options']['order'] = array('Article.title' => 'asc');
$result = $this->Paginator->sort('Title','Article.title');
$this->assertPattern('/\/accounts\/index\/page:1\/sort:Article.title\/direction:desc">Title<\/a>$/', $result);
}
/**
* testSortAdminLinks method
*
*
* @access public
* @return void
*/
function testSortAdminLinks() {
Configure::write('Routing.admin', 'admin');
Router::reload();
Router::setRequestInfo(array(
array('pass' => array(), 'named' => array(), 'controller' => 'users', 'plugin' => null, 'action' => 'admin_index', 'prefix' => 'admin', 'admin' => true, 'url' => array('ext' => 'html', 'url' => 'admin/users'), 'form' => array()),
@ -167,7 +200,7 @@ class PaginatorTest extends UnitTestCase {
$result = $this->Paginator->next('Next');
$this->assertPattern('/^<a[^<>]+>Next<\/a>$/', $result);
$this->assertPattern('/href="\/admin\/users\/index\/page:2"/', $result);
Router::reload();
Router::setRequestInfo(array(
array('plugin' => null, 'controller' => 'test', 'action' => 'admin_index', 'pass' => array(), 'prefix' => 'admin', 'admin' => true, 'form' => array(), 'url' => array('url' => 'admin/test')),
@ -180,7 +213,7 @@ class PaginatorTest extends UnitTestCase {
}
/**
* testUrlGeneration method
*
*
* @access public
* @return void
*/
@ -195,14 +228,14 @@ class PaginatorTest extends UnitTestCase {
$this->Paginator->params['paging']['Article']['options']['page'] = 2;
$result = $this->Paginator->url();
$this->assertEqual($result, '/index/page:2');
$options = array('order' => array('Article' => 'desc'));
$result = $this->Paginator->url($options);
$this->assertEqual($result, '/index/page:2/sort:Article/direction:desc');
$this->assertEqual($result, '/index/page:2/sort:Article/direction:desc');
}
/**
* testOptions method
*
*
* @access public
* @return void
*/
@ -215,7 +248,7 @@ class PaginatorTest extends UnitTestCase {
$options = array('paging' => array('Article' => array(
'order' => 'desc',
'sort' => 'title'
'sort' => 'title'
)));
$this->Paginator->options($options);
@ -230,14 +263,14 @@ class PaginatorTest extends UnitTestCase {
$options = array('Article' => array(
'order' => 'desc',
'sort' => 'title'
'sort' => 'title'
));
$this->Paginator->options($options);
$this->assertEqual($expected, $this->Paginator->params['paging']);
}
/**
* testPagingLinks method
*
*
* @access public
* @return void
*/
@ -250,7 +283,7 @@ class PaginatorTest extends UnitTestCase {
$result = $this->Paginator->prev('<< Previous', null, null, array('class' => 'disabled'));
$expected = '<div class="disabled">&lt;&lt; Previous</div>';
$this->assertEqual($result, $expected);
$result = $this->Paginator->prev('<< Previous', null, null, array('class' => 'disabled', 'tag' => 'span'));
$expected = '<span class="disabled">&lt;&lt; Previous</span>';
$this->assertEqual($result, $expected);
@ -267,7 +300,7 @@ class PaginatorTest extends UnitTestCase {
}
/**
* testGenericLinks method
*
*
* @access public
* @return void
*/
@ -287,7 +320,7 @@ class PaginatorTest extends UnitTestCase {
}
/**
* testNumbers method
*
*
* @access public
* @return void
*/
@ -380,22 +413,22 @@ class PaginatorTest extends UnitTestCase {
$this->Paginator->params['paging'] = array(
'Client' => array(
'page' => 1,
'current' => 10,
'count' => 30,
'prevPage' => false,
'nextPage' => 2,
'page' => 1,
'current' => 10,
'count' => 30,
'prevPage' => false,
'nextPage' => 2,
'pageCount' => 3,
'defaults' => array(
'limit' => 3,
'step' => 1,
'order' => array('Client.name' => 'DESC'),
'limit' => 3,
'step' => 1,
'order' => array('Client.name' => 'DESC'),
'conditions' => array()
),
'options' => array(
'page' => 1,
'limit' => 3,
'order' => array('Client.name' => 'DESC'),
'page' => 1,
'limit' => 3,
'order' => array('Client.name' => 'DESC'),
'conditions' => array()
)
)
@ -408,7 +441,7 @@ class PaginatorTest extends UnitTestCase {
}
/**
* testFirstAndLast method
*
*
* @access public
* @return void
*/
@ -457,79 +490,79 @@ class PaginatorTest extends UnitTestCase {
}
/**
* testCounter method
*
*
* @access public
* @return void
*/
function testCounter() {
$this->Paginator->params['paging'] = array(
'Client' => array(
'page' => 1,
'current' => 3,
'count' => 13,
'prevPage' => false,
'nextPage' => true,
'page' => 1,
'current' => 3,
'count' => 13,
'prevPage' => false,
'nextPage' => true,
'pageCount' => 5,
'defaults' => array(
'limit' => 3,
'step' => 1,
'order' => array('Client.name' => 'DESC'),
'limit' => 3,
'step' => 1,
'order' => array('Client.name' => 'DESC'),
'conditions' => array()
),
'options' => array(
'page' => 1,
'limit' => 3,
'order' => array('Client.name' => 'DESC'),
'page' => 1,
'limit' => 3,
'order' => array('Client.name' => 'DESC'),
'conditions' => array(),
'separator' => 'of'
),
)
);
$input = 'Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%';
$input = 'Page %page% of %pages%, showing %current% records out of %count% total, starting on record %start%, ending on %end%';
$result = $this->Paginator->counter($input);
$expected = 'Page 1 of 5, showing 3 records out of 13 total, starting on record 1, ending on 3';
$this->assertEqual($result, $expected);
$input = 'Page %page% of %pages%';
$result = $this->Paginator->counter($input);
$expected = 'Page 1 of 5';
$this->assertEqual($result, $expected);
$result = $this->Paginator->counter(array('format' => $input));
$expected = 'Page 1 of 5';
$this->assertEqual($result, $expected);
$result = $this->Paginator->counter(array('format' => 'pages'));
$expected = '1 of 5';
$this->assertEqual($result, $expected);
$result = $this->Paginator->counter(array('format' => 'range'));
$expected = '1 - 3 of 13';
$this->assertEqual($result, $expected);
}
/**
* testHasPage method
*
*
* @access public
* @return void
*/
function testHasPage() {
$result = $this->Paginator->hasPage('Article', 15);
$this->assertFalse($result);
$result = $this->Paginator->hasPage('UndefinedModel', 2);
$this->assertFalse($result);
$result = $this->Paginator->hasPage('Article', 2);
$this->assertTrue($result);
$result = $this->Paginator->hasPage(2);
$this->assertTrue($result);
}
/**
* tearDown method
*
*
* @access public
* @return void
*/