Example #1
0
 /**
  * Start the reversion process
  */
 function _revert($revert, $filter)
 {
     echo '<hr /><br />';
     echo '<p>' . $this->getLang('revstart') . '</p>';
     echo '<ul>';
     foreach ($revert as $id) {
         global $REV;
         // find the last non-spammy revision
         $data = '';
         $pagelog = new PageChangeLog($id);
         $old = $pagelog->getRevisions(0, $this->max_revs);
         if (count($old)) {
             foreach ($old as $REV) {
                 $data = rawWiki($id, $REV);
                 if (strpos($data, $filter) === false) {
                     break;
                 }
             }
         }
         if ($data) {
             saveWikiText($id, $data, 'old revision restored', false);
             printf('<li><div class="li">' . $this->getLang('reverted') . '</div></li>', $id, $REV);
         } else {
             saveWikiText($id, '', '', false);
             printf('<li><div class="li">' . $this->getLang('removed') . '</div></li>', $id);
         }
         @set_time_limit(10);
         flush();
     }
     echo '</ul>';
     echo '<p>' . $this->getLang('revstop') . '</p>';
 }
Example #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);
}
Example #3
0
/**
 * Returns a full page id
 *
 * @author Andreas Gohr <*****@*****.**>
 *
 * @param string  $ns     namespace which is context of id
 * @param string &$page   (reference) relative page id, updated to resolved id
 * @param bool   &$exists (reference) updated with existance of media
 */
function resolve_pageid($ns, &$page, &$exists, $rev = '', $date_at = false)
{
    global $conf;
    global $ID;
    $exists = false;
    //empty address should point to current page
    if ($page === "") {
        $page = $ID;
    }
    //keep hashlink if exists then clean both parts
    if (strpos($page, '#')) {
        list($page, $hash) = explode('#', $page, 2);
    } else {
        $hash = '';
    }
    $hash = cleanID($hash);
    $page = resolve_id($ns, $page, false);
    // resolve but don't clean, yet
    // get filename (calls clean itself)
    if ($rev !== '' && $date_at) {
        $pagelog = new PageChangeLog($page);
        $pagelog_rev = $pagelog->getLastRevisionAt($rev);
        if ($pagelog_rev !== false) {
            //something found
            $rev = $pagelog_rev;
        }
    }
    $file = wikiFN($page, $rev);
    // if ends with colon or slash we have a namespace link
    if (in_array(substr($page, -1), array(':', ';')) || $conf['useslash'] && substr($page, -1) == '/') {
        if (page_exists($page . $conf['start'], $rev, true, $date_at)) {
            // start page inside namespace
            $page = $page . $conf['start'];
            $exists = true;
        } elseif (page_exists($page . noNS(cleanID($page)), $rev, true, $date_at)) {
            // page named like the NS inside the NS
            $page = $page . noNS(cleanID($page));
            $exists = true;
        } elseif (page_exists($page, $rev, true, $date_at)) {
            // page like namespace exists
            $page = $page;
            $exists = true;
        } else {
            // fall back to default
            $page = $page . $conf['start'];
        }
    } else {
        //check alternative plural/nonplural form
        if (!@file_exists($file)) {
            if ($conf['autoplural']) {
                if (substr($page, -1) == 's') {
                    $try = substr($page, 0, -1);
                } else {
                    $try = $page . 's';
                }
                if (page_exists($try, $rev, true, $date_at)) {
                    $page = $try;
                    $exists = true;
                }
            }
        } else {
            $exists = true;
        }
    }
    // now make sure we have a clean page
    $page = cleanID($page);
    //add hash if any
    if (!empty($hash)) {
        $page .= '#' . $hash;
    }
}
Example #4
0
if ($DATE_AT) {
    $date_parse = strtotime($DATE_AT);
    if ($date_parse) {
        $DATE_AT = $date_parse;
    } else {
        // check for UNIX Timestamp
        $date_parse = @date('Ymd', $DATE_AT);
        if (!$date_parse || $date_parse === '19700101') {
            msg(sprintf($lang['unable_to_parse_date'], $DATE_AT));
            $DATE_AT = null;
        }
    }
}
//check for existing $REV related to $DATE_AT
if ($DATE_AT) {
    $pagelog = new PageChangeLog($ID);
    $rev_t = $pagelog->getLastRevisionAt($DATE_AT);
    if ($rev_t === '') {
        //current revision
        $REV = null;
        $DATE_AT = null;
    } else {
        if ($rev_t === false) {
            //page did not exist
            $rev_n = $pagelog->getRelativeRevision($DATE_AT, +1);
            msg(sprintf($lang['page_nonexist_rev'], strftime($conf['dformat'], $DATE_AT), wl($ID, array('rev' => $rev_n)), strftime($conf['dformat'], $rev_n)));
            $REV = $DATE_AT;
            //will result in a page not exists message
        } else {
            $REV = $rev_t;
        }
Example #5
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();
        }
    }
}
 /**
  * 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);
 }
Example #7
0
 /**
  * Send a digest mail
  *
  * Sends a digest mail showing a bunch of changes of a single page. Basically the same as send_diff()
  * but determines the last known revision first
  *
  * @author Adrian Lang <*****@*****.**>
  *
  * @param string $subscriber_mail The target mail address
  * @param string $id              The ID
  * @param int    $lastupdate      Time of the last notification
  * @return bool
  */
 protected function send_digest($subscriber_mail, $id, $lastupdate)
 {
     $pagelog = new PageChangeLog($id);
     $n = 0;
     do {
         $rev = $pagelog->getRevisions($n++, 1);
         $rev = count($rev) > 0 ? $rev[0] : null;
     } while (!is_null($rev) && $rev > $lastupdate);
     return $this->send_diff($subscriber_mail, 'subscr_digest', $id, $rev);
 }
