Completed
Push — develop ( dcfc04...3d10a6 )
by Neomerx
04:33
created

FluteContainerConfigurator   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 10

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 8
lcom 0
cbo 10
dl 0
loc 117
ccs 0
cts 64
cp 0
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B configureContainer() 0 59 5
A configureExceptionHandler() 0 36 3
1
<?php namespace Limoncello\Flute\Package;
2
3
use Doctrine\DBAL\DBALException;
4
use Doctrine\DBAL\Types\Type;
5
use Limoncello\Contracts\Application\ApplicationConfigurationInterface as A;
6
use Limoncello\Contracts\Application\CacheSettingsProviderInterface;
7
use Limoncello\Contracts\Application\ContainerConfiguratorInterface;
8
use Limoncello\Contracts\Container\ContainerInterface as LimoncelloContainerInterface;
9
use Limoncello\Contracts\Data\ModelSchemaInfoInterface;
10
use Limoncello\Contracts\Exceptions\ThrowableHandlerInterface;
11
use Limoncello\Contracts\Settings\SettingsProviderInterface;
12
use Limoncello\Flute\Api\BasicRelationshipPaginationStrategy;
13
use Limoncello\Flute\Contracts\Api\RelationshipPaginationStrategyInterface;
14
use Limoncello\Flute\Contracts\Encoder\EncoderInterface;
15
use Limoncello\Flute\Contracts\FactoryInterface;
16
use Limoncello\Flute\Contracts\Http\Query\ParametersMapperInterface;
17
use Limoncello\Flute\Contracts\Schema\JsonSchemasInterface;
18
use Limoncello\Flute\Contracts\Validation\FormValidatorFactoryInterface;
19
use Limoncello\Flute\Contracts\Validation\JsonApiParserFactoryInterface;
20
use Limoncello\Flute\Factory;
21
use Limoncello\Flute\Http\Query\ParametersMapper;
22
use Limoncello\Flute\Http\ThrowableHandlers\FluteThrowableHandler;
23
use Limoncello\Flute\Types\DateTimeType;
24
use Limoncello\Flute\Types\DateType;
25
use Limoncello\Flute\Validation\Form\Execution\FormValidatorFactory;
26
use Limoncello\Flute\Validation\JsonApi\Execution\JsonApiParserFactory;
27
use Psr\Container\ContainerInterface as PsrContainerInterface;
28
use Psr\Log\LoggerInterface;
29
30
/**
31
 * @package Limoncello\Flute
32
 *
33
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
34
 */
