summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inc/common.php22
-rw-r--r--inc/io.php124
-rw-r--r--inc/media.php2
-rw-r--r--lib/exe/mediamanager.php2
4 files changed, 133 insertions, 17 deletions
diff --git a/inc/common.php b/inc/common.php
index b1246ba7f..564d1f666 100644
--- a/inc/common.php
+++ b/inc/common.php
@@ -614,7 +614,7 @@ function rawLocale($id){
* @author Andreas Gohr <andi@splitbrain.org>
*/
function rawWiki($id,$rev=''){
- return io_readFile(wikiFN($id,$rev));
+ return io_readWikiPage(wikiFN($id, $rev), $id, $rev);
}
/**
@@ -649,7 +649,7 @@ function pageTemplate($id){
*/
function rawWikiSlices($range,$id,$rev=''){
list($from,$to) = split('-',$range,2);
- $text = io_readFile(wikiFN($id,$rev));
+ $text = io_readWikiPage(wikiFN($id, $rev), $id, $rev);
if(!$from) $from = 0;
if(!$to) $to = strlen($text)+1;
@@ -1019,7 +1019,7 @@ function getRevisionInfo($id,$rev,$mem_cache=true){
/**
- * Saves a wikitext by calling io_saveFile
+ * Saves a wikitext by calling io_writeWikiPage
*
* @author Andreas Gohr <andi@splitbrain.org>
*/
@@ -1045,13 +1045,12 @@ function saveWikiText($id,$text,$summary,$minor=false){
$del = true;
// autoset summary on deletion
if(empty($summary)) $summary = $lang['deleted'];
- // unlock early
- unlock($id);
// remove empty namespaces
- io_sweepNS($id);
+ io_sweepNS($id, 'datadir');
+ io_sweepNS($id, 'mediadir');
}else{
- // save file (datadir is created in io_saveFile)
- io_saveFile($file,$text);
+ // save file (namespace dir is created in io_writeWikiPage)
+ io_writeWikiPage($file, $text, $id);
saveMetadata($id, $file, $minor);
$del = false;
}
@@ -1100,12 +1099,7 @@ function saveOldRevision($id){
if(!@file_exists($oldf)) return '';
$date = filemtime($oldf);
$newf = wikiFN($id,$date);
- if(substr($newf,-3)=='.gz'){
- io_saveFile($newf,rawWiki($id));
- }else{
- io_makeFileDir($newf);
- copy($oldf, $newf);
- }
+ io_writeWikiPage($newf, rawWiki($id), $id, $date);
return $date;
}
diff --git a/inc/io.php b/inc/io.php
index aed27d88e..a71162c11 100644
--- a/inc/io.php
+++ b/inc/io.php
@@ -9,26 +9,74 @@
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
require_once(DOKU_INC.'inc/common.php');
require_once(DOKU_INC.'inc/HTTPClient.php');
+ require_once(DOKU_INC.'inc/events.php');
+ require_once(DOKU_INC.'inc/utf8.php');
/**
* Removes empty directories
*
+ * Sends IO_NAMESPACE_DELETED events for 'pages' and 'media' namespaces.
+ * Event data:
+ * $data[0] ns: The colon separated namespace path minus the trailing page name.
+ * $data[1] ns_type: 'pages' or 'media' namespace tree.
+ *
* @todo use safemode hack
* @author Andreas Gohr <andi@splitbrain.org>
+ * @author Ben Coburn <btcoburn@silicodon.net>
*/
function io_sweepNS($id,$basedir='datadir'){
global $conf;
+ $types = array ('datadir'=>'pages', 'mediadir'=>'media');
+ $ns_type = (isset($types[$basedir])?$types[$basedir]:false);
//scan all namespaces
while(($id = getNS($id)) !== false){
$dir = $conf[$basedir].'/'.utf8_encodeFN(str_replace(':','/',$id));
//try to delete dir else return
- if(!@rmdir($dir)) return;
+ if(@rmdir($dir)) {
+ if ($ns_type!==false) {
+ $data = array($id, $ns_type);
+ trigger_event('IO_NAMESPACE_DELETED', $data);
+ }
+ } else { return; }
}
}
/**
+ * Used to read in a DokuWiki page from file, and send IO_WIKIPAGE_READ events.
+ *
+ * Generates the action event which delegates to io_readFile().
+ * Action plugins are allowed to modify the page content in transit.
+ * The file path should not be changed.
+ *
+ * Event data:
+ * $data[0] The raw arguments for io_readFile as an array.
+ * $data[1] ns: The colon separated namespace path minus the trailing page name. (false if root ns)
+ * $data[2] page_name: The wiki page name.
+ * $data[3] rev: The page revision, false for current wiki pages.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function io_readWikiPage($file, $id, $rev=false) {
+ if (empty($rev)) { $rev = false; }
+ $data = array(array($file, false), getNS($id), noNS($id), $rev);
+ return trigger_event('IO_WIKIPAGE_READ', $data, '_io_readWikiPage_action', false);
+}
+
+/**
+ * Callback adapter for io_readFile().
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function _io_readWikiPage_action($data) {
+ if (is_array($data) && is_array($data[0]) && count($data[0])===2) {
+ return call_user_func_array('io_readFile', $data[0]);
+ } else {
+ return ''; //callback error
+ }
+}
+
+/**
* Returns content of $file as cleaned string.
*
* Uses gzip if extension is .gz
@@ -55,6 +103,41 @@ function io_readFile($file,$clean=true){
}
/**
+ * Used to write out a DokuWiki page to file, and send IO_WIKIPAGE_WRITE events.
+ *
+ * This generates an action event and delegates to io_saveFile().
+ * Action plugins are allowed to modify the page content in transit.
+ * The file path should not be changed.
+ * (The append parameter is set to false.)
+ *
+ * Event data:
+ * $data[0] The raw arguments for io_saveFile as an array.
+ * $data[1] ns: The colon separated namespace path minus the trailing page name. (false if root ns)
+ * $data[2] page_name: The wiki page name.
+ * $data[3] rev: The page revision, false for current wiki pages.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function io_writeWikiPage($file, $content, $id, $rev=false) {
+ if (empty($rev)) { $rev = false; }
+ if ($rev===false) { io_createNamespace($id); } // create namespaces as needed
+ $data = array(array($file, $content, false), getNS($id), noNS($id), $rev);
+ return trigger_event('IO_WIKIPAGE_WRITE', $data, '_io_writeWikiPage_action', false);
+}
+
+/**
+ * Callback adapter for io_saveFile().
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function _io_writeWikiPage_action($data) {
+ if (is_array($data) && is_array($data[0]) && count($data[0])===3) {
+ return call_user_func_array('io_saveFile', $data[0]);
+ } else {
+ return false; //callback error
+ }
+}
+
+/**
* Saves $content to $file.
*
* If the third parameter is set to true the given content
@@ -205,6 +288,45 @@ function io_unlock($file){
}
/**
+ * Create missing namespace directories and send the IO_NAMESPACE_CREATED events
+ * in the order of directory creation. (Parent directories first.)
+ *
+ * Event data:
+ * $data[0] ns: The colon separated namespace path minus the trailing page name.
+ * $data[1] ns_type: 'pages' or 'media' namespace tree.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function io_createNamespace($id, $ns_type='pages') {
+ // verify ns_type
+ $types = array('pages'=>'wikiFN', 'media'=>'mediaFN');
+ if (!isset($types[$ns_type])) {
+ trigger_error('Bad $ns_type parameter for io_createNamespace().');
+ return;
+ }
+ // make event list
+ $missing = array();
+ $ns_stack = explode(':', $id);
+ $ns = $id;
+ $tmp = dirname( $file = call_user_func($types[$ns_type], $ns) );
+ while (!@is_dir($tmp) && !(@file_exists($tmp) && !is_dir($tmp))) {
+ array_pop($ns_stack);
+ $ns = implode(':', $ns_stack);
+ if (strlen($ns)==0) { break; }
+ $missing[] = $ns;
+ $tmp = dirname(call_user_func($types[$ns_type], $ns));
+ }
+ // make directories
+ io_makeFileDir($file);
+ // send the events
+ $missing = array_reverse($missing); // inside out
+ foreach ($missing as $ns) {
+ $data = array($ns, $ns_type);
+ trigger_event('IO_NAMESPACE_CREATED', $data);
+ }
+}
+
+/**
* Create the directory needed for the given file
*
* @author Andreas Gohr <andi@splitbrain.org>
diff --git a/inc/media.php b/inc/media.php
index e0b1f3747..384ecb580 100644
--- a/inc/media.php
+++ b/inc/media.php
@@ -218,7 +218,7 @@ function media_upload($ns,$auth){
return false;
}
// prepare directory
- io_makeFileDir($fn);
+ io_createNamespace($id, 'media');
if(move_uploaded_file($file['tmp_name'], $fn)) {
// Set the correct permission here.
// Always chmod media because they may be saved with different permissions than expected from the php umask.
diff --git a/lib/exe/mediamanager.php b/lib/exe/mediamanager.php
index b381fabf6..fc11ed36c 100644
--- a/lib/exe/mediamanager.php
+++ b/lib/exe/mediamanager.php
@@ -31,7 +31,7 @@
$AUTH = auth_quickaclcheck("$NS:*");
// create the given namespace (just for beautification)
- if($AUTH >= AUTH_UPLOAD) io_makeFileDir(mediaFN("$NS:xxx"));
+ if($AUTH >= AUTH_UPLOAD) { io_createNamespace("$NS:xxx", 'media'); }
// handle upload
if($_FILES['upload']['tmp_name']){