mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-19 02:56:15 +00:00
Re-adding ability to order by virtual fields in DboSource::order
Adding support for paginating virtual model fields in controller
This commit is contained in:
parent
051d352eab
commit
cf359a38b3
3 changed files with 40 additions and 96 deletions
|
@ -1076,9 +1076,11 @@ class Controller extends Object {
|
|||
$value = $options['order'][$key];
|
||||
unset($options['order'][$key]);
|
||||
|
||||
if (isset($object->{$alias}) && $object->{$alias}->hasField($field)) {
|
||||
if ($object->hasField($field)) {
|
||||
$options['order'][$alias . '.' . $field] = $value;
|
||||
} elseif ($object->hasField($field)) {
|
||||
} elseif ($object->hasField($field,true)) {
|
||||
$options['order'][$field] = $value;
|
||||
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field)) {
|
||||
$options['order'][$alias . '.' . $field] = $value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2216,6 +2216,14 @@ class DboSource extends DataSource {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ORDER BY clause as a string.
|
||||
*
|
||||
* @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 field)
|
||||
* @return string ORDER BY clause
|
||||
*/
|
||||
function order($keys, $direction = 'ASC', &$model = null) {
|
||||
if (!is_array($keys)) {
|
||||
$keys = array($keys);
|
||||
|
@ -2246,7 +2254,7 @@ class DboSource extends DataSource {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (preg_match('/\\x20ASC|\\x20DESC/i', $key, $_dir)) {
|
||||
$dir = $_dir[0];
|
||||
$key = preg_replace('/\\x20ASC|\\x20DESC/i', '', $key);
|
||||
|
@ -2264,7 +2272,11 @@ class DboSource extends DataSource {
|
|||
|
||||
$key = trim($key);
|
||||
if (!preg_match('/\s/', $key) && !strpos($key,'.')) {
|
||||
$key = $this->name($key);
|
||||
if (!empty($model->virtualFields[$key])) {
|
||||
$key = $model->virtualFields[$key];
|
||||
} else {
|
||||
$key = $this->name($key);
|
||||
}
|
||||
}
|
||||
$key .= ' ' . trim($dir);
|
||||
$result[] = $key;
|
||||
|
@ -2275,79 +2287,6 @@ class DboSource extends DataSource {
|
|||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ORDER BY clause as a string.
|
||||
*
|
||||
* @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 field)
|
||||
* @return string ORDER BY clause
|
||||
*/
|
||||
function order2($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));
|
||||
}
|
||||
|
||||
if (is_array($keys)) {
|
||||
$keys = array_filter($keys);
|
||||
$dir = $direction;
|
||||
}
|
||||
|
||||
if (empty($keys) || (is_array($keys) && isset($keys[0]) && empty($keys[0]))) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (is_array($keys)) {
|
||||
|
||||
foreach ($keys as $key => $value) {
|
||||
if (is_numeric($key)) {
|
||||
$key = $value = ltrim(str_replace('ORDER BY ', '', $this->order($value,'ASC',$model)));
|
||||
$value = (!preg_match('/\\x20ASC|\\x20DESC/i', $key) ? ' ' . $direction : '');
|
||||
} else {
|
||||
$value = ' ' . $value;
|
||||
}
|
||||
|
||||
if (!preg_match('/^.+\\(.*\\)/', $key) && !strpos($key, ',')) {
|
||||
if (preg_match('/\\x20ASC|\\x20DESC/i', $key, $dir)) {
|
||||
$dir = $dir[0];
|
||||
$key = preg_replace('/\\x20ASC|\\x20DESC/i', '', $key);
|
||||
} else {
|
||||
$dir = '';
|
||||
}
|
||||
$key = trim($key);
|
||||
if (!preg_match('/\s/', $key)) {
|
||||
$key = $this->name($key);
|
||||
}
|
||||
$key .= ' ' . trim($dir);
|
||||
}
|
||||
$order[] = $this->order($key . $value,'ASC',$model);
|
||||
}
|
||||
return ' ORDER BY ' . trim(str_replace('ORDER BY', '', implode(',', $order)));
|
||||
}
|
||||
$keys = preg_replace('/ORDER\\x20BY/i', '', $keys);
|
||||
|
||||
if (strpos($keys, '.')) {
|
||||
preg_match_all('/([a-zA-Z0-9_]{1,})\\.([a-zA-Z0-9_]{1,})/', $keys, $result, PREG_PATTERN_ORDER);
|
||||
$pregCount = count($result[0]);
|
||||
|
||||
for ($i = 0; $i < $pregCount; $i++) {
|
||||
if (!is_numeric($result[0][$i])) {
|
||||
$keys = preg_replace('/' . $result[0][$i] . '/', $this->name($result[0][$i]), $keys);
|
||||
}
|
||||
}
|
||||
$result = ' ORDER BY ' . $keys;
|
||||
return $result . (!preg_match('/\\x20ASC|\\x20DESC/i', $keys) ? ' ' . $direction : '');
|
||||
|
||||
} elseif (preg_match('/(\\x20ASC|\\x20DESC)/i', $keys, $match)) {
|
||||
$direction = $match[1];
|
||||
return ' ORDER BY ' . preg_replace('/' . $match[1] . '/', '', $keys) . $direction;
|
||||
}
|
||||
return ' ORDER BY ' . $keys . ' ' . $direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a GROUP BY SQL clause
|
||||
*
|
||||
|
|
|
@ -418,25 +418,6 @@ 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
|
||||
*
|
||||
|
@ -1262,5 +1243,27 @@ class ControllerTest extends CakeTestCase {
|
|||
$this->assertEqual($Controller->RequestHandler->prefers(), 'rss');
|
||||
unset($Controller);
|
||||
}
|
||||
|
||||
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','offset_test'),
|
||||
'order' => array('offset_test' => 'DESC')
|
||||
);
|
||||
$result = $Controller->paginate('ControllerPost');
|
||||
$this->assertEqual(Set::extract($result, '{n}.ControllerPost.offset_test'), array(4,3,2));
|
||||
|
||||
$Controller->passedArgs = array('sort' => 'offset_test', 'direction' => 'asc');
|
||||
$result = $Controller->paginate('ControllerPost');
|
||||
$this->assertEqual(Set::extract($result, '{n}.ControllerPost.offset_test'), array(2,3,4));
|
||||
}
|
||||
}
|
||||
?>
|
Loading…
Add table
Reference in a new issue