From 712e95474c2a5c1d74fe240f4bdecb11661202eb Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Sat, 1 Jun 2019 15:55:48 +0100
Subject: [PATCH] Minify the pageindex by default, but also add a setting to
 control this

---
 Changelog.md                 |  2 ++
 core/05-functions.php        | 27 ++++++++++++++++++---------
 core/20-pageindex-loader.php |  2 +-
 module_index.json            | 28 ++++++++++++++--------------
 modules/action-protect.php   |  4 ++--
 modules/feature-history.php  | 17 +++++++++--------
 modules/feature-upload.php   |  4 ++--
 modules/page-delete.php      |  4 ++--
 modules/page-edit.php        |  5 ++---
 modules/page-move.php        |  4 ++--
 peppermint.guiconfig.json    |  3 ++-
 11 files changed, 56 insertions(+), 44 deletions(-)

diff --git a/Changelog.md b/Changelog.md
index 1d796e0..a4b4467 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -23,6 +23,8 @@ This file holds the changelog for Pepperminty Wiki. This is the master list of t
      - It also checks to ensure that access to `peppermint.json` is blocked correctly (coming soon as a one-time check to pre-existing wikis)
      - Pre-existing wikis will not see this first-run wizard - a new `firstrun_complete` setting has been added that's automatically set to true if Pepperminty Wiki does a settings upgrade
  - Default to allowing lossless flac and ogg audio files to be uploaded
+ - Added new `minify_pageindex` setting, which defaults to `true` and causes the page index to be minified when saved. Improves performance slightly (especially on larger wikis as the page index grows), but makes debugging and ninja-edits more awkward.
+ - [Module API] Added new `save_pageindex()` function which respects the above setting.
 
 ### Changed
  - Core sharding: split `core.php` into multiple files
diff --git a/core/05-functions.php b/core/05-functions.php
index fde0628..48de4f0 100644
--- a/core/05-functions.php
+++ b/core/05-functions.php
@@ -169,10 +169,7 @@ function check_subpage_parents(string $pagename)
 	global $pageindex, $paths, $env;
 	// Save the new pageindex and return if there aren't any more parent pages to check
 	if(strpos($pagename, "/") === false)
-	{
-		file_put_contents($paths->pageindex, json_encode($pageindex, JSON_PRETTY_PRINT));
-		return;
-	}
+		return save_pageindex();
 
 	$parent_pagename = substr($pagename, 0, strrpos($pagename, "/"));
 	$parent_page_filename = "$parent_pagename.md";
@@ -527,20 +524,32 @@ function render_editor($editorName)
 
 /**
  * Saves the settings file back to peppermint.json.
- * @return bool Whether the settings were saved successfully.
+ * @package	core
+ * @return	bool	Whether the settings were saved successfully.
  */
 function save_settings() {
 	global $paths, $settings;
 	return file_put_contents($paths->settings_file, json_encode($settings, JSON_PRETTY_PRINT)) !== false;
 }
+/**
+ * Save the page index back to disk, respecting $settings->minify_pageindex
+ * @package	core
+ * @return	bool	Whether the page index was saved successfully or not.
+ */
+function save_pageindex() {
+	global $paths, $settings, $pageindex;
+	return file_put_contents(
+		$paths->pageindex,
+		json_encode($pageindex, $settings->minify_pageindex ? 0 : JSON_PRETTY_PRINT)
+	);
+}
 
 /**
  * Saves the currently logged in user's data back to peppermint.json.
- * @package core
- * @return bool Whether the user's data was saved successfully. Returns false if the user isn't logged in.
+ * @package	core
+ * @return	bool	Whether the user's data was saved successfully. Returns false if the user isn't logged in.
  */
-function save_userdata()
-{
+function save_userdata() {
 	global $env, $settings, $paths;
 	
 	if(!$env->is_logged_in)
diff --git a/core/20-pageindex-loader.php b/core/20-pageindex-loader.php
index 58fef30..72a0af2 100644
--- a/core/20-pageindex-loader.php
+++ b/core/20-pageindex-loader.php
@@ -80,7 +80,7 @@ if(!file_exists($paths->pageindex))
 		// Store the new entry in the new page index
 		$pageindex->$pagekey = $newentry;
 	}
-	file_put_contents($paths->pageindex, json_encode($pageindex, JSON_PRETTY_PRINT));
+	save_pageindex();
 	unset($existingpages);
 }
 else
