ghwikipp: Allow subdirectories!

From b173423bc420d97c92eed8568ebb31ce0485ac71 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Tue, 14 Jun 2022 23:24:01 -0400
Subject: [PATCH] Allow subdirectories!

This will let us have other projects (SDL_mixer, SDL_image, etc) in their
own sections, which helps for automated tools and general organization.

You need to manually make the subdir at the moment, either by pushing
something through git or just mkdir'ing in the server's "raw" directory;
since subdir creation is currently intended to be an extremely rare event
that an admin does, this is acceptable for now, but a basic UI for this
would be nice eventually.
---
 index.php | 38 +++++++++++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/index.php b/index.php
index 0c50b48..e088dec 100644
--- a/index.php
+++ b/index.php
@@ -991,9 +991,41 @@ function confirm_action_on_user($action, $user, $statedir, $explanation)
 if ( ($reqargcount < 1) || ($reqargs[0] == '') ) {
     $document = 'FrontPage';  // Feed the main wiki page by default.
 } else {
-    $document = $reqargs[0];
-    if (substr($document, 0, 1) == '.') {  // Make sure we don't catch ".git" or ".." or whatever.
-        fail400("Invalid page name '$document'");
+    // eat arguments until we run out of existing subdirectories...
+    $document = '';
+    $sep = '';
+    $drop_args = 0;
+    foreach ($reqargs as $a) {
+        $document .= "$sep$a";
+        $sep = '/';  # set this after first item so there's a separator everywhere but at the start of the string.
+        if (substr($a, 0, 1) == '.') {  // Make sure we don't catch ".git" or ".." or whatever.
+            fail400("Invalid page name '$document'");
+        }
+
+        // Note that this (intentionally!) will not let you create files in subdirectories that don't exist.
+        //  Creating a new subdir should be a significant admin-controlled event. Push through git directly for now.
+        //  We can add UI for it later if we want.
+        if (is_dir("$raw_data/$document")) {
+            $drop_args++;
+        } else {
+            break;  // We're done looking for subdirs.
+        }
+    }
+
+    // drop subdirs from $reqargs, replace $reqargs[0] with the full document path just in case.
+    if ($drop_args > 0) {
+        $reqargcount -= $drop_args;
+        if ($reqargcount == 0) {
+            $document .= '/FrontPage';  // each subdir gets a default FrontPage.
+            $reqargs = array( $document );
+            $drop_args = 0;
+        } else {
+            while ($drop_args > 0) {
+                array_shift($reqargs);  // drop subdirs from $reqargs
+                $drop_args--;
+            }
+            $reqargs[0] = $document;
+        }
     }
 }