/** * @param string $pageId wiki page ID to check * @throws Exception exception on error or nothing */ protected function checkPage($pageId) { if (empty($pageId)) { throw new Exception('No page ID was sent to delete.'); } if (auth_quickaclcheck($pageId) < AUTH_DELETE) { throw new Exception("You do not have permissions to delete page <b>{$pageId}</b>. You need AUTH_DELETE or higher rights"); } if (checklock($pageId)) { throw new Exception('Page is locked by another user'); } if (!checklock($pageId) && file_exists(wikiLockFN($pageId))) { throw new Exception('Page is locked by You. You cannot delete page during edit.'); } }
/** * Rewrite pages when they are read and they need to be updated. * * @param Doku_Event $event The event object * @param mixed $param Optional parameters (not used) */ function handle_read(Doku_Event $event, $param) { global $ACT, $conf; static $stack = array(); // handle only reads of the current revision if ($event->data[3]) { return; } // only rewrite if not in move already $save = true; if (helper_plugin_move_rewrite::isLocked()) { $save = false; } $id = $event->data[2]; if ($event->data[1]) { $id = $event->data[1] . ':' . $id; } if (!$id) { // try to reconstruct the id from the filename $path = $event->data[0][0]; if (strpos($path, $conf['datadir']) === 0) { $path = substr($path, strlen($conf['datadir']) + 1); $id = pathID($path); } } if (isset($stack[$id])) { return; } // Don't change the page when the user is currently changing the page content or the page is locked $forbidden_actions = array('save', 'preview', 'recover', 'revert'); if (isset($ACT) && (in_array($ACT, $forbidden_actions) || is_array($ACT) && in_array(key($ACT), $forbidden_actions)) || checklock($id) !== false || @file_exists(wikiLockFN($id))) { return; } /** @var helper_plugin_move_rewrite $helper */ $helper = plugin_load('helper', 'move_rewrite', true); if (!is_null($helper)) { $stack[$id] = true; $event->result = $helper->rewritePage($id, $event->result, $save); unset($stack[$id]); } }
/** * Rewrite pages when they are read and they need to be updated. * * @param Doku_Event $event The event object * @param mixed $param Optional parameters (not used) */ function handle_read(Doku_Event $event, $param) { global $ACT, $conf; static $stack = array(); // handle only reads of the current revision if ($event->data[3]) return; $id = $event->data[2]; if ($event->data[1]) $id = $event->data[1].':'.$id; if (!$id) { // try to reconstruct the id from the filename $path = $event->data[0][0]; if (strpos($path, $conf['datadir']) === 0) { $path = substr($path, strlen($conf['datadir'])+1); $id = pathID($path); } } if (isset($stack[$id])) return; // Don't change the page when the user is currently changing the page content or the page is locked $forbidden_actions = array('save', 'preview', 'recover', 'revert'); if ((isset($ACT) && ( in_array($ACT, $forbidden_actions) || (is_array($ACT) && in_array(key($ACT), $forbidden_actions) ))) // checklock checks if the page lock hasn't expired and the page hasn't been locked by another user // the file exists check checks if the page is reported unlocked if a lock exists which means that // the page is locked by the current user || checklock($id) !== false || @file_exists(wikiLockFN($id))) return; /** @var helper_plugin_move $helper */ $helper = $this->loadHelper('move', true); if(!is_null($helper)) { $stack[$id] = true; $event->result = $helper->execute_rewrites($id, $event->result); unset($stack[$id]); } }
/** * Check if the given page can be moved to the given destination * * @param $src * @param $dst * @return bool */ public function checkPage($src, $dst) { // Check we have rights to move this document if (!page_exists($src)) { msg(sprintf($this->getLang('notexist'), $src), -1); return false; } if (auth_quickaclcheck($src) < AUTH_EDIT) { msg(sprintf($this->getLang('norights'), $src), -1); return false; } // Check file is not locked // checklock checks if the page lock hasn't expired and the page hasn't been locked by another user // the file exists check checks if the page is reported unlocked if a lock exists which means that // the page is locked by the current user if (checklock($src) !== false || @file_exists(wikiLockFN($src))) { msg(sprintf($this->getLang('filelocked'), $src), -1); return false; } // Has the document name and/or namespace changed? if ($src == $dst) { msg(sprintf($this->getLang('notchanged'), $src), -1); return false; } // Check the page does not already exist if (page_exists($dst)) { msg(sprintf($this->getLang('exists'), $src, $dst), -1); return false; } // Check if the current user can create the new page if (auth_quickaclcheck($dst) < AUTH_CREATE) { msg(sprintf($this->getLang('notargetperms'), $dst), -1); return false; } return true; }
/** * Display error on locked pages * * @author Andreas Gohr <*****@*****.**> */ function html_locked() { global $ID; global $conf; global $lang; global $INFO; $locktime = filemtime(wikiLockFN($ID)); $expire = dformat($locktime + $conf['locktime']); $min = round(($conf['locktime'] - (time() - $locktime)) / 60); print p_locale_xhtml('locked'); print '<ul>'; print '<li><div class="li"><strong>' . $lang['lockedby'] . ':</strong> ' . editorinfo($INFO['locked']) . '</div></li>'; print '<li><div class="li"><strong>' . $lang['lockexpire'] . ':</strong> ' . $expire . ' (' . $min . ' min)</div></li>'; print '</ul>'; }
/** * Unlock a page if it was locked by the user * * @author Andreas Gohr <*****@*****.**> * @param string $id page id to unlock * @return bool true if a lock was removed */ function unlock($id) { $lock = wikiLockFN($id); if (@file_exists($lock)) { list($ip, $session) = explode("\n", io_readFile($lock)); if ($ip == $_SERVER['REMOTE_USER'] || $ip == clientIP() || $session == session_id()) { @unlink($lock); return true; } } return false; }
/** * Forcefully remove a lock on the page given * * @param string $wiki_id */ protected function deleteLock($wiki_id) { $wikiLockFN = wikiLockFN($wiki_id); if (file_exists($wikiLockFN)) { if (!unlink($wikiLockFN)) { $this->error("Unable to delete {$wikiLockFN}"); exit(1); } } }
/** * Unlock a page if it was locked by the user * * @author Andreas Gohr <*****@*****.**> * @return bool true if a lock was removed */ function unlock($id) { $lock = wikiLockFN($id); if (@file_exists($lock)) { $ip = io_readFile($lock); if ($ip == clientIP() || $ip == $_SERVER['REMOTE_USER']) { @unlink($lock); return true; } } return false; }
/** * Determines if it would be okay to show a rename page button for the given page and current user * * @param $id * @return bool */ public function renameOkay($id) { global $ACT; global $USERINFO; if (!($ACT == 'show' || empty($ACT))) { return false; } if (!page_exists($id)) { return false; } if (auth_quickaclcheck($id) < AUTH_EDIT) { return false; } if (checklock($id) !== false || @file_exists(wikiLockFN($id))) { return false; } if (!isset($_SERVER['REMOTE_USER'])) { return false; } if (!auth_isMember($this->getConf('allowrename'), $_SERVER['REMOTE_USER'], (array) $USERINFO['grps'])) { return false; } return true; }
/** * Unlock a page if it was locked by the user * * @author Andreas Gohr <*****@*****.**> * * @param string $id page id to unlock * @return bool true if a lock was removed */ function unlock($id) { /* @var Input $INPUT */ global $INPUT; $lock = wikiLockFN($id); if (file_exists($lock)) { @(list($ip, $session) = explode("\n", io_readFile($lock))); if ($ip == $INPUT->server->str('REMOTE_USER') || $ip == clientIP() || $session == session_id()) { @unlink($lock); return true; } } return false; }
function deleteLock($WIKI_ID) { $wikiLockFN = wikiLockFN($WIKI_ID); if (file_exists($wikiLockFN)) { if (!unlink($wikiLockFN)) { fwrite(STDERR, "Unable to delete {$wikiLockFN}\n"); exit(1); } } }
/** * move page * * @author Gary Owen <*****@*****.**>, modified by Kay Roesler * @author Michael Hamann <*****@*****.**> * * @param array $opts * @param bool $checkonly Only execute the checks if the page can be moved * @return bool If the move was executed */ public function move_page(&$opts, $checkonly = false) { global $ID; // Check we have rights to move this document if ( !page_exists($ID)) { msg(sprintf($this->getLang('notexist'), $ID), -1); return false; } if ( auth_quickaclcheck($ID) < AUTH_EDIT ) { msg(sprintf($this->getLang('norights'), hsc($ID)), -1); return false; } // Check file is not locked // checklock checks if the page lock hasn't expired and the page hasn't been locked by another user // the file exists check checks if the page is reported unlocked if a lock exists which means that // the page is locked by the current user if (checklock($ID) !== false || @file_exists(wikiLockFN($ID))) { msg( sprintf($this->getLang('filelocked'), hsc($ID)), -1); return false; } // Assemble fill document name and path $opts['new_id'] = cleanID($opts['newns'].':'.$opts['newname']); $opts['new_path'] = wikiFN($opts['new_id']); // Has the document name and/or namespace changed? if ( $opts['newns'] == $opts['ns'] && $opts['newname'] == $opts['name'] ) { msg($this->getLang('nochange'), -1); return false; } // Check the page does not already exist if ( @file_exists($opts['new_path']) ) { msg(sprintf($this->getLang('existing'), $opts['newname'], ($opts['newns'] == '' ? $this->getLang('root') : $opts['newns'])), -1); return false; } // Check if the current user can create the new page if (auth_quickaclcheck($opts['new_id']) < AUTH_CREATE) { msg(sprintf($this->getLang('notargetperms'), $opts['new_id']), -1); return false; } if ($checkonly) return true; /** * End of init (checks) */ $page_meta = $this->getMoveMeta($ID); if (!$page_meta) $page_meta = array(); if (!isset($page_meta['old_ids'])) $page_meta['old_ids'] = array(); $page_meta['old_ids'][$ID] = time(); // ft_backlinks() is not used here, as it does a hidden page and acl check but we really need all pages $affected_pages = idx_get_indexer()->lookupKey('relation_references', $ID); $data = array('opts' => &$opts, 'old_ids' => $page_meta['old_ids'], 'affected_pages' => &$affected_pages); // give plugins the option to add their own meta files to the list of files that need to be moved // to the oldfiles/newfiles array or to adjust their own metadata, database, ... // and to add other pages to the affected pages // note that old_ids is in the form 'id' => timestamp of move $event = new Doku_Event('PLUGIN_MOVE_PAGE_RENAME', $data); if ($event->advise_before()) { // Open the old document and change forward links lock($ID); $text = rawWiki($ID); $text = $this->rewrite_content($text, $ID, array($ID => $opts['new_id'])); $oldRev = getRevisions($ID, -1, 1, 1024); // from changelog // Move the Subscriptions & Indexes if (method_exists('Doku_Indexer', 'renamePage')) { // new feature since Spring 2013 release $Indexer = idx_get_indexer(); } else { $Indexer = new helper_plugin_move_indexer(); // copy of the new code } if (($idx_msg = $Indexer->renamePage($ID, $opts['new_id'])) !== true || ($idx_msg = $Indexer->renameMetaValue('relation_references', $ID, $opts['new_id'])) !== true) { msg('Error while updating the search index '.$idx_msg, -1); return false; } if (!$this->movemeta($opts)) { msg('The meta files of page '.$ID.' couldn\'t be moved', -1); return false; } // Save the updated document in its new location if ($opts['ns'] == $opts['newns']) { $lang_key = 'renamed'; } elseif ( $opts['name'] == $opts['newname'] ) { $lang_key = 'moved'; } else { $lang_key = 'move_rename'; } // Wait a second when the page has just been rewritten if ($oldRev == time()) sleep(1); $summary = sprintf($this->getLang($lang_key), $ID, $opts['new_id']); saveWikiText($opts['new_id'], $text, $summary); // Delete the orginal file if (@file_exists(wikiFN($opts['new_id']))) { saveWikiText($ID, '', $this->getLang('delete') ); } // Move the old revisions if (!$this->moveattic($opts)) { // it's too late to stop the move, so just display a message. msg('The attic files of page '.$ID.' couldn\'t be moved. Please move them manually.', -1); } foreach ($affected_pages as $id) { if (!page_exists($id, '', false) || $id == $ID || $id == $opts['new_id']) continue; // we are only interested in persistent metadata, so no need to render anything. $meta = $this->getMoveMeta($id); if (!$meta) $meta = array('moves' => array()); if (!isset($meta['moves'])) $meta['moves'] = array(); $meta['moves'] = $this->resolve_moves($meta['moves'], $id); $meta['moves'][$ID] = $opts['new_id']; //if (empty($meta['moves'])) unset($meta['moves']); p_set_metadata($id, array('plugin_move' => $meta), false, true); } p_set_metadata($opts['new_id'], array('plugin_move' => $page_meta), false, true); unlock($ID); } $event->advise_after(); return true; }