From d6c56feb1d1c061e53b1e0b4233521ba0d7a0813 Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Sat, 2 Mar 2019 13:32:12 +0000
Subject: [PATCH] Download extra files in the pseudo-module_register(), and
 then pack 'em in the packer

---
 .gitignore                   |   2 +-
 build.php                    |  28 ++++++--
 module_index.json            | 128 +++++++++++++++++------------------
 modules/parser-parsedown.php |   4 +-
 pack.php                     |  24 +++----
 5 files changed, 100 insertions(+), 86 deletions(-)

diff --git a/.gitignore b/.gitignore
index 2faa93b..696fe2c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
 _docpress/
-build/*
+build/
 !build/index.php
 
 # Include the README
diff --git a/build.php b/build.php
index 51bd2b5..4d186d9 100644
--- a/build.php
+++ b/build.php
@@ -21,24 +21,38 @@ $module_index = [];
 // Defined just in case a module needs to reference them when we require() them
 // to gain information
 $env = $paths = new stdClass();
-$paths->extra_data_directory = "._extra_data";
+$paths->extra_data_directory = "build/._extra_data";
 
 function register_module($settings)
 {
-	global $module_index;
+	global $module_index, $paths;
 	
-	// If the optional flag isn't set, then we should set it to false.
-	if(!isset($settings["optional"]) || !is_bool($settings["optional"]))
-		$settings["optional"] = false;
+	// Prepare any extra files
+	if(!file_exists($paths->extra_data_directory))
+		mkdir($paths->extra_data_directory, 0750);
+	
+	foreach($settings["extra_data"] ?? [] as $filename => $file_def) {
+		$destination_filename = "$paths->extra_data_directory/{$settings["id"]}/$filename";
+		if(!file_exists(dirname($destination_filename)))
+			mkdir(dirname($destination_filename), 0750, true);
+		
+		$source = fopen($file_def, "r");
+		$destination = fopen($destination_filename, "w");
+		
+		stream_copy_to_stream($source, $destination);
+		fclose($source);
+		fclose($destination);
+	}
 	
 	$newmodule = [
+		"id" => $settings["id"],
 		"name" => $settings["name"],
 		"version" => $settings["version"],
 		"author" => $settings["author"],
 		"description" => $settings["description"],
-		"id" => $settings["id"],
 		"lastupdate" => filemtime("modules/" . $settings["id"] . ".php"),
-		"optional" => $settings["optional"],
+		// May not be set. Defaults to false
+		"optional" => $settings["optional"] ?? false,
 		"extra_data" => $settings["extra_data"] ?? []
 	];
 	$module_index[] = $newmodule;
diff --git a/module_index.json b/module_index.json
index 43c22be..9f48e24 100755
--- a/module_index.json
+++ b/module_index.json
@@ -1,321 +1,321 @@
 [
     {
+        "id": "action-hash",
         "name": "Password hashing action",
         "version": "0.7",
         "author": "Starbeamrainbowlabs",
         "description": "Adds a utility action (that anyone can use) called hash that hashes a given string. Useful when changing a user's password.",
-        "id": "action-hash",
         "lastupdate": 1549840565,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "action-protect",
         "name": "Page protection",
         "version": "0.2",
         "author": "Starbeamrainbowlabs",
         "description": "Exposes Pepperminty Wiki's new page protection mechanism and makes the protect button in the 'More...' menu on the top bar work.",
-        "id": "action-protect",
         "lastupdate": 1465751051,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "action-random",
         "name": "Random Page",
         "version": "0.3",
         "author": "Starbeamrainbowlabs",
         "description": "Adds an action called 'random' that redirects you to a random page.",
-        "id": "action-random",
         "lastupdate": 1530448215,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "action-raw",
         "name": "Raw page source",
         "version": "0.7",
         "author": "Starbeamrainbowlabs",
         "description": "Adds a 'raw' action that shows you the raw source of a page.",
-        "id": "action-raw",
         "lastupdate": 1507993763,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "api-status",
         "name": "API status",
         "version": "0.1",
         "author": "Starbeamrainbowlabs",
         "description": "Provides a basic JSON status action that provides a few useful bits of information for API consumption.",
-        "id": "api-status",
         "lastupdate": 1530565418,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "extra-sidebar",
         "name": "Sidebar",
         "version": "0.3.1",
         "author": "Starbeamrainbowlabs",
         "description": "Adds a sidebar to the left hand side of every page. Add '$settings->sidebar_show = true;' to your configuration, or append '&sidebar=yes' to the url to enable. Adding to the url sets a cookie to remember your setting.",
-        "id": "extra-sidebar",
         "lastupdate": 1505768813,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "feature-comments",
         "name": "Page Comments",
         "version": "0.3.2",
         "author": "Starbeamrainbowlabs",
         "description": "Adds threaded comments to the bottom of every page.",
-        "id": "feature-comments",
         "lastupdate": 1549840530,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "feature-guiconfig",
         "name": "Settings GUI",
         "version": "0.1.3",
         "author": "Starbeamrainbowlabs",
         "description": "The module everyone has been waiting for! Adds a web based gui that lets mods change the wiki settings.",
-        "id": "feature-guiconfig",
         "lastupdate": 1548629209,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "feature-history",
         "name": "Page History",
         "version": "0.4.1",
         "author": "Starbeamrainbowlabs",
         "description": "Adds the ability to keep unlimited page history, limited only by your disk space. Note that this doesn't store file history (yet). Currently depends on feature-recent-changes for rendering of the history page.",
-        "id": "feature-history",
         "lastupdate": 1541003921,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "feature-interwiki-links",
         "name": "Interwiki links",
         "version": "0.1.1",
         "author": "Starbeamrainbowlabs",
         "description": "Adds interwiki link support. Set the interwiki_index_location setting at an index file to activate support.",
-        "id": "feature-interwiki-links",
         "lastupdate": 1549840688,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "feature-recent-changes",
         "name": "Recent Changes",
         "version": "0.5",
         "author": "Starbeamrainbowlabs",
         "description": "Adds recent changes. Access through the 'recent-changes' action.",
-        "id": "feature-recent-changes",
         "lastupdate": 1549840473,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "feature-redirect",
         "name": "Redirect pages",
         "version": "0.3.1",
         "author": "Starbeamrainbowlabs",
         "description": "Adds support for redirect pages. Uses the same syntax that Mediawiki does.",
-        "id": "feature-redirect",
         "lastupdate": 1549840590,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "feature-search",
         "name": "Search",
         "version": "0.7",
         "author": "Starbeamrainbowlabs",
         "description": "Adds proper search functionality to Pepperminty Wiki using an inverted index to provide a full text search engine. If pages don't show up, then you might have hit a stop word. If not, try requesting the `invindex-rebuild` action to rebuild the inverted index from scratch.",
-        "id": "feature-search",
         "lastupdate": 1549840628,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "feature-stats",
         "name": "Statistics",
         "version": "0.2",
         "author": "Starbeamrainbowlabs",
         "description": "An extensible statistics calculation system. Comes with a range of built-in statistics, but can be extended by other modules too.",
-        "id": "feature-stats",
         "lastupdate": 1530614499,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "feature-upload",
         "name": "Uploader",
         "version": "0.5.14",
         "author": "Starbeamrainbowlabs",
         "description": "Adds the ability to upload files to Pepperminty Wiki. Uploaded files act as pages and have the special 'File\/' prefix.",
-        "id": "feature-upload",
         "lastupdate": 1548629209,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "feature-user-preferences",
         "name": "User Preferences",
         "version": "0.3.3",
         "author": "Starbeamrainbowlabs",
         "description": "Adds a user preferences page, letting people do things like change their email address and password.",
-        "id": "feature-user-preferences",
         "lastupdate": 1526035213,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "feature-user-table",
         "name": "User Organiser",
         "version": "0.1",
         "author": "Starbeamrainbowlabs",
         "description": "Adds a organiser page that lets moderators (or better) control the reegistered user accounts, and perform adminstrative actions such as password resets, and adding \/ removing accounts.",
-        "id": "feature-user-table",
         "lastupdate": 1526423111,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-credits",
         "name": "Credits",
         "version": "0.7.9",
         "author": "Starbeamrainbowlabs",
         "description": "Adds the credits page. You *must* have this module :D",
-        "id": "page-credits",
         "lastupdate": 1540998605,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-debug-info",
         "name": "Debug Information",
         "version": "0.1.1",
         "author": "Starbeamrainbowlabs",
         "description": "Adds a debug action for administrator use only that collects a load of useful information to make reporting bugs easier.",
-        "id": "page-debug-info",
         "lastupdate": 1524415876,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-delete",
         "name": "Page deleter",
         "version": "0.10",
         "author": "Starbeamrainbowlabs",
         "description": "Adds an action to allow administrators to delete pages.",
-        "id": "page-delete",
         "lastupdate": 1501009581,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-edit",
         "name": "Page editor",
         "version": "0.17.3",
         "author": "Starbeamrainbowlabs",
         "description": "Allows you to edit pages by adding the edit and save actions. You should probably include this one.",
-        "id": "page-edit",
         "lastupdate": 1548629209,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-export",
         "name": "Export",
         "version": "0.5",
         "author": "Starbeamrainbowlabs",
         "description": "Adds a page that you can use to export your wiki as a .zip file. Uses $settings->export_only_allow_admins, which controls whether only admins are allowed to export the wiki.",
-        "id": "page-export",
         "lastupdate": 1548970758,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-help",
         "name": "Help page",
         "version": "0.9.3",
         "author": "Starbeamrainbowlabs",
         "description": "Adds a rather useful help page. Access through the 'help' action. This module also exposes help content added to Pepperminty Wiki's inbuilt invisible help section system.",
-        "id": "page-help",
         "lastupdate": 1492433537,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-list",
         "name": "Page list",
         "version": "0.11",
         "author": "Starbeamrainbowlabs",
         "description": "Adds a page that lists all the pages in the index along with their metadata.",
-        "id": "page-list",
         "lastupdate": 1548364613,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-login",
         "name": "Login",
         "version": "0.9.2",
         "author": "Starbeamrainbowlabs",
         "description": "Adds a pair of actions (login and checklogin) that allow users to login. You need this one if you want your users to be able to login.",
-        "id": "page-login",
         "lastupdate": 1540050129,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-logout",
         "name": "Logout",
         "version": "0.6.1",
         "author": "Starbeamrainbowlabs",
         "description": "Adds an action to let users user out. For security reasons it is wise to add this module since logging in automatically opens a session that is valid for 30 days.",
-        "id": "page-logout",
         "lastupdate": 1526034779,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-move",
         "name": "Page mover",
         "version": "0.9.3",
         "author": "Starbeamrainbowlabs",
         "description": "Adds an action to allow administrators to move pages.",
-        "id": "page-move",
         "lastupdate": 1521408303,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-update",
         "name": "Update",
         "version": "0.6.2",
         "author": "Starbeamrainbowlabs",
         "description": "Adds an update page that downloads the latest stable version of Pepperminty Wiki. This module is currently outdated as it doesn't save your module preferences.",
-        "id": "page-update",
         "lastupdate": 1476906745,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-user-list",
         "name": "User list",
         "version": "0.1",
         "author": "Starbeamrainbowlabs",
         "description": "Adds a 'user-list' action that generates a list of users. Supports json output with 'format=json' in the queyr string.",
-        "id": "page-user-list",
         "lastupdate": 1487454626,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "page-view",
         "name": "Page viewer",
         "version": "0.16.7",
         "author": "Starbeamrainbowlabs",
         "description": "Allows you to view pages. You really should include this one.",
-        "id": "page-view",
         "lastupdate": 1548884009,
         "optional": false,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "parser-default-old",
         "name": "Old Default Parser",
         "version": "0.10.1",
         "author": "Johnny Broadway & Starbeamrainbowlabs",
         "description": "The *old* default parser for Pepperminty Wiki. Based on Johnny Broadway's Slimdown (with more than a few modifications). This parser's features are documented in the help page. Superceded by a customised extension of parsedown extra.",
-        "id": "parser-default-old",
         "lastupdate": 1549839049,
         "optional": true,
-        "extra_data": null
+        "extra_data": []
     },
     {
+        "id": "parser-parsedown",
         "name": "Parsedown",
         "version": "0.10",
         "author": "Emanuil Rusev & Starbeamrainbowlabs",
         "description": "An upgraded (now default!) parser based on Emanuil Rusev's Parsedown Extra PHP library (https:\/\/github.com\/erusev\/parsedown-extra), which is licensed MIT. Please be careful, as this module adds some weight to your installation, and also *requires* write access to the disk on first load.",
-        "id": "parser-parsedown",
-        "lastupdate": 1551211981,
+        "lastupdate": 1551533295,
         "optional": false,
         "extra_data": {
             "Parsedown.php": "https:\/\/raw.githubusercontent.com\/erusev\/parsedown\/819c68899d593503180ed79ef4be5a4dcd8c5f92\/Parsedown.php",
diff --git a/modules/parser-parsedown.php b/modules/parser-parsedown.php
index 57b6974..bdc88a6 100644
--- a/modules/parser-parsedown.php
+++ b/modules/parser-parsedown.php
@@ -215,8 +215,8 @@ register_module([
 	}
 ]);
 
-require_once("$paths->extra_data_directory/Parsedown.php");
-require_once("$paths->extra_data_directory/ParsedownExtra.php");
+require_once("$paths->extra_data_directory/parser-parsedown/Parsedown.php");
+require_once("$paths->extra_data_directory/parser-parsedown/ParsedownExtra.php");
 
 /**
  * Attempts to 'auto-correct' a page name by trying different capitalisation
diff --git a/pack.php b/pack.php
index be8a64e..7b80d07 100644
--- a/pack.php
+++ b/pack.php
@@ -4,14 +4,14 @@
  * Logs a string to stdout, but only on the CLI.
  * @param  string $line The line to log.
  */
