diff --git a/CHANGELOG.md b/CHANGELOG.md index d9def65287f..9ae628c1fff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ - Fixed `Phalcon\Mvc\Micro:handle` to correctly handle `before` handlers [#10931](https://github.com/phalcon/cphalcon/pull/10931) - Fixed `Phalcon\Mvc\Micro:handle` to correctly handle `afterBinding` handlers - Added way to disable setters in `Phalcon\Mvc\Model::assign` by using `Phalcon\Mvc\Model::setup` or ini option +- Fixed `Phalcon\Mvc\Model::hasChanged` to correctly use it with arrays [#12669](https://github.com/phalcon/cphalcon/issues/12669) # [3.1.2](https://github.com/phalcon/cphalcon/releases/tag/v3.1.2) (2017-04-05) - Fixed PHP 7.1 issues [#12055](https://github.com/phalcon/cphalcon/issues/12055) diff --git a/phalcon/mvc/model.zep b/phalcon/mvc/model.zep index 1af3b92e50d..3729effb062 100644 --- a/phalcon/mvc/model.zep +++ b/phalcon/mvc/model.zep @@ -3886,9 +3886,24 @@ abstract class Model implements EntityInterface, ModelInterface, ResultInterface * Check if a specific attribute has changed * This only works if the model is keeping data snapshots * + * + * $robot = new Robots(); + * + * $robot->type = "mechanical"; + * $robot->name = "Astro Boy"; + * $robot->year = 1952; + * + * $robot->create(); + * $robot->type = "hydraulic"; + * $hasChanged = $robot->hasChanged("type"); // returns true + * $hasChanged = $robot->hasChanged(["type", "name"]); // returns true + * $hasChanged = $robot->hasChanged(["type", "name", true]); // returns false + * + * * @param string|array fieldName + * @param boolean allFields */ - public function hasChanged(var fieldName = null) -> boolean + public function hasChanged(var fieldName = null, boolean allFields = false) -> boolean { var changedFields; @@ -3899,6 +3914,12 @@ abstract class Model implements EntityInterface, ModelInterface, ResultInterface */ if typeof fieldName == "string" { return in_array(fieldName, changedFields); + } elseif typeof fieldName == "array" { + if allFields { + return array_intersect(fieldName, changedFields) == fieldName; + } + + return count(array_intersect(fieldName, changedFields)) > 0; } return count(changedFields) > 0; diff --git a/tests/unit/Mvc/Model/SnapshotTest.php b/tests/unit/Mvc/Model/SnapshotTest.php index a5f2ed317d5..aa891e19e24 100644 --- a/tests/unit/Mvc/Model/SnapshotTest.php +++ b/tests/unit/Mvc/Model/SnapshotTest.php @@ -439,4 +439,37 @@ function () { } ); } + + /** + * When model is refreshed snapshot should be updated + * + * @issue 12669 + * @author Wojciech Ĺšlawski + * @since 2017-03-15 + */ + public function testIssue12669() + { + $this->specify( + 'hasChanged method for array argument is not working correctly', + function () { + $this->setUpModelsManager(); + $robots = new Robots( + [ + 'name' => 'test', + 'year' => 2017, + 'datetime' => (new \DateTime())->format('Y-m-d'), + 'text' => 'asd', + ] + ); + + expect($robots->create())->true(); + $robots->name = 'test2'; + expect($robots->hasChanged(['name', 'year']))->equals(true); + expect($robots->hasChanged(['text', 'year']))->equals(false); + expect($robots->hasChanged(['name', 'year'], true))->equals(false); + $robots->year = 2018; + expect($robots->hasChanged(['name', 'year'], true))->equals(true); + } + ); + } }