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);
+ }
+ );
+ }
}