Passed
Pull Request — master (#54)
by Frank
01:53
created

YamlDefinitionLoader::loadTypeHandlers()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 7
c 1
b 0
f 0
nc 9
nop 2
dl 0
loc 13
ccs 8
cts 8
cp 1
crap 5
rs 9.6111
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EventSauce\EventSourcing\CodeGeneration;
6
7
use InvalidArgumentException;
8
use function is_array;
9
use Symfony\Component\Yaml\Yaml;
10
use const PATHINFO_EXTENSION;
11
use function file_get_contents;
12
use function in_array;
13
use function is_string;
14
use function pathinfo;
15
16
class YamlDefinitionLoader implements DefinitionLoader
17
{
18 1
    public function canLoad(string $filename): bool
19
    {
20 1
        return in_array(pathinfo($filename, PATHINFO_EXTENSION), ['yaml', 'yml']);
21
    }
22
23 6
    public function load(string $filename, DefinitionGroup $definitionGroup = null): DefinitionGroup
24
    {
25 6
        /** @var string|bool $fileContents */
26
        $fileContents = file_get_contents($filename);
27 6
28 1
        if ( ! is_string($fileContents) || empty($fileContents)) {
29
            throw new InvalidArgumentException("File {$filename} does not contain anything");
30
        }
31 5
32
        $definition = Yaml::parse($fileContents);
33 5
34 1
        if ( ! is_array($definition)) {
35
            throw new InvalidArgumentException('The definition is incorrectly formatted');
36
        }
37 4
38
        $definitionGroup = $definitionGroup ?: new DefinitionGroup();
39 4
40 3
        if (isset($definition['namespace'])) {
41
            $definitionGroup->withNamespace($definition['namespace']);
42
        }
43 4
44 4
        $this->loadTypeHandlers($definitionGroup, $definition['types'] ?? []);
45 4
        $this->loadFieldDefaults($definitionGroup, $definition['fields'] ?? []);
46 4
        $this->loadCommands($definitionGroup, $definition['commands'] ?? []);
47
        $this->loadEvents($definitionGroup, $definition['events'] ?? []);
48 4
49
        return $definitionGroup;
50
    }
51 4
52
    private function loadTypeHandlers(DefinitionGroup $definitionGroup, array $types)
53 4
    {
54 1
        foreach ($types as $type => $handlers) {
55 1
            if (isset($handlers['type'])) {
56
                $definitionGroup->aliasType($type, $handlers['type']);
57
            }
58 1
59 1
            if (isset($handlers['serializer'])) {
60
                $definitionGroup->typeSerializer($type, $handlers['serializer']);
61
            }
62 1
63 1
            if (isset($handlers['deserializer'])) {
64
                $definitionGroup->typeDeserializer($type, $handlers['deserializer']);
65
            }
66 4
        }
67
    }
68 4
69
    private function loadCommands(DefinitionGroup $definitionGroup, array $commands)
70 4
    {
71 4
        foreach ($commands as $commandName => $commandDefinition) {
72 4
            $fields = $commandDefinition['fields'] ?? [];
73 4
            $command = $definitionGroup->command($commandName);
74
            $command->withFieldsFrom($commandDefinition['fields_from'] ?? '');
75 4
76 3
            foreach ($fields as $fieldName => $fieldDefinition) {
77 1
                if (is_string($fieldDefinition)) {
78
                    $fieldDefinition = ['type' => $fieldDefinition];
79
                }
80 3
81 3
                $type = $fieldDefinition['type'] ?? $definitionGroup->typeForField($fieldName);
82
                $command->field($fieldName, TypeNormalizer::normalize($type), $fieldDefinition['example'] ?? null);
83 3
84 1
                if (isset($fieldDefinition['serializer'])) {
85
                    $command->fieldSerializer($fieldName, $fieldDefinition['serializer']);
86
                }
87 3
88 1
                if (isset($fieldDefinition['deserializer'])) {
89
                    $command->fieldDeserializer($fieldName, $fieldDefinition['deserializer']);
90
                }
91
            }
92 4
        }
93
    }
94 4
95
    private function loadEvents(DefinitionGroup $definitionGroup, array $events)
96 4
    {
97 3
        foreach ($events as $eventName => $eventDefinition) {
98 3
            $event = $definitionGroup->event($eventName);
99 3
            $event->withFieldsFrom($eventDefinition['fields_from'] ?? '');
100
            $fields = $eventDefinition['fields'] ?? [];
101 3
102 3
            foreach ($fields as $fieldName => $fieldDefinition) {
103 1
                if (is_string($fieldDefinition)) {
104
                    $fieldDefinition = ['type' => TypeNormalizer::normalize($fieldDefinition)];
105
                }
106 3
107 3
                $type = $fieldDefinition['type'] ?? $definitionGroup->typeForField($fieldName);
108
                $event->field($fieldName, TypeNormalizer::normalize($type), (string) ($fieldDefinition['example'] ?? null));
109 3
110 1
                if (isset($fieldDefinition['serializer'])) {
111
                    $event->fieldSerializer($fieldName, $fieldDefinition['serializer']);
112
                }
113 3
114 1
                if (isset($fieldDefinition['deserializer'])) {
115
                    $event->fieldDeserializer($fieldName, $fieldDefinition['deserializer']);
116
                }
117
            }
118 4
        }
119
    }
120 4
121
    private function loadFieldDefaults(DefinitionGroup $definitionGroup, array $defaults)
122 4
    {
123 1
        foreach ($defaults as $field => $default) {
124
            $definitionGroup->fieldDefault($field, $default['type'], $default['example'] ?? null);
125 1
126 1
            if (isset($default['serializer'])) {
127
                $definitionGroup->fieldSerializer($field, $default['serializer']);
128
            }
129 1
130 1
            if (isset($default['deserializer'])) {
131
                $definitionGroup->fieldDeserializer($field, $default['deserializer']);
132
            }
133 4
        }
134
    }
135
}
136