| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  |  * @author Todd Burry <[email protected]> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  * @copyright 2009-2018 Vanilla Forums Inc. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  |  * @license MIT | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | namespace Garden\Schema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  * A class for defining and validating data schemas. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | class Schema implements \JsonSerializable, \ArrayAccess { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |      * Trigger a notice when extraneous properties are encountered during validation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |     const VALIDATE_EXTRA_PROPERTY_NOTICE = 0x1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |      * Throw a ValidationException when extraneous properties are encountered during validation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |     const VALIDATE_EXTRA_PROPERTY_EXCEPTION = 0x2; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |      * @var array All the known types. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |      * If this is ever given some sort of public access then remove the static. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |     private static $types = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |         'array' => ['a'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |         'object' => ['o'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |         'integer' => ['i', 'int'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |         'string' => ['s', 'str'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |         'number' => ['f', 'float'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |         'boolean' => ['b', 'bool'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |         // Psuedo-types | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |         'timestamp' => ['ts'], // type: integer, format: timestamp | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |         'datetime' => ['dt'], // type: string, format: date-time | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |         'null' => ['n'], // Adds nullable: true | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |     ]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |      * @var string The regular expression to strictly determine if a string is a date. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |     private static $DATE_REGEX = '`^\d{4}-\d{2}-\d{2}([ T]\d{2}:\d{2}(:\d{2})?)?`i'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |     private $schema = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |      * @var int A bitwise combination of the various **Schema::FLAG_*** constants. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |     private $flags = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |      * @var array An array of callbacks that will filter data in the schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |     private $filters = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |      * @var array An array of callbacks that will custom validate the schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |     private $validators = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |      * @var string|Validation The name of the class or an instance that will be cloned. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |     private $validationClass = Validation::class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |      * @var callable | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |     private $refLookup; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |     /// Methods /// | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |      * Initialize an instance of a new {@link Schema} class. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |      * @param array $schema The array schema to validate against. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 | 263 |  |     public function __construct(array $schema = []) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 | 263 |  |         $this->schema = $schema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         $this->refLookup = function (string $name) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |             return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |         }; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 | 263 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |      * Grab the schema's current description. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 | 1 |  |     public function getDescription(): string { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 | 1 |  |         return $this->schema['description'] ?? ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |      * Set the description for the schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |      * @param string $description The new description. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 | 1 |  |     public function setDescription(string $description) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 | 1 |  |         $this->schema['description'] = $description; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 | 1 |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |      * Get the schema's title. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |      * @return string Returns the title. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |     public function getTitle(): string { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |         return $this->schema['title'] ?? ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |      * Set the schema's title. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |      * @param string $title The new title. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |     public function setTitle(string $title) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |         $this->schema['title'] = $title; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |      * Get a schema field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |      * @param string|array $path The JSON schema path of the field with parts separated by dots. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |      * @param mixed $default The value to return if the field isn't found. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |      * @return mixed Returns the field value or `$default`. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 | 10 |  |     public function getField($path, $default = null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 | 10 |  |         if (is_string($path)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 | 10 |  |             if (strpos($path, '.') !== false && strpos($path, '/') === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 | 1 |  |                 trigger_error('Field selectors must be separated by "/" instead of "."', E_USER_DEPRECATED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 | 1 |  |                 $path = explode('.', $path); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 | 9 |  |                 $path = explode('/', $path); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 | 10 |  |         $value = $this->schema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 | 10 |  |         foreach ($path as $i => $subKey) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 | 10 |  |             if (is_array($value) && isset($value[$subKey])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 | 10 |  |                 $value = $value[$subKey]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 | 1 |  |             } elseif ($value instanceof Schema) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 | 1 |  |                 return $value->getField(array_slice($path, $i), $default); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 | 10 |  |                 return $default; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 | 10 |  |         return $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |      * Set a schema field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |      * @param string|array $path The JSON schema path of the field with parts separated by slashes. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |      * @param mixed $value The new value. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 | 4 |  |     public function setField($path, $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 | 4 |  |         if (is_string($path)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 | 4 |  |             if (strpos($path, '.') !== false && strpos($path, '/') === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 | 1 |  |                 trigger_error('Field selectors must be separated by "/" instead of "."', E_USER_DEPRECATED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 | 1 |  |                 $path = explode('.', $path); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 | 3 |  |                 $path = explode('/', $path); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 | 4 |  |         $selection = &$this->schema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 | 4 |  |         foreach ($path as $i => $subSelector) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 | 4 |  |             if (is_array($selection)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 | 4 |  |                 if (!isset($selection[$subSelector])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 | 4 |  |                     $selection[$subSelector] = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 | 1 |  |             } elseif ($selection instanceof Schema) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 | 1 |  |                 $selection->setField(array_slice($path, $i), $value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 | 1 |  |                 return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |                 $selection = [$subSelector => []]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 | 4 |  |             $selection = &$selection[$subSelector]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 | 4 |  |         $selection = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 | 4 |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |      * Get the ID for the schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |      * @return string | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 | 3 |  |     public function getID(): string { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 | 3 |  |         return isset($this->schema['id']) ? $this->schema['id'] : ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |      * Set the ID for the schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |      * @param string $id The new ID. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  |      * @throws \InvalidArgumentException Throws an exception when the provided ID is not a string. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |      * @return Schema | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 | 1 |  |     public function setID(string $id) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 | 1 |  |         if (is_string($id)) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 211 | 1 |  |             $this->schema['id'] = $id; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 212 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 213 |  |  |             throw new \InvalidArgumentException("The ID is not a valid string.", 500); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 214 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 215 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 216 | 1 |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 217 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 218 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 219 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 220 |  |  |      * Return the validation flags. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 221 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 222 |  |  |      * @return int Returns a bitwise combination of flags. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 223 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 224 | 1 |  |     public function getFlags(): int { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 225 | 1 |  |         return $this->flags; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 226 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 227 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 228 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 229 |  |  |      * Set the validation flags. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 230 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 231 |  |  |      * @param int $flags One or more of the **Schema::FLAG_*** constants. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 232 |  |  |      * @return Schema Returns the current instance for fluent calls. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 233 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 234 | 7 |  |     public function setFlags(int $flags) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 235 | 7 |  |         if (!is_int($flags)) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 236 |  |  |             throw new \InvalidArgumentException('Invalid flags.', 500); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 237 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 238 | 7 |  |         $this->flags = $flags; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 239 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 240 | 7 |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 241 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 242 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 243 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 244 |  |  |      * Whether or not the schema has a flag (or combination of flags). | 
            
                                                                                                            
                            
            
                                    
            
            
                | 245 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 246 |  |  |      * @param int $flag One or more of the **Schema::VALIDATE_*** constants. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 247 |  |  |      * @return bool Returns **true** if all of the flags are set or **false** otherwise. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 248 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 249 | 12 |  |     public function hasFlag(int $flag): bool { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 250 | 12 |  |         return ($this->flags & $flag) === $flag; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 251 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 252 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 253 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 254 |  |  |      * Set a flag. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 255 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 256 |  |  |      * @param int $flag One or more of the **Schema::VALIDATE_*** constants. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 257 |  |  |      * @param bool $value Either true or false. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 258 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 259 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 260 | 1 |  |     public function setFlag(int $flag, bool $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 261 | 1 |  |         if ($value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 262 | 1 |  |             $this->flags = $this->flags | $flag; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 263 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 264 | 1 |  |             $this->flags = $this->flags & ~$flag; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 265 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 266 | 1 |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 267 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 268 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 269 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 270 |  |  |      * Merge a schema with this one. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 271 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 272 |  |  |      * @param Schema $schema A scheme instance. Its parameters will be merged into the current instance. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 273 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 274 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 275 | 4 |  |     public function merge(Schema $schema) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 276 | 4 |  |         $this->mergeInternal($this->schema, $schema->getSchemaArray(), true, true); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 277 | 4 |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 278 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 279 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 280 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 281 |  |  |      * Add another schema to this one. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 282 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 283 |  |  |      * Adding schemas together is analogous to array addition. When you add a schema it will only add missing information. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 284 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 285 |  |  |      * @param Schema $schema The schema to add. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 286 |  |  |      * @param bool $addProperties Whether to add properties that don't exist in this schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 287 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 288 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 289 | 4 |  |     public function add(Schema $schema, $addProperties = false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 290 | 4 |  |         $this->mergeInternal($this->schema, $schema->getSchemaArray(), false, $addProperties); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 291 | 4 |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 292 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 293 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 294 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 295 |  |  |      * The internal implementation of schema merging. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 296 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 297 |  |  |      * @param array &$target The target of the merge. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 298 |  |  |      * @param array $source The source of the merge. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 299 |  |  |      * @param bool $overwrite Whether or not to replace values. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 300 |  |  |      * @param bool $addProperties Whether or not to add object properties to the target. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 301 |  |  |      * @return array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 302 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 303 | 7 |  |     private function mergeInternal(array &$target, array $source, $overwrite = true, $addProperties = true) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 304 |  |  |         // We need to do a fix for required properties here. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 305 | 7 |  |         if (isset($target['properties']) && !empty($source['required'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 306 | 5 |  |             $required = isset($target['required']) ? $target['required'] : []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 307 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 308 | 5 |  |             if (isset($source['required']) && $addProperties) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 309 | 4 |  |                 $newProperties = array_diff(array_keys($source['properties']), array_keys($target['properties'])); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 310 | 4 |  |                 $newRequired = array_intersect($source['required'], $newProperties); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 311 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 312 | 4 |  |                 $required = array_merge($required, $newRequired); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 313 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 314 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 315 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 316 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 317 | 7 |  |         foreach ($source as $key => $val) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 318 | 7 |  |             if (is_array($val) && array_key_exists($key, $target) && is_array($target[$key])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 319 | 7 |  |                 if ($key === 'properties' && !$addProperties) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 320 |  |  |                     // We just want to merge the properties that exist in the destination. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 321 | 2 |  |                     foreach ($val as $name => $prop) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 322 | 2 |  |                         if (isset($target[$key][$name])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 323 | 2 |  |                             $targetProp = &$target[$key][$name]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 324 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 325 | 2 |  |                             if (is_array($targetProp) && is_array($prop)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 326 | 2 |  |                                 $this->mergeInternal($targetProp, $prop, $overwrite, $addProperties); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 327 | 1 |  |                             } elseif (is_array($targetProp) && $prop instanceof Schema) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 328 |  |  |                                 $this->mergeInternal($targetProp, $prop->getSchemaArray(), $overwrite, $addProperties); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 329 | 1 |  |                             } elseif ($overwrite) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 330 | 2 |  |                                 $targetProp = $prop; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 331 |  |  |                             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 332 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 333 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 334 | 7 |  |                 } elseif (isset($val[0]) || isset($target[$key][0])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 335 | 5 |  |                     if ($overwrite) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 336 |  |  |                         // This is a numeric array, so just do a merge. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 337 | 3 |  |                         $merged = array_merge($target[$key], $val); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 338 | 3 |  |                         if (is_string($merged[0])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 339 | 3 |  |                             $merged = array_keys(array_flip($merged)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 340 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 341 | 5 |  |                         $target[$key] = $merged; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 342 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 343 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 344 | 7 |  |                     $target[$key] = $this->mergeInternal($target[$key], $val, $overwrite, $addProperties); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 345 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 346 | 7 |  |             } elseif (!$overwrite && array_key_exists($key, $target) && !is_array($val)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 347 |  |  |                 // Do nothing, we aren't replacing. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 348 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 349 | 7 |  |                 $target[$key] = $val; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 350 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 351 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 352 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 353 | 7 |  |         if (isset($required)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 354 | 5 |  |             if (empty($required)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 355 | 1 |  |                 unset($target['required']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 356 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 357 | 5 |  |                 $target['required'] = $required; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 358 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 359 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 360 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 361 | 7 |  |         return $target; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 362 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 363 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 364 |  |  | //    public function overlay(Schema $schema ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 365 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 366 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 367 |  |  |      * Returns the internal schema array. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 368 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 369 |  |  |      * @return array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 370 |  |  |      * @see Schema::jsonSerialize() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 371 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 372 | 17 |  |     public function getSchemaArray(): array { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 373 | 17 |  |         return $this->schema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 374 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 375 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 376 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 377 |  |  |      * Parse a short schema and return the associated schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 378 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 379 |  |  |      * @param array $arr The schema array. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 380 |  |  |      * @param mixed[] $args Constructor arguments for the schema instance. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 381 |  |  |      * @return static Returns a new schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 382 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 383 | 177 |  |     public static function parse(array $arr, ...$args) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 384 | 177 |  |         $schema = new static([], ...$args); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 385 | 177 |  |         $schema->schema = $schema->parseInternal($arr); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 386 | 176 |  |         return $schema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 387 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 388 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 389 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 390 |  |  |      * Parse a schema in short form into a full schema array. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 391 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 392 |  |  |      * @param array $arr The array to parse into a schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 393 |  |  |      * @return array The full schema array. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 394 |  |  |      * @throws \InvalidArgumentException Throws an exception when an item in the schema is invalid. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 395 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 396 | 177 |  |     protected function parseInternal(array $arr): array { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 397 | 177 |  |         if (empty($arr)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 398 |  |  |             // An empty schema validates to anything. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 399 | 6 |  |             return []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 400 | 172 |  |         } elseif (isset($arr['type'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 401 |  |  |             // This is a long form schema and can be parsed as the root. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 402 | 2 |  |             return $this->parseNode($arr); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 403 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 404 |  |  |             // Check for a root schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 405 | 171 |  |             $value = reset($arr); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 406 | 171 |  |             $key = key($arr); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 407 | 171 |  |             if (is_int($key)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 408 | 106 |  |                 $key = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 409 | 106 |  |                 $value = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 410 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 411 | 171 |  |             list ($name, $param) = $this->parseShortParam($key, $value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 412 | 170 |  |             if (empty($name)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 413 | 62 |  |                 return $this->parseNode($param, $value); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 414 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 415 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 416 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 417 |  |  |         // If we are here then this is n object schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 418 | 111 |  |         list($properties, $required) = $this->parseProperties($arr); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 419 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 420 |  |  |         $result = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 421 | 111 |  |             'type' => 'object', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 422 | 111 |  |             'properties' => $properties, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 423 | 111 |  |             'required' => $required | 
            
                                                                                                            
                            
            
                                    
            
            
                | 424 |  |  |         ]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 425 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 426 | 111 |  |         return array_filter($result); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 427 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 428 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 429 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 430 |  |  |      * Parse a schema node. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 431 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 432 |  |  |      * @param array $node The node to parse. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 433 |  |  |      * @param mixed $value Additional information from the node. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 434 |  |  |      * @return array|\ArrayAccess Returns a JSON schema compatible node. | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 435 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 436 | 171 |  |     private function parseNode($node, $value = null) { | 
            
                                                                        
                            
            
                                    
            
            
                | 437 | 171 |  |         if (is_array($value)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 438 | 66 |  |             if (is_array($node['type'])) { | 
            
                                                                        
                            
            
                                    
            
            
                | 439 |  |  |                 trigger_error('Schemas with multiple types is deprecated.', E_USER_DEPRECATED); | 
            
                                                                        
                            
            
                                    
            
            
                | 440 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 441 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 442 |  |  |             // The value describes a bit more about the schema. | 
            
                                                                        
                            
            
                                    
            
            
                | 443 | 66 |  |             switch ($node['type']) { | 
            
                                                                        
                            
            
                                    
            
            
                | 444 | 66 |  |                 case 'array': | 
            
                                                                        
                            
            
                                    
            
            
                | 445 | 11 |  |                     if (isset($value['items'])) { | 
            
                                                                        
                            
            
                                    
            
            
                | 446 |  |  |                         // The value includes array schema information. | 
            
                                                                        
                            
            
                                    
            
            
                | 447 | 4 |  |                         $node = array_replace($node, $value); | 
            
                                                                        
                            
            
                                    
            
            
                | 448 |  |  |                     } else { | 
            
                                                                        
                            
            
                                    
            
            
                | 449 | 7 |  |                         $node['items'] = $this->parseInternal($value); | 
            
                                                                        
                            
            
                                    
            
            
                | 450 |  |  |                     } | 
            
                                                                        
                            
            
                                    
            
            
                | 451 | 11 |  |                     break; | 
            
                                                                        
                            
            
                                    
            
            
                | 452 | 56 |  |                 case 'object': | 
            
                                                                        
                            
            
                                    
            
            
                | 453 |  |  |                     // The value is a schema of the object. | 
            
                                                                        
                            
            
                                    
            
            
                | 454 | 12 |  |                     if (isset($value['properties'])) { | 
            
                                                                        
                            
            
                                    
            
            
                | 455 |  |  |                         list($node['properties']) = $this->parseProperties($value['properties']); | 
            
                                                                        
                            
            
                                    
            
            
                | 456 |  |  |                     } else { | 
            
                                                                        
                            
            
                                    
            
            
                | 457 | 12 |  |                         list($node['properties'], $required) = $this->parseProperties($value); | 
            
                                                                        
                            
            
                                    
            
            
                | 458 | 12 |  |                         if (!empty($required)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 459 | 12 |  |                             $node['required'] = $required; | 
            
                                                                        
                            
            
                                    
            
            
                | 460 |  |  |                         } | 
            
                                                                        
                            
            
                                    
            
            
                | 461 |  |  |                     } | 
            
                                                                        
                            
            
                                    
            
            
                | 462 | 12 |  |                     break; | 
            
                                                                        
                            
            
                                    
            
            
                | 463 |  |  |                 default: | 
            
                                                                        
                            
            
                                    
            
            
                | 464 | 44 |  |                     $node = array_replace($node, $value); | 
            
                                                                        
                            
            
                                    
            
            
                | 465 | 66 |  |                     break; | 
            
                                                                        
                            
            
                                    
            
            
                | 466 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 467 | 131 |  |         } elseif (is_string($value)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 468 | 102 |  |             if ($node['type'] === 'array' && $arrType = $this->getType($value)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 469 | 6 |  |                 $node['items'] = ['type' => $arrType]; | 
            
                                                                        
                            
            
                                    
            
            
                | 470 | 98 |  |             } elseif (!empty($value)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 471 | 102 |  |                 $node['description'] = $value; | 
            
                                                                        
                            
            
                                    
            
            
                | 472 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 473 | 34 |  |         } elseif ($value === null) { | 
            
                                                                        
                            
            
                                    
            
            
                | 474 |  |  |             // Parse child elements. | 
            
                                                                        
                            
            
                                    
            
            
                | 475 | 30 |  |             if ($node['type'] === 'array' && isset($node['items'])) { | 
            
                                                                        
                            
            
                                    
            
            
                | 476 |  |  |                 // The value includes array schema information. | 
            
                                                                        
                            
            
                                    
            
            
                | 477 |  |  |                 $node['items'] = $this->parseInternal($node['items']); | 
            
                                                                        
                            
            
                                    
            
            
                | 478 | 30 |  |             } elseif ($node['type'] === 'object' && isset($node['properties'])) { | 
            
                                                                        
                            
            
                                    
            
            
                | 479 | 1 |  |                 list($node['properties']) = $this->parseProperties($node['properties']); | 
            
                                                                        
                            
            
                                    
            
            
                | 480 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 481 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 482 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 483 | 171 |  |         if (is_array($node)) { | 
            
                                                                        
                            
            
                                    
            
            
                | 484 | 170 |  |             if (!empty($node['allowNull'])) { | 
            
                                                                        
                            
            
                                    
            
            
                | 485 | 1 |  |                 $node['nullable'] = true; | 
            
                                                                        
                            
            
                                    
            
            
                | 486 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 487 | 170 |  |             unset($node['allowNull']); | 
            
                                                                        
                            
            
                                    
            
            
                | 488 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 489 | 170 |  |             if ($node['type'] === null || $node['type'] === []) { | 
            
                                                                        
                            
            
                                    
            
            
                | 490 | 4 |  |                 unset($node['type']); | 
            
                                                                        
                            
            
                                    
            
            
                | 491 |  |  |             } | 
            
                                                                        
                            
            
                                    
            
            
                | 492 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 493 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 494 | 171 |  |         return $node; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 495 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 496 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 497 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 498 |  |  |      * Parse the schema for an object's properties. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 499 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 500 |  |  |      * @param array $arr An object property schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 501 |  |  |      * @return array Returns a schema array suitable to be placed in the **properties** key of a schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 502 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 503 | 112 |  |     private function parseProperties(array $arr): array { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 504 | 112 |  |         $properties = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 505 | 112 |  |         $requiredProperties = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 506 | 112 |  |         foreach ($arr as $key => $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 507 |  |  |             // Fix a schema specified as just a value. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 508 | 112 |  |             if (is_int($key)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 509 | 82 |  |                 if (is_string($value)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 510 | 82 |  |                     $key = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 511 | 82 |  |                     $value = ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 512 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 513 |  |  |                     throw new \InvalidArgumentException("Schema at position $key is not a valid parameter.", 500); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 514 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 515 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 516 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 517 |  |  |             // The parameter is defined in the key. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 518 | 112 |  |             list($name, $param, $required) = $this->parseShortParam($key, $value); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 519 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 520 | 112 |  |             $node = $this->parseNode($param, $value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 521 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 522 | 112 |  |             $properties[$name] = $node; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 523 | 112 |  |             if ($required) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 524 | 112 |  |                 $requiredProperties[] = $name; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 525 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 526 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 527 | 112 |  |         return [$properties, $requiredProperties]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 528 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 529 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 530 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 531 |  |  |      * Parse a short parameter string into a full array parameter. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 532 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 533 |  |  |      * @param string $key The short parameter string to parse. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 534 |  |  |      * @param array $value An array of other information that might help resolve ambiguity. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 535 |  |  |      * @return array Returns an array in the form `[string name, array param, bool required]`. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 536 |  |  |      * @throws \InvalidArgumentException Throws an exception if the short param is not in the correct format. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 537 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 538 | 172 |  |     public function parseShortParam(string $key, $value = []): array { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 539 |  |  |         // Is the parameter optional? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 540 | 172 |  |         if (substr($key, -1) === '?') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 541 | 70 |  |             $required = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 542 | 70 |  |             $key = substr($key, 0, -1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 543 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 544 | 124 |  |             $required = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 545 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 546 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 547 |  |  |         // Check for a type. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 548 | 172 |  |         if (false !== ($pos = strrpos($key, ':'))) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 549 | 166 |  |             $name = substr($key, 0, $pos); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 550 | 166 |  |             $typeStr = substr($key, $pos + 1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 551 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 552 |  |  |             // Kludge for names with colons that are not specifying an array of a type. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 553 | 166 |  |             if (isset($value['type']) && 'array' !== $this->getType($typeStr)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 554 | 2 |  |                 $name = $key; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 555 | 166 |  |                 $typeStr = ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 556 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 557 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 558 | 16 |  |             $name = $key; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 559 | 16 |  |             $typeStr = ''; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 560 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 561 | 172 |  |         $types = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 562 | 172 |  |         $param = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 563 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 564 | 172 |  |         if (!empty($typeStr)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 565 | 164 |  |             $shortTypes = explode('|', $typeStr); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 566 | 164 |  |             foreach ($shortTypes as $alias) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 567 | 164 |  |                 $found = $this->getType($alias); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 568 | 164 |  |                 if ($found === null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 569 |  |  |                     throw new \InvalidArgumentException("Unknown type '$alias'", 500); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 570 | 164 |  |                 } elseif ($found === 'datetime') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 571 | 9 |  |                     $param['format'] = 'date-time'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 572 | 9 |  |                     $types[] = 'string'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 573 | 156 |  |                 } elseif ($found === 'timestamp') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 574 | 12 |  |                     $param['format'] = 'timestamp'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 575 | 12 |  |                     $types[] = 'integer'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 576 | 150 |  |                 } elseif ($found === 'null') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 577 | 11 |  |                     $nullable = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 578 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 579 | 164 |  |                     $types[] = $found; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 580 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 581 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 582 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 583 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 584 | 172 |  |         if ($value instanceof Schema) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 585 | 6 |  |             if (count($types) === 1 && $types[0] === 'array') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 586 | 1 |  |                 $param += ['type' => $types[0], 'items' => $value]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 587 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 588 | 6 |  |                 $param = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 589 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 590 | 170 |  |         } elseif (isset($value['type'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 591 | 10 |  |             $param = $value + $param; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 592 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 593 | 10 |  |             if (!empty($types) && $types !== (array)$param['type']) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 594 |  |  |                 $typesStr = implode('|', $types); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 595 |  |  |                 $paramTypesStr = implode('|', (array)$param['type']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 596 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 597 | 10 |  |                 throw new \InvalidArgumentException("Type mismatch between $typesStr and {$paramTypesStr} for field $name.", 500); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 598 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 599 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 600 | 165 |  |             if (empty($types) && !empty($parts[1])) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 601 |  |  |                 throw new \InvalidArgumentException("Invalid type {$parts[1]} for field $name.", 500); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 602 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 603 | 165 |  |             if (empty($types)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 604 | 4 |  |                 $param += ['type' => null]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 605 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 606 | 164 |  |                 $param += ['type' => count($types) === 1 ? $types[0] : $types]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 607 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 608 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 609 |  |  |             // Parsed required strings have a minimum length of 1. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 610 | 165 |  |             if (in_array('string', $types) && !empty($name) && $required && (!isset($value['default']) || $value['default'] !== '')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 611 | 41 |  |                 $param['minLength'] = 1; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 612 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 613 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 614 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 615 | 172 |  |         if (!empty($nullable)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 616 | 11 |  |             $param['nullable'] = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 617 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 618 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 619 | 172 |  |         if (is_array($param['type'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 620 | 1 |  |             trigger_error('Schemas with multiple types is deprecated.', E_USER_DEPRECATED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 621 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 622 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 623 | 171 |  |         return [$name, $param, $required]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 624 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 625 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 626 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 627 |  |  |      * Add a custom filter to change data before validation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 628 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 629 |  |  |      * @param string $fieldname The name of the field to filter, if any. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 630 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 631 |  |  |      * If you are adding a filter to a deeply nested field then separate the path with dots. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 632 |  |  |      * @param callable $callback The callback to filter the field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 633 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 634 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 635 | 2 |  |     public function addFilter(string $fieldname, callable $callback) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 636 | 2 |  |         $fieldname = $this->parseFieldSelector($fieldname); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 637 | 2 |  |         $this->filters[$fieldname][] = $callback; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 638 | 2 |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 639 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 640 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 641 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 642 |  |  |      * Add a custom validator to to validate the schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 643 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 644 |  |  |      * @param string $fieldname The name of the field to validate, if any. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 645 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 646 |  |  |      * If you are adding a validator to a deeply nested field then separate the path with dots. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 647 |  |  |      * @param callable $callback The callback to validate with. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 648 |  |  |      * @return Schema Returns `$this` for fluent calls. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 649 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 650 | 5 |  |     public function addValidator(string $fieldname, callable $callback) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 651 | 5 |  |         $fieldname = $this->parseFieldSelector($fieldname); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 652 | 5 |  |         $this->validators[$fieldname][] = $callback; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 653 | 5 |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 654 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 655 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 656 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 657 |  |  |      * Require one of a given set of fields in the schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 658 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 659 |  |  |      * @param array $required The field names to require. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 660 |  |  |      * @param string $fieldname The name of the field to attach to. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 661 |  |  |      * @param int $count The count of required items. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 662 |  |  |      * @return Schema Returns `$this` for fluent calls. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 663 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 664 | 3 |  |     public function requireOneOf(array $required, string $fieldname = '', int $count = 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 665 | 3 |  |         $result = $this->addValidator( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 666 | 3 |  |             $fieldname, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 667 |  |  |             function ($data, ValidationField $field) use ($required, $count) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 668 |  |  |                 // This validator does not apply to sparse validation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 669 | 3 |  |                 if ($field->isSparse()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 670 | 1 |  |                     return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 671 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 672 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 673 | 2 |  |                 $hasCount = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 674 | 2 |  |                 $flattened = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 675 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 676 | 2 |  |                 foreach ($required as $name) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 677 | 2 |  |                     $flattened = array_merge($flattened, (array)$name); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 678 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 679 | 2 |  |                     if (is_array($name)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 680 |  |  |                         // This is an array of required names. They all must match. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 681 | 1 |  |                         $hasCountInner = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 682 | 1 |  |                         foreach ($name as $nameInner) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 683 | 1 |  |                             if (array_key_exists($nameInner, $data)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 684 | 1 |  |                                 $hasCountInner++; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 685 |  |  |                             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 686 | 1 |  |                                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 687 |  |  |                             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 688 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 689 | 1 |  |                         if ($hasCountInner >= count($name)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 690 | 1 |  |                             $hasCount++; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 691 |  |  |                         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 692 | 2 |  |                     } elseif (array_key_exists($name, $data)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 693 | 1 |  |                         $hasCount++; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 694 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 695 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 696 | 2 |  |                     if ($hasCount >= $count) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 697 | 2 |  |                         return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 698 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 699 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 700 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 701 | 2 |  |                 if ($count === 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 702 | 1 |  |                     $message = 'One of {required} are required.'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 703 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 704 | 1 |  |                     $message = '{count} of {required} are required.'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 705 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 706 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 707 | 2 |  |                 $field->addError('missingField', [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 708 | 2 |  |                     'messageCode' => $message, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 709 | 2 |  |                     'required' => $required, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 710 | 2 |  |                     'count' => $count | 
            
                                                                                                            
                            
            
                                    
            
            
                | 711 |  |  |                 ]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 712 | 2 |  |                 return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 713 | 3 |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 714 |  |  |         ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 715 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 716 | 3 |  |         return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 717 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 718 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 719 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 720 |  |  |      * Validate data against the schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 721 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 722 |  |  |      * @param mixed $data The data to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 723 |  |  |      * @param array $options Validation options. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 724 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 725 |  |  |      * - **sparse**: Whether or not this is a sparse validation. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 726 |  |  |      * @return mixed Returns a cleaned version of the data. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 727 |  |  |      * @throws ValidationException Throws an exception when the data does not validate against the schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 728 |  |  |      * @throws RefNotFoundException Throws an exception when a schema `$ref` is not found. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 729 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 730 | 210 |  |     public function validate($data, $options = []) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 731 | 210 |  |         if (is_bool($options)) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 732 | 1 |  |             trigger_error('The $sparse parameter is deprecated. Use [\'sparse\' => true] instead.', E_USER_DEPRECATED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 733 | 1 |  |             $options = ['sparse' => true]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 734 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 735 | 210 |  |         $options += ['sparse' => false]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 736 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 737 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 738 | 210 |  |         list($schema, $schemaPath) = $this->lookupSchema($this->schema, ''); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 739 | 207 |  |         $field = new ValidationField($this->createValidation(), $schema, '', $schemaPath, $options); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 740 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 741 | 207 |  |         $clean = $this->validateField($data, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 742 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 743 | 205 |  |         if (Invalid::isInvalid($clean) && $field->isValid()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 744 |  |  |             // This really shouldn't happen, but we want to protect against seeing the invalid object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 745 |  |  |             $field->addError('invalid', ['messageCode' => '{field} is invalid.', 'status' => 422]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 746 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 747 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 748 | 205 |  |         if (!$field->getValidation()->isValid()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 749 | 70 |  |             throw new ValidationException($field->getValidation()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 750 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 751 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 752 | 150 |  |         return $clean; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 753 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 754 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 755 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 756 |  |  |      * Validate data against the schema and return the result. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 757 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 758 |  |  |      * @param mixed $data The data to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 759 |  |  |      * @param array $options Validation options. See `Schema::validate()`. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 760 |  |  |      * @return bool Returns true if the data is valid. False otherwise. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 761 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 762 | 44 |  |     public function isValid($data, $options = []) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 763 |  |  |         try { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 764 | 44 |  |             $this->validate($data, $options); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 765 | 31 |  |             return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 766 | 23 |  |         } catch (ValidationException $ex) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 767 | 23 |  |             return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 768 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 769 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 770 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 771 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 772 |  |  |      * Validate a field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 773 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 774 |  |  |      * @param mixed $value The value to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 775 |  |  |      * @param ValidationField $field A validation object to add errors to. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 776 |  |  |      * @return mixed|Invalid Returns a clean version of the value with all extra fields stripped out or invalid if the value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 777 |  |  |      * is completely invalid. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 778 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 779 | 207 |  |     protected function validateField($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 780 | 207 |  |         $result = $value = $this->filterField($value, $field); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 781 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 782 | 207 |  |         if ($field->getField() instanceof Schema) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 783 |  |  |             try { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 784 | 5 |  |                 $result = $field->getField()->validate($value, $field->getOptions()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 785 | 2 |  |             } catch (ValidationException $ex) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 786 |  |  |                 // The validation failed, so merge the validations together. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 787 | 5 |  |                 $field->getValidation()->merge($ex->getValidation(), $field->getName()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 788 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 789 | 207 |  |         } elseif (($value === null || ($value === '' && !$field->hasType('string'))) && ($field->val('nullable') || $field->hasType('null'))) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 790 | 13 |  |             $result = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 791 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 792 |  |  |             // Validate the field's type. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 793 | 207 |  |             $type = $field->getType(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 794 | 207 |  |             if (is_array($type)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 795 | 29 |  |                 $result = $this->validateMultipleTypes($value, $type, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 796 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 797 | 186 |  |                 $result = $this->validateSingleType($value, $type, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 798 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 799 | 207 |  |             if (Invalid::isValid($result)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 800 | 199 |  |                 $result = $this->validateEnum($result, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 801 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 802 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 803 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 804 |  |  |         // Validate a custom field validator. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 805 | 207 |  |         if (Invalid::isValid($result)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 806 | 199 |  |             $this->callValidators($result, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 807 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 808 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 809 | 207 |  |         return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 810 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 811 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 812 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 813 |  |  |      * Validate an array. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 814 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 815 |  |  |      * @param mixed $value The value to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 816 |  |  |      * @param ValidationField $field The validation results to add. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 817 |  |  |      * @return array|Invalid Returns an array or invalid if validation fails. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 818 |  |  |      * @throws RefNotFoundException Throws an exception if the array has an items `$ref` that cannot be found. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 819 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 820 | 34 |  |     protected function validateArray($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 821 | 34 |  |         if ((!is_array($value) || (count($value) > 0 && !array_key_exists(0, $value))) && !$value instanceof \Traversable) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 822 | 6 |  |             $field->addTypeError('array'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 823 | 6 |  |             return Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 824 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 825 | 29 |  |             if ((null !== $minItems = $field->val('minItems')) && count($value) < $minItems) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 826 | 1 |  |                 $field->addError( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 827 | 1 |  |                     'minItems', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 828 |  |  |                     [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 829 | 1 |  |                         'messageCode' => '{field} must contain at least {minItems} {minItems,plural,item}.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 830 | 1 |  |                         'minItems' => $minItems, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 831 | 1 |  |                         'status' => 422 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 832 |  |  |                     ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 833 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 834 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 835 | 29 |  |             if ((null !== $maxItems = $field->val('maxItems')) && count($value) > $maxItems) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 836 | 1 |  |                 $field->addError( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 837 | 1 |  |                     'maxItems', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 838 |  |  |                     [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 839 | 1 |  |                         'messageCode' => '{field} must contain no more than {maxItems} {maxItems,plural,item}.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 840 | 1 |  |                         'maxItems' => $maxItems, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 841 | 1 |  |                         'status' => 422 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 842 |  |  |                     ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 843 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 844 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 845 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 846 | 29 |  |             if ($field->val('uniqueItems') && count($value) > count(array_unique($value))) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 847 | 1 |  |                 $field->addError( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 848 | 1 |  |                     'uniqueItems', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 849 |  |  |                     [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 850 | 1 |  |                         'messageCode' => '{field} must contain unique items.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 851 |  |  |                         'status' => 422, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 852 |  |  |                     ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 853 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 854 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 855 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 856 | 29 |  |             if ($field->val('items') !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 857 | 21 |  |                 list ($items, $schemaPath) = $this->lookupSchema($field->val('items'), $field->getSchemaPath().'/items'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 858 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 859 |  |  |                 // Validate each of the types. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 860 | 21 |  |                 $itemValidation = new ValidationField( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 861 | 21 |  |                     $field->getValidation(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 862 | 21 |  |                     $items, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 863 | 21 |  |                     '', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 864 | 21 |  |                     $schemaPath, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 865 | 21 |  |                     $field->getOptions() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 866 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 867 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 868 | 21 |  |                 $result = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 869 | 21 |  |                 $count = 0; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 870 | 21 |  |                 foreach ($value as $i => $item) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 871 | 21 |  |                     $itemValidation->setName($field->getName()."/$i"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 872 | 21 |  |                     $validItem = $this->validateField($item, $itemValidation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 873 | 21 |  |                     if (Invalid::isValid($validItem)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 874 | 21 |  |                         $result[] = $validItem; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 875 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 876 | 21 |  |                     $count++; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 877 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 878 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 879 | 21 |  |                 return empty($result) && $count > 0 ? Invalid::value() : $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 880 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 881 |  |  |                 // Cast the items into a proper numeric array. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 882 | 8 |  |                 $result = is_array($value) ? array_values($value) : iterator_to_array($value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 883 | 8 |  |                 return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 884 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 885 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 886 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 887 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 888 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 889 |  |  |      * Validate a boolean value. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 890 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 891 |  |  |      * @param mixed $value The value to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 892 |  |  |      * @param ValidationField $field The validation results to add. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 893 |  |  |      * @return bool|Invalid Returns the cleaned value or invalid if validation fails. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 894 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 895 | 32 |  |     protected function validateBoolean($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 896 | 32 |  |         $value = $value === null ? $value : filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 897 | 32 |  |         if ($value === null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 898 | 4 |  |             $field->addTypeError('boolean'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 899 | 4 |  |             return Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 900 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 901 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 902 | 29 |  |         return $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 903 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 904 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 905 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 906 |  |  |      * Validate a date time. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 907 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 908 |  |  |      * @param mixed $value The value to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 909 |  |  |      * @param ValidationField $field The validation results to add. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 910 |  |  |      * @return \DateTimeInterface|Invalid Returns the cleaned value or **null** if it isn't valid. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 911 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 912 | 14 |  |     protected function validateDatetime($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 913 | 14 |  |         if ($value instanceof \DateTimeInterface) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 914 |  |  |             // do nothing, we're good | 
            
                                                                                                            
                            
            
                                    
            
            
                | 915 | 11 |  |         } elseif (is_string($value) && $value !== '' && !is_numeric($value)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 916 |  |  |             try { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 917 | 7 |  |                 $dt = new \DateTimeImmutable($value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 918 | 6 |  |                 if ($dt) { | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 919 | 6 |  |                     $value = $dt; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 920 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 921 | 6 |  |                     $value = null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 922 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 923 | 1 |  |             } catch (\Throwable $ex) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 924 | 7 |  |                 $value = Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 925 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 926 | 4 |  |         } elseif (is_int($value) && $value > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 927 |  |  |             try { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 928 | 1 |  |                 $value = new \DateTimeImmutable('@'.(string)round($value)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 929 |  |  |             } catch (\Throwable $ex) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 930 | 1 |  |                 $value = Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 931 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 932 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 933 | 3 |  |             $value = Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 934 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 935 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 936 | 14 |  |         if (Invalid::isInvalid($value)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 937 | 4 |  |             $field->addTypeError('datetime'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 938 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 939 | 14 |  |         return $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 940 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 941 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 942 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 943 |  |  |      * Validate a float. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 944 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 945 |  |  |      * @param mixed $value The value to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 946 |  |  |      * @param ValidationField $field The validation results to add. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 947 |  |  |      * @return float|Invalid Returns a number or **null** if validation fails. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 948 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 949 | 17 |  |     protected function validateNumber($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 950 | 17 |  |         $result = filter_var($value, FILTER_VALIDATE_FLOAT); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 951 | 17 |  |         if ($result === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 952 | 4 |  |             $field->addTypeError('number'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 953 | 4 |  |             return Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 954 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 955 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 956 | 13 |  |         $result = $this->validateNumberProperties($result, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 957 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 958 | 13 |  |         return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 959 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 960 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 961 |  |  |      * Validate and integer. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 962 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 963 |  |  |      * @param mixed $value The value to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 964 |  |  |      * @param ValidationField $field The validation results to add. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 965 |  |  |      * @return int|Invalid Returns the cleaned value or **null** if validation fails. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 966 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 967 | 57 |  |     protected function validateInteger($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 968 | 57 |  |         if ($field->val('format') === 'timestamp') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 969 | 7 |  |             return $this->validateTimestamp($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 970 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 971 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 972 | 52 |  |         $result = filter_var($value, FILTER_VALIDATE_INT); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 973 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 974 | 52 |  |         if ($result === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 975 | 9 |  |             $field->addTypeError('integer'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 976 | 9 |  |             return Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 977 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 978 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 979 | 47 |  |         $result = $this->validateNumberProperties($result, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 980 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 981 | 47 |  |         return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 982 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 983 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 984 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 985 |  |  |      * Validate an object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 986 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 987 |  |  |      * @param mixed $value The value to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 988 |  |  |      * @param ValidationField $field The validation results to add. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 989 |  |  |      * @return object|Invalid Returns a clean object or **null** if validation fails. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 990 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 991 | 114 |  |     protected function validateObject($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 992 | 114 |  |         if (!$this->isArray($value) || isset($value[0])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 993 | 6 |  |             $field->addTypeError('object'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 994 | 6 |  |             return Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 995 | 114 |  |         } elseif (is_array($field->val('properties')) || null !== $field->val('additionalProperties')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 996 |  |  |             // Validate the data against the internal schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 997 | 107 |  |             $value = $this->validateProperties($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 998 | 7 |  |         } elseif (!is_array($value)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 999 | 3 |  |             $value = $this->toObjectArray($value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1000 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1001 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1002 | 112 |  |         if (($maxProperties = $field->val('maxProperties')) && count($value) > $maxProperties) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1003 | 1 |  |             $field->addError( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1004 | 1 |  |                 'maxItems', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1005 |  |  |                 [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1006 | 1 |  |                     'messageCode' => '{field} must contain no more than {maxProperties} {maxProperties,plural,item}.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1007 | 1 |  |                     'maxItems' => $maxProperties, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1008 | 1 |  |                     'status' => 422 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1009 |  |  |                 ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1010 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1011 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1012 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1013 | 112 |  |         if (($minProperties = $field->val('minProperties')) && count($value) < $minProperties) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1014 | 1 |  |             $field->addError( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1015 | 1 |  |                 'minItems', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1016 |  |  |                 [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1017 | 1 |  |                     'messageCode' => '{field} must contain at least {minProperties} {minProperties,plural,item}.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1018 | 1 |  |                     'minItems' => $minProperties, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1019 | 1 |  |                     'status' => 422 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1020 |  |  |                 ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1021 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1022 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1023 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1024 | 112 |  |         return $value; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1025 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1026 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1027 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1028 |  |  |      * Validate data against the schema and return the result. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1029 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1030 |  |  |      * @param array|\Traversable|\ArrayAccess $data The data to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1031 |  |  |      * @param ValidationField $field This argument will be filled with the validation result. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1032 |  |  |      * @return array|Invalid Returns a clean array with only the appropriate properties and the data coerced to proper types. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1033 |  |  |      * or invalid if there are no valid properties. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1034 |  |  |      * @throws RefNotFoundException Throws an exception of a property or additional property has a `$ref` that cannot be found. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1035 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1036 | 107 |  |     protected function validateProperties($data, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1037 | 107 |  |         $properties = $field->val('properties', []); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1038 | 107 |  |         $additionalProperties = $field->val('additionalProperties'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1039 | 107 |  |         $required = array_flip($field->val('required', [])); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1040 | 107 |  |         $isRequest = $field->isRequest(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1041 | 107 |  |         $isResponse = $field->isResponse(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1042 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1043 | 107 |  |         if (is_array($data)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1044 | 103 |  |             $keys = array_keys($data); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1045 | 103 |  |             $clean = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1046 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1047 | 4 |  |             $keys = array_keys(iterator_to_array($data)); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1048 | 4 |  |             $class = get_class($data); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1049 | 4 |  |             $clean = new $class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1050 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1051 | 4 |  |             if ($clean instanceof \ArrayObject && $data instanceof \ArrayObject) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1052 | 3 |  |                 $clean->setFlags($data->getFlags()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1053 | 3 |  |                 $clean->setIteratorClass($data->getIteratorClass()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1054 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1055 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1056 | 107 |  |         $keys = array_combine(array_map('strtolower', $keys), $keys); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1057 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1058 | 107 |  |         $propertyField = new ValidationField($field->getValidation(), [], '', '', $field->getOptions()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1059 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1060 |  |  |         // Loop through the schema fields and validate each one. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1061 | 107 |  |         foreach ($properties as $propertyName => $property) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1062 | 105 |  |             list($property, $schemaPath) = $this->lookupSchema($property, $field->getSchemaPath().'/properties/'.$propertyField->escapeRef($propertyName)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1063 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1064 |  |  |             $propertyField | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1065 | 105 |  |                 ->setField($property) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1066 | 105 |  |                 ->setName(ltrim($field->getName().'/'.$propertyField->escapeRef($propertyName), '/')) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1067 | 105 |  |                 ->setSchemaPath($schemaPath) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1068 |  |  |             ; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1069 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1070 | 105 |  |             $lName = strtolower($propertyName); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1071 | 105 |  |             $isRequired = isset($required[$propertyName]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1072 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1073 |  |  |             // Check to strip this field if it is readOnly or writeOnly. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1074 | 105 |  |             if (($isRequest && $propertyField->val('readOnly')) || ($isResponse && $propertyField->val('writeOnly'))) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1075 | 6 |  |                 unset($keys[$lName]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1076 | 6 |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1077 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1078 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1079 |  |  |             // Check for required fields. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1080 | 105 |  |             if (!array_key_exists($lName, $keys)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1081 | 30 |  |                 if ($field->isSparse()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1082 |  |  |                     // Sparse validation can leave required fields out. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1083 | 29 |  |                 } elseif ($propertyField->hasVal('default')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1084 | 3 |  |                     $clean[$propertyName] = $propertyField->val('default'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1085 | 26 |  |                 } elseif ($isRequired) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1086 | 30 |  |                     $propertyField->addError('missingField', ['messageCode' => '{field} is required.']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1087 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1088 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1089 | 93 |  |                 $value = $data[$keys[$lName]]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1090 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1091 | 93 |  |                 if (in_array($value, [null, ''], true) && !$isRequired && !($propertyField->val('nullable') || $propertyField->hasType('null'))) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1092 | 5 |  |                     if ($propertyField->getType() !== 'string' || $value === null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1093 | 2 |  |                         continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1094 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1095 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1096 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1097 | 91 |  |                 $clean[$propertyName] = $this->validateField($value, $propertyField); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1098 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1099 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1100 | 103 |  |             unset($keys[$lName]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1101 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1102 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1103 |  |  |         // Look for extraneous properties. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1104 | 107 |  |         if (!empty($keys)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1105 | 17 |  |             if ($additionalProperties) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1106 | 6 |  |                 list($additionalProperties, $schemaPath) = $this->lookupSchema( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1107 | 6 |  |                     $additionalProperties, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1108 | 6 |  |                     $field->getSchemaPath().'/additionalProperties' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1109 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1110 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1111 | 6 |  |                 $propertyField = new ValidationField( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1112 | 6 |  |                     $field->getValidation(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1113 | 6 |  |                     $additionalProperties, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1114 | 6 |  |                     '', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1115 | 6 |  |                     $schemaPath, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1116 | 6 |  |                     $field->getOptions() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1117 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1118 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1119 | 6 |  |                 foreach ($keys as $key) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1120 |  |  |                     $propertyField | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1121 | 6 |  |                         ->setName(ltrim($field->getName()."/$key", '/')); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1122 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1123 | 6 |  |                     $valid = $this->validateField($data[$key], $propertyField); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1124 | 6 |  |                     if (Invalid::isValid($valid)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1125 | 6 |  |                         $clean[$key] = $valid; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1126 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1127 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1128 | 11 |  |             } elseif ($this->hasFlag(Schema::VALIDATE_EXTRA_PROPERTY_NOTICE)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1129 | 2 |  |                 $msg = sprintf("%s has unexpected field(s): %s.", $field->getName() ?: 'value', implode(', ', $keys)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1130 | 2 |  |                 trigger_error($msg, E_USER_NOTICE); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1131 | 9 |  |             } elseif ($this->hasFlag(Schema::VALIDATE_EXTRA_PROPERTY_EXCEPTION)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1132 | 2 |  |                 $field->addError('invalid', [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1133 | 2 |  |                     'messageCode' => '{field} has {extra,plural,an unexpected field,unexpected fields}: {extra}.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1134 | 2 |  |                     'extra' => array_values($keys), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1135 | 2 |  |                     'status' => 422 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1136 |  |  |                 ]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1137 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1138 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1139 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1140 | 105 |  |         return $clean; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1141 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1142 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1143 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1144 |  |  |      * Validate a string. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1145 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1146 |  |  |      * @param mixed $value The value to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1147 |  |  |      * @param ValidationField $field The validation results to add. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1148 |  |  |      * @return string|Invalid Returns the valid string or **null** if validation fails. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1149 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1150 | 83 |  |     protected function validateString($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1151 | 83 |  |         if ($field->val('format') === 'date-time') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1152 | 12 |  |             $result = $this->validateDatetime($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1153 | 12 |  |             return $result; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1154 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1155 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1156 | 72 |  |         if (is_string($value) || is_numeric($value)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1157 | 70 |  |             $value = $result = (string)$value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1158 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1159 | 5 |  |             $field->addTypeError('string'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1160 | 5 |  |             return Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1161 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1162 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1163 | 70 |  |         if (($minLength = $field->val('minLength', 0)) > 0 && mb_strlen($value) < $minLength) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1164 | 4 |  |             if (!empty($field->getName()) && $minLength === 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1165 | 2 |  |                 $field->addError('missingField', ['messageCode' => '{field} is required.', 'status' => 422]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1166 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1167 | 2 |  |                 $field->addError( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1168 | 2 |  |                     'minLength', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1169 |  |  |                     [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1170 | 2 |  |                         'messageCode' => '{field} should be at least {minLength} {minLength,plural,character} long.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1171 | 2 |  |                         'minLength' => $minLength, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1172 | 2 |  |                         'status' => 422 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1173 |  |  |                     ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1174 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1175 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1176 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1177 | 70 |  |         if (($maxLength = $field->val('maxLength', 0)) > 0 && mb_strlen($value) > $maxLength) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1178 | 1 |  |             $field->addError( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1179 | 1 |  |                 'maxLength', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1180 |  |  |                 [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1181 | 1 |  |                     'messageCode' => '{field} is {overflow} {overflow,plural,characters} too long.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1182 | 1 |  |                     'maxLength' => $maxLength, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1183 | 1 |  |                     'overflow' => mb_strlen($value) - $maxLength, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1184 | 1 |  |                     'status' => 422 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1185 |  |  |                 ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1186 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1187 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1188 | 70 |  |         if ($pattern = $field->val('pattern')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1189 | 4 |  |             $regex = '`'.str_replace('`', preg_quote('`', '`'), $pattern).'`'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1190 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1191 | 4 |  |             if (!preg_match($regex, $value)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1192 | 2 |  |                 $field->addError( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1193 | 2 |  |                     'invalid', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1194 |  |  |                     [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1195 | 2 |  |                         'messageCode' => '{field} is in the incorrect format.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1196 |  |  |                         'status' => 422 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1197 |  |  |                     ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1198 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1199 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1200 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1201 | 70 |  |         if ($format = $field->val('format')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1202 | 11 |  |             $type = $format; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1203 |  |  |             switch ($format) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1204 | 11 |  |                 case 'date': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1205 |  |  |                     $result = $this->validateDatetime($result, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1206 |  |  |                     if ($result instanceof \DateTimeInterface) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1207 |  |  |                         $result = $result->format("Y-m-d\T00:00:00P"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1208 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1209 |  |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1210 | 11 |  |                 case 'email': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1211 | 1 |  |                     $result = filter_var($result, FILTER_VALIDATE_EMAIL); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1212 | 1 |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1213 | 10 |  |                 case 'ipv4': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1214 | 1 |  |                     $type = 'IPv4 address'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1215 | 1 |  |                     $result = filter_var($result, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1216 | 1 |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1217 | 9 |  |                 case 'ipv6': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1218 | 1 |  |                     $type = 'IPv6 address'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1219 | 1 |  |                     $result = filter_var($result, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1220 | 1 |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1221 | 8 |  |                 case 'ip': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1222 | 1 |  |                     $type = 'IP address'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1223 | 1 |  |                     $result = filter_var($result, FILTER_VALIDATE_IP); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1224 | 1 |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1225 | 7 |  |                 case 'uri': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1226 | 7 |  |                     $type = 'URI'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1227 | 7 |  |                     $result = filter_var($result, FILTER_VALIDATE_URL); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1228 | 7 |  |                     break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1229 |  |  |                 default: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1230 |  |  |                     trigger_error("Unrecognized format '$format'.", E_USER_NOTICE); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1231 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1232 | 11 |  |             if ($result === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1233 | 5 |  |                 $field->addTypeError($type); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1234 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1235 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1236 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1237 | 70 |  |         if ($field->isValid()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1238 | 62 |  |             return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1239 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1240 | 12 |  |             return Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1241 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1242 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1243 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1244 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1245 |  |  |      * Validate a unix timestamp. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1246 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1247 |  |  |      * @param mixed $value The value to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1248 |  |  |      * @param ValidationField $field The field being validated. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1249 |  |  |      * @return int|Invalid Returns a valid timestamp or invalid if the value doesn't validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1250 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1251 | 8 |  |     protected function validateTimestamp($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1252 | 8 |  |         if (is_numeric($value) && $value > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1253 | 3 |  |             $result = (int)$value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1254 | 5 |  |         } elseif (is_string($value) && $ts = strtotime($value)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1255 | 1 |  |             $result = $ts; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1256 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1257 | 4 |  |             $field->addTypeError('timestamp'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1258 | 4 |  |             $result = Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1259 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1260 | 8 |  |         return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1261 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1262 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1263 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1264 |  |  |      * Validate a null value. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1265 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1266 |  |  |      * @param mixed $value The value to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1267 |  |  |      * @param ValidationField $field The error collector for the field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1268 |  |  |      * @return null|Invalid Returns **null** or invalid. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1269 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1270 |  |  |     protected function validateNull($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1271 |  |  |         if ($value === null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1272 |  |  |             return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1273 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1274 |  |  |         $field->addError('invalid', ['messageCode' => '{field} should be null.', 'status' => 422]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1275 |  |  |         return Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1276 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1277 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1278 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1279 |  |  |      * Validate a value against an enum. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1280 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1281 |  |  |      * @param mixed $value The value to test. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1282 |  |  |      * @param ValidationField $field The validation object for adding errors. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1283 |  |  |      * @return mixed|Invalid Returns the value if it is one of the enumerated values or invalid otherwise. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1284 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1285 | 199 |  |     protected function validateEnum($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1286 | 199 |  |         $enum = $field->val('enum'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1287 | 199 |  |         if (empty($enum)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1288 | 198 |  |             return $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1289 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1290 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1291 | 1 |  |         if (!in_array($value, $enum, true)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1292 | 1 |  |             $field->addError( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1293 | 1 |  |                 'invalid', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1294 |  |  |                 [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1295 | 1 |  |                     'messageCode' => '{field} must be one of: {enum}.', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1296 | 1 |  |                     'enum' => $enum, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1297 | 1 |  |                     'status' => 422 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1298 |  |  |                 ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1299 |  |  |             ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1300 | 1 |  |             return Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1301 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1302 | 1 |  |         return $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1303 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1304 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1305 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1306 |  |  |      * Call all of the filters attached to a field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1307 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1308 |  |  |      * @param mixed $value The field value being filtered. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1309 |  |  |      * @param ValidationField $field The validation object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1310 |  |  |      * @return mixed Returns the filtered value. If there are no filters for the field then the original value is returned. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1311 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1312 | 207 |  |     protected function callFilters($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1313 |  |  |         // Strip array references in the name except for the last one. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1314 | 207 |  |         $key = $field->getSchemaPath(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1315 | 207 |  |         if (!empty($this->filters[$key])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1316 | 2 |  |             foreach ($this->filters[$key] as $filter) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1317 | 2 |  |                 $value = call_user_func($filter, $value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1318 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1319 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1320 | 207 |  |         return $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1321 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1322 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1323 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1324 |  |  |      * Call all of the validators attached to a field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1325 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1326 |  |  |      * @param mixed $value The field value being validated. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1327 |  |  |      * @param ValidationField $field The validation object to add errors. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1328 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1329 | 199 |  |     protected function callValidators($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1330 | 199 |  |         $valid = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1331 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1332 |  |  |         // Strip array references in the name except for the last one. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1333 | 199 |  |         $key = $field->getSchemaPath(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1334 | 199 |  |         if (!empty($this->validators[$key])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1335 | 5 |  |             foreach ($this->validators[$key] as $validator) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1336 | 5 |  |                 $r = call_user_func($validator, $value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1337 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1338 | 5 |  |                 if ($r === false || Invalid::isInvalid($r)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1339 | 5 |  |                     $valid = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1340 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1341 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1342 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1343 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1344 |  |  |         // Add an error on the field if the validator hasn't done so. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1345 | 199 |  |         if (!$valid && $field->isValid()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1346 | 1 |  |             $field->addError('invalid', ['messageCode' => '{field} is invalid.', 'status' => 422]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1347 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1348 | 199 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1349 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1350 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1351 |  |  |      * Specify data which should be serialized to JSON. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1352 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1353 |  |  |      * This method specifically returns data compatible with the JSON schema format. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1354 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1355 |  |  |      * @return mixed Returns data which can be serialized by **json_encode()**, which is a value of any type other than a resource. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1356 |  |  |      * @link http://php.net/manual/en/jsonserializable.jsonserialize.php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1357 |  |  |      * @link http://json-schema.org/ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1358 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1359 | 16 |  |     public function jsonSerialize() { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1360 |  |  |         $fix = function ($schema) use (&$fix) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1361 | 16 |  |             if ($schema instanceof Schema) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1362 | 1 |  |                 return $schema->jsonSerialize(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1363 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1364 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1365 | 16 |  |             if (!empty($schema['type'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1366 | 15 |  |                 $types = (array)$schema['type']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1367 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1368 | 15 |  |                 foreach ($types as $i => &$type) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1369 |  |  |                     // Swap datetime and timestamp to other types with formats. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1370 | 15 |  |                     if ($type === 'datetime') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1371 | 4 |  |                         $type = 'string'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1372 | 4 |  |                         $schema['format'] = 'date-time'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1373 | 14 |  |                     } elseif ($schema['type'] === 'timestamp') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1374 | 2 |  |                         $type = 'integer'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1375 | 15 |  |                         $schema['format'] = 'timestamp'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1376 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1377 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1378 | 15 |  |                 $types = array_unique($types); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1379 | 15 |  |                 $schema['type'] = count($types) === 1 ? reset($types) : $types; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1380 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1381 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1382 | 16 |  |             if (!empty($schema['items'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1383 | 4 |  |                 $schema['items'] = $fix($schema['items']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1384 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1385 | 16 |  |             if (!empty($schema['properties'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1386 | 11 |  |                 $properties = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1387 | 11 |  |                 foreach ($schema['properties'] as $key => $property) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1388 | 11 |  |                     $properties[$key] = $fix($property); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1389 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1390 | 11 |  |                 $schema['properties'] = $properties; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1391 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1392 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1393 | 16 |  |             return $schema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1394 | 16 |  |         }; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1395 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1396 | 16 |  |         $result = $fix($this->schema); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1397 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1398 | 16 |  |         return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1399 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1400 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1401 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1402 |  |  |      * Look up a type based on its alias. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1403 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1404 |  |  |      * @param string $alias The type alias or type name to lookup. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1405 |  |  |      * @return mixed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1406 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1407 | 166 |  |     protected function getType($alias) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1408 | 166 |  |         if (isset(self::$types[$alias])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1409 |  |  |             return $alias; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1410 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1411 | 166 |  |         foreach (self::$types as $type => $aliases) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1412 | 166 |  |             if (in_array($alias, $aliases, true)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1413 | 166 |  |                 return $type; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1414 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1415 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1416 | 11 |  |         return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1417 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1418 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1419 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1420 |  |  |      * Get the class that's used to contain validation information. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1421 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1422 |  |  |      * @return Validation|string Returns the validation class. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1423 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1424 | 207 |  |     public function getValidationClass() { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1425 | 207 |  |         return $this->validationClass; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1426 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1427 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1428 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1429 |  |  |      * Set the class that's used to contain validation information. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1430 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1431 |  |  |      * @param Validation|string $class Either the name of a class or a class that will be cloned. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1432 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1433 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1434 | 1 |  |     public function setValidationClass($class) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1435 | 1 |  |         if (!is_a($class, Validation::class, true)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1436 |  |  |             throw new \InvalidArgumentException("$class must be a subclass of ".Validation::class, 500); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1437 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1438 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1439 | 1 |  |         $this->validationClass = $class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1440 | 1 |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1441 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1442 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1443 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1444 |  |  |      * Create a new validation instance. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1445 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1446 |  |  |      * @return Validation Returns a validation object. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1447 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1448 | 207 |  |     protected function createValidation() { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1449 | 207 |  |         $class = $this->getValidationClass(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1450 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1451 | 207 |  |         if ($class instanceof Validation) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1452 | 1 |  |             $result = clone $class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1453 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1454 | 207 |  |             $result = new $class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1455 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1456 | 207 |  |         return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1457 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1458 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1459 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1460 |  |  |      * Check whether or not a value is an array or accessible like an array. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1461 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1462 |  |  |      * @param mixed $value The value to check. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1463 |  |  |      * @return bool Returns **true** if the value can be used like an array or **false** otherwise. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1464 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1465 | 114 |  |     private function isArray($value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1466 | 114 |  |         return is_array($value) || ($value instanceof \ArrayAccess && $value instanceof \Traversable); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1467 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1468 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1469 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1470 |  |  |      * Cast a value to an array. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1471 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1472 |  |  |      * @param \Traversable $value The value to convert. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1473 |  |  |      * @return array Returns an array. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1474 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1475 | 3 |  |     private function toObjectArray(\Traversable $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1476 | 3 |  |         $class = get_class($value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1477 | 3 |  |         if ($value instanceof \ArrayObject) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1478 | 2 |  |             return new $class($value->getArrayCopy(), $value->getFlags(), $value->getIteratorClass()); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1479 | 1 |  |         } elseif ($value instanceof \ArrayAccess) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1480 | 1 |  |             $r = new $class; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1481 | 1 |  |             foreach ($value as $k => $v) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1482 | 1 |  |                 $r[$k] = $v; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1483 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1484 | 1 |  |             return $r; | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1485 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1486 |  |  |         return iterator_to_array($value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1487 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1488 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1489 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1490 |  |  |      * Return a sparse version of this schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1491 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1492 |  |  |      * A sparse schema has no required properties. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1493 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1494 |  |  |      * @return Schema Returns a new sparse schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1495 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1496 | 2 |  |     public function withSparse() { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1497 | 2 |  |         $sparseSchema = $this->withSparseInternal($this, new \SplObjectStorage()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1498 | 2 |  |         return $sparseSchema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1499 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1500 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1501 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1502 |  |  |      * The internal implementation of `Schema::withSparse()`. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1503 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1504 |  |  |      * @param array|Schema $schema The schema to make sparse. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1505 |  |  |      * @param \SplObjectStorage $schemas Collected sparse schemas that have already been made. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1506 |  |  |      * @return mixed | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1507 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1508 | 2 |  |     private function withSparseInternal($schema, \SplObjectStorage $schemas) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1509 | 2 |  |         if ($schema instanceof Schema) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1510 | 2 |  |             if ($schemas->contains($schema)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1511 | 1 |  |                 return $schemas[$schema]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1512 |  |  |             } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1513 | 2 |  |                 $schemas[$schema] = $sparseSchema = new Schema(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1514 | 2 |  |                 $sparseSchema->schema = $schema->withSparseInternal($schema->schema, $schemas); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1515 | 2 |  |                 if ($id = $sparseSchema->getID()) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1516 |  |  |                     $sparseSchema->setID($id.'Sparse'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1517 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1518 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1519 | 2 |  |                 return $sparseSchema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1520 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1521 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1522 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1523 | 2 |  |         unset($schema['required']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1524 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1525 | 2 |  |         if (isset($schema['items'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1526 | 1 |  |             $schema['items'] = $this->withSparseInternal($schema['items'], $schemas); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1527 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1528 | 2 |  |         if (isset($schema['properties'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1529 | 2 |  |             foreach ($schema['properties'] as $name => &$property) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1530 | 2 |  |                 $property = $this->withSparseInternal($property, $schemas); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1531 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1532 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1533 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1534 | 2 |  |         return $schema; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1535 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1536 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1537 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1538 |  |  |      * Filter a field's value using built in and custom filters. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1539 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1540 |  |  |      * @param mixed $value The original value of the field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1541 |  |  |      * @param ValidationField $field The field information for the field. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1542 |  |  |      * @return mixed Returns the filtered field or the original field value if there are no filters. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1543 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1544 | 207 |  |     private function filterField($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1545 |  |  |         // Check for limited support for Open API style. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1546 | 207 |  |         if (!empty($field->val('style')) && is_string($value)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1547 | 8 |  |             $doFilter = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1548 | 8 |  |             if ($field->hasType('boolean') && in_array($value, ['true', 'false', '0', '1'], true)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1549 | 4 |  |                 $doFilter = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1550 | 4 |  |             } elseif ($field->hasType('integer') || $field->hasType('number') && is_numeric($value)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1551 |  |  |                 $doFilter = false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1552 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1553 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1554 | 8 |  |             if ($doFilter) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1555 | 4 |  |                 switch ($field->val('style')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1556 | 4 |  |                     case 'form': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1557 | 2 |  |                         $value = explode(',', $value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1558 | 2 |  |                         break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1559 | 2 |  |                     case 'spaceDelimited': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1560 | 1 |  |                         $value = explode(' ', $value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1561 | 1 |  |                         break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1562 | 1 |  |                     case 'pipeDelimited': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1563 | 1 |  |                         $value = explode('|', $value); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1564 | 1 |  |                         break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1565 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1566 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1567 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1568 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1569 | 207 |  |         $value = $this->callFilters($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1570 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1571 | 207 |  |         return $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1572 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1573 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1574 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1575 |  |  |      * Whether a offset exists. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1576 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1577 |  |  |      * @param mixed $offset An offset to check for. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1578 |  |  |      * @return boolean true on success or false on failure. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1579 |  |  |      * @link http://php.net/manual/en/arrayaccess.offsetexists.php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1580 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1581 | 7 |  |     public function offsetExists($offset) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1582 | 7 |  |         return isset($this->schema[$offset]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1583 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1584 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1585 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1586 |  |  |      * Offset to retrieve. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1587 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1588 |  |  |      * @param mixed $offset The offset to retrieve. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1589 |  |  |      * @return mixed Can return all value types. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1590 |  |  |      * @link http://php.net/manual/en/arrayaccess.offsetget.php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1591 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1592 | 7 |  |     public function offsetGet($offset) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1593 | 7 |  |         return isset($this->schema[$offset]) ? $this->schema[$offset] : null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1594 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1595 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1596 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1597 |  |  |      * Offset to set. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1598 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1599 |  |  |      * @param mixed $offset The offset to assign the value to. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1600 |  |  |      * @param mixed $value The value to set. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1601 |  |  |      * @link http://php.net/manual/en/arrayaccess.offsetset.php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1602 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1603 | 1 |  |     public function offsetSet($offset, $value) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1604 | 1 |  |         $this->schema[$offset] = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1605 | 1 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1606 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1607 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1608 |  |  |      * Offset to unset. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1609 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1610 |  |  |      * @param mixed $offset The offset to unset. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1611 |  |  |      * @link http://php.net/manual/en/arrayaccess.offsetunset.php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1612 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1613 | 1 |  |     public function offsetUnset($offset) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1614 | 1 |  |         unset($this->schema[$offset]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1615 | 1 |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1616 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1617 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1618 |  |  |      * Validate a field against a single type. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1619 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1620 |  |  |      * @param mixed $value The value to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1621 |  |  |      * @param string $type The type to validate against. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1622 |  |  |      * @param ValidationField $field Contains field and validation information. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1623 |  |  |      * @return mixed Returns the valid value or `Invalid`. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1624 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1625 | 207 |  |     protected function validateSingleType($value, $type, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1626 |  |  |         switch ($type) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1627 | 207 |  |             case 'boolean': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1628 | 32 |  |                 $result = $this->validateBoolean($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1629 | 32 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1630 | 187 |  |             case 'integer': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1631 | 57 |  |                 $result = $this->validateInteger($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1632 | 57 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1633 | 169 |  |             case 'number': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1634 | 17 |  |                 $result = $this->validateNumber($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1635 | 17 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1636 | 160 |  |             case 'string': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1637 | 83 |  |                 $result = $this->validateString($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1638 | 83 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1639 | 136 |  |             case 'timestamp': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1640 | 1 |  |                 trigger_error('The timestamp type is deprecated. Use an integer with a format of timestamp instead.', E_USER_DEPRECATED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1641 | 1 |  |                 $result = $this->validateTimestamp($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1642 | 1 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1643 | 136 |  |             case 'datetime': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1644 | 2 |  |                 trigger_error('The datetime type is deprecated. Use a string with a format of date-time instead.', E_USER_DEPRECATED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1645 | 2 |  |                 $result = $this->validateDatetime($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1646 | 2 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1647 | 135 |  |             case 'array': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1648 | 34 |  |                 $result = $this->validateArray($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1649 | 34 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1650 | 115 |  |             case 'object': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1651 | 114 |  |                 $result = $this->validateObject($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1652 | 112 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1653 | 5 |  |             case 'null': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1654 |  |  |                 $result = $this->validateNull($value, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1655 |  |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1656 | 5 |  |             case null: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1657 |  |  |                 // No type was specified so we are valid. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1658 | 5 |  |                 $result = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1659 | 5 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1660 |  |  |             default: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1661 |  |  |                 throw new \InvalidArgumentException("Unrecognized type $type.", 500); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1662 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1663 | 207 |  |         return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1664 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1665 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1666 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1667 |  |  |      * Validate a field against multiple basic types. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1668 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1669 |  |  |      * The first validation that passes will be returned. If no type can be validated against then validation will fail. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1670 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1671 |  |  |      * @param mixed $value The value to validate. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1672 |  |  |      * @param string[] $types The types to validate against. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1673 |  |  |      * @param ValidationField $field Contains field and validation information. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1674 |  |  |      * @return mixed Returns the valid value or `Invalid`. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1675 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1676 | 29 |  |     private function validateMultipleTypes($value, array $types, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1677 | 29 |  |         trigger_error('Multiple schema types are deprecated.', E_USER_DEPRECATED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1678 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1679 |  |  |         // First check for an exact type match. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1680 | 29 |  |         switch (gettype($value)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1681 | 29 |  |             case 'boolean': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1682 | 4 |  |                 if (in_array('boolean', $types)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1683 | 4 |  |                     $singleType = 'boolean'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1684 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1685 | 4 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1686 | 26 |  |             case 'integer': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1687 | 7 |  |                 if (in_array('integer', $types)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1688 | 5 |  |                     $singleType = 'integer'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1689 | 2 |  |                 } elseif (in_array('number', $types)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1690 | 1 |  |                     $singleType = 'number'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1691 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1692 | 7 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1693 | 21 |  |             case 'double': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1694 | 4 |  |                 if (in_array('number', $types)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1695 | 4 |  |                     $singleType = 'number'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1696 |  |  |                 } elseif (in_array('integer', $types)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1697 |  |  |                     $singleType = 'integer'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1698 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1699 | 4 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1700 | 18 |  |             case 'string': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1701 | 9 |  |                 if (in_array('datetime', $types) && preg_match(self::$DATE_REGEX, $value)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1702 | 1 |  |                     $singleType = 'datetime'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1703 | 8 |  |                 } elseif (in_array('string', $types)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1704 | 4 |  |                     $singleType = 'string'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1705 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1706 | 9 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1707 | 10 |  |             case 'array': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1708 | 10 |  |                 if (in_array('array', $types) && in_array('object', $types)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1709 | 1 |  |                     $singleType = isset($value[0]) || empty($value) ? 'array' : 'object'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1710 | 9 |  |                 } elseif (in_array('object', $types)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1711 |  |  |                     $singleType = 'object'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1712 | 9 |  |                 } elseif (in_array('array', $types)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1713 | 9 |  |                     $singleType = 'array'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1714 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1715 | 10 |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1716 | 1 |  |             case 'NULL': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1717 |  |  |                 if (in_array('null', $types)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1718 |  |  |                     $singleType = $this->validateSingleType($value, 'null', $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1719 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1720 |  |  |                 break; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1721 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1722 | 29 |  |         if (!empty($singleType)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1723 | 25 |  |             return $this->validateSingleType($value, $singleType, $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1724 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1725 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1726 |  |  |         // Clone the validation field to collect errors. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1727 | 6 |  |         $typeValidation = new ValidationField(new Validation(), $field->getField(), '', '', $field->getOptions()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1728 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1729 |  |  |         // Try and validate against each type. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1730 | 6 |  |         foreach ($types as $type) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1731 | 6 |  |             $result = $this->validateSingleType($value, $type, $typeValidation); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1732 | 6 |  |             if (Invalid::isValid($result)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1733 | 6 |  |                 return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1734 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1735 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1736 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1737 |  |  |         // Since we got here the value is invalid. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1738 |  |  |         $field->merge($typeValidation->getValidation()); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1739 |  |  |         return Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1740 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1741 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1742 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1743 |  |  |      * Validate specific numeric validation properties. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1744 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1745 |  |  |      * @param int|float $value The value to test. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1746 |  |  |      * @param ValidationField $field Field information. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1747 |  |  |      * @return int|float|Invalid Returns the number of invalid. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1748 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1749 | 57 |  |     private function validateNumberProperties($value, ValidationField $field) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1750 | 57 |  |         $count = $field->getErrorCount(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1751 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1752 | 57 |  |         if ($multipleOf = $field->val('multipleOf')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1753 | 4 |  |             $divided = $value / $multipleOf; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1754 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1755 | 4 |  |             if ($divided != round($divided)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1756 | 2 |  |                 $field->addError('multipleOf', ['messageCode' => '{field} is not a multiple of {multipleOf}.', 'status' => 422, 'multipleOf' => $multipleOf]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1757 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1758 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1759 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1760 | 57 |  |         if ($maximum = $field->val('maximum')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1761 | 4 |  |             $exclusive = $field->val('exclusiveMaximum'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1762 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1763 | 4 |  |             if ($value > $maximum || ($exclusive && $value == $maximum)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1764 | 2 |  |                 if ($exclusive) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1765 | 1 |  |                     $field->addError('maximum', ['messageCode' => '{field} is greater than or equal to {maximum}.', 'status' => 422, 'maximum' => $maximum]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1766 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1767 | 1 |  |                     $field->addError('maximum', ['messageCode' => '{field} is greater than {maximum}.', 'status' => 422, 'maximum' => $maximum]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1768 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1769 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1770 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1771 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1772 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1773 | 57 |  |         if ($minimum = $field->val('minimum')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1774 | 4 |  |             $exclusive = $field->val('exclusiveMinimum'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1775 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1776 | 4 |  |             if ($value < $minimum || ($exclusive && $value == $minimum)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1777 | 2 |  |                 if ($exclusive) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1778 | 1 |  |                     $field->addError('minimum', ['messageCode' => '{field} is greater than or equal to {minimum}.', 'status' => 422, 'minimum' => $minimum]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1779 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1780 | 1 |  |                     $field->addError('minimum', ['messageCode' => '{field} is greater than {minimum}.', 'status' => 422, 'minimum' => $minimum]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1781 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1782 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1783 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1784 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1785 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1786 | 57 |  |         return $field->getErrorCount() === $count ? $value : Invalid::value(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1787 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1788 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1789 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1790 |  |  |      * Parse a nested field name selector. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1791 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1792 |  |  |      * Field selectors should be separated by "/" characters, but may currently be separated by "." characters which | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1793 |  |  |      * triggers a deprecated error. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1794 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1795 |  |  |      * @param string $field The field selector. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1796 |  |  |      * @return string Returns the field selector in the correct format. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1797 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1798 | 15 |  |     private function parseFieldSelector(string $field): string { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1799 | 15 |  |         if (strlen($field) === 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1800 | 4 |  |             return $field; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1801 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1802 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1803 | 11 |  |         if (strpos($field, '.') !== false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1804 | 1 |  |             if (strpos($field, '/') === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1805 | 1 |  |                 trigger_error('Field selectors must be separated by "/" instead of "."', E_USER_DEPRECATED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1806 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1807 | 1 |  |                 $parts = explode('.', $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1808 | 1 |  |                 $parts = @array_map([$this, 'parseFieldSelector'], $parts); // silence because error triggered already. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1809 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1810 | 1 |  |                 $field = implode('/', $parts); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1811 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1812 | 11 |  |         } elseif ($field === '[]') { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1813 | 1 |  |             trigger_error('Field selectors with item selector "[]" must be converted to "items".', E_USER_DEPRECATED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1814 | 1 |  |             $field = 'items'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1815 | 10 |  |         } elseif (strpos($field, '/') === false && !in_array($field, ['items', 'additionalProperties'], true)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1816 | 3 |  |             trigger_error("Field selectors must specify full schema paths. ($field)", E_USER_DEPRECATED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1817 | 3 |  |             $field = "/properties/$field"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1818 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1819 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1820 | 11 |  |         if (strpos($field, '[]') !== false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1821 | 1 |  |             trigger_error('Field selectors with item selector "[]" must be converted to "/items".', E_USER_DEPRECATED); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1822 | 1 |  |             $field = str_replace('[]', '/items', $field); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1823 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1824 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1825 | 11 |  |         return ltrim($field, '/'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1826 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1827 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1828 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1829 |  |  |      * Lookup a schema based on a schema node. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1830 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1831 |  |  |      * The node could be a schema array, `Schema` object, or a schema reference. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1832 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1833 |  |  |      * @param mixed $schema The schema node to lookup with. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1834 |  |  |      * @param string $schemaPath The current path of the schema. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1835 |  |  |      * @return array Returns an array with two elements: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1836 |  |  |      * - Schema|array|\ArrayAccess The schema that was found. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1837 |  |  |      * - string The path of the schema. This is either the reference or the `$path` parameter for inline schemas. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1838 |  |  |      * @throws RefNotFoundException Throws an exception when a reference could not be found. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1839 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1840 | 210 |  |     private function lookupSchema($schema, string $schemaPath) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1841 | 210 |  |         if ($schema instanceof Schema) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1842 | 6 |  |             return [$schema, $schemaPath]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1843 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1844 | 210 |  |             $lookup = $this->getRefLookup(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1845 | 210 |  |             $visited = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1846 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1847 | 210 |  |             while (!empty($schema['$ref'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1848 | 10 |  |                 $schemaPath = $schema['$ref']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1849 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1850 | 10 |  |                 if (isset($visited[$schemaPath])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1851 | 1 |  |                     throw new RefNotFoundException("Cyclical reference cannot be resolved. ($schemaPath)", 508); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1852 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1853 | 10 |  |                 $visited[$schemaPath] = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1854 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1855 |  |  |                 try { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1856 | 10 |  |                     $schema = call_user_func($lookup, $schemaPath); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1857 | 1 |  |                 } catch (\Exception $ex) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1858 | 1 |  |                     throw new RefNotFoundException($ex->getMessage(), $ex->getCode(), $ex); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1859 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1860 | 9 |  |                 if ($schema === null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1861 | 1 |  |                     throw new RefNotFoundException("Schema reference could not be found. ($schemaPath)"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1862 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1863 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1864 | 207 |  |             return [$schema, $schemaPath]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1865 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1866 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1867 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1868 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1869 |  |  |      * Get the refLookup. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1870 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1871 |  |  |      * @return callable Returns the refLookup. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1872 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1873 | 210 |  |     public function getRefLookup(): callable { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1874 | 210 |  |         return $this->refLookup; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1875 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1876 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1877 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1878 |  |  |      * Set the refLookup. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1879 |  |  |      * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1880 |  |  |      * @param callable $refLookup | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1881 |  |  |      * @return $this | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1882 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1883 | 10 |  |     public function setRefLookup(callable $refLookup) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1884 | 10 |  |         $this->refLookup = $refLookup; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1885 | 10 |  |         return $this; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 1886 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 1887 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 1888 |  |  |  | 
            
                        
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.