Passed
Push — feature/packages ( d10195...cc596d )
by Thierry
02:40
created

Manager::getPackage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Manager.php - Jaxon plugin manager
5
 *
6
 * Register Jaxon plugins, generate corresponding code, handle request
7
 * and redirect them to the right plugin.
8
 *
9
 * @package jaxon-core
0 ignored issues
show
Coding Style introduced by
Package name "jaxon-core" is not valid; consider "Jaxoncore" instead
Loading history...
10
 * @author Jared White
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
11
 * @author J. Max Wilson
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
12
 * @author Joseph Woolley
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
13
 * @author Steffen Konerow
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
14
 * @author Thierry Feuzeu <[email protected]>
15
 * @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
16
 * @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White  & J. Max Wilson
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
17
 * @copyright 2016 Thierry Feuzeu <[email protected]>
18
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
19
 * @link https://github.com/jaxon-php/jaxon-core
20
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
21
22
namespace Jaxon\Plugin;
23
24
use Jaxon\Jaxon;
25
use Jaxon\Plugin\Package;
26
use Jaxon\Plugin\Code\Generator as CodeGenerator;
27
use Jaxon\Request\Support\CallableRepository;
28
use Jaxon\Request\Plugin\CallableClass;
29
use Jaxon\Request\Plugin\CallableDir;
30
use Jaxon\Request\Plugin\CallableFunction;
31
use Jaxon\Request\Plugin\FileUpload;
32
use Jaxon\Response\Plugin\JQuery as JQueryPlugin;
33
use Jaxon\Utils\Config\Config;
34
35
use Closure;
36
37
class Manager
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class Manager
Loading history...
38
{
39
    use \Jaxon\Features\Manager;
40
    use \Jaxon\Features\Config;
41
    use \Jaxon\Features\Event;
42
    use \Jaxon\Features\Translator;
43
44
    /**
45
     * Request plugins, indexed by name
46
     *
47
     * @var array
48
     */
49
    private $aRequestPlugins = [];
50
51
    /**
52
     * Response plugins, indexed by name
53
     *
54
     * @var array
55
     */
56
    private $aResponsePlugins = [];
57
58
    /**
59
     * The code generator
60
     *
61
     * @var CodeGenerator
62
     */
63
    private $xCodeGenerator;
64
65
    /**
66
     * The constructor
67
     *
68
     * @param CodeGenerator     $xCodeGenerator
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter type; 5 found
Loading history...
69
     */
70
    public function __construct(CodeGenerator $xCodeGenerator)
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines before function; 1 found
Loading history...
71
    {
72
        $this->xCodeGenerator = $xCodeGenerator;
73
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
74
75
    /**
76
     * Get the request plugins
77
     *
78
     * @return array
79
     */
80
    public function getRequestPlugins()
81
    {
82
        return $this->aRequestPlugins;
83
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
84
85
    /**
86
     * Get the response plugins
87
     *
88
     * @return array
89
     */
90
    public function getResponsePlugins()
91
    {
92
        return $this->aResponsePlugins;
93
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
94
95
    /**
96
     * Get a package instance
97
     *
98
     * @param string        $sClassName           The package class name
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 11 found
Loading history...
99
     *
100
     * @return Package
101
     */
102
    public function getPackage($sClassName)
103
    {
104
        $sClassName = trim($sClassName, '\\ ');
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $sClassName. This often makes code more readable.
Loading history...
105
        return jaxon()->di()->get($sClassName);
106
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
107
108
    /**
109
     * Register a plugin
110
     *
111
     * Below is a table for priorities and their description:
112
     * - 0 thru 999: Plugins that are part of or extensions to the jaxon core
113
     * - 1000 thru 8999: User created plugins, typically, these plugins don't care about order
114
     * - 9000 thru 9999: Plugins that generally need to be last or near the end of the plugin list
115
     *
116
     * @param Plugin         $xPlugin               An instance of a plugin
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 9 found
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter name; 15 found
Loading history...
117
     * @param integer        $nPriority             The plugin priority, used to order the plugins
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 13 found
Loading history...
118
     *
119
     * @return void
120
     */
121
    public function registerPlugin(Plugin $xPlugin, $nPriority = 1000)
122
    {
123
        $bIsUsed = false;
124
        if($xPlugin instanceof Request)
125
        {
126
            // The name of a request plugin is used as key in the plugin table
127
            $this->aRequestPlugins[$xPlugin->getName()] = $xPlugin;
128
            $this->xCodeGenerator->addGenerator($xPlugin, $nPriority);
129
            $bIsUsed = true;
130
        }
131
        elseif($xPlugin instanceof Response)
132
        {
133
            // The name of a response plugin is used as key in the plugin table
134
            $this->aResponsePlugins[$xPlugin->getName()] = $xPlugin;
135
            $this->xCodeGenerator->addGenerator($xPlugin, $nPriority);
136
            $bIsUsed = true;
137
        }
138
139
        // This plugin implements the Message interface
140
        if($xPlugin instanceof \Jaxon\Contracts\Dialogs\Message)
141
        {
142
            jaxon()->dialog()->setMessage($xPlugin);
143
            $bIsUsed = true;
144
        }
145
        // This plugin implements the Question interface
146
        if($xPlugin instanceof \Jaxon\Contracts\Dialogs\Question)
147
        {
148
            jaxon()->dialog()->setQuestion($xPlugin);
149
            $bIsUsed = true;
150
        }
151
        // Register the plugin as an event listener
152
        if($xPlugin instanceof \Jaxon\Contracts\Event\Listener)
153
        {
154
            $this->addEventListener($xPlugin);
155
            $bIsUsed = true;
156
        }
157
158
        if(!$bIsUsed)
159
        {
160
            $sErrorMessage = $this->trans('errors.register.invalid', ['name' => get_class($xPlugin)]);
161
            throw new \Jaxon\Exception\Error($sErrorMessage);
162
        }
163
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
164
165
    /**
166
     * Register a package
167
     *
168
     * @param string        $sClassName           The package class name
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 11 found
Loading history...
169
     * @param array         $aOptions           The package options
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 9 found
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter name; 11 found
Loading history...
170
     *
171
     * @return void
172
     */
173
    public function registerPackage($sClassName, array $aOptions)
174
    {
175
        $jaxon = jaxon();
176
        $di = $jaxon->di();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
177
178
        $sClassName = trim($sClassName, '\\ ');
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $sClassName. This often makes code more readable.
Loading history...
179
        $di->set($sClassName, function() use($di, $sClassName, $aOptions) {
180
            return $di->make($sClassName);
181
        });
182
183
        // Read and apply the package config.
184
        $aPackageConfig = $jaxon->config()->read($sClassName::getConfigFile());
185
        $xPackageConfig = $di->newConfig($aPackageConfig);
186
        $this->_registerFromConfig($xPackageConfig);
187
        // Register the view namespaces
188
        $di->getViewManager()->addNamespaces($xPackageConfig);
189
190
        // Set the package options
191
        $cSetter = function($_aOptions) {
1 ignored issue
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
192
            $this->aOptions = $_aOptions;
1 ignored issue
show
Bug introduced by
The property aOptions does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
193
        };
194
        $xPackage = $this->getPackage($sClassName);
195
        // Can now access protected attributes
196
        \call_user_func($cSetter->bindTo($xPackage, $xPackage), $aOptions);
197
198
        $this->xCodeGenerator->addGenerator($xPackage, 500);
199
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
200
201
    /**
202
     * Register a function, event or callable class
203
     *
204
     * Call the request plugin with the $sType defined as name.
205
     *
206
     * @param string        $sType          The type of request handler being registered
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 5 spaces after parameter name; 10 found
Loading history...
207
     * @param string        $sCallable      The callable entity being registered
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 6 found
Loading history...
208
     * @param array|string  $aOptions       The associated options
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 2 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter name; 7 found
Loading history...
209
     *
210
     * @return mixed
211
     */
212
    public function registerCallable($sType, $sCallable, $aOptions = [])
213
    {
214
        if(!key_exists($sType, $this->aRequestPlugins))
215
        {
216
            throw new \Jaxon\Exception\Error($this->trans('errors.register.plugin', ['name' => $sType]));
217
        }
218
219
        $xPlugin = $this->aRequestPlugins[$sType];
220
        return $xPlugin->register($sType, $sCallable, $aOptions);
221
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
222
223
    /**
224
     * Register callable from a section of the config
225
     *
226
     * @param Config        $xAppConfig        The config options
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 4 spaces after parameter name; 8 found
Loading history...
227
     * @param string        $sSection          The config section name
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 6 spaces after parameter name; 10 found
Loading history...
228
     * @param string        $sCallableType     The type of callable to register
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 5 found
Loading history...
229
     *
230
     * @return void
231
     */
232
    private function registerCallablesFromConfig(Config $xAppConfig, $sSection, $sCallableType)
233
    {
234
        $aConfig = $xAppConfig->getOption($sSection, []);
235
        foreach($aConfig as $xKey => $xValue)
236
        {
237
            if(is_integer($xKey) && is_string($xValue))
238
            {
239
                // Register a function without options
240
                $this->registerCallable($sCallableType, $xValue);
241
            }
242
            elseif(is_string($xKey) && (is_array($xValue) || is_string($xValue)))
243
            {
244
                // Register a function with options
245
                $this->registerCallable($sCallableType, $xKey, $xValue);
246
            }
247
            else
248
            {
249
                continue;
250
                // Todo: throw an exception
251
            }
252
        }
253
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
254
255
    /**
256
     * Read and set Jaxon options from a JSON config file
257
     *
258
     * @param Config        $xAppConfig        The config options
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 8 found
Loading history...
259
     *
260
     * @return void
261
     */
262
    private function _registerFromConfig(Config $xAppConfig)
263
    {
264
        // Register functions
265
        $this->registerCallablesFromConfig($xAppConfig, 'functions', Jaxon::CALLABLE_FUNCTION);
266
267
        // Register classes
268
        $this->registerCallablesFromConfig($xAppConfig, 'classes', Jaxon::CALLABLE_CLASS);
269
270
        // Register directories
271
        $this->registerCallablesFromConfig($xAppConfig, 'directories', Jaxon::CALLABLE_DIR);
272
273
        // Register classes in DI container
274
        $di = jaxon()->di();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 15 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
275
        $aContainerConfig = $xAppConfig->getOption('container', []);
276
        foreach($aContainerConfig as $sClassName => $xClosure)
277
        {
278
            $di->set($sClassName, $xClosure);
279
        }
280
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
281
282
    /**
283
     * Read and set Jaxon options from a JSON config file
284
     *
285
     * @param Config        $xAppConfig        The config options
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 8 found
Loading history...
286
     *
287
     * @return void
288
     */
289
    public function registerFromConfig(Config $xAppConfig)
290
    {
291
        $this->_registerFromConfig($xAppConfig);
292
293
        // Register packages
294
        $aPackageConfig = $xAppConfig->getOption('packages', []);
295
        foreach($aPackageConfig as $sClassName => $aOptions)
296
        {
297
            $this->registerPackage($sClassName, $aOptions);
298
        }
299
    }
300
301
302
    /**
303
     * Find the specified response plugin by name and return a reference to it if one exists
304
     *
305
     * @param string        $sName                The name of the plugin
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 16 found
Loading history...
306
     *
307
     * @return \Jaxon\Plugin\Response
308
     */
309
    public function getResponsePlugin($sName)
310
    {
311
        if(array_key_exists($sName, $this->aResponsePlugins))
312
        {
313
            return $this->aResponsePlugins[$sName];
314
        }
315
        return null;
316
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
317
318
    /**
319
     * Find the specified request plugin by name and return a reference to it if one exists
320
     *
321
     * @param string        $sName                The name of the plugin
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 16 found
Loading history...
322
     *
323
     * @return \Jaxon\Plugin\Request
324
     */
325
    public function getRequestPlugin($sName)
326
    {
327
        if(array_key_exists($sName, $this->aRequestPlugins))
328
        {
329
            return $this->aRequestPlugins[$sName];
330
        }
331
        return null;
332
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
333
334
    /**
335
     * Register the Jaxon request plugins
336
     *
337
     * @return void
338
     */
339
    public function registerRequestPlugins()
340
    {
341
        $di = jaxon()->di();
342
        $this->registerPlugin($di->get(CallableClass::class), 101);
343
        $this->registerPlugin($di->get(CallableDir::class), 102);
344
        $this->registerPlugin($di->get(CallableFunction::class), 103);
345
        $this->registerPlugin($di->get(FileUpload::class), 104);
346
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
347
348
    /**
349
     * Register the Jaxon response plugins
350
     *
351
     * @return void
352
     */
353
    public function registerResponsePlugins()
354
    {
355
        $di = jaxon()->di();
356
        // Register an instance of the JQuery plugin
357
        $this->registerPlugin($di->get(JQueryPlugin::class), 700);
358
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 0 found
Loading history...
359
}
360