Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 95 |
|
0.00% |
0 / 6 |
CRAP | |
0.00% |
0 / 1 |
update_files | |
0.00% |
0 / 95 |
|
0.00% |
0 / 6 |
1056 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
check_requirements | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
run | |
0.00% |
0 / 66 |
|
0.00% |
0 / 1 |
600 | |||
get_file_updater | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
20 | |||
get_step_count | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
get_task_lang_name | |
0.00% |
0 / 1 |
|
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\module\update_filesystem\task; |
15 | |
16 | use phpbb\exception\runtime_exception; |
17 | use phpbb\install\exception\resource_limit_reached_exception; |
18 | use phpbb\install\helper\config; |
19 | use phpbb\install\helper\container_factory; |
20 | use phpbb\install\helper\file_updater\factory; |
21 | use phpbb\install\helper\file_updater\file_updater_interface; |
22 | use phpbb\install\helper\iohandler\iohandler_interface; |
23 | use phpbb\install\helper\update_helper; |
24 | use phpbb\install\task_base; |
25 | |
26 | /** |
27 | * File updater task |
28 | */ |
29 | class update_files extends task_base |
30 | { |
31 | /** |
32 | * @var \phpbb\cache\driver\driver_interface |
33 | */ |
34 | protected $cache; |
35 | |
36 | /** |
37 | * @var config |
38 | */ |
39 | protected $installer_config; |
40 | |
41 | /** |
42 | * @var iohandler_interface |
43 | */ |
44 | protected $iohandler; |
45 | |
46 | /** |
47 | * @var factory |
48 | */ |
49 | protected $factory; |
50 | |
51 | /** |
52 | * @var file_updater_interface|null |
53 | */ |
54 | protected $file_updater; |
55 | |
56 | /** |
57 | * @var update_helper |
58 | */ |
59 | protected $update_helper; |
60 | |
61 | /** |
62 | * Constructor |
63 | * |
64 | * @param container_factory $container |
65 | * @param config $config |
66 | * @param iohandler_interface $iohandler |
67 | * @param factory $file_updater_factory |
68 | * @param update_helper $update_helper |
69 | */ |
70 | public function __construct(container_factory $container, config $config, iohandler_interface $iohandler, factory $file_updater_factory, update_helper $update_helper) |
71 | { |
72 | $this->factory = $file_updater_factory; |
73 | $this->installer_config = $config; |
74 | $this->iohandler = $iohandler; |
75 | $this->update_helper = $update_helper; |
76 | |
77 | $this->cache = $container->get('cache.driver'); |
78 | $this->file_updater = null; |
79 | |
80 | parent::__construct(false); |
81 | } |
82 | |
83 | /** |
84 | * {@inheritdoc} |
85 | */ |
86 | public function check_requirements() |
87 | { |
88 | return $this->installer_config->get('do_update_files', false); |
89 | } |
90 | |
91 | /** |
92 | * {@inheritdoc} |
93 | */ |
94 | public function run() |
95 | { |
96 | $new_path = $this->update_helper->get_path_to_new_update_files(); |
97 | |
98 | $file_update_info = $this->installer_config->get('update_files', array()); |
99 | |
100 | $update_type_progress = $this->installer_config->get('file_updater_type_progress', ''); |
101 | $update_elem_progress = $this->installer_config->get('file_updater_elem_progress', ''); |
102 | $type_progress_found = false; |
103 | $elem_progress_found = false; |
104 | |
105 | // Progress bar |
106 | $task_count = 0; |
107 | foreach ($file_update_info as $sub_array) |
108 | { |
109 | $task_count += count($sub_array); |
110 | } |
111 | |
112 | // Everything is up to date, so just continue |
113 | if ($task_count === 0) |
114 | { |
115 | return; |
116 | } |
117 | |
118 | $progress_count = $this->installer_config->get('file_update_progress_count', 0); |
119 | $this->iohandler->set_task_count($task_count, true); |
120 | $this->iohandler->set_progress('UPDATE_UPDATING_FILES', 0); |
121 | |
122 | $this->file_updater = $this->get_file_updater(); |
123 | |
124 | // File updater fallback logic |
125 | try |
126 | { |
127 | // Update files |
128 | foreach ($file_update_info as $type => $file_update_vector) |
129 | { |
130 | if (!$type_progress_found) |
131 | { |
132 | if ($type === $update_type_progress || empty($update_elem_progress)) |
133 | { |
134 | $type_progress_found = true; |
135 | } |
136 | else |
137 | { |
138 | continue; |
139 | } |
140 | } |
141 | |
142 | foreach ($file_update_vector as $path) |
143 | { |
144 | if (!$elem_progress_found) |
145 | { |
146 | if ($path === $update_elem_progress || empty($update_elem_progress)) |
147 | { |
148 | $elem_progress_found = true; |
149 | } |
150 | else |
151 | { |
152 | continue; |
153 | } |
154 | } |
155 | |
156 | switch ($type) |
157 | { |
158 | case 'delete': |
159 | $this->file_updater->delete_file($path); |
160 | break; |
161 | case 'new': |
162 | $this->file_updater->create_new_file($path, $new_path . $path); |
163 | break; |
164 | case 'update_without_diff': |
165 | $this->file_updater->update_file($path, $new_path . $path); |
166 | break; |
167 | case 'update_with_diff': |
168 | $cache_diff_filename = '_file_' . md5($path); |
169 | if ($this->cache->_exists($cache_diff_filename)) |
170 | { |
171 | $this->file_updater->update_file( |
172 | $path, |
173 | base64_decode($this->cache->get($cache_diff_filename)), |
174 | true |
175 | ); |
176 | } |
177 | break; |
178 | } |
179 | |
180 | // Save progress |
181 | $this->installer_config->set('file_updater_type_progress', $type); |
182 | $this->installer_config->set('file_updater_elem_progress', $path); |
183 | $progress_count++; |
184 | $this->iohandler->set_progress('UPDATE_UPDATING_FILES', $progress_count); |
185 | |
186 | if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0) |
187 | { |
188 | // Request refresh |
189 | throw new resource_limit_reached_exception(); |
190 | } |
191 | } |
192 | } |
193 | |
194 | $this->iohandler->finish_progress('UPDATE_UPDATING_FILES'); |
195 | } |
196 | catch (runtime_exception $e) |
197 | { |
198 | if ($e instanceof resource_limit_reached_exception) |
199 | { |
200 | throw new resource_limit_reached_exception(); |
201 | } |
202 | |
203 | $current_method = $this->installer_config->get('file_update_method', ''); |
204 | |
205 | // File updater failed, try to fallback to download file update mode |
206 | if ($current_method !== 'compression') |
207 | { |
208 | $this->iohandler->add_warning_message(array( |
209 | 'UPDATE_FILE_UPDATER_HAS_FAILED', |
210 | $current_method, |
211 | 'compression' |
212 | )); |
213 | $this->installer_config->set('file_update_method', 'compression'); |
214 | |
215 | // We only want a simple refresh here |
216 | throw new resource_limit_reached_exception(); |
217 | } |
218 | else |
219 | { |
220 | // Nowhere to fallback to :( |
221 | // Due to the way the installer handles fatal errors, we need to throw a low level exception |
222 | throw new runtime_exception('UPDATE_FILE_UPDATERS_HAVE_FAILED'); |
223 | } |
224 | } |
225 | |
226 | $file_updater_method = $this->installer_config->get('file_update_method', ''); |
227 | if ($file_updater_method === 'compression' || $file_updater_method === 'ftp' && method_exists($this->file_updater, 'close')) |
228 | { |
229 | $this->file_updater->close(); |
230 | } |
231 | } |
232 | |
233 | /** |
234 | * Get file updater |
235 | * |
236 | * @param null|string $file_updater_method Name of the file updater to use |
237 | * |
238 | * @return file_updater_interface File updater |
239 | */ |
240 | protected function get_file_updater($file_updater_method = null) |
241 | { |
242 | $file_updater_method = ($file_updater_method === null) ? $this->installer_config->get('file_update_method', '') : $file_updater_method; |
243 | |
244 | if ($file_updater_method === 'compression') |
245 | { |
246 | $compression_method = $this->installer_config->get('file_update_compression', ''); |
247 | |
248 | /** @var \phpbb\install\helper\file_updater\compression_file_updater $file_updater */ |
249 | $file_updater = $this->factory->get('compression'); |
250 | $archive_path = $file_updater->init($compression_method); |
251 | $this->installer_config->set('update_file_archive', $archive_path); |
252 | } |
253 | else if ($file_updater_method === 'ftp') |
254 | { |
255 | /** @var \phpbb\install\helper\file_updater\ftp_file_updater $file_updater */ |
256 | $file_updater = $this->factory->get('ftp'); |
257 | $file_updater->init( |
258 | $this->installer_config->get('ftp_method', ''), |
259 | $this->installer_config->get('ftp_host', ''), |
260 | $this->installer_config->get('ftp_user', ''), |
261 | $this->installer_config->get('ftp_pass', ''), |
262 | $this->installer_config->get('ftp_path', ''), |
263 | $this->installer_config->get('ftp_port', 0), |
264 | $this->installer_config->get('ftp_timeout', 10) |
265 | ); |
266 | } |
267 | else |
268 | { |
269 | /** @var file_updater_interface $file_updater */ |
270 | $file_updater = $this->factory->get('direct_file'); |
271 | } |
272 | |
273 | return $file_updater; |
274 | } |
275 | |
276 | /** |
277 | * {@inheritdoc} |
278 | */ |
279 | public static function get_step_count() |
280 | { |
281 | return 0; |
282 | } |
283 | |
284 | /** |
285 | * {@inheritdoc} |
286 | */ |
287 | public function get_task_lang_name() |
288 | { |
289 | return ''; |
290 | } |
291 | } |