Ejemplo n.º 1
0
/**
 * Checks if the current page version is newer than the last entry in the page's
 * changelog. If so, we assume it has been an external edit and we create an
 * attic copy and add a proper changelog line.
 *
 * This check is only executed when the page is about to be saved again from the
 * wiki, triggered in @see saveWikiText()
 *
 * @param string $id the page ID
 */
function detectExternalEdit($id)
{
    global $lang;
    $fileLastMod = wikiFN($id);
    $lastMod = @filemtime($fileLastMod);
    // from page
    $pagelog = new PageChangeLog($id, 1024);
    $lastRev = $pagelog->getRevisions(-1, 1);
    // from changelog
    $lastRev = (int) (empty($lastRev) ? 0 : $lastRev[0]);
    if (!file_exists(wikiFN($id, $lastMod)) && file_exists($fileLastMod) && $lastMod >= $lastRev) {
        // add old revision to the attic if missing
        saveOldRevision($id);
        // add a changelog entry if this edit came from outside dokuwiki
        if ($lastMod > $lastRev) {
            $fileLastRev = wikiFN($id, $lastRev);
            $revinfo = $pagelog->getRevisionInfo($lastRev);
            if (empty($lastRev) || !file_exists($fileLastRev) || $revinfo['type'] == DOKU_CHANGE_TYPE_DELETE) {
                $filesize_old = 0;
            } else {
                $filesize_old = io_getSizeFile($fileLastRev);
            }
            $filesize_new = filesize($fileLastMod);
            $sizechange = $filesize_new - $filesize_old;
            addLogEntry($lastMod, $id, DOKU_CHANGE_TYPE_EDIT, $lang['external_edit'], '', array('ExternalEdit' => true), $sizechange);
            // remove soon to be stale instructions
            $cache = new cache_instructions($id, $fileLastMod);
            $cache->removeCache();
        }
    }
}
Ejemplo n.º 2
0
/**
 * Create html for revision navigation
 *
 * @param PageChangeLog $pagelog changelog object of current page
 * @param string        $type    inline vs sidebyside
 * @param int           $l_rev   left revision timestamp
 * @param int           $r_rev   right revision timestamp
 * @return string[] html of left and right navigation elements
 */
