Completed
Pull Request — master (#54)
by Frank
03:15
created

YamlDefinitionLoader::loadEvents()   A

Complexity

Conditions 6
Paths 10

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 6

Importance

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