function action_history()
{
    global $pagestore, $page, $full, $HistMax;
    $history = $pagestore->history($page);
    gen_headers($history[0][0]);
    $text = '';
    $latest_auth = '';
    $previous_ver = 0;
    $is_latest = 1;
    for ($i = 0; $i < count($history); $i++) {
        if ($latest_auth == '') {
            $latest_auth = $history[$i][3] == '' ? $history[$i][1] : $history[$i][3];
            $latest_ver = $history[$i][2];
        }
        if ($previous_ver == 0 && $latest_auth != ($history[$i][3] == '' ? $history[$i][1] : $history[$i][3])) {
            $previous_ver = $history[$i][2];
        }
        if ($i < $HistMax || $full) {
            $text = $text . html_history_entry($page, $history[$i][2], $history[$i][0], $history[$i][1], $history[$i][3], $previous_ver == $history[$i][2] || !$full && $i == count($history) - 1, $is_latest, $history[$i][4]);
        }
        $is_latest = 0;
    }
    if ($i >= $HistMax && !$full) {
        $text = $text . html_fullhistory($page, count($history));
    }
    $p1 = $pagestore->page($page);
    $p1->version = $previous_ver;
    $p2 = $pagestore->page($page);
    $p2->version = $latest_ver;
    $diff = diff_compute($p1->read(), $p2->read());
    template_history(array('page' => $p2->as_array(), 'history' => $text, 'diff' => diff_parse($diff)));
}
Example #2
0
function do_diff($body1, $body2)
{
    global $diff_mode, $DiffModeCookieName, $EnableWordDiff, $HTTP_COOKIE_VARS;
    if ($EnableWordDiff) {
        if (!isset($diff_mode)) {
            if (isset($HTTP_COOKIE_VARS[$DiffModeCookieName])) {
                $diff_mode = $HTTP_COOKIE_VARS[$DiffModeCookieName];
            } else {
                $diff_mode = 0;
            }
        }
        if (!isset($HTTP_COOKIE_VARS[$DiffModeCookieName]) || $diff_mode != $HTTP_COOKIE_VARS[$DiffModeCookieName]) {
            setcookie($DiffModeCookieName, $diff_mode, time() + 157680000, "/", false);
        }
    } else {
        $diff_mode = 0;
    }
    // diff mode: 0 = regular diff, 1 = word diff
    if ($diff_mode == 1) {
        $diff = wdiff_compute($body1, $body2);
        $diff = wdiff_parse($diff);
    } else {
        $diff = diff_compute($body1, $body2);
        $diff = diff_parse($diff);
    }
    return $diff;
}
Example #3
0
function action_diff()
{
    global $pagestore, $page, $ver1, $ver2, $ParseEngine;
    $p1 = $pagestore->page($page);
    $p1->version = $ver1;
    $p2 = $pagestore->page($page);
    $p2->version = $ver2;
    $diff = diff_compute($p1->read(), $p2->read());
    template_diff(array('page' => $p2->as_array(), 'diff_html' => diff_parse($diff), 'html' => parseText($p2->text, $ParseEngine, $page), 'editable' => $p2->acl_check(), 'timestamp' => $p2->time));
}
Example #4
0
function action_diff()
{
    global $page, $pagestore, $ParseEngine, $UserName, $ver1, $ver2;
    $p1 = $pagestore->page($page);
    $p1->version = $ver1;
    $p2 = $pagestore->page($page);
    $p2->version = $ver2;
    $diff = diff_compute($p1->read(), $p2->read());
    template_diff(array('page' => $page, 'diff_html' => diff_parse($diff), 'html' => parseText($p2->text, $ParseEngine, $page), 'editable' => $p2->mutable, 'timestamp' => $p2->time, 'editver' => $UserName && $p2->mutable ? 0 : -1));
}
Example #5
0
function action_rss()
{
    global $days, $min, $page, $pagestore;
    $itemdesc = '';
    if ($min == 0) {
        $min = 10;
    }
    if ($days == 0) {
        $days = 2;
    }
    if (!isset($_GET['page'])) {
        $page = 'RecentChanges';
    }
    if ($page == 'RecentChanges') {
        $pages = $pagestore->allpages();
    } else {
        $pages = $pagestore->givenpages(array($page));
    }
    usort($pages, 'catSort');
    $now = time();
    for ($i = 0; $i < count($pages); $i++) {
        if ($page == 'RecentChanges') {
            if ($days >= 0 && $now - $pages[$i][0] > $days * 24 * 60 * 60 && $i >= $min) {
                break;
            }
        }
        // Gets the diff as it shows by default on History page.
        // See diff_get_history_versions in lib/diff.php.
        $history = $pagestore->history($pages[$i][1]);
        $versions = diff_get_history_versions($history);
        $latest_ver = $versions['latest_ver'];
        $previous_ver = $versions['previous_ver'];
        $p1 = $pagestore->page($pages[$i][1]);
        $p1->version = $previous_ver;
        $p2 = $pagestore->page($pages[$i][1]);
        $p2->version = $latest_ver;
        if ($previous_ver == $latest_ver) {
            $diff = $p1->read();
            $diff = explode("\n", $diff);
            foreach ($diff as $key => $value) {
                $diff[$key] = "+{$value}";
            }
            $diff = implode("\n", $diff);
        } else {
            $diff = diff_compute($p1->read(), $p2->read());
        }
        $diff = diff_parse($diff);
        $diff = str_replace('<td class="diff-added">', '<td style="background-color:#ccffcc;color:#000000;">', $diff);
        $diff = str_replace('<td class="diff-removed">', '<td style="background-color:#ffaaaa;color:#000000;">', $diff);
        #$diff = preg_replace('/\n/', chr(13) . chr(10), $diff);
        #$diff = preg_replace('/\n/', "<br>\n", $diff);
        $itemdesc = $itemdesc . '<item>' . "\n" . '<title>' . $pages[$i][1] . '</title>' . "\n" . '<pubDate>' . date('r', $pages[$i][0]) . '</pubDate>' . "\n" . '<link>' . viewFullURL($pages[$i][1]) . '&amp;' . $pages[$i][7] . '</link>' . "\n" . '<description>' . htmlspecialchars(($pages[$i][5] ? $pages[$i][5] . "<br>\n<br>\n" : '') . $diff) . '</description>' . "\n" . '</item>' . "\n\n";
    }
    template_rss(array('itemdesc' => $itemdesc, 'page' => $page));
}
Example #6
0
function action_save()
{
    global $Admin, $AllowAnonymousPosts, $AllowAnonymousPostsHtml, $archive;
    global $captcha, $categories, $comment, $Diff3Cmd, $document, $EmailSuffix;
    global $EnableCaptcha, $EnableDiff3, $EnableSubscriptions;
    global $ErrorPageLocked, $HTTP_POST_VARS, $MaxPostLen, $merge, $minoredit;
    global $nextver, $NickName, $page, $pagefrom, $pagestore, $REMOTE_ADDR;
    global $Save, $SaveMacroEngine, $section, $template, $text_after;
    global $text_before, $UserName, $validationcode, $WorkingDirectory;
    if (!$UserName && !$AllowAnonymousPosts) {
        global $ErrorNoAnonComments;
        die($ErrorNoAnonComments);
    }
    if (isset($HTTP_POST_VARS['quickadd'])) {
        $quickadd = $HTTP_POST_VARS['quickadd'];
    }
    if (isset($HTTP_POST_VARS['appending'])) {
        $appending = $HTTP_POST_VARS['appending'];
    }
    // added for "Add a Quote" feature for AnnoyingQuote page
    if (isset($HTTP_POST_VARS['quoteAuthor'])) {
        $quoteAuthor = $HTTP_POST_VARS['quoteAuthor'];
    }
    if (isset($HTTP_POST_VARS['appendingQuote'])) {
        $appendingQuote = $HTTP_POST_VARS['appendingQuote'];
    }
    if (get_magic_quotes_gpc()) {
        if (isset($quickadd)) {
            $quickadd = stripslashes($quickadd);
        }
        if (isset($quoteAuthor)) {
            $quoteAuthor = stripslashes($quoteAuthor);
        }
    }
    // validations for unlogged users
    if (!$UserName) {
        if ($EnableCaptcha) {
            $captcha_d = strtolower(decode_captcha_md5($captcha));
            $captcha_v = trim(strtolower($validationcode));
            if ($captcha_v == '' || $captcha_v !== $captcha_d) {
                global $ErrorValidationCode;
                die($ErrorValidationCode);
            }
        }
        // prevent empty posts
        if (strlen(trim($quickadd)) <= 75) {
            $ptrn = '/^----\\s+\'\'\'.+?@\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3} ' . '\\(\\d{4}\\/\\d{2}\\/\\d{2}\\)\'\'\':$/';
            if (preg_match($ptrn, trim($quickadd))) {
                global $ErrorEmptyComment;
                die($ErrorEmptyComment);
            }
        }
    }
    if (empty($Save)) {
        include 'action/preview.php';
        action_preview();
        return;
    }
    $pagestore->lock();
    // Ensure atomicity.
    $pg = $pagestore->page($page);
    $pg->read();
    $pageWasEmpty = strlen($pg->text) <= 1;
    if (isset($appending)) {
        $document = $pg->text;
        $nextver = $pg->version + 1;
    } else {
        if ($section) {
            $document = $text_before . "\n\n" . trim($document) . "\n\n" . $text_after;
        }
        $pg->template = $template;
    }
    // Edit disallowed.
    if (!$pg->mutable || !$UserName && (!isset($appending) || !$pg->exists())) {
        $pagestore->unlock();
        die($ErrorPageLocked);
    }
    // gets the hostname without the nickname
    $page_hostname = array_pop(explode('@', $pg->hostname));
    if ($UserName && $pg->exists() && $pg->version >= $nextver && ($page_hostname != gethostbyaddr($REMOTE_ADDR) || $pg->username != $UserName) && !$archive) {
        $merge_conflict = 1;
        $merge = '';
        $diff3_test = array();
        if ($EnableDiff3) {
            exec($Diff3Cmd . ' --help', $diff3_test);
        }
        if (count($diff3_test)) {
            // page conflict, try to merge
            $your_file_text = $pg->text;
            $my_file_text = str_replace("\r", "", $document);
            $pg_old = $pagestore->page($page);
            $pg_old->version = $nextver - 1;
            $pg_old->read();
            $old_file_text = $pg_old->text;
            global $TempDir;
            $num = posix_getpid();
            // Comment if running on Windows.
            // $num = rand();       // Uncomment if running on Windows.
            $my_file = $TempDir . '/wiki_' . $num . '_my_file.txt';
            $old_file = $TempDir . '/wiki_' . $num . '_old_file.txt';
            $your_file = $TempDir . '/wiki_' . $num . '_your_file.txt';
            if (!($h_my = fopen($my_file, 'w')) || !($h_old = fopen($old_file, 'w')) || !($h_your = fopen($your_file, 'w'))) {
                die("ErrorCreatingTemp");
            }
            if (fwrite($h_my, $my_file_text) < 0 || fwrite($h_old, $old_file_text) < 0 || fwrite($h_your, $your_file_text) < 0) {
                die("ErrorWritingTemp");
            }
            fclose($h_my);
            fclose($h_old);
            fclose($h_your);
            $diff3_options = '-mE -L "Your modifications" -L "Original file" ' . '-L "Someone else\'s modifications"';
            exec($Diff3Cmd . ' ' . $diff3_options . ' ' . $my_file . ' ' . $old_file . ' ' . $your_file, $merge);
            unlink($my_file);
            unlink($old_file);
            unlink($your_file);
            $merge = implode("\n", $merge);
            $regexp = '/<{7} Your modifications/s';
            $merge_conflict = preg_match($regexp, $merge);
        }
        if ($merge_conflict) {
            $pagestore->unlock();
            include 'action/conflict.php';
            action_conflict();
            return;
        } else {
            $document = $merge;
        }
    }
    // "Add a Comment" is "Add a Quote" for specific pages like AnnoyingQuote
    if (isset($quickadd) && isset($appendingQuote)) {
        // if we're appending a quote, instead of a comment
        $quoteAuthor = trim($quoteAuthor);
        if ($quoteAuthor != '') {
            // Add author to quote if author provided. Add a leading dash if
            // needed. See strpos help for information about "=== false".
            $pos = strpos($quoteAuthor, '-');
            if ($pos === false || $pos > 0) {
                $quoteAuthor = "-- {$quoteAuthor}";
            }
            $quickadd .= " {$quoteAuthor}";
        }
    }
    // Silently trim string to $MaxPostLen chars.
    $document = substr($document, 0, $MaxPostLen);
    if (isset($appending)) {
        $document = str_replace("\\\\'", '"', $document);
    }
    $document = str_replace("\\", "\\\\", $document);
    $document = str_replace("'", "\\'", $document);
    $document = str_replace("\r", "", $document);
    $comment = str_replace("\\", "\\\\", $comment);
    $comment = str_replace("'", "\\'", $comment);
    if (isset($appending) && isset($quickadd)) {
        // Add new lines if document is not empty.
        if ($document) {
            $document = trim($document) . "\n\n";
        }
        $quickadd = str_replace("\\", "\\\\", $quickadd);
        $quickadd = str_replace("'", "\\'", $quickadd);
        $quickadd = str_replace("\r", "", $quickadd);
        if (!$AllowAnonymousPostsHtml) {
            $quickadd = htmlspecialchars($quickadd);
        }
        $document .= $quickadd;
    }
    $pg->text = $document;
    $pg->hostname = gethostbyaddr($REMOTE_ADDR);
    if (!$UserName && $NickName) {
        $nick_sql = str_replace("\\", "\\\\", $NickName);
        $nick_sql = str_replace("'", "\\'", $nick_sql);
        $pg->hostname = $nick_sql . '@' . $pg->hostname;
    }
    $pg->username = $UserName;
    $pg->comment = $comment;
    if ($pg->exists) {
        $pg->version++;
    } else {
        $pg->version = 1;
    }
    if (!$pg->write($minoredit)) {
        $pagestore->unlock();
        die("Error saving a page.");
    }
    // Parenting stuff for new pages.
    if ($pageWasEmpty) {
        // Ensures that $pagefrom is really a backlink.
        if ($pagefrom) {
            $backlinks = $pagestore->getBacklinks($page);
            if (!in_array($pagefrom, $backlinks)) {
                $pagefrom = '';
            }
        }
        // If no parent is specified, tries to find one.
        if (!$pagefrom) {
            $pagefrom = $pagestore->findFosterParent($page);
        }
        // The $pagefrom page becomes the new page's parent.
        if ($pagefrom) {
            $tempPage = $pagestore->page($pagefrom);
            if ($tempPage->exists()) {
                $pagestore->reparent($page, $pagefrom);
            }
        }
    }
    // Editor asked page to be added to a category or categories.
    if (!empty($categories)) {
        add_to_category($page, $categories);
    }
    // Process save macros (e.g., to define interwiki entries).
    parseText($document, $SaveMacroEngine, $page);
    // Remove any parenting if the page is empty.
    if (strlen(trim($document)) == 0) {
        $pagestore->reparent_emptypage($page);
    }
    $pagestore->unlock();
    // End "transaction".
    // Handles page subscriptions
    if ($EnableSubscriptions && isset($EmailSuffix)) {
        if ($subscribed_users = $pg->getSubscribedUsers($UserName)) {
            global $ScriptBase, $WikiName;
            foreach ($subscribed_users as $user) {
                $msg = "This is your friendly neighbourhood wiki ({$WikiName}) " . "letting you know that the page {$page} has changed!\n\n";
                if ($minoredit) {
                    $msg .= "This was a minor edit.\n\n";
                }
                $msg .= "View page: {$ScriptBase}?{$page}\n\n" . "History: {$ScriptBase}?action=history&page={$page}\n\n";
                // friendly diff
                $history = $pagestore->history($page);
                if (count($history) > 1) {
                    $previous_ver = $history[1][2];
                    $latest_ver = $history[0][2];
                    $p1 = $pagestore->page($page);
                    $p1->version = $previous_ver;
                    $p2 = $pagestore->page($page);
                    $p2->version = $latest_ver;
                    $diff = diff_compute($p1->read(), $p2->read());
                    $msg .= "Friendly diff:\n\n{$diff}";
                }
                mail($user . $EmailSuffix, "{$WikiName}: {$page} has changed", $msg, "From: {$Admin}");
            }
        }
    }
    // Aligns the browser with an HTML anchor, showing the last added comment (or quote)
    // See: action/save.php, template/save.php, template/view.php
    if (isset($quickadd)) {
        // if Add a Comment or Add a Quote
        template_save(array('page' => $page, 'text' => $document, 'anchor' => 'pageContentBottom'));
    } else {
        // Standard save
        template_save(array('page' => $page, 'text' => $document));
    }
}