Completed
Push — master ( bb67e3...5df87c )
by Nikita
08:07
created

Core::environment()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 7
ccs 0
cts 3
cp 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 2
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\core\SystemInterface;
12
use samsonframework\resource\ResourceMap;
13
use samsonphp\event\Event;
14
15
/**
16
 * Core of SamsonPHP
17
 * 
18
 * @package SamsonPHP
19
 * @author 	Vitaly Iegorov <[email protected]>
1 ignored issue
show
Coding Style introduced by
Spaces must be used for alignment; tabs are not allowed
Loading history...
20
 * @version @version@
21
 */
22
class Core implements SystemInterface
23
{
24
    /* Rendering models */
25
    /** Standard algorithm for view rendering */
26
    const RENDER_STANDART = 1;
27
    /** View rendering algorithm from array of view variables */
28
    const RENDER_VARIABLE = 3;
29
30
    const EVENT_CREATED = 'core.created';
31
    const EVENT_CONFIGURE = 'core.configure';
32
    const EVENT_MODULE_LOADED = 'core.module.loaded';
33
    const EVENT_MODULE_CONFIGURE = 'core.module.configure';
34
    const EVENT_START = 'core.started';
35
    const EVENT_SECURITY = 'core.security';
36
    const EVENT_ROUTING = 'core.routing';
37
    const EVENT_E404 = 'core.e404';
38
    const EVENT_RENDER = 'core.render';
39
    const EVENT_RENDERED = 'core.rendered';
40
    const EVENT_END = 'core.end';
41
42
    /** @deprecated Collection of paths ignored by resources collector */
43
    public static $resourceIgnorePath = array(
44
        '.git',
45
        '.svn',
46
        '.settings',
47
        '.idea',
48
        'vendor',
49
        'upload',
50
        'out',
51
        'i18n',
52
        __SAMSON_CACHE_PATH,
53
        __SAMSON_TEST_PATH,
54
    );
55
56
    /** @deprecated Module paths loaded stack */
57
    public $load_path_stack = array();
58
59
    /** @deprecated Modules to be loaded stack */
60
    public $load_stack = array();
61
62
    /** @deprecated Modules to be loaded stack */
63
    public $load_module_stack = array();
64
65
    /** @deprecated Render handlers stack, With new event system we don't need any kind of stack anymore */
66
    public $render_stack = array();
67
68
    /** @var  ResourceMap Current web-application resource map */
69
    public $map;
70
71
    /** @var Module[] Collection of loaded modules */
72
    public $module_stack = array();
73
74
    /** @var Module Pointer to current active module */
75
    protected $active = null;
76
77
    /** @var bool Flag for outputting layout template, used for asynchronous requests */
78
    protected $async = FALSE;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected false, but found FALSE.
Loading history...
79
80
    /** @var string Path to main system template */
81
    protected $template_path = __SAMSON_DEFAULT_TEMPLATE;
82
83
    /** @var string Path to current web-application */
84
    public $system_path = __SAMSON_CWD__;
85
86
    /** @var string View path modifier for templates */
87
    protected $view_path = '';
88
89
    /** @var string View path loading mode */
90
    public $render_mode = self::RENDER_STANDART;
91
92
    /**
93
     * Change current system working environment
94
     * @param string $environment Environment identifier
95
     * @return self Chaining
96
     */
97
    public function environment($environment = \samsonphp\config\Scheme::BASE)
98
    {
99
        // Signal core environment change
100
        \samsonphp\event\Event::signal('core.environment.change', array($environment, &$this));
101
102
        return $this;
103
    }
104
105
    /**
106
     * Generate special response header triggering caching mechanisms
107
     * @param int $cacheLife Amount of seconds for cache(default 3600 - 1 hour)
108
     * @param string $accessibility Cache-control accessibility value(default public)
109
     */
110 1
    public function cached($cacheLife = 3600, $accessibility = 'public')
111
    {
112
        static $cached;
113
        // Protect sending cached headers once
114
        if (!isset($cached) or $cached !== true) {
115
            header('Expires: ' . gmdate('D, d M Y H:i:s T', time() + $cacheLife));
116
            header('Cache-Control: ' . $accessibility . ', max-age=' . $cacheLife);
117
            header('Pragma: cache');
118
119
            $cached = true;
120
        }
121 1
    }
122
123
    /**
124
     * @see \samson\core\iCore::resources()
125
     * @deprecated Use ResourceMap::find()
126
     */
127
    public function resources(&$path, &$ls = array(), &$files = null)
0 ignored issues
show
Unused Code introduced by
The parameter $files is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
128
    {
129
        if (!isset($this->load_path_stack[$path])) {
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$load_path_stack has been deprecated with message: Module paths loaded stack

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...
130
            // Get the resource map for this entry point
131
            $resourceMap = ResourceMap::get($path);
132
            // Collection for gathering all resources located at module path, grouped by extension
133
            $ls['resources'] = $resourceMap->resources;
134
            $ls['controllers'] = $resourceMap->controllers;
135
            $ls['models'] = $resourceMap->models;
136
            $ls['views'] = $resourceMap->views;
137
            $ls['php'] = $resourceMap->php;
138
139
            // Save path resources data
140
            $this->load_path_stack[$path] = &$ls;
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$load_path_stack has been deprecated with message: Module paths loaded stack

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...
141
142
            return true;
143
        } else {
144
            $ls = $this->load_path_stack[$path];
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$load_path_stack has been deprecated with message: Module paths loaded stack

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...
145
        }
146
147
        return false;
148
    }
149
150
    /** @see \samson\core\iCore::load() */
151
    public function load($path = NULL, $module_id = null, $parameters = array())
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
152
    {
153
        // Check path
154
        if (!file_exists($path)) {
155
            return e('Cannot load module from[##]', E_SAMSON_FATAL_ERROR, $path);
156
        }
157
158
        /** @var ResourceMap $resourceMap Pointer to resource map object */
159
        $resourceMap = ResourceMap::get($path);
160
161
        // Check if we have found SamsonPHP external module class
162
        if (isset($resourceMap->module[0])) {
163
164
            /** @var string $controllerPath Path to module controller file */
165
            $controllerPath = $resourceMap->module[1];
166
167
            /** @var string $moduleClass Name of module controller class to load */
168
            $moduleClass = $resourceMap->module[0];
169
170
171
            // Require module controller class into PHP
172
            if (file_exists($controllerPath)) {
173
                //elapsed('+ ['.$module_id.'] Including module controller '.$controllerPath);
174
                require_once($controllerPath);
175
            }
176
177
            // TODO: this should be done via composer autoload file field
178
            // Iterate all function-style controllers and require them
179
            foreach ($resourceMap->controllers as $controller) {
180
                require_once($controller);
181
            }
182
183
            //elapsed($moduleClass);
184
185
            /** @var \samson\core\ExternalModule $connector Create module controller instance */
186
            $connector = new $moduleClass($path, $resourceMap, $this);
187
188
            //trace($connector, true);
189
190
            // Set composer parameters
191
            $connector->composerParameters = $parameters;
192
193
            // Get module identifier
194
            $module_id = $connector->id();
195
196
            // Fire core module load event
197
            \samsonphp\event\Event::fire('core.module_loaded', array($module_id, &$connector));
198
199
            // Signal core module configure event
200
            \samsonphp\event\Event::signal('core.module.configure', array(&$connector, $module_id));
201
202
            // TODO: Think how to decouple this
203
            // Call module preparation handler
204
            if (!$connector->prepare()) {
205
                // Handle module failed preparing
206
            }
207
208
            // TODO: Add ability to get configuration from parent classes
209
            // TODO: Code lower to be removed, or do we still need this
210
211
            $ls = $resourceMap->toLoadStackFormat();
0 ignored issues
show
Deprecated Code introduced by
The method samsonframework\resource...ap::toLoadStackFormat() has been deprecated.

This method has been deprecated.

Loading history...
212
            //trace($ls, true);trace();
213
214
            // Get module name space
215
            $ns = AutoLoader::getOnlyNameSpace($moduleClass);
216
217
            // Save module resources
218
            $this->load_module_stack[$module_id] = $ls;
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$load_module_stack has been deprecated with message: Modules to be loaded stack

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...
219
220
            // Check for namespace uniqueness
221
            if (!isset($this->load_stack[$ns])) $this->load_stack[$ns] = &$ls;
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$load_stack has been deprecated with message: Modules to be loaded stack

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...
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
222
            // Merge another ns location to existing
223
            else $this->load_stack[$ns] = array_merge_recursive($this->load_stack[$ns], $ls);
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$load_stack has been deprecated with message: Modules to be loaded stack

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...
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
224
225
            // Trying to find parent class for connecting to it to use View/Controller inheritance
226
            $parent_class = get_parent_class($connector);
227
            if (!in_array($parent_class, array(AutoLoader::className('samson\core\ExternalModule'), AutoLoader::className('samson\core\CompressableExternalModule')))) {
228
                // Переберем загруженные в систему модули
229
                foreach ($this->module_stack as &$m) {
230
                    // Если в систему был загружен модуль с родительским классом
231
                    if (get_class($m) == $parent_class) {
232
                        $connector->parent = &$m;
233
                        //elapsed('Parent connection for '.$moduleClass.'('.$connector->uid.') with '.$parent_class.'('.$m->uid.')');
234
                    }
235
                }
236
            }
237
        } elseif (is_array($parameters) && isset($parameters['samsonphp_package_compressable']) && ($parameters['samsonphp_package_compressable'] == 1)) {
238
            // Define default module identifier if it is not passed
239
            $moduleId = str_replace('/', '', $parameters['module_id']);
240
241
            /** @var \samson\core\ExternalModule $connector Create module controller instance */
242
            $connector = new CompressableExternalModule($path, $resourceMap, $this);
243
244
            // Set composer parameters
245
            $connector->composerParameters = $parameters;
246
247
            $connector->setId($moduleId);
248
249
            $ls = $resourceMap->toLoadStackFormat();
0 ignored issues
show
Deprecated Code introduced by
The method samsonframework\resource...ap::toLoadStackFormat() has been deprecated.

This method has been deprecated.

Loading history...
250
251
            // Save module resources
252
            $this->load_module_stack[$moduleId] = $ls;
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$load_module_stack has been deprecated with message: Modules to be loaded stack

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...
253
        } else {
254
            // Signal error
255
            e('Cannot load module from: "##"', D_SAMSON_DEBUG, $path);
256
        }
257
258
        // Chaining
259
        return $this;
260
    }
261
262
263
    /** @see \samson\core\iCore::render() */
264 2
    public function render($__view, $__data = array())
265
    {
266
        ////elapsed('Start rendering '.$__view);
267
268
        // TODO: Make rendering as external system, to split up these 3 rendering options
269
270
        // Объявить ассоциативный массив переменных в данном контексте
271 2
        if (is_array($__data)) extract($__data);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
272
273
        // Начать вывод в буффер
274 2
        ob_start();
275
276
        // Path to another template view, by default we are using default template folder path,
277
        // for meeting first condition
278 2
        $__template_view = $__view;
279
280 2
        if (locale() != SamsonLocale::DEF) {
281
            // Modify standard view path with another template
282 2
            $__template_view = str_replace(__SAMSON_VIEW_PATH, __SAMSON_VIEW_PATH . locale() . '/', $__template_view);
283 2
        }
284
285
        // Depending on core view rendering model
286 2
        switch ($this->render_mode) {
287
            // Standard algorithm for view rendering
288 2
            case self::RENDER_STANDART:
289
                // Trying to find another template path, by default it's an default template path
290 2
                if (file_exists($__template_view)) include($__template_view);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
291
                // If another template wasn't found - we will use default template path
292
                else if (file_exists($__view)) include($__view);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
293
                // Error no template view was found
294
                else e('Cannot render view(##,##) - file doesn\'t exists', E_SAMSON_RENDER_ERROR, array($__view, $this->view_path));
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
295 2
                break;
296
297
            // View rendering algorithm form array of view pathes
298
            case self::RENDER_ARRAY:
299
                // Collection of view pathes
300
                $views = &$GLOBALS['__compressor_files'];
301
                // Trying to find another template path, by default it's an default template path
302
                if (isset($views[$__template_view]) && file_exists($views[$__template_view])) include($views[$__template_view]);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
303
                // If another template wasn't found - we will use default template path
304
                else if (isset($views[$__view]) && file_exists($views[$__view])) include($views[$__view]);
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
305
                // Error no template view was found
306
                else e('Cannot render view(##,##) - file doesn\'t exists', E_SAMSON_RENDER_ERROR, array($views[$__view], $this->view_path));
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
307
                break;
308
309
            // View rendering algorithm from array of view variables
310
            case self::RENDER_VARIABLE:
311
                // Collection of views
312
                $views = &$GLOBALS['__compressor_files'];
313
                // Trying to find another template path, by default it's an default template path
314
                if (isset($views[$__template_view])) eval(' ?>' . $views[$__template_view] . '<?php ');
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
315
                // If another template wasn't found - we will use default template path
316
                else if (isset($views[$__view])) eval(' ?>' . $views[$__view] . '<?php ');
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
317
                // Error no template view was found
318
                else e('Cannot render view(##,##) - view variable not found', E_SAMSON_RENDER_ERROR, array($__view, $this->view_path));
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
319
                break;
320 2
        }
321
322
        // Получим данные из буффера вывода
323 2
        $html = ob_get_contents();
324
325
        // Очистим буффер
326 2
        ob_end_clean();
327
328
        // Fire core render event
329 2
        \samsonphp\event\Event::fire(self::EVENT_RENDER, array(&$html, &$__data, &$this->active));
330
331
        // Iterating throw render stack, with one way template processing
332 2
        foreach ($this->render_stack as &$renderer) {
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$render_stack has been deprecated with message: Render handlers stack, With new event system we don't need any kind of stack anymore

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...
333
            // Выполним одностороннюю обработку шаблона
334
            $html = call_user_func($renderer, $html, $__data, $this->active);
335 2
        }
336
337
        ////elapsed('End rendering '.$__view);
338 2
        return $html;
339
    }
340
341
    //[PHPCOMPRESSOR(remove,start)]
342
    /**
343
     * Generic wrap for Event system subscription
344
     * @see \samson\core\\samsonphp\event\Event::subscribe()
345
     *
346
     * @param string $key Event identifier
347
     * @param callable $handler Event handler
348
     * @param array $params Event parameters
349
     *
350
     * @return $this Chaining
351
     */
352 7
    public function subscribe($key, $handler, $params = array())
353
    {
354 7
        \samsonphp\event\Event::subscribe($key, $handler, $params);
355
356 7
        return $this;
357
    }
358
    //[PHPCOMPRESSOR(remove,end)]
359
360
    /**    @see iCore::async() */
361
    public function async($async = NULL)
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
362
    {
363
        // Если передан аргумент
364
        if (func_num_args()) {
365
            $this->async = $async;
366
            return $this;
367
        } // Аргументы не переданы - вернем статус ассинхронности вывода ядра системы
368
        else return $this->async;
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
369
    }
370
371
    /**    @see iCore::template() */
372
    public function template($template = NULL, $isAbsolutePath = false)
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
373
    {
374
        // Если передан аргумент
375
        if (func_num_args()) {
376
            $this->template_path = $isAbsolutePath?$template:$this->active->path() . $template;
377
        }
378
379
        // Аргументы не переданы - вернем текущий путь к шаблону системы
380
        return $this->template_path;
381
    }
382
383
    /** @see iCore::path() */
384
    public function path($path = NULL)
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
385
    {
386
        // Если передан аргумент
387
        if (func_num_args()) {
388
            // Сформируем новый относительный путь к главному шаблону системы
389
            $this->template_path = $path . $this->template_path;
390
391
            // Сохраним относительный путь к Веб-приложению
392
            $this->system_path = $path;
393
394
            // Продолжил цепирование
395
            return $this;
396
        }
397
398
        // Вернем текущее значение
399
        return $this->system_path;
400
    }
401
402
    /**    @see iModule::active() */
403 2
    public function &active(iModule &$module = null)
404
    {
405
        // Сохраним старый текущий модуль
406 2
        $old = &$this->active;
407
408
        // Если передано значение модуля для установки как текущий - проверим и установим его
409 2
        if (isset($module)) {
410 2
            $this->active = &$module;
411 2
        }
412
413
        // Вернем значение текущего модуля
414 2
        return $old;
415
    }
416
417
    /**    @see iCore::module() */
418
    public function &module($_module = NULL)
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
419
    {
420
        $ret_val = null;
421
422
        // Ничего не передано - вернем текущуй модуль системы
423
        if (!isset($_module) && isset($this->active)) $ret_val = &$this->active;
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
424
        // Если уже передан какой-то модуль - просто вернем его
425
        else if (is_object($_module)) $ret_val = &$_module;
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
426
        // If module name is passed - try to find it
427
        else if (is_string($_module) && isset($this->module_stack[$_module])) $ret_val = &$this->module_stack[$_module];
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
428
429
        //elapsed('Getting module: '.$_module);
430
431
        // Ничего не получилось вернем ошибку
432
        if ($ret_val === null) e('Не возможно получить модуль(##) системы', E_SAMSON_CORE_ERROR, array($_module));
0 ignored issues
show
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
433
434
        return $ret_val;
435
    }
436
437
    /** @see iCore::unload() */
438
    public function unload($_id)
439
    {
440
        // Если модуль загружен в ядро
441
        if (isset($this->module_stack[$_id])) {
442
            // Get module instance
443
            $m = &$this->module_stack[$_id];
444
445
            // Remove load stack data of this module
446
            $ns = \samson\core\AutoLoader::getOnlyNameSpace(get_class($m));
447
            if (isset($this->load_stack[$ns])) unset($this->load_stack[$ns]);
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$load_stack has been deprecated with message: Modules to be loaded stack

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...
Coding Style Best Practice introduced by
It is generally a best practice to always use braces with control structures.

Adding braces to control structures avoids accidental mistakes as your code changes:

// Without braces (not recommended)
if (true)
    doSomething();

// Recommended
if (true) {
    doSomething();
}
Loading history...
448
449
            // Очистим коллекцию загруженых модулей
450
            unset($this->module_stack[$_id]);
451
        }
452
    }
453
454
    //[PHPCOMPRESSOR(remove,start)]
455
    /**
456
     * Insert generic html template tags and data
457
     * @param $template_html
458
     * @deprecated Must be moved to a new HTML output object
459
     * @return mixed Changed HTML template
460
     */
461
    public function generate_template(&$template_html)
0 ignored issues
show
Coding Style introduced by
Method name "Core::generate_template" is not in camel caps format
Loading history...
462
    {
463
        // Добавим путь к ресурсам для браузера
464
        $head_html = "\n" . '<base href="' . url()->base() . '">';
465
        // Добавим отметку времени для JavaScript
466
        $head_html .= "\n" . '<script type="text/javascript">var __SAMSONPHP_STARTED = new Date().getTime();</script>';
467
468
        // Добавим поддержку HTML для старых IE
469
        $head_html .= "\n" . '<!--[if lt IE 9]>';
470
        $head_html .= "\n" . '<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>';
471
        $head_html .= "\n" . '<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>';
472
        $head_html .= "\n" . '<![endif]-->';
473
474
        // Выполним вставку главного тега <base> от которого зависят все ссылки документа
475
        // также подставим МЕТА-теги для текущего модуля и сгенерированный минифицированный CSS
476
        $template_html = str_ireplace('<head>', '<head>' . $head_html, $template_html);
477
478
        // Вставим указатель JavaScript ресурсы в конец HTML документа
479
        $template_html = str_ireplace('</html>', '</html>' . __SAMSON_COPYRIGHT, $template_html);
480
481
        return $template_html;
482
    }
483
484
    /** @see \samson\core\iCore::e404()
485
     * @deprecated Use Core:subscribe('core.e404', ...)
486
     */
487
    public function e404($callable = null)
488
    {
489
        // Если передан аргумент функции то установим новый обработчик e404
490
        if (func_num_args()) {
491
            // Subscribe external handler for e404 event
492
            $this->subscribe('core.e404', $callable);
493
494
            // Chaining
495
            return $this;
496
        }
497
    }
498
    //[PHPCOMPRESSOR(remove,end)]
499
500
    /**    @see iCore::start() */
501
    public function start($default)
502
    {
503
        // TODO: Change ExternalModule::init() signature
504
        // Fire core started event
505
        \samsonphp\event\Event::fire(self::EVENT_START);
506
507
        // TODO: Does not see why it should be here
508
        // Set main template path
509
        $this->template($this->template_path);
510
511
        // Security layer
512
        $securityResult = true;
513
        // Fire core security event
514
        \samsonphp\event\Event::fire(self::EVENT_SECURITY, array(&$this, &$securityResult));
515
516
        /** @var mixed $result External route controller action result */
517
        $result = A_FAILED;
0 ignored issues
show
Deprecated Code introduced by
The constant A_FAILED has been deprecated with message: Действие контроллера НЕ выполнено

This class constant 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 constant will be removed from the class and what other constant to use instead.

Loading history...
518
519
        // If we have passed security application layer
520
        if ($securityResult) {
521
            // Fire core routing event - go to routing application layer
522
            \samsonphp\event\Event::signal(self::EVENT_ROUTING, array(&$this, &$result, $default));
523
        }
524
525
        // If no one has passed back routing callback
526
        if (!isset($result) || $result == A_FAILED) {
0 ignored issues
show
Deprecated Code introduced by
The constant A_FAILED has been deprecated with message: Действие контроллера НЕ выполнено

This class constant 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 constant will be removed from the class and what other constant to use instead.

Loading history...
527
            // Fire core e404 - routing failed event
528
            $result = \samsonphp\event\Event::signal(self::EVENT_E404, array(url()->module, url()->method));
529
        }
530
531
        // Response
532
        $output = '';
533
534
        // If this is not asynchronous response and controller has been executed
535
        if (!$this->async && ($result !== A_FAILED)) {
0 ignored issues
show
Deprecated Code introduced by
The constant A_FAILED has been deprecated with message: Действие контроллера НЕ выполнено

This class constant 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 constant will be removed from the class and what other constant to use instead.

Loading history...
536
537
            // Store module data
538
            $data = $this->active->toView();
539
540
            // Render main template
541
            $output = $this->render($this->template_path, $data);
542
543
            // Fire after render event
544
            \samsonphp\event\Event::fire(self::EVENT_RENDERED, array(&$output, &$data, &$this->active));
545
        }
546
547
        // Output results to client
548
        echo $output;
549
550
        // Fire ended event
551
        \samsonphp\event\Event::fire(self::EVENT_END, array(&$output));
552
553
        //elapsed('Core::start() ended');
554
    }
555
556
    //[PHPCOMPRESSOR(remove,start)]
557
    /** Конструктор */
558 7
    public function __construct()
559
    {
560
        // Get correct web-application path
561 7
        $this->system_path = __SAMSON_CWD__;
562
563
        // Get web-application resource map
564 7
        $this->map = ResourceMap::get($this->system_path, false, array('src/'));
565
566
        // Connect static collection with this dynamic field to avoid duplicates
567 7
        $this->module_stack = &Module::$instances;
568
569
        // Temporary add template worker
570 7
        $this->subscribe('core.rendered', array($this, 'generate_template'));
571
572
        // Fire core creation event
573 7
        \samsonphp\event\Event::fire(self::EVENT_CREATED, array(&$this));
574
575
        // Signal core configure event
576 7
        \samsonphp\event\Event::signal(self::EVENT_CONFIGURE, array($this->system_path . __SAMSON_CONFIG_PATH));
577 7
    }
578
579
    /**
580
     * TODO: Create an event for parsing modules and subscribe to it in samsonphp/composer.
581
     *
582
     * Load system from composer.json
583
     * @param string $dependencyFilePath Path to dependencies file
584
     * @return $this Chaining
585
     */
586
    public function composer($dependencyFilePath = null)
587
    {
588
        $composerModules = array();
589
590
        \samsonphp\event\Event::fire(
591
            'core.composer.create',
592
            array(
593
                &$composerModules,
594
                isset($dependencyFilePath) ? $dependencyFilePath : $this->system_path,
595
                array(
596
                    'vendorsList' => array('samsonphp/', 'samsonos/', 'samsoncms/'),
597
                    'ignoreKey' => 'samson_module_ignore',
598
                    'includeKey' => 'samson_module_include'
599
                )
600
            )
601
        );
602
603
        // Iterate requirements
604
        foreach ($composerModules as $requirement => $parameters) {
605
            // Load module
606
            $this->load(
607
                __SAMSON_CWD__ . __SAMSON_VENDOR_PATH . $requirement,
608
                null,
609
                array_merge(
610
                    is_array($parameters) ? $parameters : array($parameters),
611
                    array('module_id' => $requirement)
612
                )
613
            );
614
        }
615
616
        // Load local module with all web-application resources
617
        $localResources = $this->map->toLoadStackFormat();
0 ignored issues
show
Deprecated Code introduced by
The method samsonframework\resource...ap::toLoadStackFormat() has been deprecated.

This method has been deprecated.

Loading history...
618
619
        // Manually include local module to load stack
620
        $this->load_stack['local'] = $localResources;
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$load_stack has been deprecated with message: Modules to be loaded stack

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...
621
        $this->load_module_stack['local'] = $localResources;
0 ignored issues
show
Deprecated Code introduced by
The property samson\core\Core::$load_module_stack has been deprecated with message: Modules to be loaded stack

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...
622
623
        // Create local module and set it as active
624
        $this->active = new CompressableLocalModule('local', $this->system_path, $this->map);
625
626
        // Require all local module model files
627
        foreach ($localResources['models'] as $model) {
628
            // TODO: Why have to require once?
629
            require_once($model);
630
        }
631
632
        // Create all local modules
633
        foreach ($localResources['controllers'] as $controller) {
634
            // Require class into PHP
635
            require($controller);
636
637
            // Create module connector instance
638
            new CompressableLocalModule(basename($controller, '.php'), $this->system_path, $this->map);
639
        }
640
641
        return $this;
642
    }
643
    //[PHPCOMPRESSOR(remove,end)]
644
645
646
    /** Магический метод для десериализации объекта */
647
    public function __wakeup()
648
    {
649
        $this->active = &$this->module_stack['local'];
650
    }
651
652
    /** Магический метод для сериализации объекта */
653
    public function __sleep()
654
    {
655
        return array('module_stack', 'render_mode', 'view_path');
656
    }
657
}
658