function html_diff_navigation($pagelog, $type, $l_rev, $r_rev)
{
    global $INFO, $ID;
    // last timestamp is not in changelog, retrieve timestamp from metadata
    // note: when page is removed, the metadata timestamp is zero
    if (!$r_rev) {
        if (isset($INFO['meta']['last_change']['date'])) {
            $r_rev = $INFO['meta']['last_change']['date'];
        } else {
            $r_rev = 0;
        }
    }
    //retrieve revisions with additional info
    list($l_revs, $r_revs) = $pagelog->getRevisionsAround($l_rev, $r_rev);
    $l_revisions = array();
    if (!$l_rev) {
        $l_revisions[0] = array(0, "", false);
        //no left revision given, add dummy
    }
    foreach ($l_revs as $rev) {
        $info = $pagelog->getRevisionInfo($rev);
        $l_revisions[$rev] = array($rev, dformat($info['date']) . ' ' . editorinfo($info['user'], true) . ' ' . $info['sum'], $r_rev ? $rev >= $r_rev : false);
    }
    $r_revisions = array();
    if (!$r_rev) {
        $r_revisions[0] = array(0, "", false);
        //no right revision given, add dummy
    }
    foreach ($r_revs as $rev) {
        $info = $pagelog->getRevisionInfo($rev);
        $r_revisions[$rev] = array($rev, dformat($info['date']) . ' ' . editorinfo($info['user'], true) . ' ' . $info['sum'], $rev <= $l_rev);
    }
    //determine previous/next revisions
    $l_index = array_search($l_rev, $l_revs);
    $l_prev = $l_revs[$l_index + 1];
    $l_next = $l_revs[$l_index - 1];
    if ($r_rev) {
        $r_index = array_search($r_rev, $r_revs);
        $r_prev = $r_revs[$r_index + 1];
        $r_next = $r_revs[$r_index - 1];
    } else {
        //removed page
        if ($l_next) {
            $r_prev = $r_revs[0];
        } else {
            $r_prev = null;
        }
        $r_next = null;
    }
    /*
     * Left side:
     */
    $l_nav = '';
    //move back
    if ($l_prev) {
        $l_nav .= html_diff_navigationlink($type, 'diffbothprevrev', $l_prev, $r_prev);
        $l_nav .= html_diff_navigationlink($type, 'diffprevrev', $l_prev, $r_rev);
    }
    //dropdown
    $form = new Doku_Form(array('action' => wl()));
    $form->addHidden('id', $ID);
    $form->addHidden('difftype', $type);
    $form->addHidden('rev2[1]', $r_rev);
    $form->addHidden('do', 'diff');
    $form->addElement(form_makeListboxField('rev2[0]', $l_revisions, $l_rev, '', '', '', array('class' => 'quickselect')));
    $form->addElement(form_makeButton('submit', 'diff', 'Go'));
    $l_nav .= $form->getForm();
    //move forward
    if ($l_next && ($l_next < $r_rev || !$r_rev)) {
        $l_nav .= html_diff_navigationlink($type, 'diffnextrev', $l_next, $r_rev);
    }
    /*
     * Right side:
     */
    $r_nav = '';
    //move back
    if ($l_rev < $r_prev) {
        $r_nav .= html_diff_navigationlink($type, 'diffprevrev', $l_rev, $r_prev);
    }
    //dropdown
    $form = new Doku_Form(array('action' => wl()));
    $form->addHidden('id', $ID);
    $form->addHidden('rev2[0]', $l_rev);
    $form->addHidden('difftype', $type);
    $form->addHidden('do', 'diff');
    $form->addElement(form_makeListboxField('rev2[1]', $r_revisions, $r_rev, '', '', '', array('class' => 'quickselect')));
    $form->addElement(form_makeButton('submit', 'diff', 'Go'));
    $r_nav .= $form->getForm();
    //move forward
    if ($r_next) {
        if ($pagelog->isCurrentRevision($r_next)) {
            $r_nav .= html_diff_navigationlink($type, 'difflastrev', $l_rev);
            //last revision is diff with current page
        } else {
            $r_nav .= html_diff_navigationlink($type, 'diffnextrev', $l_rev, $r_next);
        }
        $r_nav .= html_diff_navigationlink($type, 'diffbothnextrev', $l_next, $r_next);
    }
    return array($l_nav, $r_nav);
}
Ejemplo n.º 3
0
/**
 * Return info about the current document as associative
 * array.
 *
 * @author Andreas Gohr <*****@*****.**>
 *
 * @return array with info about current document
 */
