Completed
Push — master ( 93d0e7...d6f453 )
by Nikita
13:16 queued 03:18
created

Core   C

Complexity

Total Complexity 68

Size/Duplication

Total Lines 661
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 11

Test Coverage

Coverage 18.97%

Importance

Changes 37
Bugs 9 Features 14
Metric Value
c 37
b 9
f 14
dl 0
loc 661
ccs 37
cts 195
cp 0.1897
rs 5.2871
wmc 68
lcom 2
cbo 11

19 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 31 2
A subscribe() 0 6 1
A environment() 0 12 2
A cached() 0 12 3
A async() 0 6 1
A path() 0 17 2
A active() 0 13 2
B module() 0 20 6
A unload() 0 6 2
A generateTemplate() 0 22 1
B start() 0 51 6
A template() 0 10 3
C render() 0 64 9
D composer() 0 108 9
B initModule() 0 34 5
C load() 0 73 11
A __wakeup() 0 4 1
A __sleep() 0 4 1
A createMetadata() 0 14 1

How to fix   Complexity   

Complex Class

Complex classes like Core often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Core, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*
3
 * This file is part of the SamsonPHP\Core package.
4
 * (c) 2013 Vitaly Iegorov <[email protected]>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
namespace samson\core;
10
11
use samsonframework\container\Builder;
12
use samsonframework\container\BuilderInterface;
13
use samsonframework\container\metadata\ClassMetadata;
14
use samsonframework\container\metadata\MethodMetadata;
15
use samsonframework\core\SystemInterface;
16
use samsonframework\di\ContainerInterface;
17
use samsonframework\resource\ResourceMap;
18
use samsonphp\config\Scheme;
19
use samsonphp\core\exception\CannotLoadModule;
20
use samsonphp\core\exception\ViewPathNotFound;
21
use samsonphp\event\Event;
22
use samsonframework\container\ContainerBuilderInterface;
23
24
/**
25
 * Core of SamsonPHP
26
 * 
27
 * @package SamsonPHP
28
 * @author 	Vitaly Iegorov <[email protected]>
29
 * @version @version@
30
 */
31
class Core implements SystemInterface
32
{
33
    /* Rendering models */
34
    /** Standard algorithm for view rendering */
35
    const RENDER_STANDART = 1;
36
    /** View rendering algorithm from array of view variables */
37
    const RENDER_VARIABLE = 3;
38
39
    /** @var  ResourceMap Current web-application resource map */
40
    public $map;
41
42
    /** @var ContainerInterface */
43
    protected $container;
44
45
   
46
    /** @var string Path to current web-application */
47
    public $system_path = __SAMSON_CWD__;
48
    /** @var string View path loading mode */
49
    public $render_mode = self::RENDER_STANDART;
50
    /** @var Module Pointer to current active module */
51
    protected $active = null;
52
    /** @var bool Flag for outputting layout template, used for asynchronous requests */
53
    protected $async = false;
54
    /** @var string Path to main system template */
55
    protected $template_path = __SAMSON_DEFAULT_TEMPLATE;
56
    /** @var string Current system environment */
57
    protected $environment;
58
59
    protected $metadataCollection = [];
60
61
    protected $builder;
62
63
    /**
64
     * Core constructor.
65
     *
66
     * @param ResourceMap|null $map system resources
67
     * @param ContainerBuilderInterface|null $builder Container builder
68
     */
69
    public function __construct(ResourceMap $map = null, ContainerBuilderInterface $builder = null)
70
    {
71
        $this->builder = $builder;
72
73
        if (!isset($map)) {
74
            // Get correct web-application path
75
            $this->system_path = __SAMSON_CWD__;
76
77
            // Get web-application resource map
78
            $this->map = ResourceMap::get($this->system_path, false, array('src/'));
79
        } else { // Use data from passed map
80
            $this->map = $map;
81
            $this->system_path = $map->entryPoint;
82
        }
83
84
        // Connect static collection with this dynamic field to avoid duplicates
85
        $this->module_stack = &Module::$instances;
0 ignored issues
show
Bug introduced by
The property module_stack 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...
86
87
        // Temporary add template worker
88
        $this->subscribe('core.rendered', array($this, 'generateTemplate'));
89
90
        $whoops = new \Whoops\Run;
91
        $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler);
0 ignored issues
show
Documentation introduced by
new \Whoops\Handler\PrettyPageHandler() is of type object<Whoops\Handler\PrettyPageHandler>, but the function expects a callable.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
92
        $whoops->register();
93
94
        // Fire core creation event
95
        Event::fire('core.created', array(&$this));
96
97
        // Signal core configure event
98
        Event::signal('core.configure', array($this->system_path . __SAMSON_CONFIG_PATH));
99
    }
