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

This commit is contained in:
Mark Story 2010-01-19 09:22:13 -05:00
parent 49ad582759
commit e1b0c41254
3 changed files with 51 additions and 4 deletions

View file

@ -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));

View file

@ -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();

View file

@ -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']);
}
}
?>