Example #8
0
/**
 * Add recent changed pages to a feed object
 *
 * @author Andreas Gohr <*****@*****.**>
 * @param  FeedCreator $rss the FeedCreator Object
 * @param  array       $data the items to add
 * @param  array       $opt  the feed options
 */
function rss_buildItems(&$rss, &$data, $opt)
{
    global $conf;
    global $lang;
    /* @var DokuWiki_Auth_Plugin $auth */
    global $auth;
    $eventData = array('rss' => &$rss, 'data' => &$data, 'opt' => &$opt);
    $event = new Doku_Event('FEED_DATA_PROCESS', $eventData);
    if ($event->advise_before(false)) {
        foreach ($data as $ditem) {
            if (!is_array($ditem)) {
                // not an array? then only a list of IDs was given
                $ditem = array('id' => $ditem);
            }
            $item = new FeedItem();
            $id = $ditem['id'];
            if (!$ditem['media']) {
                $meta = p_get_metadata($id);
            } else {
                $meta = array();
            }
            // add date
            if ($ditem['date']) {
                $date = $ditem['date'];
            } elseif ($ditem['media']) {
                $date = @filemtime(mediaFN($id));
            } elseif (file_exists(wikiFN($id))) {
                $date = @filemtime(wikiFN($id));
            } elseif ($meta['date']['modified']) {
                $date = $meta['date']['modified'];
            } else {
                $date = 0;
            }
            if ($date) {
                $item->date = date('r', $date);
            }
            // add title
            if ($conf['useheading'] && $meta['title']) {
                $item->title = $meta['title'];
            } else {
                $item->title = $ditem['id'];
            }
            if ($conf['rss_show_summary'] && !empty($ditem['sum'])) {
                $item->title .= ' - ' . strip_tags($ditem['sum']);
            }
            // add item link
            switch ($opt['link_to']) {
                case 'page':
                    if ($ditem['media']) {
                        $item->link = media_managerURL(array('image' => $id, 'ns' => getNS($id), 'rev' => $date), '&', true);
                    } else {
                        $item->link = wl($id, 'rev=' . $date, true, '&');
                    }
                    break;
                case 'rev':
                    if ($ditem['media']) {
                        $item->link = media_managerURL(array('image' => $id, 'ns' => getNS($id), 'rev' => $date, 'tab_details' => 'history'), '&', true);
                    } else {
                        $item->link = wl($id, 'do=revisions&rev=' . $date, true, '&');
                    }
                    break;
                case 'current':
                    if ($ditem['media']) {
                        $item->link = media_managerURL(array('image' => $id, 'ns' => getNS($id)), '&', true);
                    } else {
                        $item->link = wl($id, '', true, '&');
                    }
                    break;
                case 'diff':
                default:
                    if ($ditem['media']) {
                        $item->link = media_managerURL(array('image' => $id, 'ns' => getNS($id), 'rev' => $date, 'tab_details' => 'history', 'mediado' => 'diff'), '&', true);
                    } else {
                        $item->link = wl($id, 'rev=' . $date . '&do=diff', true, '&');
                    }
            }
            // add item content
            switch ($opt['item_content']) {
                case 'diff':
                case 'htmldiff':
                    if ($ditem['media']) {
                        $medialog = new MediaChangeLog($id);
                        $revs = $medialog->getRevisions(0, 1);
                        $rev = $revs[0];
                        $src_r = '';
                        $src_l = '';
                        if ($size = media_image_preview_size($id, '', new JpegMeta(mediaFN($id)), 300)) {
                            $more = 'w=' . $size[0] . '&h=' . $size[1] . '&t=' . @filemtime(mediaFN($id));
                            $src_r = ml($id, $more, true, '&amp;', true);
                        }
                        if ($rev && ($size = media_image_preview_size($id, $rev, new JpegMeta(mediaFN($id, $rev)), 300))) {
                            $more = 'rev=' . $rev . '&w=' . $size[0] . '&h=' . $size[1];
                            $src_l = ml($id, $more, true, '&amp;', true);
                        }
                        $content = '';
                        if ($src_r) {
                            $content = '<table>';
                            $content .= '<tr><th width="50%">' . $rev . '</th>';
                            $content .= '<th width="50%">' . $lang['current'] . '</th></tr>';
                            $content .= '<tr align="center"><td><img src="' . $src_l . '" alt="" /></td><td>';
                            $content .= '<img src="' . $src_r . '" alt="' . $id . '" /></td></tr>';
                            $content .= '</table>';
                        }
                    } else {
                        require_once DOKU_INC . 'inc/DifferenceEngine.php';
                        $pagelog = new PageChangeLog($id);
                        $revs = $pagelog->getRevisions(0, 1);
                        $rev = $revs[0];
                        if ($rev) {
                            $df = new Diff(explode("\n", rawWiki($id, $rev)), explode("\n", rawWiki($id, '')));
                        } else {
                            $df = new Diff(array(''), explode("\n", rawWiki($id, '')));
                        }
                        if ($opt['item_content'] == 'htmldiff') {
                            // note: no need to escape diff output, TableDiffFormatter provides 'safe' html
                            $tdf = new TableDiffFormatter();
                            $content = '<table>';
                            $content .= '<tr><th colspan="2" width="50%">' . $rev . '</th>';
                            $content .= '<th colspan="2" width="50%">' . $lang['current'] . '</th></tr>';
                            $content .= $tdf->format($df);
                            $content .= '</table>';
                        } else {
                            // note: diff output must be escaped, UnifiedDiffFormatter provides plain text
                            $udf = new UnifiedDiffFormatter();
                            $content = "<pre>\n" . hsc($udf->format($df)) . "\n</pre>";
                        }
                    }
                    break;
                case 'html':
                    if ($ditem['media']) {
                        if ($size = media_image_preview_size($id, '', new JpegMeta(mediaFN($id)))) {
                            $more = 'w=' . $size[0] . '&h=' . $size[1] . '&t=' . @filemtime(mediaFN($id));
                            $src = ml($id, $more, true, '&amp;', true);
                            $content = '<img src="' . $src . '" alt="' . $id . '" />';
                        } else {
                            $content = '';
                        }
                    } else {
                        if (@filemtime(wikiFN($id)) === $date) {
                            $content = p_wiki_xhtml($id, '', false);
                        } else {
                            $content = p_wiki_xhtml($id, $date, false);
                        }
                        // no TOC in feeds
                        $content = preg_replace('/(<!-- TOC START -->).*(<!-- TOC END -->)/s', '', $content);
                        // add alignment for images
                        $content = preg_replace('/(<img .*?class="medialeft")/s', '\\1 align="left"', $content);
                        $content = preg_replace('/(<img .*?class="mediaright")/s', '\\1 align="right"', $content);
                        // make URLs work when canonical is not set, regexp instead of rerendering!
                        if (!$conf['canonical']) {
                            $base = preg_quote(DOKU_REL, '/');
                            $content = preg_replace('/(<a href|<img src)="(' . $base . ')/s', '$1="' . DOKU_URL, $content);
                        }
                    }
                    break;
                case 'abstract':
                default:
                    if ($ditem['media']) {
                        if ($size = media_image_preview_size($id, '', new JpegMeta(mediaFN($id)))) {
                            $more = 'w=' . $size[0] . '&h=' . $size[1] . '&t=' . @filemtime(mediaFN($id));
                            $src = ml($id, $more, true, '&amp;', true);
                            $content = '<img src="' . $src . '" alt="' . $id . '" />';
                        } else {
                            $content = '';
                        }
                    } else {
                        $content = $meta['description']['abstract'];
                    }
            }
            $item->description = $content;
            //FIXME a plugin hook here could be senseful
            // add user
            # FIXME should the user be pulled from metadata as well?
            $user = @$ditem['user'];
            // the @ spares time repeating lookup
            $item->author = '';
            if ($user && $conf['useacl'] && $auth) {
                $userInfo = $auth->getUserData($user);
                if ($userInfo) {
                    switch ($conf['showuseras']) {
                        case 'username':
                        case 'username_link':
                            $item->author = $userInfo['name'];
                            break;
                        default:
                            $item->author = $user;
                            break;
                    }
                } else {
                    $item->author = $user;
                }
                if ($userInfo && !$opt['guardmail']) {
                    $item->authorEmail = $userInfo['mail'];
                } else {
                    //cannot obfuscate because some RSS readers may check validity
                    $item->authorEmail = $user . '@' . $ditem['ip'];
                }
            } elseif ($user) {
                // this happens when no ACL but some Apache auth is used
                $item->author = $user;
                $item->authorEmail = $user . '@' . $ditem['ip'];
            } else {
                $item->authorEmail = 'anonymous@' . $ditem['ip'];
            }
            // add category
            if (isset($meta['subject'])) {
                $item->category = $meta['subject'];
            } else {
                $cat = getNS($id);
                if ($cat) {
                    $item->category = $cat;
                }
            }
            // finally add the item to the feed object, after handing it to registered plugins
            $evdata = array('item' => &$item, 'opt' => &$opt, 'ditem' => &$ditem, 'rss' => &$rss);
            $evt = new Doku_Event('FEED_ITEM_ADD', $evdata);
            if ($evt->advise_before()) {
                $rss->addItem($item);
            }
            $evt->advise_after();
            // for completeness
        }
    }
    $event->advise_after();
}
Example #9
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();
     }
 }
