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.
Passed
Push — master ( a3eb64...37c075 )
by cao
03:26
created

Swagger::makeExample()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 11
nc 5
nop 1
dl 0
loc 15
ccs 0
cts 12
cp 0
crap 42
rs 8.8571
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 = $app->make($name);
139
140
            //TODO status 重复怎么办
141 1
            if ($ins instanceof HttpException) {
142 1
                $status = $ins->getStatusCode();
143 1
            } else {
144
145
                $status = 500;
146
            }
147 1
            if (isset($schemas[$status])) {
148
                //$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...
149
                $res = $schemas[$status];
150
            } else {
151 1
                $res = new ResponseObject();
152
            }
153 1
            $shortName = self::getShortClassName($name);
154 1
            $desc = "$shortName: $desc";
155 1
            $res->description = self::implode("\n", [$res->description, $desc]);
156 1
            $error = $app->get(ExceptionRenderer::class)->render($ins)->getContent();
157 1
            if($error){
158
                $res->examples = [$shortName => $error];
159
            }
160
            //$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...
161 1
            $schemas[$status] = $res;
162
163 1
        }
164 1
        return $schemas;
165
    }
166
167
    /**
168
     * @param Application $app
169
     * @param ControllerContainer $controller
170
     * @param $action
171
     * @param Route $route
172
     * @return null|ResponseObject
173
     */
174 1
    public function getReturnSchema(Application $app,
175
                                    ControllerContainer $controller,
176
                                    $action,
177
                                    Route $route)
178
    {
179 1
        $response = $route->getResponseHandler();
180 1
        if (!$response) {
181
            return null;
182
        }
183 1
        $mappings = $response->getMappings();
184 1
        $output = [];
185 1
        $schema = new ResponseObject();
186 1
        foreach ($mappings as $key => $map) {
187 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...
188 1
                $key = substr($key, strlen('response.'));
189 1
            }
190 1
            ArrayHelper::set($output, $key, $map);
191 1
        }
192
        //TODO 支持 header、status 等
193 1
        if (isset($output['content'])) {
194 1
            $content = $output['content'];
195 1
            if ($content instanceof ReturnMeta) {
196 1
                $schema->description = $content->description;
197 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...
198 1
            } elseif (is_array($content)) {
199 1
                $tmpSchema = $this->makeTempSchema($app, $controller, $action, $route, $content, 'Res');
200 1
                $schema->schema = $tmpSchema;
201
202 1
            }
203
            //$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...
204 1
            return $schema;
205
        }
206
        return null;
207
    }
208
209
    /**
210
     * @param $content
211
     */
212
    public function makeExample($content)
213
    {
214
        if ($content instanceof ReturnMeta || $content instanceof ParamMeta) {
215
            return $this->makeExample($content->container);
216
        }elseif ($content instanceof TypeContainerInterface){
217
            return $content->makeExample();
218
        }elseif(is_array($content)) {
219
            $res = [];
220
            foreach ($content as $k => $v) {
221
                $res[$k] = $this->makeExample($v);
222
            }
223
            return $res;
224
        }
225
        return null;
226
    }
227
    /**
228
     * @param Application $app
229
     * @param ControllerContainer $controller
230
     * @param $action
231
     * @param Route $route
232
     * @param array $arr
233
     * @param string $suffix
234
     * @return RefSchemaObject
235
     */
236 1
    public function makeTempSchema(Application $app,
237
                                   ControllerContainer $controller,
238
                                   $action,
239
                                   Route $route,
240
                                   array $arr, $suffix)
