diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55172f6fe01..dc5980b0cff 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
- Added ability to sanitize URL to `Phalcon\Filter`
- Add argument to interface `Phalcon\Mvc\Model\Query\BuilderInterface::join()` - `type` to specify type join
- Added `Phalcon\Mvc\Model::hasUpdated` and `Phalcon\Mvc\Model:getUpdatedFields`, way to check if fields were updated after create/save/update
+- Updated `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-XX-XX)
- 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 b137b3318c7..95f21a8ea26 100644
--- a/phalcon/mvc/model.zep
+++ b/phalcon/mvc/model.zep
@@ -3861,9 +3861,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;
@@ -3874,6 +3889,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 de6c989d4f1..ac0d44a4e6d 100644
--- a/tests/unit/Mvc/Model/SnapshotTest.php
+++ b/tests/unit/Mvc/Model/SnapshotTest.php
@@ -402,4 +402,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);
+ }
+ );
+ }
}