function pageinfo()
{
    global $ID;
    global $REV;
    global $RANGE;
    global $lang;
    /* @var Input $INPUT */
    global $INPUT;
    $info = basicinfo($ID);
    // include ID & REV not redundant, as some parts of DokuWiki may temporarily change $ID, e.g. p_wiki_xhtml
    // FIXME ... perhaps it would be better to ensure the temporary changes weren't necessary
    $info['id'] = $ID;
    $info['rev'] = $REV;
    if ($INPUT->server->has('REMOTE_USER')) {
        $sub = new Subscription();
        $info['subscribed'] = $sub->user_subscription();
    } else {
        $info['subscribed'] = false;
    }
    $info['locked'] = checklock($ID);
    $info['filepath'] = fullpath(wikiFN($ID));
    $info['exists'] = file_exists($info['filepath']);
    $info['currentrev'] = @filemtime($info['filepath']);
    if ($REV) {
        //check if current revision was meant
        if ($info['exists'] && $info['currentrev'] == $REV) {
            $REV = '';
        } elseif ($RANGE) {
            //section editing does not work with old revisions!
            $REV = '';
            $RANGE = '';
            msg($lang['nosecedit'], 0);
        } else {
            //really use old revision
            $info['filepath'] = fullpath(wikiFN($ID, $REV));
            $info['exists'] = file_exists($info['filepath']);
        }
    }
    $info['rev'] = $REV;
    if ($info['exists']) {
        $info['writable'] = is_writable($info['filepath']) && $info['perm'] >= AUTH_EDIT;
    } else {
        $info['writable'] = $info['perm'] >= AUTH_CREATE;
    }
    $info['editable'] = $info['writable'] && empty($info['locked']);
    $info['lastmod'] = @filemtime($info['filepath']);
    //load page meta data
    $info['meta'] = p_get_metadata($ID);
    //who's the editor
    $pagelog = new PageChangeLog($ID, 1024);
    if ($REV) {
        $revinfo = $pagelog->getRevisionInfo($REV);
    } else {
        if (!empty($info['meta']['last_change']) && is_array($info['meta']['last_change'])) {
            $revinfo = $info['meta']['last_change'];
        } else {
            $revinfo = $pagelog->getRevisionInfo($info['lastmod']);
            // cache most recent changelog line in metadata if missing and still valid
            if ($revinfo !== false) {
                $info['meta']['last_change'] = $revinfo;
                p_set_metadata($ID, array('last_change' => $revinfo));
            }
        }
    }
    //and check for an external edit
    if ($revinfo !== false && $revinfo['date'] != $info['lastmod']) {
        // cached changelog line no longer valid
        $revinfo = false;
        $info['meta']['last_change'] = $revinfo;
        p_set_metadata($ID, array('last_change' => $revinfo));
    }
    $info['ip'] = $revinfo['ip'];
    $info['user'] = $revinfo['user'];
    $info['sum'] = $revinfo['sum'];
    // See also $INFO['meta']['last_change'] which is the most recent log line for page $ID.
    // Use $INFO['meta']['last_change']['type']===DOKU_CHANGE_TYPE_MINOR_EDIT in place of $info['minor'].
    if ($revinfo['user']) {
        $info['editor'] = $revinfo['user'];
    } else {
        $info['editor'] = $revinfo['ip'];
    }
    // draft
    $draft = getCacheName($info['client'] . $ID, '.draft');
    if (file_exists($draft)) {
        if (@filemtime($draft) < @filemtime(wikiFN($ID))) {
            // remove stale draft
            @unlink($draft);
        } else {
            $info['draft'] = $draft;
        }
    }
    return $info;
}
 /**
  * sometimes chuncksize is set to true
  */
 function test_chuncksizetrue()
 {
     $rev = 1362525899;
     $infoexpected = parseChangelogLine($this->logline);
     $pagelog = new PageChangeLog($this->pageid, true);
     $info = $pagelog->getRevisionInfo($rev);
     $this->assertEquals($infoexpected, $info);
 }
Ejemplo n.º 5
0
 /**
  * Returns a list of available revisions of a given wiki page
  *
  * @author Michael Klier <*****@*****.**>
  *
  * @param string $id    page id
  * @param int    $first skip the first n changelog lines
  * @return array
  * @throws RemoteAccessDeniedException no read access for page
  * @throws RemoteException empty id
  */
 function pageVersions($id, $first)
 {
     $id = $this->resolvePageId($id);
     if (auth_quickaclcheck($id) < AUTH_READ) {
         throw new RemoteAccessDeniedException('You are not allowed to read this page', 111);
     }
     global $conf;
     $versions = array();
     if (empty($id)) {
         throw new RemoteException('Empty page ID', 131);
     }
     $pagelog = new PageChangeLog($id);
     $revisions = $pagelog->getRevisions($first, $conf['recent'] + 1);
     if (count($revisions) == 0 && $first != 0) {
         $first = 0;
         $revisions = $pagelog->getRevisions($first, $conf['recent'] + 1);
     }
     if (count($revisions) > 0 && $first == 0) {
         array_unshift($revisions, '');
         // include current revision
         if (count($revisions) > $conf['recent']) {
             array_pop($revisions);
             // remove extra log entry
         }
     }
     if (count($revisions) > $conf['recent']) {
         array_pop($revisions);
         // remove extra log entry
     }
     if (!empty($revisions)) {
         foreach ($revisions as $rev) {
             $file = wikiFN($id, $rev);
             $time = @filemtime($file);
             // we check if the page actually exists, if this is not the
             // case this can lead to less pages being returned than
             // specified via $conf['recent']
             if ($time) {
                 $pagelog->setChunkSize(1024);
                 $info = $pagelog->getRevisionInfo($time);
                 if (!empty($info)) {
                     $data = array();
                     $data['user'] = $info['user'];
                     $data['ip'] = $info['ip'];
                     $data['type'] = $info['type'];
                     $data['sum'] = $info['sum'];
                     $data['modified'] = $this->api->toDate($info['date']);
                     $data['version'] = $info['date'];
                     array_push($versions, $data);
                 }
             }
         }
         return $versions;
     } else {
         return array();
     }
 }
