Optimize conditionals and reduce lookups.

Also, make the code easier to read removing unneded indentations.
This commit is contained in:
Ber Clausen 2013-10-23 22:38:03 -03:00
parent 7422b16327
commit 1fbe9c0021

View file

@ -987,30 +987,32 @@ class Model extends Object implements CakeEventListener {
*/
protected function _createLinks() {
foreach ($this->_associations as $type) {
if (!is_array($this->{$type})) {
$this->{$type} = explode(',', $this->{$type});
$association =& $this->{$type};
foreach ($this->{$type} as $i => $className) {
if (!is_array($association)) {
$association = explode(',', $association);
foreach ($association as $i => $className) {
$className = trim($className);
unset ($this->{$type}[$i]);
$this->{$type}[$className] = array();
unset ($association[$i]);
$association[$className] = array();
}
}
if (!empty($this->{$type})) {
foreach ($this->{$type} as $assoc => $value) {
if (!empty($association)) {
foreach ($association as $assoc => $value) {
$plugin = null;
if (is_numeric($assoc)) {
unset($this->{$type}[$assoc]);
unset($association[$assoc]);
$assoc = $value;
$value = array();
if (strpos($assoc, '.') !== false) {
list($plugin, $assoc) = pluginSplit($assoc, true);
$this->{$type}[$assoc] = array('className' => $plugin . $assoc);
$association[$assoc] = array('className' => $plugin . $assoc);
} else {
$this->{$type}[$assoc] = $value;
$association[$assoc] = $value;
}
}
@ -1066,9 +1068,10 @@ class Model extends Object implements CakeEventListener {
protected function _generateAssociation($type, $assocKey) {
$class = $assocKey;
$dynamicWith = false;
$assoc =& $this->{$type}[$assocKey];
foreach ($this->_associationKeys[$type] as $key) {
if (!isset($this->{$type}[$assocKey][$key]) || $this->{$type}[$assocKey][$key] === null) {
if (!isset($assoc[$key]) || $assoc[$key] === null) {
$data = '';
switch ($key) {
@ -1085,7 +1088,7 @@ class Model extends Object implements CakeEventListener {
break;
case 'with':
$data = Inflector::camelize(Inflector::singularize($this->{$type}[$assocKey]['joinTable']));
$data = Inflector::camelize(Inflector::singularize($assoc['joinTable']));
$dynamicWith = true;
break;
@ -1104,11 +1107,11 @@ class Model extends Object implements CakeEventListener {
break;
}
$this->{$type}[$assocKey][$key] = $data;
$assoc[$key] = $data;
}
if ($dynamicWith) {
$this->{$type}[$assocKey]['dynamicWith'] = true;
$assoc['dynamicWith'] = true;
}
}
}
@ -1180,17 +1183,16 @@ class Model extends Object implements CakeEventListener {
}
foreach ($data as $modelName => $fieldSet) {
if (is_array($fieldSet)) {
foreach ($fieldSet as $fieldName => $fieldValue) {
if (isset($this->validationErrors[$fieldName])) {
unset($this->validationErrors[$fieldName]);
if (!is_array($fieldSet)) {
continue;
}
if ($modelName === $this->alias) {
if ($fieldName === $this->primaryKey) {
foreach ($fieldSet as $fieldName => $fieldValue) {
unset($this->validationErrors[$fieldName]);
if ($modelName === $this->alias && $fieldName === $this->primaryKey) {
$this->id = $fieldValue;
}
}
if (is_array($fieldValue) || is_object($fieldValue)) {
$fieldValue = $this->deconstruct($fieldName, $fieldValue);
@ -1199,7 +1201,6 @@ class Model extends Object implements CakeEventListener {
$this->data[$modelName][$fieldName] = $fieldValue;
}
}
}
return $data;
}
@ -1744,12 +1745,15 @@ class Model extends Object implements CakeEventListener {
$now = time();
foreach ($dateFields as $updateCol) {
if ($this->hasField($updateCol) && !in_array($updateCol, $fields)) {
if (in_array($updateCol, $fields) || !$this->hasField($updateCol)) {
continue;
}
$default = array('formatter' => 'date');
$colType = array_merge($default, $db->columns[$this->getColumnType($updateCol)]);
if (!array_key_exists('format', $colType)) {
$time = $now;
} else {
if (array_key_exists('format', $colType)) {
$time = call_user_func($colType['formatter'], $colType['format']);
}
@ -1758,7 +1762,6 @@ class Model extends Object implements CakeEventListener {
}
$this->set($updateCol, $time);
}
}
if ($options['callbacks'] === true || $options['callbacks'] === 'before') {
$event = new CakeEvent('Model.beforeSave', $this, array($options));
@ -1783,8 +1786,7 @@ class Model extends Object implements CakeEventListener {
$v = $v[$n];
}
$joined[$n] = $v;
} else {
if ($n === $this->alias) {
} elseif ($n === $this->alias) {
foreach (array('created', 'updated', 'modified') as $field) {
if (array_key_exists($field, $v) && empty($v[$field])) {
unset($v[$field]);
@ -1798,7 +1800,6 @@ class Model extends Object implements CakeEventListener {
}
}
}
}
$count = count($fields);
@ -1890,28 +1891,35 @@ class Model extends Object implements CakeEventListener {
*/
protected function _saveMulti($joined, $id, $db) {
foreach ($joined as $assoc => $data) {
if (isset($this->hasAndBelongsToMany[$assoc])) {
list($join) = $this->joinModel($this->hasAndBelongsToMany[$assoc]['with']);
if (!isset($this->hasAndBelongsToMany[$assoc])) {
continue;
}
if ($with = $this->hasAndBelongsToMany[$assoc]['with']) {
$withModel = is_array($with) ? key($with) : $with;
$habtm = $this->hasAndBelongsToMany[$assoc];
list($join) = $this->joinModel($habtm['with']);
$Model = $this->{$join};
if (!empty($habtm['with'])) {
$withModel = is_array($habtm['with']) ? key($habtm['with']) : $habtm['with'];
list(, $withModel) = pluginSplit($withModel);
$dbMulti = $this->{$withModel}->getDataSource();
} else {
$dbMulti = $db;
}
$isUUID = !empty($this->{$join}->primaryKey) && $this->{$join}->_isUUIDField($this->{$join}->primaryKey);
$isUUID = !empty($Model->primaryKey) && $Model->_isUUIDField($Model->primaryKey);
$newData = $newValues = $newJoins = array();
$primaryAdded = false;
$fields = array(
$dbMulti->name($this->hasAndBelongsToMany[$assoc]['foreignKey']),
$dbMulti->name($this->hasAndBelongsToMany[$assoc]['associationForeignKey'])
$dbMulti->name($habtm['foreignKey']),
$dbMulti->name($habtm['associationForeignKey'])
);
$idField = $db->name($this->{$join}->primaryKey);
$idField = $db->name($Model->primaryKey);
if ($isUUID && !in_array($idField, $fields)) {
$fields[] = $idField;
$primaryAdded = true;
@ -1928,35 +1936,35 @@ class Model extends Object implements CakeEventListener {
$newValues[$row] = $values;
unset($values);
} elseif (isset($row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
if (!empty($row[$this->{$join}->primaryKey])) {
$newJoins[] = $row[$this->hasAndBelongsToMany[$assoc]['associationForeignKey']];
} elseif (isset($row[$habtm['associationForeignKey']])) {
if (!empty($row[$Model->primaryKey])) {
$newJoins[] = $row[$habtm['associationForeignKey']];
}
$newData[] = $row;
} elseif (isset($row[$join]) && isset($row[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']])) {
if (!empty($row[$join][$this->{$join}->primaryKey])) {
$newJoins[] = $row[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']];
} elseif (isset($row[$join]) && isset($row[$join][$habtm['associationForeignKey']])) {
if (!empty($row[$join][$Model->primaryKey])) {
$newJoins[] = $row[$join][$habtm['associationForeignKey']];
}
$newData[] = $row[$join];
}
}
$keepExisting = $this->hasAndBelongsToMany[$assoc]['unique'] === 'keepExisting';
if ($this->hasAndBelongsToMany[$assoc]['unique']) {
$keepExisting = $habtm['unique'] === 'keepExisting';
if ($habtm['unique']) {
$conditions = array(
$join . '.' . $this->hasAndBelongsToMany[$assoc]['foreignKey'] => $id
$join . '.' . $habtm['foreignKey'] => $id
);
if (!empty($this->hasAndBelongsToMany[$assoc]['conditions'])) {
$conditions = array_merge($conditions, (array)$this->hasAndBelongsToMany[$assoc]['conditions']);
if (!empty($habtm['conditions'])) {
$conditions = array_merge($conditions, (array)$habtm['conditions']);
}
$associationForeignKey = $this->{$join}->alias . '.' . $this->hasAndBelongsToMany[$assoc]['associationForeignKey'];
$links = $this->{$join}->find('all', array(
$associationForeignKey = $Model->alias . '.' . $habtm['associationForeignKey'];
$links = $Model->find('all', array(
'conditions' => $conditions,
'recursive' => empty($this->hasAndBelongsToMany[$assoc]['conditions']) ? -1 : 0,
'recursive' => empty($habtm['conditions']) ? -1 : 0,
'fields' => $associationForeignKey,
));
@ -1968,28 +1976,28 @@ class Model extends Object implements CakeEventListener {
$conditions[$associationForeignKey] = $oldLinks;
}
$dbMulti->delete($this->{$join}, $conditions);
$dbMulti->delete($Model, $conditions);
}
}
if (!empty($newData)) {
foreach ($newData as $data) {
$data[$this->hasAndBelongsToMany[$assoc]['foreignKey']] = $id;
if (empty($data[$this->{$join}->primaryKey])) {
$this->{$join}->create();
$data[$habtm['foreignKey']] = $id;
if (empty($data[$Model->primaryKey])) {
$Model->create();
}
$this->{$join}->save($data);
$Model->save($data);
}
}
if (!empty($newValues)) {
if ($keepExisting && !empty($links)) {
foreach ($links as $link) {
$oldJoin = $link[$join][$this->hasAndBelongsToMany[$assoc]['associationForeignKey']];
$oldJoin = $link[$join][$habtm['associationForeignKey']];
if (!in_array($oldJoin, $newJoins)) {
$conditions[$associationForeignKey] = $oldJoin;
$db->delete($this->{$join}, $conditions);
$db->delete($Model, $conditions);
} else {
unset($newValues[$oldJoin]);
}
@ -1999,8 +2007,7 @@ class Model extends Object implements CakeEventListener {
}
if (!empty($newValues)) {
$dbMulti->insertMulti($this->{$join}, $fields, $newValues);
}
$dbMulti->insertMulti($Model, $fields, $newValues);
}
}
}
@ -2019,7 +2026,12 @@ class Model extends Object implements CakeEventListener {
$keys['old'] = isset($keys['old']) ? $keys['old'] : array();
foreach ($this->belongsTo as $parent => $assoc) {
if (!empty($assoc['counterCache'])) {
if (empty($assoc['counterCache'])) {
continue;
}
$Model = $this->{$parent};
if (!is_array($assoc['counterCache'])) {
if (isset($assoc['counterScope'])) {
$assoc['counterCache'] = array($assoc['counterCache'] => $assoc['counterScope']);
@ -2036,7 +2048,7 @@ class Model extends Object implements CakeEventListener {
$field = Inflector::underscore($this->alias) . '_count';
}
if (!$this->{$parent}->hasField($field)) {
if (!$Model->hasField($field)) {
continue;
}
@ -2052,17 +2064,15 @@ class Model extends Object implements CakeEventListener {
$recursive = (empty($conditions) ? -1 : 0);
if (isset($keys['old'][$foreignKey])) {
if ($keys['old'][$foreignKey] != $keys[$foreignKey]) {
if (isset($keys['old'][$foreignKey]) && $keys['old'][$foreignKey] != $keys[$foreignKey]) {
$conditions[$fkQuoted] = $keys['old'][$foreignKey];
$count = intval($this->find('count', compact('conditions', 'recursive')));
$this->{$parent}->updateAll(
$Model->updateAll(
array($field => $count),
array($this->{$parent}->escapeField() => $keys['old'][$foreignKey])
array($Model->escapeField() => $keys['old'][$foreignKey])
);
}
}
$conditions[$fkQuoted] = $keys[$foreignKey];
@ -2072,14 +2082,13 @@ class Model extends Object implements CakeEventListener {
$count = intval($this->find('count', compact('conditions', 'recursive')));
$this->{$parent}->updateAll(
$Model->updateAll(
array($field => $count),
array($this->{$parent}->escapeField() => $keys[$foreignKey])
array($Model->escapeField() => $keys[$foreignKey])
);
}
}
}
}
/**
* Helper method for `Model::updateCounterCache()`. Checks the fields to be updated for
@ -2341,15 +2350,20 @@ class Model extends Object implements CakeEventListener {
$return = array();
$validates = true;
foreach ($data as $association => $values) {
$notEmpty = !empty($values[$association]) || (!isset($values[$association]) && !empty($values));
if (isset($associations[$association]) && $associations[$association] === 'belongsTo' && $notEmpty) {
$validates = $this->{$association}->create(null) !== null;
$isEmpty = empty($values) || (isset($values[$association]) && empty($values[$association]));
if ($isEmpty || !isset($associations[$association]) || $associations[$association] !== 'belongsTo') {
continue;
}
$Model = $this->{$association};
$validates = $Model->create(null) !== null;
$saved = false;
if ($validates) {
if ($options['deep']) {
$saved = $this->{$association}->saveAssociated($values, array_merge($options, array('atomic' => false)));
$saved = $Model->saveAssociated($values, array_merge($options, array('atomic' => false)));
} else {
$saved = $this->{$association}->save($values, array_merge($options, array('atomic' => false)));
$saved = $Model->save($values, array_merge($options, array('atomic' => false)));
}
$validates = ($saved === true || (is_array($saved) && !in_array(false, $saved, true)));
}
@ -2357,18 +2371,17 @@ class Model extends Object implements CakeEventListener {
if ($validates) {
$key = $this->belongsTo[$association]['foreignKey'];
if (isset($data[$this->alias])) {
$data[$this->alias][$key] = $this->{$association}->id;
$data[$this->alias][$key] = $Model->id;
} else {
$data = array_merge(array($key => $this->{$association}->id), $data, array($key => $this->{$association}->id));
$data = array_merge(array($key => $Model->id), $data, array($key => $Model->id));
}
$options = $this->_addToWhiteList($key, $options);
} else {
$validationErrors[$association] = $this->{$association}->validationErrors;
$validationErrors[$association] = $Model->validationErrors;
}
$return[$association] = $validates;
}
}
if ($validates && !($this->create(null) !== null && $this->save($data, $options))) {
$validationErrors[$this->alias] = $this->validationErrors;
@ -2381,8 +2394,13 @@ class Model extends Object implements CakeEventListener {
break;
}
$notEmpty = !empty($values[$association]) || (!isset($values[$association]) && !empty($values));
if (isset($associations[$association]) && $notEmpty) {
$isEmpty = empty($values) || (isset($values[$association]) && empty($values[$association]));
if ($isEmpty || !isset($associations[$association])) {
continue;
}
$Model = $this->{$association};
$type = $associations[$association];
$key = $this->{$type}[$association]['foreignKey'];
switch ($type) {
@ -2393,21 +2411,21 @@ class Model extends Object implements CakeEventListener {
$values = array_merge(array($key => $this->id), $values, array($key => $this->id));
}
$validates = $this->{$association}->create(null) !== null;
$validates = $Model->create(null) !== null;
$saved = false;
if ($validates) {
$options = $this->{$association}->_addToWhiteList($key, $options);
$options = $Model->_addToWhiteList($key, $options);
if ($options['deep']) {
$saved = $this->{$association}->saveAssociated($values, array_merge($options, array('atomic' => false)));
$saved = $Model->saveAssociated($values, array_merge($options, array('atomic' => false)));
} else {
$saved = $this->{$association}->save($values, $options);
$saved = $Model->save($values, $options);
}
}
$validates = ($validates && ($saved === true || (is_array($saved) && !in_array(false, $saved, true))));
if (!$validates) {
$validationErrors[$association] = $this->{$association}->validationErrors;
$validationErrors[$association] = $Model->validationErrors;
}
$return[$association] = $validates;
@ -2421,10 +2439,10 @@ class Model extends Object implements CakeEventListener {
}
}
$options = $this->{$association}->_addToWhiteList($key, $options);
$_return = $this->{$association}->saveMany($values, array_merge($options, array('atomic' => false)));
$options = $Model->_addToWhiteList($key, $options);
$_return = $Model->saveMany($values, array_merge($options, array('atomic' => false)));
if (in_array(false, $_return, true)) {
$validationErrors[$association] = $this->{$association}->validationErrors;
$validationErrors[$association] = $Model->validationErrors;
$validates = false;
}
@ -2432,7 +2450,6 @@ class Model extends Object implements CakeEventListener {
break;
}
}
}
$this->validationErrors = $validationErrors;
if (isset($validationErrors[$this->alias])) {
@ -2475,10 +2492,7 @@ class Model extends Object implements CakeEventListener {
return $options;
}
if (!empty($options['fieldList']) &&
is_array($options['fieldList']) &&
Hash::dimensions($options['fieldList']) < 2
) {
if (!empty($options['fieldList']) && is_array($options['fieldList']) && Hash::dimensions($options['fieldList']) < 2) {
$options['fieldList'][] = $key;
}
@ -2604,29 +2618,29 @@ class Model extends Object implements CakeEventListener {
continue;
}
$model = $this->{$assoc};
$Model = $this->{$assoc};
if ($data['foreignKey'] === false && $data['conditions'] && in_array($this->name, $model->getAssociated('belongsTo'))) {
$model->recursive = 0;
if ($data['foreignKey'] === false && $data['conditions'] && in_array($this->name, $Model->getAssociated('belongsTo'))) {
$Model->recursive = 0;
$conditions = array($this->escapeField(null, $this->name) => $id);
} else {
$model->recursive = -1;
$conditions = array($model->escapeField($data['foreignKey']) => $id);
$Model->recursive = -1;
$conditions = array($Model->escapeField($data['foreignKey']) => $id);
if ($data['conditions']) {
$conditions = array_merge((array)$data['conditions'], $conditions);
}
}
if (isset($data['exclusive']) && $data['exclusive']) {
$model->deleteAll($conditions);
$Model->deleteAll($conditions);
} else {
$records = $model->find('all', array(
'conditions' => $conditions, 'fields' => $model->primaryKey
$records = $Model->find('all', array(
'conditions' => $conditions, 'fields' => $Model->primaryKey
));
if (!empty($records)) {
foreach ($records as $record) {
$model->delete($record[$model->alias][$model->primaryKey]);
$Model->delete($record[$Model->alias][$Model->primaryKey]);
}
}
}
@ -2646,16 +2660,17 @@ class Model extends Object implements CakeEventListener {
protected function _deleteLinks($id) {
foreach ($this->hasAndBelongsToMany as $data) {
list(, $joinModel) = pluginSplit($data['with']);
$records = $this->{$joinModel}->find('all', array(
'conditions' => array($this->{$joinModel}->escapeField($data['foreignKey']) => $id),
'fields' => $this->{$joinModel}->primaryKey,
$Model = $this->{$joinModel};
$records = $Model->find('all', array(
'conditions' => array($Model->escapeField($data['foreignKey']) => $id),
'fields' => $Model->primaryKey,
'recursive' => -1,
'callbacks' => false
));
if (!empty($records)) {
foreach ($records as $record) {
$this->{$joinModel}->delete($record[$this->{$joinModel}->alias][$this->{$joinModel}->primaryKey]);
$Model->delete($record[$Model->alias][$Model->primaryKey]);
}
}
}