Completed
Push — master ( 14f560...15f305 )
by
unknown
08:01
created

Core   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 419
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 6

Test Coverage

Coverage 22.66%

Importance

Changes 10
Bugs 1 Features 1
Metric Value
c 10
b 1
f 1
dl 0
loc 419
ccs 29
cts 128
cp 0.2266
rs 8.3157
wmc 43
lcom 3
cbo 6

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 19 1
A subscribe() 0 6 1
A environment() 0 12 2
A cached() 0 12 3
A async() 0 6 1
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
A composer() 0 7 1
A path() 0 17 2
A getContainer() 0 4 1
A __wakeup() 0 4 1
A __sleep() 0 4 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 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 Doctrine\Common\Annotations\AnnotationReader;
12
use samsonframework\container\Builder;
13
use samsonframework\container\ContainerBuilderInterface;
14
use samsonframework\container\ContainerInterface;
15
use samsonframework\container\definition\analyzer\annotation\annotation\InjectService;
16
use samsonframework\container\metadata\ClassMetadata;
17
use samsonframework\container\metadata\MethodMetadata;
18
use samsonframework\container\metadata\PropertyMetadata;
19
use samsonframework\containerannotation\AnnotationClassResolver;
20
use samsonframework\containerannotation\AnnotationMetadataCollector;
21
use samsonframework\containerannotation\AnnotationMethodResolver;
22
use samsonframework\containerannotation\AnnotationPropertyResolver;
23
use samsonframework\containerannotation\AnnotationResolver;
24
use samsonframework\containerannotation\Injectable;
25
use samsonframework\containerannotation\InjectArgument;
26
use samsonframework\containercollection\attribute\ArrayValue;
27
use samsonframework\containercollection\attribute\ClassName;
28
use samsonframework\containercollection\attribute\Name;
29
use samsonframework\containercollection\attribute\Value;
30
use samsonframework\containercollection\CollectionClassResolver;
31
use samsonframework\containercollection\CollectionMethodResolver;
32
use samsonframework\containercollection\CollectionParameterResolver;
33
use samsonframework\containercollection\CollectionPropertyResolver;
34
use samsonframework\containerxml\XmlMetadataCollector;
35
use samsonframework\containerxml\XmlResolver;
36
use samsonframework\core\PreparableInterface;
37
use samsonframework\core\SystemInterface;
38
use samsonframework\resource\ResourceMap;
39
use samsonphp\config\Scheme;
40
use samsonphp\core\exception\CannotLoadModule;
41
use samsonphp\core\exception\ViewPathNotFound;
42
use samsonphp\core\Module;
43
use samsonphp\event\Event;
44
use samsonframework\container\definition\analyzer\annotation\annotation\Service as ServiceAnnotation;
45
46
/**
47
 * SamsonPHP Core.
48
 *
49
 * @author Vitaly Iegorov <[email protected]>
50
 * @ServiceAnnotation("core")
51
 */
