GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 1e9f36...59f2d0 )
by cao
10:57 queued 06:00
created

Swagger::getArraySchema()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 22
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4.0466

Importance

Changes 0
Metric Value
cc 4
eloc 18
nc 4
nop 5
dl 0
loc 22
ccs 12
cts 14
cp 0.8571
crap 4.0466
rs 8.9197
c 0
b 0
f 0
1
<?php
2
namespace PhpBoot\Docgen\Swagger;
3
4
use PhpBoot\Application;
5
use PhpBoot\Controller\ControllerContainer;
6
use PhpBoot\Controller\ExceptionRenderer;
7
use PhpBoot\Controller\Route;
8
use PhpBoot\Docgen\Swagger\Schemas\ArraySchemaObject;
9
use PhpBoot\Docgen\Swagger\Schemas\BodyParameterObject;
10
use PhpBoot\Docgen\Swagger\Schemas\OperationObject;
11
use PhpBoot\Docgen\Swagger\Schemas\OtherParameterObject;
12
use PhpBoot\Docgen\Swagger\Schemas\PrimitiveSchemaObject;
13
use PhpBoot\Docgen\Swagger\Schemas\RefSchemaObject;
14
use PhpBoot\Docgen\Swagger\Schemas\ResponseObject;
15
use PhpBoot\Docgen\Swagger\Schemas\SimpleModelSchemaObject;
16
use PhpBoot\Docgen\Swagger\Schemas\SwaggerObject;
17
use PhpBoot\Docgen\Swagger\Schemas\TagObject;
18
use PhpBoot\Entity\ArrayContainer;
19
use PhpBoot\Entity\EntityContainer;
20
use PhpBoot\Entity\ScalarTypeContainer;
21
use PhpBoot\Entity\TypeContainerInterface;
22
use PhpBoot\Metas\ParamMeta;
23
use PhpBoot\Metas\ReturnMeta;
24
use PhpBoot\Utils\ArrayHelper;
25
use PhpBoot\Validator\Validator;
26
use Symfony\Component\HttpKernel\Exception\HttpException;
27
28
class Swagger extends SwaggerObject
29
{
30
31
    /**
32
     * @param Application $app
33
     * @param ControllerContainer[] $controllers
34
     */
35 1
    public function appendControllers(Application $app, $controllers)
36
    {
37 1
        foreach ($controllers as $controller) {
38 1
            $this->appendController($app, $controller);
39 1
        }
40 1
    }
41
42
    /**
43
     * @param Application $app
44
     * @param ControllerContainer $controller
45
     */
46 1
    public function appendController(Application $app, ControllerContainer $controller)
47
    {
48
        //tags
49 1
        $tag = new TagObject();
50 1
        $tag->name = $controller->getSummary();
51 1
        $tag->description = $controller->getDescription();
52 1
        $this->tags[] = $tag;
53
54 1
        foreach ($controller->getRoutes() as $action => $route) {
55 1
            $op = new OperationObject();
56 1
            $op->tags = [$controller->getSummary()];
57 1
            $op->summary = $route->getSummary();
58 1
            $op->description = $route->getDescription();
59
60 1
            $op->parameters = $this->getParamsSchema($app, $controller, $action, $route);
61 1
            if($this->hasFileParam($route)){
62 1
                $op->consumes = ['multipart/form-data'];
63 1
            }
64
65 1
            if ($returnSchema = $this->getReturnSchema($app, $controller, $action, $route)) {
66 1
                $op->responses['200'] = $returnSchema;
67 1
            }
68 1
            $op->responses += $this->getExceptionsSchema($app, $controller, $action, $route);
69 1
            $uri = $app->getFullUri($route->getUri());
70 1
            if (!isset($this->paths[$uri])) {
71 1
                $this->paths[$uri] = [];
72 1
            }
73 1
            $method = strtolower($route->getMethod());
74 1
            $this->paths[$uri][$method] = $op;
75 1
        }
76 1
    }
77
78
    /**
79
     * @return string
80
     */
81
    public function toJson()
82
    {
83
        $json = $this->toArray();
84
        return json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
85
    }
86
87
    /**
88
     * @return array
89
     */
90 1
    public function toArray()
91
    {
92 1
        return self::objectToArray($this);
93
    }
94
95
    /**
96
     * @param $object
97
     * @return array
98
     */
99 1
    static public function objectToArray($object)
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
100
    {
101 1
        if (is_object($object)) {
102 1
            $object = get_object_vars($object);
103 1
        }
104 1
        $res = [];
105 1
        foreach ($object as $k => $v) {
106 1
            if ($v === null) {
107 1
                continue;
108
            }
109 1
            if (is_array($v) || is_object($v)) {
110 1
                $res[$k] = self::objectToArray($v);
111 1
            } else {
112 1
                $res[$k] = $v;
113
            }
114 1
        }
115 1
        return $res;
116
    }
117
118
    /**
119
     * @param Application $app
120
     * @param ControllerContainer $controller
121
     * @param $action
122
     * @param Route $route
123
     * @return array
124
     */
125 1
    public function getExceptionsSchema(Application $app,
126
                                        ControllerContainer $controller,
0 ignored issues
show
Unused Code introduced by
The parameter $controller is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
127
                                        $action,
0 ignored issues
show
Unused Code introduced by
The parameter $action is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
128
                                        Route $route)
129
    {
130 1
        $handler = $route->getExceptionHandler();
131 1
        if (!$handler) {
132
            return [];
133
        }
134 1
        $schemas = [];
135 1
        foreach ($handler->getExceptions() as $exception) {
136 1
            list($name, $desc) = $exception;
137
138 1
            $ins = null;
139
            try{
140 1
                $ins = $app->make($name);
141 1
            }catch (\Exception $e){
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
142
143
            }
144
145
            //TODO status 重复怎么办
146 1
            if ($ins instanceof HttpExceptio) {
0 ignored issues
show
Bug introduced by
The class PhpBoot\Docgen\Swagger\HttpExceptio 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 dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
147
                $status = $ins->getStatusCode();
148
            } else {
149 1
                $status = 500;
150
            }
151 1
            if (isset($schemas[$status])) {
152
                //$this->warnings[] = "status response $status has been used for $name, $desc";
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
153 1
                $res = $schemas[$status];
154 1
            } else {
155 1
                $res = new ResponseObject();
156
            }
157 1
            $shortName = self::getShortClassName($name);
158 1
            $desc = "$shortName: $desc";
159 1
            $res->description = self::implode("\n", [$res->description, $desc]);
160 1
            if($ins){
161 1
                $error = $app->get(ExceptionRenderer::class)->render($ins)->getContent();
162 1
                if($error){
163
                    $res->examples = [$shortName => $error];
164
                }
165 1
            }
166
            //$res->schema = new RefSchemaObject("#/definitions/$name");
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
167 1
            $schemas[$status] = $res;
168
169 1
        }
170 1
        return $schemas;
171
    }
172
173
    /**
174
     * @param Application $app
175
     * @param ControllerContainer $controller
176
     * @param $action
177
     * @param Route $route
178
     * @return null|ResponseObject
179
     */
180 1
    public function getReturnSchema(Application $app,
181
                                    ControllerContainer $controller,
182
                                    $action,
183
                                    Route $route)
184
    {
185 1
        $response = $route->getResponseHandler();
186 1
        if (!$response) {
187
            return null;
188
        }
189 1
        $mappings = $response->getMappings();
190 1
        $output = [];
191 1
        $schema = new ResponseObject();
192 1
        foreach ($mappings as $key => $map) {
193 1 View Code Duplication
            if (substr($key, 0, strlen('response.')) == 'response.') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
194 1
                $key = substr($key, strlen('response.'));
195 1
            }
196 1
            ArrayHelper::set($output, $key, $map);
197 1
        }
198
        //TODO 支持 header、status 等
199 1
        if (isset($output['content'])) {
200 1
            $content = $output['content'];
201 1
            if ($content instanceof ReturnMeta) {
202 1
                $schema->description = $content->description;
203 1
                $schema->schema = $this->getAnySchema($app, $controller, $action, $route, $content->container);
0 ignored issues
show
Bug introduced by
It seems like $content->container can be null; however, getAnySchema() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
204 1
            } elseif (is_array($content)) {
205 1
                $tmpSchema = $this->makeTempSchema($app, $controller, $action, $route, $content, 'Res');
206 1
                $schema->schema = $tmpSchema;
207
208 1
            }
209
            //$schema->examples = ['application/json'=>$this->makeExample($content)];
0 ignored issues
show
Unused Code Comprehensibility introduced by
71% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
210 1
            return $schema;
211
        }
212
        return null;
213
    }
214
215
    /**
216
     * @param $content
217
     */
218
    public function makeExample($content)
219
    {
220
        if ($content instanceof ReturnMeta || $content instanceof ParamMeta) {
221
            return $this->makeExample($content->container);
222
        }elseif ($content instanceof TypeContainerInterface){
223
            return $content->makeExample();
224
        }elseif(is_array($content)) {
225
            $res = [];
226
            foreach ($content as $k => $v) {
227
                $res[$k] = $this->makeExample($v);
228
            }
229
            return $res;
230
        }
231
        return null;
232
    }
233
    /**
234
     * @param Application $app
235
     * @param ControllerContainer $controller
236
     * @param $action
237
     * @param Route $route
238
     * @param array $arr
239
     * @param string $suffix
240
     * @return RefSchemaObject
241
     */
242 1
    public function makeTempSchema(Application $app,
243
                                   ControllerContainer $controller,
244
                                   $action,
245
                                   Route $route,
246
                                   array $arr, $suffix)
247
    {
248 1
        $className = self::getShortClassName($controller->getClassName());
249 1
        $name = $className . ucfirst($action) . $suffix;
250
251 1
        $schema = new SimpleModelSchemaObject();
252
253 1
        foreach ($arr as $k => $v) {
254 1
            if (is_array($v)) {
255 1
                $schema->properties[$k] = $this->makeTempSchema($app, $controller, $action, $route, $v, $suffix);
256 1
            } elseif ($v instanceof ReturnMeta) {
257 1
                $sub = $this->getAnySchema($app, $controller, $action, $route, $v->container);
0 ignored issues
show
Bug introduced by
It seems like $v->container can be null; however, getAnySchema() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
258 1
                if($sub){
259 1
                    $sub->description = $v->description;
260 1
                }
261 1
                $schema->properties[$k] = $sub;
262 1
            } elseif ($v instanceof ParamMeta) {
263 1 View Code Duplication
                if ($v->container instanceof ArrayContainer) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
264 1
                    $sub = $this->getArraySchema($app, $controller, $action, $route, $v->container);
265
                    //TODO array for validation
266 1
                } elseif ($v->container instanceof EntityContainer) {
267 1
                    $sub = $this->getRefSchema($app, $controller, $action, $route, $v->container);
268
                    //TODO array for validation
269 1
                } else {
270 1
                    $sub = new PrimitiveSchemaObject();
271 1
                    $sub->type = self::mapType($v->type);
272 1
                    self::mapValidation($v->validation, $sub);
273 1
                    unset($sub->required);
274
                }
275 1
                if($sub){
276 1
                    $sub->description = $v->description;
277 1
                    $sub->default = $v->default;
278 1
                }
279 1
                if (!$v->isOptional) {
280 1
                    $schema->required[] = $k;
281 1
                }
282 1
                $schema->properties[$k] = $sub;
283 1
            } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
284
                //TODO how to do?
285
            }
286 1
        }
287 1
        $unused = $name;
288 1
        $tempId = 0;
289 1
        while (isset($this->definitions[$unused])) {
290 1
            $unused = $name . $tempId;
291 1
            $tempId++;
292 1
        }
293 1
        $this->definitions[$unused] = $schema;
294 1
        return new RefSchemaObject("#/definitions/$unused");
295
    }
296
297
    /**
298
     * @param Application $app
299
     * @param ControllerContainer $controller
300
     * @param $action
301
     * @param Route $route
302
     * @param EntityContainer $container
303
     * @return RefSchemaObject
304
     */
305 1
    public function getRefSchema(Application $app,
306
                                 ControllerContainer $controller,
307
                                 $action,
308
                                 Route $route,
309
                                 EntityContainer $container)
310
    {
311 1
        $name = $container->getClassName();
312 1
        if (!isset($this->definitions[$name])) {
313 1
            $this->definitions[$name] = $this->getObjectSchema($app, $controller, $action, $route, $container);
314 1
        }
315 1
        return new RefSchemaObject("#/definitions/$name");
316
    }
317
318 1
    public function getParamsSchema(Application $app,
319
                                    ControllerContainer $controller,
320
                                    $action,
321
                                    Route $route)
322
    {
323 1
        $params = $route->getRequestHandler()->getParamMetas();
324 1
        $parameters = [];
325 1
        $body = [];
326 1
        $in = 'query';
327
328 1
        $bodyType = 'body'; // 当有文件上传时, 必须是formData方式
329 1
        if($this->hasFileParam($route)){
330 1
            $bodyType = 'formData';
331 1
        }
332
333 1
        foreach ($params as $name => $param) {
334 1
            $isFile = false;
335 1
            if ($param->isPassedByReference) {
336 1
                continue;
337
            }
338 1
            if ($param->source == 'request.request') {
339
                $in = $bodyType;
340
                $name = '';
341 1 View Code Duplication
            } elseif (strpos($param->source, 'request.request.') === 0
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
342 1
                || $param->source == 'request.request'
343 1
            ) {
344 1
                $in = $bodyType;
345 1
                $name = substr($param->source, strlen('request.request.'));
346 1
            } elseif (strpos($param->source, 'request.query.') === 0) {
347 1
                $in = 'query';
348 1
                $name = substr($param->source, strlen('request.query.'));
349 1
            } elseif (strpos($param->source, 'request.cookies.') === 0) {
350 1
                $in = 'cookie';
351 1
                $name = substr($param->source, strlen('request.cookies.'));
352 1
            } elseif (strpos($param->source, 'request.headers.') === 0) {
353 1
                $in = 'header';
354 1
                $name = substr($param->source, strlen('request.headers.'));
355 1 View Code Duplication
            } elseif (strpos($param->source, 'request.files.') === 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
356 1
                $isFile = true;
357 1
                $in = $bodyType;
358 1
                $name = substr($param->source, strlen('request.files.'));
359 1
            } elseif (strpos($param->source, 'request.') === 0) {
360 1
                $name = substr($param->source, strlen('request.'));
361 1
                if ($route->hasPathParam($param->name)) {
362 1
                    $in = 'path';
363 1
                } elseif ($route->getMethod() == 'POST'
364 1
                    || $route->getMethod() == 'PUT'
365 1
                    || $route->getMethod() == 'PATCH'
366 1
                ) {
367 1
                    $in = $bodyType;
368 1
                } else {
369 1
                    $in = 'query';
370
                }
371 1
            }
372 1
            if ($in != 'body') {
373 1 View Code Duplication
                if ($param->container instanceof ArrayContainer) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
374 1
                    $paramSchema = $this->getArraySchema($app, $controller, $action, $route, $param->container);
375
                    //TODO array for validation
376 1
                } elseif ($param->container instanceof EntityContainer) {
377 1
                    $paramSchema = $this->getRefSchema($app, $controller, $action, $route, $param->container);
378
                    //TODO array for validation
379 1
                } else {
380 1
                    $paramSchema = new PrimitiveSchemaObject();
381 1
                    if($isFile){
382 1
                        $paramSchema->type = 'file';
383 1
                    }else{
384 1
                        $paramSchema->type = self::mapType($param->type);
385 1
                        self::mapValidation($param->validation, $paramSchema);
386
                    }
387
388
                }
389 1
                $paramSchema->in = $in;
390 1
                $paramSchema->name = $name;
391 1
                $paramSchema->description = $param->description;
392 1
                $paramSchema->default = $param->default;
393 1
                $paramSchema->required = !$param->isOptional;
394 1
                $parameters[] = $paramSchema;
395 1
            } else {
396 1
                if (!$name) {
397
                    $body = $param;
398
                } else {
399 1
                    ArrayHelper::set($body, $name, $param);
0 ignored issues
show
Bug introduced by
It seems like $body defined by $param on line 397 can also be of type object<PhpBoot\Metas\ParamMeta>; however, PhpBoot\Utils\ArrayHelper::set() does only seem to accept array|object<ArrayAccess>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
400
                }
401
402
            }
403 1
        }
404 1
        if ($body && $bodyType == 'body') {
405
406 1
            $paramSchema = new BodyParameterObject();
407 1
            $paramSchema->name = 'body';
408 1
            $paramSchema->in = 'body';
409 1
            if (is_array($body)) {
410 1
                $paramSchema->schema = $this->makeTempSchema($app, $controller, $action, $route, $body, 'Req');
411 1
            } else {
412
                $paramSchema->schema = $this->getAnySchema($app, $controller, $action, $route, $body->container);
413
            }
414
415 1
            $parameters[] = $paramSchema;
416 1
        }
417
418 1
        return $parameters;
419
    }
420
421
    /**
422
     * @param Application $app
423
     * @param ControllerContainer $controller
424
     * @param $action
425
     * @param Route $route
426
     * @param TypeContainerInterface $container
427
     * @return ArraySchemaObject|PrimitiveSchemaObject|RefSchemaObject
428
     */
429 1
    public function getAnySchema(Application $app, ControllerContainer $controller, $action, Route $route, $container)
430
    {
431 1
        if ($container instanceof EntityContainer) {
432 1
            $schema = $this->getRefSchema($app, $controller, $action, $route, $container);
433 1
        } elseif ($container instanceof ArrayContainer) {
434 1
            $schema = $this->getArraySchema($app, $controller, $action, $route, $container);
435 1
        } elseif ($container instanceof ScalarTypeContainer) {
436 1
            $schema = new PrimitiveSchemaObject();
437 1
            $schema->type = self::mapType($container->getType());
438 1
        } elseif($container == null){
439
            $schema = null ;//new PrimitiveSchemaObject();
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
440
            //$schema->type = null;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
441
        }else {
442 1
            $schema = new PrimitiveSchemaObject();
443
            //$schema->type = 'mixed';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
444
        }
445 1
        return $schema;
446
    }
447
448
    /**
449
     * @param Application $app
450
     * @param ControllerContainer $controller
451
     * @param $action
452
     * @param Route $route
453
     * @param ArrayContainer $container
454
     * @return ArraySchemaObject
455
     */
456 1
    public function getArraySchema(Application $app,
457
                                   ControllerContainer $controller,
458
                                   $action,
459
                                   Route $route,
460
                                   ArrayContainer $container)
461
    {
462 1
        $schema = new ArraySchemaObject();
463 1
        $itemContainer = $container->getContainer();
464 1
        if ($itemContainer instanceof EntityContainer) {
465 1
            $itemSchema = $this->getRefSchema($app, $controller, $action, $route, $itemContainer);
466 1
        } elseif ($itemContainer instanceof ArrayContainer) {
467
            $itemSchema = $this->getArraySchema($app, $controller, $action, $route, $itemContainer);
468 1
        } elseif ($itemContainer instanceof ScalarTypeContainer) {
469 1
            $itemSchema = new PrimitiveSchemaObject();
470 1
            $itemSchema->type = self::mapType($itemContainer->getType());
471 1
        } else {
472
            $itemSchema = new PrimitiveSchemaObject();
473
            //$itemSchema->type = 'mixed';
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
474
        }
475 1
        $schema->items = $itemSchema;
476 1
        return $schema;
477
    }
478
479 1
    public function getObjectSchema(Application $app,
480
                                    ControllerContainer $controller,
481
                                    $action,
482
                                    Route $route,
483
                                    EntityContainer $container)
484
    {
485 1
        $schema = new SimpleModelSchemaObject();
486 1
        $schema->description = self::implode("\n", [$container->getSummary(), $container->getDescription()]);
487
488 1
        foreach ($container->getProperties() as $property) {
489
490 1
            if (!$property->isOptional) {
491 1
                $schema->required[] = $property->name;
492 1
            }
493 1
            if ($property->container instanceof EntityContainer) {
494 1
                $propertySchema = $this->getRefSchema($app, $controller, $action, $route, $property->container);
495 1
            } elseif ($property->container instanceof ArrayContainer) {
496 1
                $propertySchema = $this->getArraySchema($app, $controller, $action, $route, $property->container);
497 1
            } else {
498 1
                $propertySchema = new PrimitiveSchemaObject();
499 1
                $propertySchema->type = self::mapType($property->type);
500 1
                $propertySchema->description = self::implode("\n", [$property->summary, $property->description]);
501 1
                self::mapValidation($property->validation, $propertySchema);
0 ignored issues
show
Bug introduced by
It seems like $property->validation can also be of type array; however, PhpBoot\Docgen\Swagger\Swagger::mapValidation() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
502 1
                unset($propertySchema->required);
503
            }
504 1
            $schema->properties[$property->name] = $propertySchema;
505 1
        }
506
507 1
        return $schema;
508
    }
509
510 1
    public function hasFileParam(Route $route)
511
    {
512 1
        $params = $route->getRequestHandler()->getParamMetas();
513 1
        foreach ($params as $name => $param) {
514 1
            if(strpos($param->source, 'request.files.')===0){
515 1
                return true;
516
            }
517 1
        }
518 1
        return false;
519
    }
520
    /**
521
     * @param string $v
522
     * @param PrimitiveSchemaObject $schemaObject
523
     * @return PrimitiveSchemaObject
524
     */
525 1
    static public function mapValidation($v, PrimitiveSchemaObject $schemaObject)
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
526
    {
527 1
        if(!$v){
528 1
            return $schemaObject;
529
        }
530 1
        $rules = explode('|', $v);
531 1
        foreach ($rules as $r) {
532 1
            $params = explode(':', trim($r));
533 1
            $rule = $params[0];
534 1
            $params = isset($params[1]) ? explode(',', $params[1]) : [];
535
536 1
            if ($rule == 'required') {
537
                $schemaObject->required = true;
538 1
            } elseif ($rule == 'in') {
539
                $schemaObject->enum = $params;
540 1
            } elseif ($rule == 'lengthBetween' && isset($params[0]) && isset($params[1])) {
541
                $schemaObject->minLength = intval($params[0]);
542
                $schemaObject->maxLength = intval($params[1]);
543 1
            } elseif ($rule == 'lengthMin'&& isset($params[0])) {
544
                $schemaObject->minLength = intval($params[0]);
545 1
            } elseif ($rule == 'lengthMax'&& isset($params[0])) {
546
                $schemaObject->maxLength = intval($params[0]);
547 1
            } elseif ($rule == 'min'&& isset($params[0])) {
548 1
                $schemaObject->minimum = floatval($params[0]);
0 ignored issues
show
Documentation Bug introduced by
The property $minimum was declared of type integer, but floatval($params[0]) is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
549 1
            } elseif ($rule == 'max'&& isset($params[0])) {
550 1
                $schemaObject->maximum = floatval($params[0]);
0 ignored issues
show
Documentation Bug introduced by
The property $maximum was declared of type integer, but floatval($params[0]) is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
551 1
            } elseif ($rule == 'regex'&& isset($params[0])) {
552
                $schemaObject->pattern = $params[0];
553
            } elseif ($rule == 'optional') {
554
                $schemaObject->required = false;
555
            }
556 1
        }
557 1
        return $schemaObject;
558
    }
559
560
    /**
561
     * @param string $type
562
     * @return string
563
     */
564 1
    static public function mapType($type)
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
565
    {
566
        //TODO 如何处理 file、mixed 类型
567
        $map = [
568 1
            'int' => 'integer',
569 1
            'bool' => 'boolean',
570 1
            'float' => 'number',
571 1
            'mixed' => null,
572 1
        ];
573 1
        if (array_key_exists($type, $map)) {
574 1
            return $map[$type];
575
        }
576 1
        return $type;
577
    }
578
579
    /**
580
     * @param $className
581
     * @return string
582
     */
583 1
    static public function getShortClassName($className)
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
584
    {
585 1
        $className = explode('\\', $className);
586 1
        $className = $className[count($className) - 1];
587 1
        return $className;
588
    }
589
590
    static public function implode($glue , array $pieces )
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
591
    {
592
        $pieces = array_filter($pieces, function($i){return trim($i) !== '';});
593 1
        return implode($glue, $pieces);
594
    }
595
}