diff options
author | michael <michael@content-space.de> | 2009-01-18 16:43:45 +0100 |
---|---|---|
committer | michael <michael@content-space.de> | 2009-01-18 16:43:45 +0100 |
commit | 99c8d7f21203dc68bb191d77e01c2f8a6f0cf5a0 (patch) | |
tree | 6797f3dac32455b4ac4ba5ad8ce3ac6a1cf91bd8 | |
parent | 5dfff2790d523c9e0e0c1c4bcb8abd70675a213a (diff) | |
download | rpg-99c8d7f21203dc68bb191d77e01c2f8a6f0cf5a0.tar.gz rpg-99c8d7f21203dc68bb191d77e01c2f8a6f0cf5a0.tar.bz2 |
Media changelog added
There is a new media changelog now, with the flag RECENTS_MEDIA_CHANGES media changes can be requested from the getRecents()-function or the new getRecentsSince()-function, that returns all changes since a given timestamp and optionally before a given timestamp. The media upload and the XML-RPC-server have been changed to use these functions.
Additionally, the event MEDIA_UPLOAD_FINISH has been extended, it has a new $data-attribute (the 5th), that contains a boolean if the file does already exist and will be overwritten.
darcs-hash:20090118154345-074e0-5d9a90d269e86d8c6a156ecce5cf63115c827433.gz
-rw-r--r-- | inc/changelog.php | 108 | ||||
-rw-r--r-- | inc/common.php | 1 | ||||
-rw-r--r-- | inc/init.php | 1 | ||||
-rw-r--r-- | inc/media.php | 18 | ||||
-rw-r--r-- | lib/exe/indexer.php | 38 | ||||
-rw-r--r-- | lib/exe/xmlrpc.php | 123 |
6 files changed, 209 insertions, 80 deletions
diff --git a/inc/changelog.php b/inc/changelog.php index f60b487db..20e2ae340 100644 --- a/inc/changelog.php +++ b/inc/changelog.php @@ -96,6 +96,39 @@ function addLogEntry($date, $id, $type=DOKU_CHANGE_TYPE_EDIT, $summary='', $extr } /** + * Add's an entry to the media changelog + * + * @author Michael Hamann <michael@content-space.de> + * @author Andreas Gohr <andi@splitbrain.org> + * @author Esther Brunner <wikidesign@gmail.com> + * @author Ben Coburn <btcoburn@silicodon.net> + */ +function addMediaLogEntry($date, $id, $type=DOKU_CHANGE_TYPE_EDIT, $summary='', $extra='', $flags=null){ + global $conf, $INFO; + + $id = cleanid($id); + + if(!$date) $date = time(); //use current time if none supplied + $remote = $_SERVER['REMOTE_ADDR']; + $user = $_SERVER['REMOTE_USER']; + + $strip = array("\t", "\n"); + $logline = array( + 'date' => $date, + 'ip' => $remote, + 'type' => str_replace($strip, '', $type), + 'id' => $id, + 'user' => $user, + 'sum' => str_replace($strip, '', $summary), + 'extra' => str_replace($strip, '', $extra) + ); + + // add changelog lines + $logline = implode("\t", $logline)."\n"; + io_saveFile($conf['media_changelog'],$logline,true); //global media changelog cache +} + +/** * returns an array of recently changed files using the * changelog * @@ -105,6 +138,7 @@ function addLogEntry($date, $id, $type=DOKU_CHANGE_TYPE_EDIT, $summary='', $extr * RECENTS_SKIP_DELETED - don't include deleted pages * RECENTS_SKIP_MINORS - don't include minor changes * RECENTS_SKIP_SUBSPACES - don't include subspaces + * RECENTS_MEDIA_CHANGES - return media changes instead of page changes * * @param int $first number of first entry returned (for paginating * @param int $num return $num entries @@ -122,12 +156,17 @@ function getRecents($first,$num,$ns='',$flags=0){ return $recent; // read all recent changes. (kept short) - $lines = @file($conf['changelog']); + if ($flags & RECENTS_MEDIA_CHANGES) { + $lines = @file($conf['media_changelog']); + } else { + $lines = @file($conf['changelog']); + } // handle lines + $seen = array(); // caches seen lines, _handleRecent() skips them for($i = count($lines)-1; $i >= 0; $i--){ - $rec = _handleRecent($lines[$i], $ns, $flags); + $rec = _handleRecent($lines[$i], $ns, $flags, $seen); if($rec !== false) { if(--$first >= 0) continue; // skip first entries $recent[] = $rec; @@ -141,6 +180,62 @@ function getRecents($first,$num,$ns='',$flags=0){ } /** + * returns an array of files changed since a given time using the + * changelog + * + * The following constants can be used to control which changes are + * included. Add them together as needed. + * + * RECENTS_SKIP_DELETED - don't include deleted pages + * RECENTS_SKIP_MINORS - don't include minor changes + * RECENTS_SKIP_SUBSPACES - don't include subspaces + * RECENTS_MEDIA_CHANGES - return media changes instead of page changes + * + * @param int $from date of the oldest entry to return + * @param int $to date of the newest entry to return (for pagination, optional) + * @param string $ns restrict to given namespace (optional) + * @param bool $flags see above (optional) + * + * @author Michael Hamann <michael@content-space.de> + * @author Ben Coburn <btcoburn@silicodon.net> + */ +function getRecentsSince($from,$to=null,$ns='',$flags=0){ + global $conf; + $recent = array(); + + if($to && $to < $from) + return $recent; + + // read all recent changes. (kept short) + if ($flags & RECENTS_MEDIA_CHANGES) { + $lines = @file($conf['media_changelog']); + } else { + $lines = @file($conf['changelog']); + } + + // we start searching at the end of the list + $lines = array_reverse($lines); + + // handle lines + $seen = array(); // caches seen lines, _handleRecent() skips them + + foreach($lines as $line){ + $rec = _handleRecent($line, $ns, $flags, $seen); + if($rec !== false) { + if ($rec['date'] >= $from) { + if (!$to || $rec['date'] <= $to) { + $recent[] = $rec; + } + } else { + break; + } + } + } + + return array_reverse($recent); +} + +/** * Internal function used by getRecents * * don't call directly @@ -149,8 +244,7 @@ function getRecents($first,$num,$ns='',$flags=0){ * @author Andreas Gohr <andi@splitbrain.org> * @author Ben Coburn <btcoburn@silicodon.net> */ -function _handleRecent($line,$ns,$flags){ - static $seen = array(); //caches seen pages and skip them +function _handleRecent($line,$ns,$flags,&$seen){ if(empty($line)) return false; //skip empty lines // split the line into parts @@ -176,10 +270,12 @@ function _handleRecent($line,$ns,$flags){ if (($flags & RECENTS_SKIP_SUBSPACES) && (getNS($recent['id']) != $ns)) return false; // check ACL - if (auth_quickaclcheck($recent['id']) < AUTH_READ) return false; + $recent['perms'] = auth_quickaclcheck($recent['id']); + if ($recent['perms'] < AUTH_READ) return false; // check existance - if((!@file_exists(wikiFN($recent['id']))) && ($flags & RECENTS_SKIP_DELETED)) return false; + $fn = (($flags & RECENTS_MEDIA_CHANGES) ? mediaFN($recent['id']) : wikiFN($recent['id'])); + if((!@file_exists($fn)) && ($flags & RECENTS_SKIP_DELETED)) return false; return $recent; } diff --git a/inc/common.php b/inc/common.php index bb1c45baa..606f107b7 100644 --- a/inc/common.php +++ b/inc/common.php @@ -20,6 +20,7 @@ require_once(DOKU_INC.'inc/infoutils.php'); define('RECENTS_SKIP_DELETED',2); define('RECENTS_SKIP_MINORS',4); define('RECENTS_SKIP_SUBSPACES',8); +define('RECENTS_MEDIA_CHANGES',16); /** * Wrapper around htmlspecialchars() diff --git a/inc/init.php b/inc/init.php index e721cdb6c..9c4baa988 100644 --- a/inc/init.php +++ b/inc/init.php @@ -208,6 +208,7 @@ function init_paths(){ if ($conf['changelog_old']=='') { unset($conf['changelog_old']); } // hardcoded changelog because it is now a cache that lives in meta $conf['changelog'] = $conf['metadir'].'/_dokuwiki.changes'; + $conf['media_changelog'] = $conf['metadir'].'/_media.changes'; } /** diff --git a/inc/media.php b/inc/media.php index 5c7dd3843..2d3ca3556 100644 --- a/inc/media.php +++ b/inc/media.php @@ -187,6 +187,7 @@ function media_delete($id,$auth){ if ($evt->advise_before()) { $data['unl'] = @unlink($file); if($data['unl']){ + addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_DELETE); $data['del'] = io_sweepNS($id,'mediadir'); } } @@ -215,6 +216,7 @@ function media_delete($id,$auth){ * $data[1] fn: the file name of the uploaded file * $data[2] id: the future directory id of the uploaded file * $data[3] imime: the mimetype of the uploaded file + * $data[4] overwrite: if an existing file is going to be overwritten * * @triggers MEDIA_UPLOAD_FINISH * @author Andreas Gohr <andi@splitbrain.org> @@ -263,7 +265,8 @@ function media_upload($ns,$auth){ // because a temp file was created already if(preg_match('/\.('.$regex.')$/i',$fn)){ //check for overwrite - if(@file_exists($fn) && (!$_REQUEST['ow'] || $auth < AUTH_DELETE)){ + $overwrite = @file_exists($fn); + if($overwrite && (!$_REQUEST['ow'] || $auth < AUTH_DELETE)){ msg($lang['uploadexist'],0); return false; } @@ -285,6 +288,7 @@ function media_upload($ns,$auth){ $data[1] = $fn; $data[2] = $id; $data[3] = $imime; + $data[4] = $overwrite; // trigger event return trigger_event('MEDIA_UPLOAD_FINISH', $data, '_media_upload_action', true); @@ -301,8 +305,8 @@ function media_upload($ns,$auth){ */ function _media_upload_action($data) { // fixme do further sanity tests of given data? - if(is_array($data) && count($data)===4) { - return media_upload_finish($data[0], $data[1], $data[2], $data[3]); + if(is_array($data) && count($data)===5) { + return media_upload_finish($data[0], $data[1], $data[2], $data[3], $data[4]); } else { return false; //callback error } @@ -314,7 +318,7 @@ function _media_upload_action($data) { * @author Andreas Gohr <andi@splitbrain.org> * @author Michael Klier <chi@chimeric.de> */ -function media_upload_finish($fn_tmp, $fn, $id, $imime) { +function media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite) { global $conf; global $lang; @@ -328,6 +332,12 @@ function media_upload_finish($fn_tmp, $fn, $id, $imime) { chmod($fn, $conf['fmode']); msg($lang['uploadsucc'],1); media_notify($id,$fn,$imime); + // add a log entry to the media changelog + if ($overwrite) { + addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_EDIT); + } else { + addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_CREATE); + } return $id; }else{ msg($lang['uploadfail'],-1); diff --git a/lib/exe/indexer.php b/lib/exe/indexer.php index 908bbe86a..6380f8f9d 100644 --- a/lib/exe/indexer.php +++ b/lib/exe/indexer.php @@ -40,6 +40,7 @@ if ($evt->advise_before()) { metaUpdate() or runSitemapper() or runTrimRecentChanges() or + runTrimRecentChanges(true) or $evt->advise_after(); } if($defer) sendGIF(); @@ -52,15 +53,18 @@ exit; /** * Trims the recent changes cache (or imports the old changelog) as needed. * + * @param media_changes If the media changelog shall be trimmed instead of + * the page changelog + * * @author Ben Coburn <btcoburn@silicodon.net> */ -function runTrimRecentChanges() { +function runTrimRecentChanges($media_changes = false) { global $conf; // Import old changelog (if needed) // Uses the imporoldchangelog plugin to upgrade the changelog automaticaly. // FIXME: Remove this from runTrimRecentChanges when it is no longer needed. - if (isset($conf['changelog_old']) && + if (!$media_changes && isset($conf['changelog_old']) && @file_exists($conf['changelog_old']) && !@file_exists($conf['changelog']) && !@file_exists($conf['changelog'].'_importing') && !@file_exists($conf['changelog'].'_tmp')) { $tmp = array(); // no event data @@ -68,22 +72,24 @@ function runTrimRecentChanges() { return true; } + $fn = ($media_changes ? $conf['media_changelog'] : $conf['changelog']); + // Trim the Recent Changes // Trims the recent changes cache to the last $conf['changes_days'] recent // changes or $conf['recent'] items, which ever is larger. // The trimming is only done once a day. - if (@file_exists($conf['changelog']) && - (filectime($conf['changelog'])+86400)<time() && - !@file_exists($conf['changelog'].'_tmp')) { - io_lock($conf['changelog']); - $lines = file($conf['changelog']); + if (@file_exists($fn) && + (filectime($fn)+86400)<time() && + !@file_exists($fn.'_tmp')) { + io_lock($fn); + $lines = file($fn); if (count($lines)<=$conf['recent']) { // nothing to trim - io_unlock($conf['changelog']); + io_unlock($fn); return false; } - io_saveFile($conf['changelog'].'_tmp', ''); // presave tmp as 2nd lock + io_saveFile($fn.'_tmp', ''); // presave tmp as 2nd lock $trim_time = time() - $conf['recent_days']*86400; $out_lines = array(); @@ -107,15 +113,15 @@ function runTrimRecentChanges() { } // save trimmed changelog - io_saveFile($conf['changelog'].'_tmp', implode('', $out_lines)); - @unlink($conf['changelog']); - if (!rename($conf['changelog'].'_tmp', $conf['changelog'])) { + io_saveFile($fn.'_tmp', implode('', $out_lines)); + @unlink($fn); + if (!rename($fn.'_tmp', $fn)) { // rename failed so try another way... - io_unlock($conf['changelog']); - io_saveFile($conf['changelog'], implode('', $out_lines)); - @unlink($conf['changelog'].'_tmp'); + io_unlock($fn); + io_saveFile($fn, implode('', $out_lines)); + @unlink($fn.'_tmp'); } else { - io_unlock($conf['changelog']); + io_unlock($fn); } return true; } diff --git a/lib/exe/xmlrpc.php b/lib/exe/xmlrpc.php index 97e473d7e..070586c3b 100644 --- a/lib/exe/xmlrpc.php +++ b/lib/exe/xmlrpc.php @@ -122,7 +122,13 @@ class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { 'wiki.getRecentChanges', 'this:getRecentChanges', array('struct','int'), - 'Returns a strukt about all recent changes since given timestamp.' + 'Returns a struct about all recent changes since given timestamp.' + ); + $this->addCallback( + 'wiki.getRecentMediaChanges', + 'this:getRecentMediaChanges', + array('struct','int'), + 'Returns a struct about all recent media changes since given timestamp.' ); $this->addCallback( 'wiki.aclCheck', @@ -464,7 +470,8 @@ class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { // because a temp file was created already if(preg_match('/\.('.$regex.')$/i',$fn)) { //check for overwrite - if(@file_exists($fn) && (!$params['ow'] || $auth < AUTH_DELETE)) { + $overwrite = @file_exists($fn); + if($overwrite && (!$params['ow'] || $auth < AUTH_DELETE)) { return new IXR_ERROR(1, $lang['uploadexist']); } // check for valid content @@ -483,6 +490,7 @@ class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { $data[1] = $fn; $data[2] = $id; $data[3] = $imime; + $data[4] = $overwrite; // trigger event require_once(DOKU_INC.'inc/events.php'); @@ -517,7 +525,8 @@ class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { if(!count($mediareferences)){ $file = mediaFN($id); if(@unlink($file)){ - msg(str_replace('%s',noNS($id),$lang['deletesucc']),1); + require_once(DOKU_INC.'inc/changelog.php'); + addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_DELETE); io_sweepNS($id,'mediadir'); return 0; } @@ -536,11 +545,18 @@ class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { function _media_upload_action($data) { global $conf; - if(is_array($data) && count($data)===4) { + if(is_array($data) && count($data)===5) { io_createNamespace($data[2], 'media'); if(rename($data[0], $data[1])) { chmod($data[1], $conf['fmode']); media_notify($data[2], $data[1], $data[3]); + // add a log entry to the media changelog + require_once(DOKU_INC.'inc/changelog.php'); + if ($data[4]) { + addMediaLogEntry(time(), $data[2], DOKU_CHANGE_TYPE_EDIT); + } else { + addMediaLogEntry(time(), $data[2], DOKU_CHANGE_TYPE_CREATE); + } return $data[2]; } else { return new IXR_ERROR(1, 'Upload failed.'); @@ -608,74 +624,73 @@ class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { /** * Returns a list of recent changes since give timestamp * + * @author Michael Hamann <michael@content-space.de> * @author Michael Klier <chi@chimeric.de> */ function getRecentChanges($timestamp) { - global $conf; - if(strlen($timestamp) != 10) return new IXR_Error(20, 'The provided value is not a valid timestamp'); - $changes = array(); - require_once(DOKU_INC.'inc/changelog.php'); require_once(DOKU_INC.'inc/pageutils.php'); - // read changes - $lines = @file($conf['changelog']); + $recents = getRecentsSince($timestamp); - if(empty($lines)) - return new IXR_Error(10, 'The changelog could not be read'); - - // we start searching at the end of the list - $lines = array_reverse($lines); - - // cache seen pages and skip them - $seen = array(); - - foreach($lines as $line) { - - if(empty($line)) continue; // skip empty lines - - $logline = parseChangelogLine($line); - - if($logline === false) continue; + $changes = array(); - // skip seen ones - if(isset($seen[$logline['id']])) continue; + foreach ($recents as $recent) { + $change = array(); + $change['name'] = $recent['id']; + $change['lastModified'] = new IXR_Date($recent['date']); + $change['author'] = $recent['user']; + $change['version'] = $recent['date']; + $change['perms'] = $recent['perms']; + $change['size'] = @filesize(wikiFN($recent['id'])); + array_push($changes, $change); + } - // skip minors - if($logline['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT && ($flags & RECENTS_SKIP_MINORS)) continue; + if (!empty($changes)) { + return $changes; + } else { + // in case we still have nothing at this point + return new IXR_Error(30, 'There are no changes in the specified timeframe'); + } + } - // remember in seen to skip additional sights - $seen[$logline['id']] = 1; + /** + * Returns a list of recent media changes since give timestamp + * + * @author Michael Hamann <michael@content-space.de> + * @author Michael Klier <chi@chimeric.de> + */ + function getRecentMediaChanges($timestamp) { + if(strlen($timestamp) != 10) + return new IXR_Error(20, 'The provided value is not a valid timestamp'); - // check if it's a hidden page - if(isHiddenPage($logline['id'])) continue; + require_once(DOKU_INC.'inc/changelog.php'); + require_once(DOKU_INC.'inc/pageutils.php'); - // check ACL - $perms = auth_quickaclcheck($logline['id']); - if($perms < AUTH_READ) continue; + $recents = getRecentsSince($timestamp, null, '', RECENTS_MEDIA_CHANGES); - // check existance - if((!@file_exists(wikiFN($logline['id']))) && ($flags & RECENTS_SKIP_DELETED)) continue; + $changes = array(); - // check if logline is still in the queried time frame - if($logline['date'] >= $timestamp) { - $change['name'] = $logline['id']; - $change['lastModified'] = new IXR_Date($logline['date']); - $change['author'] = $logline['user']; - $change['version'] = $logline['date']; - $change['perms'] = $perms; - $change['size'] = @filesize(wikiFN($logline['id'])); - array_push($changes, $change); - } else { - $changes = array_reverse($changes); - return ($changes); - } + foreach ($recents as $recent) { + $change = array(); + $change['name'] = $recent['id']; + $change['lastModified'] = new IXR_Date($recent['date']); + $change['author'] = $recent['user']; + $change['version'] = $recent['date']; + $change['perms'] = $recent['perms']; + $change['size'] = @filesize(wikiFN($recent['id'])); + array_push($changes, $change); } - // in case we still have nothing at this point - return new IXR_Error(30, 'There are no changes in the specified timeframe'); + + if (!empty($changes)) { + return $changes; + } else { + // in case we still have nothing at this point + return new IXR_Error(30, 'There are no changes in the specified timeframe'); + } } /** |