PluginProbe
Media Cloud Sync / 1.3.11
Media Cloud Sync v1.3.11
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 1.3.0 All 34 releases
media-cloud-sync / includes / sdk / s3 / Aws / QueryCompatibleInputMiddleware.php

QueryCompatibleInputMiddleware.php in Media Cloud Sync 1.3.11, at includes/sdk/s3/Aws/QueryCompatibleInputMiddleware.php

205 lines 5.8 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;
4
5 use Dudlewebs\WPMCS\s3\Aws\Api\ListShape;
6 use Dudlewebs\WPMCS\s3\Aws\Api\MapShape;
7 use Dudlewebs\WPMCS\s3\Aws\Api\Service;
8 use Dudlewebs\WPMCS\s3\Aws\Api\Shape;
9 use Dudlewebs\WPMCS\s3\Aws\Api\StructureShape;
10 use Closure;
11 /**
12 * Inspects command input values and casts them to their modeled type.
13 * This covers query compatible services which have migrated from query
14 * to JSON wire protocols.
15 *
16 * @internal
17 */
18 class QueryCompatibleInputMiddleware
19 {
20 /** @var callable */
21 private $nextHandler;
22 /** @var Service */
23 private $service;
24 /** @var CommandInterface */
25 private $command;
26 /**
27 * Create a middleware wrapper function.
28 *
29 * @param Service $service
30 * @return Closure
31 */
32 public static function wrap(Service $service) : Closure
33 {
34 return static function (callable $handler) use($service) {
35 return new self($handler, $service);
36 };
37 }
38 public function __construct(callable $nextHandler, Service $service)
39 {
40 $this->service = $service;
41 $this->nextHandler = $nextHandler;
42 }
43 public function __invoke(CommandInterface $cmd)
44 {
45 $this->command = $cmd;
46 $nextHandler = $this->nextHandler;
47 $op = $this->service->getOperation($cmd->getName());
48 $inputMembers = $op->getInput()->getMembers();
49 $input = $cmd->toArray();
50 foreach ($input as $param => $value) {
51 if (isset($inputMembers[$param])) {
52 $shape = $inputMembers[$param];
53 $this->processInput($value, $shape, [$param]);
54 }
55 }
56 return $nextHandler($this->command);
57 }
58 /**
59 * Recurses a given input shape. if a given scalar input does not match its
60 * modeled type, it is cast to its modeled type.
61 *
62 * @param $input
63 * @param $shape
64 * @param array $path
65 *
66 * @return void
67 */
68 private function processInput($input, $shape, array $path) : void
69 {
70 switch ($shape->getType()) {
71 case 'structure':
72 $this->processStructure($input, $shape, $path);
73 break;
74 case 'list':
75 $this->processList($input, $shape, $path);
76 break;
77 case 'map':
78 $this->processMap($input, $shape, $path);
79 break;
80 default:
81 $this->processScalar($input, $shape, $path);
82 }
83 }
84 /**
85 * @param array $input
86 * @param StructureShape $shape
87 * @param array $path
88 *
89 * @return void
90 */
91 private function processStructure(array $input, StructureShape $shape, array $path) : void
92 {
93 foreach ($input as $param => $value) {
94 if ($shape->hasMember($param)) {
95 $memberPath = \array_merge($path, [$param]);
96 $this->processInput($value, $shape->getMember($param), $memberPath);
97 }
98 }
99 }
100 /**
101 * @param array $input
102 * @param ListShape $shape
103 * @param array $path
104 *
105 * @return void
106 */
107 private function processList(array $input, ListShape $shape, array $path) : void
108 {
109 foreach ($input as $param => $value) {
110 $memberPath = \array_merge($path, [$param]);
111 $this->processInput($value, $shape->getMember(), $memberPath);
112 }
113 }
114 /**
115 * @param array $input
116 * @param MapShape $shape
117 * @param array $path
118 *
119 * @return void
120 */
121 private function processMap(array $input, MapShape $shape, array $path) : void
122 {
123 foreach ($input as $param => $value) {
124 $memberPath = \array_merge($path, [$param]);
125 $this->processInput($value, $shape->getValue(), $memberPath);
126 }
127 }
128 /**
129 * @param $input
130 * @param Shape $shape
131 * @param array $path
132 *
133 * @return void
134 */
135 private function processScalar($input, Shape $shape, array $path) : void
136 {
137 $expectedType = $shape->getType();
138 if (!$this->isModeledType($input, $expectedType)) {
139 \trigger_error("The provided type for `" . \implode(' -> ', $path) . "` value was `" . (\gettype($input) === 'double' ? 'float' : \gettype($input)) . "`." . " The modeled type is `{$expectedType}`.", \E_USER_WARNING);
140 $value = $this->castValue($input, $expectedType);
141 $this->changeValueAtPath($path, $value);
142 }
143 }
144 /**
145 * Modifies command in place
146 *
147 * @param array $path
148 * @param $newValue
149 *
150 * @return void
151 */
152 private function changeValueAtPath(array $path, $newValue) : void
153 {
154 $commandRef =& $this->command;
155 foreach ($path as $segment) {
156 if (!isset($commandRef[$segment])) {
157 return;
158 }
159 $commandRef =& $commandRef[$segment];
160 }
161 $commandRef = $newValue;
162 }
163 /**
164 * @param $value
165 * @param $type
166 *
167 * @return bool
168 */
169 private function isModeledType($value, $type) : bool
170 {
171 switch ($type) {
172 case 'string':
173 return \is_string($value);
174 case 'integer':
175 case 'long':
176 return \is_int($value);
177 case 'float':
178 return \is_float($value);
179 default:
180 return \true;
181 }
182 }
183 /**
184 * @param $value
185 * @param $type
186 *
187 * @return float|int|mixed|string
188 */
189 private function castValue($value, $type)
190 {
191 switch ($type) {
192 case 'integer':
193 return (int) $value;
194 case 'long':
195 return $value + 0;
196 case 'float':
197 return (float) $value;
198 case 'string':
199 return (string) $value;
200 default:
201 return $value;
202 }
203 }
204 }
205