241
    {
242 1
        $className = self::getShortClassName($controller->getClassName());
243 1
        $name = $className . ucfirst($action) . $suffix;
244
245 1
        $schema = new SimpleModelSchemaObject();
246
247 1
        foreach ($arr as $k => $v) {
248 1
            if (is_array($v)) {
249 1
                $schema->properties[$k] = $this->makeTempSchema($app, $controller, $action, $route, $v, $suffix);
250 1
            } elseif ($v instanceof ReturnMeta) {
251 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...
252 1
                $sub->description = $v->description;
253 1
                $schema->properties[$k] = $sub;
254 1
            } elseif ($v instanceof ParamMeta) {
255 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...
256 1
                    $sub = $this->getArraySchema($app, $controller, $action, $route, $v->container);
257
                    //TODO array for validation
258 1
                } elseif ($v->container instanceof EntityContainer) {
259 1
                    $sub = $this->getRefSchema($app, $controller, $action, $route, $v->container);
260
                    //TODO array for validation
261 1
                } else {
262 1
                    $sub = new PrimitiveSchemaObject();
263 1
                    $sub->type = self::mapType($v->type);
264 1
                    self::mapValidation($v->validation, $sub);
265 1
                    unset($sub->required);
266
                }
267 1
                $sub->description = $v->description;
268 1
                $sub->default = $v->default;
269 1
                if (!$v->isOptional) {
270 1
                    $schema->required[] = $k;
271 1
                }
272 1
                $schema->properties[$k] = $sub;
273 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...
274
                //TODO how to do?
275
            }
276 1
        }
277 1
        $unused = $name;
278 1
        $tempId = 0;
279 1
        while (isset($this->definitions[$unused])) {
280 1
            $unused = $name . $tempId;
281 1
            $tempId++;
282 1
        }
283 1
        $this->definitions[$unused] = $schema;
284 1
        return new RefSchemaObject("#/definitions/$unused");
285
    }
286
287
    /**
288
     * @param Application $app
289
     * @param ControllerContainer $controller
290
     * @param $action
291
     * @param Route $route
292
     * @param EntityContainer $container
293
     * @return RefSchemaObject
294
     */
295 1
    public function getRefSchema(Application $app,
296
                                 ControllerContainer $controller,
297
                                 $action,
298
                                 Route $route,
299
                                 EntityContainer $container)
300
    {
301 1
        $name = $container->getClassName();
302 1
        if (!isset($this->definitions[$name])) {
303 1
            $this->definitions[$name] = $this->getObjectSchema($app, $controller, $action, $route, $container);
304 1
        }
305 1
        return new RefSchemaObject("#/definitions/$name");
306
    }
307
308 1
    public function getParamsSchema(Application $app,
309
                                    ControllerContainer $controller,
310
                                    $action,
311
                                    Route $route)
312
    {
313 1
        $params = $route->getRequestHandler()->getParamMetas();
314 1
        $parameters = [];
315 1
        $body = [];
316 1
        $in = 'query';
317
318 1
        $bodyType = 'body'; // 当有文件上传时, 必须是formData方式
319 1
        if($this->hasFileParam($route)){
320 1
            $bodyType = 'formData';
321 1
        }
322
323 1
        foreach ($params as $name => $param) {
324 1
            $isFile = false;
325 1
            if ($param->isPassedByReference) {
326 1
                continue;
327
            }
328 1
            if ($param->source == 'request.request') {
329
                $in = $bodyType;
330
                $name = '';
331 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...
332 1
                || $param->source == 'request.request'
333 1
            ) {
334 1
                $in = $bodyType;
335 1
                $name = substr($param->source, strlen('request.request.'));
336 1
            } elseif (strpos($param->source, 'request.query.') === 0) {
337 1
                $in = 'query';
338 1
                $name = substr($param->source, strlen('request.query.'));
339 1
            } elseif (strpos($param->source, 'request.cookies.') === 0) {
340 1
                $in = 'cookie';
341 1
                $name = substr($param->source, strlen('request.cookies.'));
342 1
            } elseif (strpos($param->source, 'request.headers.') === 0) {
343 1
                $in = 'header';
344 1
                $name = substr($param->source, strlen('request.headers.'));
345 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...
346 1
                $isFile = true;
347 1
                $in = $bodyType;
348 1
                $name = substr($param->source, strlen('request.files.'));
349 1
            } elseif (strpos($param->source, 'request.') === 0) {
350 1
                $name = substr($param->source, strlen('request.'));
351 1
                if ($route->hasPathParam($param->name)) {
352 1
                    $in = 'path';
353 1
                } elseif ($route->getMethod() == 'POST'
354 1
                    || $route->getMethod() == 'PUT'
355 1
                    || $route->getMethod() == 'PATCH'
356 1
                ) {
357 1
                    $in = $bodyType;
358 1
                } else {
359 1
                    $in = 'query';
360
                }
361 1
            }
362 1
            if ($in != 'body') {
363 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...
364 1
                    $paramSchema = $this->getArraySchema($app, $controller, $action, $route, $param->container);
365
                    //TODO array for validation
366 1
                } elseif ($param->container instanceof EntityContainer) {
367 1
                    $paramSchema = $this->getRefSchema($app, $controller, $action, $route, $param->container);
368
                    //TODO array for validation
369 1
                } else {
370 1
                    $paramSchema = new PrimitiveSchemaObject();
371 1
                    if($isFile){
372 1
                        $paramSchema->type = 'file';
373 1
                    }else{
374 1
                        $paramSchema->type = self::mapType($param->type);
375 1
                        self::mapValidation($param->validation, $paramSchema);
376
                    }
377
378
                }
379 1
                $paramSchema->in = $in;
380 1
                $paramSchema->name = $name;
381 1
                $paramSchema->description = $param->description;
382 1
                $paramSchema->default = $param->default;
383 1
                $paramSchema->required = !$param->isOptional;
384 1
                $parameters[] = $paramSchema;
385 1
            } else {
386 1
                if (!$name) {
387
                    $body = $param;
388
                } else {
389 1
                    ArrayHelper::set($body, $name, $param);
0 ignored issues
show
Bug introduced by
It seems like $body defined by $param on line 387 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...
390
                }
391
392
            }
393 1
        }
