diff --git a/cake/libs/model/datasources/dbo_source.php b/cake/libs/model/datasources/dbo_source.php index 76df4808d..17f322003 100644 --- a/cake/libs/model/datasources/dbo_source.php +++ b/cake/libs/model/datasources/dbo_source.php @@ -724,7 +724,10 @@ class DboSource extends DataSource { if($type === 'hasMany') { $ins = array(); for($i = 0; $i < $count; $i++) { - $ins[] = $this->insertQueryData('{$__cakeID__$}', $resultSet[$i], $association, $assocData, $model, $linkModel, $stack); + $in = $this->insertQueryData('{$__cakeID__$}', $resultSet[$i], $association, $assocData, $model, $linkModel, $stack); + if ($in !== false) { + $ins[] = $in; + } } if(!empty($ins)){ @@ -990,6 +993,22 @@ class DboSource extends DataSource { if (empty($queryData['fields'])) { $queryData['fields'] = $this->fields($model, $model->name); + } elseif(!empty($model->hasMany)) { + $assocFields = $this->fields($model, $model->name, array("{$model->name}.{$model->primaryKey}")); + $passedFields = $this->fields($model, $model->name, $queryData['fields']); + if(count($passedFields) === 1) { + $match = strrpos($passedFields[0], $assocFields[0]); + $match1 = strrpos($passedFields[0], 'COUNT('); + if($match === false && $match1 === false){ + $queryData['fields'] = array_unique(array_merge($passedFields, $assocFields)); + } else { + $queryData['fields'] = $passedFields; + } + } else { + $queryData['fields'] = array_unique(array_merge($passedFields, $assocFields)); + } + unset($assocFields); + unset($passedFields); } if ($linkModel == null) { @@ -1078,9 +1097,14 @@ class DboSource extends DataSource { } break; case 'hasMany': + $assocFields = $this->fields($linkModel, $alias, array("{$alias}.{$assocData['foreignKey']}")); + $passedFields = $this->fields($linkModel, $alias, $assocData['fields']); + $assocData['fields'] = array_unique(array_merge($passedFields, $assocFields)); + unset($assocFields); + unset($passedFields); $query = array( 'conditions' => $this->__mergeConditions(array("{$alias}.{$assocData['foreignKey']}" => array('{$__cakeID__$}')), $assocData['conditions']), - 'fields' => $this->fields($linkModel, $alias, $assocData['fields']), + 'fields' => $assocData['fields'], 'table' => $this->fullTableName($linkModel), 'alias' => $alias, 'order' => $assocData['order'], @@ -1381,7 +1405,6 @@ class DboSource extends DataSource { } } } - if (empty($fields)) { $fieldData = $model->loadInfo(); $fields = $fieldData->extract('{n}.name'); @@ -1407,9 +1430,21 @@ class DboSource extends DataSource { if ($dot === false) { $fields[$i] = $prepend . $this->name($alias) . '.' . $this->name($fields[$i]); } else { - $build = explode('.', $fields[$i]); - if (!Set::numeric($build)) { - $fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]); + $comma = strrpos($fields[$i], ','); + if ($comma === false) { + $build = explode('.', $fields[$i]); + if (!Set::numeric($build)) { + $fields[$i] = $prepend . $this->name($build[0]) . '.' . $this->name($build[1]); + } + } else { + $comma = explode(',', $fields[$i]); + foreach ($comma as $string) { + $build = explode('.', $string); + if (!Set::numeric($build)) { + $value[] = $prepend . $this->name(trim($build[0])) . '.' . $this->name(trim($build[1])); + } + } + $fields[$i] = implode(', ', $value); } } } elseif (preg_match('/\(([\.\w]+)\)/', $fields[$i], $field)) { diff --git a/cake/tests/cases/libs/model/datasources/dbo_source.test.php b/cake/tests/cases/libs/model/datasources/dbo_source.test.php index 8dbf6c2f4..70050dafe 100644 --- a/cake/tests/cases/libs/model/datasources/dbo_source.test.php +++ b/cake/tests/cases/libs/model/datasources/dbo_source.test.php @@ -953,12 +953,12 @@ class DboSourceTest extends UnitTestCase { $this->assertPattern('/\s+FROM\s+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result); $this->assertPattern('/\s+WHERE\s+(?:\()?`TestModel5`.`name`\s+!=\s+\'mariano\'(?:\))?\s*$/', $result); } - + function testGenerateAssociationQueryHasManyWithFields() { $this->model = new TestModel5(); $this->model->loadInfo(); $this->_buildRelatedModels($this->model); - + $binding = array('type' => 'hasMany', 'model' => 'TestModel6'); $queryData = array('fields' => array('`TestModel5`.`name`')); $resultSet = null; @@ -972,10 +972,10 @@ class DboSourceTest extends UnitTestCase { $this->assertPattern('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+IN\s+\({\$__cakeID__\$}\)(?:\))?/', $result); $result = $this->db->generateAssociationQuery($this->model, $null, null, null, null, $queryData, false, $null); - $this->assertPattern('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result); + $this->assertPattern('/^SELECT\s+`TestModel5`\.`name`, `TestModel5`\.`id`\s+/', $result); $this->assertPattern('/\s+FROM\s+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result); $this->assertPattern('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result); - + $binding = array('type' => 'hasMany', 'model' => 'TestModel6'); $queryData = array('fields' => array('`TestModel5`.`id`, `TestModel5`.`name`')); $resultSet = null; @@ -992,7 +992,7 @@ class DboSourceTest extends UnitTestCase { $this->assertPattern('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result); $this->assertPattern('/\s+FROM\s+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result); $this->assertPattern('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result); - + $binding = array('type' => 'hasMany', 'model' => 'TestModel6'); $queryData = array('fields' => array('`TestModel5`.`name`', '`TestModel5`.`created`')); $resultSet = null; @@ -1006,12 +1006,12 @@ class DboSourceTest extends UnitTestCase { $this->assertPattern('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+IN\s+\({\$__cakeID__\$}\)(?:\))?/', $result); $result = $this->db->generateAssociationQuery($this->model, $null, null, null, null, $queryData, false, $null); - $this->assertPattern('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`, `TestModel5`\.`created`\s+/', $result); + $this->assertPattern('/^SELECT\s+`TestModel5`\.`name`, `TestModel5`\.`created`, `TestModel5`\.`id`\s+/', $result); $this->assertPattern('/\s+FROM\s+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result); $this->assertPattern('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result); - + $this->model->hasMany['TestModel6']['fields'] = array('name'); - + $binding = array('type' => 'hasMany', 'model' => 'TestModel6'); $queryData = array('fields' => array('`TestModel5`.`id`', '`TestModel5`.`name`')); $resultSet = null; @@ -1020,7 +1020,7 @@ class DboSourceTest extends UnitTestCase { $params = &$this->_prepareAssociationQuery($this->model, $queryData, $binding); $result = $this->db->generateAssociationQuery($this->model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet); - $this->assertPattern('/^SELECT\s+`TestModel6`\.`test_model5_id`, `TestModel6`\.`name`\s+/', $result); + $this->assertPattern('/^SELECT\s+`TestModel6`\.`name`, `TestModel6`\.`test_model5_id`\s+/', $result); $this->assertPattern('/\s+FROM\s+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result); $this->assertPattern('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+IN\s+\({\$__cakeID__\$}\)(?:\))?/', $result); @@ -1028,11 +1028,11 @@ class DboSourceTest extends UnitTestCase { $this->assertPattern('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result); $this->assertPattern('/\s+FROM\s+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result); $this->assertPattern('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result); - + unset($this->model->hasMany['TestModel6']['fields']); - + $this->model->hasMany['TestModel6']['fields'] = array('id', 'name'); - + $binding = array('type' => 'hasMany', 'model' => 'TestModel6'); $queryData = array('fields' => array('`TestModel5`.`id`', '`TestModel5`.`name`')); $resultSet = null; @@ -1041,7 +1041,7 @@ class DboSourceTest extends UnitTestCase { $params = &$this->_prepareAssociationQuery($this->model, $queryData, $binding); $result = $this->db->generateAssociationQuery($this->model, $params['linkModel'], $params['type'], $params['assoc'], $params['assocData'], $queryData, $params['external'], $resultSet); - $this->assertPattern('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`test_model5_id`, `TestModel6`\.`name`\s+/', $result); + $this->assertPattern('/^SELECT\s+`TestModel6`\.`id`, `TestModel6`\.`name`, `TestModel6`\.`test_model5_id`\s+/', $result); $this->assertPattern('/\s+FROM\s+`test_model6` AS `TestModel6`\s+WHERE\s+/', $result); $this->assertPattern('/WHERE\s+(?:\()?`TestModel6`\.`test_model5_id`\s+IN\s+\({\$__cakeID__\$}\)(?:\))?/', $result); @@ -1049,11 +1049,11 @@ class DboSourceTest extends UnitTestCase { $this->assertPattern('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result); $this->assertPattern('/\s+FROM\s+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result); $this->assertPattern('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result); - + unset($this->model->hasMany['TestModel6']['fields']); - + $this->model->hasMany['TestModel6']['fields'] = array('test_model5_id', 'name'); - + $binding = array('type' => 'hasMany', 'model' => 'TestModel6'); $queryData = array('fields' => array('`TestModel5`.`id`', '`TestModel5`.`name`')); $resultSet = null; @@ -1070,7 +1070,7 @@ class DboSourceTest extends UnitTestCase { $this->assertPattern('/^SELECT\s+`TestModel5`\.`id`, `TestModel5`\.`name`\s+/', $result); $this->assertPattern('/\s+FROM\s+`test_model5` AS `TestModel5`\s+WHERE\s+/', $result); $this->assertPattern('/\s+WHERE\s+(?:\()?1\s+=\s+1(?:\))?\s*$/', $result); - + unset($this->model->hasMany['TestModel6']['fields']); }