diff --git a/module_index.json b/module_index.json
index f5c968b..f193492 100755
--- a/module_index.json
+++ b/module_index.json
@@ -12,10 +12,10 @@
     {
         "id": "action-protect",
         "name": "Page protection",
-        "version": "0.2",
+        "version": "0.2.1",
         "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.",
-        "lastupdate": 1465751051,
+        "lastupdate": 1559400034,
         "optional": false,
         "extra_data": []
     },
@@ -75,7 +75,7 @@
         "version": "0.1",
         "author": "Starbeamrainbowlabs",
         "description": "Displays a special page to aid in setting up a new wiki for the first time.",
-        "lastupdate": 1557611407,
+        "lastupdate": 1557611471,
         "optional": false,
         "extra_data": []
     },
@@ -92,10 +92,10 @@
     {
         "id": "feature-history",
         "name": "Page History",
-        "version": "0.4.1",
+        "version": "0.4.2",
         "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.",
-        "lastupdate": 1541003921,
+        "lastupdate": 1559400114,
         "optional": false,
         "extra_data": []
     },
@@ -135,7 +135,7 @@
         "version": "0.7.1",
         "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.",
-        "lastupdate": 1557182908,
+        "lastupdate": 1557653831,
         "optional": false,
         "extra_data": []
     },
@@ -152,10 +152,10 @@
     {
         "id": "feature-upload",
         "name": "Uploader",
-        "version": "0.5.14",
+        "version": "0.5.16",
         "author": "Starbeamrainbowlabs",
         "description": "Adds the ability to upload files to Pepperminty Wiki. Uploaded files act as pages and have the special 'File\/' prefix.",
-        "lastupdate": 1548629209,
+        "lastupdate": 1559400139,
         "optional": false,
         "extra_data": []
     },