100
101
    /**
102
     * Generic wrap for Event system subscription.
103
     * @see \samson\core\\samsonphp\event\Event::subscribe()
104
     *
105
     * @param string   $key     Event identifier
106
     * @param callable $handler Event handler
107
     * @param array    $params  Event parameters
108
     *
109
     * @return $this Chaining
110 1
     */
111
    public function subscribe($key, $handler, $params = array())
112
    {
113
        Event::subscribe($key, $handler, $params);
114
115
        return $this;
116
    }
117
118
    /**
119
     * Change current system working environment or receive
120
     * current system enviroment if no arguments are passed.
121 1
     *
122
     * @param string $environment Environment identifier
123
     *
124
     * TODO: Function has two different logics - needs to be changed!
125
     * @return $this|string Chaining or current system environment
126
     */
127
    public function environment($environment = Scheme::BASE)
128
    {
129
        if (func_num_args() !== 0) {
130
            $this->environment = $environment;
131
132
            // Signal core environment change
133
            Event::signal('core.environment.change', array($environment, &$this));
134
            return $this;
135
        }
136
137
        return $this->environment;
138
    }
139
140
    /**
141
     * Generate special response header triggering caching mechanisms
142
     * @param int $cacheLife Amount of seconds for cache(default 3600 - 1 hour)
143
     * @param string $accessibility Cache-control accessibility value(default public)
144
     */
145
    public function cached($cacheLife = 3600, $accessibility = 'public')
146
    {
147
        static $cached;
148
        // Protect sending cached headers once
149
        if (!isset($cached) or $cached !== true) {
150
            header('Expires: ' . gmdate('D, d M Y H:i:s T', time() + $cacheLife));
151
            header('Cache-Control: ' . $accessibility . ', max-age=' . $cacheLife);
152
            header('Pragma: cache');
153
154
            $cached = true;
155
        }
156
    }
157
158
    /**
159
     * Set asynchronous mode.
160
     * This mode will not output template and will just path everything that
161
     * was outputted to client.
162
     *
163
     * @param bool $async True to switch to asynchronous output mode
164
     *
165
     * @return $this Chaining
166
     */
167
    public function async($async)
168
    {
169
        $this->async = $async;
170
171
        return $this;
172
    }
173
174
    /** @see iCore::path() */
175
    public function path($path = null)
176
    {
177
        // Если передан аргумент
178
        if (func_num_args()) {
179
            // Сформируем новый относительный путь к главному шаблону системы
180
            $this->template_path = $path . $this->template_path;
181
182
            // Сохраним относительный путь к Веб-приложению
183
            $this->system_path = $path;
184
185
            // Продолжил цепирование
186
            return $this;
187
        }
188
189
        // Вернем текущее значение
190
        return $this->system_path;
191
    }
192
193
    /**    @see iModule::active() */
194
    public function &active(iModule &$module = null)
195
    {
196
        // Сохраним старый текущий модуль
197
        $old = &$this->active;
198
199
        // Если передано значение модуля для установки как текущий - проверим и установим его
200
        if (isset($module)) {
201
            $this->active = &$module;
202
        }
203
204
        // Вернем значение текущего модуля
205
        return $old;
206
    }
207
208
    /**
209
     * Retrieve module instance by identifier.
210
     *
211
     * @param string|null $module Module identifier
212
     *
213
     * @return null|Module Found or active module
214
     */
215
    public function &module($module = null)
216
    {
217
        $return = null;
218
219
        // Ничего не передано - вернем текущуй модуль системы
220
        if (!isset($module) && isset($this->active)) {
221
            $return = &$this->active;
222
        } elseif (is_object($module)) {
223
            $return = &$module;
224
        } elseif (is_string($module)) {
225
            $return = $this->container->get($module);
226
        }
227
228
        // Ничего не получилось вернем ошибку
229
        if ($return === null) {
230
            e('Не возможно получить модуль(##) системы', E_SAMSON_CORE_ERROR, array($module));
0 ignored issues
show
Deprecated Code introduced by
The function e() has been deprecated with message: Use custom exceptions

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
231
        }
232
233
        return $return;
234
    }
