mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 11:28:25 +00:00
Fixing HABTM associations on non-standard keys, fixes #4219, refactoring DboSource::calculate()
git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6565 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
parent
3ff5bfa829
commit
360b91eea7
9 changed files with 132 additions and 36 deletions
|
@ -783,7 +783,7 @@ class TreeBehavior extends ModelBehavior {
|
|||
*/
|
||||
function __getMax($model, $scope, $right) {
|
||||
$db =& ConnectionManager::getDataSource($model->useDbConfig);
|
||||
list($edge) = array_values($model->find('first', array('conditions' => $scope, 'fields' => $db->calculate('max', array($right)), 'recursive' => -1)));
|
||||
list($edge) = array_values($model->find('first', array('conditions' => $scope, 'fields' => $db->calculate($model, 'max', array($right)), 'recursive' => -1)));
|
||||
return ife(empty ($edge[$right]), 0, $edge[$right]);
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -697,7 +697,6 @@ class DboSource extends DataSource {
|
|||
|
||||
if (!empty($fetch) && is_array($fetch)) {
|
||||
if ($recursive > 0) {
|
||||
|
||||
foreach ($linkModel->__associations as $type1) {
|
||||
foreach ($linkModel->{$type1} as $assoc1 => $assocData1) {
|
||||
$deepModel =& $linkModel->{$assoc1};
|
||||
|
@ -733,8 +732,8 @@ class DboSource extends DataSource {
|
|||
$joinKeys = array($foreignKey, $model->hasAndBelongsToMany[$association]['associationForeignKey']);
|
||||
list($with, $habtmFields) = $model->joinModel($model->hasAndBelongsToMany[$association]['with'], $joinKeys);
|
||||
$habtmFieldsCount = count($habtmFields);
|
||||
|
||||
$q = $this->insertQueryData($query, null, $association, $assocData, $model, $linkModel, $stack);
|
||||
|
||||
if ($q != false) {
|
||||
$fetch = $this->fetchAll($q, $model->cacheQueries, $model->alias);
|
||||
} else {
|
||||
|
@ -775,14 +774,19 @@ class DboSource extends DataSource {
|
|||
}
|
||||
}
|
||||
if ($type == 'hasAndBelongsToMany') {
|
||||
$merge = array();
|
||||
$uniqueIds = $merge = array();
|
||||
|
||||
foreach($fetch as $j => $data) {
|
||||
if (isset($data[$with]) && $data[$with][$foreignKey] === $row[$model->alias][$model->primaryKey]) {
|
||||
if ($habtmFieldsCount > 2) {
|
||||
$merge[] = $data;
|
||||
} else {
|
||||
$merge[] = Set::diff($data, array($with => $data[$with]));
|
||||
if (
|
||||
(isset($data[$with]) && $data[$with][$foreignKey] === $row[$model->alias][$model->primaryKey]) &&
|
||||
(!in_array($data[$with][$joinKeys[1]], $uniqueIds))
|
||||
) {
|
||||
$uniqueIds[] = $data[$with][$joinKeys[1]];
|
||||
|
||||
if ($habtmFieldsCount <= 2) {
|
||||
unset($data[$with]);
|
||||
}
|
||||
$merge[] = $data;
|
||||
}
|
||||
}
|
||||
if (empty($merge) && !isset($row[$association])) {
|
||||
|
@ -1358,12 +1362,13 @@ class DboSource extends DataSource {
|
|||
/**
|
||||
* Returns the an SQL calculation, i.e. COUNT() or MAX()
|
||||
*
|
||||
* @param model $model
|
||||
* @param string $func Lowercase name of SQL function, i.e. 'count' or 'max'
|
||||
* @param array $params Function parameters (any values must be quoted manually)
|
||||
* @return string An SQL calculation function
|
||||
* @access public
|
||||
*/
|
||||
function calculate($func, $params = array()) {
|
||||
function calculate(&$model, $func, $params = array()) {
|
||||
|
||||
switch (strtolower($func)) {
|
||||
case 'count':
|
||||
|
|
|
@ -1331,11 +1331,11 @@ class Model extends Overloadable {
|
|||
break;
|
||||
default:
|
||||
if ($options['atomic']) {
|
||||
if ($validates) {
|
||||
return ($db->commit($this) !== false);
|
||||
} else {
|
||||
$db->rollback($this);
|
||||
if ($validates && ($db->commit($this) !== false)) {
|
||||
return true;
|
||||
}
|
||||
$db->rollback($this);
|
||||
return false;
|
||||
}
|
||||
return $validates;
|
||||
break;
|
||||
|
@ -1779,7 +1779,7 @@ class Model extends Overloadable {
|
|||
if ($state == 'before') {
|
||||
if (empty($query['fields'])) {
|
||||
$db =& ConnectionManager::getDataSource($this->useDbConfig);
|
||||
$query['fields'] = $db->calculate('count');
|
||||
$query['fields'] = $db->calculate($this, 'count');
|
||||
}
|
||||
$query['order'] = false;
|
||||
return $query;
|
||||
|
|
|
@ -2139,25 +2139,25 @@ class DboSourceTest extends CakeTestCase {
|
|||
}
|
||||
|
||||
function testCalculations() {
|
||||
$result = $this->db->calculate('count');
|
||||
$result = $this->db->calculate($this->Model, 'count');
|
||||
$this->assertEqual($result, 'COUNT(*) AS `count`');
|
||||
|
||||
$result = $this->db->calculate('count', array('id'));
|
||||
$result = $this->db->calculate($this->Model, 'count', array('id'));
|
||||
$this->assertEqual($result, 'COUNT(`id`) AS `count`');
|
||||
|
||||
$result = $this->db->calculate('count', array('id', 'id_count'));
|
||||
$result = $this->db->calculate($this->Model, 'count', array('id', 'id_count'));
|
||||
$this->assertEqual($result, 'COUNT(`id`) AS `id_count`');
|
||||
|
||||
$result = $this->db->calculate('count', array('Model.id', 'id_count'));
|
||||
$result = $this->db->calculate($this->Model, 'count', array('Model.id', 'id_count'));
|
||||
$this->assertEqual($result, 'COUNT(`Model`.`id`) AS `id_count`');
|
||||
|
||||
$result = $this->db->calculate('max', array('id'));
|
||||
$result = $this->db->calculate($this->Model, 'max', array('id'));
|
||||
$this->assertEqual($result, 'MAX(`id`) AS `id`');
|
||||
|
||||
$result = $this->db->calculate('max', array('Model.id', 'id'));
|
||||
$result = $this->db->calculate($this->Model, 'max', array('Model.id', 'id'));
|
||||
$this->assertEqual($result, 'MAX(`Model`.`id`) AS `id`');
|
||||
|
||||
$result = $this->db->calculate('max', array('`Model`.`id`', 'id'));
|
||||
$result = $this->db->calculate($this->Model, 'max', array('`Model`.`id`', 'id'));
|
||||
$this->assertEqual($result, 'MAX(`Model`.`id`) AS `id`');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ class ModelTest extends CakeTestCase {
|
|||
'core.syfile', 'core.image', 'core.device_type', 'core.device_type_category', 'core.feature_set', 'core.exterior_type_category',
|
||||
'core.document', 'core.device', 'core.document_directory', 'core.primary_model', 'core.secondary_model', 'core.something',
|
||||
'core.something_else', 'core.join_thing', 'core.join_a', 'core.join_b', 'core.join_c', 'core.join_a_b', 'core.join_a_c',
|
||||
'core.uuid'
|
||||
'core.uuid', 'core.data_test', 'core.posts_tag'
|
||||
);
|
||||
|
||||
function start() {
|
||||
|
@ -2980,12 +2980,46 @@ class ModelTest extends CakeTestCase {
|
|||
}
|
||||
|
||||
function testZeroDefaultFieldValue() {
|
||||
$this->loadFixtures('Uuid');
|
||||
$this->model =& new Uuid();
|
||||
$this->loadFixtures('DataTest');
|
||||
$this->model =& new DataTest();
|
||||
|
||||
$this->model->create() && $this->model->save();
|
||||
$this->model->create(array('float' => '')) && $this->model->save();
|
||||
$result = $this->model->findById($this->model->id);
|
||||
$this->assertIdentical($result['Uuid']['count'], '0');
|
||||
$this->assertIdentical($result['DataTest']['count'], '0');
|
||||
$this->assertIdentical($result['DataTest']['float'], '0');
|
||||
}
|
||||
|
||||
function testNonNumericHabtmJoinKey() {
|
||||
$this->loadFixtures('Post', 'Tag', 'PostsTag');
|
||||
$this->Post =& new Post();
|
||||
$this->Post->bind('Tag', array('type' => 'hasAndBelongsToMany'));
|
||||
$this->Post->Tag->primaryKey = 'tag';
|
||||
|
||||
$result = $this->Post->find('all');
|
||||
$expected = array(
|
||||
array(
|
||||
'Post' => array('id' => '1', 'author_id' => '1', 'title' => 'First Post', 'body' => 'First Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
|
||||
'Author' => array('id' => null, 'user' => null, 'password' => null, 'created' => null, 'updated' => null, 'test' => 'working'),
|
||||
'Tag' => array(
|
||||
array('id' => '1', 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'),
|
||||
array('id' => '2', 'tag' => 'tag2', 'created' => '2007-03-18 12:24:23', 'updated' => '2007-03-18 12:26:31'),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'Post' => array('id' => '2', 'author_id' => '3', 'title' => 'Second Post', 'body' => 'Second Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
|
||||
'Author' => array('id' => null, 'user' => null, 'password' => null, 'created' => null, 'updated' => null, 'test' => 'working'),
|
||||
'Tag' => array(
|
||||
array('id' => '1', 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'),
|
||||
array('id' => '3', 'tag' => 'tag3', 'created' => '2007-03-18 12:26:23', 'updated' => '2007-03-18 12:28:31')
|
||||
)
|
||||
),
|
||||
array(
|
||||
'Post' => array('id' => '3', 'author_id' => '1', 'title' => 'Third Post', 'body' => 'Third Post Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'),
|
||||
'Author' => array('id' => null, 'user' => null, 'password' => null, 'created' => null, 'updated' => null, 'test' => 'working'),
|
||||
'Tag' => array()
|
||||
)
|
||||
);
|
||||
$this->assertEqual($result, $expected);
|
||||
}
|
||||
|
||||
function testAfterFindAssociation() {
|
||||
|
|
|
@ -503,6 +503,15 @@ class Callback extends CakeTestModel {
|
|||
class Uuid extends CakeTestModel {
|
||||
var $name = 'Uuid';
|
||||
}
|
||||
/**
|
||||
* Short description for class.
|
||||
*
|
||||
* @package cake.tests
|
||||
* @subpackage cake.tests.cases.libs.model
|
||||
*/
|
||||
class DataTest extends CakeTestModel {
|
||||
var $name = 'DataTest';
|
||||
}
|
||||
/**
|
||||
* Short description for class.
|
||||
*
|
||||
|
|
|
@ -97,8 +97,8 @@ class TestAppSchema extends CakeSchema {
|
|||
|
||||
var $posts_tags = array(
|
||||
'post_id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'),
|
||||
'tag_id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'),
|
||||
'indexes' => array('UNIQUE_TAG' => array('column'=> array('post_id', 'tag_id'), 'unique'=>1))
|
||||
'tag_id' => array('type' => 'string', 'null' => false),
|
||||
'indexes' => array()
|
||||
);
|
||||
|
||||
var $tags = array(
|
||||
|
|
48
cake/tests/fixtures/data_test_fixture.php
vendored
Normal file
48
cake/tests/fixtures/data_test_fixture.php
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
/* SVN FILE: $Id: data_test_fixture.php 6354 2008-01-10 07:02:33Z nate $ */
|
||||
/**
|
||||
* Short description for file.
|
||||
*
|
||||
* Long description for file
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
|
||||
* Copyright 2005-2008, Cake Software Foundation, Inc.
|
||||
* 1785 E. Sahara Avenue, Suite 490-204
|
||||
* Las Vegas, Nevada 89104
|
||||
*
|
||||
* Licensed under The Open Group Test Suite License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @filesource
|
||||
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc.
|
||||
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
|
||||
* @package cake.tests
|
||||
* @subpackage cake.tests.fixtures
|
||||
* @since CakePHP(tm) v 1.2.0.6700
|
||||
* @version $Revision: 6354 $
|
||||
* @modifiedby $LastChangedBy: nate $
|
||||
* @lastmodified $Date: 2008-01-10 02:02:33 -0500 (Thu, 10 Jan 2008) $
|
||||
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
|
||||
*/
|
||||
/**
|
||||
* Short description for class.
|
||||
*
|
||||
* @package cake.tests
|
||||
* @subpackage cake.tests.fixtures
|
||||
*/
|
||||
class DataTestFixture extends CakeTestFixture {
|
||||
var $name = 'DataTest';
|
||||
var $fields = array(
|
||||
'id' => array('type' => 'integer', 'key' => 'primary'),
|
||||
'count' => array('type' => 'integer', 'default' => 0),
|
||||
'float' => array('type' => 'float', 'default' => 0),
|
||||
//'timestamp' => array('type' => 'timestamp', 'default' => null, 'null' => true),
|
||||
'created' => array('type' => 'datetime', 'default' => null),
|
||||
'updated' => array('type' => 'datetime', 'default' => null)
|
||||
);
|
||||
var $records = array();
|
||||
}
|
||||
|
||||
?>
|
12
cake/tests/fixtures/posts_tag_fixture.php
vendored
12
cake/tests/fixtures/posts_tag_fixture.php
vendored
|
@ -36,14 +36,14 @@ class PostsTagFixture extends CakeTestFixture {
|
|||
var $name = 'PostsTag';
|
||||
var $fields = array(
|
||||
'post_id' => array('type' => 'integer', 'null' => false),
|
||||
'tag_id' => array('type' => 'integer', 'null' => false),
|
||||
'indexes' => array('UNIQUE_TAG' => array('column'=> array('post_id', 'tag_id'), 'unique'=> 1))
|
||||
'tag_id' => array('type' => 'string', 'null' => false),
|
||||
);
|
||||
|
||||
var $records = array(
|
||||
array('post_id' => 1, 'tag_id' => 1),
|
||||
array('post_id' => 1, 'tag_id' => 2),
|
||||
array('post_id' => 2, 'tag_id' => 1),
|
||||
array('post_id' => 2, 'tag_id' => 3)
|
||||
array('post_id' => 1, 'tag_id' => 'tag1'),
|
||||
array('post_id' => 1, 'tag_id' => 'tag2'),
|
||||
array('post_id' => 2, 'tag_id' => 'tag1'),
|
||||
array('post_id' => 2, 'tag_id' => 'tag3')
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue