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.
Test Failed
Push — master ( 004efd...1e9f36 )
by cao
15:19
created

Swagger::getParamsSchema()   F

Complexity

Conditions 24
Paths 372

Size

Total Lines 102
Code Lines 78

Duplication

Lines 27
Ratio 26.47 %

Code Coverage

Tests 76
CRAP Score 24.1352

Importance

Changes 0
Metric Value
cc 24
eloc 78
nc 372
nop 4
dl 27
loc 102
ccs 76
cts 81
cp 0.9383
crap 24.1352
rs 3.5633
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
                $sub->description = $v->description;
259 1
                $schema->properties[$k] = $sub;
260 1
            } elseif ($v instanceof ParamMeta) {
261 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...
262 1
                    $sub = $this->getArraySchema($app, $controller, $action, $route, $v->container);
263
                    //TODO array for validation
264 1
                } elseif ($v->container instanceof EntityContainer) {
265 1
                    $sub = $this->getRefSchema($app, $controller, $action, $route, $v->container);
266
                    //TODO array for validation
267 1
                } else {
268 1
                    $sub = new PrimitiveSchemaObject();
269 1
                    $sub->type = self::mapType($v->type);
270 1
                    self::mapValidation($v->validation, $sub);
271 1
                    unset($sub->required);
272
                }
273 1
                $sub->description = $v->description;
274 1
                $sub->default = $v->default;
275 1
                if (!$v->isOptional) {
276 1
                    $schema->required[] = $k;
277 1
                }
278 1
                $schema->properties[$k] = $sub;
279 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...
280
                //TODO how to do?
281
            }
282 1
        }
283 1
        $unused = $name;
284 1
        $tempId = 0;
285 1
        while (isset($this->definitions[$unused])) {
286 1
            $unused = $name . $tempId;
287 1
            $tempId++;
288 1
        }
289 1
        $this->definitions[$unused] = $schema;
290 1
        return new RefSchemaObject("#/definitions/$unused");
291
    }
292
293
    /**
294
     * @param Application $app
295
     * @param ControllerContainer $controller
296
     * @param $action
297
     * @param Route $route
298
     * @param EntityContainer $container
299
     * @return RefSchemaObject
300
     */
301 1
    public function getRefSchema(Application $app,
302
                                 ControllerContainer $controller,
303
                                 $action,
304
                                 Route $route,
305
                                 EntityContainer $container)
306
    {
307 1
        $name = $container->getClassName();
308 1
        if (!isset($this->definitions[$name])) {
309 1
            $this->definitions[$name] = $this->getObjectSchema($app, $controller, $action, $route, $container);
310 1
        }
311 1
        return new RefSchemaObject("#/definitions/$name");
312
    }
313
314 1
    public function getParamsSchema(Application $app,
315
                                    ControllerContainer $controller,
316
                                    $action,
317
                                    Route $route)
