These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | /** |
||
6 | * balloon |
||
7 | * |
||
8 | * @copyright Copryright (c) 2012-2019 gyselroth GmbH (https://gyselroth.com) |
||
9 | * @license GPL-3.0 https://opensource.org/licenses/GPL-3.0 |
||
10 | */ |
||
11 | |||
12 | namespace Balloon\App\Api; |
||
13 | |||
14 | use Balloon\App\Api\v2\Collections as ApiCollection; |
||
15 | use Balloon\App\Api\v2\Files as ApiFile; |
||
16 | use Balloon\Filesystem; |
||
17 | use Balloon\Filesystem\Node\Collection; |
||
18 | use Balloon\Filesystem\Node\File; |
||
19 | use Balloon\Filesystem\Node\NodeInterface; |
||
20 | use Closure; |
||
21 | use Generator; |
||
22 | use Micro\Http\ExceptionInterface; |
||
23 | use Micro\Http\Response; |
||
24 | |||
25 | abstract class Controller |
||
26 | { |
||
27 | /** |
||
28 | * Filesystem. |
||
29 | * |
||
30 | * @var Filesystem |
||
31 | */ |
||
32 | protected $fs; |
||
33 | |||
34 | /** |
||
35 | * @apiDefine _getNode |
||
36 | * |
||
37 | * @apiParam (GET Parameter) {string} id Either id or p (path) of a node must be given. |
||
38 | * @apiParam (GET Parameter) {string} p Either id or p (path) of a node must be given. |
||
39 | * @apiError (General Error Response) {number} status Status Code |
||
40 | * @apiError (General Error Response) {object[]} data Error body |
||
41 | * @apiError (General Error Response) {string} data.error Exception |
||
42 | * @apiError (General Error Response) {string} data.message Message |
||
43 | * @apiError (General Error Response) {number} data.code Error code |
||
44 | * |
||
45 | * @apiErrorExample {json} Error-Response (Invalid Parameter): |
||
46 | * HTTP/1.1 400 Bad Request |
||
47 | * { |
||
48 | * "status": 400, |
||
49 | * "data": { |
||
50 | * "error": "Balloon\\Exception\\InvalidArgument", |
||
51 | * "message": "invalid node id specified", |
||
52 | * "code": 0 |
||
53 | * } |
||
54 | * } |
||
55 | * |
||
56 | * @apiErrorExample {json} Error-Response (Insufficient Access): |
||
57 | * HTTP/1.1 403 Forbidden |
||
58 | * { |
||
59 | * "status": 403, |
||
60 | * "data": { |
||
61 | * "error": "Balloon\\Exception\\Forbidden", |
||
62 | * "message": "not allowed to read node 51354d073c58891f058b4580", |
||
63 | * "code": 40 |
||
64 | * } |
||
65 | * } |
||
66 | * |
||
67 | * @apiErrorExample {json} Error-Response (Not found): |
||
68 | * HTTP/1.1 404 Not Found |
||
69 | * { |
||
70 | * "status": 404, |
||
71 | * "data": { |
||
72 | * "error": "Balloon\\Exception\\NotFound", |
||
73 | * "message": "node 51354d073c58891f058b4580 not found", |
||
74 | * "code": 49 |
||
75 | * } |
||
76 | * } |
||
77 | */ |
||
78 | |||
79 | /** |
||
80 | * @apiDefine _multiError |
||
81 | * |
||
82 | * @apiErrorExample {json} Error-Response (Multi node error): |
||
83 | * HTTP/1.1 400 Bad Request |
||
84 | * { |
||
85 | * "status": 400, |
||
86 | * "data": [ |
||
87 | * { |
||
88 | * id: "51354d073c58891f058b4580", |
||
89 | * name: "file.zip", |
||
90 | * error: "Balloon\\Exception\\Conflict", |
||
91 | * message: "node already exists", |
||
92 | * code: 30 |
||
93 | * } |
||
94 | * ] |
||
95 | * } |
||
96 | */ |
||
97 | |||
98 | /** |
||
99 | * @apiDefine _writeAction |
||
100 | * |
||
101 | * @apiErrorExample {json} Error-Response (Conflict): |
||
102 | * HTTP/1.1 400 Bad Request |
||
103 | * { |
||
104 | * "status": 400, |
||
105 | * "data": { |
||
106 | * "error": "Balloon\\Exception\\Conflict", |
||
107 | * "message": "a node called myname does already exists", |
||
108 | * "code": 17 |
||
109 | * } |
||
110 | * } |
||
111 | */ |
||
112 | |||
113 | /** |
||
114 | * @apiDefine _conflictNode |
||
115 | * @apiParam (GET Parameter) {number} [conflict=0] Decides how to handle a conflict if a node with the same name already exists at the destination. |
||
116 | * Possible values are:</br> |
||
117 | * - 0 No action</br> |
||
118 | * - 1 Automatically rename the node</br> |
||
119 | * - 2 Overwrite the destination (merge)</br> |
||
120 | */ |
||
121 | |||
122 | /** |
||
123 | * @apiDefine _getNodes |
||
124 | * |
||
125 | * @apiParam (GET Parameter) {string[]} id Either a single id as string or multiple as an array or a single p (path) as string or multiple paths as array must be given. |
||
126 | * @apiParam (GET Parameter) {string[]} p Either a single id as string or multiple as an array or a single p (path) as string or multiple paths as array must be given. |
||
127 | * @apiError (General Error Response) {number} status Status Code |
||
128 | * @apiError (General Error Response) {object[]} data Error body |
||
129 | * @apiError (General Error Response) {string} data.error Exception |
||
130 | * @apiError (General Error Response) {string} data.message Message |
||
131 | * @apiError (General Error Response) {number} data.code General error messages of type Balloon\\Exception do not usually have an error code |
||
132 | * |
||
133 | * @apiErrorExample {json} Error-Response (Invalid Parameter): |
||
134 | * HTTP/1.1 400 Bad Request |
||
135 | * { |
||
136 | * "status": 400, |
||
137 | * "data": { |
||
138 | * "error": "Balloon\\Exception\\InvalidArgument", |
||
139 | * "message": "invalid node id specified", |
||
140 | * "code": 0 |
||
141 | * } |
||
142 | * } |
||
143 | * |
||
144 | * @apiErrorExample {json} Error-Response (Insufficient Access): |
||
145 | * HTTP/1.1 403 Forbidden |
||
146 | * { |
||
147 | * "status": 403, |
||
148 | * "data": { |
||
149 | * "error": "Balloon\\Exception\\Forbidden", |
||
150 | * "message": "not allowed to read node 51354d073c58891f058b4580", |
||
151 | * "code": 40 |
||
152 | * } |
||
153 | * } |
||
154 | * |
||
155 | * @apiErrorExample {json} Error-Response (Not found): |
||
156 | * HTTP/1.1 404 Not Found |
||
157 | * { |
||
158 | * "status": 404, |
||
159 | * "data": { |
||
160 | * "error": "Balloon\\Exception\\NotFound", |
||
161 | * "message": "node 51354d073c58891f058b4580 not found", |
||
162 | * "code": 49 |
||
163 | * } |
||
164 | * } |
||
165 | */ |
||
166 | |||
167 | /** |
||
168 | * Do bulk operations. |
||
169 | * |
||
170 | * @param array|string $id |
||
171 | * @param array|string $p |
||
172 | */ |
||
173 | protected function bulk($id, $p, Closure $action): Response |
||
174 | { |
||
175 | if (is_array($id) || is_array($p)) { |
||
176 | $body = []; |
||
177 | foreach ($this->_getNodes($id, $p) as $node) { |
||
0 ignored issues
–
show
It seems like
$p defined by parameter $p on line 173 can also be of type array ; however, Balloon\App\Api\Controller::_getNodes() does only seem to accept string|null , maybe add an additional type check?
This check looks at variables that have been passed in as parameters and are passed out again to other methods. If the outgoing method call has stricter type requirements than the method itself, an issue is raised. An additional type check may prevent trouble.
Loading history...
|
|||
178 | try { |
||
179 | $body[(string) $node->getId()] = $action->call($this, $node); |
||
180 | } catch (\Exception $e) { |
||
181 | $body[(string) $node->getId()] = [ |
||
182 | 'code' => $e instanceof ExceptionInterface ? $e->getStatusCode() : 400, |
||
0 ignored issues
–
show
The class
Micro\Http\ExceptionInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed.
Loading history...
|
|||
183 | 'data' => [ |
||
184 | 'error' => get_class($e), |
||
185 | 'message' => $e->getMessage(), |
||
186 | 'code' => $e->getCode(), |
||
187 | ], |
||
188 | ]; |
||
189 | } |
||
190 | } |
||
191 | |||
192 | return (new Response())->setCode(207)->setBody($body); |
||
193 | } |
||
194 | |||
195 | $body = $action->call($this, $this->_getNode($id, $p)); |
||
196 | $response = (new Response())->setCode($body['code']); |
||
197 | |||
198 | if (isset($body['data'])) { |
||
199 | $response->setBody($body['data']); |
||
200 | } |
||
201 | |||
202 | return $response; |
||
203 | } |
||
204 | |||
205 | /** |
||
206 | * Get node. |
||
207 | * |
||
208 | * @param string $id |
||
209 | * @param string $path |
||
210 | * @param string $class Force set node type |
||
211 | * @param bool $multiple Allow $id to be an array |
||
212 | * @param bool $allow_root Allow instance of root collection |
||
213 | * @param bool $deleted How to handle deleted node |
||
214 | */ |
||
215 | protected function _getNode( |
||
216 | ?string $id = null, |
||
217 | ?string $path = null, |
||
218 | ?string $class = null, |
||
219 | bool $multiple = false, |
||
220 | bool $allow_root = false, |
||
221 | int $deleted = 2 |
||
222 | ): NodeInterface { |
||
223 | if (null === $class) { |
||
224 | switch (get_class($this)) { |
||
225 | case ApiFile::class: |
||
226 | $class = File::class; |
||
227 | |||
228 | break; |
||
229 | case ApiCollection::class: |
||
230 | $class = Collection::class; |
||
231 | |||
232 | break; |
||
233 | } |
||
234 | } |
||
235 | |||
236 | return $this->fs->getNode($id, $path, $class, $multiple, $allow_root, $deleted); |
||
237 | } |
||
238 | |||
239 | /** |
||
240 | * Get nodes. |
||
241 | * |
||
242 | * @param string $id |
||
243 | * @param string $path |
||
244 | * @param string $class Force set node type |
||
245 | * @param bool $deleted How to handle deleted node |
||
246 | */ |
||
247 | protected function _getNodes( |
||
248 | $id = null, |
||
249 | $path = null, |
||
250 | ?string $class = null, |
||
251 | int $deleted = 2 |
||
252 | ): Generator { |
||
253 | if (null === $class) { |
||
254 | switch (get_class($this)) { |
||
255 | case ApiFile::class: |
||
256 | $class = File::class; |
||
257 | |||
258 | break; |
||
259 | case ApiCollection::class: |
||
260 | $class = Collection::class; |
||
261 | |||
262 | break; |
||
263 | } |
||
264 | } |
||
265 | |||
266 | return $this->fs->getNodes($id, $path, $class, $deleted); |
||
267 | } |
||
268 | } |
||
269 |
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.