PluginProbe
Media Cloud Sync / 1.4.1
Media Cloud Sync v1.4.1
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.4.1, at includes/sdk/s3/Aws/Api/Validator.php

239 lines 9.0 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 \array_is_list($arr) || Aws\is_associative($arr);
177 }
178 private function checkCanString($value)
179 {
180 static $valid = ['string' => \true, 'integer' => \true, 'double' => \true, 'NULL' => \true];
181 $type = \gettype($value);
182 return isset($valid[$type]) || $type == 'object' && \method_exists($value, '__toString');
183 }
184 private function checkAssociativeArray($value)
185 {
186 $isAssociative = \false;
187 if (\is_array($value)) {
188 $expectedIndex = 0;
189 $key = \key($value);
190 do {
191 $isAssociative = $key !== $expectedIndex++;
192 \next($value);
193 $key = \key($value);
194 } while (!$isAssociative && null !== $key);
195 }
196 if (!$isAssociative) {
197 $this->addError('must be an associative array. Found ' . Aws\describe_type($value));
198 return \false;
199 }
200 return \true;
201 }
202 private function checkDocumentType($value)
203 {
204 if (\is_array($value)) {
205 $typeOfFirstKey = \gettype(\key($value));
206 foreach ($value as $key => $val) {
207 if (!$this->checkDocumentType($val) || \gettype($key) != $typeOfFirstKey) {
208 return \false;
209 }
210 }
211 return $this->checkArray($value);
212 }
213 return \is_null($value) || \is_numeric($value) || \is_string($value) || \is_bool($value);
214 }
215 private function checkUnion($value)
216 {
217 if (\is_array($value)) {
218 $nonNullCount = 0;
219 foreach ($value as $key => $val) {
220 if (!\is_null($val) && !(\strpos($key, "@") === 0)) {
221 $nonNullCount++;
222 }
223 }
224 return $nonNullCount == 1;
225 }
226 return !\is_null($value);
227 }
228 private function addError($message)
229 {
230 $this->errors[] = \implode('', \array_map(function ($s) {
231 return "[{$s}]";
232 }, $this->path)) . ' ' . $message;
233 }
234 private function canJsonEncode($data)
235 {
236 return !\is_resource($data);
237 }
238 }
239