Completed
Push — master ( d6f453...f38598 )
by Vitaly
08:02
created

Core::getContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
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\metadata\ClassMetadata;
13
use samsonframework\container\metadata\MethodMetadata;
14
use samsonframework\core\SystemInterface;
15
use samsonframework\di\ContainerInterface;
16
use samsonframework\resource\ResourceMap;
17
use samsonphp\config\Scheme;
18
use samsonphp\core\exception\CannotLoadModule;
19
use samsonphp\core\exception\ViewPathNotFound;
20
use samsonphp\event\Event;
21
use samsonframework\container\ContainerBuilderInterface;
22
23
/**
24
 * SamsonPHP Core.
25
 *
26
 * @author Vitaly Iegorov <[email protected]>
27
 */
28
class Core implements SystemInterface
29
{
30
    /** @var ContainerInterface */
31
    protected $container;
32
33
    /** @var ClassMetadata[] */
34
    protected $metadataCollection = [];
35
36
    /** @var ContainerBuilderInterface */
37
    protected $builder;
38
39
    /** @var string Current system environment */
40
    protected $environment;
41
42
    /* Rendering models */
43
    /** @deprecated Standard algorithm for view rendering */
44
    const RENDER_STANDART = 1;
45
    /** @deprecated View rendering algorithm from array of view variables */
46
    const RENDER_VARIABLE = 3;
47
48
    /** @deprecated @var  ResourceMap Current web-application resource map */
49
    public $map;
50
   
51
    /** @deprecated @var string Path to current web-application */
52
    public $system_path = __SAMSON_CWD__;
53
    /** @deprecated @var string View path loading mode */
54
    public $render_mode = self::RENDER_STANDART;
55
    /** @var Module Pointer to current active module */
56
    protected $active = null;
57
    /** @var bool Flag for outputting layout template, used for asynchronous requests */
58
    protected $async = false;
59
    /** @var string Path to main system template */
60
    protected $template_path = __SAMSON_DEFAULT_TEMPLATE;
61
62
    /** @return ContainerInterface Get system container */
63
    public function getContainer()
64
    {
65
        return $this->container;
66
    }
67
68
    /**
69
     * Core constructor.
70
     *
71
     * @param ContainerBuilderInterface $builder Container builder
72
     * @param ResourceMap|null $map system resources
73
     */
74
    public function __construct(ContainerBuilderInterface $builder, ResourceMap $map = null)
75
    {
76
        $this->builder = $builder;
77
78
        if (!isset($map)) {
79
            // Get correct web-application path
80
            $this->system_path = __SAMSON_CWD__;
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$system_path has been deprecated with message: @var string Path to current web-application

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
81
82
            // Get web-application resource map
83
            $this->map = ResourceMap::get($this->system_path, false, array('src/'));
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$map has been deprecated with message: @var ResourceMap Current web-application resource map

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
Deprecated Code introduced by
The property samson\core\Core::$system_path has been deprecated with message: @var string Path to current web-application

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
84
        } else { // Use data from passed map
85
            $this->map = $map;
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$map has been deprecated with message: @var ResourceMap Current web-application resource map

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
86
            $this->system_path = $map->entryPoint;
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$system_path has been deprecated with message: @var string Path to current web-application

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
87
        }
88
89
        // Temporary add template worker
90
        $this->subscribe('core.rendered', array($this, 'generateTemplate'));
91
92
        // TODO: Shoud be configurable not fixed integration
93
        $whoops = new \Whoops\Run;
94
        $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...
95
        $whoops->register();
96
97
        // Fire core creation event
98
        Event::fire('core.created', array(&$this));
99
100
        // Signal core configure event
101
        Event::signal('core.configure', array($this->system_path . __SAMSON_CONFIG_PATH));
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$system_path has been deprecated with message: @var string Path to current web-application

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
102
    }
103
104
    /**
105
     * Generic wrap for Event system subscription.
106
     * @see \samson\core\\samsonphp\event\Event::subscribe()
107
     *
108
     * @param string   $key     Event identifier
109
     * @param callable $handler Event handler
110 1
     * @param array    $params  Event parameters
111
     *
112
     * @return $this Chaining
113
     */
114
    public function subscribe($key, $handler, $params = array())
115
    {
116
        Event::subscribe($key, $handler, $params);
117
118
        return $this;
119
    }
120
121 1
    /**
122
     * Change current system working environment or receive
123
     * current system enviroment if no arguments are passed.
124
     *
125
     * @param string $environment Environment identifier
126
     *
127
     * TODO: Function has two different logics - needs to be changed!
128
     * @return $this|string Chaining or current system environment
129
     */
130
    public function environment($environment = Scheme::BASE)
131
    {
132
        if (func_num_args() !== 0) {
133
            $this->environment = $environment;
134
135
            // Signal core environment change
136
            Event::signal('core.environment.change', array($environment, &$this));
137
            return $this;
138
        }
139
140
        return $this->environment;
141
    }
142
143
    /**
144
     * Generate special response header triggering caching mechanisms
145
     * @param int $cacheLife Amount of seconds for cache(default 3600 - 1 hour)
146
     * @param string $accessibility Cache-control accessibility value(default public)
147
     */
148
    public function cached($cacheLife = 3600, $accessibility = 'public')
149
    {
150
        static $cached;
151
        // Protect sending cached headers once
152
        if (!isset($cached) or $cached !== true) {
153
            header('Expires: ' . gmdate('D, d M Y H:i:s T', time() + $cacheLife));
154
            header('Cache-Control: ' . $accessibility . ', max-age=' . $cacheLife);
155
            header('Pragma: cache');
156
157
            $cached = true;
158
        }
159
    }
160
161
    /**
162
     * Set asynchronous mode.
163
     * This mode will not output template and will just path everything that
164
     * was outputted to client.
165
     *
166
     * @param bool $async True to switch to asynchronous output mode
167
     *
168
     * @return $this Chaining
169
     */
170
    public function async($async)
171
    {
172
        $this->async = $async;
173
174
        return $this;
175
    }
176
177
    /** @see iCore::path() */
178
    public function path($path = null)
179
    {
180
        // Если передан аргумент
181
        if (func_num_args()) {
182
            // Сформируем новый относительный путь к главному шаблону системы
183
            $this->template_path = $path . $this->template_path;
184
185
            // Сохраним относительный путь к Веб-приложению
186
            $this->system_path = $path;
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$system_path has been deprecated with message: @var string Path to current web-application

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
187
188
            // Продолжил цепирование
189
            return $this;
190
        }
191
192
        // Вернем текущее значение
193
        return $this->system_path;
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$system_path has been deprecated with message: @var string Path to current web-application

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
194
    }
195
196
    /**    @see iModule::active() */
197
    public function &active(iModule &$module = null)
198
    {
199
        // Сохраним старый текущий модуль
200
        $old = &$this->active;
201
202
        // Если передано значение модуля для установки как текущий - проверим и установим его
203
        if (isset($module)) {
204
            $this->active = &$module;
205
        }
206
207
        // Вернем значение текущего модуля
208
        return $old;
209
    }
210
211
    /**
212
     * Retrieve module instance by identifier.
213
     *
214
     * @param string|null $module Module identifier
215
     *
216
     * @return null|Module Found or active module
217
     */
218
    public function &module($module = null)
219
    {
220
        $return = null;
221
222
        // Ничего не передано - вернем текущуй модуль системы
223
        if (!isset($module) && isset($this->active)) {
224
            $return = &$this->active;
225
        } elseif (is_object($module)) {
226
            $return = &$module;
227
        } elseif (is_string($module)) {
228
            $return = $this->container->get($module);
229
        }
230
231
        // Ничего не получилось вернем ошибку
232
        if ($return === null) {
233
            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...
234
        }
235
236
        return $return;
237
    }
238
239
    /**
240
     * Unload module from core.
241
     *
242
     * @param string $moduleID Module identifier
243
     */
244
    public function unload($moduleID)
245
    {
246
        if (isset($this->module_stack[$moduleID])) {
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...
247
            unset($this->module_stack[$moduleID]);
248
        }
249
    }
250
251
    /**
252
     * Insert generic html template tags and data
253
     *
254
     * @param string $templateHtml Generated HTML
255
     *
256
     * @deprecated Must be moved to a new HTML output object
257
     * @return mixed Changed HTML template
258
     */
259
    public function generateTemplate(&$templateHtml)
260
    {
261
        // Добавим путь к ресурсам для браузера
262
        $headHtml = "\n" . '<base href="' . url()->base() . '">';
263
        // Добавим отметку времени для JavaScript
264 2
        $headHtml .= "\n" . '<script type="text/javascript">var __SAMSONPHP_STARTED = new Date().getTime();</script>';
265
266
        // Добавим поддержку HTML для старых IE
267
        $headHtml .= "\n" . '<!--[if lt IE 9]>';
268
        $headHtml .= "\n" . '<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>';
269
        $headHtml .= "\n" . '<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>';
270
        $headHtml .= "\n" . '<![endif]-->';
271 2
272
        // Выполним вставку главного тега <base> от которого зависят все ссылки документа
273
        // также подставим МЕТА-теги для текущего модуля и сгенерированный минифицированный CSS
274 2
        $templateHtml = str_ireplace('<head>', '<head>' . $headHtml, $templateHtml);
275
276
        // Вставим указатель JavaScript ресурсы в конец HTML документа
277
        $templateHtml = str_ireplace('</html>', '</html>' . __SAMSON_COPYRIGHT, $templateHtml);
278 2
279
        return $templateHtml;
280 2
    }
281
282 2
    /**
283 2
     * Start SamsonPHP framework.
284
     *
285
     * @param string $default Default module identifier
286 2
     *
287
     * @throws ViewPathNotFound
288 2
     */
289
    public function start($default)
290 2
    {
291
        // TODO: Change ExternalModule::init() signature
292
        // Fire core started event
293
        Event::fire('core.started');
294
295 2
        // TODO: Does not see why it should be here
296
        // Set main template path
297
        $this->template($this->template_path);
298
299
        // Security layer
300
        $securityResult = true;
301
        // Fire core security event
302
        Event::fire('core.security', array(&$this, &$securityResult));
303
304
        /** @var mixed $result External route controller action result */
305
        $result = false;
306
307
        // If we have passed security application layer
308
        if ($securityResult) {
309
            // Fire core routing event - go to routing application layer
310
            Event::signal('core.routing', array(&$this, &$result, $default));
311
        }
312
313
        // If no one has passed back routing callback
314
        if (!isset($result) || $result === false) {
315
            // Fire core e404 - routing failed event
316
            $result = Event::signal('core.e404', array(url()->module, url()->method));
317
        }
318
319
        // Response
320 2
        $output = '';
321
322
        // If this is not asynchronous response and controller has been executed
323 2
        if (!$this->async && ($result !== false)) {
324
            // Store module data
325
            $data = $this->active->toView();
326 2
327
            // Render main template
328
            $output = $this->render($this->template_path, $data);
329 2
330
            // Fire after render event
331
            Event::fire('core.rendered', array(&$output));
332 2
        }
333
334
        // Output results to client
335 2
        echo $output;
336
337
        // Fire ended event
338 2
        Event::fire('core.ended', array(&$output));
339
    }
340
341
    /**	@see iCore::template() */
342
    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...
343
    {
344
        // Если передан аргумент
345
        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...
346
            $this->template_path = ($absolutePath)?$template:$this->active->path().$template;
347
        }
348
349
        // Аргументы не переданы - вернем текущий путь к шаблону системы
350
        return $this->template_path;
351
    }
