1 | <?php |
||||
2 | /** |
||||
3 | * webtrees: online genealogy |
||||
4 | * Copyright (C) 2019 webtrees development team |
||||
5 | * This program is free software: you can redistribute it and/or modify |
||||
6 | * it under the terms of the GNU General Public License as published by |
||||
7 | * the Free Software Foundation, either version 3 of the License, or |
||||
8 | * (at your option) any later version. |
||||
9 | * This program is distributed in the hope that it will be useful, |
||||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
12 | * GNU General Public License for more details. |
||||
13 | * You should have received a copy of the GNU General Public License |
||||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
||||
15 | */ |
||||
16 | namespace Fisharebest\Webtrees; |
||||
17 | |||||
18 | use Exception; |
||||
19 | use Fisharebest\Webtrees\Controller\PageController; |
||||
20 | use Fisharebest\Webtrees\Functions\Functions; |
||||
21 | use Fisharebest\Webtrees\Functions\FunctionsDate; |
||||
22 | use PclZip; |
||||
23 | |||||
24 | define('WT_SCRIPT_NAME', 'admin_site_upgrade.php'); |
||||
25 | |||||
26 | require './includes/session.php'; |
||||
27 | |||||
28 | // Check for updates |
||||
29 | $latest_version_txt = Functions::fetchLatestVersion(); |
||||
30 | if (preg_match('/^[0-9.]+\|[0-9.]+\|/', $latest_version_txt)) { |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
31 | list($latest_version, $earliest_version, $download_url) = explode('|', $latest_version_txt); |
||||
0 ignored issues
–
show
It seems like
$latest_version_txt can also be of type null ; however, parameter $string of explode() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
32 | } else { |
||||
33 | // Cannot determine the latest version |
||||
34 | list($latest_version, $earliest_version, $download_url) = explode('|', '||'); |
||||
35 | } |
||||
36 | |||||
37 | $latest_version_html = '<span dir="ltr">' . $latest_version . '</span>'; |
||||
38 | |||||
39 | // Show a friendly message while the site is being upgraded |
||||
40 | $lock_file = __DIR__ . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'offline.txt'; |
||||
41 | $lock_file_text = I18N::translate('This website is being upgraded. Try again in a few minutes.') . PHP_EOL . FunctionsDate::formatTimestamp(WT_TIMESTAMP) . /* I18N: Timezone - http://en.wikipedia.org/wiki/UTC */ I18N::translate('UTC'); |
||||
42 | |||||
43 | // Success/failure indicators |
||||
44 | $icon_success = '<i class="icon-yes"></i>'; |
||||
45 | $icon_failure = '<i class="icon-failure"></i>'; |
||||
46 | |||||
47 | // Need confirmation for various actions |
||||
48 | $continue = Filter::post('continue', '1') && Filter::checkCsrf(); |
||||
49 | $modules_action = Filter::post('modules', 'ignore|disable'); |
||||
50 | $themes_action = Filter::post('themes', 'ignore|disable'); |
||||
51 | |||||
52 | $controller = new PageController; |
||||
53 | $controller |
||||
54 | ->restrictAccess(Auth::isAdmin()) |
||||
55 | ->setPageTitle(I18N::translate('Upgrade wizard')) |
||||
56 | ->pageHeader(); |
||||
57 | |||||
58 | echo '<h1>', $controller->getPageTitle(), '</h1>'; |
||||
59 | |||||
60 | if ($latest_version == '') { |
||||
61 | echo '<p>', I18N::translate('No upgrade information is available.'), '</p>'; |
||||
62 | |||||
63 | return; |
||||
64 | } |
||||
65 | |||||
66 | if (version_compare(WT_VERSION, $latest_version) >= 0) { |
||||
67 | echo '<p>', I18N::translate('This is the latest version of webtrees. No upgrade is available.'), '</p>'; |
||||
68 | |||||
69 | return; |
||||
70 | } |
||||
71 | |||||
72 | echo '<form method="post" action="admin_site_upgrade.php">'; |
||||
73 | echo Filter::getCsrf(); |
||||
74 | |||||
75 | if ($continue) { |
||||
76 | echo '<input type="hidden" name="continue" value="1">'; |
||||
77 | echo '<p>', I18N::translate('It can take several minutes to download and install the upgrade. Be patient.'), '</p>'; |
||||
78 | } else { |
||||
79 | echo '<p>', I18N::translate('A new version of webtrees is available.'), '</p>'; |
||||
80 | echo '<p>', I18N::translate('Depending on your server configuration, you may be able to upgrade automatically.'), '</p>'; |
||||
81 | echo '<p>', I18N::translate('It can take several minutes to download and install the upgrade. Be patient.'), '</p>'; |
||||
82 | echo '<button type="submit" name="continue" value="1">', /* I18N: %s is a version number, such as 1.2.3 */ I18N::translate('Upgrade to webtrees %s.', $latest_version_html), '</button>'; |
||||
83 | echo '</form>'; |
||||
84 | |||||
85 | return; |
||||
86 | } |
||||
87 | |||||
88 | echo '<ul>'; |
||||
89 | |||||
90 | //////////////////////////////////////////////////////////////////////////////// |
||||
91 | // Cannot upgrade until pending changes are accepted/rejected |
||||
92 | //////////////////////////////////////////////////////////////////////////////// |
||||
93 | |||||
94 | echo '<li>', /* I18N: The system is about to… */ I18N::translate('Check for pending changes…'); |
||||
95 | |||||
96 | $changes = Database::prepare("SELECT 1 FROM `##change` WHERE status='pending' LIMIT 1")->fetchOne(); |
||||
97 | |||||
98 | if ($changes) { |
||||
99 | echo '<br>', I18N::translate('You should accept or reject all pending changes before upgrading.'), $icon_failure; |
||||
100 | echo '<br><button onclick="window.open(\'edit_changes.php\',\'_blank\', chan_window_specs); return false;"">', I18N::translate('Pending changes'), '</button>'; |
||||
101 | echo '</li></ul></form>'; |
||||
102 | |||||
103 | return; |
||||
104 | } else { |
||||
105 | echo '<br>', I18N::translate('There are no pending changes.'), $icon_success; |
||||
106 | } |
||||
107 | |||||
108 | echo '</li>'; |
||||
109 | |||||
110 | //////////////////////////////////////////////////////////////////////////////// |
||||
111 | // Custom modules may not work with the new version. |
||||
112 | //////////////////////////////////////////////////////////////////////////////// |
||||
113 | |||||
114 | echo '<li>', /* I18N: The system is about to [...] */ I18N::translate('Check for custom modules…'); |
||||
115 | |||||
116 | $custom_modules = false; |
||||
117 | foreach (Module::getInstalledModules('disabled') as $module) { |
||||
118 | if (!in_array($module->getName(), Module::getCoreModuleNames())) { |
||||
119 | switch ($modules_action) { |
||||
120 | case 'disable': |
||||
121 | Database::prepare( |
||||
122 | "UPDATE `##module` SET status = 'disabled' WHERE module_name = ?" |
||||
123 | )->execute(array($module->getName())); |
||||
124 | break; |
||||
125 | case 'ignore': |
||||
126 | echo '<br>', I18N::translate('Custom module'), ' — ', WT_MODULES_DIR, $module->getName(), ' — ', $module->getTitle(), $icon_success; |
||||
127 | break; |
||||
128 | default: |
||||
129 | echo '<br>', I18N::translate('Custom module'), ' — ', WT_MODULES_DIR, $module->getName(), ' — ', $module->getTitle(), $icon_failure; |
||||
130 | $custom_modules = true; |
||||
131 | break; |
||||
132 | } |
||||
133 | } |
||||
134 | } |
||||
135 | if ($custom_modules) { |
||||
136 | echo '<br>', I18N::translate('You should consult the module’s author to confirm compatibility with this version of webtrees.'); |
||||
137 | echo '<br>', '<button type="submit" name="modules" value="disable">', I18N::translate('Disable these modules'), '</button> — ', I18N::translate('You can re-enable these modules after the upgrade.'); |
||||
138 | echo '<br>', '<button type="submit" name="modules" value="ignore">', /* I18N: Ignore the warnings, and… */ I18N::translate('Upgrade anyway'), '</button> — ', I18N::translate('Caution: old modules may not work, or they may prevent webtrees from working.'); |
||||
139 | echo '</li></ul></form>'; |
||||
140 | |||||
141 | return; |
||||
142 | } else { |
||||
143 | if ($modules_action != 'ignore') { |
||||
144 | echo '<br>', I18N::translate('No custom modules are enabled.'), $icon_success; |
||||
145 | } |
||||
146 | echo '<input type="hidden" name="modules" value="', Filter::escapeHtml($modules_action), '">'; |
||||
147 | } |
||||
148 | |||||
149 | echo '</li>'; |
||||
150 | |||||
151 | //////////////////////////////////////////////////////////////////////////////// |
||||
152 | // Custom themes may not work with the new version. |
||||
153 | //////////////////////////////////////////////////////////////////////////////// |
||||
154 | |||||
155 | echo '<li>', /* I18N: The system is about to… */ I18N::translate('Check for custom themes…'); |
||||
156 | |||||
157 | $custom_themes = false; |
||||
158 | foreach (Theme::themeNames() as $theme_id => $theme_name) { |
||||
159 | switch ($theme_id) { |
||||
160 | case 'clouds': |
||||
161 | case 'colors': |
||||
162 | case 'fab': |
||||
163 | case 'minimal': |
||||
164 | case 'webtrees': |
||||
165 | case 'xenea': |
||||
166 | break; |
||||
167 | default: |
||||
168 | $theme_used = Database::prepare( |
||||
169 | "SELECT EXISTS (SELECT 1 FROM `##site_setting` WHERE setting_name='THEME_DIR' AND setting_value=?)" . |
||||
170 | " OR EXISTS (SELECT 1 FROM `##gedcom_setting` WHERE setting_name='THEME_DIR' AND setting_value=?)" . |
||||
171 | " OR EXISTS (SELECT 1 FROM `##user_setting` WHERE setting_name='theme' AND setting_value=?)" |
||||
172 | )->execute(array($theme_id, $theme_id, $theme_id))->fetchOne(); |
||||
173 | if ($theme_used) { |
||||
174 | switch ($themes_action) { |
||||
175 | case 'disable': |
||||
176 | Database::prepare( |
||||
177 | "DELETE FROM `##site_setting` WHERE setting_name = 'THEME_DIR' AND setting_value = ?" |
||||
178 | )->execute(array($theme_id)); |
||||
179 | Database::prepare( |
||||
180 | "DELETE FROM `##gedcom_setting` WHERE setting_name = 'THEME_DIR' AND setting_value = ?" |
||||
181 | )->execute(array($theme_id)); |
||||
182 | Database::prepare( |
||||
183 | "DELETE FROM `##user_setting` WHERE setting_name = 'theme' AND setting_value = ?" |
||||
184 | )->execute(array($theme_id)); |
||||
185 | break; |
||||
186 | case 'ignore': |
||||
187 | echo '<br>', I18N::translate('Custom theme'), ' — ', $theme_id, ' — ', $theme_name, $icon_success; |
||||
188 | break; |
||||
189 | default: |
||||
190 | echo '<br>', I18N::translate('Custom theme'), ' — ', $theme_id, ' — ', $theme_name, $icon_failure; |
||||
191 | $custom_themes = true; |
||||
192 | break; |
||||
193 | } |
||||
194 | } |
||||
195 | break; |
||||
196 | } |
||||
197 | } |
||||
198 | |||||
199 | if ($custom_themes) { |
||||
200 | echo '<br>', I18N::translate('You should consult the theme’s author to confirm compatibility with this version of webtrees.'); |
||||
201 | echo '<br>', '<button type="submit" name="themes" value="disable">', I18N::translate('Disable these themes'), '</button> — ', I18N::translate('You can re-enable these themes after the upgrade.'); |
||||
202 | echo '<br>', '<button type="submit" name="themes" value="ignore">', I18N::translate('Upgrade anyway'), '</button> — ', I18N::translate('Caution: old themes may not work, or they may prevent webtrees from working.'); |
||||
203 | echo '</li></ul></form>'; |
||||
204 | |||||
205 | return; |
||||
206 | } else { |
||||
207 | if ($themes_action != 'ignore') { |
||||
208 | echo '<br>', I18N::translate('No custom themes are enabled.'), $icon_success; |
||||
209 | } |
||||
210 | echo '<input type="hidden" name="themes" value="', Filter::escapeHtml($themes_action), '">'; |
||||
211 | } |
||||
212 | |||||
213 | echo '</li>'; |
||||
214 | |||||
215 | //////////////////////////////////////////////////////////////////////////////// |
||||
216 | // Make a backup of genealogy data |
||||
217 | //////////////////////////////////////////////////////////////////////////////// |
||||
218 | |||||
219 | echo '<li>', /* I18N: The system is about to… */ I18N::translate('Export all the family trees to GEDCOM files…'); |
||||
220 | |||||
221 | foreach (Tree::getAll() as $tree) { |
||||
222 | reset_timeout(); |
||||
223 | $filename = WT_DATA_DIR . $tree->getName() . date('-Y-m-d') . '.ged'; |
||||
224 | |||||
225 | try { |
||||
226 | // To avoid partial trees on timeout/diskspace/etc, write to a temporary file first |
||||
227 | $stream = fopen($filename . '.tmp', 'w'); |
||||
228 | $tree->exportGedcom($stream); |
||||
229 | fclose($stream); |
||||
230 | rename($filename . '.tmp', $filename); |
||||
231 | echo '<br>', I18N::translate('The family tree has been exported to %s.', Html::filename($filename)), $icon_success; |
||||
232 | } catch (\ErrorException $ex) { |
||||
233 | echo '<br>', I18N::translate('The file %s could not be created.', Html::filename($filename)), $icon_failure; |
||||
234 | } |
||||
235 | } |
||||
236 | |||||
237 | echo '</li>'; |
||||
238 | |||||
239 | //////////////////////////////////////////////////////////////////////////////// |
||||
240 | // Download a .ZIP file containing the new code |
||||
241 | //////////////////////////////////////////////////////////////////////////////// |
||||
242 | |||||
243 | echo '<li>', /* I18N: The system is about to…; %s is a URL. */ I18N::translate('Download %s…', Html::filename($download_url)); |
||||
244 | |||||
245 | $zip_file = WT_DATA_DIR . basename($download_url); |
||||
246 | $zip_dir = WT_DATA_DIR . basename($download_url, '.zip'); |
||||
247 | $zip_stream = fopen($zip_file, 'w'); |
||||
248 | reset_timeout(); |
||||
249 | $start_time = microtime(true); |
||||
250 | File::fetchUrl($download_url, $zip_stream); |
||||
251 | $end_time = microtime(true); |
||||
252 | $zip_size = filesize($zip_file); |
||||
253 | fclose($zip_stream); |
||||
254 | |||||
255 | echo '<br>', /* I18N: %1$s is a number of KB, %2$s is a (fractional) number of seconds */ I18N::translate('%1$s KB were downloaded in %2$s seconds.', I18N::number($zip_size / 1024), I18N::number($end_time - $start_time, 2)); |
||||
256 | if ($zip_size) { |
||||
257 | echo $icon_success; |
||||
258 | } else { |
||||
259 | echo $icon_failure; |
||||
260 | // Guess why we might have failed... |
||||
261 | if (preg_match('/^https:/', $download_url) && !in_array('ssl', stream_get_transports())) { |
||||
262 | echo '<br>', /* I18N: http://en.wikipedia.org/wiki/Https */ I18N::translate('This server does not support secure downloads using HTTPS.'); |
||||
263 | } |
||||
264 | } |
||||
265 | |||||
266 | echo '</li>'; |
||||
267 | |||||
268 | //////////////////////////////////////////////////////////////////////////////// |
||||
269 | // Unzip the file - this checks we have enough free disk space, that the .zip |
||||
270 | // file is valid, etc. |
||||
271 | //////////////////////////////////////////////////////////////////////////////// |
||||
272 | |||||
273 | echo '<li>', /* I18N: The system is about to…; %s is a .ZIP file. */ I18N::translate('Unzip %s to a temporary folder…', Html::filename(basename($download_url))); |
||||
274 | |||||
275 | File::delete($zip_dir); |
||||
276 | File::mkdir($zip_dir); |
||||
277 | |||||
278 | $archive = new PclZip($zip_file); |
||||
279 | |||||
280 | $res = $archive->properties(); |
||||
281 | if (!is_array($res) || $res['status'] != 'ok') { |
||||
282 | echo '<br>', I18N::translate('An error occurred when unzipping the file.'), $icon_failure; |
||||
283 | echo '<br>', $archive->errorInfo(true); |
||||
284 | echo '</li></ul></form>'; |
||||
285 | |||||
286 | return; |
||||
287 | } |
||||
288 | |||||
289 | $num_files = $res['nb']; |
||||
290 | |||||
291 | reset_timeout(); |
||||
292 | $start_time = microtime(true); |
||||
293 | $res = $archive->extract( |
||||
294 | \PCLZIP_OPT_PATH, $zip_dir, |
||||
295 | \PCLZIP_OPT_REMOVE_PATH, 'webtrees', |
||||
296 | \PCLZIP_OPT_REPLACE_NEWER |
||||
297 | ); |
||||
298 | $end_time = microtime(true); |
||||
299 | |||||
300 | if (is_array($res)) { |
||||
301 | foreach ($res as $result) { |
||||
302 | // Note that we're stripping the initial "webtrees/", so the top folder will fail. |
||||
303 | if ($result['status'] != 'ok' && $result['filename'] != 'webtrees/') { |
||||
304 | echo '<br>', I18N::translate('An error occurred when unzipping the file.'), $icon_failure; |
||||
305 | echo '<pre>', $result['status'], '</pre>'; |
||||
306 | echo '<pre>', $result['filename'], '</pre>'; |
||||
307 | echo '</li></ul></form>'; |
||||
308 | |||||
309 | return; |
||||
310 | } |
||||
311 | } |
||||
312 | echo '<br>', /* I18N: …from the .ZIP file, %2$s is a (fractional) number of seconds */ I18N::plural('%1$s file was extracted in %2$s seconds.', '%1$s files were extracted in %2$s seconds.', count($res), count($res), I18N::number($end_time - $start_time, 2)), $icon_success; |
||||
313 | } else { |
||||
314 | echo '<br>', I18N::translate('An error occurred when unzipping the file.'), $icon_failure; |
||||
315 | echo '<pre>', $archive->errorInfo(true), '</pre>'; |
||||
316 | echo '</li></ul></form>'; |
||||
317 | |||||
318 | return; |
||||
319 | } |
||||
320 | |||||
321 | echo '</li>'; |
||||
322 | |||||
323 | //////////////////////////////////////////////////////////////////////////////// |
||||
324 | // This is it - take the site offline first |
||||
325 | //////////////////////////////////////////////////////////////////////////////// |
||||
326 | |||||
327 | echo '<li>', /* I18N: The system is about to… */ I18N::translate('Check file permissions…'); |
||||
328 | |||||
329 | reset_timeout(); |
||||
330 | $iterator = new \RecursiveDirectoryIterator($zip_dir); |
||||
331 | $iterator->setFlags(\RecursiveDirectoryIterator::SKIP_DOTS); |
||||
332 | foreach (new \RecursiveIteratorIterator($iterator) as $file) { |
||||
333 | $file = WT_ROOT . substr($file, strlen($zip_dir) + 1); |
||||
334 | if (file_exists($file) && (!is_readable($file) || !is_writable($file))) { |
||||
335 | echo '<br>', I18N::translate('The file %s could not be updated.', Html::filename($file)), $icon_failure; |
||||
336 | echo '</li></ul>'; |
||||
337 | echo '<p class="error">', I18N::translate('To complete the upgrade, you should install the files manually.'), '</p>'; |
||||
338 | echo '<p>', I18N::translate('The new files are currently located in the folder %s.', Html::filename($zip_dir)), '</p>'; |
||||
339 | echo '<p>', I18N::translate('Copy these files to the folder %s, replacing any that have the same name.', Html::filename(WT_ROOT)), '</p>'; |
||||
340 | echo '<p>', I18N::translate('To prevent visitors from accessing the website while you are in the middle of copying files, you can temporarily create a file %s on the server. If it contains a message, it will be displayed to visitors.', Html::filename($lock_file)), '</p>'; |
||||
341 | |||||
342 | return; |
||||
343 | } |
||||
344 | } |
||||
345 | |||||
346 | echo '<br>', I18N::translate('All files have read and write permission.'), $icon_success; |
||||
347 | |||||
348 | echo '</li>'; |
||||
349 | |||||
350 | //////////////////////////////////////////////////////////////////////////////// |
||||
351 | // This is it - take the site offline first |
||||
352 | //////////////////////////////////////////////////////////////////////////////// |
||||
353 | |||||
354 | echo '<li>', I18N::translate('Place the website offline, by creating the file %s…', $lock_file); |
||||
355 | |||||
356 | try { |
||||
357 | file_put_contents($lock_file, $lock_file_text); |
||||
358 | echo '<br>', I18N::translate('The file %s has been created.', Html::filename($lock_file)), $icon_success; |
||||
359 | } catch (\ErrorException $ex) { |
||||
360 | echo '<br>', I18N::translate('The file %s could not be created.', Html::filename($lock_file)), $icon_failure; |
||||
361 | } |
||||
362 | |||||
363 | echo '</li>'; |
||||
364 | |||||
365 | //////////////////////////////////////////////////////////////////////////////// |
||||
366 | // Copy files |
||||
367 | //////////////////////////////////////////////////////////////////////////////// |
||||
368 | |||||
369 | echo '<li>', /* I18N: The system is about to… */ I18N::translate('Copy files…'); |
||||
370 | |||||
371 | // The wiki tells people how to customize webtrees by modifying various files. |
||||
372 | // Create a backup of these, just in case the user forgot! |
||||
373 | try { |
||||
374 | copy('app/GedcomCode/GedcomCode/Rela.php', WT_DATA_DIR . 'GedcomCodeRela' . date('-Y-m-d') . '.php'); |
||||
375 | copy('app/GedcomTag.php', WT_DATA_DIR . 'GedcomTag' . date('-Y-m-d') . '.php'); |
||||
376 | } catch (\ErrorException $ex) { |
||||
377 | // No problem if we cannot do this. |
||||
378 | } |
||||
379 | |||||
380 | reset_timeout(); |
||||
381 | $start_time = microtime(true); |
||||
382 | $res = $archive->extract( |
||||
383 | \PCLZIP_OPT_PATH, WT_ROOT, |
||||
384 | \PCLZIP_OPT_REMOVE_PATH, 'webtrees', |
||||
385 | \PCLZIP_OPT_REPLACE_NEWER |
||||
386 | ); |
||||
387 | $end_time = microtime(true); |
||||
388 | |||||
389 | if (is_array($res)) { |
||||
390 | foreach ($res as $result) { |
||||
391 | // Note that most of the folders will already exist, so it is not an error if we cannot create them |
||||
392 | if ($result['status'] != 'ok' && !substr($result['filename'], -1) == '/') { |
||||
393 | echo '<br>', I18N::translate('The file %s could not be created.', Html::filename($result['filename'])), $icon_failure; |
||||
394 | } |
||||
395 | } |
||||
396 | echo '<br>', /* I18N: …from the .ZIP file, %2$s is a (fractional) number of seconds */ I18N::plural('%1$s file was extracted in %2$s seconds.', '%1$s files were extracted in %2$s seconds.', count($res), count($res), I18N::number($end_time - $start_time, 2)), $icon_success; |
||||
397 | } else { |
||||
398 | echo '<br>', I18N::translate('An error occurred when unzipping the file.'), $icon_failure; |
||||
399 | echo '</li></ul></form>'; |
||||
400 | |||||
401 | return; |
||||
402 | } |
||||
403 | |||||
404 | echo '</li>'; |
||||
405 | |||||
406 | //////////////////////////////////////////////////////////////////////////////// |
||||
407 | // All done - put the site back online |
||||
408 | //////////////////////////////////////////////////////////////////////////////// |
||||
409 | |||||
410 | echo '<li>', I18N::translate('Place the website online, by deleting the file %s…', Html::filename($lock_file)); |
||||
411 | |||||
412 | if (File::delete($lock_file)) { |
||||
413 | echo '<br>', I18N::translate('The file %s has been deleted.', Html::filename($lock_file)), $icon_success; |
||||
414 | } else { |
||||
415 | echo '<br>', I18N::translate('The file %s could not be deleted.', Html::filename($lock_file)), $icon_failure; |
||||
416 | } |
||||
417 | |||||
418 | echo '</li>'; |
||||
419 | |||||
420 | //////////////////////////////////////////////////////////////////////////////// |
||||
421 | // Clean up |
||||
422 | //////////////////////////////////////////////////////////////////////////////// |
||||
423 | |||||
424 | echo '<li>', /* I18N: The system is about to… */ I18N::translate('Delete temporary files…'); |
||||
425 | |||||
426 | reset_timeout(); |
||||
427 | if (File::delete($zip_dir)) { |
||||
428 | echo '<br>', I18N::translate('The folder %s has been deleted.', Html::filename($zip_dir)), $icon_success; |
||||
429 | } else { |
||||
430 | echo '<br>', I18N::translate('The folder %s could not be deleted.', Html::filename($zip_dir)), $icon_failure; |
||||
431 | } |
||||
432 | |||||
433 | if (File::delete($zip_file)) { |
||||
434 | echo '<br>', I18N::translate('The file %s has been deleted.', Html::filename($zip_file)), $icon_success; |
||||
435 | } else { |
||||
436 | echo '<br>', I18N::translate('The file %s could not be deleted.', Html::filename($zip_file)), $icon_failure; |
||||
437 | } |
||||
438 | |||||
439 | echo '</li>'; |
||||
440 | echo '</ul>'; |
||||
441 | |||||
442 | // We have updated the language files. |
||||
443 | foreach (glob(WT_DATA_DIR . 'cache/language-*') as $file) { |
||||
444 | File::delete($file); |
||||
445 | } |
||||
446 | |||||
447 | echo '<p>', I18N::translate('The upgrade is complete.'), '</p>'; |
||||
448 | |||||
449 | echo '<p><a href="index.php" class="btn btn-primary">', I18N::translate('continue'), '</a></p>'; |
||||
450 | |||||
451 | /** |
||||
452 | * Reset the time limit, as timeouts in this script could leave the upgrade incomplete. |
||||
453 | */ |
||||
454 | function reset_timeout() |
||||
455 | { |
||||
456 | if (!ini_get('safe_mode') && strpos(ini_get('disable_functions'), 'set_time_limit') === false) { |
||||
457 | try { |
||||
458 | set_time_limit(ini_get('max_execution_time')); |
||||
0 ignored issues
–
show
ini_get('max_execution_time') of type string is incompatible with the type integer expected by parameter $seconds of set_time_limit() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
459 | } catch (Exception $ex) { |
||||
460 | // "set_time_limt(): Cannot set max execution time limit due to system policy" |
||||
461 | } |
||||
462 | } |
||||
463 | } |
||||
464 |