Esempio n. 1
0
function macro_Category($formatter, $value = '', $params = array())
{
    if (!isset($formatter->categories)) {
        $formatter->categories = array();
    }
    if (isset($value[0])) {
        // add a backlink
        $tmp = $formatter->word_repl('[[' . $value . ']]');
        // is it a category link
        if (preg_match('@' . $formatter->category_regex . '@', $value)) {
            $formatter->categories[] = $value;
            return '<span></span>';
        }
        // not a category link
        return $tmp;
    }
    $cc = new Cache_Text('categories');
    if (count($formatter->categories) > 0) {
        if (!$formatter->preview) {
            $cc->update($formatter->page->name, $formatter->categories);
        }
        $categories = $formatter->categories;
    } else {
        if ($formatter->page->exists()) {
            $categories = $cc->fetch($formatter->page->name);
        } else {
            $cc->remove($formatter->page->name);
            $categories = array();
        }
    }
    if (!empty($params['call']) || !empty($params['.call'])) {
        return $categories;
    }
    if (empty($categories)) {
        return '';
    }
    $out = '<div class="wikiCategory">';
    $out .= '<h2>' . _("Category") . '</h2>';
    $out .= '<ul>';
    foreach ($categories as $cat) {
        if (preg_match('@' . $formatter->category_regex . '@', $cat, $m)) {
            // strip category prefix
            if (isset($m[1])) {
                $text = $m[1];
            } else {
                $text = substr($cat, strlen($m[0]));
            }
            $tmp = $formatter->word_repl('[[' . $cat . ']]', $text);
            $out .= '<li>' . $tmp . '</li>' . "\n";
        }
    }
    $out .= '</ul></div>';
    return $out;
}
Esempio n. 2
0
/**
 * Store pagelinks
 *
 * @author   Won-Kyu Park <*****@*****.**>
 */
