01138: Identify the PageStore of a page

Summary: Identify the PageStore of a page
Created: 2009-09-04 02:36
Status: Open
Category: Feature
Assigned:
Priority: 55
Version: 2.2.x

Description: Currently, it isn't possible to determine the PageStore from which a page has been found. This presents difficulties especially on sites using a wikifarm that shares some PageStore between the wikis, as it isn't possible to determine if a page is local only to the current wiki, or to all wikis on a wikifarm. To fix this, a small change is required in the ReadPage function in pmwiki.php:

===================================================================
--- pmwiki.php	(revision 2413)
+++ pmwiki.php	(working copy)
@@ -994,11 +994,11 @@
 function ReadPage($pagename, $since=0) {
   # read a page from the appropriate directories given by $WikiReadDirsFmt.
   global $WikiLibDirs,$Now;
-  foreach ($WikiLibDirs as $dir) {
+  foreach ($WikiLibDirs as $key => $dir) {
     $page = $dir->read($pagename, $since);
-    if ($page) break;
+    if ($page) { $page['=source'] = $key; break; }
   }
   if (@!$page) $page['ctime'] = $Now;
   if (@!$page['time']) $page['time'] = $Now;
   return $page;
 }

With the above, the $page array will gain an entry '=source' that will hold the key to the $WikiLibDirs array entry of the corresponding PageStore. Using = as the first character of the key will prevent it from being written to disk when the page is saved.

We could also add something like $page['=sourcedir'] = $dir->dirfmt; --Petko

But why? That loses information in case you have for whatever reason matching dirfmts, and requires a lookup from the PageStore. Also actually using the information later becomes more difficult, as you need to look for a matching value in a PageStore in $WikiLibDirs instead of just having the key. —Eemeli Aro

As a side effect, not setting this value for pages that aren't found means that its non-existence when writing the page to disk can be used to mark the change in recent changes as the creation of a new page.

For convenience, the default $WikiLibDirs declaration could also be modified to provide literal keys:

===================================================================
--- pmwiki.php	(revision 2413)
+++ pmwiki.php	(working copy)
@@ -49,3 +49,3 @@
 $WikiDir = new PageStore('wiki.d/{$FullName}');
-$WikiLibDirs = array(&$WikiDir,new PageStore('$FarmD/wikilib.d/{$FullName}'));
+$WikiLibDirs = array('local' => &$WikiDir, 'wikilib' => new PageStore('$FarmD/wikilib.d/{$FullName}'));
 $LocalDir = 'local';

These changes should be completely backwards-compatible and transparent if not directly used.


This looks great, but could there be side effects for wikis having this if also there is a recipe containing
for($i=0; $i<count($WikiLibDirs); $i++) { $d = $WikiLibDirs[$i]; /* do something */ }
I thing this is unlikely though. --Petko September 04, 2009, at 03:48 AM

The only recipe that I could find that conflicts with named pagestores is DataQuery, which loops through $WikiLibDirs as above, but should be really easy to patch (one- or two-line change). A few recipes re-set $WikiLibDirs directly to some new value, in which cases the names would be lost. Splicing works fine no matter what the keys are. —Eemeli Aro September 04, 2009, at 05:21 AM