From e1b0c41254addfae5471e57a0579a2064965e7a1 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Tue, 19 Jan 2010 09:22:13 -0500 Subject: [PATCH] Making Model::isVirtualField() and Model::getVirtualField() work with both `Model.field` as `field`. This fixes a number of issues in conditions, and fields arrays when model aliases are used. Fixes #208 and #220 --- cake/libs/model/datasources/dbo_source.php | 2 +- cake/libs/model/model.php | 18 +++++++++- .../cases/libs/model/model_read.test.php | 35 +++++++++++++++++-- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/cake/libs/model/datasources/dbo_source.php b/cake/libs/model/datasources/dbo_source.php index 4a900ab11..c0d86f10f 100755 --- a/cake/libs/model/datasources/dbo_source.php +++ b/cake/libs/model/datasources/dbo_source.php @@ -2120,7 +2120,7 @@ class DboSource extends DataSource { * @return string * @access private */ - function __parseKey($model, $key, $value) { + function __parseKey(&$model, $key, $value) { $operatorMatch = '/^((' . implode(')|(', $this->__sqlOps); $operatorMatch .= '\\x20)|<[>=]?(?![^>]+>)\\x20?|[>=!]{1,3}(?!<)\\x20?)/is'; $bound = (strpos($key, '?') !== false || (is_array($value) && strpos($key, ':') !== false)); diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php index 32b3d5003..6a04a8396 100644 --- a/cake/libs/model/model.php +++ b/cake/libs/model/model.php @@ -1077,7 +1077,19 @@ class Model extends Overloadable { * @access public */ function isVirtualField($field) { - return !empty($this->virtualFields) && is_string($field) && array_key_exists($field, $this->virtualFields); + if (empty($this->virtualFields) || !is_string($field)) { + return false; + } + if (isset($this->virtualFields[$field])) { + return true; + } + if (strpos($field, '.') !== false) { + list($model, $field) = explode('.', $field); + if (isset($this->virtualFields[$field])) { + return true; + } + } + return false; } /** @@ -1094,6 +1106,9 @@ class Model extends Overloadable { return empty($this->virtualFields) ? false : $this->virtualFields; } if ($this->isVirtualField($field)) { + if (strpos($field, '.') !== false) { + list($model, $field) = explode('.', $field); + } return $this->virtualFields[$field]; } return false; @@ -2126,6 +2141,7 @@ class Model extends Overloadable { if (!$db =& ConnectionManager::getDataSource($this->useDbConfig)) { return false; } + $results = $db->read($this, $query); $this->resetAssociations(); diff --git a/cake/tests/cases/libs/model/model_read.test.php b/cake/tests/cases/libs/model/model_read.test.php index 1ed9fd9e1..a0cd6d9b6 100755 --- a/cake/tests/cases/libs/model/model_read.test.php +++ b/cake/tests/cases/libs/model/model_read.test.php @@ -7172,7 +7172,7 @@ class ModelReadTest extends BaseModelTest { * @return void */ function testVirtualFields() { - $this->loadFixtures('Post','Author'); + $this->loadFixtures('Post', 'Author'); $Post =& ClassRegistry::init('Post'); $Post->virtualFields = array('two' => "1 + 1"); $result = $Post->find('first'); @@ -7235,7 +7235,7 @@ class ModelReadTest extends BaseModelTest { $Writing->virtualFields = array('two' => "1 + 1"); $result = $Writing->find('first'); $this->assertEqual($result['Writing']['two'], 2); - + $Post->create(); $Post->virtualFields = array('other_field' => 'COUNT(Post.id) + 1'); $result = $Post->field('other_field'); @@ -7264,5 +7264,36 @@ class ModelReadTest extends BaseModelTest { $this->assertEqual($result, $expectation); } + +/** + * test that isVirtualField will accept both aliased and non aliased fieldnames + * + * @return void + */ + function testIsVirtualField() { + $this->loadFixtures('Post'); + $Post =& ClassRegistry::init('Post'); + $Post->virtualFields = array('other_field' => 'COUNT(Post.id) + 1'); + + $this->assertTrue($Post->isVirtualField('other_field')); + $this->assertTrue($Post->isVirtualField('Post.other_field')); + $this->assertFalse($Post->isVirtualField('id')); + $this->assertFalse($Post->isVirtualField('Post.id')); + $this->assertFalse($Post->isVirtualField(array())); + } + +/** + * test that getting virtual fields works with and without model alias attached + * + * @return void + */ + function testGetVirtualField() { + $this->loadFixtures('Post'); + $Post =& ClassRegistry::init('Post'); + $Post->virtualFields = array('other_field' => 'COUNT(Post.id) + 1'); + + $this->assertEqual($Post->getVirtualField('other_field'), $Post->virtualFields['other_field']); + $this->assertEqual($Post->getVirtualField('Post.other_field'), $Post->virtualFields['other_field']); + } } ?> \ No newline at end of file