AbstractHandler::invokePluginsHook()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 0
loc 8
ccs 5
cts 5
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Vectorface\SnappyRouter\Handler;
4
5
use \Exception;
6
use Vectorface\SnappyRouter\Config\Config;
7
use Vectorface\SnappyRouter\Di\Di;
8
use Vectorface\SnappyRouter\Di\DiProviderInterface;
9
use Vectorface\SnappyRouter\Di\ServiceProvider;
10
use Vectorface\SnappyRouter\Encoder\NullEncoder;
11
use Vectorface\SnappyRouter\Exception\PluginException;
12
13
/**
14
 * The base class for all handlers.
15
 * @copyright Copyright (c) 2014, VectorFace, Inc.
16
 * @author Dan Bruce <[email protected]>
17
 */
18
abstract class AbstractHandler implements DiProviderInterface
19
{
20
    /** An array of handler-specific options */
21
    protected $options;
22
23
    /** A sorted array of handler plugins */
24
    private $plugins;
25
26
    /** The service provider to use */
27
    private $serviceProvider;
28
29
    /**
30
     * Constructor for the class.
31
     * @param array $options An array of options for the plugin.
32
     */
33 52
    public function __construct($options)
34
    {
35 52
        $this->options = $options;
36 52
        $this->plugins = array();
37 52
        if (isset($options[Config::KEY_PLUGINS])) {
38 8
            $this->setPlugins((array)$options[Config::KEY_PLUGINS]);
39
        }
40
        // configure the service provider
41 50
        $services = array();
42 50
        if (isset($options[Config::KEY_CONTROLLERS])) {
43 29
            $services = (array)$options[Config::KEY_CONTROLLERS];
44
        }
45 50
        $this->serviceProvider = new ServiceProvider($services);
46 50
        if (isset($options[Config::KEY_NAMESPACES])) {
47
            // namespace provisioning
48 1
            $this->serviceProvider->setNamespaces((array)$options[Config::KEY_NAMESPACES]);
49 49
        } elseif (isset($options[Config::KEY_FOLDERS])) {
50
            // folder provisioning
51 1
            $this->serviceProvider->setFolders((array)$options[Config::KEY_FOLDERS]);
52
        }
53 50
    }
54
55
    /**
56
     * Performs the actual routing.
57
     * @return mixed Returns the result of the route.
58
     */
59
    abstract public function performRoute();
60
61
    /**
62
     * Retrieve an element from the DI container.
63
     * @param string $key The DI key.
64
     * @param boolean $useCache (optional) An optional indicating whether we
65
     *        should use the cached version of the element (true by default).
66
     * @return mixed Returns the DI element mapped to that key.
67
     */
68 1
    public function get($key, $useCache = true)
69
    {
70 1
        return Di::getDefault()->get($key, $useCache);
71
    }
72
73
    /**
74
     * Sets an element in the DI container for the specified key.
75
     * @param string $key The DI key.
76
     * @param mixed  $element The DI element to store.
77
     * @return Di Returns the Di instance.
78
     */
79 1
    public function set($key, $element)
80
    {
81 1
        return Di::getDefault()->set($key, $element);
82
    }
83
84
    /**
85
     * Returns the active service provider for this handler.
86
     * @return ServiceProvider The active service provider for this handler.
87
     */
88 20
    public function getServiceProvider()
89
    {
90 20
        return $this->serviceProvider;
91
    }
92
93
    /**
94
     * Returns the array of plugins registered with this handler.
95
     */
96 17
    public function getPlugins()
97
    {
98 17
        return $this->plugins;
99
    }
100
101
    /**
102
     * Sets the current list of plugins.
103
     * @param array $plugins The array of plugins.
104
     * @return AbstractHandler Returns $this.
105
     */
106 8
    public function setPlugins($plugins)
107
    {
108 8
        $this->plugins = array();
109 8
        foreach ($plugins as $key => $plugin) {
110 8
            $pluginClass = $plugin;
111 8
            if (is_array($plugin)) {
112 8
                if (!isset($plugin[Config::KEY_CLASS])) {
113 1
                    throw new PluginException('Invalid or missing class for plugin '.$key);
114 7
                } elseif (!class_exists($plugin[Config::KEY_CLASS])) {
115 1
                    throw new PluginException('Invalid or missing class for plugin '.$key);
116
                }
117 6
                $pluginClass = $plugin[Config::KEY_CLASS];
118
            }
119 6
            $options = array();
120 6
            if (isset($plugin[Config::KEY_OPTIONS])) {
121 6
                $options = (array)$plugin[Config::KEY_OPTIONS];
122
            }
123 6
            $this->plugins[] = new $pluginClass($options);
124
        }
125 6
        $this->plugins = $this->sortPlugins($this->plugins);
126 6
        return $this;
127
    }
128
129
    // sorts the list of plugins according to their execution order
130
    private function sortPlugins($plugins)
131
    {
132 6
        usort($plugins, function ($a, $b) {
133 6
            return $a->getExecutionOrder() - $b->getExecutionOrder();
134 6
        });
135 6
        return $plugins;
136
    }
137
138
    /**
139
     * Invokes the plugin hook against all the listed plugins.
140
     * @param string $hook The hook to invoke.
141
     * @param array $args The arguments to pass to the call.
142
     */
143 17
    public function invokePluginsHook($hook, $args)
144
    {
145 17
        foreach ($this->getPlugins() as $plugin) {
146 2
            if (method_exists($plugin, $hook)) {
147 2
                call_user_func_array(array($plugin, $hook), $args);
148
            }
149
        }
150 17
    }
151
152
    /**
153
     * Returns whether a handler should function in a CLI environment.
154
     * @return bool Returns true if the handler should function in a CLI
155
     *         environment and false otherwise.
156
     */
157
    abstract public function isCliHandler();
158
159
    /**
160
     * Returns the active response encoder.
161
     * @return EncoderInterface Returns the response encoder.
162
     */
163 1
    public function getEncoder()
164
    {
165 1
        return new NullEncoder();
166
    }
167
168
    /**
169
     * Provides the handler with an opportunity to perform any last minute
170
     * error handling logic. The returned value will be serialized by the
171
     * handler's encoder.
172
     * @param Exception $e The exception that was thrown.
173
     * @return Returns a serializable value that will be encoded and returned
174
     *         to the client.
175
     */
176 2
    public function handleException(Exception $e)
177
    {
178 2
        return $e->getMessage();
179
    }
180
181
    /**
182
     * Returns the array of options.
183
     * @return array $options The array of options.
184
     */
185 35
    public function getOptions()
186
    {
187 35
        return $this->options;
188
    }
189
}
190