PluginManager   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 46
c 1
b 0
f 0
dl 0
loc 182
rs 10
wmc 16

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getRequestHandlers() 0 3 1
A __construct() 0 5 1
A getResponsePlugin() 0 4 2
A registerCallable() 0 10 3
A getParameterReader() 0 3 1
A registerPlugins() 0 13 1
B registerPlugin() 0 36 7
1
<?php
2
3
/**
4
 * PluginManager.php - Jaxon plugin registry
5
 *
6
 * Register Jaxon plugins and callables.
7
 *
8
 * @package jaxon-core
9
 * @author Jared White
10
 * @author J. Max Wilson
11
 * @author Joseph Woolley
12
 * @author Steffen Konerow
13
 * @author Thierry Feuzeu <[email protected]>
14
 * @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
15
 * @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White  & J. Max Wilson
16
 * @copyright 2016 Thierry Feuzeu <[email protected]>
17
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
18
 * @link https://github.com/jaxon-php/jaxon-core
19
 */
20
21
namespace Jaxon\Plugin\Manager;
22
23
use Jaxon\Jaxon;
24
use Jaxon\App\I18n\Translator;
25
use Jaxon\Di\Container;
26
use Jaxon\Exception\SetupException;
27
use Jaxon\Plugin\CallableRegistryInterface;
28
use Jaxon\Plugin\Code\CodeGenerator;
29
use Jaxon\Plugin\CodeGeneratorInterface;
30
use Jaxon\Plugin\Request\CallableClass\CallableClassPlugin;
31
use Jaxon\Plugin\Request\CallableClass\CallableDirPlugin;
32
use Jaxon\Plugin\Request\CallableFunction\CallableFunctionPlugin;
33
use Jaxon\Plugin\RequestHandlerInterface;
34
use Jaxon\Plugin\Response\DataBag\DataBagPlugin;
35
use Jaxon\Plugin\Response\Dialog\DialogPlugin;
36
use Jaxon\Plugin\Response\Script\ScriptPlugin;
37
use Jaxon\Plugin\Response\Pagination\PaginatorPlugin;
38
use Jaxon\Plugin\Response\Psr\PsrPlugin;
39
use Jaxon\Plugin\AbstractResponsePlugin;
40
use Jaxon\Plugin\ResponsePluginInterface;
41
use Jaxon\Request\Handler\ParameterReader;
42
43
use function class_implements;
44
use function in_array;
45
46
class PluginManager
47
{
48
    /**
49
     * @var Container
50
     */
51
    protected $di;
52
53
    /**
54
     * @var CodeGenerator
55
     */
56
    private $xCodeGenerator;
57
58
    /**
59
     * @var Translator
60
     */
61
    protected $xTranslator;
62
63
    /**
64
     * Request plugins, indexed by name
65
     *
66
     * @var array<string>
67
     */
68
    private $aRegistryPlugins = [];
69
70
    /**
71
     * Request handlers, indexed by name
72
     *
73
     * @var array<string>
74
     */
75
    private $aRequestHandlers = [];
76
77
    /**
78
     * Response plugins, indexed by name
79
     *
80
     * @var array<string>
81
     */
82
    private $aResponsePlugins = [];
83
84
    /**
85
     * The constructor
86
     *
87
     * @param Container $di
88
     * @param CodeGenerator $xCodeGenerator
89
     * @param Translator $xTranslator
90
     */
91
    public function __construct(Container $di, CodeGenerator $xCodeGenerator, Translator $xTranslator)
92
    {
93
        $this->di = $di;
94
        $this->xCodeGenerator = $xCodeGenerator;
95
        $this->xTranslator = $xTranslator;
96
    }
97
98
    /**
99
     * Get the request plugins
100
     *
101
     * @return array<string>
102
     */
103
    public function getRequestHandlers(): array
104
    {
105
        return $this->aRequestHandlers;
106
    }
107
108
    /**
109
     * Register a plugin
110
     *
111
     * Below is a table for priorities and their description:
112
     * - 0 to 999: Plugins that are part of or extensions to the jaxon core
113
     * - 1000 to 8999: User created plugins, typically, these plugins don't care about order
114
     * - 9000 to 9999: Plugins that generally need to be last or near the end of the plugin list
115
     *
116
     * @param string $sClassName    The plugin class
117
     * @param string $sPluginName    The plugin name
118
     * @param integer $nPriority    The plugin priority, used to order the plugins
119
     *
120
     * @return void
121
     * @throws SetupException
122
     */
123
    public function registerPlugin(string $sClassName, string $sPluginName, int $nPriority = 1000)
124
    {
125
        $bIsUsed = false;
126
        $aInterfaces = class_implements($sClassName);
127
        if(in_array(CodeGeneratorInterface::class, $aInterfaces))
128
        {
129
            $this->xCodeGenerator->addCodeGenerator($sClassName, $nPriority);
130
            $bIsUsed = true;
131
        }
132
        if(in_array(CallableRegistryInterface::class, $aInterfaces))
133
        {
134
            $this->aRegistryPlugins[$sPluginName] = $sClassName;
135
            $bIsUsed = true;
136
        }
137
        if(in_array(RequestHandlerInterface::class, $aInterfaces))
138
        {
139
            $this->aRequestHandlers[$sPluginName] = $sClassName;
140
            $bIsUsed = true;
141
        }
142
        if(in_array(ResponsePluginInterface::class, $aInterfaces))
143
        {
144
            $this->aResponsePlugins[$sPluginName] = $sClassName;
145
            $bIsUsed = true;
146
        }
147
148
        if(!$bIsUsed)
149
        {
150
            // The class is invalid.
151
            $sMessage = $this->xTranslator->trans('errors.register.invalid', ['name' => $sClassName]);
152
            throw new SetupException($sMessage);
153
        }
154
155
        // Register the plugin in the DI container, if necessary
156
        if(!$this->di->has($sClassName))
157
        {
158
            $this->di->auto($sClassName);
159
        }
160
    }
161
162
    /**
163
     * Find the specified response plugin by name and return a reference to it if one exists
164
     *
165
     * @param string $sName    The name of the plugin
166
     *
167
     * @return AbstractResponsePlugin|null
168
     */
169
    public function getResponsePlugin(string $sName): ?AbstractResponsePlugin
170
    {
171
        return !isset($this->aResponsePlugins[$sName]) ? null :
172
            $this->di->g($this->aResponsePlugins[$sName]);
173
    }
174
175
    /**
176
     * Register a function or callable class
177
     *
178
     * Call the request plugin with the $sType defined as name.
179
     *
180
     * @param string $sType    The type of request handler being registered
181
     * @param string $sCallable    The callable entity being registered
182
     * @param array|string $xOptions    The associated options
183
     *
184
     * @return void
185
     * @throws SetupException
186
     */
187
    public function registerCallable(string $sType, string $sCallable, $xOptions = [])
188
    {
189
        if(isset($this->aRegistryPlugins[$sType]) &&
190
            ($xPlugin = $this->di->g($this->aRegistryPlugins[$sType])))
191
        {
192
            $xPlugin->register($sType, $sCallable, $xPlugin->checkOptions($sCallable, $xOptions));
193
            return;
194
        }
195
        throw new SetupException($this->xTranslator->trans('errors.register.plugin',
196
            ['name' => $sType, 'callable' => $sCallable]));
197
    }
198
199
    /**
200
     * Register the Jaxon request plugins
201
     *
202
     * @return void
203
     * @throws SetupException
204
     */
205
    public function registerPlugins()
206
    {
207
        // Request plugins
208
        $this->registerPlugin(CallableClassPlugin::class, Jaxon::CALLABLE_CLASS, 101);
209
        $this->registerPlugin(CallableFunctionPlugin::class, Jaxon::CALLABLE_FUNCTION, 102);
210
        $this->registerPlugin(CallableDirPlugin::class, Jaxon::CALLABLE_DIR, 103);
211
212
        // Response plugins
213
        $this->registerPlugin(ScriptPlugin::class, ScriptPlugin::NAME, 700);
214
        $this->registerPlugin(DataBagPlugin::class, DataBagPlugin::NAME, 700);
215
        $this->registerPlugin(DialogPlugin::class, DialogPlugin::NAME, 750);
216
        $this->registerPlugin(PaginatorPlugin::class, PaginatorPlugin::NAME, 800);
217
        $this->registerPlugin(PsrPlugin::class, PsrPlugin::NAME, 850);
218
    }
219
220
    /**
221
     * Get the parameter reader
222
     *
223
     * @return ParameterReader
224
     */
225
    public function getParameterReader()
226
    {
227
        return $this->di->g(ParameterReader::class);
228
    }
229
}
230