diff --git a/Cake/ORM/Entity.php b/Cake/ORM/Entity.php index a324638197e..a7c94c819ad 100644 --- a/Cake/ORM/Entity.php +++ b/Cake/ORM/Entity.php @@ -352,12 +352,15 @@ public function jsonSerialize() { * stored in this entity, indexed by property name * * @param array $properties list of properties to be returned + * @param boolean $onlyDirty Return the requested property only if it is dirty * @return array */ - public function extract(array $properties) { + public function extract(array $properties, $onlyDirty = false) { $result = []; foreach ($properties as $property) { - $result[$property] = $this->get($property); + if (!$onlyDirty || $this->dirty($property)) { + $result[$property] = $this->get($property); + } } return $result; } diff --git a/Cake/ORM/Table.php b/Cake/ORM/Table.php index 7d60bc30f67..3aba0dfaeb2 100644 --- a/Cake/ORM/Table.php +++ b/Cake/ORM/Table.php @@ -738,7 +738,7 @@ public function exists(array $conditions) { * @return \Cake\ORM\Entity|boolean */ public function save(Entity $entity, array $options = []) { - $options = new \ArrayObject($options + ['atomic' => true]); + $options = new \ArrayObject($options + ['atomic' => true, 'fieldList' => []]); if ($options['atomic']) { $connection = $this->connection(); $success = $connection->transactional(function() use ($entity, $options) { @@ -766,20 +766,10 @@ protected function _processSave($entity, $options) { return $event->result; } - $data = empty($options['fieldList']) ? - $entity->toArray() : - $entity->extract($options['fieldList']); - - $schema = $this->schema(); - $data = array_intersect_key($data, array_flip($schema->columns())); + $list = $options['fieldList'] ?: $this->schema()->columns(); + $data = $entity->extract($list, true); $keys = array_keys($data); - foreach ($keys as $i => $property) { - if (!$entity->dirty($property)) { - unset($keys[$i], $data[$property]); - } - } - $primary = $entity->extract((array)$this->primaryKey()); if ($primary && $entity->isNew() === null) { $entity->isNew(!$this->exists($primary)); diff --git a/Cake/Test/TestCase/ORM/EntityTest.php b/Cake/Test/TestCase/ORM/EntityTest.php index 3cb44ba55bd..126ca59d491 100644 --- a/Cake/Test/TestCase/ORM/EntityTest.php +++ b/Cake/Test/TestCase/ORM/EntityTest.php @@ -492,6 +492,24 @@ public function testDirtyChangingProperties() { $this->assertTrue($entity->dirty('something')); } +/** + * Tests extract only dirty properties + * + * @return void + */ + public function testExtractDirty() { + $entity = new \Cake\ORM\Entity([ + 'id' => 1, + 'title' => 'Foo', + 'author_id' => 3 + ]); + $entity->dirty('id', false); + $entity->dirty('title', false); + $expected = ['author_id' => 3]; + $result = $entity->extract(['id', 'title', 'author_id'], true); + $this->assertEquals($expected, $result); + } + /** * Tests the clean method *