35
class FluteContainerConfigurator implements ContainerConfiguratorInterface
36
{
37
    /** @var callable */
38
    const CONFIGURATOR = [self::class, self::CONTAINER_METHOD_NAME];
39
40
    /** @var callable */
41
    const CONFIGURE_EXCEPTION_HANDLER = [self::class, 'configureExceptionHandler'];
42
43
    /**
44
     * @inheritdoc
45
     *
46
     * @throws DBALException
47
     *
48
     * @SuppressWarnings(PHPMD.StaticAccess)
49
     */
50
    public static function configureContainer(LimoncelloContainerInterface $container): void
51
    {
52
        $factory = new Factory($container);
53
54
        $container[FactoryInterface::class] = $factory;
55
56
        $container[JsonSchemasInterface::class] = function (PsrContainerInterface $container) use ($factory) {
57
            $settings     = $container->get(SettingsProviderInterface::class)->get(FluteSettings::class);
58
            $modelSchemas = $container->get(ModelSchemaInfoInterface::class);
59
60
            return $factory->createJsonSchemas(
61
                $settings[FluteSettings::KEY_MODEL_TO_SCHEMA_MAP],
62
                $settings[FluteSettings::KEY_TYPE_TO_SCHEMA_MAP],
63
                $modelSchemas
64
            );
65
        };
66
67
        $container[ParametersMapperInterface::class] = function (PsrContainerInterface $container) {
68
            return new ParametersMapper($container->get(JsonSchemasInterface::class));
69
        };
70
71
        $container[EncoderInterface::class] = function (PsrContainerInterface $container) use ($factory) {
72
            /** @var JsonSchemasInterface $jsonSchemas */
73
            $jsonSchemas = $container->get(JsonSchemasInterface::class);
74
            $settings    = $container->get(SettingsProviderInterface::class)->get(FluteSettings::class);
75
            $encoder     = $factory
76
                ->createEncoder($jsonSchemas)
77
                ->withEncodeOptions($settings[FluteSettings::KEY_JSON_ENCODE_OPTIONS])
78
                ->withEncodeDepth($settings[FluteSettings::KEY_JSON_ENCODE_DEPTH])
79
                ->withUrlPrefix($settings[FluteSettings::KEY_URI_PREFIX]);
80
            isset($settings[FluteSettings::KEY_META]) ? $encoder->withMeta($settings[FluteSettings::KEY_META]) : null;
81
            ($settings[FluteSettings::KEY_IS_SHOW_VERSION] ?? false) ?
82
                $encoder->withJsonApiVersion(FluteSettings::DEFAULT_JSON_API_VERSION) : null;
83
84
            return $encoder;
85
        };
86
87
        $container[RelationshipPaginationStrategyInterface::class] = function (PsrContainerInterface $container) {
88
            $settings = $container->get(SettingsProviderInterface::class)->get(FluteSettings::class);
89
90
            return new BasicRelationshipPaginationStrategy($settings[FluteSettings::KEY_DEFAULT_PAGING_SIZE]);
91
        };
92
93
        $container[JsonApiParserFactoryInterface::class] = function (PsrContainerInterface $container) {
94
            $factory = new JsonApiParserFactory($container);
95
96
            return $factory;
97
        };
98
99
        $container[FormValidatorFactoryInterface::class] = function (PsrContainerInterface $container) {
100
            $factory = new FormValidatorFactory($container);
101
102
            return $factory;
103
        };
104
105
        // register date/date time types
106
        Type::hasType(DateTimeType::NAME) === true ?: Type::addType(DateTimeType::NAME, DateTimeType::class);
107
        Type::hasType(DateType::NAME) === true ?: Type::addType(DateType::NAME, DateType::class);
108
    }
109
110
    /**
111
     * @param LimoncelloContainerInterface $container
112
     *
113
     * @return void
114
     */
115
    public static function configureExceptionHandler(LimoncelloContainerInterface $container)
116
    {
117
        $container[ThrowableHandlerInterface::class] = function (PsrContainerInterface $container) {
118
            /** @var CacheSettingsProviderInterface $provider */
119
            $provider      = $container->get(CacheSettingsProviderInterface::class);
120
            $appConfig     = $provider->getApplicationConfiguration();
121
            $fluteSettings = $provider->get(FluteSettings::class);
122
123
            $isLogEnabled = $appConfig[A::KEY_IS_LOG_ENABLED];
124
            $isDebug      = $appConfig[A::KEY_IS_DEBUG];
125
126
            $ignoredErrorClasses = $fluteSettings[FluteSettings::KEY_DO_NOT_LOG_EXCEPTIONS_LIST__AS_KEYS];
127
            $codeForUnexpected   = $fluteSettings[FluteSettings::KEY_HTTP_CODE_FOR_UNEXPECTED_THROWABLE];
128
            $throwableConverter  =
129
                $fluteSettings[FluteSettings::KEY_THROWABLE_TO_JSON_API_EXCEPTION_CONVERTER] ?? null;
130
131
            /** @var EncoderInterface $encoder */
132
            $encoder = $container->get(EncoderInterface::class);
133
134
            $handler = new FluteThrowableHandler(
135
                $encoder,
136
                $ignoredErrorClasses,
137
                $codeForUnexpected,
138
                $isDebug,
139
                $throwableConverter
140
            );
141
142
            if ($isLogEnabled === true && $container->has(LoggerInterface::class) === true) {
143
                /** @var LoggerInterface $logger */
144
                $logger = $container->get(LoggerInterface::class);
145
                $handler->setLogger($logger);
146
            }
147
148
            return $handler;
149
        };
150
    }
151
}
152