-function log(string $line) {
+function log_str(string $line) {
 	if(php_sapi_name() == "cli")
 		echo($line);
 	//else error_log($line);
 }
 
-log("*** Beginning main build sequence ***\n");
-log("Reading in module index...\n");
+log_str("*** Beginning main build sequence ***\n");
+log_str("Reading in module index...\n");
 
 $module_index = json_decode(file_get_contents("module_index.json"));
 $module_list = [];
@@ -37,7 +37,7 @@ if(php_sapi_name() != "cli") {
 	header("content-disposition: attachment; filename=\"index.php\"");
 }
 
-log("Reading in core files...\n");
+log_str("Reading in core files...\n");
 
 // We trim from the end here because of the __halt_compiler() directive
 $core = rtrim(file_get_contents("core.php"));
@@ -76,11 +76,11 @@ foreach($module_list as $module)
 {
 	if($module->id == "") continue;
 	
-	log("[$i / $module_list_count] Adding $module->id      \r");
+	log_str("[$i / $module_list_count] Adding $module->id      \r");
 	
 	$module_filepath = "modules/" . preg_replace("[^a-zA-Z0-9\-]", "", $module->id) . ".php";
 	
-	//log("id: $module->id | filepath: $module_filepath\n");
+	//log_str("id: $module->id | filepath: $module_filepath\n");
 	
 	if(!file_exists($module_filepath)) {
 		http_response_code(400);
@@ -101,27 +101,27 @@ foreach($module_list as $module)
 	foreach($module->extra_data as $filepath_pack => $extra_data_item) {
 		if(is_string($extra_data_item)) {
 			// TODO: Test whether this works for urls. If not, then we'll need to implement a workaround
-			$extra_data_archive->addFile($extra_data_item, "$module->id/$filepath_pack");
+			$extra_data_archive->addFile("$paths->extra_data_directory/$module->id/$filepath_pack", "$module->id/$filepath_pack");
 		}
 	}
 	
 	$i++;
 }
-log("\n");
+log_str("\n");
 
 $archive_stream = fopen("php://fd/$archive_file_descriptor", "r");
 
 $output_stream = null;
 if(php_sapi_name() == "cli") {
 	if(file_exists("build/index.php")) {
-		log("index.php already exists in the build folder, exiting\n");
+		log_str("index.php already exists in the build folder, exiting\n");
 		exit(1);
 	}
 	
-	log("Done. Saving to disk...");
+	log_str("Done. Saving to disk...");
 	$output_stream = fopen("build/index.php", "w");
-	log("complete!\n");
-	log("*** Build completed! ***\n");
+	log_str("complete!\n");
+	log_str("*** Build completed! ***\n");
 }
 else {
 	$output_stream = fopen("php://output", "w");
