Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 106 |
|
0.00% |
0 / 6 |
CRAP | |
0.00% |
0 / 1 |
installer | |
0.00% |
0 / 106 |
|
0.00% |
0 / 6 |
1122 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
set_modules | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
set_iohandler | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
set_purge_cache_before | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
run | |
0.00% |
0 / 95 |
|
0.00% |
0 / 1 |
812 | |||
recover_progress | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * |
4 | * This file is part of the phpBB Forum Software package. |
5 | * |
6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
7 | * @license GNU General Public License, version 2 (GPL-2.0) |
8 | * |
9 | * For full copyright and license information, please see |
10 | * the docs/CREDITS.txt file. |
11 | * |
12 | */ |
13 | |
14 | namespace phpbb\install; |
15 | |
16 | use phpbb\cache\driver\driver_interface; |
17 | use phpbb\di\ordered_service_collection; |
18 | use phpbb\install\exception\cannot_build_container_exception; |
19 | use phpbb\install\exception\installer_config_not_writable_exception; |
20 | use phpbb\install\exception\jump_to_restart_point_exception; |
21 | use phpbb\install\exception\resource_limit_reached_exception; |
22 | use phpbb\install\exception\user_interaction_required_exception; |
23 | use phpbb\install\helper\config; |
24 | use phpbb\install\helper\container_factory; |
25 | use phpbb\install\helper\iohandler\ajax_iohandler; |
26 | use phpbb\install\helper\iohandler\cli_iohandler; |
27 | use phpbb\install\helper\iohandler\iohandler_interface; |
28 | use phpbb\path_helper; |
29 | |
30 | class installer |
31 | { |
32 | /** |
33 | * @var driver_interface |
34 | */ |
35 | protected $cache; |
36 | |
37 | /** |
38 | * @var container_factory |
39 | */ |
40 | protected $container_factory; |
41 | |
42 | /** |
43 | * @var config |
44 | */ |
45 | protected $install_config; |
46 | |
47 | /** |
48 | * @var ordered_service_collection|null |
49 | */ |
50 | protected $installer_modules; |
51 | |
52 | /** |
53 | * @var iohandler_interface |
54 | */ |
55 | protected $iohandler; |
56 | |
57 | /** |
58 | * @var string |
59 | */ |
60 | protected $web_root; |
61 | |
62 | /** |
63 | * Stores the number of steps that a given module has |
64 | * |
65 | * @var array |
66 | */ |
67 | protected $module_step_count; |
68 | |
69 | /** |
70 | * @var bool |
71 | */ |
72 | protected $purge_cache_before; |
73 | |
74 | /** |
75 | * Constructor |
76 | * |
77 | * @param driver_interface $cache Cache service |
78 | * @param config $config Installer config handler |
79 | * @param path_helper $path_helper Path helper |
80 | * @param container_factory $container Container |
81 | */ |
82 | public function __construct(driver_interface $cache, config $config, path_helper $path_helper, container_factory $container) |
83 | { |
84 | $this->cache = $cache; |
85 | $this->install_config = $config; |
86 | $this->container_factory = $container; |
87 | $this->installer_modules = null; |
88 | $this->web_root = $path_helper->get_web_root_path(); |
89 | $this->purge_cache_before = false; |
90 | } |
91 | |
92 | /** |
93 | * Sets modules to execute |
94 | * |
95 | * Note: The installer will run modules in the order they are set in |
96 | * the array. |
97 | * |
98 | * @param ordered_service_collection $modules Service collection of module service names |
99 | */ |
100 | public function set_modules(ordered_service_collection $modules) |
101 | { |
102 | $this->installer_modules = $modules; |
103 | } |
104 | |
105 | /** |
106 | * Sets input-output handler objects |
107 | * |
108 | * @param iohandler_interface $iohandler |
109 | */ |
110 | public function set_iohandler(iohandler_interface $iohandler) |
111 | { |
112 | $this->iohandler = $iohandler; |
113 | } |
114 | |
115 | /** |
116 | * Sets whether to purge cache before the installation process |
117 | * |
118 | * @param bool $purge_cache_before |
119 | */ |
120 | public function set_purge_cache_before($purge_cache_before) |
121 | { |
122 | $this->purge_cache_before = $purge_cache_before; |
123 | } |
124 | |
125 | /** |
126 | * Run phpBB installer |
127 | */ |
128 | public function run() |
129 | { |
130 | if ($this->iohandler instanceof ajax_iohandler) |
131 | { |
132 | $this->iohandler->acquire_lock(); |
133 | } |
134 | |
135 | // Load install progress |
136 | $this->install_config->load_config(); |
137 | |
138 | if (!$this->install_config->get('cache_purged_before', false) && $this->purge_cache_before) |
139 | { |
140 | /** @var driver_interface $cache */ |
141 | $cache = $this->container_factory->get('cache.driver'); |
142 | $cache->purge(); |
143 | $this->install_config->set('cache_purged_before', true); |
144 | } |
145 | |
146 | // Recover install progress |
147 | $module_index = $this->recover_progress(); |
148 | |
149 | // Variable used to check if the install process have been finished |
150 | $install_finished = false; |
151 | $fail_cleanup = false; |
152 | $send_refresh = false; |
153 | |
154 | // We are installing something, so the introduction stage can go now... |
155 | $this->install_config->set_finished_navigation_stage(array('install', 0, 'introduction')); |
156 | $this->iohandler->set_finished_stage_menu(array('install', 0, 'introduction')); |
157 | |
158 | if ($this->install_config->get_task_progress_count() === 0) |
159 | { |
160 | // Count all tasks in the current installer modules |
161 | $step_count = 0; |
162 | |
163 | /** @var \phpbb\install\module_interface $module */ |
164 | foreach ($this->installer_modules as $name => $module) |
165 | { |
166 | $module_step_count = $module->get_step_count(); |
167 | $step_count += $module_step_count; |
168 | $this->module_step_count[$name] = $module_step_count; |
169 | } |
170 | |
171 | // Set task count |
172 | $this->install_config->set_task_progress_count($step_count); |
173 | } |
174 | |
175 | // Set up progress information |
176 | $this->iohandler->set_task_count( |
177 | $this->install_config->get_task_progress_count() |
178 | ); |
179 | |
180 | try |
181 | { |
182 | /** @psalm-suppress InvalidTemplateParam */ |
183 | $iterator = $this->installer_modules->getIterator(); |
184 | |
185 | if ($module_index < $iterator->count()) |
186 | { |
187 | $iterator->seek($module_index); |
188 | } |
189 | else |
190 | { |
191 | $iterator->seek($module_index - 1); |
192 | $iterator->next(); |
193 | } |
194 | |
195 | while ($iterator->valid()) |
196 | { |
197 | $module = $iterator->current(); |
198 | $name = $iterator->key(); |
199 | |
200 | // Check if module should be executed |
201 | if (!$module->is_essential() && !$module->check_requirements()) |
202 | { |
203 | $this->install_config->set_finished_navigation_stage($module->get_navigation_stage_path()); |
204 | $this->iohandler->set_finished_stage_menu($module->get_navigation_stage_path()); |
205 | |
206 | $this->iohandler->add_log_message(array( |
207 | 'SKIP_MODULE', |
208 | $name, |
209 | )); |
210 | $this->install_config->increment_current_task_progress($this->module_step_count[$name]); |
211 | } |
212 | else |
213 | { |
214 | // Set the correct stage in the navigation bar |
215 | $this->install_config->set_active_navigation_stage($module->get_navigation_stage_path()); |
216 | $this->iohandler->set_active_stage_menu($module->get_navigation_stage_path()); |
217 | |
218 | $this->iohandler->send_response(); |
219 | |
220 | $module->run(); |
221 | |
222 | $this->install_config->set_finished_navigation_stage($module->get_navigation_stage_path()); |
223 | $this->iohandler->set_finished_stage_menu($module->get_navigation_stage_path()); |
224 | } |
225 | |
226 | $module_index++; |
227 | $iterator->next(); |
228 | |
229 | // Save progress |
230 | $this->install_config->set_active_module($name, $module_index); |
231 | |
232 | if ($iterator->valid() && ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0)) |
233 | { |
234 | throw new resource_limit_reached_exception(); |
235 | } |
236 | } |
237 | |
238 | // Installation finished |
239 | $install_finished = true; |
240 | |
241 | if ($this->iohandler instanceof cli_iohandler) |
242 | { |
243 | $this->iohandler->add_success_message('INSTALLER_FINISHED'); |
244 | } |
245 | else |
246 | { |
247 | // Start session if not installing and get user object |
248 | // to allow redirecting to ACP |
249 | $user = $this->container_factory->get('user'); |
250 | if (!isset($module) || !($module instanceof \phpbb\install\module\install_finish\module)) |
251 | { |
252 | $auth = $this->container_factory->get('auth'); |
253 | |
254 | $user->session_begin(); |
255 | $auth->acl($user->data); |
256 | $user->setup(); |
257 | } |
258 | |
259 | $phpbb_root_path = $this->container_factory->get_parameter('core.root_path'); |
260 | |
261 | $acp_url = append_sid($phpbb_root_path . 'adm/index.php', 'i=acp_help_phpbb&mode=help_phpbb', true, $user->session_id); |
262 | $this->iohandler->add_success_message('INSTALLER_FINISHED', array( |
263 | 'ACP_LINK', |
264 | $acp_url, |
265 | )); |
266 | } |
267 | } |
268 | catch (user_interaction_required_exception $e) |
269 | { |
270 | $this->iohandler->send_response(true); |
271 | } |
272 | catch (resource_limit_reached_exception $e) |
273 | { |
274 | $send_refresh = true; |
275 | } |
276 | catch (jump_to_restart_point_exception $e) |
277 | { |
278 | $this->install_config->jump_to_restart_point($e->get_restart_point_name()); |
279 | $send_refresh = true; |
280 | } |
281 | catch (\Exception $e) |
282 | { |
283 | $this->iohandler->add_error_message($e->getMessage()); |
284 | $this->iohandler->send_response(true); |
285 | $fail_cleanup = true; |
286 | } |
287 | |
288 | if ($this->iohandler instanceof ajax_iohandler) |
289 | { |
290 | $this->iohandler->release_lock(); |
291 | } |
292 | |
293 | if ($install_finished) |
294 | { |
295 | // Send install finished message |
296 | $this->iohandler->set_progress('INSTALLER_FINISHED', $this->install_config->get_task_progress_count()); |
297 | $this->iohandler->send_response(true); |
298 | } |
299 | else if ($send_refresh) |
300 | { |
301 | $this->iohandler->request_refresh(); |
302 | $this->iohandler->send_response(true); |
303 | } |
304 | |
305 | // Save install progress |
306 | try |
307 | { |
308 | if ($install_finished || $fail_cleanup) |
309 | { |
310 | $this->install_config->clean_up_config_file(); |
311 | $this->cache->purge(); |
312 | |
313 | try |
314 | { |
315 | /** @var driver_interface $cache */ |
316 | $cache = $this->container_factory->get('cache.driver'); |
317 | $cache->purge(); |
318 | } |
319 | catch (cannot_build_container_exception $e) |
320 | { |
321 | // Do not do anything, this just means there is no config.php yet |
322 | } |
323 | } |
324 | else |
325 | { |
326 | $this->install_config->save_config(); |
327 | } |
328 | } |
329 | catch (installer_config_not_writable_exception $e) |
330 | { |
331 | // It is allowed to fail this test during requirements testing |
332 | $progress_data = $this->install_config->get_progress_data(); |
333 | |
334 | if ($progress_data['last_task_module_name'] !== 'installer.module.requirements_install') |
335 | { |
336 | $this->iohandler->add_error_message('INSTALLER_CONFIG_NOT_WRITABLE'); |
337 | } |
338 | } |
339 | } |
340 | |
341 | /** |
342 | * Recover install progress |
343 | * |
344 | * @return int Index of the next installer module to execute |
345 | */ |
346 | protected function recover_progress(): int |
347 | { |
348 | $progress_array = $this->install_config->get_progress_data(); |
349 | return (int) $progress_array['last_task_module_index']; |
350 | } |
351 | } |