Completed
Branch 7-dev (bf2895)
by Oscar
03:53
created

FieldFactory::getClassName()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 8.9777
c 0
b 0
f 0
cc 6
nc 7
nop 2
1
<?php
2
declare(strict_types = 1);
3
4
namespace SimpleCrud;
5
6
use SimpleCrud\Fields\Boolean;
7
use SimpleCrud\Fields\Date;
8
use SimpleCrud\Fields\Datetime;
9
use SimpleCrud\Fields\Decimal;
10
use SimpleCrud\Fields\Field;
11
use SimpleCrud\Fields\FieldInterface;
12
use SimpleCrud\Fields\Integer;
13
use SimpleCrud\Fields\Json;
14
use SimpleCrud\Fields\Point;
15
use SimpleCrud\Fields\Set;
16
17
/**
18
 * Class to create instances of fields.
19
 */
20
final class FieldFactory implements FieldFactoryInterface
21
{
22
    private $defaultType = Field::class;
23
    private $fields = [
24
        Integer::class => [
25
            'names' => ['id'],
26
            'regex' => ['/_id$/'],
27
            'types' => ['bigint', 'int', 'mediumint', 'smallint', 'tinyint', 'year'],
28
        ],
29
        Boolean::class => [
30
            'names' => ['active'],
31
            'regex' => ['/^(is|has)[A-Z]/'],
32
            'types' => ['boolean'],
33
        ],
34
        Datetime::class => [
35
            'names' => ['pubdate'],
36
            'regex' => ['/[a-z]At$/'],
37
            'types' => ['datetime'],
38
        ],
39
        Date::class => [
40
            'names' => [],
41
            'regex' => [],
42
            'types' => ['date'],
43
        ],
44
        Decimal::class => [
45
            'names' => [],
46
            'regex' => [],
47
            'types' => ['decimal', 'float', 'real'],
48
        ],
49
        Set::class => [
50
            'names' => [],
51
            'regex' => [],
52
            'types' => ['set'],
53
        ],
54
        Point::class => [
55
            'names' => [],
56
            'regex' => [],
57
            'types' => ['point'],
58
        ],
59
        Json::class => [
60
            'names' => [],
61
            'regex' => [],
62
            'types' => ['json'],
63
        ],
64
    ];
65
66
    public function defineField(string $className, array $definition): self
67
    {
68
        if (isset($this->fields[$className])) {
69
            $this->fields[$className] = $definition;
70
            return $this;
71
        }
72
73
        $this->fields = [$className => $values] + $this->fields;
0 ignored issues
show
Bug introduced by
The variable $values does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
74
75
        return $this;
76
    }
77
78
    public function getFieldDefinition(string $className): ?array
79
    {
80
        return $this->fields[$className] ?? null;
81
    }
82
83
    /**
84
     * @see FieldFactoryInterface
85
     *
86
     * {@inheritdoc}
87
     */
88
    public function get(Table $table, array $info): FieldInterface
89
    {
90
        $className = $this->getClassName($info['name'], $info['type']);
91
92
        if (class_exists($className)) {
93
            return new $className($table, $info);
94
        }
95
96
        throw new SimpleCrudException("No field class found for '{$className}'");
97
    }
98
99
    /**
100
     * Get the field class name.
101
     */
102
    private function getClassName(string $name, string $type): ?string
103
    {
104
        foreach ($this->fields as $className => $definition) {
105
            if (in_array($name, $definition['names'])) {
106
                return $className;
107
            }
108
109
            foreach ($definition['regex'] as $regex) {
110
                if (preg_match($regex, $name)) {
111
                    return $className;
112
                }
113
            }
114
115
            if (in_array($type, $definition['types'])) {
116
                return $className;
117
            }
118
        }
119
120
        return $this->defaultType;
121
    }
122
}
123