Ejemplo n.º 6
0
/**
 * Get the changelog information for a specific page id
 * and revision (timestamp). Adjacent changelog lines
 * are optimistically parsed and cached to speed up
 * consecutive calls to getRevisionInfo. For large
 * changelog files, only the chunk containing the
 * requested changelog line is read.
 *
 * @deprecated 2013-11-20
 *
 * @author Ben Coburn <*****@*****.**>
 * @author Kate Arzamastseva <*****@*****.**>
 */
function getRevisionInfo($id, $rev, $chunk_size = 8192, $media = false)
{
    dbg_deprecated('class PageChangeLog or class MediaChangelog');
    if ($media) {
        $changelog = new MediaChangeLog($id, $chunk_size);
    } else {
        $changelog = new PageChangeLog($id, $chunk_size);
    }
    return $changelog->getRevisionInfo($rev);
}
Ejemplo n.º 7
0
 function handle_display_banner(&$event, $param)
 {
     global $ID, $REV, $INFO;
     if ($event->data != 'show') {
         return;
     }
     if (!$INFO['exists']) {
         return;
     }
     $m = p_get_metadata($ID);
     $changelog = new PageChangeLog($ID);
     //sprawdź status aktualnej strony
     if ($REV != 0) {
         $ch = $changelog->getRevisionInfo($REV);
         $sum = $ch['sum'];
     } else {
         $sum = $m['last_change']['sum'];
     }
     if ($sum != APPRVOED) {
         $class = 'approved_no';
         $last_approved_rev = $this->find_lastest_approved();
     }
     ptln('<div class="approval ' . ($sum == APPROVED ? 'approved_yes' : 'approved_no') . '">');
     tpl_pageinfo();
     ptln(' | ');
     if ($sum == APPROVED) {
         ptln('<span>' . $this->getLang('approved') . '</span>');
         if ($REV != 0 && auth_quickaclcheck($ID) > AUTH_READ) {
             ptln('<a href="' . wl($ID) . '">');
             ptln($this->getLang($m['last_change']['sum'] == APPROVED ? 'newest_approved' : 'newest_draft'));
             ptln('</a>');
         } else {
             if ($REV != 0 && $REV != $last_approved_rev) {
                 ptln('<a href="' . wl($ID) . '">');
                 ptln($this->getLang('newest_approved'));
                 ptln('</a>');
             }
         }
     } else {
         ptln('<span>' . $this->getLang('draft') . '</span>');
         if (isset($last_approved_rev)) {
             if ($last_approved_rev != 0) {
                 ptln('<a href="' . wl($ID, array('rev' => $last_approved_rev)) . '">');
             } else {
                 ptln('<a href="' . wl($ID) . '">');
             }
             ptln($this->getLang('newest_approved'));
             ptln('</a>');
         } else {
             ptln('<a href="' . wl($ID) . '">');
             ptln($this->getLang('newest_draft'));
             ptln('</a>');
         }
         //można zatwierdzać tylko najnowsze strony
         if ($REV == 0 && $this->can_approve()) {
             ptln('<a href="' . wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff', 'approve' => 'approve')) . '">');
             ptln($this->getLang('approve'));
             ptln('</a>');
         }
     }
     ptln('</div>');
 }
 /**
  * request existing rev and check cache
  */
 function test_requestrev_checkcache()
 {
     $rev = 1362525359;
     $dir = 1;
     $revexpected = 1362525899;
     $infoexpected = parseChangelogLine($this->logline);
     $pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
     $revfound = $pagelog->getRelativeRevision($rev, $dir);
     $this->assertEquals($revexpected, $revfound);
     //checked info returned from cache
     $info = $pagelog->getRevisionInfo($revfound);
     $this->assertEquals($infoexpected, $info);
 }
/**
 * Get the changelog information for a specific page id
 * and revision (timestamp). Adjacent changelog lines
 * are optimistically parsed and cached to speed up
 * consecutive calls to getRevisionInfo. For large
 * changelog files, only the chunk containing the
 * requested changelog line is read.
 *
 * @deprecated 20-11-2013
 *
 * @author Ben Coburn <*****@*****.**>
 * @author Kate Arzamastseva <*****@*****.**>
 */
function getRevisionInfo($id, $rev, $chunk_size = 8192, $media = false)
{
    if ($media) {
        $changelog = new MediaChangeLog($id, $chunk_size);
    } else {
        $changelog = new PageChangeLog($id, $chunk_size);
    }
    return $changelog->getRevisionInfo($rev);
}