Making DboSource order by virtual fields

This commit is contained in:
José Lorenzo Rodríguez 2009-11-28 16:31:42 -04:30
parent 7efafc685e
commit 5a58813031
2 changed files with 26 additions and 21 deletions

View file

@ -2221,9 +2221,13 @@ class DboSource extends DataSource {
*
* @param string $key Field reference, as a key (i.e. Post.title)
* @param string $direction Direction (ASC or DESC)
* @param object $model model reference (used to look for virtual fields)
* @return string ORDER BY clause
*/
function order($keys, $direction = 'ASC', &$model = null) {
if (is_string($keys) && !empty($model->virtualFields[$keys])) {
return '(' . $model->virtualFields[$keys] . ') ' . $direction;
}
if (is_string($keys) && strpos($keys, ',') && !preg_match('/\(.+\,.+\)/', $keys)) {
$keys = array_map('trim', explode(',', $keys));
}
@ -2241,7 +2245,7 @@ class DboSource extends DataSource {
foreach ($keys as $key => $value) {
if (is_numeric($key)) {
$key = $value = ltrim(str_replace('ORDER BY ', '', $this->order($value)));
$key = $value = ltrim(str_replace('ORDER BY ', '', $this->order($value,'ASC',$model)));
$value = (!preg_match('/\\x20ASC|\\x20DESC/i', $key) ? ' ' . $direction : '');
} else {
$value = ' ' . $value;
@ -2260,7 +2264,7 @@ class DboSource extends DataSource {
}
$key .= ' ' . trim($dir);
}
$order[] = $this->order($key . $value);
$order[] = $this->order($key . $value,'ASC',$model);
}
return ' ORDER BY ' . trim(str_replace('ORDER BY', '', implode(',', $order)));
}

View file

@ -418,6 +418,25 @@ class ControllerTest extends CakeTestCase {
App::build();
}
function testPaginateOrderVirtualField() {
$Controller =& new Controller();
$Controller->uses = array('ControllerPost', 'ControllerComment');
$Controller->passedArgs[] = '1';
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->ControllerPost->virtualFields = array('offset_test' => 'ControllerPost.id + 1');
$Controller->paginate = array(
'fields' => array('id', 'title'),
'order' => 'offset_test',
'limit' => 1
);
$result = $Controller->paginate('ControllerPost');
$this->assertEqual(Set::extract($result, '{n}.ControllerPost.offset_test'), array(2, 3));
exit;
}
/**
* testConstructClasses method
*
@ -563,7 +582,7 @@ class ControllerTest extends CakeTestCase {
$this->assertIdentical($Controller->params['paging']['ControllerPost']['pageCount'], 3);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['prevPage'], false);
$this->assertIdentical($Controller->params['paging']['ControllerPost']['nextPage'], true);
$Controller->passedArgs = array();
$Controller->paginate = array('limit' => 'garbage!');
$Controller->paginate('ControllerPost');
@ -688,24 +707,6 @@ class ControllerTest extends CakeTestCase {
$this->assertFalse(isset($Controller->params['paging']['ControllerPost']['options'][0]));
}
function testPaginateOrderVirtualField() {
$Controller =& new Controller();
$Controller->uses = array('ControllerPost', 'ControllerComment');
$Controller->passedArgs[] = '1';
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->ControllerPost->virtualFields = array('offset_test' => 'ControllerPost.id + 1');
$Controller->paginate = array(
'fields' => array('id', 'title'),
'order' => 'offset_test',
'limit' => 1
);
$result = $Controller->paginate('ControllerPost');
$this->assertEqual(Set::extract($result, '{n}.ControllerPost.offset_test'), array(2, 3));
}
/**
* testDefaultPaginateParams method
*