Completed
Push — master ( a8fb97...ba7e2b )
by Mathieu
05:06
created

ResolverFactory::__construct()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 31
Code Lines 22

Duplication

Lines 16
Ratio 51.61 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 16
loc 31
rs 8.439
cc 5
eloc 22
nc 16
nop 1
1
<?php
2
3
namespace Charcoal\Factory;
4
5
use \InvalidArgumentException;
6
7
// Local namespace dependencies
8
use \Charcoal\Factory\AbstractFactory;
9
10
/**
11
 * The Resolver Factory resolves the **class name**  by different configurably methods applied to the **type**.
12
 */
13
class ResolverFactory extends AbstractFactory
14
{
15
    /**
16
     * @var string $resolverPrefix
17
     */
18
    private $resolverPrefix = '';
19
20
    /**
21
     * @var string $resolverSuffix
22
     */
23
    private $resolverSuffix = '';
24
25
    /**
26
     * @var array $resolverCapitals
27
     */
28
    private $resolverCapitals;
29
30
    /**
31
     * @var array $resolverReplacements
32
     */
33
    private $resolverReplacements;
34
35
    public function __construct($data = null)
36
    {
37
        parent::__construct($data);
38
39
        if (!isset($data['resolver_prefix'])) {
40
            $data['resolver_prefix'] = '';
41
        }
42
        if (!isset($data['resolverSuffix'])) {
43
            $data['resolver_suffix'] = '';
44
        }
45 View Code Duplication
        if (!isset($data['resolver_capitals'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
46
            $data['resolver_capitals'] = [
47
                '-',
48
                '\\',
49
                '/',
50
                '.',
51
                '_'
52
            ];
53
        }
54 View Code Duplication
        if (!isset($data['resolver_replacements'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
55
            $data['resolver_replacements'] = [
56
                '-'=>'',
57
                '/'=>'\\',
58
                '.'=>'_'
59
            ];
60
        }
61
        $this->setResolverPrefix($data['resolver_prefix']);
62
        $this->setResolverSuffix($data['resolver_suffix']);
63
        $this->setResolverCapitals($data['resolver_capitals']);
64
        $this->setResolverReplacements($data['resolver_replacements']);
65
    }
66
67
    /**
68
     * @param string $prefix The resolver prefix string.
69
     * @throws InvalidArgumentException If the prefix argument is not a string.
70
     * @return ResolverFactory Chainable
71
     */
72
    public function setResolverPrefix($prefix)
73
    {
74
        if (!is_string($prefix)) {
75
            throw new InvalidArgumentException(
76
                'Prefix must be a string'
77
            );
78
        }
79
        $this->resolverPrefix = $prefix;
80
        return $this;
81
    }
82
83
    /**
84
     * @return string
85
     */
86
    public function resolverPrefix()
87
    {
88
        return $this->resolverPrefix;
89
    }
90
91
    /**
92
     * @param string $suffix The resolver suffix string.
93
     * @throws InvalidArgumentException If the suffix argument is not a string.
94
     * @return ResolverFactory Chainable
95
     */
96
    public function setResolverSuffix($suffix)
97
    {
98
        if (!is_string($suffix)) {
99
            throw new InvalidArgumentException(
100
                'Prefix must be a string'
101
            );
102
        }
103
        $this->resolverSuffix = $suffix;
104
        return $this;
105
    }
106
107
    /**
108
     * @return string
109
     */
110
    public function resolverSuffix()
111
    {
112
        return $this->resolverSuffix;
113
    }
114
115
    /**
116
     * @param array $capitals The array of letter to "calitalize-next" (uppercase next letter in the string).
117
     * @return ResolverFactory Chainable
118
     */
119
    public function setResolverCapitals(array $capitals)
120
    {
121
        $this->resolverCapitals = $capitals;
122
        return $this;
123
    }
124
125
    /**
126
     * @return array
127
     */
128
    public function resolverCapitals()
129
    {
130
        return $this->resolverCapitals;
131
    }
132
133
    /**
134
     * @param array $replacements The array (key=>value) of replacements.
135
     * @return ResolverFactory Chainable
136
     */
137
    public function setResolverReplacements(array $replacements)
138
    {
139
        $this->resolverReplacements = $replacements;
140
        return $this;
141
    }
142
143
    /**
144
     * @return array
145
     */
146
    public function resolverReplacements()
147
    {
148
        return $this->resolverReplacements;
149
    }
150
151
    /**
152
     * Resolve the class name from the requested type.
153
     *
154
     * @param string $type The "type" of object to resolve (the object ident).
155
     * @throws InvalidArgumentException If the type parameter is not a string.
156
     * @return string The resolved class name (FQN).
157
     */
158
    public function resolve($type)
159
    {
160
        if (!is_string($type)) {
161
            throw new InvalidArgumentException(
162
                'Can not resolve class ident: type must be a string'
163
            );
164
        }
165
166
        $capitalize_next = function(&$i) {
167
            $i = ucfirst($i);
168
        };
169
170
        $capitals = $this->resolverCapitals();
171
        foreach ($capitals as $cap) {
172
            $expl = explode($cap, $type);
173
            array_walk($expl, $capitalize_next);
174
            $type = implode($cap, $expl);
175
        }
176
177
        $replacements = $this->resolverReplacements();
178
        foreach ($replacements as $rep => $target) {
179
            $type = str_replace($rep, $target, $type);
180
        }
181
182
        $class = '\\'.trim($type, '\\');
183
184
        // Add prefix + suffix, if applicable
185
        $class = $this->resolverPrefix().$class.$this->resolverSuffix();
186
187
        return $class;
188
    }
189
190
    /**
191
     * @param string $type The "type" of object to resolve (the object ident).
192
     * @throws InvalidArgumentException If the type parameter is not a string.
193
     * @return boolean
194
     */
195
    public function isResolvable($type)
196
    {
197
        if (!is_string($type)) {
198
            throw new InvalidArgumentException(
199
                'Can not check resolvable: type must be a string'
200
            );
201
        }
202
203
        $class_name = $this->resolve($type);
204
        return class_exists($class_name);
205
    }
206
}
207