235
236
    /**
237
     * Unload module from core.
238
     *
239
     * @param string $moduleID Module identifier
240
     */
241
    public function unload($moduleID)
242
    {
243
        if (isset($this->module_stack[$moduleID])) {
244
            unset($this->module_stack[$moduleID]);
245
        }
246
    }
247
248
    /**
249
     * Insert generic html template tags and data
250
     *
251
     * @param string $templateHtml Generated HTML
252
     *
253
     * @deprecated Must be moved to a new HTML output object
254
     * @return mixed Changed HTML template
255
     */
256
    public function generateTemplate(&$templateHtml)
257
    {
258
        // Добавим путь к ресурсам для браузера
259
        $headHtml = "\n" . '<base href="' . url()->base() . '">';
260
        // Добавим отметку времени для JavaScript
261
        $headHtml .= "\n" . '<script type="text/javascript">var __SAMSONPHP_STARTED = new Date().getTime();</script>';
262
263
        // Добавим поддержку HTML для старых IE
264 2
        $headHtml .= "\n" . '<!--[if lt IE 9]>';
265
        $headHtml .= "\n" . '<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>';
266
        $headHtml .= "\n" . '<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>';
267
        $headHtml .= "\n" . '<![endif]-->';
268
269
        // Выполним вставку главного тега <base> от которого зависят все ссылки документа
270
        // также подставим МЕТА-теги для текущего модуля и сгенерированный минифицированный CSS
271 2
        $templateHtml = str_ireplace('<head>', '<head>' . $headHtml, $templateHtml);
272
273
        // Вставим указатель JavaScript ресурсы в конец HTML документа
274 2
        $templateHtml = str_ireplace('</html>', '</html>' . __SAMSON_COPYRIGHT, $templateHtml);
275
276
        return $templateHtml;
277
    }
278 2
279
    /**
280 2
     * Start SamsonPHP framework.
281
     *
282 2
     * @param string $default Default module identifier
283 2
     *
284
     * @throws ViewPathNotFound
285
     */
286 2
    public function start($default)
287
    {
288 2
        // TODO: Change ExternalModule::init() signature
289
        // Fire core started event
290 2
        Event::fire('core.started');
291
292
        // TODO: Does not see why it should be here
293
        // Set main template path
294
        $this->template($this->template_path);
295 2
296
        // Security layer
297
        $securityResult = true;
298
        // Fire core security event
299
        Event::fire('core.security', array(&$this, &$securityResult));
300
301
        /** @var mixed $result External route controller action result */
302
        $result = false;
303
304
        // If we have passed security application layer
305
        if ($securityResult) {
306
            // Fire core routing event - go to routing application layer
307
            Event::signal('core.routing', array(&$this, &$result, $default));
308
        }
309
310
        // If no one has passed back routing callback
311
        if (!isset($result) || $result === false) {
312
            // Fire core e404 - routing failed event
313
            $result = Event::signal('core.e404', array(url()->module, url()->method));
314
        }
315
316
        // Response
317
        $output = '';
318
319
        // If this is not asynchronous response and controller has been executed
320 2
        if (!$this->async && ($result !== false)) {
321
            // Store module data
322
            $data = $this->active->toView();
323 2
324
            // Render main template
325
            $output = $this->render($this->template_path, $data);
326 2
327
            // Fire after render event
328
            Event::fire('core.rendered', array(&$output));
329 2
        }
330
331
        // Output results to client
332 2
        echo $output;
333
334
        // Fire ended event
335 2
        Event::fire('core.ended', array(&$output));
336
    }
337
338 2
    /**	@see iCore::template() */
339
    public function template( $template = NULL, $absolutePath = false )
0 ignored issues
show
Coding Style introduced by
Expected 0 spaces between opening bracket and argument "$template"; 1 found
Loading history...
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
Coding Style introduced by
Expected 0 spaces between argument "$absolutePath" and closing bracket; 1 found
Loading history...
340
    {
341
        // Если передан аргумент
342
        if( func_num_args() ){
0 ignored issues
show
Coding Style introduced by
Expected 1 space after IF keyword; 0 found
Loading history...
Coding Style introduced by
Expected 0 spaces before closing bracket; 1 found
Loading history...
343
            $this->template_path = ($absolutePath)?$template:$this->active->path().$template;
344
        }
345
346
        // Аргументы не переданы - вернем текущий путь к шаблону системы
347
        return $this->template_path;
348
    }
