Passed
Push — master ( c5bd37...640ffc )
by
unknown
05:22
created

ApieConfigResolver::createResolver()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 48
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 38
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 48
rs 9.312
1
<?php
2
namespace W2w\Laravel\Apie\Providers;
3
4
use Illuminate\Auth\Access\AuthorizationException;
5
use Illuminate\Auth\AuthenticationException;
6
use Illuminate\Contracts\Cache\LockTimeoutException;
7
use Illuminate\Contracts\Filesystem\FileNotFoundException;
8
use Illuminate\Contracts\Redis\LimiterTimeoutException;
9
use PDOException;
10
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
11
use Symfony\Component\OptionsResolver\Options;
12
use Symfony\Component\OptionsResolver\OptionsResolver;
13
use Symfony\Component\Serializer\Exception\RuntimeException;
14
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
15
use W2w\Lib\Apie\Annotations\ApiResource;
16
use W2w\Lib\Apie\Resources\ApiResourcesInterface;
0 ignored issues
show
Bug introduced by
The type W2w\Lib\Apie\Resources\ApiResourcesInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
18
class ApieConfigResolver
19
{
20
    private static $configResolver;
21
22
    public static function resolveConfig(array $config)
23
    {
24
        $resolver = self::getResolver();
25
        return $resolver->resolve($config);
26
    }
27
28
    private static function getResolver(): OptionsResolver
29
    {
30
        if (!self::$configResolver) {
31
            self::$configResolver = self::createResolver(require __DIR__ . '/../../config/apie.php');
32
        }
33
        return self::$configResolver;
34
    }
35
36
    private static function createResolver(array $defaults): OptionsResolver
37
    {
38
        $resolver = new OptionsResolver();
39
40
        $resolver->setDefaults($defaults)
41
                 ->setAllowedTypes('resources', ['string[]', ApiResourcesInterface::class])
42
                 ->setAllowedTypes('plugins', ['string[]'])
43
                 ->setAllowedTypes('resources-service', ['null', 'string'])
44
                 ->setAllowedTypes('mock', ['null', 'bool'])
45
                 ->setAllowedTypes('mock-skipped-resources', ['string[]'])
46
                 ->setAllowedTypes('base-url', 'string')
47
                 ->setAllowedTypes('api-url', 'string')
48
                 ->setAllowedTypes('disable-routes', ['null', 'bool'])
49
                 ->setAllowedTypes('swagger-ui-test-page', ['null', 'string'])
50
                 ->setAllowedTypes('apie-middleware', 'string[]')
51
                 ->setAllowedTypes('swagger-ui-test-page-middleware', 'string[]')
52
                 ->setAllowedTypes('bind-api-resource-facade-response', 'bool')
53
                 ->setAllowedTypes('metadata', 'string[]')
54
                 ->setAllowedTypes('resource-config', [ApiResource::class . '[]', 'array[]'])
55
                 ->setAllowedTypes('exception-mapping', 'int[]');
56
        $resolver->setDefault('metadata', function (OptionsResolver $metadataResolver) use (&$defaults) {
57
            $metadataResolver->setDefaults($defaults['metadata']);
58
59
            $urlNormalizer = function (Options $options, $value) {
60
                if (empty($value)) {
61
                    return '';
62
                }
63
                return self::urlNormalize($value);
64
            };
65
            $metadataResolver->setNormalizer('terms-of-service', $urlNormalizer);
66
            $metadataResolver->setNormalizer('license-url', $urlNormalizer);
67
            $metadataResolver->setNormalizer('contact-url', $urlNormalizer);
68
        });
69
        $resolver->setNormalizer('resource-config', function (Options $options, $value) {
70
            return array_map(function ($field) {
71
                return $field instanceof ApiResource ? $field : ApiResource::createFromArray($field);
72
            }, $value);
73
        });
74
        $resolver->setNormalizer('contexts', function (Options $options, $value) use (&$defaults) {
75
            return array_map(function ($field) use ($defaults) {
76
                return self::createResolver($defaults)->resolve($field);
77
            }, $value);
78
        });
79
        $resolver->setNormalizer('exception-mapping', function (Options $options, $value) {
80
            ApieConfigResolver::addExceptionsForExceptionMapping($value);
81
            return $value;
82
        });
83
        return $resolver;
84
    }
85
86
    public static function addExceptionsForExceptionMapping(array& $array)
87
    {
88
        $array[AuthorizationException::class] = 403;
89
        $array[AuthenticationException::class] = 401;
90
        $array[UnexpectedValueException::class] = 415;
91
        $array[RuntimeException::class] = 415;
92
        $array[LockTimeoutException::class] = 502;
93
        $array[LimiterTimeoutException::class] = 502;
94
        $array[FileNotFoundException::class] = 502;
95
        $array[PDOException::class] = 502;
96
        return $array;
97
    }
98
99
    private static function urlNormalize($value)
100
    {
101
        if ('http://' !== substr($value, 0, 7) && 'https://' !== substr($value, 0, 8)) {
102
            $value = 'https://' . $value;
103
        }
104
        $parsedUrl = parse_url($value);
105
        if (empty($parsedUrl) || !in_array($parsedUrl['scheme'], ['http', 'https']) || !filter_var($value, FILTER_VALIDATE_URL)) {
106
            throw new InvalidOptionsException('"' . $value . '" is not a valid url');
107
        }
108
109
        return $value;
110
    }
111
}
112