11<?php
22
3- /** @noinspection PhpUndefinedClassInspection */
4-
53/**
64 * This file is part of the Phalcon Framework.
75 *
2018use MongoDB \BSON \Serializable ;
2119use MongoDB \BSON \Unserializable ;
2220use Phalcon \Helper \Str ;
21+ use Phalcon \Incubator \MongoDB \Mvc \CollectionInterface ;
2322use Phalcon \Mvc \EntityInterface ;
23+ use ReflectionClass ;
24+ use ReflectionException ;
2425
2526/**
2627 * Class Document
@@ -42,19 +43,68 @@ class Document implements
4243 *
4344 * @param array $data
4445 */
45- final public function __construct (array $ data = [] )
46+ final public function __construct ($ data = null )
4647 {
47- foreach ($ data as $ key => $ value ) {
48- $ this ->offsetSet ($ key , $ value );
49- }
50-
5148 /**
5249 * This allows the developer to execute initialization stuff every time
5350 * an instance is created
5451 */
5552 if (method_exists ($ this , 'onConstruct ' )) {
56- $ this ->onConstruct ();
53+ $ this ->onConstruct ($ data );
54+ }
55+
56+ if (is_array ($ data )) {
57+ $ this ->assign ($ data );
58+ }
59+ }
60+
61+ /**
62+ * @param array $data
63+ * @param null $dataColumnMap
64+ * @param null $whiteList
65+ * @return $this|CollectionInterface
66+ */
67+ public function assign (array $ data , $ dataColumnMap = null , $ whiteList = null ): self
68+ {
69+ if (is_array ($ dataColumnMap )) {
70+ $ dataMapped = [];
71+
72+ foreach ($ data as $ key => $ value ) {
73+ if (isset ($ dataColumnMap [$ key ])) {
74+ $ dataMapped [$ dataColumnMap [$ key ]] = $ value ;
75+ }
76+ }
77+ } else {
78+ $ dataMapped = $ data ;
79+ }
80+
81+ if (count ($ dataMapped ) === 0 ) {
82+ return $ this ;
83+ }
84+
85+ // Use reflection to list uninitialized properties
86+ try {
87+ $ reflection = new ReflectionClass ($ this );
88+ $ reflectionProperties = $ reflection ->getProperties ();
89+ } catch (ReflectionException $ e ) {
90+ $ reflectionProperties = [];
91+ }
92+
93+ foreach ($ reflectionProperties as $ reflectionMethod ) {
94+ $ key = $ reflectionMethod ->getName ();
95+
96+ if (isset ($ dataMapped [$ key ])) {
97+ if (is_array ($ whiteList ) && !in_array ($ key , $ whiteList , true )) {
98+ continue ;
99+ }
100+
101+ if (!$ this ->possibleSetter ($ key , $ dataMapped [$ key ])) {
102+ $ this ->$ key = $ dataMapped [$ key ];
103+ }
104+ }
57105 }
106+
107+ return $ this ;
58108 }
59109
60110 /**
@@ -146,7 +196,7 @@ public function toArray(): array
146196 *
147197 * @return array
148198 */
149- public function jsonSerialize ()
199+ public function jsonSerialize (): array
150200 {
151201 $ data = [];
152202
@@ -157,9 +207,13 @@ public function jsonSerialize()
157207 return $ data ;
158208 }
159209
210+ /**
211+ * @param string $property
212+ * @return mixed
213+ */
160214 final protected function possibleGetter (string $ property )
161215 {
162- $ possibleGetter = "get " . Str::camelize ($ property );
216+ $ possibleGetter = "get " . ucfirst ( Str::camelize ($ property) );
163217
164218 if (!method_exists ($ this , $ possibleGetter )) {
165219 return $ this ->$ property ;
@@ -171,15 +225,33 @@ final protected function possibleGetter(string $property)
171225 /**
172226 * @return array
173227 */
174- public function bsonSerialize ()
228+ public function bsonSerialize (): array
175229 {
176230 return $ this ->toArray ();
177231 }
178232
233+ /**
234+ * @param string $property
235+ * @param $value
236+ * @return bool
237+ */
238+ final protected function possibleSetter (string $ property , $ value ): bool
239+ {
240+ $ possibleSetter = "set " . ucfirst (Str::camelize ($ property ));
241+
242+ if (!method_exists ($ this , $ possibleSetter )) {
243+ return false ;
244+ }
245+
246+ $ this ->$ possibleSetter ($ value );
247+
248+ return true ;
249+ }
250+
179251 /**
180252 * @param array $data
181253 */
182- public function bsonUnserialize (array $ data )
254+ public function bsonUnserialize (array $ data ): void
183255 {
184256 foreach ($ data as $ key => $ value ) {
185257 $ this ->offsetSet ($ key , $ value );
0 commit comments