349
350
    /**
351
     * Render file to a buffer.
352 7
     *
353
     * @param string $view Path to file
354 7
     * @param array  $data Collection of variables to path to file
355
     *
356 7
     * @return string Rendered file contents
357
     * @throws ViewPathNotFound
358
     */
359
    public function render($view, $data = array())
360
    {
361
        // TODO: Make rendering as external system, to split up these 3 rendering options
362
363
        // Объявить ассоциативный массив переменных в данном контексте
364
        if (is_array($data)) {
365
            extract($data);
366
        }
367
368
        // Начать вывод в буффер
369
        ob_start();
370
371
        // Path to another template view, by default we are using default template folder path,
372
        // for meeting first condition
373
        $templateView = $view;
374
375
        if (locale() != SamsonLocale::DEF) {
376
            // Modify standard view path with another template
377
            $templateView = str_replace(__SAMSON_VIEW_PATH, __SAMSON_VIEW_PATH . locale() . '/', $templateView);
378
        }
379
380
        // Depending on core view rendering model
381
        switch ($this->render_mode) {
382
            // Standard algorithm for view rendering
383
            case self::RENDER_STANDART:
384
                // Trying to find another template path, by default it's an default template path
385
                if (file_exists($templateView)) {
386
                    include($templateView);
387
                } elseif (file_exists($view)) {
388
                    // If another template wasn't found - we will use default template path
389
                    include($view);
390
                } else { // Error no template view was found
391
                    throw(new ViewPathNotFound($view));
392
                }
393
                break;
394
395
            // View rendering algorithm from array of view variables
396
            case self::RENDER_VARIABLE:
397
                // Collection of views
398
                $views = &$GLOBALS['__compressor_files'];
399
                // Trying to find another template path, by default it's an default template path
400
                if (isset($views[$templateView])) {
401
                    eval(' ?>' . $views[$templateView] . '<?php ');
402
                } elseif (isset($views[$view])) {
403 2
                    // If another template wasn't found - we will use default template path
404
                    eval(' ?>' . $views[$view] . '<?php ');
405
                } else { // Error no template view was found
406 2
                    throw(new ViewPathNotFound($view));
407
                }
408
                break;
409 2
        }
410 2
411 2
        // Получим данные из буффера вывода
412
        $html = ob_get_contents();
413
414 2
        // Очистим буффер
415
        ob_end_clean();
416
417
        // Fire core render event
418
        Event::fire('core.render', array(&$html, &$data, &$this->active));
419
420
        ////elapsed('End rendering '.$__view);
421
        return $html;
422
    }
423
424
    //[PHPCOMPRESSOR(remove,start)]
425
426
    /**
427
     * Load system from composer.json
428
     * @param string $dependencyFilePath Path to dependencies file
429
     * @return $this Chaining
430
     */
431
    public function composer($dependencyFilePath = null)
