Binder::arrayHas()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 2
1
<?php
2
3
namespace Enzyme\LaravelBinder;
4
5
use Illuminate\Contracts\Container\Container;
6
7
/**
8
 * Manages a set of context bindings using Laravel's service container.
9
 */
10
class Binder
11
{
12
    /**
13
     * A reference to the service container.
14
     *
15
     * @var \Illuminate\Contracts\Container\Container
16
     */
17
    protected $container;
18
19
    /**
20
     * A collection of bindings.
21
     *
22
     * @var array
23
     */
24
    protected $bindings = [];
25
26
    /**
27
     * A collection of aliases.
28
     *
29
     * @var array
30
     */
31
    protected $aliases = [];
32
33
    /**
34
     * A collection of classes and their dependencies.
35
     *
36
     * @var array
37
     */
38
    protected $needs = [];
39
40
    /**
41
     * Holds a record of the last binding that occured.
42
     *
43
     * @var array
44
     */
45
    protected $lastBinding = [];
46
47
    /**
48
     * Create a new Binder from the given service container instance.
49
     * 
50
     * @param \Illuminate\Contracts\Container\Container $container
51
     */
52
    public function __construct(Container $container)
53
    {
54
        $this->container = $container;
55
    }
56
57
    /**
58
     * Create an alias for the given class or interface.
59
     *
60
     * @param string $alias The alias.
61
     * @param string $fqn   The full namespaced path to the class or interface.
62
     */
63
    public function setAlias($alias, $fqn)
64
    {
65
        $this->aliases[$this->cleanAlias($alias)] = $fqn;
66
    }
67
68
    /**
69
     * Create a binding from an interface to a concrete class.
70
     *
71
     * @param string $alias     The alias for this binding.
72
     * @param string $interface The interface.
73
     * @param string $concrete  The concrete implementation.
74
     */
75
    public function setBinding($alias, $interface, $concrete)
76
    {
77
        $this->bindings[$this->cleanAlias($alias)] = [
78
            'interface' => $interface,
79
            'concrete'  => $concrete,
80
        ];
81
82
        $this->lastBinding = compact('alias', 'concrete');
83
84
        return $this;
85
    }
86
87
    /**
88
     * Binds the previous virtual binding into the Laravel service container.
89
     * This will map the interface to the concrete class, then create an alias
90
     * for the interface so it can later be referenced by its short name.
91
     */
92
    public function solidify()
93
    {
94
        if (count($this->lastBinding) < 2) {
95
            throw new BindingException(
96
                "Container injection can't be completed as a previous ".
97
                "binding operation hasn't yet to occur."
98
            );
99
        }
100
101
        $alias = $this->lastBinding['alias'];
102
        $concrete = $this->lastBinding['concrete'];
103
104
        $this
105
            ->container
106
            ->bind($alias, function($app) use($concrete) {
107
                return $app->make($concrete);
108
            });
109
    }
110
111
    /**
112
     * Set the dependencies of a class.
113
     *
114
     * @param string $alias The alias of the class.
115
     * @param array  $needs An array of dependencies.
116
     */
117
    public function setNeeds($alias, array $needs)
118
    {
119
        $this->needs[$this->cleanAlias($alias)] = $needs;
120
    }
121
122
    /**
123
     * Register all the dependencies with the underlying service container.
124
     */
125
    public function register()
126
    {
127
        foreach ($this->needs as $parent => $dependencies) {
128
            $this->registerDependencies($this->getFqn($parent), $dependencies);
129
        }
130
    }
131
132
    /**
133
     * Registers the given dependencies with the parent class.
134
     *
135
     * @param string $parent_fqn   The full namespaced class path.
136
     * @param array  $dependencies The collection of dependencies.
137
     */
138
    protected function registerDependencies($parent_fqn, array $dependencies)
139
    {
140
        foreach ($dependencies as $dependency) {
141
            $dependency_tree = $this->bindings[$dependency];
142
143
            $this
144
                ->container
145
                ->when($parent_fqn)
146
                ->needs($this->getFqn($dependency_tree['interface']))
147
                ->give($this->getFqn($dependency_tree['concrete']));
148
        }
149
    }
150
151
    /**
152
     * Get the fully qualified name for the given string if it's an alias
153
     * otherwise ensure the class/interface exists and return it. Will throw a
154
     * BindingException if the class/interface does not exist.
155
     *
156
     * @param string $string
157
     *
158
     * @return string
159
     */
160
    protected function getFqn($string)
161
    {
162
        if (class_exists($string) || interface_exists($string)) {
163
            return $string;
164
        }
165
166
        if ($this->arrayHas($this->aliases, $string)) {
167
            return $this->getFqn($this->aliases[$string]);
168
        }
169
170
        throw new BindingException(
171
            "The class or alias [{$string}] does not exist."
172
        );
173
    }
174
175
    /**
176
     * Check if the given array has the key specified.
177
     *
178
     * @param array $array The array to check.
179
     * @param mixed $key   The key.
180
     *
181
     * @return boolean
182
     */
183
    protected function arrayHas(array $array, $key)
184
    {
185
        return isset($array[$key])
186
            && array_key_exists($key, $array);
187
    }
188
189
    /**
190
     * Return a clean alias and ensure it is a string and not of length zero.
191
     * Will throw a BindingException if the value given is not a string or a
192
     * string of length zero.
193
     *
194
     * @param string $alias
195
     *
196
     * @return string
197
     */
198
    protected function cleanAlias($alias)
199
    {
200
        if (is_string($alias) && strlen($alias) > 0)
201
        {
202
            return $alias;
203
        }
204
205
        throw new BindingException("The alias [{$alias}] is invalid.");
206
    }
207
}
208