Completed
Push — develop ( 562875...7cd02c )
by Freddie
03:25
created

Schema::fkRelations()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 10
nc 1
nop 0
dl 0
loc 19
ccs 12
cts 12
cp 1
crap 2
rs 9.9332
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of FlexPHP.
4
 *
5
 * (c) Freddie Gar <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace FlexPHP\Schema;
11
12
use FlexPHP\Schema\Constants\Keyword;
13
use FlexPHP\Schema\Exception\InvalidFileSchemaException;
14
use FlexPHP\Schema\Exception\InvalidSchemaException;
15
use Symfony\Component\Yaml\Exception\ParseException;
16
use Symfony\Component\Yaml\Yaml;
17
18
final class Schema implements SchemaInterface
19
{
20
    /**
21
     * @var string
22
     */
23
    private $name;
24
25
    /**
26
     * @var string
27
     */
28
    private $title;
29
30
    /**
31
     * @var array<int,SchemaAttributeInterface>
32
     */
33
    private $attributes;
34
35
    /**
36
     * @var null|string
37
     */
38
    private $icon;
39
40
    /**
41
     * @var string
42
     */
43
    private $language;
44
45 11
    public static function fromArray(array $schema): SchemaInterface
46
    {
47
        /** @var string $name */
48 11
        $name = \key($schema) ?? '';
49 11
        $title = $schema[$name][Keyword::TITLE] ?? '';
50 11
        $attributes = $schema[$name][Keyword::ATTRIBUTES] ?? [];
51 11
        $icon = $schema[$name][Keyword::ICON] ?? null;
52 11
        $language = $schema[$name][Keyword::LANGUAGE] ?? null;
53
54 11
        return new self($name, $title, $attributes, $icon, $language);
55
    }
56
57 3
    public static function fromFile(string $schemafile): SchemaInterface
58
    {
59
        try {
60 3
            $yaml = new Yaml();
61 3
            $schema = $yaml->parseFile($schemafile);
62 1
        } catch (ParseException $e) {
63 1
            throw new InvalidFileSchemaException();
64
        }
65
66 2
        return self::fromArray($schema);
67
    }
68
69 17
    public function __construct(
70
        string $name,
71
        string $title,
72
        array $attributes,
73
        ?string $icon = null,
74
        ?string $language = null
75
    ) {
76 17
        $this->setName($name);
77 13
        $this->setTitle($title);
78 8
        $this->setAttributes($attributes);
79 6
        $this->setIcon($icon);
80 6
        $this->setLanguage($language);
81 6
    }
82
83 8
    public function name(): string
84
    {
85 8
        return $this->name;
86
    }
87
88 3
    public function title(): string
89
    {
90 3
        return $this->title;
91
    }
92
93 3
    public function attributes(): array
94
    {
95 3
        return $this->attributes;
96
    }
97
98 2
    public function icon(): ?string
99
    {
100 2
        return $this->icon;
101
    }
102
103 2
    public function language(): string
104
    {
105 2
        return $this->language;
106
    }
107
108 3
    public function pkName(): string
109
    {
110 3
        $pkName = 'id';
111
112
        \array_filter($this->attributes(), function (SchemaAttributeInterface $property) use (&$pkName) {
113 3
            if ($property->isPk()) {
114 2
                $pkName = $property->name();
115
            }
116
117 3
            return true;
118 3
        });
119
120 3
        return $pkName;
121
    }
122
123 2
    public function pkTypeHint(): string
124
    {
125 2
        $pkTypeHint = 'string';
126
127
        \array_filter($this->attributes(), function (SchemaAttributeInterface $property) use (&$pkTypeHint) {
128 2
            if ($property->isPk()) {
129 2
                $pkTypeHint = $property->typeHint();
130
            }
131
132 2
            return true;
133 2
        });
134
135 2
        return $pkTypeHint;
136
    }
137
138 2
    public function fkRelations(): array
139
    {
140 2
        $fkRelations = \array_reduce(
141 2
            $this->attributes(),
142
            function (array $result, SchemaAttributeInterface $property): array {
143 2
                if ($property->isfk()) {
144 2
                    $result[$property->name()] = [
145 2
                        'table' => $property->fkTable(),
146 2
                        'id' => $property->fkId(),
147 2
                        'name' => $property->fkName(),
148
                    ];
149
                }
150
151 2
                return $result;
152 2
            },
153 2
            []
154
        );
155
156 2
        return $fkRelations;
157
    }
158
159 17
    private function setName(string $name): void
160
    {
161 17
        if (empty(\trim($name))) {
162 4
            throw new InvalidSchemaException('Schema name is required');
163
        }
164
165 13
        $this->name = $name;
166 13
    }
167
168 13
    private function setTitle(string $title): void
169
    {
170 13
        if (empty(\trim($title))) {
171 5
            throw new InvalidSchemaException(\sprintf('Schema %s:title is required', $this->name()));
172
        }
173
174 8
        $this->title = $title;
175 8
    }
176
177 8
    private function setAttributes(array $attributes): void
178
    {
179 8
        $schemaAttributes = [];
180
181 8
        foreach ($attributes as $attribute) {
182 5
            $name = $attribute[Keyword::NAME] ?? '';
183 5
            $dataType = $attribute[Keyword::DATATYPE] ?? '';
184 5
            $constraints = $attribute[Keyword::CONSTRAINTS] ?? '';
185
186 5
            $schemaAttributes[] = new SchemaAttribute($name, $dataType, $constraints);
187
        }
188
189 6
        $this->attributes = $schemaAttributes;
190 6
    }
191
192 6
    private function setIcon(?string $icon): void
193
    {
194 6
        $this->icon = $icon;
195 6
    }
196
197 6
    private function setLanguage(?string $language): void
198
    {
199 6
        if (empty($language)) {
200 6
            $language = 'en';
201
        }
202
203 6
        $this->language = $language;
204 6
    }
205
}
206