Completed
Push — master ( b6f561...db9bd8 )
by Neomerx
03:16
created

configureExceptionHandler()   B

Complexity

Conditions 3
Paths 1

Size

Total Lines 34
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 34
ccs 19
cts 19
cp 1
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 21
nc 1
nop 1
crap 3
1
<?php namespace Limoncello\Flute\Package;
2
3
use Doctrine\DBAL\Types\Type;
4
use Limoncello\Contracts\Application\ApplicationSettingsInterface as A;
5
use Limoncello\Contracts\Application\ContainerConfiguratorInterface;
6
use Limoncello\Contracts\Container\ContainerInterface as LimoncelloContainerInterface;
7
use Limoncello\Contracts\Data\ModelSchemeInfoInterface;
8
use Limoncello\Contracts\Exceptions\ThrowableHandlerInterface;
9
use Limoncello\Contracts\Settings\SettingsProviderInterface;
10
use Limoncello\Flute\Adapters\PaginationStrategy;
11
use Limoncello\Flute\Contracts\Adapters\PaginationStrategyInterface;
12
use Limoncello\Flute\Contracts\Encoder\EncoderInterface;
13
use Limoncello\Flute\Contracts\FactoryInterface;
14
use Limoncello\Flute\Contracts\Http\Query\ParametersMapperInterface;
15
use Limoncello\Flute\Contracts\Http\Query\QueryParserInterface;
16
use Limoncello\Flute\Contracts\Schema\JsonSchemesInterface;
17
use Limoncello\Flute\Contracts\Validation\JsonApiValidatorFactoryInterface;
18
use Limoncello\Flute\Factory;
19
use Limoncello\Flute\Http\Query\ParametersMapper;
20
use Limoncello\Flute\Http\Query\QueryParser;
21
use Limoncello\Flute\Http\ThrowableHandlers\FluteThrowableHandler;
22
use Limoncello\Flute\Types\DateJsonApiStringType;
23
use Limoncello\Flute\Types\DateTimeJsonApiStringType;
24
use Limoncello\Flute\Types\JsonApiDateTimeType;
25
use Limoncello\Flute\Types\JsonApiDateType;
26
use Limoncello\Flute\Validation\Execution\JsonApiValidatorFactory;
27
use Neomerx\JsonApi\Encoder\EncoderOptions;
28
use Psr\Container\ContainerInterface as PsrContainerInterface;
29
use Psr\Log\LoggerInterface;
30
31
/**
32
 * @package Limoncello\Flute
33
 *
34
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
35
 */
