From f39dcc7caadab73fc0eef9e7c285f9d0958a7f17 Mon Sep 17 00:00:00 2001 From: Ed Sanders Date: Mon, 2 Nov 2020 16:42:07 +0000 Subject: [PATCH] Allow wikis to be redirected when deleting Fixes #54 --- .gitignore | 1 + 404.php | 37 +++++++++++++++-- delete.php | 115 ++++++++++++++++++++++++++++++++++++++++------------- index.php | 1 - 4 files changed, 122 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index 381abcc9..5950c340 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ repositories composer composer.lock vendor +redirects.txt node_modules diff --git a/404.php b/404.php index 04366812..59a816d0 100644 --- a/404.php +++ b/404.php @@ -2,11 +2,40 @@ header( 'HTTP/1.0 404 Not Found' ); require_once "includes.php"; +// Check for redirect +$redirects = get_if_file_exists( 'redirects.txt' ); +$redirect = false; +if ( $redirects ) { + $uri = $_SERVER['REQUEST_URI']; + $lines = explode( "\n", $redirects ); + foreach ( $lines as $line ) { + if ( !$line ) { + continue; + } + $parts = explode( ' ', $line ); + if ( strpos( $uri, $parts[0] ) !== false ) { + $uri = str_replace( $parts[0], $parts[1], $uri ); + $redirect = true; + } + } +} + include "header.php"; -echo new \OOUI\MessageWidget( [ - 'type' => 'error', - 'label' => 'Page not found. The wiki you are looking for may have been deleted.' -] ); +if ( $redirect ) { + echo new \OOUI\MessageWidget( [ + 'type' => 'info', + 'icon' => 'articleRedirect', + 'label' => new \OOUI\HtmlSnippet( + 'This wiki has been deleted. The following wiki was selected as a direct replacement: ' . + '' . $uri . '' + ) + ] ); +} 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..b0fbfd9a 100644 --- a/delete.php +++ b/delete.php @@ -33,35 +33,96 @@ '' . ''; - echo '
' . - '

Are you sure you want to delete this wiki?

' . - '

This cannot be undone.

' . - new OOUI\ButtonInputWidget( [ - 'type' => 'submit', - 'name' => 'confirm', - 'label' => 'Delete', - 'flags' => [ 'primary', 'destructive' ] - ] ) . - new OOUI\HiddenInputWidget( [ - 'name' => 'csrf_token', - 'value' => get_csrf_token(), - ] ) . - '
'; - die(); -} + $wikilist = [ + [ + 'data' => '', + 'label' => 'None', + ] + ]; + $results = $mysqli->query( 'SELECT wiki, creator, UNIX_TIMESTAMP( created ) created FROM wikis WHERE !deleted ORDER BY created DESC' ); + if ( !$results ) { + die( $mysqli->error ); + } + while ( $data = $results->fetch_assoc() ) { + if ( $data[ 'wiki' ] === $wiki ) { + continue; + } + $wikilist[] = [ + 'data' => $data[ 'wiki' ], + 'label' => substr( $data[ 'wiki' ], 0, 10 ) . ' - ' . $data[ 'creator' ] . ' (' . date( 'Y-m-d H:i:s', $data[ 'created' ] ) . ')', + ]; + } + echo new OOUI\FormLayout( [ + 'method' => 'POST', + 'items' => [ + new OOUI\FieldsetLayout( [ + 'label' => new OOUI\HtmlSnippet( + '
Are you sure you want to delete this wiki? This cannot be undone.' + ), + 'items' => array_filter( [ + count( $wikilist ) > 1 ? + new OOUI\FieldLayout( + new OOUI\DropdownInputWidget( [ + 'name' => 'redirect', + 'options' => $wikilist, + ] ), + [ + 'label' => 'Leave a redirect another wiki (optional):', + 'align' => 'left', + ] + ) : + null, + new OOUI\FieldLayout( + new OOUI\ButtonInputWidget( [ + 'type' => 'submit', + 'name' => 'confirm', + 'label' => 'Delete', + 'flags' => [ 'primary', 'destructive' ] + ] ), + [ + 'label' => ' ', + 'align' => 'left', + ] + ), + ] ) + ] ) + ] + ] ); -if ( !isset( $_POST['csrf_token'] ) || !check_csrf_token( $_POST['csrf_token'] ) ) { - die( "Invalid session." ); -} +} else { + if ( !isset( $_POST['csrf_token'] ) || !check_csrf_token( $_POST['csrf_token'] ) ) { + die( "Invalid session." ); + } -ob_implicit_flush( true ); + ob_implicit_flush( true ); -echo '
'; -$error = delete_wiki( $wiki ); -echo '
'; + echo '
'; + $error = delete_wiki( $wiki ); + echo '
'; -if ( $error ) { - die( '

Error deleting wiki:
' . htmlentities( $error ) . '

' ); -} else { - echo '

Wiki deleted.

'; + if ( $error ) { + die( '

Error deleting wiki:
' . htmlentities( $error ) . '

' ); + } else { + echo '

Wiki deleted.

'; + } + + function isValidHash( $hash ) { + return preg_match( '/^[0-9a-f]{10,32}$/', $hash ); + } + + $redirect = $_POST['redirect'] ?? null; + + if ( + $redirect && + isValidHash( $redirect ) && + isValidHash( $wiki ) + ) { + // TODO: Avoid duplication in redirect file + file_put_contents( + 'redirects.txt', + $wiki . ' ' . $redirect . "\n", + FILE_APPEND | LOCK_EX + ); + echo ' Redirected to ' . $redirect . '.'; + } } diff --git a/index.php b/index.php index ea4f9fc9..bd856536 100644 --- a/index.php +++ b/index.php @@ -182,7 +182,6 @@ 'classes' => [ 'form-submit' ], 'label' => 'Create demo', 'type' => 'submit', - // 'disabled' => true, 'flags' => [ 'progressive', 'primary' ] ] ), [