/**
  * @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.');
     }
 }
Esempio n. 2
0
 /**
  * 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]);
     }
 }
Esempio n. 3
0
    /**
     * 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]);
        }
    }
Esempio n. 4
0
 /**
  * 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;
 }
Esempio n. 5
0
/**
 * 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>';
}
Esempio n. 6
0
/**
 * 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;
}
Esempio n. 7
0
 /**
  * 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);
         }
     }
 }
Esempio n. 8
0
/**
 * 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;
}
Esempio n. 9
0
 /**
  * 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;
 }
Esempio n. 10
0
/**
 * 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;
}
Esempio n. 11
0
function deleteLock($WIKI_ID)
{
    $wikiLockFN = wikiLockFN($WIKI_ID);
    if (file_exists($wikiLockFN)) {
        if (!unlink($wikiLockFN)) {
            fwrite(STDERR, "Unable to delete {$wikiLockFN}\n");
            exit(1);
        }
    }
}
Esempio n. 12
0
    /**
     * 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;
    }