PluginProbe
Media Cloud Sync / 1.2.0
Media Cloud Sync v1.2.0
1.4.1 1.4.0 1.3.12 1.3.11 1.3.10 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.2.0 1.2.10 1.2.11 1.2.12 1.2.13 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 All 35 releases
media-cloud-sync / includes / sdk / s3 / Aws / Api / Validator.php

Validator.php in Media Cloud Sync 1.2.0, at includes/sdk/s3/Aws/Api/Validator.php

247 lines 9.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Dudlewebs\WPMCS\s3\Aws\Api;
4
5 use Dudlewebs\WPMCS\s3\Aws;
6 /**
7 * Validates a schema against a hash of input.
8 */
9 class Validator
10 {
11 private $path = [];
12 private $errors = [];
13 private $constraints = [];
14 private static $defaultConstraints = ['required' => \true, 'min' => \true, 'max' => \false, 'pattern' => \false];
15 /**
16 * @param array $constraints Associative array of constraints to enforce.
17 * Accepts the following keys: "required", "min",
18 * "max", and "pattern". If a key is not
19 * provided, the constraint will assume false.
20 */
21 public function __construct(array $constraints = null)
22 {
23 static $assumedFalseValues = ['required' => \false, 'min' => \false, 'max' => \false, 'pattern' => \false];
24 $this->constraints = empty($constraints) ? self::$defaultConstraints : $constraints + $assumedFalseValues;
25 }
26 /**
27 * Validates the given input against the schema.
28 *
29 * @param string $name Operation name
30 * @param Shape $shape Shape to validate
31 * @param array $input Input to validate
32 *
33 * @throws \InvalidArgumentException if the input is invalid.
34 */
35 public function validate($name, Shape $shape, array $input)
36 {
37 $this->dispatch($shape, $input);
38 if ($this->errors) {
39 $message = \sprintf("Found %d error%s while validating the input provided for the " . "%s operation:\n%s", \count($this->errors), \count($this->errors) > 1 ? 's' : '', $name, \implode("\n", $this->errors));
40 $this->errors = [];
41 throw new \InvalidArgumentException($message);
42 }
43 }
44 private function dispatch(Shape $shape, $value)
45 {
46 static $methods = ['structure' => 'check_structure', 'list' => 'check_list', 'map' => 'check_map', 'blob' => 'check_blob', 'boolean' => 'check_boolean', 'integer' => 'check_numeric', 'float' => 'check_numeric', 'long' => 'check_numeric', 'string' => 'check_string', 'byte' => 'check_string', 'char' => 'check_string'];
47 $type = $shape->getType();
48 if (isset($methods[$type])) {
49 $this->{$methods[$type]}($shape, $value);
50 }
51 }
52 private function check_structure(StructureShape $shape, $value)
53 {
54 $isDocument = isset($shape['document']) && $shape['document'];
55 $isUnion = isset($shape['union']) && $shape['union'];
56 if ($isDocument) {
57 if (!$this->checkDocumentType($value)) {
58 $this->addError("is not a valid document type");
59 return;
60 }
61 } elseif ($isUnion) {
62 if (!$this->checkUnion($value)) {
63 $this->addError("is a union type and must have exactly one non null value");
64 return;
65 }
66 } elseif (!$this->checkAssociativeArray($value)) {
67 return;
68 }
69 if ($this->constraints['required'] && $shape['required']) {
70 foreach ($shape['required'] as $req) {
71 if (!isset($value[$req])) {
72 $this->path[] = $req;
73 $this->addError('is missing and is a required parameter');
74 \array_pop($this->path);
75 }
76 }
77 }
78 if (!$isDocument) {
79 foreach ($value as $name => $v) {
80 if ($shape->hasMember($name)) {
81 $this->path[] = $name;
82 $this->dispatch($shape->getMember($name), isset($value[$name]) ? $value[$name] : null);
83 \array_pop($this->path);
84 }
85 }
86 }
87 }
88 private function check_list(ListShape $shape, $value)
89 {
90 if (!\is_array($value)) {
91 $this->addError('must be an array. Found ' . Aws\describe_type($value));
92 return;
93 }
94 $this->validateRange($shape, \count($value), "list element count");
95 $items = $shape->getMember();
96 foreach ($value as $index => $v) {
97 $this->path[] = $index;
98 $this->dispatch($items, $v);
99 \array_pop($this->path);
100 }
101 }
102 private function check_map(MapShape $shape, $value)
103 {
104 if (!$this->checkAssociativeArray($value)) {
105 return;
106 }
107 $values = $shape->getValue();
108 foreach ($value as $key => $v) {
109 $this->path[] = $key;
110 $this->dispatch($values, $v);
111 \array_pop($this->path);
112 }
113 }
114 private function check_blob(Shape $shape, $value)
115 {
116 static $valid = ['string' => \true, 'integer' => \true, 'double' => \true, 'resource' => \true];
117 $type = \gettype($value);
118 if (!isset($valid[$type])) {
119 if ($type != 'object' || !\method_exists($value, '__toString')) {
120 $this->addError('must be an fopen resource, a ' . 'Dudlewebs\\WPMCS\\s3\\GuzzleHttp\\Stream\\StreamInterface object, or something ' . 'that can be cast to a string. Found ' . Aws\describe_type($value));
121 }
122 }
123 }
124 private function check_numeric(Shape $shape, $value)
125 {
126 if (!\is_numeric($value)) {
127 $this->addError('must be numeric. Found ' . Aws\describe_type($value));
128 return;
129 }
130 $this->validateRange($shape, $value, "numeric value");
131 }
132 private function check_boolean(Shape $shape, $value)
133 {
134 if (!\is_bool($value)) {
135 $this->addError('must be a boolean. Found ' . Aws\describe_type($value));
136 }
137 }
138 private function check_string(Shape $shape, $value)
139 {
140 if ($shape['jsonvalue']) {
141 if (!self::canJsonEncode($value)) {
142 $this->addError('must be a value encodable with \'json_encode\'.' . ' Found ' . Aws\describe_type($value));
143 }
144 return;
145 }
146 if (!$this->checkCanString($value)) {
147 $this->addError('must be a string or an object that implements ' . '__toString(). Found ' . Aws\describe_type($value));
148 return;
149 }
150 $value = isset($value) ? $value : '';
151 $this->validateRange($shape, \strlen($value), "string length");
152 if ($this->constraints['pattern']) {
153 $pattern = $shape['pattern'];
154 if ($pattern && !\preg_match("/{$pattern}/", $value)) {
155 $this->addError("Pattern /{$pattern}/ failed to match '{$value}'");
156 }
157 }
158 }
159 private function validateRange(Shape $shape, $length, $descriptor)
160 {
161 if ($this->constraints['min']) {
162 $min = $shape['min'];
163 if ($min && $length < $min) {
164 $this->addError("expected {$descriptor} to be >= {$min}, but " . "found {$descriptor} of {$length}");
165 }
166 }
167 if ($this->constraints['max']) {
168 $max = $shape['max'];
169 if ($max && $length > $max) {
170 $this->addError("expected {$descriptor} to be <= {$max}, but " . "found {$descriptor} of {$length}");
171 }
172 }
173 }
174 private function checkArray($arr)
175 {
176 return $this->isIndexed($arr) || $this->isAssociative($arr);
177 }
178 private function isAssociative($arr)
179 {
180 return \count(\array_filter(\array_keys($arr), "is_string")) == \count($arr);
181 }
182 private function isIndexed(array $arr)
183 {
184 return $arr == \array_values($arr);
185 }
186 private function checkCanString($value)
187 {
188 static $valid = ['string' => \true, 'integer' => \true, 'double' => \true, 'NULL' => \true];
189 $type = \gettype($value);
190 return isset($valid[$type]) || $type == 'object' && \method_exists($value, '__toString');
191 }
192 private function checkAssociativeArray($value)
193 {
194 $isAssociative = \false;
195 if (\is_array($value)) {
196 $expectedIndex = 0;
197 $key = \key($value);
198 do {
199 $isAssociative = $key !== $expectedIndex++;
200 \next($value);
201 $key = \key($value);
202 } while (!$isAssociative && null !== $key);
203 }
204 if (!$isAssociative) {
205 $this->addError('must be an associative array. Found ' . Aws\describe_type($value));
206 return \false;
207 }
208 return \true;
209 }
210 private function checkDocumentType($value)
211 {
212 if (\is_array($value)) {
213 $typeOfFirstKey = \gettype(\key($value));
214 foreach ($value as $key => $val) {
215 if (!$this->checkDocumentType($val) || \gettype($key) != $typeOfFirstKey) {
216 return \false;
217 }
218 }
219 return $this->checkArray($value);
220 }
221 return \is_null($value) || \is_numeric($value) || \is_string($value) || \is_bool($value);
222 }
223 private function checkUnion($value)
224 {
225 if (\is_array($value)) {
226 $nonNullCount = 0;
227 foreach ($value as $key => $val) {
228 if (!\is_null($val) && !(\strpos($key, "@") === 0)) {
229 $nonNullCount++;
230 }
231 }
232 return $nonNullCount == 1;
233 }
234 return !\is_null($value);
235 }
236 private function addError($message)
237 {
238 $this->errors[] = \implode('', \array_map(function ($s) {
239 return "[{$s}]";
240 }, $this->path)) . ' ' . $message;
241 }
242 private function canJsonEncode($data)
243 {
244 return !\is_resource($data);
245 }
246 }
247