• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

RonasIT / laravel-swagger / 3950499686

pending completion
3950499686

Pull #64

github

GitHub
Merge 3ceb03e20 into cf7bb3d1f
Pull Request #64: #20 :- limit response data

21 of 21 new or added lines in 2 files covered. (100.0%)

255 of 482 relevant lines covered (52.9%)

3.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

47.45
/src/Services/SwaggerService.php
1
<?php
2

3
namespace RonasIT\Support\AutoDoc\Services;
4

5
use Illuminate\Container\Container;
6
use Illuminate\Http\Testing\File;
7
use Illuminate\Support\Arr;
8
use Illuminate\Support\Str;
9
use ReflectionClass;
10
use Illuminate\Http\Request;
11
use RonasIT\Support\AutoDoc\Exceptions\LegacyConfigException;
12
use RonasIT\Support\AutoDoc\Exceptions\WrongSecurityConfigException;
13
use RonasIT\Support\AutoDoc\Traits\GetDependenciesTrait;
14
use Symfony\Component\HttpFoundation\Response;
15
use RonasIT\Support\AutoDoc\Interfaces\SwaggerDriverInterface;
16
use RonasIT\Support\AutoDoc\Exceptions\InvalidDriverClassException;
17
use RonasIT\Support\AutoDoc\Exceptions\SwaggerDriverClassNotFoundException;
18

19
/**
20
 * @property SwaggerDriverInterface $driver
21
 */