Example #10
0
/**
 * Return a list of page revisions numbers
 * Does not guarantee that the revision exists in the attic,
 * only that a line with the date exists in the changelog.
 * By default the current revision is skipped.
 *
 * The current revision is automatically skipped when the page exists.
 * See $INFO['meta']['last_change'] for the current revision.
 *
 * For efficiency, the log lines are parsed and cached for later
 * calls to getRevisionInfo. Large changelog files are read
 * backwards in chunks until the requested number of changelog
 * lines are recieved.
 *
 * @deprecated 2013-11-20
 *
 * @author Ben Coburn <*****@*****.**>
 * @author Kate Arzamastseva <*****@*****.**>
 *
 * @param string $id          the page of interest
 * @param int    $first       skip the first n changelog lines
 * @param int    $num         number of revisions to return
 * @param int    $chunk_size
 * @param bool   $media
 * @return array
 */
function getRevisions($id, $first, $num, $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->getRevisions($first, $num);
}
Example #11
0
/**
 * 
 * Show diff
 * between current page version and provided $text
 * or between the revisions provided via GET or POST
 *
 * @author Andreas Gohr <*****@*****.**>
 * @param  string $text  when non-empty: compare with this text with most current version
 * @param  bool   $intro display the intro text
 * @param  string $type  type of the diff (inline or sidebyside)
 */