52
class Core implements SystemInterface
53
{
54
    /** @deprecated Standard algorithm for view rendering */
55
    const RENDER_STANDART = 1;
56
    /** @deprecated View rendering algorithm from array of view variables */
57
    const RENDER_VARIABLE = 3;
58
    /** @deprecated @var  ResourceMap Current web-application resource map */
59
    public $map;
60
    /** @deprecated @var string Path to current web-application */
61
    public $system_path = __SAMSON_CWD__;
62
63
    /* Rendering models */
64
    /** @deprecated @var string View path loading mode */
65
    public $render_mode = self::RENDER_STANDART;
66
    /** @var ContainerInterface */
67
    protected $container;
68
    /** @var ClassMetadata[] */
69
    protected $metadataCollection = [];
70
    /** @var ContainerBuilderInterface */
71
    protected $builder;
72
    /** @var string Current system environment */
73
    protected $environment;
74
    protected $classes = [];
75
    /** @var Module Pointer to current active module */
76
    protected $active = null;
77
    /** @var bool Flag for outputting layout template, used for asynchronous requests */
78
    protected $async = false;
79
    /** @var string Path to main system template */
80
    protected $template_path = __SAMSON_DEFAULT_TEMPLATE;
81
82
    /**
83
     * Core constructor.
84
     *
85
     * @param ContainerBuilderInterface $builder Container builder
86
     * @param ResourceMap|null $map system resources
87
     * @InjectService(container="container")
88
     * InjectArgument(builder="samsonframework\container\ContainerBuilderInterface")
89
     * InjectArgument(builder="samsonframework\core\ResourceInterface")
90
     */
91
    public function __construct(ContainerInterface $container, ContainerBuilderInterface $builder = null, ResourceMap $map = null)
0 ignored issues
show
Unused Code introduced by
The parameter $map 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...
92
    {
93
        $this->container = $container;
94
        $this->builder = $builder;
95
        // Get correct web-application path
96
        $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...
97
98
        // Get web-application resource map
99
        $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...
100
101
        // Temporary add template worker
102
        $this->subscribe('core.rendered', array($this, 'generateTemplate'));
103
104
        // Fire core creation event
105
        Event::fire('core.created', array(&$this));
106
107
        // Signal core configure event
108
        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...
109
    }
110 1
111
    /**
112
     * Generic wrap for Event system subscription.
113
     * @see \samson\core\\samsonphp\event\Event::subscribe()
114
     *
115
     * @param string   $key     Event identifier
116
     * @param callable $handler Event handler
117
     * @param array    $params  Event parameters
118
     *
119
     * @return $this Chaining
120
     */
121 1
    public function subscribe($key, $handler, $params = array())
122
    {
123
        Event::subscribe($key, $handler, $params);
124
125
        return $this;
126
    }
127
128
    /**
129
     * Change current system working environment or receive
130
     * current system enviroment if no arguments are passed.
131
     *
132
     * @param string $environment Environment identifier
133
     *
134
     * TODO: Function has two different logics - needs to be changed!
135
     * @return $this|string Chaining or current system environment
136
     */
137
    public function environment($environment = Scheme::BASE)
138
    {
139
        if (func_num_args() !== 0) {
140
            $this->environment = $environment;
141
142
            // Signal core environment change
143
            Event::signal('core.environment.change', array($environment, &$this));
144
            return $this;
145
        }
146
147
        return $this->environment;
148
    }
149
150
    /**
151
     * Generate special response header triggering caching mechanisms
152
     * @param int $cacheLife Amount of seconds for cache(default 3600 - 1 hour)
153
     * @param string $accessibility Cache-control accessibility value(default public)
154
     */
155
    public function cached($cacheLife = 3600, $accessibility = 'public')
156
    {
157
        static $cached;
158
        // Protect sending cached headers once
159
        if (!isset($cached) or $cached !== true) {
160
            header('Expires: ' . gmdate('D, d M Y H:i:s T', time() + $cacheLife));
161
            header('Cache-Control: ' . $accessibility . ', max-age=' . $cacheLife);
162
            header('Pragma: cache');
163
164
            $cached = true;
165
        }
166
    }
167
168
    /**
169
     * Set asynchronous mode.
170
     * This mode will not output template and will just path everything that
171
     * was outputted to client.
172
     *
173
     * @param bool $async True to switch to asynchronous output mode
174
     *
175
     * @return $this Chaining
176
     */
177
    public function async($async)
178
    {
179
        $this->async = $async;
180
181
        return $this;
182
    }
183
184
    /**    @see iModule::active() */
185
    public function active($module = null)
186
    {
187
        // Сохраним старый текущий модуль
188
        $old = $this->active;
189
190
        // Если передано значение модуля для установки как текущий - проверим и установим его
191
        if (isset($module)) {
192
            $this->active = $module;
193
        }
194
195
        // Вернем значение текущего модуля
196
        return $old;
197
    }
198
199
    /**
200
     * Retrieve module instance by identifier.
201
     *
202
     * @param string|null $module Module identifier
203
     *
204
     * @return null|Module Found or active module
205
     */
206
    public function module($module = null)
207
    {
208
        $return = null;
209
210
        // Ничего не передано - вернем текущуй модуль системы
211
        if (!isset($module) && isset($this->active)) {
212
            $return = &$this->active;
213
        } elseif (is_object($module)) {
214
            $return = &$module;
215
        } elseif (is_string($module)) {
216
            $return = $this->container->get($module);
217
        }
218
219
//        // Ничего не получилось вернем ошибку
220
        if ($return === null) {
221
            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...
222
        }
223
224
        return $return;
225
    }
226
227
    /**
228
     * Unload module from core.
229
     *
230
     * @param string $moduleID Module identifier
231
     */
232
    public function unload($moduleID)
233
    {
234
        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...
235
            unset($this->module_stack[$moduleID]);
236
        }
237
    }
238
239
    /**
240
     * Insert generic html template tags and data
241
     *
242
     * @param string $templateHtml Generated HTML
243
     *
244
     * @deprecated Must be moved to a new HTML output object
245
     * @return mixed Changed HTML template
246
     */
247
    public function generateTemplate(&$templateHtml)
248
    {
249
        // Добавим путь к ресурсам для браузера
250
        $headHtml = "\n" . '<base href="' . url()->base() . '">';
251
        // Добавим отметку времени для JavaScript
252
        $headHtml .= "\n" . '<script type="text/javascript">var __SAMSONPHP_STARTED = new Date().getTime();</script>';
253
254
        // Добавим поддержку HTML для старых IE
255
        $headHtml .= "\n" . '<!--[if lt IE 9]>';
256
        $headHtml .= "\n" . '<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>';
257
        $headHtml .= "\n" . '<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>';
258
        $headHtml .= "\n" . '<![endif]-->';
259
260
        // Выполним вставку главного тега <base> от которого зависят все ссылки документа
261
        // также подставим МЕТА-теги для текущего модуля и сгенерированный минифицированный CSS
262
        $templateHtml = str_ireplace('<head>', '<head>' . $headHtml, $templateHtml);
263
264 2
        // Вставим указатель JavaScript ресурсы в конец HTML документа
265
        $templateHtml = str_ireplace('</html>', '</html>' . __SAMSON_COPYRIGHT, $templateHtml);
266
267
        return $templateHtml;
268
    }
269
270
    /**
271 2
     * Start SamsonPHP framework.
272
     *
273
     * @param string $default Default module identifier
274 2
     *
275
     * @throws ViewPathNotFound
276
     */
277
    public function start($default)
278 2
    {
279
        // TODO: Change ExternalModule::init() signature
280 2
        // Fire core started event
281
        Event::fire('core.started');
282 2
283 2
        // TODO: Does not see why it should be here
284
        // Set main template path
285
        $this->template($this->template_path);
286 2
287
        // Security layer
288 2
        $securityResult = true;
289
        // Fire core security event
290 2
//        Event::fire('core.security', array(&$this, &$securityResult));
291
292
        /** @var mixed $result External route controller action result */
293
        $result = false;
294
295 2
        // If we have passed security application layer
296
        if ($securityResult) {
297
            // Fire core routing event - go to routing application layer
298
            Event::signal('core.routing', array(&$this, &$result, $default));
299
        }
300
301
        // If no one has passed back routing callback
302
        if (!isset($result) || $result === false) {
303
            // Fire core e404 - routing failed event
304
            $result = Event::signal('core.e404', array(url()->module, url()->method));
305
        }
306
307
        // Response
308
        $output = '';
309
310
        // If this is not asynchronous response and controller has been executed
311
        if (!$this->async && ($result !== false)) {
312
            // Store module data
313
            $data = $this->active->toView();
314
315
            // Render main template
316
            $output = $this->render($this->template_path, $data);
317
318
            // Fire after render event
319
            Event::fire('core.rendered', array(&$output));
320 2
        }
321
322
        // Output results to client
323 2
        echo $output;
324
325
        // Fire ended event
326 2
        Event::fire('core.ended', array(&$output));
327
    }
328
329 2
    /**	@see iCore::template() */
330
    public function template($template = NULL, $absolutePath = false)
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
331
    {
332 2
        // Если передан аргумент
333
        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...
334
            $this->template_path = ($absolutePath)?$template: $this->active->path().$template;
335 2
        }
336
337
        // Аргументы не переданы - вернем текущий путь к шаблону системы
338 2
        return $this->template_path;
339
    }
340
341
    /**
342
     * Render file to a buffer.
343
     *
344
     * @param string $view Path to file
345
     * @param array  $data Collection of variables to path to file
346
     *
347
     * @return string Rendered file contents
348
     * @throws ViewPathNotFound
349
     */
350
    public function render($view, $data = array())
351
    {
352 7
        // TODO: Make rendering as external system, to split up these 3 rendering options
353
354 7
        // Объявить ассоциативный массив переменных в данном контексте
355
        if (is_array($data)) {
356 7
            extract($data);
357
        }
358
359
        // Начать вывод в буффер
360
        ob_start();
361
362
        // Path to another template view, by default we are using default template folder path,
363
        // for meeting first condition
364
        $templateView = $view;
365
366
        if (locale() != SamsonLocale::DEF) {
367
            // Modify standard view path with another template
368
            $templateView = str_replace(__SAMSON_VIEW_PATH, __SAMSON_VIEW_PATH . locale() . '/', $templateView);
369
        }
370
371
        // Depending on core view rendering model
372
        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...
373
            // Standard algorithm for view rendering
374
            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...
375
                // Trying to find another template path, by default it's an default template path
376
                if (file_exists($templateView)) {
377
                    include($templateView);
378
                } elseif (file_exists($view)) {
379
                    // If another template wasn't found - we will use default template path
380
                    include($view);
381
                } else { // Error no template view was found
382
                    throw(new ViewPathNotFound($view));
383
                }
384
                break;
385
386
            // View rendering algorithm from array of view variables
387
            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...
388
                // Collection of views
389
                $views = &$GLOBALS['__compressor_files'];
390
                // Trying to find another template path, by default it's an default template path
391
                if (isset($views[$templateView])) {
392
                    eval(' ?>' . $views[$templateView] . '<?php ');
393
                } elseif (isset($views[$view])) {
394
                    // If another template wasn't found - we will use default template path
395
                    eval(' ?>' . $views[$view] . '<?php ');
396
                } else { // Error no template view was found
397
                    throw(new ViewPathNotFound($view));
398
                }
399
                break;
400
        }
401
402
        // Получим данные из буффера вывода
403 2
        $html = ob_get_contents();
404
405
        // Очистим буффер
406 2
        ob_end_clean();
407
408
        // Fire core render event
409 2
        Event::fire('core.render', array(&$html, &$data, &$this->active));
410 2
411 2
        ////elapsed('End rendering '.$__view);
412
        return $html;
413
    }
414 2
415
    /**
416
     * Load system from composer.json
417
     * @param string $dependencyFilePath Path to dependencies file
418
     * @return $this Chaining
419
     * @deprecated
420
     */
421
    public function composer($dependencyFilePath = null)
0 ignored issues
show
Unused Code introduced by
The parameter $dependencyFilePath 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...
422
    {
423
424
        $this->active = new VirtualModule($this->system_path, $this->map, $this, 'local');
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...
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...
425
426
        return $this;
427
    }
428
429
430
    //[PHPCOMPRESSOR(remove,start)]
431
432
    /** @see iCore::path() */
433
    public function path($path = null)
434
    {
435
        // Если передан аргумент
436
        if (func_num_args()) {
437
            // Сформируем новый относительный путь к главному шаблону системы
438
            $this->template_path = $path . $this->template_path;
439
440
            // Сохраним относительный путь к Веб-приложению
441
            $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...
442
443
            // Продолжил цепирование
444
            return $this;
445
        }
446
447
        // Вернем текущее значение
448
        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...
449
    }
450
451
    //[PHPCOMPRESSOR(remove,end)]
452
453
    /** @return \Container Get system container */
454
    public function getContainer()
455
    {
456
        return $this->container;
457
    }
458
459
    /** Магический метод для десериализации объекта */
460
    public function __wakeup()
461
    {
462
        $this->active = &$this->module_stack['local'];
463
    }
464
465
    /** Магический метод для сериализации объекта */
466
    public function __sleep()
467
    {
468
        return array('module_stack', 'render_mode');
469
    }
470
}
471