@@ -121,17 +121,102 @@ public function validateElement($element, $matches, $objectDefinition = null, Js
121121 */
122122 public function validateDefinition ($ element , $ objectDefinition = null , JsonPointer $ path = null )
123123 {
124+ $ default = $ this ->getFactory ()->createInstanceFor ('undefined ' );
125+
124126 foreach ($ objectDefinition as $ i => $ value ) {
125- $ property = $ this ->getProperty ($ element , $ i , $ this -> getFactory ()-> createInstanceFor ( ' undefined ' ) );
127+ $ property = $ this ->getProperty ($ element , $ i , $ default );
126128 $ definition = $ this ->getProperty ($ objectDefinition , $ i );
127129
130+ if ($ this ->checkMode & Constraint::CHECK_MODE_TYPE_CAST ){
131+ if (!($ property instanceof Constraint)) {
132+ $ property = $ this ->coerce ($ property , $ definition );
133+
134+ if ($ this ->checkMode & Constraint::CHECK_MODE_COERCE ) {
135+ if (is_object ($ element )) {
136+ $ element ->{$ i } = $ property ;
137+ } else {
138+ $ element [$ i ] = $ property ;
139+ }
140+ }
141+ }
142+ }
143+
128144 if (is_object ($ definition )) {
129145 // Undefined constraint will check for is_object() and quit if is not - so why pass it?
130146 $ this ->checkUndefined ($ property , $ definition , $ path , $ i );
131147 }
132148 }
133149 }
134150
151+ /**
152+ * Converts a value to boolean. For example, "true" becomes true.
153+ * @param $value The value to convert to boolean
154+ * @return bool|mixed
155+ */
156+ protected function toBoolean ($ value )
157+ {
158+ if ($ value === "true " ){
159+ return true ;
160+ }
161+
162+ if ($ value === "false " ){
163+ return false ;
164+ }
165+
166+ return $ value ;
167+ }
168+
169+ /**
170+ * Converts a numeric string to a number. For example, "4" becomes 4.
171+ *
172+ * @param mixed $value The value to convert to a number.
173+ * @return int|float|mixed
174+ */
175+ protected function toNumber ($ value )
176+ {
177+ if (is_numeric ($ value )) {
178+ return $ value + 0 ; // cast to number
179+ }
180+
181+ return $ value ;
182+ }
183+
184+ protected function toInteger ($ value )
185+ {
186+ if (ctype_digit ($ value )) {
187+ return (int )$ value ; // cast to number
188+ }
189+
190+ return $ value ;
191+ }
192+
193+ /**
194+ * Given a value and a definition, attempts to coerce the value into the
195+ * type specified by the definition's 'type' property.
196+ *
197+ * @param mixed $value Value to coerce.
198+ * @param \stdClass $definition A definition with information about the expected type.
199+ * @return bool|int|string
200+ */
201+ protected function coerce ($ value , $ definition )
202+ {
203+ $ type = isset ($ definition ->type )?$ definition ->type :null ;
204+ if ($ type ){
205+ switch ($ type ){
206+ case "boolean " :
207+ $ value = $ this ->toBoolean ($ value );
208+ break ;
209+ case "integer " :
210+ $ value = $ this ->toInteger ($ value );
211+ break ;
212+ case "number " :
213+ $ value = $ this ->toNumber ($ value );
214+ break ;
215+ }
216+ }
217+ return $ value ;
218+ }
219+
135220 /**
136221 * retrieves a property from an object or array
137222 *
0 commit comments