36
class FluteContainerConfigurator implements ContainerConfiguratorInterface
37
{
38
    /** @var callable */
39
    const CONFIGURE_EXCEPTION_HANDLER = [self::class, 'configureExceptionHandler'];
40
41
    /**
42
     * @inheritdoc
43
     *
44
     * @SuppressWarnings(PHPMD.StaticAccess)
45
     */
46 1
    public static function configureContainer(LimoncelloContainerInterface $container): void
47
    {
48 1
        $factory = new Factory($container);
49
50 1
        $container[FactoryInterface::class] = $factory;
51
52 1
        $container[JsonSchemesInterface::class] = function (PsrContainerInterface $container) use ($factory) {
53 1
            $settings     = $container->get(SettingsProviderInterface::class)->get(FluteSettings::class);
54 1
            $modelSchemes = $container->get(ModelSchemeInfoInterface::class);
55
56 1
            return $factory->createJsonSchemes($settings[FluteSettings::KEY_MODEL_TO_SCHEME_MAP], $modelSchemes);
57
        };
58
59 1
        $container[QueryParserInterface::class] = function (PsrContainerInterface $container) {
60 1
            return new QueryParser($container->get(PaginationStrategyInterface::class));
61
        };
62
63 1
        $container[ParametersMapperInterface::class] = function (PsrContainerInterface $container) {
64 1
            return new ParametersMapper($container->get(JsonSchemesInterface::class));
65
        };
66
67 1
        $container[EncoderInterface::class] = function (PsrContainerInterface $container) use ($factory) {
68
            /** @var JsonSchemesInterface $jsonSchemes */
69 1
            $jsonSchemes = $container->get(JsonSchemesInterface::class);
70 1
            $settings    = $container->get(SettingsProviderInterface::class)->get(FluteSettings::class);
71 1
            $encoder     = $factory->createEncoder($jsonSchemes, new EncoderOptions(
72 1
                $settings[FluteSettings::KEY_JSON_ENCODE_OPTIONS],
73 1
                $settings[FluteSettings::KEY_URI_PREFIX],
74 1
                $settings[FluteSettings::KEY_JSON_ENCODE_DEPTH]
75
            ));
76 1
            isset($settings[FluteSettings::KEY_META]) ? $encoder->withMeta($settings[FluteSettings::KEY_META]) : null;
77 1
            ($settings[FluteSettings::KEY_IS_SHOW_VERSION] ?? false) ? $encoder->withJsonApiVersion() : null;
78
79 1
            return $encoder;
80
        };
81
82 1
        $container[PaginationStrategyInterface::class] = function (PsrContainerInterface $container) {
83 1
            $settings = $container->get(SettingsProviderInterface::class)->get(FluteSettings::class);
84
85 1
            return new PaginationStrategy(
86 1
                $settings[FluteSettings::KEY_DEFAULT_PAGING_SIZE],
87 1
                $settings[FluteSettings::KEY_MAX_PAGING_SIZE]
88
            );
89
        };
90
91 1
        $container[JsonApiValidatorFactoryInterface::class] = function (PsrContainerInterface $container) {
92 1
            $factory = new JsonApiValidatorFactory($container);
93
94 1
            return $factory;
95
        };
96
97
        // register date/date time types
98 1
        if (Type::hasType(DateTimeJsonApiStringType::NAME) === false) {
99 1
            Type::addType(DateTimeJsonApiStringType::NAME, DateTimeJsonApiStringType::class);
100
        }
101 1
        if (Type::hasType(DateJsonApiStringType::NAME) === false) {
102 1
            Type::addType(DateJsonApiStringType::NAME, DateJsonApiStringType::class);
103
        }
104 1
        if (Type::hasType(JsonApiDateTimeType::NAME) === false) {
105 1
            Type::addType(JsonApiDateTimeType::NAME, JsonApiDateTimeType::class);
106
        }
107 1
        if (Type::hasType(JsonApiDateType::NAME) === false) {
108 1
            Type::addType(JsonApiDateType::NAME, JsonApiDateType::class);
109
        }
110
    }
111
112
    /**
113
     * @param LimoncelloContainerInterface $container
114
     *
115
     * @return void
116
     */
117
    public static function configureExceptionHandler(LimoncelloContainerInterface $container)
118
    {
119 1
        $container[ThrowableHandlerInterface::class] = function (PsrContainerInterface $container) {
120 1
            $appSettings   = $container->get(SettingsProviderInterface::class)->get(A::class);
121 1
            $fluteSettings = $container->get(SettingsProviderInterface::class)->get(FluteSettings::class);
122
123 1
            $isLogEnabled = $appSettings[A::KEY_IS_LOG_ENABLED];
124 1
            $isDebug      = $appSettings[A::KEY_IS_DEBUG];
125
126 1
            $ignoredErrorClasses = $fluteSettings[FluteSettings::KEY_DO_NOT_LOG_EXCEPTIONS_LIST__AS_KEYS];
127 1
            $codeForUnexpected   = $fluteSettings[FluteSettings::KEY_HTTP_CODE_FOR_UNEXPECTED_THROWABLE];
128
            $throwableConverter  =
129 1
                $fluteSettings[FluteSettings::KEY_THROWABLE_TO_JSON_API_EXCEPTION_CONVERTER] ?? null;
130
131
            /** @var EncoderInterface $encoder */
132 1
            $encoder = $container->get(EncoderInterface::class);
133
134 1
            $handler = new FluteThrowableHandler(
135 1
                $encoder,
136 1
                $ignoredErrorClasses,
137 1
                $codeForUnexpected,
138 1
                $isDebug,
139 1
                $throwableConverter
140
            );
141
142 1
            if ($isLogEnabled === true && $container->has(LoggerInterface::class) === true) {
143
                /** @var LoggerInterface $logger */
144 1
                $logger = $container->get(LoggerInterface::class);
145 1
                $handler->setLogger($logger);
146
            }
147
148 1
            return $handler;
149
        };
150
    }
151
}
152