Completed
Push — master ( 7ed859...0d1801 )
by Oscar
02:48
created

FieldFactory::getClass()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 19
rs 8.8571
cc 5
eloc 10
nc 9
nop 1
1
<?php
2
3
namespace SimpleCrud;
4
5
/**
6
 * Class to create instances of fields.
7
 */
8
class FieldFactory implements FieldFactoryInterface
9
{
10
    protected $cachedTypes = [];
11
    protected $namespaces = ['SimpleCrud\\Fields\\'];
12
    protected $defaultType = 'SimpleCrud\\Fields\\Field';
13
    protected $smartTypes = [
14
        'Decimal' => ['float'],
15
    ];
16
    protected $smartNames = [
17
        'Boolean' => ['active'],
18
        'Datetime' => ['pubdate'],
19
        'Integer' => ['id'],
20
    ];
21
22
    /**
23
     * Set the namespace for the fields classes.
24
     *
25
     * @param string $namespace
26
     *
27
     * @return self
28
     */
29
    public function addNamespace($namespace)
30
    {
31
        array_unshift($this->namespaces, $namespace);
32
33
        return $this;
34
    }
35
36
    /**
37
     * Set new smart names.
38
     *
39
     * @param string $name
40
     * @param string $type
41
     *
42
     * @return self
43
     */
44
    public function addSmartName($name, $type)
45
    {
46
        if (!isset($this->smartNames[$type])) {
47
            $this->smartNames[$type] = [$name];
48
        } else {
49
            $this->smartNames[$type][] = $name;
50
        }
51
52
        return $this;
53
    }
54
55
    /**
56
     * @see FieldFactoryInterface
57
     *
58
     * {@inheritdoc}
59
     */
60
    public function get($name, $type = null)
61
    {
62
        try {
63
            if (($smartType = $this->getTypeByName($name))) {
64
                $type = $smartType;
65
            }
66
67
            if ($type) {
68
                if (isset($this->cachedTypes[$type])) {
69
                    $class = $this->cachedTypes[$type];
70
71
                    return new $class();
72
                }
73
74
                $class = $this->getClass($type);
75
76
                if (!empty($class)) {
77
                    $this->cachedTypes[$type] = $class;
78
79
                    return new $class();
80
                }
81
            }
82
83
            $class = $this->cachedTypes[$type] = $this->defaultType;
84
85
            return new $class();
86
        } catch (\Exception $exception) {
87
            throw new SimpleCrudException("Error getting the '{$type}' field", 0, $exception);
88
        }
89
    }
90
91
    /**
92
     * Retrieves the field type to use.
93
     *
94
     * @param string $name
95
     *
96
     * @return string|null
97
     */
98
    protected function getTypeByName($name)
99
    {
100
        foreach ($this->smartNames as $type => $names) {
101
            if (in_array($name, $names, true)) {
102
                return $type;
103
            }
104
        }
105
106
        if (substr($name, -3) === '_id') {
107
            return 'Integer';
108
        }
109
110
        //Begin with is|has (for example: isActive, hasContent)
111
        if (preg_match('/^(is|has)[A-Z]/', $name)) {
112
            return 'Boolean';
113
        }
114
115
        //End with At (for example: publishedAt)
116
        if (preg_match('/[a-z]At$/', $name)) {
117
            return 'Datetime';
118
        }
119
    }
120
121
    /**
122
     * Retrieves a class name if exists.
123
     *
124
     * @param string $name
0 ignored issues
show
Bug introduced by
There is no parameter named $name. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
125
     *
126
     * @return string|null
127
     */
128
    protected function getClass($type)
129
    {
130
        foreach ($this->smartTypes as $smartType => $types) {
131
            if (in_array($type, $types, true)) {
132
                $type = $smartType;
133
                break;
134
            }
135
        }
136
137
        $name = ucfirst($type);
138
139
        foreach ($this->namespaces as $namespace) {
140
            $class = $namespace.$name;
141
142
            if (class_exists($class)) {
143
                return $class;
144
            }
145
        }
146
    }
147
}
148