From 98bc995623e3d567fc18f349bf580b07985651de Mon Sep 17 00:00:00 2001 From: Philippe Gibert Date: Fri, 23 Mar 2018 17:19:41 +0100 Subject: [PATCH] fixes #11870 Add DboSource::expression support for Dbo VirtualFields --- lib/Cake/Model/Datasource/DboSource.php | 14 ++++++-- .../Case/Model/Datasource/DboSourceTest.php | 36 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php index 9e3495e18..a8481a38a 100644 --- a/lib/Cake/Model/Datasource/DboSource.php +++ b/lib/Cake/Model/Datasource/DboSource.php @@ -2578,7 +2578,12 @@ class DboSource extends DataSource { $virtual = array(); foreach ($fields as $field) { $virtualField = $this->name($alias . $this->virtualFieldSeparator . $field); - $expression = $this->_quoteFields($Model->getVirtualField($field)); + $virtualFieldExpression = $Model->getVirtualField($field); + if (is_object($virtualFieldExpression) && $virtualFieldExpression->type == 'expression') { + $expression = $virtualFieldExpression->value; + } else { + $expression = $this->_quoteFields($virtualFieldExpression); + } $virtual[] = '(' . $expression . ") {$this->alias} {$virtualField}"; } return $virtual; @@ -2887,7 +2892,12 @@ class DboSource extends DataSource { if ($Model !== null) { if ($Model->isVirtualField($key)) { - $key = $this->_quoteFields($Model->getVirtualField($key)); + $virtualField = $Model->getVirtualField($key); + if (is_object($virtualField) && $virtualField->type == 'expression') { + $key = $virtualField->value; + } else { + $key = $this->_quoteFields($virtualField); + } $virtual = true; } diff --git a/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php b/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php index 8daa5ba31..37d0a66c6 100644 --- a/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php +++ b/lib/Cake/Test/Case/Model/Datasource/DboSourceTest.php @@ -1650,6 +1650,42 @@ class DboSourceTest extends CakeTestCase { $this->assertEquals($expected, $result[0]); } + /** + * Test conditionKeysToString() with virtual field + * + * @return void + */ + public function testConditionKeysToStringVirtualFieldExpression() { + $Article = ClassRegistry::init('Article'); + $Article->virtualFields = array( + 'extra' => DboSource::expression('something virtual') + ); + $conn = $this->getMock('MockPDO', array('quote')); + $db = new DboTestSource(); + $db->setConnection($conn); + + $conn->expects($this->at(0)) + ->method('quote') + ->will($this->returnValue('just text')); + + $conditions = array('Article.extra' => 'just text'); + $result = $db->conditionKeysToString($conditions, true, $Article); + $expected = "(" . $Article->virtualFields['extra']->value . ") = just text"; + $this->assertEquals($expected, $result[0]); + + $conn->expects($this->at(0)) + ->method('quote') + ->will($this->returnValue('just text')); + $conn->expects($this->at(1)) + ->method('quote') + ->will($this->returnValue('other text')); + + $conditions = array('Article.extra' => array('just text', 'other text')); + $result = $db->conditionKeysToString($conditions, true, $Article); + $expected = "(" . $Article->virtualFields['extra']->value . ") IN (just text, other text)"; + $this->assertEquals($expected, $result[0]); + } + /** * Test conditionKeysToString() with virtual field *