Completed
Push — develop ( b6f561...b77323 )
by Neomerx
01:59
created

FluteSettings::getDoNotLogExceptionsList()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
ccs 4
cts 4
cp 1
cc 1
eloc 3
nc 1
nop 0
crap 1
1
<?php namespace Limoncello\Flute\Package;
2
3
use Generator;
4
use Limoncello\Contracts\Settings\SettingsInterface;
5
use Limoncello\Flute\Contracts\Schema\SchemaInterface;
6
use Limoncello\Flute\Contracts\Validation\JsonApiRuleSetInterface;
7
use Limoncello\Flute\Validation\Execution\JsonApiRuleSerializer;
8
use Neomerx\JsonApi\Exceptions\JsonApiException;
9
10
/**
11
 * @package Limoncello\Flute
12
 */
13
abstract class FluteSettings implements SettingsInterface
14
{
15
    /**
16
     * By default it checks that all Schemes have unique resource types. That's a legit case
17
     * to have multiple Schemes for a same resource type however it's more likely that developer
18
     * just forgot to set a unique one. If you do need multiple Schemes for a resource feel free
19
     * to set it to `false`.
20
     *
21
     * @var bool
22
     */
23
    protected $requireUniqueTypes = true;
24
25
    /**
26
     * @return string
27
     */
28
    abstract protected function getSchemesPath(): string;
29
30
    /**
31
     * @return string
32
     */
33
    abstract protected function getRuleSetsPath(): string;
34
35
    /**
36
     * @param string $path
37
     * @param string $implementClassName
38
     *
39
     * @return Generator
40
     */
41
    abstract protected function selectClasses(string $path, string $implementClassName): Generator;
42
43
    /** Config key */
44
    const KEY_DO_NOT_LOG_EXCEPTIONS_LIST__AS_KEYS = 0;
45
46
    /** Config key */
47
    const KEY_HTTP_CODE_FOR_UNEXPECTED_THROWABLE = self::KEY_DO_NOT_LOG_EXCEPTIONS_LIST__AS_KEYS + 1;
48
49
    /** Config key */
50
    const KEY_MODEL_TO_SCHEME_MAP = self::KEY_HTTP_CODE_FOR_UNEXPECTED_THROWABLE + 1;
51
52
    /** Config key */
53
    const KEY_VALIDATION_RULE_SETS_DATA = self::KEY_MODEL_TO_SCHEME_MAP + 1;
54
55
    /** Config key */
56
    const KEY_DEFAULT_PAGING_SIZE = self::KEY_VALIDATION_RULE_SETS_DATA + 1;
57
58
    /** Config key */
59
    const KEY_MAX_PAGING_SIZE = self::KEY_DEFAULT_PAGING_SIZE + 1;
60
61
    /** Config key */
62
    const KEY_JSON_ENCODE_OPTIONS = self::KEY_MAX_PAGING_SIZE + 1;
63
64
    /** Config key */
65
    const KEY_JSON_ENCODE_DEPTH = self::KEY_JSON_ENCODE_OPTIONS + 1;
66
67
    /** Config key */
68
    const KEY_IS_SHOW_VERSION = self::KEY_JSON_ENCODE_DEPTH + 1;
69
70
    /** Config key */
71
    const KEY_META = self::KEY_IS_SHOW_VERSION + 1;
72
73
    /** Config key */
74
    const KEY_URI_PREFIX = self::KEY_META + 1;
75
76
    /** Config key */
77
    const KEY_LAST = self::KEY_URI_PREFIX + 1;
78 29
79
    /**
80 29
     * @return array
81
     */
82
    public function get(): array
83 29
    {
84 29
        $jsonOptions = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_UNESCAPED_SLASHES;
85 29
86 29
        return [
87 29
            static::KEY_DO_NOT_LOG_EXCEPTIONS_LIST__AS_KEYS => array_flip($this->getDoNotLogExceptionsList()),
88 29
            static::KEY_HTTP_CODE_FOR_UNEXPECTED_THROWABLE  => 500,
89 29
            static::KEY_MODEL_TO_SCHEME_MAP                 => $this->createModelToSchemeMap(),
90 29
            static::KEY_VALIDATION_RULE_SETS_DATA           => $this->createRulesSetData(),
91 29
            static::KEY_DEFAULT_PAGING_SIZE                 => 20,
92
            static::KEY_MAX_PAGING_SIZE                     => 100,
93
            static::KEY_JSON_ENCODE_OPTIONS                 => $jsonOptions,
94
            static::KEY_JSON_ENCODE_DEPTH                   => 512,
95
            static::KEY_IS_SHOW_VERSION                     => false,
96
            static::KEY_META                                => null,
97
            static::KEY_URI_PREFIX                          => null,
98 29
        ];
99
    }
100 29
101 29
    /**
102 29
     * @return string[]
103 29
     */
104 29
    protected function getDoNotLogExceptionsList(): array
105 29
    {
106 29
        return [
107
            JsonApiException::class,
108
        ];
109 29
    }
110 29
111
    /**
112 29
     * @return array
113 29
     */
114
    private function createModelToSchemeMap(): array
115
    {
116
        $map   = [];
117
        $types = [];
118
        foreach ($this->selectClasses($this->getSchemesPath(), SchemaInterface::class) as $schemeClass) {
119 29
            assert(
120 29
                is_string($schemeClass) &&
121 29
                class_exists($schemeClass) &&
122
                array_key_exists(SchemaInterface::class, class_implements($schemeClass))
123 29
            );
124
            /** @var SchemaInterface $schemeClass */
125 29
            $modelClass   = $schemeClass::MODEL;
126
            $resourceType = $schemeClass::TYPE;
127
128 29
            assert(is_string($modelClass) === true && empty($modelClass) === false);
129
            assert(is_string($resourceType) === true && empty($resourceType) === false);
130
131
            // By default it checks that all Schemes have unique resource types. That's a legit case
132
            // to have multiple Schemes for a same resource type however it's more likely that developer
133
            // just forgot to set a unique one. If you do need multiple Schemes for a resource feel free
134 29
            // to set to turn off this check.
135
            assert(
136 29
                $this->requireUniqueTypes === false || array_key_exists($resourceType, $types) === false,
137 29
                "Are you sure it's not an error to use resource type `$resourceType` more than once?"
138
            );
139 29
            $types[$resourceType] = true;
140 29
141 29
            $map[$modelClass] = $schemeClass;
142 29
        }
143 29
144
        return $map;
145
    }
146 29
147 29
    /**
148 29
     * @return array
149 29
     */
150 29
    private function createRulesSetData(): array
151 29
    {
152 29
        $serializer = new JsonApiRuleSerializer();
153
        foreach ($this->selectClasses($this->getRuleSetsPath(), JsonApiRuleSetInterface::class) as $setClass) {
154
            /** @var string $setName */
155
            $setName = $setClass;
156 29
            assert(
157
                is_string($setClass) &&
158 29
                class_exists($setClass) &&
159
                array_key_exists(JsonApiRuleSetInterface::class, class_implements($setClass))
160
            );
161
            /** @var JsonApiRuleSetInterface $setClass */
162
            $serializer->addResourceRules(
163
                $setName,
164
                $setClass::getIdRule(),
165
                $setClass::getTypeRule(),
166
                $setClass::getAttributeRules(),
167
                $setClass::getToOneRelationshipRules(),
168
                $setClass::getToManyRelationshipRules()
169
            );
170
        }
171
172
        $ruleSetsData = $serializer->getData();
173
174
        return $ruleSetsData;
175
    }
176
}
177