function revisionsfull_html_diff($text = '', $intro = true, $type = null)
{
    global $ID;
    global $REV;
    global $lang;
    global $INPUT;
    global $INFO;
    $pagelog = new PageChangeLog($ID);
    /*
     * Determine diff type
     */
    if (!$type) {
        $type = $INPUT->str('difftype');
        if (empty($type)) {
            $type = get_doku_pref('difftype', $type);
            if (empty($type) && $INFO['ismobile']) {
                $type = 'inline';
            }
        }
    }
    if (!in_array($type, array('inline', 'sidebyside'))) {
        $type = 'full';
    }
    /*
     * Determine requested revision(s)
     */
    // we're trying to be clever here, revisions to compare can be either
    // given as rev and rev2 parameters, with rev2 being optional. Or in an
    // array in rev2.
    $rev1 = $REV;
    $rev2 = $INPUT->ref('rev2');
    if (is_array($rev2)) {
        $rev1 = (int) $rev2[0];
        $rev2 = (int) $rev2[1];
        if (!$rev1) {
            $rev1 = $rev2;
            unset($rev2);
        }
    } else {
        $rev2 = $INPUT->int('rev2');
    }
    /*
     * Determine left and right revision, its texts and the header
     */
    $r_minor = '';
    $l_minor = '';
    if ($text) {
        // compare text to the most current revision
        $l_rev = '';
        $l_text = rawWiki($ID, '');
        $l_head = '<a class="wikilink1" href="' . wl($ID) . '">' . $ID . ' ' . dformat((int) @filemtime(wikiFN($ID))) . '</a> ' . $lang['current'];
        $r_rev = '';
        $r_text = cleanText($text);
        $r_head = $lang['yours'];
    } else {
        if ($rev1 && isset($rev2) && $rev2) {
            // two specific revisions wanted
            // make sure order is correct (older on the left)
            if ($rev1 < $rev2) {
                $l_rev = $rev1;
                $r_rev = $rev2;
            } else {
                $l_rev = $rev2;
                $r_rev = $rev1;
            }
        } elseif ($rev1) {
            // single revision given, compare to current
            $r_rev = '';
            $l_rev = $rev1;
        } else {
            // no revision was given, compare previous to current
            $r_rev = '';
            $revs = $pagelog->getRevisions(0, 1);
            $l_rev = $revs[0];
            $REV = $l_rev;
            // store revision back in $REV
        }
        // when both revisions are empty then the page was created just now
        if (!$l_rev && !$r_rev) {
            $l_text = '';
        } else {
            $l_text = rawWiki($ID, $l_rev);
        }
        $r_text = rawWiki($ID, $r_rev);
        list($l_head, $r_head, $l_minor, $r_minor) = html_diff_head($l_rev, $r_rev, null, false, $type == 'inline');
    }
    /*
     * Build navigation
     */
    $l_nav = '';
    $r_nav = '';
    if (!$text) {
        list($l_nav, $r_nav) = html_diff_navigation($pagelog, $type, $l_rev, $r_rev);
    }
    /*
     * Create diff object and the formatter
     */
    $diff = new Diff(explode("\n", $l_text), explode("\n", $r_text));
    if ($type == 'inline') {
        $diffformatter = new InlineDiffFormatter();
    } elseif ($type == 'sidebyside') {
        $diffformatter = new TableDiffFormatter();
    } else {
        $diffformatter = new FullTableDiffFormatter();
    }
    /*
     * Display intro
     */
    if ($intro) {
        print p_locale_xhtml('diff');
    }
    /*
     * Display type and exact reference
     */
    if (!$text) {
        ptln('<div class="diffoptions group">');
        $form = new Doku_Form(array('action' => wl()));
        $form->addHidden('id', $ID);
        $form->addHidden('rev2[0]', $l_rev);
        $form->addHidden('rev2[1]', $r_rev);
        $form->addHidden('do', 'diff');
        $form->addElement(form_makeListboxField('difftype', array('full' => 'Full Side by Side', 'sidebyside' => $lang['diff_side'], 'inline' => $lang['diff_inline']), $type, $lang['diff_type'], '', '', array('class' => 'quickselect')));
        $form->addElement(form_makeButton('submit', 'diff', 'Go'));
        $form->printForm();
        ptln('<p>');
        // link to exactly this view FS#2835
        echo html_diff_navigationlink($type, 'difflink', $l_rev, $r_rev ? $r_rev : $INFO['currentrev']);
        ptln('</p>');
        ptln('</div>');
        // .diffoptions
    }
    /*
     * Display diff view table
     */
    ?>
    <div class="table">
    <table class="diff diff_<?php 
    echo $type;
    ?>
">

        <?php 
    //navigation and header
    if ($type == 'inline') {
        if (!$text) {
            ?>
                <tr>
                    <td class="diff-lineheader">-</td>
                    <td class="diffnav"><?php 
            echo $l_nav;
            ?>
</td>
                </tr>
                <tr>
                    <th class="diff-lineheader">-</th>
                    <th <?php 
            echo $l_minor;
            ?>
>
                        <?php 
            echo $l_head;
            ?>
                    </th>
                </tr>
            <?php 
        }
        ?>
            <tr>
                <td class="diff-lineheader">+</td>
                <td class="diffnav"><?php 
        echo $r_nav;
        ?>
</td>
            </tr>
            <tr>
                <th class="diff-lineheader">+</th>
                <th <?php 
        echo $r_minor;
        ?>
>
                    <?php 
        echo $r_head;
        ?>
                </th>
            </tr>
        <?php 
    } else {
        if (!$text) {
            ?>
                <tr>
                    <td colspan="2" class="diffnav"><?php 
            echo $l_nav;
            ?>
</td>
                    <td colspan="2" class="diffnav"><?php 
            echo $r_nav;
            ?>
</td>
                </tr>
            <?php 
        }
        ?>
            <tr>
                <th colspan="2" <?php 
        echo $l_minor;
        ?>
>
                    <?php 
        echo $l_head;
        ?>
                </th>
                <th colspan="2" <?php 
        echo $r_minor;
        ?>
>
                    <?php 
        echo $r_head;
        ?>
                </th>
            </tr>
        <?php 
    }
    //diff view
    echo html_insert_softbreaks($diffformatter->format($diff));
    ?>

    </table>
    </div>
<?php 
}
 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>');
 }
 /**
  * When rev1 > rev2, their order is changed
  */
 function test_request_wrong_order_revs()
 {
     $rev1 = 1362527164;
     $rev2 = 1362526767;
     $max = 10;
     $revsexpected = array(array_slice($this->revsexpected, 8, 11), array_slice($this->revsexpected, 5, 11));
     $pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
     $revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
     $this->assertEquals($revsexpected, $revs);
     $pagelog = new PageChangeLog($this->pageid, $chunk_size = 512);
     $revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
     $this->assertEquals($revsexpected, $revs);
     $pagelog = new PageChangeLog($this->pageid, $chunk_size = 20);
     $revs = $pagelog->getRevisionsAround($rev1, $rev2, $max);
     $this->assertEquals($revsexpected, $revs);
 }
 function test_notexistingcurrentpage()
 {
     $rev = 1385051947;
     $currentexpected = false;
     $pagelog = new PageChangeLog('nonexistingpage', $chunk_size = 8192);
     $current = $pagelog->isCurrentRevision($rev);
     $this->assertEquals($currentexpected, $current);
 }
 function _exportPostcontent($exporter)
 {
     global $ID, $INFO, $REV, $conf;
     $exporter->setParameters('Article: ' . $INFO['meta']['title'] . ($REV ? ' (rev ' . $REV . ')' : ''), $this->_getDokuUrl(), $this->_getDokuUrl() . 'doku.php?', 'utf-8', $this->agentlink);
     // create user object
     // $id, $uri, $name, $email, $homepage='', $foaf_uri='', $role=false, $nick='', $sioc_url='', $foaf_url=''
     $dwuserpage_id = cleanID($this->getConf('userns')) . ($conf['useslash'] ? '/' : ':') . $INFO['editor'];
     /*
     if ($INFO['editor'] && $this->getConf('userns'))
         $pageuser = new SIOCUser($INFO['editor'],
                                     normalizeUri(getAbsUrl(exportlink($dwuserpage_id, 'siocxml', array('type'=>'user'), false, '&'))), // user page
                                     $INFO['meta']['contributor'][$INFO['editor']],
                                     getDwUserInfo($dwuserpage_id,$this,'mail'),
                                     '', // no homepage is saved for dokuwiki user
                                     '#'.$INFO['editor'], // local uri
                                     false, // no roles right now
                                     '', // no nick name is saved for dokuwiki user
                                     normalizeUri($exporter->siocURL('user', $dwuserpage_id))
                                 );
     */
     // create wiki page object
     $wikipage = new SIOCDokuWikiArticle($ID, normalizeUri($exporter->siocURL('post', $ID . ($REV ? $exporter->_urlseparator . 'rev' . $exporter->_urlequal . $REV : ''))), $INFO['meta']['title'] . ($REV ? ' (rev ' . $REV . ')' : ''), rawWiki($ID, $REV));
     /* encoded content   */
     $wikipage->addContentEncoded(p_cached_output(wikiFN($ID, $REV), 'xhtml'));
     /* created           */
     if (isset($INFO['meta']['date']['created'])) {
         $wikipage->addCreated(date('c', $INFO['meta']['date']['created']));
     }
     /* or modified       */
     if (isset($INFO['meta']['date']['modified'])) {
         $wikipage->addModified(date('c', $INFO['meta']['date']['modified']));
     }
     /* creator/modifier  */
     if ($INFO['editor'] && $this->getConf('userns')) {
         $wikipage->addCreator(array('foaf:maker' => '#' . $INFO['editor'], 'sioc:modifier' => $dwuserpage_id));
     }
     /* is creator        */
     if (isset($INFO['meta']['date']['created'])) {
         $wikipage->isCreator();
     }
     /* intern wiki links */
     $wikipage->addLinks($INFO['meta']['relation']['references']);
     // contributors - only for last revision b/c of wrong meta data for older revisions
     if (!$REV && $this->getConf('userns') && isset($INFO['meta']['contributor'])) {
         $cont_temp = array();
         $cont_ns = $this->getConf('userns') . ($conf['useslash'] ? '/' : ':');
         foreach ($INFO['meta']['contributor'] as $cont_id => $cont_name) {
             $cont_temp[$cont_ns . $cont_id] = $cont_name;
         }
         $wikipage->addContributors($cont_temp);
     }
     // backlinks - only for last revision
     if (!$REV) {
         require_once DOKU_INC . 'inc/fulltext.php';
         $backlinks = ft_backlinks($ID);
         if (count($backlinks) > 0) {
             $wikipage->addBacklinks($backlinks);
         }
     }
     // TODO: addLinksExtern
     /* previous and next revision */
     $changelog = new PageChangeLog($ID);
     $pagerevs = $changelog->getRevisions(0, $conf['recent'] + 1);
     $prevrev = false;
     $nextrev = false;
     if (!$REV) {
         // latest revision, previous rev is on top in array
         $prevrev = 0;
     } else {
         // other revision
         $currentrev = array_search($REV, $pagerevs);
         if ($currentrev !== false) {
             $prevrev = $currentrev + 1;
             $nextrev = $currentrev - 1;
         }
     }
     if ($prevrev !== false && $prevrev > -1 && page_exists($ID, $pagerevs[$prevrev])) {
         /* previous revision*/
         $wikipage->addVersionPrevious($pagerevs[$prevrev]);
     }
     if ($nextrev !== false && $nextrev > -1 && page_exists($ID, $pagerevs[$nextrev])) {
         /* next revision*/
         $wikipage->addVersionNext($pagerevs[$nextrev]);
     }
     /* latest revision   */
     if ($REV) {
         $wikipage->addVersionLatest();
     }
     // TODO: topics
     /* has_container     */
     if ($INFO['namespace']) {
         $wikipage->addContainer($INFO['namespace']);
     }
     /* has_space         */
     if ($this->getConf('owners')) {
         $wikipage->addSite($this->getConf('owners'));
     }
     // TODO: dc:contributor / has_modifier
     // TODO: attachment (e.g. pictures in that dwns)
     // add wiki page to exporter
     $exporter->addObject($wikipage);
     //if ($INFO['editor'] && $this->getConf('userns')) $exporter->addObject($pageuser);
     return $exporter;
 }
Example #16
0
/**
 * Saves a wikitext by calling io_writeWikiPage.
 * Also directs changelog and attic updates.
 *
 * @author Andreas Gohr <*****@*****.**>
 * @author Ben Coburn <*****@*****.**>
 *
 * @param string $id       page id
 * @param string $text     wikitext being saved
 * @param string $summary  summary of text update
 * @param bool   $minor    mark this saved version as minor update
 */
function saveWikiText($id, $text, $summary, $minor = false)
{
    /* Note to developers:
         This code is subtle and delicate. Test the behavior of
         the attic and changelog with dokuwiki and external edits
         after any changes. External edits change the wiki page
         directly without using php or dokuwiki.
       */
    global $conf;
    global $lang;
    global $REV;
    /* @var Input $INPUT */
    global $INPUT;
    // ignore if no changes were made
    if ($text == rawWiki($id, '')) {
        return;
    }
    $file = wikiFN($id);
    $old = @filemtime($file);
    // from page
    $wasRemoved = trim($text) == '';
    // check for empty or whitespace only
    $wasCreated = !file_exists($file);
    $wasReverted = $REV == true;
    $pagelog = new PageChangeLog($id, 1024);
    $newRev = false;
    $oldRev = $pagelog->getRevisions(-1, 1);
    // from changelog
    $oldRev = (int) (empty($oldRev) ? 0 : $oldRev[0]);
    if (!file_exists(wikiFN($id, $old)) && file_exists($file) && $old >= $oldRev) {
        // add old revision to the attic if missing
        saveOldRevision($id);
        // add a changelog entry if this edit came from outside dokuwiki
        if ($old > $oldRev) {
            addLogEntry($old, $id, DOKU_CHANGE_TYPE_EDIT, $lang['external_edit'], '', array('ExternalEdit' => true));
            // remove soon to be stale instructions
            $cache = new cache_instructions($id, $file);
            $cache->removeCache();
        }
    }
    if ($wasRemoved) {
        // Send "update" event with empty data, so plugins can react to page deletion
        $data = array(array($file, '', false), getNS($id), noNS($id), false);
        trigger_event('IO_WIKIPAGE_WRITE', $data);
        // pre-save deleted revision
        @touch($file);
        clearstatcache();
        $newRev = saveOldRevision($id);
        // remove empty file
        @unlink($file);
        // don't remove old meta info as it should be saved, plugins can use IO_WIKIPAGE_WRITE for removing their metadata...
        // purge non-persistant meta data
        p_purge_metadata($id);
        $del = true;
        // autoset summary on deletion
        if (empty($summary)) {
            $summary = $lang['deleted'];
        }
        // remove empty namespaces
        io_sweepNS($id, 'datadir');
        io_sweepNS($id, 'mediadir');
    } else {
        // save file (namespace dir is created in io_writeWikiPage)
        io_writeWikiPage($file, $text, $id);
        // pre-save the revision, to keep the attic in sync
        $newRev = saveOldRevision($id);
        $del = false;
    }
    // select changelog line type
    $extra = '';
    $type = DOKU_CHANGE_TYPE_EDIT;
    if ($wasReverted) {
        $type = DOKU_CHANGE_TYPE_REVERT;
        $extra = $REV;
    } else {
        if ($wasCreated) {
            $type = DOKU_CHANGE_TYPE_CREATE;
        } else {
            if ($wasRemoved) {
                $type = DOKU_CHANGE_TYPE_DELETE;
            } else {
                if ($minor && $conf['useacl'] && $INPUT->server->str('REMOTE_USER')) {
                    $type = DOKU_CHANGE_TYPE_MINOR_EDIT;
                }
            }
        }
    }
    //minor edits only for logged in users
    addLogEntry($newRev, $id, $type, $summary, $extra);
    // send notify mails
    notify($id, 'admin', $old, $summary, $minor);
    notify($id, 'subscribers', $old, $summary, $minor);
    // update the purgefile (timestamp of the last time anything within the wiki was changed)
    io_saveFile($conf['cachedir'] . '/purgefile', time());
    // if useheading is enabled, purge the cache of all linking pages
    if (useHeading('content')) {
        $pages = ft_backlinks($id, true);
        foreach ($pages as $page) {
            $cache = new cache_renderer($page, wikiFN($page), 'xhtml');
            $cache->removeCache();
        }
    }
}
 /**
  * request with too large offset and range
  */
 function test_requesttoolargenumberrevs()
 {
     $first = 50;
     $num = 50;
     $revsexpected = array();
     $pagelog = new PageChangeLog($this->pageid, $chunk_size = 8192);
     $revs = $pagelog->getRevisions($first, $num);
     $this->assertEquals($revsexpected, $revs);
 }
/**
 * Return a list of page revisions numbers
 * Does not guarantee that the revision exists in the attic,
 * only that a line with the date exists in the changelog.
 * By default the current revision is skipped.
 *
 * id:    the page of interest
 * first: skip the first n changelog lines
 * num:   number of revisions to return
 *
 * The current revision is automatically skipped when the page exists.
 * See $INFO['meta']['last_change'] for the current revision.
 *
 * For efficiency, the log lines are parsed and cached for later
 * calls to getRevisionInfo. Large changelog files are read
 * backwards in chunks until the requested number of changelog
 * lines are recieved.
 *
 * @deprecated 20-11-2013
 *
 * @author Ben Coburn <*****@*****.**>
 * @author Kate Arzamastseva <*****@*****.**>
 */
function getRevisions($id, $first, $num, $chunk_size = 8192, $media = false)
{
    if ($media) {
        $changelog = new MediaChangeLog($id, $chunk_size);
    } else {
        $changelog = new PageChangeLog($id, $chunk_size);
    }
    return $changelog->getRevisions($first, $num);
}