function store_pagelinks($pagename, $pagelinks)
{
    global $DBInfo;
    $bcache = new Cache_Text('backlinks');
    $cache = new Cache_Text('pagelinks');
    unset($pagelinks['TwinPages']);
    $cur = $cache->fetch($pagename);
    if (!is_array($cur)) {
        $cur = array();
    }
    $add = array_diff($pagelinks, $cur);
    $del = array_diff($cur, $pagelinks);
    // merge new backlinks
    foreach ($add as $a) {
        if (!isset($a[0])) {
            continue;
        }
        $bl = $bcache->fetch($a);
        if (!is_array($bl)) {
            $bl = array();
        }
        $bl = array_merge($bl, array($pagename));
        $bl = array_unique($bl);
        sort($bl);
        $bcache->update($a, $bl);
    }
    // remove deleted backlinks
    foreach ($del as $d) {
        if (!isset($d[0])) {
            continue;
        }
        $bl = $bcache->fetch($d);
        if (!is_array($bl)) {
            $bl = array();
        }
        $bl = array_diff($bl, array($pagename));
        sort($bl);
        $bcache->update($d, $bl);
    }
    if (!empty($pagelinks)) {
        $cache->update($pagename, $pagelinks);
    } else {
        $cache->remove($pagename);
    }
}
Esempio n. 3
0
function do_ipinfo($formatter, $params = array())
{
    global $DBInfo, $Config;
    $u = $DBInfo->user;
    $list = '';
    $myip = '';
    $mask = 24;
    $masks = array(24, 25, 16, 18, 8);
    $ttls = array(1800 => '30 minutes', 3600 => '1 hour', 7200 => '2 hours', 10800 => '3 hours', 21600 => '6 hours', 43200 => '12 hours', 1 => '1 day', 2 => '2 days', 7 => '7 days', 30 => '1 month', 60 => '2 month', 182 => '6 month', 365 => '1 year');
    $reasons = array(100 => _("Vandalism"), 150 => _("Abusing"), 200 => _("Incompatible License"), 210 => _("CCL BY"), 220 => _("CCL NC"), 300 => _("Discussion needed"), 400 => _("Robot"), 500 => _("Testing"));
    if (!empty($params['q'])) {
        $tmp = normalize_network($params['q']);
        $myip = $params['q'];
        if ($tmp === false) {
            $params['msg'] = sprintf(_("Invalid IP Address %s"), $ip);
            $params['q'] = '';
        } else {
            $myip = $params['q'] = $ip = $tmp[0];
            if ($tmp[1] != 32) {
                $netmask = $tmp[1];
            }
        }
    }
    $control_action = false;
    if (!empty($params['q']) && isset($_POST) && !empty($params['button_block'])) {
        $control_action = 'block';
    } else {
        if (!empty($params['q']) && !empty($params['toggle'])) {
            $control_action = 'toggle';
            $params['ttl'] = -1;
            // HACK to toggle block staus
        } else {
            if (!empty($params['q']) && !empty($params['remove'])) {
                if (in_array($u->id, $DBInfo->owners)) {
                    $control_action = 'remove';
                } else {
                    $control_action = 'reset';
                }
                $params['ttl'] = -1;
                // HACK
            }
        }
    }
    while ($u->is_member && $control_action !== false) {
        // check parameters
        // TTL check
        if (!empty($params['reason']) and array_key_exists($params['reason'], $reasons)) {
            $reason = $params['reason'];
        }
        if (!empty($params['comment'])) {
            $comment = $params['comment'];
        }
        $ttl = !empty($params['ttl']) ? (int) $params['ttl'] : 1800;
        // default 30 minutes
        if (in_array($u->id, $DBInfo->owners)) {
            $ttl = !empty($params['ttl']) ? $params['ttl'] : 0;
            // default for owners
        } else {
            if ($ttl >= 60) {
                $ttl = 1800;
            }
        }
        if ($ttl < 0) {
            $ttl = 1;
        } else {
            if ($ttl <= 365) {
                // days to seconds
                $ttl = $ttl * 60 * 60 * 24;
            }
        }
        if ($ttl >= 0 && !in_array($u->id, $DBInfo->owners)) {
            if (empty($comment) && empty($reason)) {
                $params['msg'] = _("Please select block reason");
                break;
            }
        }
        $netmask = !empty($params['netmask']) ? (int) $params['netmask'] : $netmask;
        if ($netmask >= 32) {
            $netmask = '';
        }
        $try = $ip;
        if (!empty($netmask)) {
            $try .= '/' . $netmask;
        }
        $tmp = normalize_network($try);
        if ($tmp === false) {
            if (empty($netmask)) {
                $params['msg'] = sprintf(_("Not a valid IP address: %s"), $try);
            } else {
                $params['msg'] = sprintf(_("Not a valid IP range: %s"), $try);
            }
        } else {
            // prepare to return
            $ret = array();
            $retval = array();
            $ret['retval'] =& $retval;
            if ($tmp[1] == 32) {
                // normalized IP
                $ip = $tmp[0];
                // abusefilter cache
                $arena = 'abusefilter';
                $ac = new Cache_Text('abusefilter');
                // fetch monitor information
                $info = $ac->fetch($ip, 0, $ret);
                if ($info === false) {
                    $new_info = array('create' => 0, 'delete' => 0, 'revert' => 0, 'save' => 0, 'edit' => 0, 'add_lines' => 0, 'del_lines' => 0, 'add_chars' => 0, 'del_chars' => 0);
                    $new_info['id'] = $ip;
                    $new_info['suspended'] = true;
                } else {
                    $new_info = $info;
                    $new_info['id'] = $ip;
                }
            } else {
                // normalized IP
                $ip = $tmp[0] . '/' . $tmp[1];
                // ipblock cache
                $arena = 'ipblock';
                $ac = new Cache_Text('ipblock');
                // fetch monitor information
                $info = $ac->fetch($ip, 0, $ret);
                if ($info === false) {
                    $new_info['id'] = $ip;
                    $new_info['suspended'] = true;
                } else {
                    $new_info = $info;
                    $new_info['id'] = $ip;
                }
            }
            if (!empty($reason)) {
                $new_info['reason'] = $reason;
            }
            if (!empty($comment)) {
                // upate comments
                $comments = array();
                if (!empty($info['comment'])) {
                    $comments = explode("\n", $new_info['comment']);
                }
                $comments[] = date('Y-m-d H:i', time()) . "\t" . $u->id . "\t" . $comment;
                if (sizeof($comments) > 100) {
                    array_shift($comments);
                }
                $new_info['comment'] = implode("\n", $comments);
            }
            if ($ttl == 1) {
                if ($control_action == 'reset') {
                    $new_info['suspended'] = false;
                } else {
                    if ($control_action == 'toggle') {
                        $new_info['suspended'] = !$new_info['suspended'];
                    }
                }
                $newttl = $retval['ttl'] - (time() - $retval['mtime']);
                if ($newttl < 0) {
                    $newttl = 0;
                }
                if ($control_action == 'remove') {
                    $ac->remove($ip);
                } else {
                    $ac->update($ip, $new_info, $newttl);
                }
            } else {
                $new_info['suspended'] = true;
                $ac->update($ip, $new_info, $ttl);
            }
            if ($control_action == 'toggle') {
                $params['msg'] = sprintf(_("Successfully Toggle Block status: %s"), $try);
            } else {
                if ($control_action == 'reset') {
                    $params['msg'] = sprintf(_("Successfully Enable IP (range) status: %s"), $try);
                } else {
                    if ($control_action == 'remove') {
                        $params['msg'] = sprintf(_("Successfully Removed IP range: %s"), $try);
                    } else {
                        if (!empty($netmask)) {
                            $params['msg'] = sprintf(_("Successfully Blocked IP range: %s"), $try);
                        } else {
                            $params['msg'] = sprintf(_("Successfully Blocked IP address: %s"), $try);
                        }
                    }
                }
            }
        }
        break;
    }
    if (!empty($params['q']) && empty($params['button_block'])) {
        // search
        $retval = array();
        $ret = array('retval' => &$retval);
        $try = $params['q'];
        $cache = 'abusefilter';
        if (!empty($netmask)) {
            $try .= '/' . $netmask;
            $cache = 'ipblock';
        }
        // try to find blocked IP or IP range
        $ac = new Cache_Text($cache);
        $info = $ac->fetch($try, 0, $ret);
        if ($info === false) {
            // get temporary blocked IP ranges
            $blocked = get_cached_temporary_blacklist();
            $res = search_network($blocked, $params['q'], $ret);
            $permenant = false;
            if ($res === false) {
                // search blacklist ranges
                $res = search_network($Config['ruleset']['blacklist.ranges'], $params['q'], $ret);
                $permenant = true;
            }
            if ($res) {
                list($network, $netmask) = explode('/', $retval);
                if ($netmask == 32) {
                    $title = _("Temporary blocked IP (range) found") . ' : ' . $network;
                } else {
                    $found = $retval;
                    if ($permenant) {
                        $title = _("Permenantly blocked IP range found") . ' : ' . $found;
                        // show all temporary blocked list
                        $list = macro_IpInfo($formatter);
                    } else {
                        $title = _("Temporary blocked IP range found") . ' : ' . $found;
                        // retrieve found
                        $ac = new Cache_Text('ipblock');
                        $info = $ac->fetch($found, 0, $ret);
                        if ($info !== false) {
                            $info['ttl'] = $retval['ttl'];
                            $info['mtime'] = $retval['mtime'];
                            $list = macro_IpInfo($formatter, '', array('info' => $info));
                        }
                    }
                }
            } else {
                $title = _("IP (range) is not found");
                // show all temporary blocked list
                $list = macro_IpInfo($formatter);
            }
        } else {
            $info['ttl'] = $retval['ttl'];
            $info['mtime'] = $retval['mtime'];
            $list = macro_IpInfo($formatter, '', array('info' => $info));
            $title = _("Temporary blocked IP found") . ' : ' . $params['q'];
        }
    } else {
        if ($u->is_member) {
            $opt = 'range';
            if (!empty($params['static'])) {
                $opt = 'static';
            }
            if (!empty($params['all'])) {
                $opt = '';
            }
            $list = macro_IpInfo($formatter, $opt);
        } else {
            if (!$u->is_member) {
                $myip = $params['q'] = $_SERVER['REMOTE_ADDR'];
            }
        }
    }
    $params['.title'] = _("IP Information");
    if (!empty($title)) {
        $params['title'] = $title;
    } else {
        if (!empty($params['q'])) {
            $params['title'] = sprintf(_("%s: IP Information"), $params['q']);
        }
    }
    $formatter->send_header('', $params);
    $formatter->send_title($title, '', $params);
    $searchform = <<<FORM
<form method='post' action=''>
<label>Search</label>: <input type='text' name='q' value='{$myip}' placeholder='IP or IP range' />
<input type='submit' name='button_search' value='search' /><br />
<input type='hidden' name='action' value='ipinfo' />
</form>
FORM;
    echo '<h2>' . _("Temporary blocked IPs") . '</h2>', "\n";
    echo $searchform;
    echo $list;
    echo $searchform;
    echo '<h2>' . _("Input IP or IP range") . '</h2>', "\n";
    $mask_select = '<select name="netmask"><option value="">-- ' . _("Netmask") . ' --</option>' . "\n";
    foreach ($masks as $m) {
        $selected = '';
        if ($m == $netmask) {
            $selected = ' selected="selected"';
        }
        $mask_select .= '<option value="' . $m . '"' . $selected . '>' . "\n";
        $mask_select .= $m . ' : ';
        $c = 1 << 32 - $m;
        if ($c > 1) {
            $c -= 2;
        }
        $mask_select .= number_format($c) . ' IPs';
        $mask_select .= '</option>' . "\n";
    }
    $mask_select .= '</select>' . "\n";
    $ttl_select = '<select name="ttl"><option value="0">-- ' . _("Expire") . ' --</option>' . "\n";
    foreach ($ttls as $time => $str) {
        $ttl_select .= '<option value="' . $time . '">' . $str . '</option>' . "\n";
    }
    $ttl_select .= '</select>' . "\n";
    $reason_select = '<select name="reason"><option value="">-- ' . _("Block reason") . ' --</option>' . "\n";
    foreach ($reasons as $code => $str) {
        $reason_select .= '<option value="' . $code . '">' . $str . '</option>' . "\n";
    }
    $reason_select .= '</select>' . "\n";
    $ip_lab = _("IP Address");
    $net_lab = _("Netmask (i.e. 24)");
    $ttl_lab = _("Expire");
    $block_btn = _("Block IP");
    echo <<<FORM
<form method='post' action=''>
<table class='wiki'><tr><th>{$ip_lab}</th>
<th>{$net_lab}</th>
<th>{$ttl_lab}</th>
</tr>
<tr>
<td><input type='text' name='q' value='{$myip}' /></td>
<td>
{$mask_select}
</td>
<td>
{$ttl_select}
</td>
</tr>
<tr><td>{$reason_select}</td><td colspan='2'><input type='text' name='comment' size='50' /></td></tr>
</table>

FORM;
    echo <<<FORM
<input type='hidden' name='action' value='ipinfo' />
<input type='submit' name='button_block' value='{$block_btn}' />
</form>

FORM;
    $formatter->send_footer('', $params);
}
Esempio n. 4
0
function do_rss_rc($formatter, $options)
{
    global $DBInfo, $Config;
    // get members to hide log
    $members = $DBInfo->members;
    $days = !empty($DBInfo->rc_days) ? $DBInfo->rc_days : RSS_DEFAULT_DAYS;
    $options['quick'] = 1;
    if (!empty($options['c'])) {
        $options['items'] = $options['c'];
    }
    $lines = $DBInfo->editlog_raw_lines($days, $options);
    if (!empty($DBInfo->rss_rc_options)) {
        $opts = $DBInfo->rss_rc_options;
        $opts = explode(',', $opts);
        foreach ($opts as $opt) {
            $options[$opt] = 1;
            // FIXME
        }
    }
    // HTTP conditional get
    $mtime = $DBInfo->mtime();
    $lastmod = gmdate('D, d M Y H:i:s \\G\\M\\T', $mtime);
    $cache_ttl = !empty($DBInfo->rss_rc_ttl) ? $DBInfo->rss_rc_ttl : 60;
    /* 60 seconds */
    // make etag based on some options and mtime.
    $check_opts = array('quick', 'items', 'oe', 'diffs', 'raw', 'nomsg', 'summary');
    $check = array();
    foreach ($check_opts as $c) {
        if (isset($options[$c])) {
            $check[$c] = $options[$c];
        }
    }
    $etag = md5($mtime . $DBInfo->logo_img . serialize($check) . $cache_ttl . $options['id']);
    $headers = array();
    $headers[] = 'Pragma: cache';
    $maxage = $cache_ttl;
    $public = 'public';
    if ($options['id'] != 'Anonymous') {
        $public = 'private';
    }
    $headers[] = 'Cache-Control: ' . $public . ', max-age=' . $maxage;
    $headers[] = 'Last-Modified: ' . $lastmod;
    $headers[] = 'ETag: "' . $etag . '"';
    $need = http_need_cond_request($mtime, $lastmod, $etag);
    if (!$need) {
        $headers[] = 'HTTP/1.0 304 Not Modified';
    }
    foreach ($headers as $h) {
        header($h);
    }
    if (!$need) {
        @ob_end_clean();
        return;
    }
    $cache = new Cache_Text('rss_rc');
    $cache_delay = min($cache_ttl, 30);
    $mtime = $cache->mtime($etag);
    $val = false;
    if (empty($formatter->refresh)) {
        if (($val = $cache->fetch($etag)) !== false and $DBInfo->checkUpdated($mtime, $cache_delay)) {
            header("Content-Type: text/xml");
            echo $val;
            return;
        }
    }
    // need to update cache
    if ($val !== false and $cache->exists($etag . '.lock')) {
        header("Content-Type: text/xml");
        echo $val . '<!-- cached at ' . date('Y-m-d H:i:s', $mtime) . ' -->';
        return;
    }
    if ($cache->exists($etag . '.lock')) {
        header("Content-Type: text/xml");
        echo '';
        return;
    }
    $cache->update($etag . '.lock', array('lock'), 5);
    // 5s lock
    $time_current = time();
    #  $secs_per_day= 60*60*24;
    #  $days_to_show= 30;
    #  $time_cutoff= $time_current - ($days_to_show * $secs_per_day);
    $URL = qualifiedURL($formatter->prefix);
    $img_url = qualifiedURL($DBInfo->logo_img);
    $url = qualifiedUrl($formatter->link_url("RecentChanges"));
    $channel = <<<CHANNEL
<channel rdf:about="{$URL}">
  <title>{$DBInfo->sitename}</title>
  <link>{$url}</link>
  <description>RecentChanges at {$DBInfo->sitename}</description>
  <image rdf:resource="{$img_url}"></image>
  <items>
  <rdf:Seq>

CHANNEL;
    $items = "";
    $ratchet_day = FALSE;
    if (!$lines) {
        $lines = array();
    }
    foreach ($lines as $line) {
        $parts = explode("\t", $line);
        $page_name = $DBInfo->keyToPagename($parts[0]);
        // hide log
        if (!empty($members) && !in_array($options['id'], $members) && !empty($Config['ruleset']['hidelog'])) {
            if (in_array($page_name, $Config['ruleset']['hidelog'])) {
                continue;
            }
        }
        $addr = $parts[1];
        $ed_time = $parts[2];
        $user = $parts[4];
        $log = _stripslashes($parts[5]);
        $act = rtrim($parts[6]);
        #    if ($ed_time < $time_cutoff)
        #      break;
        $url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name)));
        $diff_url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name), '?action=diff'));
        $extra = "<br /><a href='{$diff_url}'>" . _("show changes") . "</a>\n";
        if (!$DBInfo->hasPage($page_name)) {
            $status = 'deleted';
            $html = '<![CDATA[' . "<a href='{$url}'>" . $page_name . "</a> is deleted" . ']]>' . "\n";
        } else {
            $status = 'updated';
            if (!empty($options['diffs'])) {
                $p = new WikiPage($page_name);
                $f = new Formatter($p);
                $options['raw'] = 1;
                $options['nomsg'] = 1;
                $html = $f->macro_repl('Diff', '', $options);
                if (!$html) {
                    ob_start();
                    $f->send_page('', array('fixpath' => 1));
                    #$f->send_page('');
                    $html = ob_get_contents();
                    ob_end_clean();
                    $extra = '';
                }
                $html = str_replace(']', '&#93;', $html);
                $html = "<![CDATA[" . $html . $extra . "]]>";
                #$html=strtr($html.$extra,array('&'=>'&amp;','<'=>'&lt;'));
            } else {
                if (!empty($options['summary'])) {
                    $p = new WikiPage($page_name);
                    $f = new Formatter($p);
                    $f->section_edit = 0;
                    $f->sister_on = 0;
                    $f->perma_icon = '';
                    $options['nomsg'] = 1;
                    $b = $p->_get_raw_body();
                    $chunks = preg_split('/\\n#{4,}/', $b);
                    # summary breaker is ####
                    ob_start();
                    if ($chunks) {
                        $f->send_page($chunks[0], array('fixpath' => 1));
                    } else {
                        $f->send_page('', array('fixpath' => 1));
                    }
                    #$f->send_page('');
                    $html = ob_get_contents();
                    ob_end_clean();
                    $chunks = preg_split('/<!-- break -->/', $html);
                    # <!-- break -->
                    if ($chunks[0]) {
                        $html = $chunks[0];
                    }
                    $html = str_replace(']', '&#93;', $html);
                    $html = "<![CDATA[" . $html . "]]>";
                } else {
                    $html = str_replace('&', '&amp;', $log);
                }
            }
        }
        $zone = "+00:00";
        $date = gmdate("Y-m-d\\TH:i:s", $ed_time) . $zone;
        #$datetag = gmdate("YmdHis",$ed_time);
        $channel .= "<rdf:li rdf:resource=\"{$url}\"></rdf:li>\n";
        $valid_page_name = preg_replace('/&(?!#?\\w+;)/', '&amp;', _html_escape($page_name));
        $items .= "<item rdf:about=\"{$url}\">\n";
        $items .= "  <title>{$valid_page_name}</title>\n";
        $items .= "  <link>{$url}</link>\n";
        $items .= "  <description>{$html}</description>\n";
        $items .= "  <dc:date>{$date}</dc:date>\n";
        $items .= "<dc:creator>{$user}</dc:creator>\n";
        $items .= "<dc:contributor>{$user}</dc:contributor>\n";
        #    $items.="     <dc:contributor>\n     <rdf:Description>\n"
        #          ."     <rdf:value>$user</rdf:value>\n"
        #          ."     </rdf:Description>\n     </dc:contributor>\n";
        $items .= "     <wiki:status>{$status}</wiki:status>\n";
        $items .= "     <wiki:diff>{$diff_url}</wiki:diff>\n";
        $items .= "</item>\n";
    }
    $url = qualifiedUrl($formatter->link_url($DBInfo->frontpage));
    $channel .= <<<FOOT
    </rdf:Seq>
  </items>