352 7
353
    /**
354 7
     * Render file to a buffer.
355
     *
356 7
     * @param string $view Path to file
357
     * @param array  $data Collection of variables to path to file
358
     *
359
     * @return string Rendered file contents
360
     * @throws ViewPathNotFound
361
     */
362
    public function render($view, $data = array())
363
    {
364
        // TODO: Make rendering as external system, to split up these 3 rendering options
365
366
        // Объявить ассоциативный массив переменных в данном контексте
367
        if (is_array($data)) {
368
            extract($data);
369
        }
370
371
        // Начать вывод в буффер
372
        ob_start();
373
374
        // Path to another template view, by default we are using default template folder path,
375
        // for meeting first condition
376
        $templateView = $view;
377
378
        if (locale() != SamsonLocale::DEF) {
379
            // Modify standard view path with another template
380
            $templateView = str_replace(__SAMSON_VIEW_PATH, __SAMSON_VIEW_PATH . locale() . '/', $templateView);
381
        }
382
383
        // Depending on core view rendering model
384
        switch ($this->render_mode) {
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$render_mode has been deprecated with message: @var string View path loading mode

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
385
            // Standard algorithm for view rendering
386
            case self::RENDER_STANDART:
0 ignored issues
show
Deprecated Code introduced by
The constant samson\core\Core::RENDER_STANDART has been deprecated with message: Standard algorithm for view rendering

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
387
                // Trying to find another template path, by default it's an default template path
388
                if (file_exists($templateView)) {
389
                    include($templateView);
390
                } elseif (file_exists($view)) {
391
                    // If another template wasn't found - we will use default template path
392
                    include($view);
393
                } else { // Error no template view was found
394
                    throw(new ViewPathNotFound($view));
395
                }
396
                break;
397
398
            // View rendering algorithm from array of view variables
399
            case self::RENDER_VARIABLE:
0 ignored issues
show
Deprecated Code introduced by
The constant samson\core\Core::RENDER_VARIABLE has been deprecated with message: View rendering algorithm from array of view variables

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
400
                // Collection of views
401
                $views = &$GLOBALS['__compressor_files'];
402
                // Trying to find another template path, by default it's an default template path
403 2
                if (isset($views[$templateView])) {
404
                    eval(' ?>' . $views[$templateView] . '<?php ');
405
                } elseif (isset($views[$view])) {
406 2
                    // If another template wasn't found - we will use default template path
407
                    eval(' ?>' . $views[$view] . '<?php ');
408
                } else { // Error no template view was found
409 2
                    throw(new ViewPathNotFound($view));
410 2
                }
411 2
                break;
412
        }
413
414 2
        // Получим данные из буффера вывода
415
        $html = ob_get_contents();
416
417
        // Очистим буффер
418
        ob_end_clean();
419
420
        // Fire core render event
421
        Event::fire('core.render', array(&$html, &$data, &$this->active));
422
423
        ////elapsed('End rendering '.$__view);
424
        return $html;
425
    }