432
    {
433
        $composerModules = array();
434
435
        Event::fire(
436
            'core.composer.create',
437
            array(
438
                &$composerModules,
439
                isset($dependencyFilePath) ? $dependencyFilePath : $this->system_path,
440
                array(
441
                    'vendorsList' => array('samsonphp/', 'samsonos/', 'samsoncms/', 'samsonjavascript/'),
442
                    'ignoreKey' => 'samson_module_ignore',
443
                    'includeKey' => 'samson_module_include'
444
                )
445
            )
446
        );
447
448
        $modulesToLoad = [];
449
450
        // Iterate requirements
451
        foreach ($composerModules as $requirement => $parameters) {
452
            $moduleName = $this->load(__SAMSON_CWD__ . __SAMSON_VENDOR_PATH . $requirement,
453
            array_merge(
454
                is_array($parameters) ? $parameters : array($parameters),
455
                array('module_id' => $requirement)
456
            ));
457
458
            $modulesToLoad[$moduleName] = $parameters;
459
        }
460
461
        $localModulesPath = '../src';
462
        ResourceMap::get('cache');
463
        // TODO: Nested modules relation
464
        for ($i = 0; $i < 2; $i++) {
465
            $resourceMap = ResourceMap::get($localModulesPath);
466
467
            foreach ($resourceMap->modules as $moduleFile) {
468
                $modulePath = str_replace(realpath($localModulesPath), '', $moduleFile[1]);
469
                $modulePath = explode('/', $modulePath);
470
                $modulePath = $localModulesPath . '/' . $modulePath[1];
471
                $moduleName = $this->load($modulePath, $parameters);
0 ignored issues
show
Bug introduced by
The variable $parameters seems to be defined by a foreach iteration on line 451. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
472
                $modulesToLoad[$moduleName] = $parameters;
473
            }
474
        }
475
476
        //$this->active = new VirtualModule($this->system_path, $this->map, $this, 'local');
477
478
        // Create local module and set it as active
479
        $this->createMetadata(VirtualModule::class, 'local', $this->system_path);
480
481
        // TODO: This should be changed to one single logic
482
        // Require all local module model files
483
        foreach ($this->map->models as $model) {
484
            // TODO: Why have to require once?
485
            require_once($model);
486
        }
487
488
        // Create all local modules
489
        foreach ($this->map->controllers as $controller) {
490
            // Require class into PHP
491
            require($controller);
492
493
            //new VirtualModule($this->system_path, $this->map, $this, basename($controller, '.php'));
494
495
            $this->createMetadata(VirtualModule::class, basename($controller, '.php'), $this->system_path);
496
        }
497
498
        $this->createMetadata(get_class($this), get_class($this), $this->system_path);
499
500
        $metadata = new ClassMetadata();
501
        $metadata->className = get_class($this);
502
        $metadata->name = get_class($this);
503
        $metadata->scopes[] = Builder::SCOPE_SERVICES;
504
        $metadata->methodsMetadata['__construct'] = new MethodMetadata($metadata);
505
        $metadata->methodsMetadata['__construct']->dependencies['map'] = ResourceMap::class;
506
507
        $this->metadataCollection[$metadata->name] = $metadata;
508
509
        $metadata = new ClassMetadata();
510
        $metadata->className = ResourceMap::class;
511
        $metadata->name = ResourceMap::class;
512
        $metadata->scopes[] = Builder::SCOPE_SERVICES;
513
514
        $this->metadataCollection[$metadata->name] = $metadata;
515
        $containerPath = $this->path().'www/cache/Container.php';
516
517
        file_put_contents($containerPath, $this->builder->build($this->metadataCollection));
518
519
        require_once($containerPath);
520
521
        $this->container = new \Container();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Container() of type object<Container> is incompatible with the declared type object<samsonframework\di\ContainerInterface> of property $container.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
522
        $containerReflection = new \ReflectionClass(get_class($this->container));
523
        $serviceProperty = $containerReflection->getProperty('servicesInstances');
524
        $serviceProperty->setAccessible(true);
525
        $containerServices = $serviceProperty->getValue($this->container);
526
        $containerServices[get_class($this)] = $this;
527
        $serviceProperty->setValue(null, $containerServices);
528
        $serviceProperty->setAccessible(false);
529
530
        foreach ($modulesToLoad as $name => $parameters) {
531
            $instance = $this->container->get($name);
532
            $this->initModule($instance, $parameters);
533
        }
534
535
        $this->active = $this->container->getLocal();
536
537
        return $this;
538
    }
539
540
    /**
541
     * Initialize module.
542
     *
543
     * @param ExternalModule $instance           Module instance for initialization
544
     * @param array          $composerParameters Collection of extra parameters from composer.json file
545
     */
546
    protected function initModule($instance, $composerParameters)
547
    {
548
        $identifier = $instance->id();
549
550
        // Set composer parameters
551
        $instance->composerParameters = $composerParameters;
552
553
        // TODO: Change event signature to single approach
554
        // Fire core module load event
555
        Event::fire('core.module_loaded', array($identifier, &$instance));
556
557
        // Signal core module configure event
558 7
        Event::signal('core.module.configure', array(&$instance, $identifier));
559
560
        // Call module preparation handler
561 7
        if (!$instance->prepare()) {
562
            // Handle module failed preparing
563
        }
564 7
565
        // Trying to find parent class for connecting to it to use View/Controller inheritance
566
        $parentClass = get_parent_class($instance);
567 7
        if (!in_array($parentClass,
568
            array('samson\core\ExternalModule', 'samson\core\CompressableExternalModule'))
569
        ) {
570 7
            // Переберем загруженные в систему модули
571
            foreach ($this->module_stack as &$m) {
572
                // Если в систему был загружен модуль с родительским классом
573 7
                if (get_class($m) === $parentClass) {
574
                    $instance->parent = &$m;
575
                    //elapsed('Parent connection for '.$moduleClass.'('.$connector->uid.') with '.$parent_class.'('.$m->uid.')');
576 7
                }
577 7
            }
578
        }
579
    }
