diff --git a/404.php b/404.php index 04366812..855cd0ad 100644 --- a/404.php +++ b/404.php @@ -4,9 +4,41 @@ include "header.php"; -echo new \OOUI\MessageWidget( [ - 'type' => 'error', - 'label' => 'Page not found. The wiki you are looking for may have been deleted.' -] ); +$redirect = false; + +// Check for redirect +$uri = $_SERVER['REQUEST_URI']; +if ( preg_match( '`/wikis/([0-9a-f]{10,32})/`', $uri, $matches, PREG_OFFSET_CAPTURE ) !== false ) { + $wiki = $matches[1][0]; + $offset = $matches[1][1]; + $wikiData = get_wiki_data( $wiki ); + // Follow up to 10 redirect steps + $i = 0; + while ( $wikiData['redirect'] && $i < 10 ) { + $redirect = $wikiData['redirect']; + $wikiData = get_wiki_data( $redirect ); + $i++; + } + $redirectUri = + substr( $uri, 0, $offset ) . + $redirect . + substr( $uri, $offset + strlen( $wiki ) ); +} + +if ( $redirect ) { + echo new \OOUI\MessageWidget( [ + 'type' => 'info', + 'icon' => 'articleRedirect', + 'label' => new \OOUI\HtmlSnippet( + 'This wiki has been deleted and the following wiki was selected as a direct replacement: ' . + '' . substr( $redirect, 0, 10 ) . '' + ) + ] ); +} else { + echo new \OOUI\MessageWidget( [ + 'type' => 'error', + 'label' => 'Page not found. The wiki you are looking for may have been deleted.' + ] ); +} include "footer.html"; diff --git a/delete.php b/delete.php index 906ac1ac..50a25681 100644 --- a/delete.php +++ b/delete.php @@ -11,57 +11,140 @@ die( '
You are not allowed to delete this wiki.
' ); } -if ( !isset( $_POST['confirm' ] ) ) { - $patches = format_patch_list( $wikiData['patchList'], $wikiData['branch'] ); - $linkedTasks = format_linked_tasks( $wikiData['linkedTaskList'] ); - $creator = $wikiData[ 'creator' ] ?? ''; +if ( !$wikiData['deleted'] ) { + if ( !isset( $_POST['confirm' ] ) ) { + $patches = format_patch_list( $wikiData['patchList'], $wikiData['branch'] ); + $linkedTasks = format_linked_tasks( $wikiData['linkedTaskList'] ); + $creator = $wikiData[ 'creator' ] ?? ''; - echo 'Wiki | ' . - 'Patches ✓=Merged ✗=Abandoned | ' .
- 'Linked tasks ✓=Resolved ✗=Declined/Invalid | ' .
- 'Time | ' . - ( $useOAuth ? 'Creator | ' : '' ) . - '
---|---|---|---|---|
' . substr( $wiki, 0, 10 ) . ' | ' . - '' . $patches . ' | ' . - '' . $linkedTasks . ' | ' . - '' . date( 'Y-m-d H:i:s', $wikiData[ 'created' ] ) . ' | ' . - ( $useOAuth ? '' . ( $creator ? user_link( $creator ) : '?' ) . ' | ' : '' ) . - '
Wiki | ' . + 'Patches ✓=Merged ✗=Abandoned | ' .
+ 'Linked tasks ✓=Resolved ✗=Declined/Invalid | ' .
+ 'Time | ' . + ( $useOAuth ? 'Creator | ' : '' ) . + '
---|---|---|---|---|
' . substr( $wiki, 0, 10 ) . ' | ' . + '' . $patches . ' | ' . + '' . $linkedTasks . ' | ' . + '' . date( 'Y-m-d H:i:s', $wikiData[ 'created' ] ) . ' | ' . + ( $useOAuth ? '' . ( $creator ? user_link( $creator ) : '?' ) . ' | ' : '' ) . + '
Error deleting wiki:
' . htmlentities( $error ) . '
Error deleting wiki:
' . htmlentities( $error ) . '
Wiki deleted.
'; } + +if ( $wikiData['redirect'] ) { + echo 'Redirected to ' . $wikiData['redirect'] . '.
'; +} diff --git a/includes.php b/includes.php index 9ef3eba3..682b4ffe 100644 --- a/includes.php +++ b/includes.php @@ -77,7 +77,7 @@ function get_wiki_data( string $wiki ): array { global $mysqli; $stmt = $mysqli->prepare( ' - SELECT wiki, creator, UNIX_TIMESTAMP( created ) created, patches, branch, announcedTasks, timeToCreate, deleted + SELECT wiki, creator, UNIX_TIMESTAMP( created ) created, patches, branch, announcedTasks, timeToCreate, deleted, redirect FROM wikis WHERE wiki = ? ' ); if ( !$stmt ) { @@ -316,7 +316,11 @@ function shell( $cmd, array $env = [] ): ?string { return $error ? null : $process->getOutput(); } -function delete_wiki( string $wiki ): int { +function is_valid_hash( string $hash ): bool { + return preg_match( '/^[0-9a-f]{10,32}$/', $hash ) !== false; +} + +function delete_wiki( string $wiki, ?string $redirect = null ): ?string { global $mysqli; $wikiData = get_wiki_data( $wiki ); @@ -325,7 +329,7 @@ function delete_wiki( string $wiki ): int { return 'Wiki already deleted.'; } - $error = shell_echo( __DIR__ . '/deletewiki.sh', + $errorCode = shell_echo( __DIR__ . '/deletewiki.sh', [ 'PATCHDEMO' => __DIR__, 'WIKI' => $wiki @@ -346,16 +350,20 @@ function delete_wiki( string $wiki ): int { ); } + if ( $redirect && !is_valid_hash( $redirect ) ) { + $redirect = null; + } + $stmt = $mysqli->prepare( ' UPDATE wikis - SET deleted = 1 + SET deleted = 1, redirect = ? WHERE wiki = ? ' ); - $stmt->bind_param( 's', $wiki ); + $stmt->bind_param( 'ss', $redirect, $wiki ); $stmt->execute(); $stmt->close(); - return $error; + return $errorCode ? 'Delete script failed.' : null; } $requestCache = []; diff --git a/sql/patchdemo.sql b/sql/patchdemo.sql index c78762b9..1d213cc8 100644 --- a/sql/patchdemo.sql +++ b/sql/patchdemo.sql @@ -42,3 +42,6 @@ ALTER TABLE `tasks` ALTER TABLE `wikis` ADD COLUMN IF NOT EXISTS `branch` VARCHAR(64) NOT NULL AFTER `patches`; + +ALTER TABLE `wikis` + ADD COLUMN IF NOT EXISTS `redirect` VARCHAR(32) NULL AFTER `deleted`;