22
class SwaggerService
23
{
24
    use GetDependenciesTrait;
25

26
    protected $driver;
27

28
    protected $data;
29
    protected $config;
30
    protected $container;
31
    private $uri;
32
    private $method;
33
    /**
34
     * @var Request
35
     */
36
    private $request;
37
    private $item;
38
    private $security;
39

40
    protected $ruleToTypeMap = [
41
        'array' => 'object',
42
        'boolean' => 'boolean',
43
        'date' => 'date',
44
        'digits' => 'integer',
45
        'integer' => 'integer',
46
        'numeric' => 'double',
47
        'string' => 'string',
48
        'int' => 'integer'
49
    ];
50

51
    protected $documentation;
52

53
    public function __construct(Container $container)
54
    {
55
        $this->initConfig();
16✔
56

57
        $this->setDriver();
14✔
58

59
        if (config('app.env') == 'testing') {
12✔
60
            $this->container = $container;
12✔
61

62
            $this->security = $this->config['security'];
12✔
63

64
            $this->data = $this->driver->getTmpData();
12✔
65

66
            if (empty($this->data)) {
12✔
67
                $this->data = $this->generateEmptyData();
6✔
68

69
                $this->driver->saveTmpData($this->data);
5✔
70
            }
71
        }
72
    }
73

74
    protected function initConfig()
75
    {
76
        $this->config = config('auto-doc');
16✔
77

78
        $version = Arr::get($this->config, 'config_version');
16✔
79

80
        if (empty($version)) {
16✔
81
            throw new LegacyConfigException();
1✔
82
        }
83

84
        $packageConfigs = require __DIR__ . '/../../config/auto-doc.php';
15✔
85

86
        if (version_compare($packageConfigs['config_version'], $version, '>')) {
15✔
87
            throw new LegacyConfigException();
1✔
88
        }
89
    }
90

91
    protected function setDriver()
92
    {
93
        $driver = $this->config['driver'];
14✔
94
        $className = Arr::get($this->config, "drivers.{$driver}.class");
14✔
95

96
        if (!class_exists($className)) {
14✔
97
            throw new SwaggerDriverClassNotFoundException($className);
1✔
98
        } else {
99
            $this->driver = app($className);
13✔
100
        }
101

102
        if (!$this->driver instanceof SwaggerDriverInterface) {
13✔
103
            throw new InvalidDriverClassException($driver);
1✔
104
        }
105
    }
106

107
    protected function generateEmptyData(): array
108
    {
109
        $data = [
6✔
110
            'swagger' => Arr::get($this->config, 'swagger.version'),
6✔
111
            'host' => $this->getAppUrl(),
6✔
112
            'basePath' => $this->config['basePath'],
6✔
113
            'schemes' => $this->config['schemes'],
6✔
114
            'paths' => [],
6✔
115
            'definitions' => $this->config['definitions']
6✔
116
        ];
6✔
117

118
        $info = $this->prepareInfo($this->config['info']);
6✔
119

120
        if (!empty($info)) {
6✔
121
            $data['info'] = $info;
6✔
122
        }
123

124
        $securityDefinitions = $this->generateSecurityDefinition();
6✔
125

126
        if (!empty($securityDefinitions)) {
5✔
127
            $data['securityDefinitions'] = $securityDefinitions;
2✔
128
        }
129

130
        $data['info']['description'] = view($data['info']['description'])->render();
5✔
131

132
        return $data;
5✔
133
    }
134

135
    protected function getAppUrl()
136
    {
137
        $url = config('app.url');
6✔
138

139
        return str_replace(['http://', 'https://', '/'], '', $url);
6✔
140
    }
141

142
    protected function generateSecurityDefinition()
143
    {
144
        if (empty($this->security)) {
6✔
145
            return '';
3✔
146
        }
147

148
        return [
3✔
149
            $this->security => $this->generateSecurityDefinitionObject($this->security)
3✔
150
        ];
3✔
151
    }
152

153
    protected function generateSecurityDefinitionObject($type): array
154
    {
155
        switch ($type) {
156
            case 'jwt':
3✔
157
                return [
1✔
158
                    'type' => 'apiKey',
1✔
159
                    'name' => 'authorization',
1✔
160
                    'in' => 'header'
1✔
161
                ];
1✔
162

163
            case 'laravel':
2✔
164
                return [
1✔
165
                    'type' => 'apiKey',
1✔
166
                    'name' => 'Cookie',
1✔
167
                    'in' => 'header'
1✔
168
                ];
1✔
169
            default:
170
                throw new WrongSecurityConfigException();
1✔
171
        }
172
    }
173

174
    public function addData(Request $request, $response)
175
    {
176
        $this->request = $request;
4✔
177

178
        $this->prepareItem();
4✔
179

180
        $this->parseRequest();
4✔
181
        $this->parseResponse($response);
4✔
182

183
        $this->driver->saveTmpData($this->data);
4✔
184
    }
185

186
    protected function prepareItem()
187
    {
188
        $this->uri = "/{$this->getUri()}";
4✔
189
        $this->method = strtolower($this->request->getMethod());
4✔
190

191
        if (empty(Arr::get($this->data, "paths.{$this->uri}.{$this->method}"))) {
4✔
192
            $this->data['paths'][$this->uri][$this->method] = [
4✔
193
                'tags' => [],
4✔
194
                'consumes' => [],
4✔
195
                'produces' => [],
4✔
196
                'parameters' => $this->getPathParams(),
4✔
197
                'responses' => [],
4✔
198
                'security' => [],
4✔
199
                'description' => ''
4✔
200
            ];
4✔
201
        }
202

203
        $this->item = &$this->data['paths'][$this->uri][$this->method];
4✔
204
    }
205

206
    protected function getUri()
207
    {
208
        $uri = $this->request->route()->uri();
4✔
209
        $basePath = preg_replace("/^\//", '', $this->config['basePath']);
4✔
210
        $preparedUri = preg_replace("/^{$basePath}/", '', $uri);
4✔
211

212
        return preg_replace("/^\//", '', $preparedUri);
4✔
213
    }
214

215
    protected function getPathParams(): array
216
    {
217
        $params = [];
4✔
218

219
        preg_match_all('/{.*?}/', $this->uri, $params);
4✔
220

221
        $params = Arr::collapse($params);
4✔
222

223
        $result = [];
4✔
224

225
        foreach ($params as $param) {
4✔
226
            $key = preg_replace('/[{}]/', '', $param);
1✔
227

228
            $result[] = [
1✔
229
                'in' => 'path',
1✔
230
                'name' => $key,
1✔
231
                'description' => '',
1✔
232
                'required' => true,
1✔
233
                'type' => 'string'
1✔
234
            ];
1✔
235
        }
236

237
        return $result;
4✔
238
    }
239

240
    protected function parseRequest()
241
    {
242
        $this->saveConsume();
4✔
243
        $this->saveTags();
4✔
244
        $this->saveSecurity();
4✔
245

246
        $concreteRequest = $this->getConcreteRequest();
4✔
247

248
        if (empty($concreteRequest)) {
4✔
249
            $this->item['description'] = '';
4✔
250

251
            return;
4✔
252
        }
253

254
        $annotations = $this->getClassAnnotations($concreteRequest);
×
255

256
        $this->saveParameters($concreteRequest, $annotations);
×
257
        $this->saveDescription($concreteRequest, $annotations);
×
258
    }
259

260
    protected function parseResponse($response)
261
    {
262
        $produceList = $this->data['paths'][$this->uri][$this->method]['produces'];
4✔
263

264
        $produce = $response->headers->get('Content-type');
4✔
265

266
        if (is_null($produce)) {
4✔
267
            $produce = 'text/plain';
×
268
        }
269

270
        if (!in_array($produce, $produceList)) {
4✔
271
            $this->item['produces'][] = $produce;
4✔
272
        }
273

274
        $responses = $this->item['responses'];
4✔
275
        $code = $response->getStatusCode();
4✔
276

277
        if (!in_array($code, $responses)) {
4✔
278
            $this->saveExample(
4✔
279
                $response->getStatusCode(),
4✔
280
                $response->getContent(),
4✔
281
                $produce
4✔
282
            );
4✔
283
        }
284
    }
285

286
    protected function saveExample($code, $content, $produce)
287
    {
288
        $description = $this->getResponseDescription($code);
4✔
289
        $availableContentTypes = [
4✔
290
            'application',
4✔
291
            'text'
4✔
292
        ];
4✔
293
        $explodedContentType = explode('/', $produce);
4✔
294

295
        if (in_array($explodedContentType[0], $availableContentTypes)) {
4✔
296
            $this->item['responses'][$code] = $this->makeResponseExample($content, $produce, $description);
4✔
297
        } else {
298
            $this->item['responses'][$code] = '*Unavailable for preview*';
×
299
        }
300
    }
301

302
    protected function makeResponseExample($content, $mimeType, $description = ''): array
303
    {
304
        $responseExample = ['description' => $description];
4✔
305

306
        if ($mimeType === 'application/json') {
4✔
307
            $responseExample['schema'] = ['example' => json_decode($content, true)];
4✔
308
        } elseif ($mimeType === 'application/pdf') {
×
309
            $responseExample['schema'] = ['example' => base64_encode($content)];
×
310
        } else {
311
            $responseExample['examples']['example'] = $content;
×
312
        }
313

314
        return $responseExample;
4✔
315
    }
316

317
    protected function saveParameters($request, array $annotations)
318
    {
319
        $formRequest = new $request;
×
320
        $formRequest->setUserResolver($this->request->getUserResolver());
×
321
        $formRequest->setRouteResolver($this->request->getRouteResolver());
×
322
        $rules = method_exists($formRequest, 'rules') ? $formRequest->rules() : [];
×
323
        $attributes = method_exists($formRequest, 'attributes') ? $formRequest->attributes() : [];
×
324

325
        $actionName = $this->getActionName($this->uri);
×
326

327
        if (in_array($this->method, ['get', 'delete'])) {
×
328
            $this->saveGetRequestParameters($rules, $attributes, $annotations);
×
329
        } else {
330
            $this->savePostRequestParameters($actionName, $rules, $attributes, $annotations);
×
331
        }
332
    }
333

334
    protected function saveGetRequestParameters($rules, array $attributes, array $annotations)
335
    {
336
        foreach ($rules as $parameter => $rule) {
×
337
            $validation = explode('|', $rule);
×
338

339
            $description = Arr::get($annotations, $parameter);
×
340

341
            if (empty($description)) {
×
342
                $description = Arr::get($attributes, $parameter, implode(', ', $validation));
×
343
            }
344

345
            $existedParameter = Arr::first($this->item['parameters'], function ($existedParameter) use ($parameter) {
×
346
                return $existedParameter['name'] == $parameter;
×
347
            });
×
348

349
            if (empty($existedParameter)) {
×
350
                $parameterDefinition = [
×
351
                    'in' => 'query',
×
352
                    'name' => $parameter,
×
353
                    'description' => $description,
×
354
                    'type' => $this->getParameterType($validation)
×
355
                ];
×
356
                if (in_array('required', $validation)) {
×
357
                    $parameterDefinition['required'] = true;
×
358
                }
359

360
                $this->item['parameters'][] = $parameterDefinition;
×
361
            }
362
        }
363
    }
364

365
    protected function savePostRequestParameters($actionName, $rules, array $attributes, array $annotations)
366
    {
367
        if ($this->requestHasMoreProperties($actionName)) {
×
368
            if ($this->requestHasBody()) {
×
369
                $this->item['parameters'][] = [
×
370
                    'in' => 'body',
×
371
                    'name' => 'body',
×
372
                    'description' => '',
×
373
                    'required' => true,
×
374
                    'schema' => [
×
375
                        "\$ref" => "#/definitions/{$actionName}Object"
×
376
                    ]
×
377
                ];
×
378
            }
379

380
            $this->saveDefinitions($actionName, $rules, $attributes, $annotations);
×
381
        }
382
    }
383

384
    protected function saveDefinitions($objectName, $rules, $attributes, array $annotations)
385
    {
386
        $data = [
×
387
            'type' => 'object',
×
388
            'properties' => []
×
389
        ];
×
390

391
        foreach ($rules as $parameter => $rule) {
×
392
            $rulesArray = (is_array($rule)) ? $rule : explode('|', $rule);
×
393
            $parameterType = $this->getParameterType($rulesArray);
×
394
            $this->saveParameterType($data, $parameter, $parameterType);
×
395

396
            $uselessRules = $this->ruleToTypeMap;
×
397
            $uselessRules['required'] = 'required';
×
398

399
            if (in_array('required', $rulesArray)) {
×
400
                $data['required'][] = $parameter;
×
401
            }
402

403
            $rulesArray = array_flip(array_diff_key(array_flip($rulesArray), $uselessRules));
×
404

405
            $this->saveParameterDescription($data, $parameter, $rulesArray, $attributes, $annotations);
×
406
        }
407

408
        $data['example'] = $this->generateExample($data['properties']);
×
409
        $this->data['definitions'][$objectName . 'Object'] = $data;
×
410
    }
411

412
    protected function getParameterType(array $validation): string
413
    {
414
        $validationRules = $this->ruleToTypeMap;
×
415
        $validationRules['email'] = 'string';
×
416

417
        $parameterType = 'string';
×
418

419
        foreach ($validation as $item) {
×
420
            if (in_array($item, array_keys($validationRules))) {
×
421
                return $validationRules[$item];
×
422
            }
423
        }
424

425
        return $parameterType;
×
426
    }
427

428
    protected function saveParameterType(&$data, $parameter, $parameterType)
429
    {
430
        $data['properties'][$parameter] = [
×
431
            'type' => $parameterType
×
432
        ];
×
433
    }
434

435
    protected function saveParameterDescription(&$data, $parameter, array $rulesArray, array $attributes, array $annotations)
436
    {
437
        $description = Arr::get($annotations, $parameter);
×
438

439
        if (empty($description)) {
×
440
            $description = Arr::get($attributes, $parameter, implode(', ', $rulesArray));
×
441
        }
442

443
        $data['properties'][$parameter]['description'] = $description;
×
444
    }
445

446
    protected function requestHasMoreProperties($actionName): bool
447
    {
448
        $requestParametersCount = count($this->request->all());
×
449

450
        if (isset($this->data['definitions'][$actionName . 'Object']['properties'])) {
×
451
            $objectParametersCount = count($this->data['definitions'][$actionName . 'Object']['properties']);
×
452
        } else {
453
            $objectParametersCount = 0;
×
454
        }
455

456
        return $requestParametersCount > $objectParametersCount;
×
457
    }
458

459
    protected function requestHasBody(): bool
460
    {
461
        $parameters = $this->data['paths'][$this->uri][$this->method]['parameters'];
×
462

463
        $bodyParamExisted = Arr::where($parameters, function ($value) {
×
464
            return $value['name'] == 'body';
×
465
        });
×
466

467
        return empty($bodyParamExisted);
×
468
    }
469

470
    public function getConcreteRequest()
471
    {
472
        $controller = $this->request->route()->getActionName();
4✔
473

474
        if ($controller == 'Closure') {
4✔
475
            return null;
4✔
476
        }
477

478
        $explodedController = explode('@', $controller);
×
479

480
        $class = $explodedController[0];
×
481
        $method = $explodedController[1];
×
482

483
        $instance = app($class);
×
484
        $route = $this->request->route();
×
485

486
        $parameters = $this->resolveClassMethodDependencies(
×
487
            $route->parametersWithoutNulls(), $instance, $method
×
488
        );
×
489

490
        return Arr::first($parameters, function ($key) {
×
491
            return preg_match('/Request/', $key);
×
492
        });
×
493
    }
494

495
    public function saveConsume()
496
    {
497
        $consumeList = $this->data['paths'][$this->uri][$this->method]['consumes'];
4✔
498
        $consume = $this->request->header('Content-Type');
4✔
499

500
        if (!empty($consume) && !in_array($consume, $consumeList)) {
4✔
501
            $this->item['consumes'][] = $consume;
1✔
502
        }
503
    }
504

505
    public function saveTags()
506
    {
507
        $tagIndex = 1;
4✔
508

509
        $explodedUri = explode('/', $this->uri);
4✔
510

511
        $tag = Arr::get($explodedUri, $tagIndex);
4✔
512

513
        $this->item['tags'] = [$tag];
4✔
514
    }
515

516
    public function saveDescription($request, array $annotations)
517
    {
518
        $this->item['summary'] = $this->getSummary($request, $annotations);
×
519

520
        $description = Arr::get($annotations, 'description');
×
521

522
        if (!empty($description)) {
×
523
            $this->item['description'] = $description;
×
524
        }
525
    }
526

527
    protected function saveSecurity()
528
    {
529
        if ($this->requestSupportAuth()) {
4✔
530
            $this->addSecurityToOperation();
×
531
        }
532
    }
533

534
    protected function addSecurityToOperation()
535
    {
536
        $security = &$this->data['paths'][$this->uri][$this->method]['security'];
×
537

538
        if (empty($security)) {
×
539
            $security[] = [
×
540
                "{$this->security}" => []
×
541
            ];
×
542
        }
543
    }
544

545
    protected function getSummary($request, array $annotations)
546
    {
547
        $summary = Arr::get($annotations, 'summary');
×
548

549
        if (empty($summary)) {
×
550
            $summary = $this->parseRequestName($request);
×
551
        }
552

553
        return $summary;
×
554
    }
555

556
    protected function requestSupportAuth(): bool
557
    {
558
        switch ($this->security) {
4✔
559
            case 'jwt' :
4✔
560
                $header = $this->request->header('authorization');
1✔
561
                break;
1✔
562
            case 'laravel' :
3✔
563
                $header = $this->request->cookie('__ym_uid');
1✔
564
                break;
1✔
565
        }
566

567
        return !empty($header);
4✔
568
    }
569

570
    protected function parseRequestName($request)
571
    {
572
        $explodedRequest = explode('\\', $request);
×
573
        $requestName = array_pop($explodedRequest);
×
574
        $summaryName = str_replace('Request', '', $requestName);
×
575

576
        $underscoreRequestName = $this->camelCaseToUnderScore($summaryName);
×
577

578
        return preg_replace('/[_]/', ' ', $underscoreRequestName);
×
579
    }
580

581
    protected function getResponseDescription($code)
582
    {
583
        $defaultDescription = Response::$statusTexts[$code];
4✔
584

585
        $request = $this->getConcreteRequest();
4✔
586

587
        if (empty($request)) {
4✔
588
            return $defaultDescription;
4✔
589
        }
590

591
        $annotations = $this->getClassAnnotations($request);
×
592

593
        $localDescription = Arr::get($annotations, "_{$code}");
×
594

595
        if (!empty($localDescription)) {
×
596
            return $localDescription;
×
597
        }
598

599
        return Arr::get($this->config, "defaults.code-descriptions.{$code}", $defaultDescription);
×
600
    }
601

602
    protected function getActionName($uri): string
603
    {
604
        $action = preg_replace('[\/]', '', $uri);
×
605

606
        return Str::camel($action);
×
607
    }
608

609
    protected function saveTempData()
610
    {
611
        $exportFile = Arr::get($this->config, 'files.temporary');
×
612
        $data = json_encode($this->data);
×
613

614
        file_put_contents($exportFile, $data);
×
615
    }
616

617
    public function saveProductionData()
618
    {
619
        $this->driver->saveData();
×
620
    }
621

622
    public function getDocFileContent()
623
    {
624
        $this->documentation = $this->driver->getDocumentation();
2✔
625

626
        $additionalDocs = config('auto-doc.additional_paths', []);
2✔
627

628
        foreach ($additionalDocs as $filePath) {
2✔
629
            $fileContent = json_decode(file_get_contents($filePath), true);
×
630

631
            $paths = array_keys($fileContent['paths']);
×
632

633
            foreach ($paths as $path) {
×
634
                $additionalDocPath =  $fileContent['paths'][$path];
×
635

636
                if (empty($this->documentation['paths'][$path])) {
×
637
                    $this->documentation['paths'][$path] = $additionalDocPath;
×
638
                } else {
639
                    $methods = array_keys($this->documentation['paths'][$path]);
×
640
                    $additionalDocMethods = array_keys($additionalDocPath);
×
641

642
                    foreach ($additionalDocMethods as $method) {
×
643
                        if (!in_array($method, $methods)) {
×
644
                            $this->documentation['paths'][$path][$method] = $additionalDocPath[$method];
×
645
                        }
646
                    }
647
                }
648
            }
649

650
            $definitions = array_keys($fileContent['definitions']);
×
651

652
            foreach ($definitions as $definition) {
×
653
                if (empty($this->documentation['definitions'][$definition])) {
×
654
                    $this->documentation['definitions'][$definition] = $fileContent['definitions'][$definition];
×
655
                }
656
            }
657
        }
658

659
        $this->limitResponseData();
2✔
660

661
        $this->cutExceptions();
2✔
662

663
        return $this->documentation;
2✔
664
    }
665

666
    protected function limitResponseData()
667
    {
668
        $paths = array_keys($this->documentation['paths']);
2✔
669

670
        $responseExampleLimitCount = config('auto-doc.response_example_limit_count');
2✔
671

672
        if (!empty($responseExampleLimitCount)) {
2✔
673
            foreach ($paths as $path) {
2✔
674
                $example = Arr::get($this->documentation['paths'][$path], 'get.responses.200.schema.example');
2✔
675

676
                if (!empty($example['data'])) {
2✔
677
                    $limitedResponseData = array_slice($example['data'], 0, $responseExampleLimitCount, true);
×
678
                    $this->documentation['paths'][$path]['get']['responses'][200]['schema']['example']['data'] = $limitedResponseData;
×
679
                }
680
            }
681
        }
682
    }
683

684
    protected function cutExceptions()
685
    {
686
        $paths = $this->documentation['paths'];
2✔
687

688
        foreach ($paths as $path => $methods) {
2✔
689
            foreach ($methods as $method => $data) {
2✔
690
                if(!empty($data['responses'])) {
2✔
691
                    foreach ($data['responses'] as $code => $data) {
2✔
692
                        $example = Arr::get($data, 'schema.example');
2✔
693

694
                        if (!empty($example['exception'])) {
2✔
695
                            $uselessKeys = array_keys(Arr::except($example, ['message']));
×
696

697
                            $this->documentation['paths'][$path][$method]['responses'][$code]['schema']['example'] = Arr::except($example, $uselessKeys);
×
698
                        }
699
                    }
700
                }
701
            }
702
        }
703
    }
704

705
    protected function camelCaseToUnderScore($input): string
706
    {
707
        preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches);
×
708
        $ret = $matches[0];
×
709

710
        foreach ($ret as &$match) {
×
711
            $match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
×
712
        }
713

714
        return implode('_', $ret);
×
715
    }