318
    {
319 1
        $params = $route->getRequestHandler()->getParamMetas();
320 1
        $parameters = [];
321 1
        $body = [];
322 1
        $in = 'query';
323
324 1
        $bodyType = 'body'; // 当有文件上传时, 必须是formData方式
325 1
        if($this->hasFileParam($route)){
326 1
            $bodyType = 'formData';
327 1
        }
328
329 1
        foreach ($params as $name => $param) {
330 1
            $isFile = false;
331 1
            if ($param->isPassedByReference) {
332 1
                continue;
333
            }
334 1
            if ($param->source == 'request.request') {
335
                $in = $bodyType;
336
                $name = '';
337 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...
338 1
                || $param->source == 'request.request'
339 1
            ) {
340 1
                $in = $bodyType;
341 1
                $name = substr($param->source, strlen('request.request.'));
342 1
            } elseif (strpos($param->source, 'request.query.') === 0) {
343 1
                $in = 'query';
344 1
                $name = substr($param->source, strlen('request.query.'));
345 1
            } elseif (strpos($param->source, 'request.cookies.') === 0) {
346 1
                $in = 'cookie';
347 1
                $name = substr($param->source, strlen('request.cookies.'));
348 1
            } elseif (strpos($param->source, 'request.headers.') === 0) {
349 1
                $in = 'header';
350 1
                $name = substr($param->source, strlen('request.headers.'));
351 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...
352 1
                $isFile = true;
353 1
                $in = $bodyType;
354 1
                $name = substr($param->source, strlen('request.files.'));
355 1
            } elseif (strpos($param->source, 'request.') === 0) {
356 1
                $name = substr($param->source, strlen('request.'));
357 1
                if ($route->hasPathParam($param->name)) {
358 1
                    $in = 'path';
359 1
                } elseif ($route->getMethod() == 'POST'
360 1
                    || $route->getMethod() == 'PUT'
361 1
                    || $route->getMethod() == 'PATCH'
362 1
                ) {
363 1
                    $in = $bodyType;
364 1
                } else {
365 1
                    $in = 'query';
366
                }
367 1
            }
368 1
            if ($in != 'body') {
369 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...
370 1
                    $paramSchema = $this->getArraySchema($app, $controller, $action, $route, $param->container);
371
                    //TODO array for validation
372 1
                } elseif ($param->container instanceof EntityContainer) {
373 1
                    $paramSchema = $this->getRefSchema($app, $controller, $action, $route, $param->container);
374
                    //TODO array for validation
375 1
                } else {
376 1
                    $paramSchema = new PrimitiveSchemaObject();
377 1
                    if($isFile){
378 1
                        $paramSchema->type = 'file';
379 1
                    }else{
380 1
                        $paramSchema->type = self::mapType($param->type);
381 1
                        self::mapValidation($param->validation, $paramSchema);
382
                    }
383
384
                }
385 1
                $paramSchema->in = $in;
386 1
                $paramSchema->name = $name;
387 1
                $paramSchema->description = $param->description;
388 1
                $paramSchema->default = $param->default;
389 1
                $paramSchema->required = !$param->isOptional;
390 1
                $parameters[] = $paramSchema;
391 1
            } else {
392 1
                if (!$name) {
393
                    $body = $param;
394
                } else {
395 1
                    ArrayHelper::set($body, $name, $param);
0 ignored issues
show
Bug introduced by
It seems like $body defined by $param on line 393 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...
396
                }
397
398
            }
399 1
        }
400 1
        if ($body && $bodyType == 'body') {
401
402 1
            $paramSchema = new BodyParameterObject();
403 1
            $paramSchema->name = 'body';
404 1
            $paramSchema->in = 'body';
405 1
            if (is_array($body)) {
406 1
                $paramSchema->schema = $this->makeTempSchema($app, $controller, $action, $route, $body, 'Req');
407 1
            } else {
408
                $paramSchema->schema = $this->getAnySchema($app, $controller, $action, $route, $body->container);
409
            }
410
411 1
            $parameters[] = $paramSchema;
412 1
        }
413
414 1
        return $parameters;
415
    }
416
417
    /**
418
     * @param Application $app
419
     * @param ControllerContainer $controller
420
     * @param $action
421
     * @param Route $route
422
     * @param TypeContainerInterface $container
423
     * @return ArraySchemaObject|PrimitiveSchemaObject|RefSchemaObject
424
     */
425 1
    public function getAnySchema(Application $app, ControllerContainer $controller, $action, Route $route, $container)
426
    {
427 1
        if ($container instanceof EntityContainer) {
428 1
            $schema = $this->getRefSchema($app, $controller, $action, $route, $container);
429 1
        } elseif ($container instanceof ArrayContainer) {
430 1
            $schema = $this->getArraySchema($app, $controller, $action, $route, $container);
431 1
        } elseif ($container instanceof ScalarTypeContainer) {
432 1
            $schema = new PrimitiveSchemaObject();
433 1
            $schema->type = self::mapType($container->getType());
434 1
        } elseif($container == null){
435
            $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...
436
            //$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...
437
        }else {
438 1
            $schema = new PrimitiveSchemaObject();
439
            //$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...
440
        }
441 1
        return $schema;
442
    }
443
444
    /**
445
     * @param Application $app
446
     * @param ControllerContainer $controller
447
     * @param $action
448
     * @param Route $route
449
     * @param ArrayContainer $container
450
     * @return ArraySchemaObject
451
     */
452 1
    public function getArraySchema(Application $app,
453
                                   ControllerContainer $controller,
454
                                   $action,
455
                                   Route $route,
456
                                   ArrayContainer $container)
457
    {
458 1
        $schema = new ArraySchemaObject();
459 1
        $itemContainer = $container->getContainer();
460 1
        if ($itemContainer instanceof EntityContainer) {
461 1
            $itemSchema = $this->getRefSchema($app, $controller, $action, $route, $itemContainer);
462 1
        } elseif ($itemContainer instanceof ArrayContainer) {
463
            $itemSchema = $this->getArraySchema($app, $controller, $action, $route, $itemContainer);
464 1
        } elseif ($itemContainer instanceof ScalarTypeContainer) {
465 1
            $itemSchema = new PrimitiveSchemaObject();
466 1
            $itemSchema->type = self::mapType($itemContainer->getType());
467 1
        } else {
468
            $itemSchema = new PrimitiveSchemaObject();
469
            //$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...
470
        }
471 1
        $schema->items = $itemSchema;
472 1
        return $schema;
473
    }
474
475 1
    public function getObjectSchema(Application $app,
476
                                    ControllerContainer $controller,
477
                                    $action,
478
                                    Route $route,
479
                                    EntityContainer $container)
480
    {
481 1
        $schema = new SimpleModelSchemaObject();
482 1
        $schema->description = self::implode("\n", [$container->getSummary(), $container->getDescription()]);
483
484 1
        foreach ($container->getProperties() as $property) {
485
486 1
            if (!$property->isOptional) {
487 1
                $schema->required[] = $property->name;
488 1
            }
489 1
            if ($property->container instanceof EntityContainer) {
490 1
                $propertySchema = $this->getRefSchema($app, $controller, $action, $route, $property->container);
491 1
            } elseif ($property->container instanceof ArrayContainer) {
492 1
                $propertySchema = $this->getArraySchema($app, $controller, $action, $route, $property->container);
493 1
            } else {
494 1
                $propertySchema = new PrimitiveSchemaObject();
495 1
                $propertySchema->type = self::mapType($property->type);
496 1
                $propertySchema->description = self::implode("\n", [$property->summary, $property->description]);
497 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...
498 1
                unset($propertySchema->required);
499
            }
500 1
            $schema->properties[$property->name] = $propertySchema;
501 1
        }
502
503 1
        return $schema;
504
    }
505
506 1
    public function hasFileParam(Route $route)
507
    {
508 1
        $params = $route->getRequestHandler()->getParamMetas();
509 1
        foreach ($params as $name => $param) {
510 1
            if(strpos($param->source, 'request.files.')===0){
511 1
                return true;
512
            }
513 1
        }
514 1
        return false;
515
    }
516
    /**
517
     * @param string $v
518
     * @param PrimitiveSchemaObject $schemaObject
519
     * @return PrimitiveSchemaObject
520
     */
521 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...
522
    {
523 1
        if(!$v){
524 1
            return $schemaObject;
525
        }
526 1
        $rules = explode('|', $v);
527 1
        foreach ($rules as $r) {
528 1
            $params = explode(':', trim($r));
529 1
            $rule = $params[0];
530 1
            $params = isset($params[1]) ? explode(',', $params[1]) : [];
531
532 1
            if ($rule == 'required') {
533
                $schemaObject->required = true;
534 1
            } elseif ($rule == 'in') {
535
                $schemaObject->enum = $params;
536 1
            } elseif ($rule == 'lengthBetween' && isset($params[0]) && isset($params[1])) {
537
                $schemaObject->minLength = intval($params[0]);
538
                $schemaObject->maxLength = intval($params[1]);
539 1
            } elseif ($rule == 'lengthMin'&& isset($params[0])) {
540
                $schemaObject->minLength = intval($params[0]);
541 1
            } elseif ($rule == 'lengthMax'&& isset($params[0])) {
542
                $schemaObject->maxLength = intval($params[0]);
543 1
            } elseif ($rule == 'min'&& isset($params[0])) {
544 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...
545 1
            } elseif ($rule == 'max'&& isset($params[0])) {
546 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...
547 1
            } elseif ($rule == 'regex'&& isset($params[0])) {
548
                $schemaObject->pattern = $params[0];
549
            } elseif ($rule == 'optional') {
550
                $schemaObject->required = false;
551
            }
552 1
        }
553 1
        return $schemaObject;
554
    }
555
556
    /**
557
     * @param string $type
558
     * @return string
559
     */
560 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...
561
    {
562
        //TODO 如何处理 file、mixed 类型
563
        $map = [
564 1
            'int' => 'integer',
565 1
            'bool' => 'boolean',
566 1
            'float' => 'number',
567 1
            'mixed' => null,
568 1
        ];
569 1
        if (array_key_exists($type, $map)) {
570 1
            return $map[$type];
571
        }
572 1
        return $type;
573
    }
574
575
    /**
576
     * @param $className
577
     * @return string
578
     */
579 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...
580
    {
581 1
        $className = explode('\\', $className);
582 1
        $className = $className[count($className) - 1];
583 1
        return $className;
584
    }
585
586
    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...
587
    {
588
        $pieces = array_filter($pieces, function($i){return trim($i) !== '';});
589 1
        return implode($glue, $pieces);
590
    }
591
}