394 1
        if ($body && $bodyType == 'body') {
395
396 1
            $paramSchema = new BodyParameterObject();
397 1
            $paramSchema->name = 'body';
398 1
            $paramSchema->in = 'body';
399 1
            if (is_array($body)) {
400 1
                $paramSchema->schema = $this->makeTempSchema($app, $controller, $action, $route, $body, 'Req');
401 1
            } else {
402
                $paramSchema->schema = $this->getAnySchema($app, $controller, $action, $route, $body->container);
403
            }
404
405 1
            $parameters[] = $paramSchema;
406 1
        }
407
408 1
        return $parameters;
409
    }
410
411
    /**
412
     * @param Application $app
413
     * @param ControllerContainer $controller
414
     * @param $action
415
     * @param Route $route
416
     * @param TypeContainerInterface $container
417
     * @return ArraySchemaObject|PrimitiveSchemaObject|RefSchemaObject
418
     */
419 1
    public function getAnySchema(Application $app, ControllerContainer $controller, $action, Route $route, $container)
420
    {
421 1
        if ($container instanceof EntityContainer) {
422 1
            $schema = $this->getRefSchema($app, $controller, $action, $route, $container);
423 1
        } elseif ($container instanceof ArrayContainer) {
424 1
            $schema = $this->getArraySchema($app, $controller, $action, $route, $container);
425 1
        } elseif ($container instanceof ScalarTypeContainer) {
426 1
            $schema = new PrimitiveSchemaObject();
427 1
            $schema->type = self::mapType($container->getType());
428 1
        } elseif($container == null){
429
            $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...
430
            //$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...
431
        }else {
432 1
            $schema = new PrimitiveSchemaObject();
433
            //$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...
434
        }
435 1
        return $schema;
436
    }
437
438
    /**
439
     * @param Application $app
440
     * @param ControllerContainer $controller
441
     * @param $action
442
     * @param Route $route
443
     * @param ArrayContainer $container
444
     * @return ArraySchemaObject
445
     */
446 1
    public function getArraySchema(Application $app,
447
                                   ControllerContainer $controller,
448
                                   $action,
449
                                   Route $route,
450
                                   ArrayContainer $container)
451
    {
452 1
        $schema = new ArraySchemaObject();
453 1
        $itemContainer = $container->getContainer();
454 1
        if ($itemContainer instanceof EntityContainer) {
455 1
            $itemSchema = $this->getRefSchema($app, $controller, $action, $route, $itemContainer);
456 1
        } elseif ($itemContainer instanceof ArrayContainer) {
457
            $itemSchema = $this->getArraySchema($app, $controller, $action, $route, $itemContainer);
458 1
        } elseif ($itemContainer instanceof ScalarTypeContainer) {
459 1
            $itemSchema = new PrimitiveSchemaObject();
460 1
            $itemSchema->type = self::mapType($itemContainer->getType());
461 1
        } else {
462
            $itemSchema = new PrimitiveSchemaObject();
463
            //$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...
464
        }
465 1
        $schema->items = $itemSchema;
466 1
        return $schema;
467
    }
468
469 1
    public function getObjectSchema(Application $app,
470
                                    ControllerContainer $controller,
471
                                    $action,
472
                                    Route $route,
473
                                    EntityContainer $container)
474
    {
475 1
        $schema = new SimpleModelSchemaObject();
476 1
        $schema->description = self::implode("\n", [$container->getSummary(), $container->getDescription()]);
477
478 1
        foreach ($container->getProperties() as $property) {
479
480 1
            if (!$property->isOptional) {
481 1
                $schema->required[] = $property->name;
482 1
            }
483 1
            if ($property->container instanceof EntityContainer) {
484 1
                $propertySchema = $this->getRefSchema($app, $controller, $action, $route, $property->container);
485 1
            } elseif ($property->container instanceof ArrayContainer) {
486 1
                $propertySchema = $this->getArraySchema($app, $controller, $action, $route, $property->container);
487 1
            } else {
488 1
                $propertySchema = new PrimitiveSchemaObject();
489 1
                $propertySchema->type = self::mapType($property->type);
490 1
                $propertySchema->description = self::implode("\n", [$property->summary, $property->description]);
491 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...
492 1
                unset($propertySchema->required);
493
            }
494 1
            $schema->properties[$property->name] = $propertySchema;
495 1
        }
496
497 1
        return $schema;
498
    }
499
500 1
    public function hasFileParam(Route $route)
501
    {
502 1
        $params = $route->getRequestHandler()->getParamMetas();
503 1
        foreach ($params as $name => $param) {
504 1
            if(strpos($param->source, 'request.files.')===0){
505 1
                return true;
506
            }
507 1
        }
508 1
        return false;
509
    }
510
    /**
511
     * @param string $v
512
     * @param PrimitiveSchemaObject $schemaObject
513
     * @return PrimitiveSchemaObject
514
     */
515 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...
516
    {
517 1
        if(!$v){
518 1
            return $schemaObject;
519
        }
520 1
        $rules = explode('|', $v);
521 1
        foreach ($rules as $r) {
522 1
            $params = explode(':', trim($r));
523 1
            $rule = $params[0];
524 1
            $params = isset($params[1]) ? explode(',', $params[1]) : [];
525
526 1
            if ($rule == 'required') {
527
                $schemaObject->required = true;
528 1
            } elseif ($rule == 'in') {
529
                $schemaObject->enum = $params;
530 1
            } elseif ($rule == 'lengthBetween' && isset($params[0]) && isset($params[1])) {
531
                $schemaObject->minLength = intval($params[0]);
532
                $schemaObject->maxLength = intval($params[1]);
533 1
            } elseif ($rule == 'lengthMin'&& isset($params[0])) {
534
                $schemaObject->minLength = intval($params[0]);
535 1
            } elseif ($rule == 'lengthMax'&& isset($params[0])) {
536
                $schemaObject->maxLength = intval($params[0]);
537 1
            } elseif ($rule == 'min'&& isset($params[0])) {
538 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...
539 1
            } elseif ($rule == 'max'&& isset($params[0])) {
540 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...
541 1
            } elseif ($rule == 'regex'&& isset($params[0])) {
542
                $schemaObject->pattern = $params[0];
543
            } elseif ($rule == 'optional') {
544
                $schemaObject->required = false;
545
            }
546 1
        }
547 1
        return $schemaObject;
548
    }
549
550
    /**
551
     * @param string $type
552
     * @return string
553
     */
554 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...
555
    {
556
        //TODO 如何处理 file、mixed 类型
557
        $map = [
558 1
            'int' => 'integer',
559 1
            'bool' => 'boolean',
560 1
            'float' => 'number',
561 1
            'mixed' => null,
562 1
        ];
563 1
        if (array_key_exists($type, $map)) {
564 1
            return $map[$type];
565
        }
566 1
        return $type;
567
    }
568
569
    /**
570
     * @param $className
571
     * @return string
572
     */
573 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...
574
    {
575 1
        $className = explode('\\', $className);
576 1
        $className = $className[count($className) - 1];
577 1
        return $className;
578
    }
579
580
    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...
581
    {
582
        $pieces = array_filter($pieces, function($i){return trim($i) !== '';});
583 1
        return implode($glue, $pieces);
584
    }
585
}