716

717
    protected function generateExample($properties): array
718
    {
719
        $parameters = $this->replaceObjectValues($this->request->all());
×
720
        $example = [];
×
721

722
        $this->replaceNullValues($parameters, $properties, $example);
×
723

724
        return $example;
×
725
    }
726

727
    protected function replaceObjectValues($parameters): array
728
    {
729
        $classNamesValues = [
×
730
            File::class => '[uploaded_file]',
×
731
        ];
×
732

733
        $parameters = Arr::dot($parameters);
×
734
        $returnParameters = [];
×
735

736
        foreach ($parameters as $parameter => $value) {
×
737
            if (is_object($value)) {
×
738
                $class = get_class($value);
×
739

740
                $value = Arr::get($classNamesValues, $class, $class);
×
741
            }
742

743
            Arr::set($returnParameters, $parameter, $value);
×
744
        }
745

746
        return $returnParameters;
×
747
    }
748

749
    protected function getClassAnnotations($class): array
750
    {
751
        $reflection = new ReflectionClass($class);
×
752

753
        $annotations = $reflection->getDocComment();
×
754

755
        $blocks = explode("\n", $annotations);
×
756

757
        $result = [];
×
758

759
        foreach ($blocks as $block) {
×
760
            if (Str::contains($block, '@')) {
×
761
                $index = strpos($block, '@');
×
762
                $block = substr($block, $index);
×
763
                $exploded = explode(' ', $block);
×
764

765
                $paramName = str_replace('@', '', array_shift($exploded));
×
766
                $paramValue = implode(' ', $exploded);
×
767

768
                $result[$paramName] = $paramValue;
×
769
            }
770
        }
771

772
        return $result;
×
773
    }