</channel>
<image rdf:about="{$img_url}">
<title>{$DBInfo->sitename}</title>
<link>{$url}</link>
<url>{$img_url}</url>
</image>

FOOT;
    $url = qualifiedUrl($formatter->link_url("FindPage"));
    $form = <<<FORM
<textinput>
<title>Search</title>
<link>{$url}</link>
<name>goto</name>
</textinput>

FORM;
    $new = "";
    if (!empty($options['oe']) and strtolower($options['oe']) != $DBInfo->charset) {
        $charset = $options['oe'];
        if (function_exists('iconv')) {
            $out = $head . $channel . $items . $form;
            $new = iconv($DBInfo->charset, $charset, $out);
            if (!$new) {
                $charset = $DBInfo->charset;
            }
        }
    } else {
        $charset = $DBInfo->charset;
    }
    $head = <<<HEAD
<?xml version="1.0" encoding="{$charset}"?>
<?xml-stylesheet href="{$DBInfo->url_prefix}/css/_feed.css" type="text/css"?>
<rdf:RDF xmlns="http://purl.org/rss/1.0/"
\txmlns:wiki="http://purl.org/rss/1.0/modules/wiki/"
\txmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
\txmlns:xlink="http://www.w3.org/1999/xlink"
\txmlns:dc="http://purl.org/dc/elements/1.1/">
<!--
    Add "diffs=1" to add change diffs to the description of each items.
    Add "summary=1" to add summary to the description of each items.
    Add "oe=utf-8" to convert the charset of this rss to UTF-8.
-->

HEAD;
    header("Content-Type: text/xml");
    if ($new) {
        $out = $head . $new;
    } else {
        $out = $head . $channel . $items . $form;
    }
    $out .= "</rdf:RDF>\n";
    echo $out;
    $cache->update($etag, $out);
    $cache->remove($etag . '.lock');
}
Esempio n. 5
0
function do_atom($formatter, $options)
{
    global $DBInfo, $Config;
    global $_release;
    define('ATOM_DEFAULT_DAYS', 7);
    // get members to hide log
    $members = $DBInfo->members;
    $days = $DBInfo->rc_days ? $DBInfo->rc_days : ATOM_DEFAULT_DAYS;
    $options['quick'] = 1;
    if ($options['c']) {
        $options['items'] = $options['c'];
    }
    $lines = $DBInfo->editlog_raw_lines($days, $options);
    // HTTP conditional get
    $mtime = $DBInfo->mtime();
    $lastmod = gmdate('D, d M Y H:i:s \\G\\M\\T', $mtime);
    $cache_ttl = !empty($DBInfo->atom_ttl) ? $DBInfo->atom_ttl : 60 * 30;
    /* 30 minutes */
    // make etag based on some options and mtime.
    $check_opts = array('quick', 'items', 'c');
    $check = array();
    foreach ($check_opts as $c) {
        if (isset($options[$c])) {
            $check[$c] = $options[$c];
        }
    }
    $etag = md5($mtime . $DBInfo->logo_img . serialize($check) . $cache_ttl . $options['id']);
    $headers = array();
    $headers[] = 'Pragma: cache';
    $maxage = $cache_ttl;
    $public = 'public';
    if ($options['id'] != 'Anonymous') {
        $public = 'private';
    }
    $headers[] = 'Cache-Control: ' . $public . ', max-age=' . $maxage;
    $headers[] = 'Last-Modified: ' . $lastmod;
    $headers[] = 'ETag: "' . $etag . '"';
    $need = http_need_cond_request($mtime, $lastmod, $etag);
    if (!$need) {
        $headers[] = 'HTTP/1.0 304 Not Modified';
    }
    foreach ($headers as $h) {
        header($h);
    }
    if (!$need) {
        @ob_end_clean();
        return;
    }
    $cache = new Cache_Text('atom');
    $cache_delay = min($cache_ttl, 30);
    $mtime = $cache->mtime($etag);
    $time_current = time();
    $val = false;
    if (empty($formatter->refresh)) {
        if (($val = $cache->fetch($etag)) !== false and $DBInfo->checkUpdated($mtime, $cache_delay)) {
            header("Content-Type: application/xml");
            echo $val;
            return;
        }
    }
    // need to update cache
    if ($val !== false and $cache->exists($etag . '.lock')) {
        header("Content-Type: application/xml");
        echo $val . '<!-- cached at ' . date('Y-m-d H:i:s', $mtime) . ' -->';
        return;
    }
    if ($cache->exists($etag . '.lock')) {
        header("Content-Type: application/xml");
        echo '';
        return;
    }
    $cache->update($etag . '.lock', array('lock'), 30);
    // 30s lock
    $URL = qualifiedURL($formatter->prefix);
    $img_url = qualifiedURL($DBInfo->logo_img);
    $url = qualifiedUrl($formatter->link_url($DBInfo->frontpage));
    $surl = qualifiedUrl($formatter->link_url($options['page'] . '?action=atom'));
    $channel = <<<CHANNEL
  <title>{$DBInfo->sitename}</title>
  <link href="{$url}"></link>
  <link rel="self" type="application/atom+xml" href="{$surl}" />
  <subtitle>RecentChanges at {$DBInfo->sitename}</subtitle>
  <generator version="{$_release}">MoniWiki Atom feeder</generator>

CHANNEL;
    $items = "";
    $ratchet_day = FALSE;
    if (!$lines) {
        $lines = array();
    }
    foreach ($lines as $line) {
        $parts = explode("\t", $line);
        $page_name = $DBInfo->keyToPagename($parts[0]);
        // hide log
        if (!empty($members) && !in_array($options['id'], $members) && !empty($Config['ruleset']['hidelog'])) {
            if (in_array($page_name, $Config['ruleset']['hidelog'])) {
                continue;
            }
        }
        $addr = $parts[1];
        $ed_time = $parts[2];
        $user = $parts[4];
        $user_uri = '';
        if ($user != 'Anonymous' && $DBInfo->hasPage($user)) {
            $user_uri = $formatter->link_url(_rawurlencode($user), "", $user);
            $user_uri = '<uri>' . $user_uri . '</uri>';
        }
        $log = _stripslashes($parts[5]);
        $act = rtrim($parts[6]);
        $url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name)));
        $diff_url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name), '?action=diff'));
        $extra = "<br /><a href='{$diff_url}'>" . _("show changes") . "</a>\n";
        $content = '';
        if (!$DBInfo->hasPage($page_name)) {
            $status = 'deleted';
            $content = "<content type='html'><a href='{$url}'>{$page_name}</a> is deleted</content>\n";
        } else {
            $status = 'updated';
            if ($options['diffs']) {
                $p = new WikiPage($page_name);
                $f = new Formatter($p);
                $options['raw'] = 1;
                $options['nomsg'] = 1;
                $html = $f->macro_repl('Diff', '', $options);
                if (!$html) {
                    ob_start();
                    $f->send_page('', array('fixpath' => 1));
                    #$f->send_page('');
                    $html = ob_get_contents();
                    ob_end_clean();
                    $extra = '';
                }
                $content = "  <content type='xhtml'><div xmlns='http://www.w3.org/1999/xhtml'>{$html}</content>\n";
            } else {
                if ($log) {
                    $html = str_replace('&', '&amp;', $log);
                    $content = "<content type='text'>" . $html . "</content>\n";
                } else {
                    $content = "<content type='text'>updated</content>\n";
                }
            }
        }
        $zone = '+00:00';
        $date = gmdate("Y-m-d\\TH:i:s", $ed_time) . $zone;
        if (!isset($updated)) {
            $updated = $date;
        }
        #$datetag = gmdate("YmdHis",$ed_time);
        $valid_page_name = str_replace('&', '&amp;', $page_name);
        $items .= "<entry>\n";
        $items .= "  <title>{$valid_page_name}</title>\n";
        $items .= "  <link href='{$url}'></link>\n";
        $items .= '  ' . $content;
        $items .= "  <author><name>{$user}</name>{$user_uri}</author>\n";
        $items .= "  <updated>{$date}</updated>\n";
        $items .= "  <contributor><name>{$user}</name>{$user_uri}</contributor>\n";
        $items .= "</entry>\n";
    }
    $updated = "  <updated>{$updated}</updated>\n";
    $new = "";
    if ($options['oe'] and strtolower($options['oe']) != $DBInfo->charset) {
        $charset = $options['oe'];
        if (function_exists('iconv')) {
            $out = $head . $channel . $items . $form;
            $new = iconv($DBInfo->charset, $charset, $out);
            if (!$new) {
                $charset = $DBInfo->charset;
            }
        }
    } else {
        $charset = $DBInfo->charset;
    }
    $head = <<<HEAD
