Passed
Push — master ( 80001a...1201cf )
by
unknown
03:47
created

ApieConfigResolver   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 55
dl 0
loc 81
rs 10
c 1
b 0
f 0
wmc 12

4 Methods

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