774

775
    /**
776
     * NOTE: All functions below are temporary solution for
777
     * this issue: https://github.com/OAI/OpenAPI-Specification/issues/229
778
     * We hope swagger developers will resolve this problem in next release of Swagger OpenAPI
779
     * */
780
    protected function replaceNullValues($parameters, $types, &$example)
781
    {
782
        foreach ($parameters as $parameter => $value) {
×
783
            if (is_null($value) && in_array($parameter, $types)) {
×
784
                $example[$parameter] = $this->getDefaultValueByType($types[$parameter]['type']);
×
785
            } elseif (is_array($value)) {
×
786
                $this->replaceNullValues($value, $types, $example[$parameter]);
×
787
            } else {
788
                $example[$parameter] = $value;
×
789
            }
790
        }
791
    }
792

793
    protected function getDefaultValueByType($type)
794
    {
795
        $values = [
×
796
            'object' => 'null',
×
797
            'boolean' => false,
×
798
            'date' => "0000-00-00",
×
799
            'integer' => 0,
×
800
            'string' => '',
×
801
            'double' => 0
×
802
        ];
×
803

804
        return $values[$type];
×
805
    }
806

807
    /**
808
     * @param $info
809
     * @return mixed
810
     */
811
    protected function prepareInfo($info)
812
    {
813
        if (empty($info)) {
6✔
814
            return $info;
×
815
        }
816

817
        foreach ($info['license'] as $key => $value) {
6✔
818
            if (empty($value)) {
6✔
819
                unset($info['license'][$key]);
6✔
820
            }
821
        }
822
        if (empty($info['license'])) {
6✔
823
            unset($info['license']);
6✔
824
        }
825

826
        return $info;
6✔
827
    }
828
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc