1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
namespace samson\core; |
3
|
|
|
|
4
|
|
|
use samsonframework\core\ResourcesInterface; |
5
|
|
|
use samsonframework\core\SystemInterface; |
6
|
|
|
use samsonframework\core\ViewInterface; |
7
|
|
|
use samsonframework\core\PreparableInterface; |
8
|
|
|
use samsonphp\core\Module; |
9
|
|
|
use samsonphp\event\Event; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* SamsonPHP external module |
13
|
|
|
* |
14
|
|
|
* @author Vitaly Iegorov <[email protected]> |
15
|
|
|
*/ |
16
|
|
|
class ExternalModule extends Module implements PreparableInterface |
|
|
|
|
17
|
|
|
{ |
18
|
|
|
/** @var Module Pointer to parent module */ |
19
|
|
|
public $parent = null; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* ExternalModule constructor. |
23
|
|
|
* |
24
|
|
|
* @param string $path |
25
|
|
|
* @param ResourcesInterface $resources |
26
|
|
|
* @param SystemInterface $system |
27
|
|
|
*/ |
28
|
|
|
public function __construct($path, ResourcesInterface $resources, SystemInterface $system) |
29
|
|
|
{ |
30
|
|
|
// Module identifier not specified - set it to NameSpace\Classname |
31
|
|
|
if (!isset($this->id{0})) { |
32
|
|
|
// Generate identifier from module class |
33
|
|
|
$this->id = strtolower(str_replace(__NS_SEPARATOR__, '_', get_class($this))); |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
// Generate unique module cache path in local web-application |
37
|
|
|
$this->cache_path = __SAMSON_CWD__ . __SAMSON_CACHE_PATH . $this->id . '/'; |
38
|
|
|
|
39
|
|
|
// Subscribe to an config ready core event |
40
|
|
|
Event::subscribe('core.started', array(& $this, 'init')); |
41
|
|
|
|
42
|
|
|
// Call parent constructor |
43
|
|
|
parent::__construct($this->id, $path, $resources, $system); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** @see \samson\core\iExternalModule::copy() */ |
47
|
|
|
public function ©() |
48
|
|
|
{ |
49
|
|
|
// Get current class name |
50
|
|
|
$classname = get_class($this); |
51
|
|
|
|
52
|
|
|
// Create copy instance |
53
|
|
|
$clone = new $classname($this->path, $this->resourceMap, $this->system); |
54
|
|
|
$clone->views = &$this->views; |
55
|
|
|
$clone->parent = &$this->parent; |
56
|
|
|
$clone->path = $this->path; |
57
|
|
|
|
58
|
|
|
return $clone; |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** Обработчик сериализации объекта */ |
62
|
|
|
public function __sleep() |
63
|
|
|
{ |
64
|
|
|
// Remove all unnecessary fields from serialization |
65
|
|
|
return array_diff(array_keys(get_object_vars($this)), array('view_path', 'view_html', 'view_data')); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Set current view for rendering. |
71
|
|
|
* |
72
|
|
|
* @param string $viewPath Path for view searching |
73
|
|
|
* @return self Chaining |
74
|
|
|
*/ |
75
|
|
|
public function view($viewPath) |
76
|
|
|
{ |
77
|
|
|
if (is_a($viewPath, ViewInterface::class)) { |
78
|
|
|
$this->view_path = $viewPath; |
79
|
|
|
return $this; |
80
|
|
|
// Old string approach - will be deprecated soon |
81
|
|
|
} elseif (is_string($viewPath)) { |
82
|
|
|
//elapsed('['.$this->id.'] Setting view context: ['.$viewPath.']'); |
83
|
|
|
// Find full path to view file |
84
|
|
|
$this->view_path = $this->findView($viewPath); |
85
|
|
|
|
86
|
|
|
// If we have not found view in current module but we have parent module |
87
|
|
|
if (isset($this->parent) && $this->view_path === false) { |
88
|
|
|
//elapsed('['.$this->id.'] Cannot set view['.$viewPath.'] - passing it to parent['.$this->parent->id.']'); |
89
|
|
|
|
90
|
|
|
/* |
91
|
|
|
* Call parent module view setting and return PARENT module to chain |
92
|
|
|
* actually switching current module in chain |
93
|
|
|
*/ |
94
|
|
|
return $this->parent->view($viewPath); |
95
|
|
|
} else { // Call default module behaviour |
96
|
|
|
// Call default module behaviour |
97
|
|
|
parent::view($this->view_path); |
98
|
|
|
|
99
|
|
|
return $this; |
100
|
|
|
} |
101
|
|
|
} |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Overloading default module rendering behaviour |
106
|
|
|
* as it is used in templates and views using m()->render() |
107
|
|
|
* without specifying concrete module or passing a variable. |
108
|
|
|
* |
109
|
|
|
* @param string $controller Controller action name |
110
|
|
|
*/ |
111
|
|
|
public function render($controller = null) |
112
|
|
|
{ |
113
|
|
|
// If we have parent module connection and have no view set |
114
|
|
|
if (isset($this->parent) && $this->view_path == false /*&& !method_exists($this, $controller)*/) { |
|
|
|
|
115
|
|
|
// Merge current and parent module view data |
116
|
|
|
$this->parent->view_data = array_merge($this->parent->view_data, $this->view_data); |
117
|
|
|
// Set internal view context data pointer |
118
|
|
|
$this->parent->data = &$this->parent->view_data[$this->parent->view_context]; |
119
|
|
|
// Call parent render |
120
|
|
|
$this->parent->render($controller); |
121
|
|
|
} else { // Call default module behaviour |
122
|
|
|
parent::render($controller); |
123
|
|
|
} |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
public function setId($id) |
127
|
|
|
{ |
128
|
|
|
$this->id = $id; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Module preparation handler. |
133
|
|
|
* This function is triggered after module instance is being created. |
134
|
|
|
* |
135
|
|
|
* @return bool Preparation result |
136
|
|
|
*/ |
137
|
|
|
public function prepare() |
138
|
|
|
{ |
139
|
|
|
return true; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* Module initialization. |
144
|
|
|
* This function is triggered when system has started. So here |
145
|
|
|
* we have all modules already prepared and loaded. |
146
|
|
|
* |
147
|
|
|
* @param array $params Collection of module initialization parameters |
148
|
|
|
* @return bool Initialization result |
149
|
|
|
*/ |
150
|
|
|
public function init(array $params = array()) |
151
|
|
|
{ |
152
|
|
|
$this->set($params); |
153
|
|
|
|
154
|
|
|
return true; |
155
|
|
|
} |
156
|
|
|
} |
157
|
|
|
|
This class, trait or interface 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 type will be removed from the class and what other constant to use instead.