mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 11:28:25 +00:00
Implemented 'counterCache' and 'counterScope' for belongsTo associations
Exempted 'created', 'updated' and 'modified' fields from whitelist when saving, closes #3720 Updated Model::bind(), closes #2355 Adding Model::saveAll() to save multiple records and associated records, closes #3615 Replacing Model::generateList() with Model::find('list'), deprecates Model::generateList() git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6295 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
parent
43e05117fa
commit
5abe66289d
9 changed files with 339 additions and 71 deletions
|
@ -293,7 +293,7 @@ class ControllerTask extends Shell {
|
||||||
$habtmModelName = $this->_modelName($associationName);
|
$habtmModelName = $this->_modelName($associationName);
|
||||||
$habtmSingularName = $this->_singularName($associationName);
|
$habtmSingularName = $this->_singularName($associationName);
|
||||||
$habtmPluralName = $this->_pluralName($associationName);
|
$habtmPluralName = $this->_pluralName($associationName);
|
||||||
$actions .= "\t\t\${$habtmPluralName} = \$this->{$currentModelName}->{$habtmModelName}->generateList();\n";
|
$actions .= "\t\t\${$habtmPluralName} = \$this->{$currentModelName}->{$habtmModelName}->find('list');\n";
|
||||||
$compact[] = "'{$habtmPluralName}'";
|
$compact[] = "'{$habtmPluralName}'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,7 +301,7 @@ class ControllerTask extends Shell {
|
||||||
if (!empty($associationName)) {
|
if (!empty($associationName)) {
|
||||||
$belongsToModelName = $this->_modelName($associationName);
|
$belongsToModelName = $this->_modelName($associationName);
|
||||||
$belongsToPluralName = $this->_pluralName($associationName);
|
$belongsToPluralName = $this->_pluralName($associationName);
|
||||||
$actions .= "\t\t\${$belongsToPluralName} = \$this->{$currentModelName}->{$belongsToModelName}->generateList();\n";
|
$actions .= "\t\t\${$belongsToPluralName} = \$this->{$currentModelName}->{$belongsToModelName}->find('list');\n";
|
||||||
$compact[] = "'{$belongsToPluralName}'";
|
$compact[] = "'{$belongsToPluralName}'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,7 +347,7 @@ class ControllerTask extends Shell {
|
||||||
$habtmModelName = $this->_modelName($associationName);
|
$habtmModelName = $this->_modelName($associationName);
|
||||||
$habtmSingularName = $this->_singularName($associationName);
|
$habtmSingularName = $this->_singularName($associationName);
|
||||||
$habtmPluralName = $this->_pluralName($associationName);
|
$habtmPluralName = $this->_pluralName($associationName);
|
||||||
$actions .= "\t\t\${$habtmPluralName} = \$this->{$currentModelName}->{$habtmModelName}->generateList();\n";
|
$actions .= "\t\t\${$habtmPluralName} = \$this->{$currentModelName}->{$habtmModelName}->find('list');\n";
|
||||||
$compact[] = "'{$habtmPluralName}'";
|
$compact[] = "'{$habtmPluralName}'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,7 @@ class ControllerTask extends Shell {
|
||||||
if (!empty($associationName)) {
|
if (!empty($associationName)) {
|
||||||
$belongsToModelName = $this->_modelName($associationName);
|
$belongsToModelName = $this->_modelName($associationName);
|
||||||
$belongsToPluralName = $this->_pluralName($associationName);
|
$belongsToPluralName = $this->_pluralName($associationName);
|
||||||
$actions .= "\t\t\${$belongsToPluralName} = \$this->{$currentModelName}->{$belongsToModelName}->generateList();\n";
|
$actions .= "\t\t\${$belongsToPluralName} = \$this->{$currentModelName}->{$belongsToModelName}->find('list');\n";
|
||||||
$compact[] = "'{$belongsToPluralName}'";
|
$compact[] = "'{$belongsToPluralName}'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,11 +310,11 @@ class Scaffold extends Object {
|
||||||
|
|
||||||
foreach ($this->ScaffoldModel->belongsTo as $assocName => $assocData) {
|
foreach ($this->ScaffoldModel->belongsTo as $assocName => $assocData) {
|
||||||
$varName = Inflector::variable(Inflector::pluralize(preg_replace('/_id$/', '', $assocData['foreignKey'])));
|
$varName = Inflector::variable(Inflector::pluralize(preg_replace('/_id$/', '', $assocData['foreignKey'])));
|
||||||
$this->controller->set($varName, $this->ScaffoldModel->{$assocName}->generateList());
|
$this->controller->set($varName, $this->ScaffoldModel->{$assocName}->find('list'));
|
||||||
}
|
}
|
||||||
foreach ($this->ScaffoldModel->hasAndBelongsToMany as $assocName => $assocData) {
|
foreach ($this->ScaffoldModel->hasAndBelongsToMany as $assocName => $assocData) {
|
||||||
$varName = Inflector::variable(Inflector::pluralize($assocName));
|
$varName = Inflector::variable(Inflector::pluralize($assocName));
|
||||||
$this->controller->set($varName, $this->ScaffoldModel->{$assocName}->generateList());
|
$this->controller->set($varName, $this->ScaffoldModel->{$assocName}->find('list'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->__scaffoldForm($formAction);
|
return $this->__scaffoldForm($formAction);
|
||||||
|
|
|
@ -239,7 +239,7 @@ class TranslateBehavior extends ModelBehavior {
|
||||||
$RuntimeModel =& $this->translateModel($model);
|
$RuntimeModel =& $this->translateModel($model);
|
||||||
|
|
||||||
if (empty($created)) {
|
if (empty($created)) {
|
||||||
$translations = $RuntimeModel->generateList(array_merge($conditions, array($RuntimeModel->displayField => array_keys($tempData))));
|
$translations = $RuntimeModel->find('list', array('conditions' => array_merge($conditions, array($RuntimeModel->displayField => array_keys($tempData)))));
|
||||||
|
|
||||||
if ($translations) {
|
if ($translations) {
|
||||||
foreach ($translations as $id => $field) {
|
foreach ($translations as $id => $field) {
|
||||||
|
|
|
@ -246,6 +246,30 @@ class DataSource extends Object {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Begin a transaction
|
||||||
|
*
|
||||||
|
* @return boolean True
|
||||||
|
*/
|
||||||
|
function begin() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Commit a transaction
|
||||||
|
*
|
||||||
|
* @return boolean True
|
||||||
|
*/
|
||||||
|
function commit(&$model) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Rollback a transaction
|
||||||
|
*
|
||||||
|
* @return boolean True
|
||||||
|
*/
|
||||||
|
function rollback(&$model) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Converts column types to basic types
|
* Converts column types to basic types
|
||||||
*
|
*
|
||||||
|
|
|
@ -310,7 +310,7 @@ class Model extends Overloadable {
|
||||||
* @var array
|
* @var array
|
||||||
* @access private
|
* @access private
|
||||||
*/
|
*/
|
||||||
var $__findMethods = array('all' => true, 'first' => true, 'count' => true, 'neighbors' => true);
|
var $__findMethods = array('all' => true, 'first' => true, 'count' => true, 'neighbors' => true, 'list' => true);
|
||||||
/**
|
/**
|
||||||
* Constructor. Binds the Model's database table to the object.
|
* Constructor. Binds the Model's database table to the object.
|
||||||
*
|
*
|
||||||
|
@ -495,13 +495,14 @@ class Model extends Overloadable {
|
||||||
* If $permanent is true, association will not be reset
|
* If $permanent is true, association will not be reset
|
||||||
* to the originals defined in the model.
|
* to the originals defined in the model.
|
||||||
*
|
*
|
||||||
* @param array $model Set of binding options (indexed by model name type)
|
* @param mixed $model A model or association name (string) or set of binding options (indexed by model name type)
|
||||||
* @param array $options Currently not used
|
* @param array $options If $model is a string, this is the list of association properties with which $model will
|
||||||
|
* be bound
|
||||||
* @param boolean $permanent Set to true to make the binding permanent
|
* @param boolean $permanent Set to true to make the binding permanent
|
||||||
* @access public
|
* @access public
|
||||||
* @todo
|
* @todo
|
||||||
*/
|
*/
|
||||||
function bind($model, $options, $permanent = true) {
|
function bind($model, $options = array(), $permanent = true) {
|
||||||
if (!is_array($model)) {
|
if (!is_array($model)) {
|
||||||
$model = array($model => $options);
|
$model = array($model => $options);
|
||||||
}
|
}
|
||||||
|
@ -511,21 +512,28 @@ class Model extends Overloadable {
|
||||||
$assoc = $options['type'];
|
$assoc = $options['type'];
|
||||||
} elseif (isset($options[0])) {
|
} elseif (isset($options[0])) {
|
||||||
$assoc = $options[0];
|
$assoc = $options[0];
|
||||||
|
} else {
|
||||||
|
$assoc = 'belongsTo';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$permanent) {
|
if (!$permanent) {
|
||||||
$this->__backAssociation[$assoc] = $this->{$assoc};
|
$this->__backAssociation[$assoc] = $this->{$assoc};
|
||||||
}
|
}
|
||||||
foreach ($model as $key => $value) {
|
foreach ($model as $key => $value) {
|
||||||
$assocName = $key;
|
$assocName = $modelName = $key;
|
||||||
$modelName = $key;
|
|
||||||
|
|
||||||
if (isset($value['className'])) {
|
if (isset($this->{$assoc}[$assocName])) {
|
||||||
$modelName = $value['className'];
|
$this->{$assoc}[$assocName] = array_merge($this->{$assoc}[$assocName], $options);
|
||||||
|
} else {
|
||||||
|
if (isset($value['className'])) {
|
||||||
|
$modelName = $value['className'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->__constructLinkedModel($assocName, $modelName);
|
||||||
|
$this->{$assoc}[$assocName] = $model[$assocName];
|
||||||
|
$this->__generateAssociation($assoc);
|
||||||
}
|
}
|
||||||
|
unset($this->{$assoc}[$assocName]['type'], $this->{$assoc}[$assocName][0]);
|
||||||
$this->__constructLinkedModel($assocName, $modelName);
|
|
||||||
$this->{$assoc}[$assocName] = $model[$assocName];
|
|
||||||
$this->__generateAssociation($assoc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1124,6 +1132,11 @@ class Model extends Overloadable {
|
||||||
$fields = array_keys($this->data[$this->alias]);
|
$fields = array_keys($this->data[$this->alias]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($validate && !$this->validates()) {
|
||||||
|
$this->whitelist = $_whitelist;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($dateFields as $updateCol) {
|
foreach ($dateFields as $updateCol) {
|
||||||
if ($this->hasField($updateCol) && !in_array($updateCol, $fields)) {
|
if ($this->hasField($updateCol) && !in_array($updateCol, $fields)) {
|
||||||
$colType = array_merge(array('formatter' => 'date'), $db->columns[$this->getColumnType($updateCol)]);
|
$colType = array_merge(array('formatter' => 'date'), $db->columns[$this->getColumnType($updateCol)]);
|
||||||
|
@ -1132,15 +1145,13 @@ class Model extends Overloadable {
|
||||||
} else {
|
} else {
|
||||||
$time = $colType['formatter']($colType['format']);
|
$time = $colType['formatter']($colType['format']);
|
||||||
}
|
}
|
||||||
|
if (!empty($this->whitelist)) {
|
||||||
|
$this->whitelist[] = $updateCol;
|
||||||
|
}
|
||||||
$this->set($updateCol, $time);
|
$this->set($updateCol, $time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($validate && !$this->validates()) {
|
|
||||||
$this->whitelist = $_whitelist;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($this->behaviors)) {
|
if (!empty($this->behaviors)) {
|
||||||
$behaviors = array_keys($this->behaviors);
|
$behaviors = array_keys($this->behaviors);
|
||||||
$ct = count($behaviors);
|
$ct = count($behaviors);
|
||||||
|
@ -1207,11 +1218,7 @@ class Model extends Overloadable {
|
||||||
} else {
|
} else {
|
||||||
$created = true;
|
$created = true;
|
||||||
if (!empty($this->belongsTo)) {
|
if (!empty($this->belongsTo)) {
|
||||||
foreach ($this->belongsTo as $parent => $assoc) {
|
$this->updateCounterCache();
|
||||||
if (isset($assoc['counterCache']) && !empty($assoc['counterCache'])) {
|
|
||||||
$parentObj =& $this->{$assoc['className']};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1294,6 +1301,103 @@ class Model extends Overloadable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Updates the counter cache of belongsTo associations after a save or delete operation
|
||||||
|
*
|
||||||
|
* @param array $keys Optional foreign key data, defaults to the information $this->data
|
||||||
|
* @return void
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function updateCounterCache($keys = array()) {
|
||||||
|
if (empty($keys)) {
|
||||||
|
$keys = $this->data[$this->alias];
|
||||||
|
}
|
||||||
|
foreach ($this->belongsTo as $parent => $assoc) {
|
||||||
|
if (!empty($assoc['counterCache'])) {
|
||||||
|
if ($assoc['counterCache'] === true) {
|
||||||
|
$assoc['counterCache'] = Inflector::underscore($this->alias) . '_count';
|
||||||
|
}
|
||||||
|
if ($this->{$parent}->hasField($assoc['counterCache'])) {
|
||||||
|
$conditions = array($this->escapeField($assoc['foreignKey']) => $keys[$assoc['foreignKey']]);
|
||||||
|
if (isset($assoc['counterScope'])) {
|
||||||
|
$conditions = array_merge($conditions, (array)$assoc['counterScope']);
|
||||||
|
}
|
||||||
|
$this->{$parent}->updateAll(
|
||||||
|
array($assoc['counterCache'] => intval($this->find('count', compact('conditions')))),
|
||||||
|
array($this->{$parent}->escapeField() => $keys[$assoc['foreignKey']])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Saves (a) multiple individual records for a single model or (b) this record, as well as
|
||||||
|
* all associated records
|
||||||
|
*
|
||||||
|
* @param array $data Record data to save
|
||||||
|
* @param array $options
|
||||||
|
* @return mixed True on success, or an array of validation errors on failure
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function saveAll($data = null, $options = array()) {
|
||||||
|
if (empty($data)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$db =& ConnectionManager::getDataSource($this->useDbConfig);
|
||||||
|
|
||||||
|
$options = array_merge(
|
||||||
|
array('validate' => true, 'fieldList' => array(), 'atomic' => true),
|
||||||
|
$options
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($options['atomic']) {
|
||||||
|
$db->begin($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Set::numeric(array_keys($data))) {
|
||||||
|
foreach ($data as $record) {
|
||||||
|
if (!($this->create($record) && $this->save(null, $options['validate'], $options['fieldList'])) && $options['atomic']) {
|
||||||
|
$db->rollback($this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$associations = $this->getAssociated();
|
||||||
|
|
||||||
|
foreach ($data as $association => $values) {
|
||||||
|
if (isset($associations[$association]) && ($type = $associations[$association]) == 'belongsTo') {
|
||||||
|
$alias = $this->{$association}->alias;
|
||||||
|
$foreignKey = $this->{$type}[$association]['foreignKey'];
|
||||||
|
|
||||||
|
if (!$result = $this->{$association}->save($values, $options['validate'], $options['fieldList'])) {
|
||||||
|
$db->rollback($this);
|
||||||
|
return false;
|
||||||
|
} elseif (!isset($data[$foreignKey]) || empty($data[$foreignKey])) {
|
||||||
|
$data[$this->alias][$foreignKey] = $this->{$association}->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->save($data[$this->alias], $options['validate'], $options['fieldList'])) {
|
||||||
|
$db->rollback($this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($data as $association => $values) {
|
||||||
|
if (isset($associations[$association])) {
|
||||||
|
switch ($associations[$association]) {
|
||||||
|
case 'hasMany':
|
||||||
|
$this->{$association}->saveAll($values);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($options['atomic']) {
|
||||||
|
$db->commit($this);
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Allows model records to be updated based on a set of conditions
|
* Allows model records to be updated based on a set of conditions
|
||||||
*
|
*
|
||||||
|
@ -1348,7 +1452,14 @@ class Model extends Overloadable {
|
||||||
$this->_deleteLinks($id);
|
$this->_deleteLinks($id);
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
|
|
||||||
|
if (!empty($this->belongsTo)) {
|
||||||
|
$keys = $this->find('first', array('fields', $this->__collectForeignKeys()));
|
||||||
|
}
|
||||||
|
|
||||||
if ($db->delete($this)) {
|
if ($db->delete($this)) {
|
||||||
|
if (!empty($this->belongsTo)) {
|
||||||
|
$this->updateCounterCache($keys[$this->alias]);
|
||||||
|
}
|
||||||
if (!empty($this->behaviors)) {
|
if (!empty($this->behaviors)) {
|
||||||
for ($i = 0; $i < $ct; $i++) {
|
for ($i = 0; $i < $ct; $i++) {
|
||||||
$this->behaviors[$behaviors[$i]]->afterDelete($this);
|
$this->behaviors[$behaviors[$i]]->afterDelete($this);
|
||||||
|
@ -1393,11 +1504,16 @@ class Model extends Overloadable {
|
||||||
$model =& $this->{$assoc};
|
$model =& $this->{$assoc};
|
||||||
$field = $model->escapeField($data['foreignKey']);
|
$field = $model->escapeField($data['foreignKey']);
|
||||||
$model->recursive = -1;
|
$model->recursive = -1;
|
||||||
$records = $model->findAll(array($field => $id), $model->primaryKey);
|
|
||||||
|
|
||||||
if (!empty($records)) {
|
if (isset($data['exclusive']) && $data['exclusive']) {
|
||||||
foreach ($records as $record) {
|
$model->deleteAll(array($field => $id));
|
||||||
$model->delete($record[$model->alias][$model->primaryKey]);
|
} else {
|
||||||
|
$records = $model->findAll(array($field => $id), $model->primaryKey);
|
||||||
|
|
||||||
|
if (!empty($records)) {
|
||||||
|
foreach ($records as $record) {
|
||||||
|
$model->delete($record[$model->alias][$model->primaryKey]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1476,6 +1592,21 @@ class Model extends Overloadable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Collects foreign keys from associations
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function __collectForeignKeys($type = 'belongsTo') {
|
||||||
|
$result = array();
|
||||||
|
|
||||||
|
foreach ($this->{$type} as $assoc => $data) {
|
||||||
|
if (isset($data['foreignKey']) && is_string($data['foreignKey'])) {
|
||||||
|
$result[$assoc] = $data['foreignKey'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Returns true if a record with set id exists.
|
* Returns true if a record with set id exists.
|
||||||
*
|
*
|
||||||
|
@ -1547,13 +1678,26 @@ class Model extends Overloadable {
|
||||||
$query
|
$query
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($type == 'count') {
|
switch ($type) {
|
||||||
if (empty($query['fields'])) {
|
case 'count' :
|
||||||
$query['fields'] = 'COUNT(*) AS ' . $db->name('count');
|
if (empty($query['fields'])) {
|
||||||
}
|
$query['fields'] = 'COUNT(*) AS ' . $db->name('count');
|
||||||
$query['order'] = false;
|
}
|
||||||
} elseif ($type == 'first') {
|
$query['order'] = false;
|
||||||
$query['limit'] = 1;
|
break;
|
||||||
|
case 'first' :
|
||||||
|
$query['limit'] = 1;
|
||||||
|
if (empty($query['conditions']) && !empty($this->id)) {
|
||||||
|
$query['conditions'] = array($this->escapeField() => $this->id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'list' :
|
||||||
|
if (empty($query['fields'])) {
|
||||||
|
$query['fields'] = array("{$this->alias}.{$this->primaryKey}", "{$this->alias}.{$this->displayField}");
|
||||||
|
}
|
||||||
|
$keyPath = "{n}.{$this->alias}.{$this->primaryKey}";
|
||||||
|
$valuePath = "{n}.{$this->alias}.{$this->displayField}";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_numeric($query['page']) || intval($query['page']) < 1) {
|
if (!is_numeric($query['page']) || intval($query['page']) < 1) {
|
||||||
|
@ -1618,6 +1762,12 @@ class Model extends Overloadable {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
case 'list':
|
||||||
|
if (empty($results)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
return Set::combine($results, $keyPath, $valuePath);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -1761,7 +1911,7 @@ class Model extends Overloadable {
|
||||||
if ($or) {
|
if ($or) {
|
||||||
$fields = array('or' => $fields);
|
$fields = array('or' => $fields);
|
||||||
}
|
}
|
||||||
return ($this->findCount($fields) == 0);
|
return ($this->find('count', array('conditions' => $fields)) == 0);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Special findAll variation for tables joined to themselves.
|
* Special findAll variation for tables joined to themselves.
|
||||||
|
@ -2028,6 +2178,8 @@ class Model extends Overloadable {
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
function generateList($conditions = null, $order = null, $limit = null, $keyPath = null, $valuePath = null, $groupPath = null) {
|
function generateList($conditions = null, $order = null, $limit = null, $keyPath = null, $valuePath = null, $groupPath = null) {
|
||||||
|
trigger_error(__('(Model::generateList) Deprecated, use Model::find("list") or Model::find("all") and Set::combine()', true), E_USER_WARNING);
|
||||||
|
|
||||||
if ($keyPath == null && $valuePath == null && $groupPath == null && $this->hasField($this->displayField)) {
|
if ($keyPath == null && $valuePath == null && $groupPath == null && $this->hasField($this->displayField)) {
|
||||||
$fields = array($this->primaryKey, $this->displayField);
|
$fields = array($this->primaryKey, $this->displayField);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2048,11 +2200,11 @@ class Model extends Overloadable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($keyPath == null) {
|
if ($keyPath == null) {
|
||||||
$keyPath = '{n}.' . $this->alias . '.' . $this->primaryKey;
|
$keyPath = "{n}.{$this->alias}.{$this->primaryKey}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($valuePath == null) {
|
if ($valuePath == null) {
|
||||||
$valuePath = '{n}.' . $this->alias . '.' . $this->displayField;
|
$valuePath = "{n}.{$this->alias}.{$this->displayField}";
|
||||||
}
|
}
|
||||||
|
|
||||||
return Set::combine($result, $keyPath, $valuePath, $groupPath);
|
return Set::combine($result, $keyPath, $valuePath, $groupPath);
|
||||||
|
|
|
@ -118,6 +118,17 @@ class Article extends CakeTestModel {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Short description for class.
|
||||||
|
*
|
||||||
|
* @package cake.tests
|
||||||
|
* @subpackage cake.tests.cases.libs.model
|
||||||
|
*/
|
||||||
|
class Article10 extends CakeTestModel {
|
||||||
|
var $name = 'Article10';
|
||||||
|
var $useTable = 'articles';
|
||||||
|
var $hasMany = array('Comment' => array('dependent' => true, 'exclusive' => true));
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Short description for class.
|
* Short description for class.
|
||||||
*
|
*
|
||||||
|
@ -392,7 +403,7 @@ class Portfolio extends CakeTestModel {
|
||||||
}
|
}
|
||||||
class Item extends CakeTestModel {
|
class Item extends CakeTestModel {
|
||||||
var $name = 'Item';
|
var $name = 'Item';
|
||||||
var $belongsTo = array('Syfile');
|
var $belongsTo = array('Syfile' => array('counterCache' => true));
|
||||||
var $hasAndBelongsToMany = array('Portfolio');
|
var $hasAndBelongsToMany = array('Portfolio');
|
||||||
}
|
}
|
||||||
class ItemsPortfolio extends CakeTestModel {
|
class ItemsPortfolio extends CakeTestModel {
|
||||||
|
@ -515,12 +526,12 @@ class ModelTest extends CakeTestCase {
|
||||||
'Item' => array(
|
'Item' => array(
|
||||||
array('id' => 2, 'syfile_id' => 2, 'name' => 'Item 2',
|
array('id' => 2, 'syfile_id' => 2, 'name' => 'Item 2',
|
||||||
'ItemsPortfolio' => array('id' => 2, 'item_id' => 2, 'portfolio_id' => 2),
|
'ItemsPortfolio' => array('id' => 2, 'item_id' => 2, 'portfolio_id' => 2),
|
||||||
'Syfile' => array('id' => 2, 'image_id' => 2, 'name' => 'Syfile 2',
|
'Syfile' => array('id' => 2, 'image_id' => 2, 'name' => 'Syfile 2', 'item_count' => null,
|
||||||
'Image' => array('id' => 2, 'name' => 'Image 2'))),
|
'Image' => array('id' => 2, 'name' => 'Image 2'))),
|
||||||
|
|
||||||
array('id' => 6, 'syfile_id' => 6, 'name' => 'Item 6',
|
array('id' => 6, 'syfile_id' => 6, 'name' => 'Item 6',
|
||||||
'ItemsPortfolio' => array('id' => 6, 'item_id' => 6, 'portfolio_id' => 2),
|
'ItemsPortfolio' => array('id' => 6, 'item_id' => 6, 'portfolio_id' => 2),
|
||||||
'Syfile' => array('id' => 6, 'image_id' => null, 'name' => 'Syfile 6',
|
'Syfile' => array('id' => 6, 'image_id' => null, 'name' => 'Syfile 6', 'item_count' => null,
|
||||||
'Image' => array()))));
|
'Image' => array()))));
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
unset($this->Portfolio);
|
unset($this->Portfolio);
|
||||||
|
@ -915,35 +926,30 @@ class ModelTest extends CakeTestCase {
|
||||||
$this->model =& new Article();
|
$this->model =& new Article();
|
||||||
$this->model->displayField = 'title';
|
$this->model->displayField = 'title';
|
||||||
|
|
||||||
$result = $this->model->generateList(null, 'Article.title ASC');
|
$result = $this->model->find('list', array('order' => 'Article.title ASC'));
|
||||||
$expected = array(1 => 'First Article', 2 => 'Second Article', 3 => 'Third Article');
|
$expected = array(1 => 'First Article', 2 => 'Second Article', 3 => 'Third Article');
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
$result = $this->model->generateList(null, 'Article.title ASC', null, '{n}.Article.id');
|
$result = Set::combine($this->model->find('all', array('order' => 'Article.title ASC', 'fields' => array('id', 'title'))), '{n}.Article.id', '{n}.Article.title');
|
||||||
$expected = array(1 => 'First Article', 2 => 'Second Article', 3 => 'Third Article');
|
$expected = array(1 => 'First Article', 2 => 'Second Article', 3 => 'Third Article');
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
$result = $this->model->generateList(null, 'Article.title ASC', null, '{n}.Article.id', '{n}.Article');
|
$result = Set::combine($this->model->find('all', array('order' => 'Article.title ASC')), '{n}.Article.id', '{n}.Article');
|
||||||
$expected = array(
|
$expected = array(
|
||||||
1 => array('id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
|
1 => array('id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
|
||||||
2 => array('id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
|
2 => array('id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
|
||||||
3 => array('id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'));
|
3 => array('id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31'));
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
$result = $this->model->generateList(null, 'Article.title ASC', null, '{n}.Article.id', '{n}.Article.title');
|
$result = Set::combine($this->model->find('all', array('order' => 'Article.title ASC')), '{n}.Article.id', '{n}.Article', '{n}.Article.user_id');
|
||||||
$expected = array(1 => 'First Article', 2 => 'Second Article', 3 => 'Third Article');
|
|
||||||
$this->assertEqual($result, $expected);
|
|
||||||
|
|
||||||
$result = $this->model->generateList(null, 'Article.title ASC', null, '{n}.Article.id', '{n}.Article', '{n}.Article.user_id');
|
|
||||||
$expected = array(1 => array(
|
$expected = array(1 => array(
|
||||||
1 => array('id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
|
1 => array('id' => 1, 'user_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
|
||||||
3 => array('id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')),
|
3 => array('id' => 3, 'user_id' => 1, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')),
|
||||||
3 => array(2 => array('id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31')));
|
3 => array(2 => array('id' => 2, 'user_id' => 3, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31')));
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
$result = $this->model->generateList(null, 'Article.title ASC', null, '{n}.Article.id', '{n}.Article.title', '{n}.Article.user_id');
|
$result = Set::combine($this->model->find('all', array('order' => 'Article.title ASC', 'fields' => array('id', 'title', 'user_id'))), '{n}.Article.id', '{n}.Article.title', '{n}.Article.user_id');
|
||||||
$expected = array(1 => array(1 => 'First Article', 3 => 'Third Article'),
|
$expected = array(1 => array(1 => 'First Article', 3 => 'Third Article'), 3 => array(2 => 'Second Article'));
|
||||||
3 => array(2 => 'Second Article'));
|
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1099,6 +1105,25 @@ class ModelTest extends CakeTestCase {
|
||||||
array('User' => array('id' => '4', 'user' => 'garrett'), 'Comment' => array(
|
array('User' => array('id' => '4', 'user' => 'garrett'), 'Comment' => array(
|
||||||
array('id' => '2', 'article_id' => '1', 'user_id' => '4', 'comment' => 'Second Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'))));
|
array('id' => '2', 'article_id' => '1', 'user_id' => '4', 'comment' => 'Second Comment for First Article', 'published' => 'Y', 'created' => '2007-03-18 10:47:23', 'updated' => '2007-03-18 10:49:31'))));
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
|
|
||||||
|
$this->model2 =& new DeviceType();
|
||||||
|
|
||||||
|
$expected = array('className' => 'FeatureSet', 'foreignKey' => 'feature_set_id', 'conditions' => '', 'fields' => '', 'order' => '', 'counterCache' => '');
|
||||||
|
$this->assertEqual($this->model2->belongsTo['FeatureSet'], $expected);
|
||||||
|
|
||||||
|
$this->model2->bind('FeatureSet', array('conditions' => array('active' => true)));
|
||||||
|
$expected['conditions'] = array('active' => true);
|
||||||
|
$this->assertEqual($this->model2->belongsTo['FeatureSet'], $expected);
|
||||||
|
|
||||||
|
$this->model2->bind('FeatureSet', array('foreignKey' => false, 'conditions' => array('Feature.name' => 'DeviceType.name')));
|
||||||
|
$expected['conditions'] = array('Feature.name' => 'DeviceType.name');
|
||||||
|
$expected['foreignKey'] = false;
|
||||||
|
$this->assertEqual($this->model2->belongsTo['FeatureSet'], $expected);
|
||||||
|
|
||||||
|
$this->model2->bind('NewFeatureSet', array('type' => 'hasMany', 'className' => 'FeatureSet', 'conditions' => array('active' => true)));
|
||||||
|
$expected = array('className' => 'FeatureSet', 'conditions' => array('active' => true), 'foreignKey' => 'device_type_id', 'fields' => '', 'order' => '', 'limit' => '', 'offset' => '', 'dependent' => '', 'exclusive' => '', 'finderQuery' => '', 'counterQuery' => '');
|
||||||
|
$this->assertEqual($this->model2->hasMany['NewFeatureSet'], $expected);
|
||||||
|
$this->assertTrue(is_object($this->model2->NewFeatureSet));
|
||||||
}
|
}
|
||||||
|
|
||||||
function testFindCount() {
|
function testFindCount() {
|
||||||
|
@ -2296,6 +2321,60 @@ class ModelTest extends CakeTestCase {
|
||||||
$this->assertEqual($result, $expected);
|
$this->assertEqual($result, $expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testSaveAll() {
|
||||||
|
$this->model =& new Post();
|
||||||
|
|
||||||
|
$result = $this->model->find('all');
|
||||||
|
$this->assertEqual(count($result), 3);
|
||||||
|
$this->assertFalse(isset($result[3]));
|
||||||
|
$ts = date('Y-m-d H:i:s');
|
||||||
|
|
||||||
|
$this->model->saveAll(array(
|
||||||
|
'Post' => array('title' => 'Post with Author', 'body' => 'This post will be saved with an author'),
|
||||||
|
'Author' => array('user' => 'bob', 'password' => '5f4dcc3b5aa765d61d8327deb882cf90')
|
||||||
|
));
|
||||||
|
|
||||||
|
$result = $this->model->find('all');
|
||||||
|
$expected = array(
|
||||||
|
'Post' => array('id' => '4', 'author_id' => '5', 'title' => 'Post with Author', 'body' => 'This post will be saved with an author', 'published' => 'N', 'created' => $ts, 'updated' => $ts),
|
||||||
|
'Author' => array('id' => '5', 'user' => 'bob', 'password' => '5f4dcc3b5aa765d61d8327deb882cf90', 'created' => $ts, 'updated' => $ts, 'test' => 'working')
|
||||||
|
);
|
||||||
|
$this->assertEqual($result[3], $expected);
|
||||||
|
$this->assertEqual(count($result), 4);
|
||||||
|
|
||||||
|
$this->model->deleteAll(true);
|
||||||
|
$this->assertEqual($this->model->find('all'), array());
|
||||||
|
|
||||||
|
$ts = date('Y-m-d H:i:s');
|
||||||
|
$this->model->saveAll(array(
|
||||||
|
array('title' => 'Multi-record post 1', 'body' => 'First multi-record post', 'author_id' => 2),
|
||||||
|
array('title' => 'Multi-record post 2', 'body' => 'Second multi-record post', 'author_id' => 2)
|
||||||
|
));
|
||||||
|
|
||||||
|
$result = $this->model->find('all', array('recursive' => -1));
|
||||||
|
$expected = array(
|
||||||
|
array('Post' => array('id' => '6', 'author_id' => '2', 'title' => 'Multi-record post 2', 'body' => 'Second multi-record post', 'published' => 'N', 'created' => $ts, 'updated' => $ts)),
|
||||||
|
array('Post' => array('id' => '5', 'author_id' => '2', 'title' => 'Multi-record post 1', 'body' => 'First multi-record post', 'published' => 'N', 'created' => $ts, 'updated' => $ts))
|
||||||
|
);
|
||||||
|
$this->assertEqual($result, $expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSaveWithCounterCache() {
|
||||||
|
$this->model =& new Syfile();
|
||||||
|
$this->model2 =& new Item();
|
||||||
|
|
||||||
|
$result = $this->model->findById(1);
|
||||||
|
$this->assertIdentical($result['Syfile']['item_count'], null);
|
||||||
|
|
||||||
|
$this->model2->save(array('name' => 'Item 7', 'syfile_id' => 1));
|
||||||
|
$result = $this->model->findById(1);
|
||||||
|
$this->assertIdentical($result['Syfile']['item_count'], '2');
|
||||||
|
|
||||||
|
$this->model2->delete(1);
|
||||||
|
$result = $this->model->findById(1);
|
||||||
|
$this->assertIdentical($result['Syfile']['item_count'], '1');
|
||||||
|
}
|
||||||
|
|
||||||
function testDel() {
|
function testDel() {
|
||||||
$this->model =& new Article();
|
$this->model =& new Article();
|
||||||
|
|
||||||
|
@ -2412,6 +2491,18 @@ class ModelTest extends CakeTestCase {
|
||||||
$this->assertEqual($result, 0);
|
$this->assertEqual($result, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testDependentExclusiveDelete() {
|
||||||
|
$this->model =& new Article10();
|
||||||
|
|
||||||
|
$result = $this->model->find('all');
|
||||||
|
$this->assertEqual(count($result[0]['Comment']), 4);
|
||||||
|
$this->assertEqual(count($result[1]['Comment']), 2);
|
||||||
|
$this->assertEqual($this->model->Comment->find('count'), 6);
|
||||||
|
|
||||||
|
$this->model->delete(1);
|
||||||
|
$this->assertEqual($this->model->Comment->find('count'), 2);
|
||||||
|
}
|
||||||
|
|
||||||
function testFindAllThreaded() {
|
function testFindAllThreaded() {
|
||||||
$this->model =& new Category();
|
$this->model =& new Category();
|
||||||
|
|
||||||
|
|
2
cake/tests/fixtures/author_fixture.php
vendored
2
cake/tests/fixtures/author_fixture.php
vendored
|
@ -35,7 +35,7 @@
|
||||||
class AuthorFixture extends CakeTestFixture {
|
class AuthorFixture extends CakeTestFixture {
|
||||||
var $name = 'Author';
|
var $name = 'Author';
|
||||||
var $fields = array(
|
var $fields = array(
|
||||||
'id' => array('type' => 'integer', 'key' => 'primary', 'extra'=> 'auto_increment'),
|
'id' => array('type' => 'integer', 'key' => 'primary', 'extra' => 'auto_increment'),
|
||||||
'user' => array('type' => 'string', 'null' => false),
|
'user' => array('type' => 'string', 'null' => false),
|
||||||
'password' => array('type' => 'string', 'null' => false),
|
'password' => array('type' => 'string', 'null' => false),
|
||||||
'created' => 'datetime',
|
'created' => 'datetime',
|
||||||
|
|
12
cake/tests/fixtures/item_fixture.php
vendored
12
cake/tests/fixtures/item_fixture.php
vendored
|
@ -40,12 +40,12 @@ class ItemFixture extends CakeTestFixture {
|
||||||
'name' => array('type' => 'string', 'null' => false)
|
'name' => array('type' => 'string', 'null' => false)
|
||||||
);
|
);
|
||||||
var $records = array(
|
var $records = array(
|
||||||
array ('id' => 1, 'syfile_id' => 1, 'name' => 'Item 1'),
|
array('id' => 1, 'syfile_id' => 1, 'name' => 'Item 1'),
|
||||||
array ('id' => 2, 'syfile_id' => 2, 'name' => 'Item 2'),
|
array('id' => 2, 'syfile_id' => 2, 'name' => 'Item 2'),
|
||||||
array ('id' => 3, 'syfile_id' => 3, 'name' => 'Item 3'),
|
array('id' => 3, 'syfile_id' => 3, 'name' => 'Item 3'),
|
||||||
array ('id' => 4, 'syfile_id' => 4, 'name' => 'Item 4'),
|
array('id' => 4, 'syfile_id' => 4, 'name' => 'Item 4'),
|
||||||
array ('id' => 5, 'syfile_id' => 5, 'name' => 'Item 5'),
|
array('id' => 5, 'syfile_id' => 5, 'name' => 'Item 5'),
|
||||||
array ('id' => 6, 'syfile_id' => 6, 'name' => 'Item 6')
|
array('id' => 6, 'syfile_id' => 6, 'name' => 'Item 6')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
?>
|
?>
|
15
cake/tests/fixtures/syfile_fixture.php
vendored
15
cake/tests/fixtures/syfile_fixture.php
vendored
|
@ -37,15 +37,16 @@ class SyfileFixture extends CakeTestFixture {
|
||||||
var $fields = array(
|
var $fields = array(
|
||||||
'id' => array('type' => 'integer', 'key' => 'primary', 'extra'=> 'auto_increment'),
|
'id' => array('type' => 'integer', 'key' => 'primary', 'extra'=> 'auto_increment'),
|
||||||
'image_id' => array('type' => 'integer', 'null' => true),
|
'image_id' => array('type' => 'integer', 'null' => true),
|
||||||
'name' => array('type' => 'string', 'null' => false)
|
'name' => array('type' => 'string', 'null' => false),
|
||||||
|
'item_count' => array('type' => 'integer', 'null' => true)
|
||||||
);
|
);
|
||||||
var $records = array(
|
var $records = array(
|
||||||
array ('id' => 1, 'image_id' => 1, 'name' => 'Syfile 1'),
|
array('id' => 1, 'image_id' => 1, 'name' => 'Syfile 1'),
|
||||||
array ('id' => 2, 'image_id' => 2, 'name' => 'Syfile 2'),
|
array('id' => 2, 'image_id' => 2, 'name' => 'Syfile 2'),
|
||||||
array ('id' => 3, 'image_id' => 5, 'name' => 'Syfile 3'),
|
array('id' => 3, 'image_id' => 5, 'name' => 'Syfile 3'),
|
||||||
array ('id' => 4, 'image_id' => 3, 'name' => 'Syfile 4'),
|
array('id' => 4, 'image_id' => 3, 'name' => 'Syfile 4'),
|
||||||
array ('id' => 5, 'image_id' => 4, 'name' => 'Syfile 5'),
|
array('id' => 5, 'image_id' => 4, 'name' => 'Syfile 5'),
|
||||||
array ('id' => 6, 'image_id' => null, 'name' => 'Syfile 6')
|
array('id' => 6, 'image_id' => null, 'name' => 'Syfile 6')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
?>
|
?>
|
Loading…
Reference in a new issue