<?xml version="1.0" encoding="{$charset}"?>
<!--<?xml-stylesheet href="{$DBInfo->url_prefix}/css/_feed.css" type="text/css"?>-->
<feed xmlns="http://www.w3.org/2005/Atom">
<!--
    Add "diffs=1" to add change diffs to the description of each items.
    Add "oe=utf-8" to convert the charset of this rss to UTF-8.
-->

HEAD;
    header("Content-Type: application/xml");
    $out = '';
    if ($new) {
        $out = $head . $new;
    } else {
        $out = $head . $channel . $updated . $items . $form;
    }
    $out .= "</feed>\n";
    echo $out;
    $cache->update($etag, $out);
    $cache->remove($etag . '.lock');
}
Esempio n. 6
0
function wiki_main($options)
{
    global $DBInfo, $Config;
    $pagename = isset($options['pagename'][0]) ? $options['pagename'] : $DBInfo->frontpage;
    # get primary variables
    if (isset($_SERVER['REQUEST_METHOD']) and $_SERVER['REQUEST_METHOD'] == 'POST') {
        // reset some reserved variables
        if (isset($_POST['retstr'])) {
            unset($_POST['retstr']);
        }
        if (isset($_POST['header'])) {
            unset($_POST['header']);
        }
        # hack for TWiki plugin
        $action = '';
        if (!empty($_FILES['filepath']['name'])) {
            $action = 'draw';
        }
        if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
            # hack for Oekaki: PageName----action----filename
            list($pagename, $action, $value) = explode('----', $pagename, 3);
            $options['value'] = $value;
        } else {
            $value = !empty($_POST['value']) ? $_POST['value'] : '';
            $action = !empty($_POST['action']) ? $_POST['action'] : $action;
            if (empty($action)) {
                $dum = explode('----', $pagename, 3);
                if (isset($dum[0][0]) && isset($dum[1][0])) {
                    $pagename = trim($dum[0]);
                    $action = trim($dum[1]);
                    $value = isset($dum[2][0]) ? $dum[2] : '';
                }
            }
        }
        $goto = !empty($_POST['goto']) ? $_POST['goto'] : '';
        $popup = !empty($_POST['popup']) ? 1 : 0;
        // ignore invalid POST actions
        if (empty($goto) and empty($action)) {
            header('Status: 405 Not allowed');
            return;
        }
    } else {
        // reset some reserved variables
        if (isset($_GET['retstr'])) {
            unset($_GET['retstr']);
        }
        if (isset($_GET['header'])) {
            unset($_GET['header']);
        }
        $action = !empty($_GET['action']) ? $_GET['action'] : '';
        $value = isset($_GET['value'][0]) ? $_GET['value'] : '';
        $goto = isset($_GET['goto'][0]) ? $_GET['goto'] : '';
        $rev = !empty($_GET['rev']) ? $_GET['rev'] : '';
        if ($options['id'] == 'Anonymous') {
            $refresh = 0;
        } else {
            $refresh = !empty($_GET['refresh']) ? $_GET['refresh'] : '';
        }
        $popup = !empty($_GET['popup']) ? 1 : 0;
    }
    // parse action
    // action=foobar, action=foobar/macro, action=foobar/json etc.
    $full_action = $action;
    $action_mode = '';
    if (($p = strpos($action, '/')) !== false) {
        $full_action = strtr($action, '/', '-');
        $action_mode = substr($action, $p + 1);
        $action = substr($action, 0, $p);
    }
    $options['page'] = $pagename;
    $options['action'] =& $action;
    $reserved = array('call', 'prefix');
    foreach ($reserved as $k) {
        unset($options[$k]);
    }
    // unset all reserved
    // check pagename length
    $key = $DBInfo->pageToKeyname($pagename);
    if (!empty($options['action']) && strlen($key) > 255) {
        $i = 252;
        // 252 + reserved 3 (.??) = 255
        $newname = $DBInfo->keyToPagename(substr($key, 0, 252));
        $j = mb_strlen($newname, $Config['charset']);
        $j--;
        do {
            $newname = mb_substr($pagename, 0, $j, $Config['charset']);
            $key = $DBInfo->pageToKeyname($newname);
        } while (strlen($key) > 248 && --$j > 0);
        $options['page'] = $newname;
        $options['orig_pagename'] = $pagename;
        // original page name
        $pagename = $newname;
    } else {
        $options['orig_pagename'] = '';
    }
    if (function_exists('local_pre_check')) {
        local_pre_check($action, $options);
    }
    // load ruleset
    if (!empty($Config['config_ruleset'])) {
        $ruleset_file = 'config/ruleset.' . $Config['config_ruleset'] . '.php';
        if (file_exists($ruleset_file)) {
            $ruleset = load_ruleset($ruleset_file);
            $Config['ruleset'] = $ruleset;
        }
        // is it robot ?
        if (!empty($ruleset['allowedrobot'])) {
            if (empty($_SERVER['HTTP_USER_AGENT'])) {
                $options['is_robot'] = 1;
            } else {
                $options['is_robot'] = is_allowed_robot($ruleset['allowedrobot'], $_SERVER['HTTP_USER_AGENT']);
            }
        }
        // setup staff members
        if (!empty($ruleset['staff'])) {
            $DBInfo->members = array_merge($DBInfo->members, $ruleset['staff']);
        }
    }
    $page = $DBInfo->getPage($pagename);
    $page->is_static = false;
    // FIXME
    $pis = array();
    // get PI cache
    if ($page->exists()) {
        $page->pi = $pis = $page->get_instructions('', array('refresh' => $refresh));
        // set some PIs for robot
        if (!empty($options['is_robot'])) {
            $DBInfo->use_sectionedit = 0;
            # disable section edit
            $page->is_static = true;
        } else {
            if ($_SERVER['REQUEST_METHOD'] == 'GET' or $_SERVER['REQUEST_METHOD'] == 'HEAD') {
                if (empty($action) and empty($refresh)) {
                    $page->is_static = empty($pis['#nocache']) && empty($pis['#dynamic']);
                }
            }
        }
    }
    // HEAD support for robots
    if (empty($action) and !empty($_SERVER['REQUEST_METHOD']) and $_SERVER['REQUEST_METHOD'] == 'HEAD') {
        if (!$page->exists()) {
            header("HTTP/1.1 404 Not found");
            header("Status: 404 Not found");
        } else {
            if ($page->is_static or is_static_action($options)) {
                $mtime = $page->mtime();
                $etag = $page->etag($options);
                $lastmod = gmdate('D, d M Y H:i:s \\G\\M\\T', $mtime);
                header('Last-Modified: ' . $lastmod);
                if (!empty($action)) {
                    $etag = '"' . $etag . '"';
                    header('ETag: ' . $etag);
                }
                // checksum request
                if (isset($_SERVER['HTTP_X_GET_CHECKSUM'])) {
                    header('X-Checksum: md5-' . md5($page->get_raw_body()));
                }
            }
        }
        return;
    }
    if (is_static_action($options) or !empty($DBInfo->use_conditional_get) and $page->is_static) {
        $mtime = $page->mtime();
        $etag = $page->etag($options);
        $lastmod = gmdate('D, d M Y H:i:s \\G\\M\\T', $mtime);
        $need = http_need_cond_request($mtime, $lastmod, $etag);
        if (!$need) {
            @ob_end_clean();
            $headers = array();
            $headers[] = 'HTTP/1.0 304 Not Modified';
            $headers[] = 'Last-Modified: ' . $lastmod;
            foreach ($headers as $header) {
                header($header);
            }
            return;
        }
    }
    $formatter = new Formatter($page, $options);
    $formatter->refresh = !empty($refresh) ? $refresh : '';
    $formatter->popup = !empty($popup) ? $popup : '';
    $formatter->tz_offset = $options['tz_offset'];
    // check blocklist/whitelist for block_actions
    $act = strtolower($action);
    while (!empty($DBInfo->block_actions) && !empty($ruleset) && in_array($act, $DBInfo->block_actions)) {
        require_once 'lib/checkip.php';
        // check whitelist
        if (isset($ruleset['whitelist']) && check_ip($ruleset['whitelist'], $_SERVER['REMOTE_ADDR'])) {
            break;
        }
        $res = null;
        // check blacklist
        if (isset($ruleset['blacklist']) && check_ip($ruleset['blacklist'], $_SERVER['REMOTE_ADDR']) || isset($ruleset['blacklist.ranges']) && search_network($ruleset['blacklist.ranges'], $_SERVER['REMOTE_ADDR'])) {
            $res = true;
        } else {
            if (!empty($DBInfo->use_dynamic_blacklist)) {
                require_once 'plugin/ipinfo.php';
                $blacklist = get_cached_temporary_blacklist();
                $retval = array();
                $ret = array('retval' => &$retval);
                $res = search_network($blacklist, $_SERVER['REMOTE_ADDR'], $ret);
                if ($res !== false) {
                    // retrieve found
                    $ac = new Cache_Text('ipblock');
                    $info = $ac->fetch($retval, 0, $ret);
                    if ($info !== false) {
                        if (!$info['suspended']) {
                            // whitelist IP
                            break;
                        }
                        $res = true;
                    } else {
                        $ac->remove($retval);
                        // expired IP entry.
                        $res = false;
                    }
                }
            }
        }
        // show warning message
        if ($res) {
            $options['notice'] = _("Your IP is in the blacklist");
            $options['msg'] = _("Please contact WikiMasters");
            $options['msgtype'] = 'warn';
            if (!empty($DBInfo->edit_actions) and in_array($act, $DBInfo->edit_actions)) {
                $options['action'] = $action = 'edit';
            } else {
                if ($act != 'edit') {
                    $options['action'] = $action = 'show';
                }
            }
            break;
        }
        // check kiwirian
        if (isset($ruleset['kiwirian']) && in_array($options['id'], $ruleset['kiwirian'])) {
            $options['title'] = _("You are blocked in this wiki");
            $options['msg'] = _("Please contact WikiMasters");
            do_invalid($formatter, $options);
            return false;
        }
        break;
    }
    // set robot class
    if (!empty($options['is_robot'])) {
        if (!empty($DBInfo->security_class_robot)) {
            $class = 'Security_' . $DBInfo->security_class_robot;
            include_once 'plugin/security/' . $DBInfo->security_class_robot . '.php';
        } else {
            $class = 'Security_robot';
            include_once 'plugin/security/robot.php';
        }
        $DBInfo->security = new $class($DBInfo);
        // is it allowed to robot ?
        if (!$DBInfo->security->is_allowed($action, $options)) {
            $action = 'show';
            if (!empty($action_mode)) {
                return '[]';
            }
        }
        $DBInfo->extra_macros = '';
    }
    while (empty($action) or $action == 'show') {
        if (isset($value[0])) {
            # ?value=Hello
            $options['value'] = $value;
            do_goto($formatter, $options);
            return true;
        } else {
            if (isset($goto[0])) {
                # ?goto=Hello
                $options['value'] = $goto;
                do_goto($formatter, $options);
                return true;
            }
        }
        if (!$page->exists()) {
            if (isset($options['retstr'])) {
                return false;
            }
            if (!empty($DBInfo->auto_search) && $action != 'show' && ($p = getPlugin($DBInfo->auto_search))) {
                $action = $DBInfo->auto_search;
                break;
            }
            // call notfound action
            $action = 'notfound';
            break;
        }
        # render this page
        if (isset($_GET['redirect']) and !empty($DBInfo->use_redirect_msg) and $action == 'show') {
            $redirect = $_GET['redirect'];
            $options['msg'] = '<h3>' . sprintf(_("Redirected from page \"%s\""), $formatter->link_tag(_rawurlencode($redirect), '?action=show', $redirect)) . "</h3>";
        }
        if (empty($action)) {
            $options['pi'] = 1;
        }
        # protect a recursivly called #redirect
        if (!empty($DBInfo->control_read) and !$DBInfo->security->is_allowed('read', $options)) {
            $options['action'] = 'read';
            do_invalid($formatter, $options);
            return;
        }
        $formatter->pi = $formatter->page->get_instructions();
        if (!empty($DBInfo->body_attr)) {
            $options['attr'] = $DBInfo->body_attr;
        }
        $ret = $formatter->send_header('', $options);
        if (empty($options['is_robot'])) {
            if ($DBInfo->use_counter) {
                $DBInfo->counter->incCounter($pagename, $options);
            }
            if (!empty($DBInfo->use_referer) and isset($_SERVER['HTTP_REFERER'])) {
                log_referer($_SERVER['HTTP_REFERER'], $pagename);
            }
        }
        $formatter->send_title("", "", $options);
        $formatter->write("<div id='wikiContent'>\n");
        if (isset($options['timer']) and is_object($options['timer'])) {
            $options['timer']->Check("init");
        }
        // force #nocache for #redirect pages
        if (isset($formatter->pi['#redirect'][0])) {
            $formatter->pi['#nocache'] = 1;
        }
        $extra_out = '';
        $options['pagelinks'] = 1;
        if (!empty($Config['cachetime']) and $Config['cachetime'] > 0 and empty($formatter->pi['#nocache'])) {
            $cache = new Cache_text('pages', array('ext' => 'html'));
            $mcache = new Cache_text('dynamic_macros');
            $mtime = $cache->mtime($pagename);
            $now = time();
            $check = $now - $mtime;
            $_macros = null;
            if ($cache->mtime($pagename) < $formatter->page->mtime()) {
                $formatter->refresh = 1;
            }
            // force update
            $valid = false;
            $delay = !empty($DBInfo->default_delaytime) ? $DBInfo->default_delaytime : 0;
            if (empty($formatter->refresh) and $DBInfo->checkUpdated($mtime, $delay) and $check < $Config['cachetime']) {
                if ($mcache->exists($pagename)) {
                    $_macros = $mcache->fetch($pagename);
                }
                // FIXME TODO: check postfilters
                if (0 && empty($_macros)) {
                    #$out = $cache->fetch($pagename);
                    $valid = $cache->fetch($pagename, '', array('print' => 1));
                } else {
                    $out = $cache->fetch($pagename);
                    $valid = $out !== false;
                }
                $mytime = gmdate("Y-m-d H:i:s", $mtime + $options['tz_offset']);
                $extra_out = "<!-- Cached at {$mytime} -->";
            }
            if (!$valid) {
                $formatter->_macrocache = 1;
                ob_start();
                $formatter->send_page('', $options);
                flush();
                $out = ob_get_contents();
                ob_end_clean();
                $formatter->_macrocache = 0;
                $_macros = $formatter->_dynamic_macros;
                if (!empty($_macros)) {
                    $mcache->update($pagename, $_macros);
                }
                if (isset($out[0])) {
                    $cache->update($pagename, $out);
                }
            }
            if (!empty($_macros)) {
                $mrule = array();
                $mrepl = array();
                foreach ($_macros as $m => $v) {
                    if (!is_array($v)) {
                        continue;
                    }
                    $mrule[] = '@@' . $v[0] . '@@';
                    $options['mid'] = $v[1];
                    $mrepl[] = $formatter->macro_repl($m, '', $options);
                    // XXX
                }
                echo $formatter->get_javascripts();
                $out = str_replace($mrule, $mrepl, $out);
                // no more dynamic macros found
                if (empty($formatter->_dynamic_macros)) {
                    // update contents
                    $cache->update($pagename, $out);
                    // remove dynamic macros cache
                    $mcache->remove($pagename);
                }
            }
            if ($options['id'] != 'Anonymous') {
                $args['refresh'] = 1;
            }
            // add refresh menu
        } else {
            ob_start();
            $formatter->send_page('', $options);
            flush();
            $out = ob_get_contents();
            ob_end_clean();
        }
        // fixup to use site specific thumbwidth
        if (!empty($Config['site_thumb_width']) and $Config['site_thumb_width'] != $DBInfo->thumb_width) {
            $opts = array('thumb_width' => $Config['site_thumb_width']);
            $out = $formatter->postfilter_repl('imgs_for_mobile', $out, $opts);
        }
        echo $out, $extra_out;
        // automatically set #dynamic PI
        if (empty($formatter->pi['#dynamic']) and !empty($formatter->_dynamic_macros)) {
            $pis = $formatter->pi;
            if (empty($pis['raw'])) {
                // empty PIs
                $pis = array();
            } else {
                if (isset($pis['#format']) and !preg_match('/#format\\s/', $pis['raw'])) {
                    // #format not found in PIs
                    unset($pis['#format']);
                }
            }
            $pis['#dynamic'] = 1;
            // internal instruction
            $pi_cache = new Cache_text('PI');
            $pi_cache->update($formatter->page->name, $pis);
        } else {
            if (empty($formatter->_dynamic_macros) and !empty($formatter->pi['#dynamic'])) {
                $pi_cache = new Cache_text('PI');
                $pi_cache->remove($formatter->page->name);
                // reset PI
                $mcache->remove($pagename);
                // remove macro cache
                if (isset($out[0])) {
                    $cache->update($pagename, $out);
                }
                // update cache content
            }
        }
        if (isset($options['timer']) and is_object($options['timer'])) {
            $options['timer']->Check("send_page");
        }
        $formatter->write("<!-- wikiContent --></div>\n");
        if (!empty($DBInfo->extra_macros) and $formatter->pi['#format'] == $DBInfo->default_markup) {
            if (!empty($formatter->pi['#nocomment'])) {
                $options['nocomment'] = 1;
                $options['notoolbar'] = 1;
            }
            $options['mid'] = 'dummy';
            echo '<div id="wikiExtra">' . "\n";
            $mout = '';
            $extra = array();
            if (is_array($DBInfo->extra_macros)) {
                $extra = $DBInfo->extra_macros;
            } else {
                $extra[] = $DBInfo->extra_macros;
            }
            // XXX
            if (!empty($formatter->pi['#comment'])) {
                array_unshift($extra, 'Comment');
            }
            foreach ($extra as $macro) {
                $mout .= $formatter->macro_repl($macro, '', $options);
            }
            echo $formatter->get_javascripts();
            echo $mout;
            echo '</div>' . "\n";
        }
        $args['editable'] = 1;
        $formatter->send_footer($args, $options);
        return;
    }
    $act = $action;
    if (!empty($DBInfo->myplugins) and array_key_exists($action, $DBInfo->myplugins)) {
        $act = $DBInfo->myplugins[$action];
    }
    if ($act) {
        $options['noindex'] = true;
        $options['custom'] = '';
        $options['help'] = '';
        $options['value'] = $value;
        $a_allow = $DBInfo->security->is_allowed($act, $options);
        if (!empty($action_mode)) {
            $myopt = $options;
            $myopt['explicit'] = 1;
            $f_allow = $DBInfo->security->is_allowed($full_action, $myopt);
            # check if hello/ajax is defined or not
            if ($f_allow === false && $a_allow) {
                $f_allow = $a_allow;
            }
            # follow action permission if it is not defined explicitly.
            if (!$f_allow) {
                $args = array('action' => $action);
                $args['allowed'] = $options['allowed'] = $f_allow;
                if ($f_allow === false) {
                    $title = sprintf(_("%s action is not found."), $action);
                } else {
                    $title = sprintf(_("Invalid %s action."), $action_mode);
                }
                if ($action_mode == 'ajax') {
                    $args['title'] = $title;
                    return ajax_invalid($formatter, $args);
                }
                $options['title'] = $title;
                return do_invalid($formatter, $options);
            }
        } else {
            if (!$a_allow) {
                $options['allowed'] = $a_allow;
                if ($options['custom'] != '' and method_exists($DBInfo->security, $options['custom'])) {
                    $options['action'] = $action;
                    if ($action) {
                        call_user_func(array(&$DBInfo->security, $options['custom']), $formatter, $options);
                    }
                    return;
                }
                return do_invalid($formatter, $options);
            } else {
                if ($_SERVER['REQUEST_METHOD'] == "POST" and $DBInfo->security->is_protected($act, $options) and !$DBInfo->security->is_valid_password($_POST['passwd'], $options)) {
                    # protect some POST actions and check a password
                    $title = sprintf(_("Fail to \"%s\" !"), $action);
                    $formatter->send_header("", $options);
                    $formatter->send_title($title, "", $options);
                    $formatter->send_page("== " . _("Please enter the valid password") . " ==");
                    $formatter->send_footer("", $options);
                    return;
                }
            }
        }
        $options['action_mode'] = '';
        if (!empty($action_mode) and in_array($action_mode, array('ajax', 'macro'))) {
            if ($_SERVER['REQUEST_METHOD'] == "POST") {
                $options = array_merge($_POST, $options);
            } else {
                $options = array_merge($_GET, $options);
            }
            $options['action_mode'] = $action_mode;
            if ($action_mode == 'ajax') {
                $formatter->ajax_repl($action, $options);
            } else {
                if (!empty($DBInfo->use_macro_as_action)) {
                    # XXX
                    echo $formatter->macro_repl($action, $options['value'], $options);
                } else {
                    do_invalid($formatter, $options);
                }
            }
            return;
        }
        // is it valid action ?
        $plugin = $pn = getPlugin($action);
        if ($plugin === '') {
            // action not found
            $plugin = $action;
        }
        if (!function_exists("do_post_" . $plugin) and !function_exists("do_" . $plugin) and $pn) {
            include_once "plugin/{$pn}.php";
        }
        if (function_exists("do_" . $plugin)) {
            if ($_SERVER['REQUEST_METHOD'] == "POST") {
                $options = array_merge($_POST, $options);
            } else {
                $options = array_merge($_GET, $options);
            }
            call_user_func("do_{$plugin}", $formatter, $options);
            return;
        } else {
            if (function_exists("do_post_" . $plugin)) {
                if ($_SERVER['REQUEST_METHOD'] == "POST") {
                    $options = array_merge($_POST, $options);
                } else {
                    # do_post_* set some primary variables as $options
                    $options['value'] = isset($_GET['value'][0]) ? $_GET['value'] : '';
                }
                call_user_func("do_post_{$plugin}", $formatter, $options);
                return;
            }
        }
        do_invalid($formatter, $options);
        return;
    }
}
Esempio n. 7
0
 function cache_instructions($pi, $params = array())
 {
     global $Config;
     global $DBInfo;
     $pagename = $this->name;
     // update aliases
     if (!empty($Config['use_alias'])) {
         $ac = new Cache_text('alias');
         // is it removed ?
         if ($ac->exists($pagename) and empty($pi['#alias']) and empty($pi['#title'])) {
             // remove aliases
             store_aliases($pagename, array());
         } else {
             if (!$ac->exists($pagename) or $ac->mtime($pagename) < $this->mtime() or !empty($_GET['update_alias'])) {
                 $as = array();
                 // parse #alias
                 if (!empty($pi['#alias'])) {
                     $as = get_csv($pi['#alias']);
                 }
                 // add #title as a alias
                 if (!empty($pi['#title'])) {
                     $as[] = $pi['#title'];
                 }
                 // update aliases
                 store_aliases($pagename, $as);
             }
         }
     }
     // update #redirect
     $rc = new Cache_Text('redirect');
     $old = $rc->fetch($pagename);
     if ($old or isset($pi['#redirect'][0])) {
         // update invert redirect index
         $rc2 = new Cache_Text('redirects');
         if (!empty($params['refresh']) or $old != $pi['#redirect']) {
             // update direct cache
             $rc->update($pagename, $pi['#redirect']);
             $nr = $pi['#redirect'];
             if (($p = strpos($nr, '#')) > 0) {
                 // get pagename only
                 //$anchor = substr($nr, $p);
                 $nr = substr($nr, 0, $p);
             }
             if (!isset($nr[0])) {
                 $rc->remove($pagename);
             } else {
                 if (!preg_match('@^https?://@', $nr)) {
                     // not a URL redirect
                     // add redirect links
                     $redirects = $rc2->fetch($nr);
                     if (empty($redirects)) {
                         $redirects = array();
                     }
                     $redirects = array_merge($redirects, array($pagename));
                     $rc2->update($nr, $redirects);
                 }
             }
             while ($old != '' and $old != false) {
                 // get pagename only
                 if (($p = strpos($old, '#')) > 0) {
                     //$anchor = substr($old, $p);
                     $old = substr($old, 0, $p);
                 }
                 if ($nr == $old) {
                     break;
                 }
                 // check A#s-1 ~ A#s-2 redirects
                 // delete redirect links
                 $l = $rc2->fetch($old);
                 if ($l !== false and is_array($l)) {
                     $redirects = array_diff($l, array($pagename));
                     if (empty($redirects)) {
                         $rc2->remove($old);
                     } else {
                         $rc2->update($old, $redirects);
                     }
                 }
                 break;
             }
         }
     }
     if (!empty($Config['use_keywords']) or !empty($Config['use_tagging']) or !empty($_GET['update_keywords'])) {
         $tcache = new Cache_text('keyword');
         $cache = new Cache_text('keywords');
         $cur = $tcache->fetch($pagename);
         if (empty($cur)) {
             $cur = array();
         }
         $keys = array();
         if (empty($pi['#keywords'])) {
             $tcache->remove($pagename);
         } else {
             $keys = explode(',', $pi['#keywords']);
             $keys = array_map('trim', $keys);
             if (!$tcache->exists($pagename) or $tcache->mtime($pagename) < $this->mtime() or !empty($_GET['update_keywords'])) {
                 $tcache->update($pagename, $keys);
             }
         }
         $adds = array_diff($keys, $cur);
         $dels = array_diff($cur, $keys);
         // merge new keywords
         foreach ($adds as $a) {
             if (!isset($a[0])) {
                 continue;
             }
             $l = $cache->fetch($a);
             if (!is_array($l)) {
                 $l = array();
             }
             $l = array_merge($l, array($pagename));
             $cache->update($a, $l);
         }
         // remove deleted keywords
         foreach ($dels as $d) {
             if (!isset($d[0])) {
                 continue;
             }
             $l = $cache->fetch($d);
             if (!is_array($l)) {
                 $l = array();
             }
             $l = array_diff($l, array($pagename));
             $cache->update($d, $l);
         }
     }
     if (!empty($pi['#title']) and !empty($Config['use_titlecache'])) {
         $tc = new Cache_text('title');
         $old = $tc->fetch($pagename);
         if (!isset($pi['#title'])) {
             $tc->remove($pagename);
         } else {
             if ($old != $pi['#title'] or !$tcache->exists($pagename) or !empty($_GET['update_title'])) {
                 $tc->update($pagename, $pi['#title']);
             }
         }
     }
     return;
 }