Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ca25179fb | ||
|
|
08ae7ec083 | ||
|
|
d0d6f282d2 | ||
|
|
9324ff5ca2 | ||
|
|
3158204e6f | ||
|
|
bcd8ac3d2e | ||
|
|
609f6ad1f1 | ||
|
|
9ecbf8e83e | ||
|
|
32532147e8 | ||
|
|
2fd033a8c5 | ||
|
|
a1b030e463 | ||
|
|
21fb878ffb | ||
|
|
2114bcc8b5 | ||
|
|
7d88fc5066 | ||
|
|
08a53a737f | ||
|
|
46e90bd798 | ||
|
|
c8b88021ed | ||
|
|
dabe69967d | ||
|
|
154bd410a4 | ||
|
|
7e85faf2f2 | ||
|
|
21e577b2ca | ||
|
|
04ae283e13 | ||
|
|
9f31cf0304 | ||
|
|
e3a9fb1454 | ||
|
|
b99438c925 | ||
|
|
ab55fd9abb | ||
|
|
ff93b288c2 | ||
|
|
8ea6328f43 | ||
|
|
fd1ef5153a | ||
|
|
364ad27157 | ||
|
|
531d67e76f | ||
|
|
0725582282 | ||
|
|
b1b4ee649e | ||
|
|
dc5568720b |
No files matched your search
+3
-1
@@ -1,3 +1,5 @@
|
||||
dist/
|
||||
extensions.txt
|
||||
|
||||
.idea/
|
||||
/vendor/
|
||||
.phpunit.result.cache
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App;
|
||||
|
||||
use Exception;
|
||||
|
||||
class DownloadException extends Exception
|
||||
{
|
||||
public function __construct(
|
||||
string $message,
|
||||
public readonly ?int $httpStatus = null
|
||||
) {
|
||||
parent::__construct(message: $message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App;
|
||||
|
||||
class Downloader
|
||||
{
|
||||
/**
|
||||
* @throws DownloadException if the transfer fails or the server does not answer with 200
|
||||
*/
|
||||
public function download(string $url): string
|
||||
{
|
||||
$ch = curl_init(url: $url);
|
||||
curl_setopt_array(handle: $ch, options: [
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
// download.phpbb.com sits behind Cloudflare, which challenges fake
|
||||
// browser user agents (they can't solve the JS challenge). An honest
|
||||
// curl UA is allowed through.
|
||||
CURLOPT_USERAGENT => 'curl/' . (curl_version()['version'] ?? '8'),
|
||||
CURLOPT_CONNECTTIMEOUT => 15,
|
||||
CURLOPT_TIMEOUT => 300,
|
||||
]);
|
||||
$data = curl_exec(handle: $ch);
|
||||
$curlError = curl_error(handle: $ch);
|
||||
$httpCode = curl_getinfo(handle: $ch, option: CURLINFO_HTTP_CODE);
|
||||
curl_close(handle: $ch);
|
||||
|
||||
if ($data === false) {
|
||||
throw new DownloadException(message: "Download of $url failed: $curlError");
|
||||
}
|
||||
|
||||
if ($httpCode !== 200) {
|
||||
throw new DownloadException(
|
||||
message: "Download of $url failed: server answered with HTTP status $httpCode.",
|
||||
httpStatus: $httpCode
|
||||
);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,611 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App;
|
||||
|
||||
error_reporting(error_level: E_ALL);
|
||||
|
||||
use DirectoryIterator;
|
||||
use Exception;
|
||||
use JetBrains\PhpStorm\NoReturn;
|
||||
use PDO;
|
||||
use PharData;
|
||||
|
||||
|
||||
const SUPPORTED_RELEASE_MAJOR = 3;
|
||||
const SUPPORTED_RELEASE_MINOR = 2;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class UpdateController
|
||||
{
|
||||
/**
|
||||
* @var true
|
||||
*/
|
||||
private bool $dryRun = false;
|
||||
private string $installedVersion = '';
|
||||
|
||||
function parseOpts(): array
|
||||
{
|
||||
$shortOpts = 'h::d::';
|
||||
|
||||
$longOpts = [
|
||||
'help',
|
||||
'dry-run',
|
||||
];
|
||||
|
||||
return getopt(
|
||||
short_options: $shortOpts,
|
||||
long_options: $longOpts
|
||||
);
|
||||
}
|
||||
|
||||
#[NoReturn]
|
||||
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);
|
||||
}
|
||||
|
||||
if (!$this->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();
|
||||
|
||||
$this->installedVersion = $result['config_value'];
|
||||
print("Installed version: phpBB $this->installedVersion" . PHP_EOL);
|
||||
|
||||
// phpBB has major, minor and maintenance version scheme
|
||||
[$major, $minor, $patch] = explode(separator: '.', string: $this->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: '. $this->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";
|
||||
|
||||
$downloader = new Downloader();
|
||||
|
||||
if (!file_exists(filename: $phpBBTarget)) {
|
||||
echo "Downloading $currentFile" . PHP_EOL;
|
||||
$filePath = "https://download.phpbb.com/pub/release/$major.$minor/$availableUpdate/$currentFile";
|
||||
try {
|
||||
$phpBBtbz = $downloader->download(url: $filePath);
|
||||
} catch (DownloadException $e) {
|
||||
echo 'Failed to download the phpBB archive — aborting.' . PHP_EOL;
|
||||
echo $e->getMessage() . PHP_EOL;
|
||||
if ($e->httpStatus === 403) {
|
||||
echo 'The download server refused the request (possibly Cloudflare bot protection).' . PHP_EOL;
|
||||
echo "You can download the file manually and place it at $phpBBTarget, then rerun this script." . PHP_EOL;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
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;
|
||||
$languageFile = "phpBB_lang_de-$availableUpdate.tar.bz2";
|
||||
$langDeDuTarget = "dist/$languageFile";
|
||||
|
||||
if (!file_exists(filename: $langDeDuTarget)) {
|
||||
echo " Downloading $languageFile" . PHP_EOL;
|
||||
$filePath = "https://downloads.phpbb.de/pakete/deutsch/$major.$minor/$availableUpdate/$languageFile";
|
||||
|
||||
try {
|
||||
file_put_contents(filename: $langDeDuTarget, data: $downloader->download(url: $filePath));
|
||||
} catch (DownloadException $e) {
|
||||
echo ' Skipping language Deutsch "Du": ' . $e->getMessage() . 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";
|
||||
|
||||
try {
|
||||
file_put_contents(filename: $langDeSieTarget, data: $downloader->download(url: $filePath));
|
||||
} catch (DownloadException $e) {
|
||||
echo ' Skipping language Deutsch "Sie": ' . $e->getMessage() . 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);
|
||||
}
|
||||
|
||||
// fail before the board is disabled if the archive cannot be extracted into the root
|
||||
if (!is_writable(filename: $phpBBRootPath)) {
|
||||
$owner = posix_getpwuid(user_id: fileowner(filename: $phpBBRootPath))['name'];
|
||||
$me = posix_getpwuid(user_id: posix_geteuid())['name'];
|
||||
echo "The board root $phpBBRootPath is not writable by user '$me' (owned by '$owner').", PHP_EOL,
|
||||
"Run the update as that user or make the directory writable, then try again.", PHP_EOL,
|
||||
"Nothing has been changed.", PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// 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 = <<<EOC
|
||||
cd ..
|
||||
php install/phpbbcli.php update update-config.yml
|
||||
EOC;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// 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 (phpBB >= 3.1 keeps it in cache/production; the installer's own purge
|
||||
// silently fails when that directory is owned by the web server user)
|
||||
$cacheDir = $phpBBRootPath . 'cache/production';
|
||||
$cleared = 0;
|
||||
$failed = 0;
|
||||
foreach (glob(pattern: $cacheDir . '/*.' . $phpEx) ?: [] as $cacheFile) {
|
||||
if (@unlink(filename: $cacheFile)) {
|
||||
$cleared++;
|
||||
} else {
|
||||
$failed++;
|
||||
}
|
||||
}
|
||||
echo "Cache cleared ($cleared files)", PHP_EOL;
|
||||
if ($failed > 0) {
|
||||
echo "Could not remove $failed cache files in $cacheDir. Purge the cache in the ACP",
|
||||
" (General > Purge the cache) or run 'rm $cacheDir/*.$phpEx' as the web server user,",
|
||||
" otherwise the board keeps reporting the old database version.", PHP_EOL;
|
||||
}
|
||||
|
||||
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');
|
||||
// fgetc() returns false on EOF (e.g. non-interactive stdin) — fall back to default
|
||||
$line = trim(string: (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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,29 @@
|
||||
# phpbb_updates
|
||||
|
||||
Shell Script to update phpBB to current version.
|
||||
Shell Script to update phpBB to current version.
|
||||
|
||||
|
||||
Usage:
|
||||
|
||||
Switch into your current phpBB root directory, then
|
||||
|
||||
`git clone https://git.24unix.net/tracer/phpbb_updates.git`
|
||||
|
||||
Or download either:
|
||||
https://git.24unix.net/tracer/phpbb_updates/archive/v0.0.3.zip
|
||||
|
||||
or:
|
||||
https://git.24unix.net/tracer/phpbb_updates/archive/v0.0.3.tar.gz
|
||||
|
||||
and unpack them into the same directory and change into phpbb_updates.
|
||||
|
||||
Then: Install composer (https://getcomposer.org/download/) and run
|
||||
`composer install`
|
||||
|
||||
followed by:
|
||||
`php update.php` or `./update.php`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "tracer/phpbb_updates",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Micha Espey",
|
||||
"email": "tracer@24unix.net"
|
||||
}
|
||||
],
|
||||
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-posix": "*",
|
||||
"ext-pdo": "*"
|
||||
},
|
||||
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "Controller/"
|
||||
}
|
||||
},
|
||||
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^13.3"
|
||||
}
|
||||
}
|
||||
Generated
+1941
File diff suppressed because it is too large.
Load diff
+11
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
failOnWarning="true">
|
||||
<testsuites>
|
||||
<testsuite name="default">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use App\Downloader;
|
||||
use App\DownloadException;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(Downloader::class)]
|
||||
class DownloaderTest extends TestCase
|
||||
{
|
||||
private static string $baseUrl;
|
||||
/** @var resource */
|
||||
private static $serverProcess;
|
||||
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
$port = self::findFreePort();
|
||||
self::$baseUrl = "http://127.0.0.1:$port";
|
||||
|
||||
self::$serverProcess = proc_open(
|
||||
command: [PHP_BINARY, '-S', "127.0.0.1:$port", __DIR__ . '/router.php'],
|
||||
descriptor_spec: [1 => ['file', '/dev/null', 'w'], 2 => ['file', '/dev/null', 'w']],
|
||||
pipes: $pipes
|
||||
);
|
||||
|
||||
// wait until the server accepts connections
|
||||
$deadline = microtime(as_float: true) + 5.0;
|
||||
while (microtime(as_float: true) < $deadline) {
|
||||
$socket = @fsockopen(hostname: '127.0.0.1', port: $port);
|
||||
if ($socket !== false) {
|
||||
fclose(stream: $socket);
|
||||
return;
|
||||
}
|
||||
usleep(microseconds: 50_000);
|
||||
}
|
||||
self::fail(message: 'Test web server did not start.');
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass(): void
|
||||
{
|
||||
proc_terminate(process: self::$serverProcess);
|
||||
proc_close(process: self::$serverProcess);
|
||||
}
|
||||
|
||||
private static function findFreePort(): int
|
||||
{
|
||||
$socket = stream_socket_server(address: 'tcp://127.0.0.1:0');
|
||||
$address = stream_socket_get_name(socket: $socket, remote: false);
|
||||
fclose(stream: $socket);
|
||||
|
||||
return (int)substr(string: $address, offset: strrpos(haystack: $address, needle: ':') + 1);
|
||||
}
|
||||
|
||||
public function testReturnsBodyOnSuccess(): void
|
||||
{
|
||||
$downloader = new Downloader();
|
||||
|
||||
$data = $downloader->download(url: self::$baseUrl . '/ok.tar.bz2');
|
||||
|
||||
$this->assertSame(expected: 'FAKE-ARCHIVE-CONTENT', actual: $data);
|
||||
}
|
||||
|
||||
public function testThrowsWithHttpStatusOn403(): void
|
||||
{
|
||||
$downloader = new Downloader();
|
||||
|
||||
try {
|
||||
$downloader->download(url: self::$baseUrl . '/forbidden.tar.bz2');
|
||||
$this->fail(message: 'Expected DownloadException was not thrown.');
|
||||
} catch (DownloadException $e) {
|
||||
$this->assertSame(expected: 403, actual: $e->httpStatus);
|
||||
$this->assertStringContainsString(needle: '403', haystack: $e->getMessage());
|
||||
$this->assertStringContainsString(needle: '/forbidden.tar.bz2', haystack: $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testThrowsWithHttpStatusOn404(): void
|
||||
{
|
||||
$downloader = new Downloader();
|
||||
|
||||
try {
|
||||
$downloader->download(url: self::$baseUrl . '/missing.tar.bz2');
|
||||
$this->fail(message: 'Expected DownloadException was not thrown.');
|
||||
} catch (DownloadException $e) {
|
||||
$this->assertSame(expected: 404, actual: $e->httpStatus);
|
||||
$this->assertStringContainsString(needle: '404', haystack: $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function testThrowsWithCurlErrorWhenServerUnreachable(): void
|
||||
{
|
||||
$downloader = new Downloader();
|
||||
// a port nothing listens on
|
||||
$deadPort = self::findFreePort();
|
||||
|
||||
try {
|
||||
$downloader->download(url: "http://127.0.0.1:$deadPort/x.tar.bz2");
|
||||
$this->fail(message: 'Expected DownloadException was not thrown.');
|
||||
} catch (DownloadException $e) {
|
||||
$this->assertNull(actual: $e->httpStatus);
|
||||
// message must carry the underlying curl error, not just "failed"
|
||||
$this->assertStringContainsString(needle: 'connect', haystack: strtolower(string: $e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
public function testSendsHonestCurlUserAgent(): void
|
||||
{
|
||||
// download.phpbb.com's Cloudflare challenges fake browser user agents;
|
||||
// an honest curl UA is what actually passes.
|
||||
$downloader = new Downloader();
|
||||
|
||||
$userAgent = $downloader->download(url: self::$baseUrl . '/echo-user-agent');
|
||||
|
||||
$this->assertStringStartsWith(prefix: 'curl/', string: $userAgent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
// Router for PHP's built-in server used by DownloaderTest.
|
||||
// Behavior is selected by request path.
|
||||
|
||||
$path = parse_url(url: $_SERVER['REQUEST_URI'], component: PHP_URL_PATH);
|
||||
|
||||
switch ($path) {
|
||||
case '/ok.tar.bz2':
|
||||
header(header: 'Content-Type: application/x-bzip2');
|
||||
echo 'FAKE-ARCHIVE-CONTENT';
|
||||
break;
|
||||
case '/forbidden.tar.bz2':
|
||||
http_response_code(response_code: 403);
|
||||
echo 'blocked';
|
||||
break;
|
||||
case '/echo-user-agent':
|
||||
echo $_SERVER['HTTP_USER_AGENT'] ?? '';
|
||||
break;
|
||||
default:
|
||||
http_response_code(response_code: 404);
|
||||
echo 'not found';
|
||||
}
|
||||
Regular → Executable
+11
-330
@@ -1,340 +1,21 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
use App\UpdateController;
|
||||
|
||||
// make absolute or relative to phpBB /
|
||||
define('PHPBB_ROOT_PATH', '../');
|
||||
define('IN_PHPBB', true);
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
define('SUPPORTED_RELEASE_MAJOR', 3);
|
||||
define('SUPPORTED_RELEASE_MINOR', 2);
|
||||
$update = new UpdateController();
|
||||
|
||||
$options = $update->parseOpts();
|
||||
|
||||
function confirm($message = 'Are you sure? ', $options = array('y', 'n'), $default ='n')
|
||||
{
|
||||
// first $options means true, any other false
|
||||
|
||||
echo $message, ' (';
|
||||
$first = true;
|
||||
foreach ($options as $option) {
|
||||
// mark default
|
||||
if ($option == $default) {
|
||||
$option = strtoupper($option);
|
||||
}
|
||||
if ($first) {
|
||||
echo $option;
|
||||
$first = false;
|
||||
} else {
|
||||
echo '/', $option;
|
||||
}
|
||||
}
|
||||
echo '): ';
|
||||
|
||||
$handle = fopen("php://stdin", 'r');
|
||||
$line = trim(fgetc($handle));
|
||||
fclose($handle);
|
||||
|
||||
|
||||
if ($line == '') {
|
||||
// enter
|
||||
$line = $default;
|
||||
}
|
||||
|
||||
if ($line == $options[0]) {
|
||||
$result = true;
|
||||
} else {
|
||||
$result = false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
// Help option
|
||||
if (array_key_exists(key: 'h', array: $options) || array_key_exists(key: 'help', array: $options)) {
|
||||
$update->printHelp();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function deleteDirectory($dir, $excludes = array())
|
||||
{
|
||||
if (!file_exists($dir)) {
|
||||
return false;
|
||||
}
|
||||
$dir = rtrim($dir, '/') . '/';
|
||||
static $skip = false;
|
||||
|
||||
$entries = glob($dir . '{,.}[!.,!..]*', GLOB_MARK | GLOB_BRACE);
|
||||
|
||||
foreach($entries as $entry) {
|
||||
if (!in_array(basename($entry), $excludes)) {
|
||||
if (is_dir($entry)) {
|
||||
deleteDirectory($entry);
|
||||
} else {
|
||||
unlink($entry);
|
||||
}
|
||||
} else {
|
||||
$skip = true;
|
||||
}
|
||||
}
|
||||
if ($skip == false) {
|
||||
rmdir($dir);
|
||||
}
|
||||
if (array_key_exists(key: 'd', array: $options) || array_key_exists(key: 'dry-run', array: $options)) {
|
||||
$update->setDryRun();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function copyDirectory($source, $target)
|
||||
{
|
||||
if (!file_exists($source)) {
|
||||
die("missing source: $source");
|
||||
}
|
||||
|
||||
if (is_file($source)) {
|
||||
if (copy($source, $target)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_dir($source)) {
|
||||
if (!file_exists($target)) {
|
||||
mkdir($target);
|
||||
}
|
||||
$source = rtrim($source, '/') . '/';
|
||||
$target = rtrim($target, '/') . '/';
|
||||
$dir = new DirectoryIterator($source);
|
||||
|
||||
foreach ($dir as $entry) {
|
||||
if (!$entry->isDot()) {
|
||||
copyDirectory("$source$entry", "$target$entry");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ignore links, not part of phpBB arch
|
||||
}
|
||||
|
||||
|
||||
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
|
||||
$phpEx = substr(strrchr(__FILE__, '.'), 1);
|
||||
include($phpbb_root_path . 'common.' . $phpEx);
|
||||
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
||||
echo 'This script is intended for unixoid installations.';
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
$fileowner = fileowner($phpbb_root_path);
|
||||
$filegroup = filegroup($phpbb_root_path);
|
||||
$fileownerName = posix_getpwuid($fileowner)['name'];
|
||||
$filegroupName = posix_getgrgid($filegroup)['name'];
|
||||
|
||||
|
||||
if (!empty($argv[1])) {
|
||||
switch ($argv[1]) {
|
||||
case '--prepare':
|
||||
// handle version stuff
|
||||
$sql = "SELECT config_value FROM ${table_prefix}config WHERE config_name = 'version'";
|
||||
$result = $db->sql_query($sql);
|
||||
$row = $db->sql_fetchrow($result);
|
||||
$installedVersion = $row['config_value'];
|
||||
print("Installed version: $installedVersion" . PHP_EOL);
|
||||
|
||||
// phpBB has major, minor and maintenance version scheme
|
||||
list($major, $minor, $patch) = explode('.', $installedVersion);
|
||||
if ((intval($major) != SUPPORTED_RELEASE_MAJOR) || (intval($minor) != SUPPORTED_RELEASE_MINOR)) {
|
||||
echo 'This script only supports phpBB ' . SUPPORTED_RELEASE_MAJOR . '.' . SUPPORTED_RELEASE_MINOR . ' branch.', PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
// ok, start update
|
||||
$now = date('d.m.Y H:i');
|
||||
$disableMsg = "Softwareupdate am $now, das Bord ist kurzzeitig nicht erreichbar.";
|
||||
$sql = "UPDATE ${table_prefix}config SET config_value = '$disableMsg' WHERE config_name = 'board_disable_msg'";
|
||||
$result = $db->sql_query($sql);
|
||||
echo "Disable Message set …", PHP_EOL;
|
||||
|
||||
$sql = "UPDATE ${table_prefix}config SET config_value = '1' WHERE config_name = 'board_disable'";
|
||||
$result = $db->sql_query($sql);
|
||||
echo "Board disabled …", PHP_EOL;
|
||||
|
||||
// clear cache
|
||||
$data_global_cache = $phpbb_root_path . '/cache/data_global.' . $phpEx;
|
||||
|
||||
if (file_exists($data_global_cache)) {
|
||||
unlink($data_global_cache);
|
||||
echo "Cache cleared …";
|
||||
}
|
||||
|
||||
|
||||
// http://version.phpbb.com/phpbb/versions.json
|
||||
$json = file_get_contents('http://version.phpbb.com/phpbb/versions.json');
|
||||
$versions = json_decode($json);
|
||||
$currentVersion = $versions->{'stable'}->{SUPPORTED_RELEASE_MAJOR . '.' . SUPPORTED_RELEASE_MINOR}->{'current'};
|
||||
print("Current version: $currentVersion" . PHP_EOL);
|
||||
|
||||
// check for existing update
|
||||
if (!file_exists('dist')) {
|
||||
echo "'dist' folder is missing, create a new one …'";
|
||||
mkdir ('dist');
|
||||
}
|
||||
$currentFile = "phpBB-$currentVersion-deutsch.tar.bz2";
|
||||
$filePath = 'http://downloads.phpbb.de/pakete/deutsch/' . SUPPORTED_RELEASE_MAJOR . '.' . SUPPORTED_RELEASE_MINOR . "/$currentVersion/$currentFile";
|
||||
echo $filePath;
|
||||
|
||||
$target = "dist/$currentFile";
|
||||
|
||||
if (!file_exists($target)) {
|
||||
print("Downloading $currentFile");
|
||||
$phpBBtbz = file_get_contents($filePath);
|
||||
file_put_contents($target, $phpBBtbz);
|
||||
} else {
|
||||
print("File exists: $currentFile" . PHP_EOL);
|
||||
if (!confirm('Use this copy and continue?')) {
|
||||
echo "Aborted due to user request.", PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
$data = new PharData($target);
|
||||
try {
|
||||
unset($data['phpBB3/config.php']);
|
||||
unset($data['phpBB3/.htaccess']);
|
||||
} catch (Exception $e) {
|
||||
echo 'error: ', $e;
|
||||
}
|
||||
|
||||
// check for enabled extensions
|
||||
$sql = "SELECT ext_name FROM ${table_prefix}ext WHERE ext_active = '1'";
|
||||
$result = $db->sql_query($sql);
|
||||
$rows = $db->sql_fetchrowset($result);
|
||||
if (count($rows) > 0) {
|
||||
$rows = json_encode($rows);
|
||||
|
||||
// safe enabled extensions
|
||||
$ofile = fopen('extensions.txt', 'w');
|
||||
fputs($ofile, $rows);
|
||||
fclose($ofile);
|
||||
|
||||
// disable all extensions
|
||||
$sql = "UPDATE ${table_prefix}ext SET ext_active = '0' WHERE ext_active = '1'";
|
||||
$result = $db->sql_query($sql);
|
||||
}
|
||||
|
||||
// disable all styles but prosilver
|
||||
$sql = "UPDATE ${table_prefix}styles SET style_active = '0' WHERE NOT style_name = 'prosilver'";
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
// remove all old files
|
||||
$excludes = array(
|
||||
'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
|
||||
// deleteDirectory($phpbb_root_path, $excludes);
|
||||
|
||||
|
||||
try {
|
||||
// $data->extractTo($phpbb_root_path, 'phpBB3');
|
||||
// does not work due to php bug:
|
||||
// https://bugs.php.net/bug.php?id=54289
|
||||
$data->extractTo($phpbb_root_path, null, true);
|
||||
|
||||
$fromDir = $phpbb_root_path . 'phpBB3/';
|
||||
$toDir = $phpbb_root_path;
|
||||
|
||||
copyDirectory($fromDir, $toDir);
|
||||
deleteDirectory($fromDir);
|
||||
|
||||
} catch (Exception $e) {
|
||||
print("Error while extracting $data: $e");
|
||||
exit(1);
|
||||
}
|
||||
echo 'Moved the update in place.', PHP_EOL;
|
||||
|
||||
echo 'Check fileowner', PHP_EOL;
|
||||
print("You might need to perform 'chown -R $fileownerName:$filegroupName $phpbb_root_path'" . PHP_EOL);
|
||||
|
||||
echo 'prepare config.yml.', PHP_EOL;
|
||||
$oFile = fopen($phpbb_root_path . '/install/config.yml', 'w');
|
||||
fputs($oFile, 'updater:' . PHP_EOL . " type: db_only" . PHP_EOL);
|
||||
fclose($oFile);
|
||||
echo "Now head over to ${phpbb_root_path}install and execute 'php phpbbcli.php update config.yml'", PHP_EOL;
|
||||
echo "After, return here and finish the update by excuting php $argv[0] --finish", PHP_EOL;
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
case "--finish":
|
||||
if (confirm('Remove the install directory?')) {
|
||||
deleteDirectory($phpbb_root_path . 'install');
|
||||
}
|
||||
|
||||
$sql = "UPDATE ${table_prefix}config SET config_value = '0' WHERE config_name = 'board_disable'";
|
||||
$result = $db->sql_query($sql);
|
||||
|
||||
echo "Board reenabled …", PHP_EOL;
|
||||
|
||||
// clear cache
|
||||
$data_global_cache = $phpbb_root_path . '/cache/production/data_global.' . $phpEx;
|
||||
|
||||
if (file_exists($data_global_cache)) {
|
||||
unlink($data_global_cache);
|
||||
echo "Cache cleared …", PHP_EOL;
|
||||
}
|
||||
echo "Your board should now be up and running, you might want to reeanble the extensions using php $argv[0] --reenable-extensions", PHP_EOL;
|
||||
exit(0);
|
||||
break;
|
||||
case "--reenable-extensions":
|
||||
$extensionsFile = 'extensions.txt';
|
||||
|
||||
if (file_exists($extensionsFile)) {
|
||||
$iFile = fopen($extensionsFile, 'r');
|
||||
$extensions = json_decode(fgets($iFile), true);
|
||||
|
||||
echo 'Enable extensions: ';
|
||||
|
||||
foreach($extensions as $extension) {
|
||||
$ext = $extension['ext_name'];
|
||||
// disable all extensions
|
||||
$sql = "UPDATE ${table_prefix}ext SET ext_active = '1' WHERE ext_name = '$ext'";
|
||||
$result = $db->sql_query($sql);
|
||||
echo '.';
|
||||
}
|
||||
echo 'done.', PHP_EOL;
|
||||
|
||||
// clear cache
|
||||
$data_ext_cache = $phpbb_root_path . '/cache/production/data_ext.' . $phpEx;
|
||||
|
||||
if (file_exists($data_ext_cache)) {
|
||||
unlink($data_ext_cache);
|
||||
echo "Cache cleared …", PHP_EOL;
|
||||
}
|
||||
|
||||
} else {
|
||||
echo 'There are no saved extension information available.', PHP_EOL;
|
||||
}
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
echo "unknow option $argv[1]", PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
echo "$argv[0]: missing parameter", PHP_EOL;
|
||||
echo 'Usage:', PHP_EOL;
|
||||
echo 'To perfom an update, you need two steps. Fist prepare the board for the update:', PHP_EOL;
|
||||
echo "php $argv[0] --prepare", PHP_EOL;
|
||||
echo 'Then perform the DB update with the CLI tool from phpBB, after:', PHP_EOL;
|
||||
echo "php $argv[0] --finish", PHP_EOL;
|
||||
echo "Additional steps:", PHP_EOL;
|
||||
echo "php $argv[0] --reenable-extensions", PHP_EOL;
|
||||
// echo "php $argv[0] --reenable-styles", PHP_EOL;
|
||||
// really?
|
||||
exit(0);
|
||||
}
|
||||
$update->handleUpdate();
|
||||
Reference in new issue
Block a user