@@ -202,20 +202,20 @@
     {
         "id": "page-delete",
         "name": "Page deleter",
-        "version": "0.10",
+        "version": "0.10.1",
         "author": "Starbeamrainbowlabs",
         "description": "Adds an action to allow administrators to delete pages.",
-        "lastupdate": 1557585339,
+        "lastupdate": 1559400151,
         "optional": false,
         "extra_data": []
     },
     {
         "id": "page-edit",
         "name": "Page editor",
-        "version": "0.17.3",
+        "version": "0.17.4",
         "author": "Starbeamrainbowlabs",
         "description": "Allows you to edit pages by adding the edit and save actions. You should probably include this one.",
-        "lastupdate": 1551560775,
+        "lastupdate": 1559400186,
         "optional": false,
         "extra_data": {
             "diff.min.js": "https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jsdiff\/2.2.2\/diff.min.js"
@@ -274,10 +274,10 @@
     {
         "id": "page-move",
         "name": "Page mover",
-        "version": "0.9.3",
+        "version": "0.9.4",
         "author": "Starbeamrainbowlabs",
         "description": "Adds an action to allow administrators to move pages.",
-        "lastupdate": 1521408303,
+        "lastupdate": 1559400217,
         "optional": false,
         "extra_data": []
     },
diff --git a/modules/action-protect.php b/modules/action-protect.php
index 927a11c..d283119 100644
--- a/modules/action-protect.php
+++ b/modules/action-protect.php
@@ -1,7 +1,7 @@
 <?php
 register_module([
 	"name" => "Page protection",
-	"version" => "0.2",
+	"version" => "0.2.1",
 	"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",
@@ -45,7 +45,7 @@ register_module([
 				}
 				
 				// Save the pageindex
-				file_put_contents($paths->pageindex, json_encode($pageindex, JSON_PRETTY_PRINT));
+				save_pageindex();
 				
 				$state = ($pageindex->$page->protect ? "enabled" : "disabled");
 				$title = "Page protection $state.";
diff --git a/modules/feature-history.php b/modules/feature-history.php
index 819b894..2036ce5 100644
--- a/modules/feature-history.php
+++ b/modules/feature-history.php
@@ -1,7 +1,7 @@
 <?php
 register_module([
 	"name" => "Page History",
-	"version" => "0.4.1",
+	"version" => "0.4.2",
 	"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",
@@ -213,11 +213,12 @@ register_module([
  * records a new revision against a page name. Thus it is possible to have a 
  * disparaty between the history revisions and the actual content displayed in 
  * the current revision if you're not careful!
- * @param object  $pageinfo       The pageindex object of the page to operate on.
- * @param string  $newsource      The page content to save as the new revision.
- * @param string  $oldsource      The old page content that is the current revision (before the update).
- * @param boolean $save_pageindex Whether the page index should be saved to disk.
- * @param string  $change_type    The type of change to record this as in the history revision log
+ * @package	feature-history
+ * @param	object	$pageinfo		The pageindex object of the page to operate on.
+ * @param	string	$newsource		The page content to save as the new revision.
+ * @param	string	$oldsource		The old page content that is the current revision (before the update).
+ * @param	bool	$save_pageindex	Whether the page index should be saved to disk.
+ * @param	string	$change_type	The type of change to record this as in the history revision log
  */
 function history_add_revision(&$pageinfo, &$newsource, &$oldsource, $save_pageindex = true, $change_type = "edit") {
 	global $env, $paths, $settings, $pageindex;
@@ -233,7 +234,7 @@ function history_add_revision(&$pageinfo, &$newsource, &$oldsource, $save_pagein
 	// this point
 	
 	// TODO Store tag changes here
-	end($pageinfo->history); // Calculate the next revision id - we can't just count the reivisions here because we might have a revision limit
+	end($pageinfo->history); // Calculate the next revision id - we can't just count the revisions here because we might have a revision limit
 	$nextRid = !empty($pageindex->history) ? $pageinfo->history[key($pageinfo->history)]->rid + 1 : 0;
 	$ridFilename = "$pageinfo->filename.r$nextRid";
 	// Insert a new entry into the history
@@ -261,7 +262,7 @@ function history_add_revision(&$pageinfo, &$newsource, &$oldsource, $save_pagein
 	
 	// Save the edited pageindex
 	if($result !== false && $save_pageindex)
-		$result = file_put_contents($paths->pageindex, json_encode($pageindex, JSON_PRETTY_PRINT));
+		$result = save_pageindex();
 	
 	
 	return $result;
diff --git a/modules/feature-upload.php b/modules/feature-upload.php
index 822f4b3..a5d88b3 100644
--- a/modules/feature-upload.php
+++ b/modules/feature-upload.php
@@ -1,7 +1,7 @@
 <?php
 register_module([
 	"name" => "Uploader",
-	"version" => "0.5.15",
+	"version" => "0.5.16",
 	"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",
@@ -258,7 +258,7 @@ register_module([
 					}
 					
 					// Save the pageindex
-					file_put_contents($paths->pageindex, json_encode($pageindex, JSON_PRETTY_PRINT));
+					save_pageindex();
 					
 					if(module_exists("feature-recent-changes"))
 					{
diff --git a/modules/page-delete.php b/modules/page-delete.php
index 8662cb0..be2b028 100644
--- a/modules/page-delete.php
+++ b/modules/page-delete.php
@@ -1,7 +1,7 @@
 <?php
 register_module([
 	"name" => "Page deleter",
-	"version" => "0.10",
+	"version" => "0.10.1",
 	"author" => "Starbeamrainbowlabs",
 	"description" => "Adds an action to allow administrators to delete pages.",
 	"id" => "page-delete",
@@ -78,7 +78,7 @@ register_module([
 			unset($pageindex->$page);
 			
 			// Save the new page index
-			file_put_contents($paths->pageindex, json_encode($pageindex, JSON_PRETTY_PRINT)); 
+			save_pageindex();
 			
 			// Remove the page's name from the id index
 			ids::deletepagename($env->page);
diff --git a/modules/page-edit.php b/modules/page-edit.php
index 02aaeb4..cc842fd 100644
--- a/modules/page-edit.php
+++ b/modules/page-edit.php
@@ -1,7 +1,7 @@
 <?php
 register_module([
 	"name" => "Page editor",
-	"version" => "0.17.3",
+	"version" => "0.17.4",
 	"author" => "Starbeamrainbowlabs",
 	"description" => "Allows you to edit pages by adding the edit and save actions. You should probably include this one.",
 	"id" => "page-edit",
@@ -504,8 +504,7 @@ DIFFSCRIPT;
 				if($pagedata !== $pagedata_orig)
 					file_put_contents("$env->storage_prefix$env->page.md", $pagedata);
 				
-				
-				file_put_contents($paths->pageindex, json_encode($pageindex, JSON_PRETTY_PRINT));
+				save_pageindex();
 				
 				if(isset($_GET["newpage"]))
 					http_response_code(201);
diff --git a/modules/page-move.php b/modules/page-move.php
index b86b743..b5d16b7 100644
--- a/modules/page-move.php
+++ b/modules/page-move.php
@@ -1,7 +1,7 @@
 <?php
 register_module([
 	"name" => "Page mover",
-	"version" => "0.9.3",
+	"version" => "0.9.4",
 	"author" => "Starbeamrainbowlabs",
 	"description" => "Adds an action to allow administrators to move pages.",
 	"id" => "page-move",
@@ -111,7 +111,7 @@ register_module([
 			}
 			
 			// Save the updated pageindex
-			file_put_contents($paths->pageindex, json_encode($pageindex, JSON_PRETTY_PRINT));
+			save_pageindex();
 			
 			// Move the page on the disk
 			rename("$env->storage_prefix$env->page.md", "$env->storage_prefix$new_name.md");
diff --git a/peppermint.guiconfig.json b/peppermint.guiconfig.json
index 8405c72..16917d0 100644
--- a/peppermint.guiconfig.json
+++ b/peppermint.guiconfig.json
@@ -166,7 +166,8 @@
 	"dynamic_page_suggestion_count": { "type": "number", "description": "The number of dynamic page name suggestions to fetch from the server when typing in the page search box. Note that lowering this number doesn't <em>really</em> improve performance. Set to 0 to disable.", "default": 7 },
 	"defaultaction": { "type": "text", "description": "The default action. This action will be performed if no other action is specified. It is recommended you set this to \"view\" - that way the user automatically views the default page (see above).", "default": "view" },
 	"updateurl": { "type": "url", "description": "The url from which to fetch updates. Defaults to the master (development) branch. MAKE SURE THAT THIS POINTS TO A *HTTPS* URL, OTHERWISE SOMEONE COULD INJECT A VIRUS INTO YOUR WIKI!", "default": "https://raw.githubusercontent.com/sbrl/pepperminty-wiki/master/index.php" },
-	"optimize_pages": { "type": "checkbox", "description": "Whether to optimise all webpages generated.", "default": true},
+	"optimize_pages": { "type": "checkbox", "description": "Whether to optimise all webpages generated.", "default": true },
+	"minify_pageindex": { "type": "checkbox", "description": "Whether to minify the page index when saving it. Improves performance slightly (especially on larger wikis), but can make debugging and quick ninja-edits more awkward. Note that this only takes effect when the page index is next saved.", "default": true },
 	"http2_server_push": { "type": "checkbox", "description": "Whether HTTP/2.0 server should should be enabled. If true, then 'link' HTTP headers will be attached to rendered pages specifying files to push down. Note that web server support <em>also</em> has to be abled for this to work, as PHP can't push resources to the client on its own.", "default": true },
 	"http2_server_push_items": { "type": "server-push", "description": "An array of items to push to clients when rendering pages. Should be in the format <code>[ [type, path], [type, path], ....]</code>, where <code>type</code> is a <a href='https://fetch.spec.whatwg.org/#concept-request-destination'>resource type</a>, and <code>path</code> is a relative url path to a static file to send via <em>HTTP/2.0 Server Push</em>.<br />Note: These resources will only be pushed if your web server also has support for the link: HTTP/2.0 header, and it's a page that being rendered. If it's some other thing that being sent (e.g. an image, error message, event stream, redirect, etc.), then no server push is indicated by <em>Pepperminty Wiki</em>. Test your estup with your browser's developer tools, or <a href='https://http2-push.io/'>This testing site</a>.", "default": [] },
 	"max_recent_changes": { "type": "number", "description": "The maximum number of recent changes to display on the recent changes page.", "default": 512},