580
581
    /**
582
     * Load module from path to core.
583
     *
584
     * @param string $path       Path for module loading
585
     * @param array  $parameters Collection of loading parameters
586
     *
587
     * @return string module name
588
     * @throws \samsonphp\core\exception\CannotLoadModule
589
     */
590
    public function load($path, $parameters = array())
591
    {
592
        $name = '';
593
        // Check path
594
        if (file_exists($path)) {
595
            /** @var ResourceMap $resourceMap Gather all resources from path */
596
            $resourceMap = ResourceMap::get($path);
597
            if (isset($resourceMap->module[0])) {
598
599
                /** @var string $controllerPath Path to module controller file */
600
                $controllerPath = $resourceMap->module[1];
601
602
                /** @var string $moduleClass Name of module controller class to load */
603
                $moduleClass = $resourceMap->module[0];
604
605
                // Require module controller class into PHP
606
                if (file_exists($controllerPath)) {
607
                    require_once($controllerPath);
608
                }
609
610
                // TODO: this should be done via composer autoload file field
611
                // Iterate all function-style controllers and require them
612
                foreach ($resourceMap->controllers as $controller) {
613
                    require_once($controller);
614
                }
615
616
                $reflection = new \ReflectionClass($moduleClass);
617
                $name = $reflection->getDefaultProperties();
618
                $name = $name['id'] ?? str_replace('/', '', $moduleClass);
619
620
                $this->createMetadata($moduleClass, $name, $path);
621
622
                /*$this->initModule(
623
                    new $moduleClass($path, $resourceMap, $this),
624
                    $parameters
625
                );*/
626
            } elseif (is_array($parameters) && isset($parameters['samsonphp_package_compressable']) && ($parameters['samsonphp_package_compressable'] == 1)) {
627
                $name = str_replace('/', '', $parameters['module_id']);
628
                $this->createMetadata(VirtualModule::class, str_replace('/', '', $parameters['module_id']), $path);
629
630
                /*$this->initModule(
631
                    new VirtualModule($path, $resourceMap, $this, str_replace('/', '', $parameters['module_id'])),
632
                    $parameters
633
                );*/
634
            } elseif (count($resourceMap->classes)) {
635
                /** Update for future version: Search classes that implement LoadableInterface */
636
                foreach ($resourceMap->classes as $classPath => $class) {
637
                    // This class implements LoadableInterface LoadableInterface::class
638
                    if (in_array('\samsonframework\core\LoadableInterface', $resourceMap->classData[$classPath]['implements'])) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
639
640
                        $name =  str_replace('/', '', $parameters['module_id']);
641
642
                        $this->createMetadata(VirtualModule::class, str_replace('/', '', $parameters['module_id']), $path);
643
644
                        /*$this->initModule(
645
                            new VirtualModule(
646
                                $path,
647
                                $resourceMap,
648
                                $this,
649
                                str_replace('/', '', $resourceMap->classData[$classPath]['className'])
650
                            ),
651
                            $parameters
652
                        );*/
653
                    }
654
                }
655
            }
656
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
657
        } else {
658
            throw new CannotLoadModule($path);
659
        }
660
661
        return $name;
662
    }
663
    //[PHPCOMPRESSOR(remove,end)]
664
665
    /** Магический метод для десериализации объекта */
666
    public function __wakeup()
667
    {
668
        $this->active = &$this->module_stack['local'];
669
    }
670
671
    /** Магический метод для сериализации объекта */
672
    public function __sleep()
673
    {
674
        return array('module_stack', 'render_mode');
675
    }
676
677
    protected function createMetadata($class, $name, $path)
678
    {
679
        $metadata = new ClassMetadata();
680
        $class = ltrim($class, '\\');
681
        $metadata->className = $class;
682
        $metadata->name = str_replace('/', '', $name ?? $class);
683
        $metadata->scopes[] = Builder::SCOPE_SERVICES;
684
        $metadata->methodsMetadata['__construct'] = new MethodMetadata($metadata);
685
        $metadata->methodsMetadata['__construct']->dependencies['path'] = $path;
686
        $metadata->methodsMetadata['__construct']->dependencies['resources'] = ResourceMap::class;
687
        $metadata->methodsMetadata['__construct']->dependencies['system'] = get_class($this);
688
689
        $this->metadataCollection[$metadata->name] = $metadata;
690
    }
691
}
692