diff --git a/Controller/UpdateController.php b/Controller/UpdateController.php index b44662b..f8d3aaf 100644 --- a/Controller/UpdateController.php +++ b/Controller/UpdateController.php @@ -6,6 +6,7 @@ error_reporting(error_level: E_ALL); use DirectoryIterator; use Exception; +use JetBrains\PhpStorm\NoReturn; use PDO; use PharData; @@ -18,504 +19,561 @@ const SUPPORTED_RELEASE_MINOR = 2; */ class UpdateController { - function handleUpdate(): void - { - define(constant_name: "PHPBB_ROOT_PATH", value: dirname(path: __DIR__, levels: 2)); - - $phpBBRootPath = PHPBB_ROOT_PATH . '/'; - $phpEx = substr(string: strrchr(haystack: __FILE__, needle: '.'), offset: 1); - - - // sanity checks - - if (strtoupper(string: substr(string: PHP_OS, offset: 0, length: 3)) === 'WIN') { - echo 'This program must not be used on Windows installations.' . PHP_EOL; - exit(1); - } - - if (PHP_VERSION_ID < 80100) { - echo 'You need at least php version 8.1.0'; - exit(1); - } - - if (php_sapi_name() !== 'cli') { - echo 'This program must be run from the command line.' . PHP_EOL; - exit(1); - } - - if (!extension_loaded(extension: 'bz2')) { - echo 'You need to install/enable the bz2 PHP extension' . PHP_EOL; - exit(1); - } - - include $phpBBRootPath . 'config.php'; - - /** @var String $dbhost */ - /** @var String $dbport */ - /** @var String $dbname */ - /** @var String $dbuser */ - /** @var String $dbpasswd */ - $pdo = new PDO( - dsn : "mysql:host=$dbhost;port=$dbport;charset=utf8mb4;dbname=$dbname", - username: $dbuser, - password: $dbpasswd - ); - - - /** @var String $table_prefix */ - $sql = "SELECT config_value FROM ${table_prefix}config WHERE config_name = 'version'"; - $statement = $pdo->prepare(query: $sql); - $statement->execute(); - $result = $statement->fetch(); - - $installedVersion = $result['config_value']; - print("Installed version: phpBB $installedVersion" . PHP_EOL); - - // phpBB has major, minor and maintenance version scheme - [$major, $minor, $patch] = explode(separator: '.', string: $installedVersion); - if ((intval(value: $major) != SUPPORTED_RELEASE_MAJOR) || (intval(value: $minor) < SUPPORTED_RELEASE_MINOR)) { - echo 'This script only supports phpBB ' . SUPPORTED_RELEASE_MAJOR . '.' . SUPPORTED_RELEASE_MINOR . ' and above branch.', PHP_EOL; - exit(1); - } - - $json = file_get_contents(filename: 'https://version.phpbb.com/phpbb/versions.json'); - $versions = json_decode(json: $json); - - $stableVersions = $versions->stable; - $availableUpdate = $stableVersions->{$major . '.' . $minor}->{'current'}; - - echo 'Current Version: ' . $availableUpdate . PHP_EOL; - - // check for existing update - if (!file_exists(filename: 'dist')) { - echo "'dist' folder is missing, create a new one …'"; - mkdir(directory: 'dist'); - } - - $currentFile = "phpBB-$availableUpdate.tar.bz2"; - - $phpBBTarget = "dist/$currentFile"; - - if (!file_exists(filename: $phpBBTarget)) { - echo "Downloading $currentFile" . PHP_EOL; - $filePath = "https://download.phpbb.com/pub/release/$major.$minor/$availableUpdate/$currentFile"; - $phpBBtbz = file_get_contents(filename: $filePath); - file_put_contents(filename: $phpBBTarget, data: $phpBBtbz); - } else { - echo $currentFile . ' already exists' . PHP_EOL; - } - - // TODO check SHA256? - - // check for available language files - - $useLangDeDu = false; - if (file_exists(filename: $phpBBRootPath . 'language/de')) { - $useLangDeDu = true; - $languageFile = "phpBB_lang_de-$availableUpdate.tar.bz2"; - $langDeDuTarget = "dist/$languageFile"; - - if (!file_exists(filename: $langDeDuTarget)) { - echo "Downloading language $languageFile" . PHP_EOL; - $filePath = "https://downloads.phpbb.de/pakete/deutsch/$major.$minor/$availableUpdate/$languageFile"; - if (file_exists(filename: $filePath)) { - $phpBBtbz = file_get_contents(filename: $filePath); - file_put_contents(filename: $langDeDuTarget, data: $phpBBtbz); - } else { - echo "Language file $languageFile does not exist." . PHP_EOL; - $useLangDeDu = false; - } - } else { - echo 'Language file ' . $languageFile . ' already exists' . PHP_EOL; - } - } else { - echo 'Language Deutsch "Du" ist not installed, skipping' . PHP_EOL; - } - - $useLangDeSie = false; - if (file_exists(filename: $phpBBRootPath . 'language/de_x_sie')) { - $useLangDeSie = true; - $languageFile = "phpBB_lang_de_x_sie-$availableUpdate.tar.bz2"; - $langDeSieTarget = "dist/$languageFile"; - - if (!file_exists(filename: $langDeSieTarget)) { - echo "Downloading language $languageFile" . PHP_EOL; - $filePath = "https://downloads.phpbb.de/pakete/deutsch/$major.$minor/$availableUpdate/$languageFile"; - if (file_exists(filename: $filePath)) { - $phpBBtbz = file_get_contents(filename: $filePath); - file_put_contents(filename: $langDeSieTarget, data: $phpBBtbz); - } else { - echo 'Language file ' . $languageFile . ' does not exist' . PHP_EOL; - $useLangDeSie = false; - } - } else { - echo 'Language file ' . $languageFile . ' already exists' . PHP_EOL; - } - } else { - echo 'Language Deutsch "Sie" ist not installed, skipping' . PHP_EOL; - } - - if (!$this->confirm(message: 'Do you want to proceed with the update now?')) { - exit(0); - } - - // ok, start update - $now = date(format: 'd.m.Y H:i'); - $disableMsg = "Software-update at $now, the forum ist down due to maintenance. We'll be back soon."; - $sql = "UPDATE ${table_prefix}config SET config_value = :disable_message WHERE config_name = 'board_disable_msg'"; - $statement = $pdo->prepare(query: $sql); - $statement->bindParam(param: 'disable_message', var: $disableMsg); - - if ($statement->execute()) { - echo "Disable Message set …", PHP_EOL; - } else { - echo 'There was an error talking to the DB.' . PHP_EOL; - echo 'Failed SQL-statement: ' . $sql . PHP_EOL; - exit(1); - } - - $sql = "UPDATE ${table_prefix}config SET config_value = '1' WHERE config_name = 'board_disable'"; - $statement = $pdo->prepare(query: $sql); - if ($statement->execute()) { - echo "Board disabled …", PHP_EOL; - } else { - echo 'There was an error talking to the DB.' . PHP_EOL; - echo 'Failed SQL-statement: ' . $sql . PHP_EOL; - exit(1); - } - - $extensionsFile = 'extensions.txt'; - - if (file_exists(filename: $extensionsFile)) { - echo 'Extensions state already stored. Remove extensions.txt if you wish to recreate it.' . PHP_EOL; - } else { - // check for enabled extensions - $sql = "SELECT ext_name FROM ${table_prefix}ext WHERE ext_active = '1'"; - $statement = $pdo->prepare(query: $sql); - if ($statement->execute()) { - $result = $statement->fetchAll(); - - if (count(value: $result) > 0) { - $extensions = json_encode(value: $result); - - // safe enabled extensions - $oFile = fopen(filename: 'extensions.txt', mode: 'w'); - fputs(stream: $oFile, data: $extensions); - fclose(stream: $oFile); - echo 'Stored extensions state'; - - // disable all extensions - $sql = "UPDATE ${table_prefix}ext SET ext_active = '0' WHERE ext_active = '1'"; - $statement = $pdo->prepare(query: $sql); - if ($statement->execute()) { - echo 'Disabled all extensions'; - } - } - - } - } - - $stylesFile = 'styles.txt'; - if (file_exists(filename: $stylesFile)) { - echo 'Styles state already stored. Remove styles.txt if you wish to recreate it' . PHP_EOL; - } else { - // check for enabled style - $sql = "SELECT style_name FROM ${table_prefix}styles WHERE style_active = '1'"; - $statement = $pdo->prepare(query: $sql); - if ($statement->execute()) { - $result = $statement->fetchAll(); - - if (count(value: $result) > 0) { - $styles = json_encode(value: $result); - - // safe enabled styles - $oFile = fopen(filename: 'styles.txt', mode: 'w'); - fputs(stream: $oFile, data: $styles); - fclose(stream: $oFile); - echo 'Stored styles state.' . PHP_EOL; - - // disable all styles except prosilver - $sql = "UPDATE ${table_prefix}styles SET style_active = '0' WHERE NOT style_name = 'prosilver'"; - $statement = $pdo->prepare(query: $sql); - if ($statement->execute()) { - echo 'Disabled all styles except prosilver.' . PHP_EOL; - } - } - - } - } - - // update phpBB - $data = new PharData(filename: $phpBBTarget); - try { - unset($data['phpBB3/config.php']); - unset($data['phpBB3/.htaccess']); - } catch (Exception $e) { - echo 'error: ', $e; - } - - // remove all old files - $excludes = [ - 'config.php', - '.htaccess', - '.htpasswd', - 'images', - 'files', - 'ext', - 'styles', - 'store', - 'updates', - 'mobiquo']; - // this will fuck up nearly all modified boards, leave the files alone by default. - // It will also destroy any API-keys and whatever you might have in your document root. - // deleteDirectory($phpbb_root_path, $excludes); - - - try { - $data->extractTo(directory: $phpBBRootPath); - - $fromDir = $phpBBRootPath . 'phpBB3/'; - $toDir = $phpBBRootPath; - - $this->copyDirectory(source: $fromDir, target: $toDir); - $this->deleteDirectory(dir: $fromDir); - } catch (Exception $e) { - print("Error while extracting $data: $e"); - exit(1); - } - echo 'Moved the update in place.', PHP_EOL; - - $fileOwner = fileowner(filename: $phpBBRootPath); - $fileGroup = filegroup(filename: $phpBBRootPath); - $fileOwnerName = posix_getpwuid(user_id: $fileOwner)['name']; - $fileGroupName = posix_getgrgid(group_id: $fileGroup)['name']; - - - echo 'Check file owner', PHP_EOL; - print("You might need to perform 'chown -R $fileOwnerName:$fileGroupName $phpBBRootPath'" . PHP_EOL); - - echo 'prepare config.yml.', PHP_EOL; - $oFile = fopen(filename: $phpBBRootPath . '/update-config.yml', mode: 'w'); - fputs(stream: $oFile, data: 'updater:' . PHP_EOL . " type: db_only" . PHP_EOL); - fclose(stream: $oFile); - - $command = <<dryRun) { + include $phpBBRootPath . 'config.php'; + + /** @var String $dbhost */ + /** @var String $dbport */ + /** @var String $dbname */ + /** @var String $dbuser */ + /** @var String $dbpasswd */ + $pdo = new PDO( + dsn: "mysql:host=$dbhost;port=$dbport;charset=utf8mb4;dbname=$dbname", + username: $dbuser, + password: $dbpasswd + ); + + + /** @var String $table_prefix */ + $sql = "SELECT config_value FROM {$table_prefix}config WHERE config_name = 'version'"; + $statement = $pdo->prepare(query: $sql); + $statement->execute(); + $result = $statement->fetch(); + + $installedVersion = $result['config_value']; + print("Installed version: phpBB $installedVersion" . PHP_EOL); + + // phpBB has major, minor and maintenance version scheme + [$major, $minor, $patch] = explode(separator: '.', string: $installedVersion); + if ((intval(value: $major) != SUPPORTED_RELEASE_MAJOR) || (intval(value: $minor) < SUPPORTED_RELEASE_MINOR)) { + echo 'This script only supports phpBB ' . SUPPORTED_RELEASE_MAJOR . '.' . SUPPORTED_RELEASE_MINOR . ' and above branch.', PHP_EOL; + exit(1); + } + } + + echo "Checking for the current version …" . PHP_EOL; + $json = file_get_contents(filename: 'https://version.phpbb.com/phpbb/versions.json'); + $versions = json_decode(json: $json, associative: true); + + $stableVersions = $versions['stable']; + + // Get the highest stable version + $highestStableVersion = null; + foreach ($stableVersions as $version => $details) { + if ($highestStableVersion === null || version_compare(version1: $version, version2: $highestStableVersion, operator: '>')) { + $highestStableVersion = $version; + } + } + + echo "Highest Stable Version: $highestStableVersion" . PHP_EOL; + if (!$this->dryRun) { + echo "Installed Version: $installedVersion" . PHP_EOL; + } + + [$major, $minor, $patch] = explode(separator: '.', string: $stableVersions[$highestStableVersion]['current']); + echo "Latest stable release: $major.$minor.$patch" . PHP_EOL; + $availableUpdate = $stableVersions[$highestStableVersion]['current']; + // check for existing update + if (!file_exists(filename: 'dist')) { + echo "'dist' folder is missing, create a new one …'"; + mkdir(directory: 'dist'); + } + + $currentFile = "phpBB-$availableUpdate.tar.bz2"; + + $phpBBTarget = "dist/$currentFile"; + + if (!file_exists(filename: $phpBBTarget)) { + echo "Downloading $currentFile" . PHP_EOL; + $filePath = "https://download.phpbb.com/pub/release/$major.$minor/$availableUpdate/$currentFile"; + $phpBBtbz = file_get_contents(filename: $filePath); + file_put_contents(filename: $phpBBTarget, data: $phpBBtbz); + } else { + echo $currentFile . ' already exists. Skipping download.' . PHP_EOL; + } + + // TODO check SHA256? + + // check for available language files + + $useLangDeDu = false; + if (file_exists(filename: $phpBBRootPath . 'language/de')) { + $useLangDeDu = true; + // https://downloads.phpbb.de/pakete/deutsch/3.3/3.3.10/phpBB_lang_de-3.3.10.tar.bz2 + $languageFile = "phpBB_lang_de-$availableUpdate.tar.bz2"; + echo "language file: $languageFile"; + $langDeDuTarget = "dist/$languageFile"; + + if (!file_exists(filename: $langDeDuTarget)) { + echo "Downloading language $languageFile" . PHP_EOL; + $filePath = "https://downloads.phpbb.de/pakete/deutsch/$major.$minor/$availableUpdate/$languageFile"; + if (file_exists(filename: $filePath)) { + $phpBBtbz = file_get_contents(filename: $filePath); + file_put_contents(filename: $langDeDuTarget, data: $phpBBtbz); + } else { + echo "Language file $languageFile does not exist." . PHP_EOL; + $useLangDeDu = false; + } + } else { + echo 'Language file ' . $languageFile . ' already exists' . PHP_EOL; + } + } else { + echo 'Language Deutsch "Du" ist not installed, skipping' . PHP_EOL; + } + + $useLangDeSie = false; + if (file_exists(filename: $phpBBRootPath . 'language/de_x_sie')) { + $useLangDeSie = true; + $languageFile = "phpBB_lang_de_x_sie-$availableUpdate.tar.bz2"; + $langDeSieTarget = "dist/$languageFile"; + + if (!file_exists(filename: $langDeSieTarget)) { + echo "Downloading language $languageFile" . PHP_EOL; + $filePath = "https://downloads.phpbb.de/pakete/deutsch/$major.$minor/$availableUpdate/$languageFile"; + if (file_exists(filename: $filePath)) { + $phpBBtbz = file_get_contents(filename: $filePath); + file_put_contents(filename: $langDeSieTarget, data: $phpBBtbz); + } else { + echo 'Language file ' . $languageFile . ' does not exist' . PHP_EOL; + $useLangDeSie = false; + } + } else { + echo 'Language file ' . $languageFile . ' already exists' . PHP_EOL; + } + } else { + echo 'Language Deutsch "Sie" ist not installed, skipping' . PHP_EOL; + } + + if (!$this->confirm(message: 'Do you want to proceed with the update now?')) { + exit(0); + } + + if ($this->dryRun) { + echo 'Dry run, exiting.' . PHP_EOL; + exit(0); + } + + // ok, start update + $now = date(format: 'd.m.Y H:i'); + $disableMsg = "Software-update at $now, the forum ist down due to maintenance. We'll be back soon."; + $sql = "UPDATE {$table_prefix}config SET config_value = :disable_message WHERE config_name = 'board_disable_msg'"; + $statement = $pdo->prepare(query: $sql); + $statement->bindParam(param: 'disable_message', var: $disableMsg); + + if ($statement->execute()) { + echo "Disable Message set …", PHP_EOL; + } else { + echo 'There was an error talking to the DB.' . PHP_EOL; + echo 'Failed SQL-statement: ' . $sql . PHP_EOL; + exit(1); + } + + $sql = "UPDATE {$table_prefix}config SET config_value = '1' WHERE config_name = 'board_disable'"; + $statement = $pdo->prepare(query: $sql); + if ($statement->execute()) { + echo "Board disabled …", PHP_EOL; + } else { + echo 'There was an error talking to the DB.' . PHP_EOL; + echo 'Failed SQL-statement: ' . $sql . PHP_EOL; + exit(1); + } + + $extensionsFile = 'extensions.txt'; + + if (file_exists(filename: $extensionsFile)) { + echo 'Extensions state already stored. Remove extensions.txt if you wish to recreate it.' . PHP_EOL; + } else { + // check for enabled extensions + $sql = "SELECT ext_name FROM {$table_prefix}ext WHERE ext_active = '1'"; + $statement = $pdo->prepare(query: $sql); + if ($statement->execute()) { + $result = $statement->fetchAll(); + + if (count(value: $result) > 0) { + $extensions = json_encode(value: $result); + + // safe enabled extensions + $oFile = fopen(filename: 'extensions.txt', mode: 'w'); + fputs(stream: $oFile, data: $extensions); + fclose(stream: $oFile); + echo 'Stored extensions state'; + + // disable all extensions + $sql = "UPDATE {$table_prefix}ext SET ext_active = '0' WHERE ext_active = '1'"; + $statement = $pdo->prepare(query: $sql); + if ($statement->execute()) { + echo 'Disabled all extensions'; + } + } + + } + } + + $stylesFile = 'styles.txt'; + if (file_exists(filename: $stylesFile)) { + echo 'Styles state already stored. Remove styles.txt if you wish to recreate it' . PHP_EOL; + } else { + // check for enabled style + $sql = "SELECT style_name FROM {$table_prefix}styles WHERE style_active = '1'"; + $statement = $pdo->prepare(query: $sql); + if ($statement->execute()) { + $result = $statement->fetchAll(); + + if (count(value: $result) > 0) { + $styles = json_encode(value: $result); + + // safe enabled styles + $oFile = fopen(filename: 'styles.txt', mode: 'w'); + fputs(stream: $oFile, data: $styles); + fclose(stream: $oFile); + echo 'Stored styles state.' . PHP_EOL; + + // disable all styles except prosilver + $sql = "UPDATE {$table_prefix}styles SET style_active = '0' WHERE NOT style_name = 'prosilver'"; + $statement = $pdo->prepare(query: $sql); + if ($statement->execute()) { + echo 'Disabled all styles except prosilver.' . PHP_EOL; + } + } + + } + } + + // update phpBB + $data = new PharData(filename: $phpBBTarget); + try { + unset($data['phpBB3/config.php']); + unset($data['phpBB3/.htaccess']); + } catch (Exception $e) { + echo 'error: ', $e; + } + + // remove all old files + $excludes = [ + 'config.php', + '.htaccess', + '.htpasswd', + 'images', + 'files', + 'ext', + 'styles', + 'store', + 'updates', + 'mobiquo']; + // this will fuck up nearly all modified boards, leave the files alone by default. + // It will also destroy any API-keys and whatever you might have in your document root. + // deleteDirectory($phpbb_root_path, $excludes); + + + try { + $data->extractTo(directory: $phpBBRootPath); + + $fromDir = $phpBBRootPath . 'phpBB3/'; + $toDir = $phpBBRootPath; + + $this->copyDirectory(source: $fromDir, target: $toDir); + $this->deleteDirectory(dir: $fromDir); + } catch (Exception $e) { + print("Error while extracting $data: $e"); + exit(1); + } + echo 'Moved the update in place.', PHP_EOL; + + $fileOwner = fileowner(filename: $phpBBRootPath); + $fileGroup = filegroup(filename: $phpBBRootPath); + $fileOwnerName = posix_getpwuid(user_id: $fileOwner)['name']; + $fileGroupName = posix_getgrgid(group_id: $fileGroup)['name']; + + + echo 'Check file owner', PHP_EOL; + print("You might need to perform 'chown -R $fileOwnerName:$fileGroupName $phpBBRootPath'" . PHP_EOL); + + echo 'prepare config.yml.', PHP_EOL; + $oFile = fopen(filename: $phpBBRootPath . '/update-config.yml', mode: 'w'); + fputs(stream: $oFile, data: 'updater:' . PHP_EOL . " type: db_only" . PHP_EOL); + fclose(stream: $oFile); + + $command = <<deleteDirectory(dir: $installDir); - } - - - // update langDeDu - if ($useLangDeDu) { - $data = new PharData(filename: $langDeDuTarget); - - try { - $data->extractTo(directory: $phpBBRootPath, overwrite: true); - } catch (Exception $e) { - print("Error while extracting $langDeDuTarget: $e"); - exit(1); - } - } - - - // update langDeSie - if ($useLangDeSie) { - $data = new PharData(filename: $langDeSieTarget); - - try { - $data->extractTo(directory: $phpBBRootPath, overwrite: true); - } catch (Exception $e) { - print("Error while extracting $langDeSieTarget: $e"); - exit(1); - } - } - - - - $sql = "UPDATE ${table_prefix}config SET config_value = '0' WHERE config_name = 'board_disable'"; - $statement = $pdo->prepare(query: $sql); - $statement->execute(); - - echo "Board reenabled …", PHP_EOL; - - - if (file_exists(filename: $extensionsFile)) { - $iFile = fopen(filename: $extensionsFile, mode: 'r'); - $extensions = json_decode(json: fgets(stream: $iFile), associative: true); - - echo 'Enable extensions: '; - - foreach ($extensions as $extension) { - $ext = $extension['ext_name']; - $sql = "UPDATE ${table_prefix}ext SET ext_active = '1' WHERE ext_name = '$ext'"; - $statement = $pdo->prepare(query: $sql); - $statement->execute(); - echo '.'; - } - echo 'done.', PHP_EOL; - } else { - echo 'There are no saved extension information available.', PHP_EOL; - } - - if (file_exists(filename: $stylesFile)) { - $iFile = fopen(filename: $stylesFile, mode: 'r'); - $styles = json_decode(json: fgets(stream: $iFile), associative: true); - - echo 'Enable styles: '; - - foreach ($styles as $style) { - $style = $style['style_name']; - $sql = "UPDATE ${table_prefix}styles SET style_active = '1' WHERE style_name = '$style'"; - $statement = $pdo->prepare(query: $sql); - $statement->execute(); - echo '.'; - } - echo 'done.', PHP_EOL; - } else { - echo 'There are no saved extension information available.', PHP_EOL; - } + + system(command: $command, result_code: $resultCode); + + if ($resultCode != 0) { + echo 'There was an error updating the database: ' . $resultCode . PHP_EOL; + exit(1); + } else { + echo 'The database has been updated' . PHP_EOL; + } + + $installDir = $phpBBRootPath . '/install'; + if (is_dir(filename: $installDir)) { + $this->deleteDirectory(dir: $installDir); + } - // clear cache - $dataGlobalCache = $phpBBRootPath . '/cache/data_global.' . $phpEx; - - if (file_exists(filename: $dataGlobalCache)) { - unlink(filename: $dataGlobalCache); - echo "Cache cleared …"; - } - - echo "Your board should now be up and running." . PHP_EOL; - } - - - /** - * @param String $message - * @param string[] $options - * @param string $default - * - * @return bool - */ - function confirm(string $message = 'Are you sure? ', array $options = ['y', 'n'], string $default = 'n'): bool - { - // first $options means true, any other false - - echo $message, ' ('; - $first = true; - foreach ($options as $option) { - // mark default - if ($option == $default) { - $option = strtoupper(string: $option); - } - if ($first) { - echo $option; - $first = false; - } else { - echo '/', $option; - } - } - echo '): '; - - $handle = fopen(filename: "php://stdin", mode: 'r'); - $line = trim(string: fgetc(stream: $handle)); - fclose(stream: $handle); - - if ($line == '') { - // enter - $line = $default; - } - - if ($line == $options[0]) { - $result = true; - } else { - $result = false; - } - - return $result; - } - - - /** - * @param $dir - * @param array $excludes - * - * @return false|void - */ - function deleteDirectory($dir, array $excludes = []) - { - if (!file_exists(filename: $dir)) { - return false; - } - $dir = rtrim(string: $dir, characters: '/') . '/'; - static $skip = false; - - $entries = glob(pattern: $dir . '{,.}[!.,!..]*', flags: GLOB_MARK | GLOB_BRACE); - - foreach ($entries as $entry) { - if (!in_array(needle: basename(path: $entry), haystack: $excludes)) { - if (is_dir(filename: $entry)) { - $this->deleteDirectory(dir: $entry); - } else { - unlink(filename: $entry); - } - } else { - $skip = true; - } - } - if (!$skip) { - rmdir(directory: $dir); - } - } - - - /** - * @param $source - * @param $target - * - * @return bool|void - */ - function copyDirectory($source, $target) - { - if (!file_exists(filename: $source)) { - die("missing source: $source"); - } - - if (is_file(filename: $source)) { - if (copy(from: $source, to: $target)) { - return true; - } else { - return false; - } - } - - if (is_dir(filename: $source)) { - if (!file_exists(filename: $target)) { - mkdir(directory: $target); - } - $source = rtrim(string: $source, characters: '/') . '/'; - $target = rtrim(string: $target, characters: '/') . '/'; - $dir = new DirectoryIterator(directory: $source); - - foreach ($dir as $entry) { - if (!$entry->isDot()) { - $this->copyDirectory(source: "$source$entry", target: "$target$entry"); - } - } - } - // ignore links, not part of phpBB arch - } - + // update langDeDu + if ($useLangDeDu) { + $data = new PharData(filename: $langDeDuTarget); + + try { + $data->extractTo(directory: $phpBBRootPath, overwrite: true); + } catch (Exception $e) { + print("Error while extracting $langDeDuTarget: $e"); + exit(1); + } + } + + + // update langDeSie + if ($useLangDeSie) { + $data = new PharData(filename: $langDeSieTarget); + + try { + $data->extractTo(directory: $phpBBRootPath, overwrite: true); + } catch (Exception $e) { + print("Error while extracting $langDeSieTarget: $e"); + exit(1); + } + } + + + $sql = "UPDATE {$table_prefix}config SET config_value = '0' WHERE config_name = 'board_disable'"; + $statement = $pdo->prepare(query: $sql); + $statement->execute(); + + echo "Board reenabled …", PHP_EOL; + + + if (file_exists(filename: $extensionsFile)) { + $iFile = fopen(filename: $extensionsFile, mode: 'r'); + $extensions = json_decode(json: fgets(stream: $iFile), associative: true); + + echo 'Enable extensions: '; + + foreach ($extensions as $extension) { + $ext = $extension['ext_name']; + $sql = "UPDATE {$table_prefix}ext SET ext_active = '1' WHERE ext_name = '$ext'"; + $statement = $pdo->prepare(query: $sql); + $statement->execute(); + echo '.'; + } + echo 'done.', PHP_EOL; + } else { + echo 'There are no saved extension information available.', PHP_EOL; + } + + if (file_exists(filename: $stylesFile)) { + $iFile = fopen(filename: $stylesFile, mode: 'r'); + $styles = json_decode(json: fgets(stream: $iFile), associative: true); + + echo 'Enable styles: '; + + foreach ($styles as $style) { + $style = $style['style_name']; + $sql = "UPDATE {$table_prefix}styles SET style_active = '1' WHERE style_name = '$style'"; + $statement = $pdo->prepare(query: $sql); + $statement->execute(); + echo '.'; + } + echo 'done.', PHP_EOL; + } else { + echo 'There are no saved extension information available.', PHP_EOL; + } + + + // clear cache + $dataGlobalCache = $phpBBRootPath . '/cache/data_global.' . $phpEx; + + if (file_exists(filename: $dataGlobalCache)) { + unlink(filename: $dataGlobalCache); + echo "Cache cleared …"; + } + + echo "Your board should now be up and running." . PHP_EOL; + } + + + /** + * @param String $message + * @param string[] $options + * @param string $default + * + * @return bool + */ + function confirm(string $message = 'Are you sure? ', array $options = ['y', 'n'], string $default = 'n'): bool + { + // first $options means true, any other false + + echo $message, ' ('; + $first = true; + foreach ($options as $option) { + // mark default + if ($option == $default) { + $option = strtoupper(string: $option); + } + if ($first) { + echo $option; + $first = false; + } else { + echo '/', $option; + } + } + echo '): '; + + $handle = fopen(filename: "php://stdin", mode: 'r'); + $line = trim(string: fgetc(stream: $handle)); + fclose(stream: $handle); + + if ($line == '') { + // enter + $line = $default; + } + + if ($line == $options[0]) { + $result = true; + } else { + $result = false; + } + + return $result; + } + + + /** + * @param $dir + * @param array $excludes + * + * @return false|void + */ + function deleteDirectory($dir, array $excludes = []) + { + if (!file_exists(filename: $dir)) { + return false; + } + $dir = rtrim(string: $dir, characters: '/') . '/'; + static $skip = false; + + $entries = glob(pattern: $dir . '{,.}[!.,!..]*', flags: GLOB_MARK | GLOB_BRACE); + + foreach ($entries as $entry) { + if (!in_array(needle: basename(path: $entry), haystack: $excludes)) { + if (is_dir(filename: $entry)) { + $this->deleteDirectory(dir: $entry); + } else { + unlink(filename: $entry); + } + } else { + $skip = true; + } + } + if (!$skip) { + rmdir(directory: $dir); + } + } + + + /** + * @param $source + * @param $target + * + * @return bool|void + */ + function copyDirectory($source, $target) + { + if (!file_exists(filename: $source)) { + die("missing source: $source"); + } + + if (is_file(filename: $source)) { + if (copy(from: $source, to: $target)) { + return true; + } else { + return false; + } + } + + if (is_dir(filename: $source)) { + if (!file_exists(filename: $target)) { + mkdir(directory: $target); + } + $source = rtrim(string: $source, characters: '/') . '/'; + $target = rtrim(string: $target, characters: '/') . '/'; + $dir = new DirectoryIterator(directory: $source); + + foreach ($dir as $entry) { + if (!$entry->isDot()) { + $this->copyDirectory(source: "$source$entry", target: "$target$entry"); + } + } + } + // ignore links, not part of phpBB arch + } + + public function printHelp(): void + { + echo "Usage: php update.php [options]", PHP_EOL; + echo "Options:", PHP_EOL; + echo "-h --help Print this help", PHP_EOL; + echo "-d --dry-run Just check for downloadable files, don't connect to database.", PHP_EOL; + } + + public function setDryRun(): void + { + $this->dryRun = true; + } + } diff --git a/README.md b/README.md index 095e8fe..812ceeb 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Shell Script to update phpBB to current version. Usage: -Switch into you current phpBB root directory, then +Switch into your current phpBB root directory, then `git clone https://git.24unix.net/tracer/phpbb_updates.git` diff --git a/update.php b/update.php index c6931c7..dc4f983 100755 --- a/update.php +++ b/update.php @@ -6,4 +6,17 @@ use App\UpdateController; require __DIR__ . '/vendor/autoload.php'; $update = new UpdateController(); + +$options = $update->parseOpts(); + +// Help option +if (array_key_exists(key: 'h', array: $options) || array_key_exists(key: 'help', array: $options)) { + $update->printHelp(); + exit(0); +} + +if (array_key_exists(key: 'd', array: $options) || array_key_exists(key: 'dry-run', array: $options)) { + $update->setDryRun(); +} + $update->handleUpdate();