From a207a95893f2d0e0ad7dc894ed1a17cee36f7320 Mon Sep 17 00:00:00 2001 From: phpnut Date: Wed, 17 Oct 2007 21:19:30 +0000 Subject: [PATCH] Fixes #3187 and #3230, Model -> save issue with fieldList and id git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@5781 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/libs/model/model.php | 67 ++++++++++++++-------- cake/tests/cases/libs/model/model.test.php | 25 +++++++- 2 files changed, 65 insertions(+), 27 deletions(-) diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php index 70be333a4..0520b4b83 100644 --- a/cake/libs/model/model.php +++ b/cake/libs/model/model.php @@ -238,6 +238,12 @@ class Model extends Overloadable { * @var array */ var $behaviors = array(); +/** + * Whitelist of fields allowed to be saved + * + * @var array + */ + var $whitelist = array(); /** * Enter description here... * @@ -812,18 +818,17 @@ class Model extends Overloadable { foreach ($data as $n => $v) { if (is_array($v)) { + foreach ($v as $x => $y) { - if ($n == $this->name) { + if (empty($this->whitelist) || (in_array($x, $this->whitelist) || $n !== $this->name)) { if (isset($this->validationErrors[$x])) { unset ($this->validationErrors[$x]); } - if ($x === $this->primaryKey) { $this->id = $y; } + $this->data[$n][$x] = $y; } - - $this->data[$n][$x] = $y; } } } @@ -1031,11 +1036,38 @@ class Model extends Overloadable { */ function save($data = null, $validate = true, $fieldList = array()) { $db =& ConnectionManager::getDataSource($this->useDbConfig); + $_whitelist = $this->whitelist; + + if (!empty($fieldList)) { + $this->whitelist = $fieldList; + } elseif ($fieldList === null) { + $this->whitelist = array(); + } $this->set($data); - $whitelist = !empty($fieldList); + foreach (array('created', 'updated', 'modified') as $field) { + if (array_key_exists($field, $this->data[$this->name]) && $this->data[$this->name][$field] === null) { + unset($this->data[$this->name][$field]); + } + } + + $exists = $this->exists(); + $fields = array_keys($this->data[$this->name]); + + if (!$exists && $this->hasField('created') && !in_array('created', $fields)) { + $colType = am(array('formatter' => 'date'), $db->columns[$this->getColumnType('created')]); + $this->set('created', $colType['formatter']($colType['format'])); + } + + foreach (array('modified', 'updated') as $updateCol) { + if ($this->hasField($updateCol) && !in_array($updateCol, $fields)) { + $colType = am(array('formatter' => 'date'), $db->columns[$this->getColumnType($updateCol)]); + $this->set($updateCol, $colType['formatter']($colType['format'])); + } + } if ($validate && !$this->validates()) { + $this->whitelist = $_whitelist; return false; } @@ -1044,12 +1076,14 @@ class Model extends Overloadable { $ct = count($behaviors); for ($i = 0; $i < $ct; $i++) { if ($this->behaviors[$behaviors[$i]]->beforeSave($this) === false) { + $this->whitelist = $_whitelist; return false; } } } if (!$this->beforeSave()) { + $this->whitelist = $_whitelist; return false; } $fields = $values = array(); @@ -1061,13 +1095,13 @@ class Model extends Overloadable { } else { if ($n === $this->name) { foreach (array('created', 'updated', 'modified') as $field) { - if (array_key_exists($field, $v) && (empty($v[$field]) || $v[$field] === null)) { + if (array_key_exists($field, $v) && empty($v[$field])) { unset($v[$field]); } } foreach ($v as $x => $y) { - if ($this->hasField($x) && ($whitelist && in_array($x, $fieldList) || !$whitelist)) { + if ($this->hasField($x)) { $fields[] = $x; $values[] = $y; } @@ -1075,22 +1109,6 @@ class Model extends Overloadable { } } } - - $exists = $this->exists(); - - if (!$exists && $this->hasField('created') && !in_array('created', $fields) && ($whitelist && in_array('created', $fieldList) || !$whitelist)) { - $colType = am(array('formatter' => 'date'), $db->columns[$this->getColumnType('created')]); - $fields[] = 'created'; - $values[] = $colType['formatter']($colType['format']); - } - - foreach (array('modified', 'updated') as $updateCol) { - if ($this->hasField($updateCol) && !in_array($updateCol, $fields) && ($whitelist && in_array($updateCol, $fieldList) || !$whitelist)) { - $colType = am(array('formatter' => 'date'), $db->columns[$this->getColumnType($updateCol)]); - $fields[] = $updateCol; - $values[] = $colType['formatter']($colType['format']); - } - } $count = count($fields); if (!$exists && $count > 0) { @@ -1148,6 +1166,7 @@ class Model extends Overloadable { $this->_clearCache(); $this->validationErrors = array(); } + $this->whitelist = $_whitelist; return $success; } /** @@ -2141,4 +2160,4 @@ class Model extends Overloadable { if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) { Overloadable::overload('Model'); } -?> \ No newline at end of file +?> diff --git a/cake/tests/cases/libs/model/model.test.php b/cake/tests/cases/libs/model/model.test.php index abb9886d5..522528af1 100644 --- a/cake/tests/cases/libs/model/model.test.php +++ b/cake/tests/cases/libs/model/model.test.php @@ -1878,7 +1878,7 @@ class ModelTest extends CakeTestCase { $this->assertEqual($result, $expected); $data = array('Article' => array('id' => 1, 'user_id' => '2', 'title' => 'First Article', 'body' => 'New First Article Body', 'published' => 'Y')); - $result = $this->model->create() && $this->model->save($data, true, array('title', 'published')); + $result = $this->model->create() && $this->model->save($data, true, array('id', 'title', 'published')); $this->assertTrue($result); $this->model->recursive = -1; @@ -1896,6 +1896,7 @@ class ModelTest extends CakeTestCase { 'Tag' => array(1, 3) ) ); + $this->model->create(); $result = $this->model->create() && $this->model->save($data); $this->assertTrue($result); @@ -2161,7 +2162,7 @@ class ModelTest extends CakeTestCase { 'belongsTo' => array('User'), 'hasMany' => array('Comment') )); - $result = $this->model->find(array('Article.id'=>2), array('id', 'user_id', 'title', 'body')); + $result = $this->model->find(array('Article.id' => 2), array('id', 'user_id', 'title', 'body')); $expected = array( 'Article' => array( 'id' => '2', 'user_id' => '3', 'title' => 'New Second Article', 'body' => 'Second Article Body' @@ -2344,6 +2345,24 @@ class ModelTest extends CakeTestCase { ) ); $this->assertEqual($result, $expected); + + $data = array('Article' => array('id' => 10, 'user_id' => '2', 'title' => 'New Article With Tags and fieldList', + 'body' => 'New Article Body with Tags and fieldList', 'created' => '2007-03-18 14:55:23', + 'updated' => '2007-03-18 14:57:31'), + 'Tag' => array('Tag' => array(1, 2, 3))); + $result = $this->model->create() && $this->model->save($data, true, array('user_id', 'title', 'published')); + $this->assertTrue($result); + + $this->model->unbindModel(array('belongsTo' => array('User'), 'hasMany' => array('Comment'))); + $result = $this->model->read(); + $expected = array('Article' => array('id' => 4, + 'user_id' => 2, 'title' => 'New Article With Tags and fieldList', + 'body' => '', 'published' => 'N', 'created' => '', 'updated' => ''), + 'Tag' => array( + 0 => array('id' => 1, 'tag' => 'tag1', 'created' => '2007-03-18 12:22:23', 'updated' => '2007-03-18 12:24:31'), + 1 => array('id' => 2, 'tag' => 'tag2', 'created' => '2007-03-18 12:24:23', 'updated' => '2007-03-18 12:26:31'), + 2 => array('id' => 3, 'tag' => 'tag3', 'created' => '2007-03-18 12:26:23', 'updated' => '2007-03-18 12:28:31'))); + $this->assertEqual($result, $expected); } function testDel() { @@ -2886,4 +2905,4 @@ class ValidationTest extends CakeTestModel { return new Set(); } } -?> \ No newline at end of file +?>