426
427
    //[PHPCOMPRESSOR(remove,start)]
428
429
    /**
430
     * Load system from composer.json
431
     * @param string $dependencyFilePath Path to dependencies file
432
     * @return $this Chaining
433
     */
434
    public function composer($dependencyFilePath = null)
435
    {
436
        $composerModules = array();
437
438
        Event::fire(
439
            'core.composer.create',
440
            array(
441
                &$composerModules,
442
                isset($dependencyFilePath) ? $dependencyFilePath : $this->system_path,
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$system_path has been deprecated with message: @var string Path to current web-application

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
443
                array(
444
                    'vendorsList' => array('samsonphp/', 'samsonos/', 'samsoncms/', 'samsonjavascript/'),
445
                    'ignoreKey' => 'samson_module_ignore',
446
                    'includeKey' => 'samson_module_include'
447
                )
448
            )
449
        );
450
451
        $modulesToLoad = [];
452
453
        // Iterate requirements
454
        foreach ($composerModules as $requirement => $parameters) {
455
            $moduleName = $this->load(__SAMSON_CWD__ . __SAMSON_VENDOR_PATH . $requirement,
456
            array_merge(
457
                is_array($parameters) ? $parameters : array($parameters),
458
                array('module_id' => $requirement)
459
            ));
460
461
            $modulesToLoad[$moduleName] = $parameters;
462
        }
463
464
        $localModulesPath = '../src';
465
        ResourceMap::get('cache');
466
        // TODO: Nested modules relation
467
        for ($i = 0; $i < 2; $i++) {
468
            $resourceMap = ResourceMap::get($localModulesPath);
469
470
            foreach ($resourceMap->modules as $moduleFile) {
471
                $modulePath = str_replace(realpath($localModulesPath), '', $moduleFile[1]);
472
                $modulePath = explode('/', $modulePath);
473
                $modulePath = $localModulesPath . '/' . $modulePath[1];
474
                $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 454. 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...
475
                $modulesToLoad[$moduleName] = $parameters;
476
            }
477
        }
478
479
        //$this->active = new VirtualModule($this->system_path, $this->map, $this, 'local');
480
481
        // Create local module and set it as active
482
        $this->createMetadata(VirtualModule::class, 'local', $this->system_path);
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$system_path has been deprecated with message: @var string Path to current web-application

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
483
484
        // TODO: This should be changed to one single logic
485
        // Require all local module model files
486
        foreach ($this->map->models as $model) {
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$map has been deprecated with message: @var ResourceMap Current web-application resource map

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
487
            // TODO: Why have to require once?
488
            require_once($model);
489
        }
490
491
        // Create all local modules
492
        foreach ($this->map->controllers as $controller) {
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$map has been deprecated with message: @var ResourceMap Current web-application resource map

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
493
            // Require class into PHP
494
            require($controller);
495
496
            //new VirtualModule($this->system_path, $this->map, $this, basename($controller, '.php'));
497
498
            $this->createMetadata(VirtualModule::class, basename($controller, '.php'), $this->system_path);
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$system_path has been deprecated with message: @var string Path to current web-application

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
499
        }
500
501
        $this->createMetadata(get_class($this), get_class($this), $this->system_path);
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$system_path has been deprecated with message: @var string Path to current web-application

This property has been deprecated. The supplier of the class has supplied an explanatory message.

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

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