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

FieldFactory   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 103
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 1
dl 0
loc 103
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A defineField() 0 11 2
A getFieldDefinition() 0 4 1
A get() 0 10 2
B getClassName() 0 20 6
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