Permalink
Browse files

Add sorting on joined model virtual field, fixes #2250

  • Loading branch information...
ceeram committed Nov 14, 2011
1 parent 3cb5188 commit e5c8a446d64c8713f2393c6df5d5882a11a4919b
@@ -353,7 +353,7 @@ public function validateSort($object, $options, $whitelist = array()) {
$order[$alias . '.' . $field] = $value;
} elseif ($object->hasField($key, true)) {
$order[$field] = $value;
- } elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field)) {
+ } elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field, true)) {
$order[$alias . '.' . $field] = $value;
}
}
@@ -2590,6 +2590,10 @@ public function order($keys, $direction = 'ASC', $model = null) {
if (is_object($model) && $model->isVirtualField($key)) {
$key = '(' . $this->_quoteFields($model->getVirtualField($key)) . ')';
}
+ list($alias, $field) = pluginSplit($key);
+ if (is_object($model) && $alias !== $model->alias && is_object($model->{$alias}) && $model->{$alias}->isVirtualField($key)) {
+ $key = '(' . $this->_quoteFields($model->{$alias}->getVirtualField($key)) . ')';
+ }
if (strpos($key, '.')) {
$key = preg_replace_callback('/([a-zA-Z0-9_-]{1,})\\.([a-zA-Z0-9_-]{1,})/', array(&$this, '_quoteMatchedField'), $key);
@@ -87,6 +87,13 @@ class PaginatorControllerPost extends CakeTestModel {
*/
public $lastQueries = array();
+/**
+ * belongsTo property
+ *
+ * @var array
+ */
+ public $belongsTo = array('PaginatorAuthor' => array('foreignKey' => 'author_id'));
+
/**
* beforeFind method
*
@@ -183,14 +190,53 @@ class PaginatorControllerComment extends CakeTestModel {
public $alias = 'PaginatorControllerComment';
}
+/**
+ * PaginatorAuthorclass
+ *
+ * @package Cake.Test.Case.Controller.Component
+ */
+class PaginatorAuthor extends CakeTestModel {
+
+/**
+ * name property
+ *
+ * @var string 'PaginatorAuthor'
+ */
+ public $name = 'PaginatorAuthor';
+
+/**
+ * useTable property
+ *
+ * @var string 'authors'
+ */
+ public $useTable = 'authors';
+
+/**
+ * alias property
+ *
+ * @var string 'PaginatorAuthor'
+ */
+ public $alias = 'PaginatorAuthor';
+
+/**
+ * alias property
+ *
+ * @var string 'PaginatorAuthor'
+ */
+ public $virtualFields = array(
+ 'joined_offset' => 'PaginatorAuthor.id + 1'
+ );
+
+}
+
class PaginatorComponentTest extends CakeTestCase {
/**
* fixtures property
*
* @var array
*/
- public $fixtures = array('core.post', 'core.comment');
+ public $fixtures = array('core.post', 'core.comment', 'core.author');
/**
* setup
@@ -490,6 +536,30 @@ public function testPaginateOrderVirtualField() {
$this->assertEqual(Set::extract($result, '{n}.PaginatorControllerPost.offset_test'), array(2, 3, 4));
}
+/**
+ * test paginate() and virtualField on joined model
+ *
+ * @return void
+ */
+ public function testPaginateOrderVirtualFieldJoinedModel() {
+ $Controller = new PaginatorTestController($this->request);
+ $Controller->uses = array('PaginatorControllerPost');
+ $Controller->params['url'] = array();
+ $Controller->constructClasses();
+ $Controller->PaginatorControllerPost->recursive = 0;
+ $Controller->Paginator->settings = array(
+ 'order' => array('PaginatorAuthor.joined_offset' => 'DESC'),
+ 'maxLimit' => 10,
+ 'paramType' => 'named'
+ );
+ $result = $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertEqual(Set::extract($result, '{n}.PaginatorAuthor.joined_offset'), array(4, 2, 2));
+
+ $Controller->request->params['named'] = array('sort' => 'PaginatorAuthor.joined_offset', 'direction' => 'asc');
+ $result = $Controller->Paginator->paginate('PaginatorControllerPost');
+ $this->assertEqual(Set::extract($result, '{n}.PaginatorAuthor.joined_offset'), array(2, 2, 4));
+ }
+
/**
* Tests for missing models
*
@@ -7543,6 +7543,50 @@ public function testVirtualFields() {
$this->assertEqual($result, 4);
}
+/**
+ * testVirtualFieldsOrder()
+ *
+ * Test correct order on virtual fields
+ *
+ * @return void
+ */
+ public function testVirtualFieldsOrder() {
+ $this->loadFixtures('Post', 'Author');
+ $Post = ClassRegistry::init('Post');
+ $Post->virtualFields = array('other_field' => '10 - Post.id');
+ $result = $Post->find('list', array('order' => array('Post.other_field' => 'ASC')));
+ $expected = array(
+ '3' => 'Third Post',
+ '2' => 'Second Post',
+ '1' => 'First Post'
+ );
+ $this->assertEqual($result, $expected);
+
+ $result = $Post->find('list', array('order' => array('Post.other_field' => 'DESC')));
+ $expected = array(
+ '1' => 'First Post',
+ '2' => 'Second Post',
+ '3' => 'Third Post'
+ );
+ $this->assertEqual($result, $expected);
+
+ $Post->Author->virtualFields = array('joined' => 'Post.id * Author.id');
+ $result = $Post->find('all');
+ $result = Set::extract('{n}.Author.joined', $result);
+ $expected = array(1, 6, 3);
+ $this->assertEqual($result, $expected);
+
+ $result = $Post->find('all', array('order' => array('Author.joined' => 'ASC')));
+ $result = Set::extract('{n}.Author.joined', $result);
+ $expected = array(1, 3, 6);
+ $this->assertEqual($result, $expected);
+
+ $result = $Post->find('all', array('order' => array('Author.joined' => 'DESC')));
+ $result = Set::extract('{n}.Author.joined', $result);
+ $expected = array(6, 3, 1);
+ $this->assertEqual($result, $expected);
+ }
+
/**
* testVirtualFieldsMysql()
*

0 comments on commit e5c8a44

Please sign in to comment.