Пример #1
0
function do_highlight($formatter, $params = array())
{
    if (isset($params['value'])) {
        $expr = $params['value'];
    } else {
        if (isset($params['q'])) {
            $expr = $params['q'];
        }
    }
    $expr = _stripslashes($expr);
    $formatter->send_header('', $params);
    $formatter->send_title('', '', $params);
    flush();
    ob_start();
    $formatter->send_page();
    flush();
    $out = ob_get_contents();
    ob_end_clean();
    if (isset($expr[0])) {
        highlight_repl(null, true);
        $highlight = _preg_search_escape($expr);
        $out = preg_replace_callback('/((<[^>]*>)|(' . $highlight . '))/i', 'highlight_repl', $out);
        echo $out;
    } else {
        echo $out;
    }
    $args['editable'] = 1;
    $formatter->send_footer($args, $params);
}
Пример #2
0
 function hasSubscribePage($pagename)
 {
     if (!$this->info['email'] or !$this->info['subscribed_pages']) {
         return false;
     }
     $page_list = _preg_search_escape($this->info['subscribed_pages']);
     if (!trim($page_list)) {
         return false;
     }
     $page_lists = explode("\t", $page_list);
     $page_rule = '^' . join("\$|^", $page_lists) . '$';
     if (preg_match('/(' . $page_rule . ')/', $pagename)) {
         return true;
     }
     return false;
 }
Пример #3
0
function macro_FullSearch($formatter, $value = "", &$opts)
{
    global $DBInfo;
    $needle = $value;
    if ($value === true) {
        $needle = $value = $formatter->page->name;
        $options['noexpr'] = 1;
    } else {
        # for MoinMoin compatibility with [[FullSearch("blah blah")]]
        #$needle = preg_replace("/^('|\")([^\\1]*)\\1/","\\2",$value);
        $needle = $value;
    }
    // for pagination
    $offset = '';
    if (!empty($opts['offset']) and is_numeric($opts['offset'])) {
        if ($opts['offset'] > 0) {
            $offset = $opts['offset'];
        }
    }
    $url = $formatter->link_url($formatter->page->urlname);
    $fneedle = _html_escape($needle);
    $tooshort = !empty($DBInfo->fullsearch_tooshort) ? $DBInfo->fullsearch_tooshort : 2;
    $m1 = _("Display context of search results");
    $m2 = _("Search BackLinks only");
    $m3 = _("Case-sensitive searching");
    $msg = _("Go");
    $bchecked = !empty($DBInfo->use_backlinks) ? 'checked="checked"' : '';
    $form = <<<EOF
<form method='get' action='{$url}'>
   <input type='hidden' name='action' value='fullsearch' />
   <input name='value' size='30' value="{$fneedle}" />
   <span class='button'><input type='submit' class='button' value='{$msg}' /></span><br />
   <input type='checkbox' name='backlinks' value='1' {$bchecked} />{$m2}<br />
   <input type='checkbox' name='context' value='20' />{$m1}<br />
   <input type='checkbox' name='case' value='1' />{$m3}<br />
   </form>
EOF;
    if (!isset($needle[0]) or !empty($opts['form'])) {
        # or blah blah
        $opts['msg'] = _("No search text");
        return $form;
    }
    $opts['form'] = $form;
    # XXX
    $excl = array();
    $incl = array();
    if (!empty($opts['noexpr'])) {
        $tmp = preg_split("/\\s+/", $needle);
        $needle = $value = join('|', $tmp);
        $raw_needle = implode(' ', $tmp);
        $needle = preg_quote($needle);
    } else {
        if (empty($opts['backlinks'])) {
            $terms = preg_split('/((?<!\\S)[-+]?"[^"]+?"(?!\\S)|\\S+)/s', $needle, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
            $common_words = array('the', 'that', 'where', 'what', 'who', 'how', 'too', 'are');
            $common = array();
            foreach ($terms as $term) {
                if (trim($term) == '') {
                    continue;
                }
                if (preg_match('/^([-+]?)("?)([^\\2]+?)\\2$/', $term, $match)) {
                    $word = str_replace(array('\\', '.', '*'), '', $match[3]);
                    $len = strlen($word);
                    if (!$match[1] and $match[2] != '"') {
                        if ($len < $tooshort or in_array($word, $common_words)) {
                            $common[] = $word;
                            continue;
                        }
                    }
                    if ($match[1] == '-') {
                        $excl[] = $word;
                    } else {
                        $incl[] = $word;
                    }
                }
            }
            $needle = implode('|', $incl);
            $needle = _preg_search_escape($needle);
            $raw_needle = implode(' ', $incl);
            $test = validate_needle($needle);
            if ($test === false) {
                // invalid regex
                $tmp = array_map('preg_quote', $incl);
                $needle = implode('|', $tmp);
            }
            $excl_needle = implode('|', $excl);
            $test = validate_needle($excl_needle);
            if ($test2 === false) {
                // invalid regex
                $tmp = array_map('preg_quote', $excl);
                $excl_needle = implode('|', $tmp);
            }
        } else {
            $cneedle = _preg_search_escape($needle);
            $test = validate_needle($cneedle);
            if ($test === false) {
                $needle = preg_quote($needle);
            } else {
                $needle = $cneedle;
            }
        }
    }
    $test3 = trim($needle);
    if (!isset($test3[0])) {
        $opts['msg'] = _("Empty expression");
        return $form;
    }
    # set arena and sid
    if (!empty($opts['backlinks'])) {
        $arena = 'backlinks';
    } else {
        if (!empty($opts['keywords'])) {
            $arena = 'keywords';
        } else {
            $arena = 'fullsearch';
        }
    }
    if ($arena == 'fullsearch') {
        $sid = md5($value . 'v' . $offset);
    } else {
        $sid = $value;
    }
    $delay = !empty($DBInfo->default_delaytime) ? $DBInfo->default_delaytime : 0;
    # retrieve cache
    $fc = new Cache_text($arena);
    if (!$formatter->refresh and $fc->exists($sid)) {
        $data = $fc->fetch($sid);
        if (!empty($opts['backlinks'])) {
            // backlinks are not needed to check it.
            $hits = $data;
            // also fetch redirects
            $r = new Cache_Text('redirects');
            $redirects = $r->fetch($sid);
        } else {
            if (is_array($data)) {
                # check cache mtime
                $cmt = $fc->mtime($sid);
                # check update or not
                $dmt = $DBInfo->mtime();
                if ($dmt > $cmt + $delay) {
                    # XXX crude method
                    $data = array();
                } else {
                    # XXX smart but incomplete method
                    if (isset($data['hits'])) {
                        $hits =& $data['hits'];
                    } else {
                        $hits =& $data;
                    }
                    foreach ($hits as $p => $c) {
                        $mp = $DBInfo->getPage($p);
                        $mt = $mp->mtime();
                        if ($mt > $cmt + $delay) {
                            $data = array();
                            break;
                        }
                    }
                }
                if (isset($data['searched'])) {
                    extract($data);
                } else {
                    if (!empty($data)) {
                        $hits = $data;
                    }
                }
            }
        }
    }
    $pattern = '/' . $needle . '/';
    if (!empty($excl_needle)) {
        $excl_pattern = '/' . $excl_needle . '/';
    }
    if (!empty($opts['case'])) {
        $pattern .= "i";
        $excl_pattern .= "i";
    }
    if (isset($hits)) {
        if (in_array($arena, array('backlinks', 'keywords'))) {
            $test = key($hits);
            if (is_int($test) and $hits[$test] != -1) {
                // fix compatible issue for keywords, backlinks
                $hits = array_flip($hits);
                foreach ($hits as $k => $v) {
                    $hits[$k] = -1;
                }
                reset($hits);
            }
            // check invert redirect index
            if (!empty($redirects)) {
                $redirects = array_flip($redirects);
                ksort($redirects);
                foreach ($redirects as $k => $v) {
                    $hits[$k] = -2;
                }
                reset($hits);
            }
        }
        //continue;
    } else {
        $hits = array();
        set_time_limit(0);
        if (!empty($opts['backlinks']) and empty($DBInfo->use_backlink_search)) {
            $hits = array();
        } else {
            if (!empty($opts['keywords']) and empty($DBInfo->use_keyword_search)) {
                $hits = array();
            } else {
                if (!empty($opts['backlinks'])) {
                    $pages = $DBInfo->getPageLists();
                    #$opts['context']=-1; # turn off context-matching
                    $cache = new Cache_text("pagelinks");
                    foreach ($pages as $page_name) {
                        $links = $cache->fetch($page_name);
                        if (is_array($links)) {
                            if (in_array($value, $links)) {
                                $hits[$page_name] = -1;
                            }
                            // ignore count if < 0
                        }
                    }
                } else {
                    if (!empty($opts['keywords'])) {
                        $pages = $DBInfo->getPageLists();
                        $opts['context'] = -1;
                        # turn off context-matching
                        $cache = new Cache_text("keyword");
                        foreach ($pages as $page_name) {
                            $links = $cache->fetch($page_name);
                            // XXX
                            if (is_array($links)) {
                                if (stristr(implode(' ', $links), $needle)) {
                                    $hits[$page_name] = -1;
                                }
                                // ignore count if < 0
                            }
                        }
                    } else {
                        $params = array();
                        $ret = array();
                        $params['ret'] =& $ret;
                        $params['offset'] = $offset;
                        $params['search'] = 1;
                        $params['incl'] = $incl;
                        $params['excl'] = $excl;
                        $pages = $DBInfo->getPageLists($params);
                        // set time_limit
                        $mt = explode(' ', microtime());
                        $timestamp = $mt[0] + $mt[1];
                        $j = 0;
                        $time_limit = isset($DBInfo->process_time_limit) ? $DBInfo->process_time_limit : 3;
                        // default 3-seconds
                        $j = 0;
                        while (list($_, $page_name) = each($pages)) {
                            // check time_limit
                            if ($time_limit and $j % 30 == 0) {
                                $mt = explode(' ', microtime());
                                $now = $mt[0] + $mt[1];
                                if ($now - $timestamp > $time_limit) {
                                    break;
                                }
                            }
                            $j++;
                            $p = new WikiPage($page_name);
                            if (!$p->exists()) {
                                continue;
                            }
                            $body = $p->_get_raw_body();
                            #$count = count(preg_split($pattern, $body))-1;
                            $count = preg_match_all($pattern, $body, $matches);
                            if ($count) {
                                foreach ($excl as $ex) {
                                    if (stristr($body, $ex)) {
                                        continue;
                                    }
                                }
                                foreach ($incl as $in) {
                                    if (!stristr($body, $in)) {
                                        continue;
                                    }
                                }
                                $hits[$page_name] = $count;
                            }
                        }
                        $searched = $j > 0 ? $j : 0;
                        $offset = !empty($offset) ? $offset + $j : $j;
                    }
                }
            }
        }
        #krsort($hits);
        #ksort($hits);
        $name = array_keys($hits);
        array_multisort($hits, SORT_DESC, $name, SORT_ASC);
        if (in_array($arena, array('backlinks', 'keywords'))) {
            $fc->update($sid, $name);
        } else {
            $fc->update($sid, array('hits' => $hits, 'offset' => $offset, 'searched' => $searched));
        }
    }
    $opts['hits'] = $hits;
    $opts['hit'] = count($hits);
    $opts['all'] = $DBInfo->getCounter();
    if ($opts['all'] > $searched) {
        $opts['next'] = $offset;
        $opts['searched'] = $searched;
    }
    if (!empty($opts['call'])) {
        return $hits;
    }
    $out = "<!-- RESULT LIST START -->";
    // for search plugin
    $out .= "<ul class='fullsearchResult'>";
    $idx = 1;
    $checkbox = '';
    while (list($page_name, $count) = each($hits)) {
        $pgname = _html_escape($page_name);
        if (!empty($opts['checkbox'])) {
            $checkbox = "<input type='checkbox' name='pagenames[]' value=\"{$pgname}\" />";
        }
        $out .= '<!-- RESULT ITEM START -->';
        // for search plugin
        $out .= '<li>' . $checkbox . $formatter->link_tag(_rawurlencode($page_name), '?action=highlight&amp;value=' . _urlencode($value), $pgname, 'tabindex="' . $idx . '"');
        if ($count > 0) {
            $out .= ' . . . . ' . sprintf($count == 1 ? _("%d match") : _("%d matches"), $count);
        } else {
            if ($count == -2) {
                $out .= " <span class='redirectIcon'><span>" . _("Redirect page") . "</span></span>\n";
            }
        }
        if (!empty($opts['context']) and $opts['context'] > 0) {
            # search matching contexts
            $p = new WikiPage($page_name);
            if ($p->exists()) {
                $body = $p->_get_raw_body();
                $out .= find_needle($body, $needle, $excl_needle, $opts['context']);
            }
        }
        $out .= "</li>\n";
        $out .= '<!-- RESULT ITEM END -->';
        // for search plugin
        $idx++;
        #if ($idx > 50) break;
    }
    $out .= "</ul>\n";
    $out .= "<!-- RESULT LIST END -->";
    // for search plugin
    return $out;
}
Пример #4
0
function macro_PageList($formatter, $arg = "", $options = array())
{
    global $DBInfo;
    $offset = '';
    if (!is_numeric($options['offset']) or $options['offset'] <= 0) {
        unset($options['offet']);
    } else {
        $offset = $options['offset'];
    }
    preg_match("/([^,]*)(\\s*,\\s*)?(.*)?\$/", $arg, $match);
    if ($match[1] == 'date') {
        $options['date'] = 1;
        $arg = '';
    } else {
        if ($match) {
            $arg = $match[1];
            $opts = array();
            if ($match[3]) {
                $opts = explode(",", $match[3]);
            }
            if (in_array('date', $opts)) {
                $options['date'] = 1;
            }
            if (in_array('dir', $opts)) {
                $options['dir'] = 1;
            }
            if (in_array('subdir', $opts)) {
                $options['subdir'] = 1;
            }
            if (in_array('info', $opts)) {
                $options['info'] = 1;
            } else {
                if ($arg and (in_array('metawiki', $opts) or in_array('m', $opts))) {
                    $options['metawiki'] = 1;
                }
            }
        }
    }
    $upper = '';
    if (!empty($options['subdir'])) {
        if (($p = strrpos($formatter->page->name, '/')) !== false) {
            $upper = substr($formatter->page->name, 0, $p);
        }
        $needle = _preg_search_escape($formatter->page->name);
        $needle = '^' . $needle . '\\/';
    } else {
        if (!empty($options['rawre'])) {
            $needle = $arg;
        } else {
            $needle = _preg_search_escape($arg);
        }
    }
    $test = @preg_match("/{$needle}/", "", $match);
    if ($test === false) {
        # show error message
        return "[[PageList(<font color='red'>Invalid \"{$arg}\"</font>)]]";
    }
    $ret = array();
    $options['ret'] =& $ret;
    $options['offset'] = $offset;
    if (!empty($options['date'])) {
        $tz_offset =& $formatter->tz_offset;
        $all_pages = $DBInfo->getPageLists($options);
    } else {
        if (!empty($options['metawiki'])) {
            $all_pages = $DBInfo->metadb->getLikePages($needle);
        } else {
            $all_pages = $DBInfo->getLikePages($needle);
        }
    }
    $hits = array();
    $out = '';
    if (!empty($options['date']) and !is_numeric($k = key($all_pages)) and is_numeric($all_pages[$k])) {
        if ($needle) {
            while (list($pagename, $mtime) = @each($all_pages)) {
                preg_match("/{$needle}/", $pagename, $matches);
                if ($matches) {
                    $hits[$pagename] = $mtime;
                }
            }
        } else {
            $hits = $all_pages;
        }
        arsort($hits);
        while (list($pagename, $mtime) = @each($hits)) {
            $out .= '<li>' . $formatter->link_tag(_rawurlencode($pagename), "", _html_escape($pagename)) . ". . . . [" . gmdate("Y-m-d", $mtime + $tz_offset) . "]</li>\n";
        }
        $out = "<ol>\n" . $out . "</ol>\n";
    } else {
        foreach ($all_pages as $page) {
            preg_match("/{$needle}/", $page, $matches);
            if ($matches) {
                $hits[] = $page;
            }
        }
        sort($hits);
        if (!empty($options['dir']) or !empty($options['subdir'])) {
            $dirs = array();
            $files = array();
            if ($options['subdir']) {
                $plen = strlen($formatter->page->name) + 1;
            } else {
                $plen = 0;
            }
            foreach ($hits as $pagename) {
                if (($rp = strrpos($pagename, '/')) !== false) {
                    $p = strpos($pagename, '/');
                    $name = substr($pagename, $plen);
                    $dum = explode('/', $name);
                    if (sizeof($dum) > 1) {
                        $dirname = array_shift($dum);
                        $orgname = substr($pagename, 0, $p) . '/' . $dirname;
                        if (empty($dirs[$orgname])) {
                            $dirs[$orgname] = array();
                        }
                        $dirs[$orgname][] = implode('/', $dum);
                        $files[$orgname] = $dirname;
                    } else {
                        $files[$pagename] = $name;
                    }
                    continue;
                }
                $files[$pagename] = $pagename;
            }
            $iconset = 'tango';
            $icon_dir = $DBInfo->imgs_dir . '/plugin/UploadedFiles/' . $iconset;
            $dicon = "<img src='{$icon_dir}/folder-16.png' width='16px'/>";
            $uicon = "<img src='{$icon_dir}/up-16.png' width='16px'/>";
            $ficon = "<img src='{$icon_dir}/text-16.png' width='16px'/>";
            $now = time();
            if ($upper) {
                $out .= '<tr><td>' . $uicon . '</td><td>' . $formatter->link_tag(_rawurlencode($upper), "", '..') . '</td>';
            }
            foreach ($dirs as $pg => $name) {
                $out .= '<tr><td>' . $dicon . '</td><td>' . $formatter->link_tag(_rawurlencode($pg), "", _html_escape($files[$pg])) . '</td>';
                if ($options['info']) {
                    $p = new WikiPage($pg);
                    $mtime = $p->mtime();
                    $time_diff = (int) ($now - $mtime) / 60;
                    if ($time_diff < 1440) {
                        $date = sprintf(_("[%sh %sm ago]"), (int) ($time_diff / 60), $time_diff % 60);
                    } else {
                        $date = date("Y/m/d H:i", $mtime);
                    }
                    $out .= '<td>' . $date . '</td>';
                }
                $out .= "</tr>\n";
                if (isset($files[$pg])) {
                    unset($files[$pg]);
                }
            }
            foreach ($files as $pg => $name) {
                $out .= '<tr><td>' . $ficon . '</td><td>' . $formatter->link_tag(_rawurlencode($pg), "", _html_escape($name)) . '</td>';
                if (!empty($options['info'])) {
                    $p = new WikiPage($pg);
                    $mtime = $p->mtime();
                    $time_diff = (int) ($now - $mtime) / 60;
                    if ($time_diff < 1440) {
                        $date = sprintf(_("[%sh %sm ago]"), (int) ($time_diff / 60), $time_diff % 60);
                    } else {
                        $date = date("Y/m/d H:i", $mtime);
                    }
                    $out .= '<td>' . $date . '</td>';
                }
                $out .= "</tr>\n";
            }
            $out = '<table>' . $out . '</table>';
        } else {
            foreach ($hits as $pagename) {
                $out .= '<li>' . $formatter->link_tag(_rawurlencode($pagename), "", _html_escape($pagename)) . "</li>\n";
            }
            $out = "<ol>\n" . $out . "</ol>\n";
            $count = count($hits);
            $total = $DBInfo->getCounter();
            // hide the link of next page for anonymous user
            if (!empty($options['id']) and $options['id'] == 'Anonymous') {
                return $out;
            }
            if ($total > $count or $offset < $total) {
                if (isset($ret['offset']) and $ret['offset'] < $total and $count < $total) {
                    $extra = '';
                    if ($options['date']) {
                        $extra .= '&amp;date=1';
                    }
                    if ($options['info']) {
                        $extra .= '&amp;info=1';
                    }
                    if (isset($needle[0])) {
                        $extra .= '&amp;value=' . $needle;
                    }
                    $qoff = '&amp;offset=' . ($ret['offset'] + $count);
                    $out .= $formatter->link_to("?action=pagelist{$extra}{$qoff}", _("Show next page"));
                }
            }
        }
    }
    return $out;
}
Пример #5
0
 function getLikePages($needle, $limit = 100, $params = array())
 {
     if (!isset($needle[0])) {
         return false;
     }
     // null needle
     if ($limit <= 0) {
         $limit = 0;
     }
     // no limit
     // protect \n char
     $needle = str_replace("\n", "", $needle);
     $total = file_get_contents($this->pagecnt);
     if ($total === false) {
         return false;
     }
     $flst = fopen($this->pagelst, 'r');
     if (!is_resource($flst)) {
         return false;
     }
     $fidx = fopen($this->pageidx, 'r');
     if (!is_resource($fidx)) {
         fclose($flst);
         return false;
     }
     $pages = array();
     $pre = '.*';
     $suf = '.*';
     if ($needle[0] == '^') {
         $pre = '';
         $needle = substr($needle, 1);
     }
     if (substr($needle, -1) == '$') {
         $suf = '';
         $needle = substr($needle, 0, -1);
     }
     // check regex
     $test = validate_needle($needle);
     if (!$test) {
         $needle = preg_quote($needle);
     } else {
         $needle = _preg_search_escape($needle);
     }
     $chunk = $this->chunksize - 1;
     // chunk size
     $is = $ie = 0;
     // index start/end
     $ss = $se = 0;
     // seek start/end
     fseek($flst, 0, SEEK_SET);
     while ($ie < $total - 1) {
         $ie = $is + $chunk;
         if ($ie >= $total) {
             $ie = $total - 1;
         }
         fseek($fidx, $ie * 4, SEEK_SET);
         $dum = unpack('N', fread($fidx, 4));
         $se = $dum[1];
         $tmp = '';
         if ($se > $ss) {
             $tmp = fread($flst, $se - $ss);
         }
         $addtmp = fgets($flst, 1024);
         // include last chunk
         $tmp .= $addtmp;
         $se += strlen($addtmp);
         if (preg_match_all('/^' . $pre . '(?:' . $needle . ')' . $suf . '$/' . $this->_match_flags, $tmp, $match)) {
             $pages = array_merge($pages, $match[0]);
             if (!empty($limit) and count($pages) > $limit) {
                 if (empty($params['nocut'])) {
                     $pages = array_slice($pages, 0, $limit);
                 }
                 break;
             }
         }
         $ss = $se;
         $is = $ie + 1;
     }
     fclose($flst);
     fclose($fidx);
     return $pages;
 }
Пример #6
0
function macro_RecentChanges($formatter, $value = '', $options = '')
{
    global $DBInfo, $Config;
    // get members to hide log
    $members = $DBInfo->members;
    $checknew = 1;
    $checkchange = 0;
    $template_bra = "";
    $template = '"$icon&nbsp;&nbsp;$title$updated $date . . . . $user $count$diff $extra<br />\\n"';
    $template_cat = "";
    $use_day = 1;
    $users = array();
    $target = '';
    if (!empty($options['target'])) {
        $target = "target='{$options['target']}'";
    }
    $bookmark_action = empty($options['bookmark_action']) ? '?action=bookmark' : '?action=' . $options['bookmark_action'];
    // $date_fmt='D d M Y';
    $date_fmt = $DBInfo->date_fmt_rc;
    $days = !empty($DBInfo->rc_days) ? $DBInfo->rc_days : RC_DEFAULT_DAYS;
    $perma_icon = $formatter->perma_icon;
    $changed_time_fmt = $DBInfo->changed_time_fmt;
    $args = explode(',', $value);
    // first arg assumed to be a date fmt arg
    if (preg_match("/^[\\s\\/\\-:aABdDFgGhHiIjmMOrSTY\\[\\]]+\$/", $args[0])) {
        $my_date_fmt = $args[0];
    }
    $strimwidth = isset($DBInfo->rc_strimwidth) ? $DBInfo->rc_strimwidth : 20;
    // use javascript
    $use_js = 0;
    // show last edit entry only
    $last_entry_only = 1;
    $last_entry_check = 60 * 60 * 24;
    // show last editor only
    $last_editor_only = 1;
    // show editrange like as MoinMoin
    $use_editrange = 0;
    // avatar
    $use_avatar = 0;
    $avatar_type = 'identicon';
    if (!empty($DBInfo->use_avatar)) {
        $use_avatar = 1;
        if (is_string($DBInfo->use_avatar)) {
            $avatar_type = $DBInfo->use_avatar;
        }
    }
    // RC cache delay
    // $rc_cache_delay <= $rc_delay
    $cache_delay = isset($DBInfo->rc_cache_delay) ? $DBInfo->rc_cache_delay : 0;
    $avatarlink = $formatter->link_url('', '?action=' . $avatar_type . '&amp;seed=');
    $ipicon = '<img src="' . $DBInfo->imgs_dir . '/misc/ip.png" />';
    $trash = 0;
    $rctype = '';
    $opts = array();
    $bra = '';
    $cat = '';
    $cat0 = '';
    $rctitle = "<h2>" . _("Recent Changes") . "</h2>";
    foreach ($args as $arg) {
        $arg = trim($arg);
        if (($p = strpos($arg, '=')) !== false) {
            $k = trim(substr($arg, 0, $p));
            $v = trim(substr($arg, $p + 1));
            if ($k == 'item' or $k == 'items') {
                $opts['items'] = min((int) $v, RC_MAX_ITEMS);
            } else {
                if ($k == 'days') {
                    $days = min(abs($v), RC_MAX_DAYS);
                } else {
                    if ($k == "datefmt") {
                        $my_date_fmt = $v;
                    } else {
                        if ($k == 'ago') {
                            if (is_numeric($v) and $v == abs($v)) {
                                $opts['ago'] = abs($v);
                            } else {
                                $opts['from'] = $v;
                            }
                        } else {
                            if ($k == "new") {
                                $checknew = $v;
                            } else {
                                if ($k == "delay") {
                                    $cache_delay = intval($v);
                                } else {
                                    if ($k == 'strimwidth' and is_numeric($v) and (abs($v) > 15 or $v == 0)) {
                                        $strimwidth = abs($v);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } else {
            if ($arg == "quick") {
                $opts['quick'] = 1;
            } else {
                if ($arg == "nonew") {
                    $checknew = 0;
                } else {
                    if ($arg == "change") {
                        $checkchange = 1;
                    } else {
                        if ($arg == "showhost") {
                            $showhost = 1;
                        } else {
                            if ($arg == "comment") {
                                $comment = 1;
                            } else {
                                if ($arg == "comments") {
                                    $comment = 1;
                                } else {
                                    if ($arg == "nobookmark") {
                                        $nobookmark = 1;
                                    } else {
                                        if ($arg == "noperma") {
                                            $perma_icon = '';
                                        } else {
                                            if ($arg == "button") {
                                                $button = 1;
                                            } else {
                                                if ($arg == "timesago") {
                                                    $timesago = 1;
                                                } else {
                                                    if ($arg == "notitle") {
                                                        $rctitle = '';
                                                    } else {
                                                        if ($arg == "hits") {
                                                            $use_hits = 1;
                                                        } else {
                                                            if ($arg == "daysago") {
                                                                $use_daysago = 1;
                                                            } else {
                                                                if ($arg == "trash") {
                                                                    $trash = 1;
                                                                } else {
                                                                    if ($arg == "editrange") {
                                                                        $use_editrange = 1;
                                                                    } else {
                                                                        if ($arg == "allauthors") {
                                                                            $last_editor_only = 0;
                                                                        } else {
                                                                            if ($arg == "allusers") {
                                                                                $last_editor_only = 0;
                                                                            } else {
                                                                                if ($arg == "allentries") {
                                                                                    $last_entry_only = 0;
                                                                                } else {
                                                                                    if ($arg == "avatar") {
                                                                                        $use_avatar = 1;
                                                                                    } else {
                                                                                        if ($arg == "noavatar") {
                                                                                            $use_avatar = 0;
                                                                                        } else {
                                                                                            if ($arg == "js") {
                                                                                                $use_js = 1;
                                                                                            } else {
                                                                                                if ($arg == "diffwidth") {
                                                                                                    $use_diffwidth = 1;
                                                                                                } else {
                                                                                                    if (in_array($arg, array('simple', 'moztab', 'board', 'table', 'list'))) {
                                                                                                        $rctype = $arg;
                                                                                                    }
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    ksort($opts);
    if (!empty($nobookmark)) {
        $use_js = 0;
    }
    // set as dynamic macro or not.
    if ($formatter->_macrocache and empty($options['call']) and empty($use_js) || $rctype != 'list') {
        return $formatter->macro_cache_repl('RecentChanges', $value);
    }
    if (empty($options['call'])) {
        $formatter->_dynamic_macros['@RecentChanges'] = 1;
    }
    if (empty($DBInfo->interwiki)) {
        $formatter->macro_repl('InterWiki', '', array('init' => 1));
    }
    // reset some conflict params
    if (empty($DBInfo->use_counter)) {
        $use_hits = 0;
    }
    if (empty($DBInfo->show_hosts)) {
        $showhost = 0;
    }
    if (!empty($rctype)) {
        if ($rctype == "simple") {
            $checkchange = 0;
            $use_day = 0;
            if ($showhost) {
                $template = '"$icon&nbsp;&nbsp;$title @ $day $date by $user $count $extra<br />\\n"';
            } else {
                $template = '"$icon&nbsp;&nbsp;$title @ $day $date $count $extra<br />\\n"';
            }
        } else {
            if ($rctype == "list") {
                $rctitle = '';
                $changed_time_fmt = !empty($my_date_fmt) ? $my_date_fmt : '[H:i]';
                $checkchange = 0;
                $use_day = 0;
                $template = '"<li>$date $title</li>\\n"';
                $template_bra = "<ul>\n";
                $template_cat = "</ul>\n";
            } else {
                if ($rctype == "moztab") {
                    $use_day = 1;
                    $template = '"<li>$title $date</li>\\n"';
                } else {
                    if ($rctype == "table") {
                        $bra = "<table border='0' cellpadding='0' cellspacing='0' width='100%'>";
                        $template = '"<tr><td style=\'white-space:nowrap;width:2%\'>$icon</td><td style=\'width:40%\'>$title$updated</td><td class=\'date\' style=\'width:15%\'>$date</td><td>$user $count$diff $extra</td></tr>\\n"';
                        $cat = "</table>";
                        $cat0 = "";
                    } else {
                        if ($rctype == "board") {
                            $changed_time_fmt = !empty($my_date_fmt) ? $my_date_fmt : 'm-d [H:i]';
                            $use_day = 0;
                            $template_bra = "<table border='0' cellpadding='0' cellspacing='0' width='100%'>";
                            if (empty($nobookmark)) {
                                $cols = 3;
                            } else {
                                $cols = 2;
                            }
                            $template_bra .= "<thead><tr><th colspan='{$cols}' class='title'>" . _("Title") . "</th>";
                            if (!empty($showhost)) {
                                $template_bra .= "<th class='author'>" . _("Editor") . '</th>';
                            }
                            $template_bra .= "<th class='editinfo'>" . _("Changes") . '</th>';
                            if (!empty($use_hits)) {
                                $template_bra .= "<th class='hits'>" . _("Hits") . "</th>";
                            }
                            $template_bra .= "<th class='date'>" . _("Change Date") . '</th>';
                            $template_bra .= "</tr></thead>\n<tbody>\n";
                            $template = '"<tr$alt><td style=\'white-space:nowrap;width:2%\'>$icon</td><td class=\'title\' style=\'width:40%\'>$title$updated</td>';
                            if (empty($nobookmark)) {
                                $template .= '<td>$bmark</td>';
                            }
                            if (!empty($showhost)) {
                                $template .= '<td class=\'author\'>$user</td>';
                            }
                            $template .= '<td class=\'editinfo\'>$count';
                            if (!empty($checkchange) or !empty($checknew)) {
                                $template .= ' $diff';
                            }
                            $template .= '</td>';
                            if (!empty($use_hits)) {
                                $template .= '<td class=\'hits\'>$hits</td>';
                            }
                            $template .= '<td class=\'date\'>$date</td>';
                            $template_extra = $template . '</tr>\\n<tr class=\'log\'$style><td colspan=\'6\'><div>$extra</div></td></tr>\\n"';
                            $template .= '</tr>\\n"';
                            $template_cat = "</tbody></table>";
                            $cat0 = "";
                        }
                    }
                }
            }
        }
    }
    // override days
    $days = !empty($_GET['days']) ? min(abs($_GET['days']), RC_MAX_DAYS) : $days;
    // override ago
    empty($opts['ago']) ? $opts['ago'] = 0 : null;
    if (!empty($_GET['ago']) and is_numeric($_GET['ago'])) {
        $opts['ago'] = abs($_GET['ago']);
    } else {
        $opts['from'] = $_GET['ago'];
    }
    // override times
    // accept both 'item' or 'items'
    $tmp = isset($_GET['item']) ? $_GET['item'] : (isset($_GET['items']) ? $_GET['items'] : null);
    !empty($tmp) ? $opts['items'] = min(abs($tmp), RC_MAX_ITEMS) : null;
    unset($tmp);
    // daysago
    $daysago = '&amp;days=' . $days;
    $daysago = $opts['ago'] ? $daysago . '&amp;ago=' . $opts['ago'] : $daysago;
    $u = $DBInfo->user;
    # retrive user info
    // check member
    $ismember = $u->is_member;
    // use uniq avatar ?
    $uniq_avatar = 0;
    if (!empty($DBInfo->use_uniq_avatar)) {
        $uniq_avatar = $DBInfo->use_uniq_avatar;
    }
    if ($ismember) {
        $uniq_avatar = 'Y';
    }
    // change avatar after year :>
    if ($u->id != 'Anonymous') {
        $bookmark = !empty($u->info['bookmark']) ? $u->info['bookmark'] : '';
    } else {
        $bookmark = $u->bookmark;
    }
    $tz_offset = $formatter->tz_offset;
    if (!$bookmark or !empty($nobookmark)) {
        if (!empty($checknew) and preg_match('/^\\d+(\\s*\\*\\s*\\d+)*$/', $checknew)) {
            $checknew = eval('return ' . $checknew . ';');
        }
        if ($checknew > 1) {
            $bookmark = strtotime(date('Y-m-d', time() - $checknew) . ' 00:00:00');
        }
    }
    if (!$bookmark) {
        $bookmark = time();
    }
    // set search query
    if (isset($_GET['q'][0])) {
        $query = _preg_search_escape(trim($_GET['q']));
        if (@preg_match('/' . $query . '/', '') === false) {
            unset($query);
        }
    }
    // make rclog uniq key
    $locals = get_defined_vars();
    unset($locals['bookmark']);
    unset($locals['formatter']);
    unset($locals['options']);
    unset($locals['DBInfo']);
    unset($locals['Config']);
    unset($locals['args']);
    unset($locals['arg']);
    unset($locals['u']);
    unset($locals['k']);
    unset($locals['v']);
    unset($locals['p']);
    unset($locals['value']);
    unset($locals['tz_offset']);
    unset($locals['members']);
    $rckey = md5(serialize($locals));
    $rckey2 = $rckey;
    $rclog = '<!-- rckey = ' . $rckey . ', cache delay = ' . $cache_delay . ' -->';
    if ($use_js) {
        unset($locals['use_js']);
        $rckey2 = md5(serialize($locals));
        // rckey without js option
    }
    unset($locals);
    // check RC cache
    $lc = new Cache_text('rccache');
    $mtime = $lc->mtime($rckey);
    if (empty($formatter->refresh)) {
        if (($val = $lc->fetch($rckey)) !== false and $DBInfo->checkUpdated($mtime, $cache_delay)) {
            return $val . '<!-- cached at ' . date('Y-m-d H:i:s', $mtime) . ' -->';
        } else {
            if (!empty($options['ajax']) && $rctype == 'list' && $rckey != $rckey2) {
                // rctype == list with ajax option does not depend on "use_js" option.
                $mtime = $lc->mtime($rckey2);
                if (($val = $lc->fetch($rckey2)) !== false and $DBInfo->checkUpdated($mtime, $cache_delay)) {
                    return $val . '<!-- cached at ' . date('Y-m-d H:i:s', $mtime) . ' -->';
                }
            }
        }
        // need to update cache
        if ($val !== false and $lc->exists($rckey . '.lock')) {
            return $val . '<!-- cached at ' . date('Y-m-d H:i:s', $mtime) . ' -->';
        }
        $lc->update($rckey . '.lock', array('lock'), 5);
        // 5s lock
    } else {
        $lc->update($rckey . '.lock', array('lock'), 5);
        // 5s lock
    }
    // $uniq_avatar is numeric case: change avatar icon after 24 hours
    if (is_numeric($uniq_avatar)) {
        $uniq_avatar = $rckey . date('mdH', time());
    } else {
        if (is_string($uniq_avatar) and preg_match('/^[YmdHi]+$/', $uniq_avatar)) {
            // date format string case: change avatar icon after 'Ymd' etc period
            $uniq_avatar = $rckey . date($uniq_avatar, time());
        }
    }
    $time_current = isset($_SERVER['REQUEST_TIME']) ? $_SERVER['REQUEST_TIME'] : time();
    $secs_per_day = 60 * 60 * 24;
    //$time_cutoff= $time_current - ($days * $secs_per_day);
    $lines = $DBInfo->editlog_raw_lines($days, $opts);
    // make a daysago button
    $btnlist = '';
    if (!empty($use_daysago) or !empty($_GET['ago'])) {
        $msg[0] = _("Show changes for ");
        $agolist = array(-$days, $days, 2 * $days, 3 * $days);
        $btn = array();
        $arg = 'days=' . $days . '&amp;ago';
        $msg[1] = _("days ago");
        foreach ($agolist as $d) {
            $d += $opts['ago'];
            if ($d <= 0) {
                continue;
            }
            $link = $formatter->link_tag($formatter->page_urlname, "?{$arg}=" . $d, $d);
            $btn[] = $link;
        }
        #if (sizeof($lines)==0) $btn=array_slice($btn,0,1);
        $btn[] = $formatter->link_tag($formatter->page_urlname, "?{$arg}=...", '...', 'onClick="return daysago(this)"');
        $script = "<script type='text/javascript' src='{$DBInfo->url_prefix}/local/rc.js' ></script>";
        $btnlist = $msg[0] . ' <ul><li>' . implode("</li>\n<li>", $btn) . '</li></ul> ' . $msg[1];
        $btnlist = $script . "<div class='rc-button'>\n" . $btnlist . "</div>\n";
    }
    $rc = new Cache_text('rclogs');
    $ratchet_day = FALSE;
    $editors = array();
    $editcount = array();
    $rc_delay = isset($DBInfo->rc_delay) ? $DBInfo->rc_delay : $rc_cache_delay;
    $rctimestamp = 0;
    $needupdate = false;
    $use_val = false;
    while (($val = $rc->fetch($rckey)) !== false) {
        $use_val = true;
        if (!empty($formatter->refresh) or !$DBInfo->checkUpdated($rc->mtime($rckey), $rc_delay)) {
            $use_val = $rc->exists($rckey . '.lock');
        }
        if (!$use_val) {
            break;
        }
        $editors = $val['editors'];
        $editcount = $val['editcount'];
        $lastmod = $val['lastmod'];
        $rclastline = $val['lastline'];
        $rctimestamp = $val['timestamp'];
        $users = $val['users'];
        break;
    }
    // no cache available
    if (!$use_val) {
        $rc->update($rckey . '.lock', array('lock'), 5);
    }
    // 5s lock
    $lastline = $lines[0];
    $tmp = explode("\t", $lastline, 6);
    $timestamp = $tmp[2];
    unset($tmp);
    $updatemod = array();
    $needupdate = $rctimestamp < $timestamp or $lastline != $rclastline;
    if ($needupdate) {
        foreach ($lines as $line) {
            $parts = explode("\t", $line, 6);
            if ($lastline == $rclastline) {
                break;
            }
            $page_key = $parts[0];
            $ed_time = $parts[2];
            $user = $parts[4];
            $addr = $parts[1];
            if ($user == 'Anonymous') {
                $user = '******' . $addr;
            } else {
                $user = $user . "\t" . $addr;
            }
            $day = gmdate('Ymd', $ed_time + $tz_offset);
            //if ($day != $ratchet_day) {
            //  $ratchet_day = $day;
            //}
            if ($last_entry_only and !empty($last_entry_check)) {
                if (!empty($lastmod[$page_key]) and $lastmod[$page_key] < $ed_time + $last_entry_check) {
                    $edit_day = gmdate('Ymd', $lastmod[$page_key] + $tz_offset);
                    $editors[$page_key][$edit_day][] = $user;
                    $editcount[$page_key][$edit_day]++;
                    if ($needupdate and empty($updatemod[$page_key])) {
                        $updatemod[$page_key] = $ed_time;
                    }
                    continue;
                }
            } else {
                if (!empty($editcount[$page_key][$day])) {
                    $editors[$page_key][$day][] = $user;
                    $editcount[$page_key][$day]++;
                    if ($needupdate and empty($updatemod[$page_key])) {
                        $updatemod[$page_key] = $ed_time;
                    }
                    continue;
                }
            }
            if (empty($editcount[$page_key])) {
                $editcount[$page_key] = array();
                $editors[$page_key] = array();
            }
            $editcount[$page_key][$day] = 1;
            $editors[$page_key][$day] = array();
            $editors[$page_key][$day][] = $user;
            $lastmod[$page_key] = $ed_time;
            if ($needupdate) {
                $updatemod[$page_key] = $ed_time;
            }
        }
    }
    if (!empty($lastmod)) {
        $lastmod = array_merge($lastmod, $updatemod);
    }
    // search query
    if (isset($query[0])) {
        $lines = preg_grep("/{$query}/i", $lines);
    }
    // setup hidelog rule
    $hiderule = null;
    if (!$ismember && !empty($Config['ruleset']['hiderule'])) {
        $rule = implode('|', $Config['ruleset']['hiderule']);
        if (preg_match('@' . $rule . '@', null) !== false) {
            $hiderule = '@' . $rule . '@';
        }
    }
    $out = "";
    $ratchet_day = FALSE;
    $br = "";
    $ii = 0;
    $rc_list = array();
    $list = array();
    foreach ($lines as $line) {
        $parts = explode("\t", $line);
        $page_key = $parts[0];
        $ed_time = $parts[2];
        $day = gmdate('Ymd', $ed_time + $tz_offset);
        // show last edit only
        if (!empty($last_entry_only) and !empty($logs[$page_key])) {
            continue;
        } else {
            if (!empty($logs[$page_key][$day])) {
                continue;
            }
        }
        $page_name = $DBInfo->keyToPagename($parts[0]);
        if (!empty($hiderule)) {
            if (preg_match($hiderule, $page_name)) {
                continue;
            }
        }
        // show trashed pages only
        if ($trash and $DBInfo->hasPage($page_name)) {
            continue;
        }
        $addr = $parts[1];
        $user = $parts[4];
        $log = _stripslashes($parts[5]);
        $act = rtrim($parts[6]);
        $via_proxy = false;
        if (($p = strpos($addr, ',')) !== false) {
            // user via Proxy
            $via_proxy = true;
            $real_ip = substr($addr, 0, $p);
            $log_proxy = '<span class="via-proxy">' . $real_ip . '</span>';
            $log = isset($log[0]) ? $log_proxy . ' ' . $log : $log_proxy;
            $dum = explode(',', $addr);
            $addr = array_pop($dum);
        }
        //    if ($ed_time < $time_cutoff)
        //      break;
        $group = '';
        if ($formatter->group) {
            if (!preg_match("/^({$formatter->group})(.*)\$/", $page_name, $match)) {
                continue;
            }
            $title = $match[2];
        } else {
            if (!empty($formatter->use_group) and ($p = strpos($page_name, '~')) !== false) {
                $title = substr($page_name, $p + 1);
                $group = ' (' . substr($page_name, 0, $p) . ')';
            } else {
                $title = $page_name;
            }
        }
        if (!empty($changed_time_fmt)) {
            if (empty($timesago)) {
                $date = gmdate($changed_time_fmt, $ed_time + $tz_offset);
            } else {
                $date = _timesago($ed_time, 'Y-m-d', $tz_offset);
            }
        }
        $pageurl = _rawurlencode($page_name);
        // get title
        $title0 = get_title($title) . $group;
        $title0 = _html_escape($title0);
        if ($rctype == 'list') {
            $attr = '';
        } else {
            $attr = " id='title-{$ii}'";
        }
        if (!empty($strimwidth) and strlen(get_title($title)) > $strimwidth and function_exists('mb_strimwidth')) {
            $title0 = mb_strimwidth($title0, 0, $strimwidth, '...', $DBInfo->charset);
        }
        $attr .= ' title="' . $title0 . '"';
        $title = $formatter->link_tag($pageurl, "", $title0, $target . $attr);
        // simple list format
        if ($rctype == 'list') {
            if (empty($logs[$page_key])) {
                $logs[$page_key] = array();
            }
            $logs[$page_key][$day] = 1;
            if (!$DBInfo->hasPage($page_name)) {
                $act = 'DELETE';
                $title = '<strike>' . $title . '</strike>';
            }
            $list[$page_name] = array($title, $date, $ed_time, $act);
            continue;
        }
        // print $ed_time."/".$bookmark."//";
        $diff = '';
        $updated = '';
        if ($act == 'UPLOAD') {
            $icon = $formatter->link_tag($pageurl, "?action=uploadedfiles", $formatter->icon['attach']);
        } else {
            if (!$DBInfo->hasPage($page_name)) {
                $icon = $formatter->link_tag($pageurl, "?action=info", $formatter->icon['del']);
                if (!empty($use_js)) {
                    $rc_list[] = $page_name;
                }
            } else {
                $icon = $formatter->link_tag($pageurl, "?action=diff", $formatter->icon['diff'], " id='icon-{$ii}'");
                if (empty($use_js) and $ed_time > $bookmark) {
                    $icon = $formatter->link_tag($pageurl, "?action=diff&amp;date={$bookmark}", $formatter->icon['diff']);
                    $updated = ' ' . $formatter->link_tag($pageurl, "?action=diff&amp;date={$bookmark}", $formatter->icon['updated'], 'class="updated"');
                    $add = 0;
                    $del = 0;
                    if ($checknew or $checkchange) {
                        $p = new WikiPage($page_name);
                        $v = $p->get_rev($bookmark);
                        if (empty($v)) {
                            $icon = $formatter->link_tag($pageurl, "?action=info", $formatter->icon['show']);
                            $updated = ' ' . $formatter->link_tag($pageurl, "?action=info", $formatter->icon['new'], 'class="new"');
                            $add += $p->lines();
                        }
                    }
                    if ($checkchange) {
                        if (empty($v)) {
                            // new
                            $infos = array();
                        } else {
                            $infos = $p->get_info('>' . $bookmark);
                        }
                        foreach ($infos as $inf) {
                            $tmp = explode(' ', trim($inf[1]));
                            if (isset($tmp[1])) {
                                $add += $tmp[0];
                                $del += $tmp[1];
                            }
                        }
                    }
                    if (!empty($add)) {
                        $diff .= '<span class="diff-added"><span>+' . $add . '</span></span>';
                    }
                    if (!empty($del)) {
                        $diff .= '<span class="diff-removed"><span>' . $del . '</span></span>';
                    }
                } else {
                    if (!empty($use_js)) {
                        $diff = '<span id="diff-' . $ii . '"></span>';
                        $rc_list[] = $page_name;
                    }
                }
            }
        }
        if (!empty($use_hits)) {
            $hits = $DBInfo->counter->pageCounter($page_name);
        }
        if (!empty($showhost)) {
            if ($last_editor_only) {
                // show last editor only
                $editor = $editors[$page_key][$day];
                if (is_array($editor)) {
                    $editor = $editor[0];
                }
            } else {
                // all show all authors
                // count edit number
                // make range list
                if ($use_editrange) {
                    // MoinMoin like edit range
                    $editor_list = array();
                    if ($editors[$page_key][$day]) {
                        foreach ($editors[$page_key][$day] as $idx => $name) {
                            if (empty($editor_list[$name])) {
                                $editor_list[$name] = array();
                            }
                            $editor_list[$name][] = $idx + 1;
                        }
                    }
                    $editor_counts = array();
                    foreach ($editor_list as $name => $edits) {
                        $range = ',';
                        if (isset($edits[1])) {
                            $edits[] = 999999;
                            // MoinMoin method
                            for ($i = 0, $sz = count($edits) - 1; $i < $sz; $i++) {
                                if (substr($range, -1) == ',') {
                                    $range .= $edits[$i];
                                    if ($edits[$i] + 1 == $edits[$i + 1]) {
                                        $range .= '-';
                                    } else {
                                        $range .= ',';
                                    }
                                } else {
                                    if ($edits[$i] + 1 != $edits[$i + 1]) {
                                        $range .= $edits[$i] . ',';
                                    }
                                }
                            }
                            $range = trim($range, ',-');
                            $editor_counts[$name] = $range;
                        } else {
                            $editor_counts[$name] = $edits[0];
                        }
                    }
                } else {
                    $editor_counts = array_count_values($editors[$page_key][$day]);
                }
                $editor = array_keys($editor_counts);
            }
            $all_user = array();
            foreach ((array) $editor as $user) {
                if (!$last_editor_only and isset($editor[1]) and isset($editor_counts[$user])) {
                    $count = " <span class='range'>[" . $editor_counts[$user] . "]</span>";
                } else {
                    $count = '';
                }
                if (!empty($showhost) && substr($user, 0, 9) == 'Anonymous') {
                    $ouser = $user;
                    if (isset($users[$ouser])) {
                        $user = $users[$ouser];
                    } else {
                        $checkaddr = null;
                        $addr = null;
                        $tmp = $user;
                        if (strpos($user, "\t") !== false) {
                            list($tmp, $addr) = explode("\t", $user);
                        }
                        $checkaddr = substr($tmp, 10);
                        // Anonymous-127.0.0.1 or Anonymous-email@foo.bar
                        if (($p = strpos($checkaddr, ',')) !== false) {
                            $dum = explode(',', $checkaddr);
                            $checkaddr = array_pop($dum);
                            // last address is the REMOTE_ADDR
                        }
                        $user = $addr = $addr ? $addr : $checkaddr;
                        if (!is_numeric($checkaddr[0]) and preg_match('/^[a-z][a-z0-9_\\-\\.]+@[a-z][a-z0-9_\\-]+(\\.[a-z0-9_]+)+$/i', $user)) {
                            $user = $checkaddr;
                            if (!empty($DBInfo->hide_emails)) {
                                $user = substr(md5($user), 0, 8);
                            } else {
                                $user = email_guard($user);
                            }
                        } else {
                            if (isset($DBInfo->interwiki['Whois'])) {
                                $wip = "<a href='" . $DBInfo->interwiki['Whois'] . "{$addr}' target='_blank'>{$ipicon}</a>";
                            } else {
                                $wip = "<a href='?action=whois&q=" . $addr . "' target='_blank'>{$ipicon}</a>";
                            }
                            if ($ismember) {
                                if (in_array($user, $members)) {
                                    $wip = '';
                                }
                                if (!empty($DBInfo->use_admin_user_url)) {
                                    $user = '******' . $DBInfo->use_admin_user_url . $user . '">' . $user . '</a>' . $wip;
                                } else {
                                    $user = $user . $wip;
                                }
                            } else {
                                if (!empty($DBInfo->mask_hostname)) {
                                    $user = _mask_hostname($addr, intval($DBInfo->mask_hostname));
                                }
                            }
                        }
                        $avatar = '';
                        if (!empty($use_avatar)) {
                            if (!empty($uniq_avatar)) {
                                $key = $addr . $uniq_avatar;
                            } else {
                                $key = $addr . $rckey;
                            }
                            $crypted = md5($key);
                            $mylnk = preg_replace('/seed=/', 'seed=' . $crypted, $avatarlink);
                            $avatar = '<img src="' . $mylnk . '" class="avatar" alt="avatar" />';
                        }
                        $user = $avatar . $user;
                        $users[$ouser] = $user;
                    }
                } else {
                    list($user, $addr) = explode("\t", $user);
                    $ouser = $user;
                    if (!isset($users[$ouser])) {
                        if (isset($DBInfo->interwiki['Whois'])) {
                            $wip = "<a href='" . $DBInfo->interwiki['Whois'] . "{$addr}' target='_blank'>{$ipicon}</a>";
                        } else {
                            $wip = "<a href='?action=whois&q=" . $addr . "' target='_blank'>{$ipicon}</a>";
                        }
                        $avatar = '';
                        if (!empty($use_avatar)) {
                            if (!empty($uniq_avatar)) {
                                $key = $addr . $uniq_avatar;
                            } else {
                                $key = $addr . $rckey;
                            }
                            if (!$ismember) {
                                $key .= $user;
                            }
                            // not a member: show different avatar for login user
                            $crypted = md5($key);
                            $mylnk = preg_replace('/seed=/', 'seed=' . $crypted, $avatarlink);
                            if ($ouser != 'Anonymous') {
                                $mylnk .= '&amp;user='******'<img src="' . $mylnk . '" class="avatar" alt="avatar" />';
                        }
                    }
                    if (isset($users[$ouser])) {
                        $user = $users[$ouser];
                    } else {
                        if ($ismember) {
                            if (in_array($user, $members)) {
                                $wip = '';
                            }
                            if (!empty($DBInfo->use_admin_user_url)) {
                                $user = $avatar . '<a href="' . $DBInfo->use_admin_user_url . $user . '">' . $user . '</a>' . $wip;
                            } else {
                                $user = $avatar . $user . $wip;
                            }
                            $users[$ouser] = $user;
                        } else {
                            if (!empty($DBInfo->use_nick)) {
                                $uid = $user;
                                if (($p = strpos($uid, ' ')) !== false) {
                                    $uid = substr($uid, 0, $p);
                                }
                                $u = $DBInfo->udb->getUser($uid);
                                if (!empty($u->info)) {
                                    if (!empty($DBInfo->interwiki['User'])) {
                                        $user = $formatter->link_repl('[wiki:User:'******' ' . $u->info['nick'] . ']');
                                    } else {
                                        if (!empty($u->info['home'])) {
                                            $user = $formatter->link_repl('[' . $u->info['home'] . ' ' . $u->info['nick'] . ']');
                                        } else {
                                            if (!empty($u->info['nick'])) {
                                                $user = $formatter->link_repl('[wiki:' . $uid . ' ' . $u->info['nick'] . ']');
                                            }
                                        }
                                    }
                                }
                                $user = $avatar . $user;
                                $users[$ouser] = $user;
                            } else {
                                if (strpos($user, ' ') !== false) {
                                    $user = $avatar . $formatter->link_repl($user);
                                    $users[$ouser] = $user;
                                } else {
                                    if (empty($DBInfo->no_wikihomepage) and $DBInfo->hasPage($user)) {
                                        $user = $formatter->link_tag(_rawurlencode($user), "", $user);
                                        $user = $avatar . $user;
                                        $users[$ouser] = $user;
                                    } else {
                                        if (substr($user, 0, 9) == 'Anonymous') {
                                            $addr = substr($user, 10);
                                            $user = _('Anonymous');
                                        }
                                        $uid = $user;
                                        if (preg_match('/^[a-z][a-z0-9_\\-\\.]+@[a-z][a-z0-9_\\-]+(\\.[a-z0-9_]+)+$/i', $user)) {
                                            if (!empty($DBInfo->hide_emails)) {
                                                $user = substr(md5($user), 0, 8);
                                            } else {
                                                $user = email_guard($user);
                                            }
                                        }
                                        $user = $avatar . $user;
                                        $users[$ouser] = $user;
                                    }
                                }
                            }
                        }
                    }
                }
                $all_user[] = $user . $count;
            }
            if (isset($editor[1])) {
                $user = '******' . implode("</span> <span class='editor'>", $all_user) . "</span></span>\n";
            } else {
                $user = '******' . $all_user[0] . "</span>\n";
            }
        } else {
            $user = '******';
        }
        $jsattr = '';
        if (!empty($use_js)) {
            $jsattr = ' onclick="update_bookmark(' . $ed_time . ');return false;"';
        }
        $bmark = '';
        if ($day != $ratchet_day) {
            $ratchet_day = $day;
            if (!empty($use_day)) {
                $tag = str_replace('-', '', $day);
                $perma = "<a name='{$tag}'></a><a class='perma' href='#{$tag}'>{$perma_icon}</a>";
                $out .= $cat0;
                $rcdate = gmdate($date_fmt, $ed_time + $tz_offset);
                $out .= sprintf("%s<span class='rc-date' style='font-size:large'>%s ", $br, $rcdate);
                if (empty($nobookmark)) {
                    $out .= "<span class='rc-bookmark' style='font-size:small'>[" . $formatter->link_tag($formatter->page->urlname, $bookmark_action . "&amp;time={$ed_time}" . $daysago, _("set bookmark"), $jsattr) . "]</span>\n";
                }
                $br = "<br />";
                $out .= '</span>' . $perma . '<br />' . $bra;
                $cat0 = $cat;
            } else {
                $bmark = $formatter->link_to($bookmark_action . "&amp;time={$ed_time}" . $daysago, _("Bookmark"), $jsattr . ' class="button-small"');
            }
        }
        //if (empty($use_day) and empty($nobookmark)) {
        if (empty($nobookmark)) {
            $date = $formatter->link_to($bookmark_action . "&amp;time={$ed_time}" . $daysago, $date, ' id="time-' . $ii . '" ' . $jsattr);
        }
        $count = "";
        $extra = "";
        if ($editcount[$page_key][$day] > 1) {
            $count = '<span id="change-' . $ii . '">' . sprintf(_("%s changes"), " <span class='num'>" . $editcount[$page_key][$day] . "</span>") . '</span>';
        } else {
            $count = '<span id="change-' . $ii . '"></span>';
        }
        if (!empty($comment) && !empty($log)) {
            $extra = "&nbsp; &nbsp; &nbsp; <small name='word-break'>{$log}</small>";
        }
        $alt = $ii % 2 == 0 ? ' class="alt"' : '';
        if ($extra and isset($template_extra)) {
            if ($rctype == 'board' and !empty($use_js)) {
                $style = ' style="display:none"';
            } else {
                $style = '';
            }
            if (!empty($use_js)) {
                $title = '<button onclick="toggle_log(this);return false;"><span>+</span></button>' . $title;
            }
            $out .= eval('return ' . $template_extra . ';');
        } else {
            $out .= eval('return ' . $template . ';');
        }
        if (empty($logs[$page_key])) {
            $logs[$page_key] = array();
        }
        $logs[$page_key][$day] = 1;
        ++$ii;
    }
    if ($needupdate) {
        $rc->update($rckey, array('editors' => $editors, 'editcount' => $editcount, 'lastmod' => $lastmod, 'lastline' => $lastline, 'timestamp' => $timestamp, 'users' => $users));
    }
    $js = '';
    if (!empty($rc_list)) {
        require_once 'lib/JSON.php';
        $json = new Services_JSON();
        $icon_new = $formatter->icon['new'];
        $icon_updated = $formatter->icon['updated'];
        $icon_show = $formatter->icon['show'];
        $icon_diff = $formatter->icon['diff'];
        $js = "<script type='text/javascript'>\n/*<![CDATA[*/\nvar rclist =";
        $ext = array();
        if (!empty($checknew)) {
            $ext[] = 'new=1';
        }
        if (!empty($checkchange)) {
            $ext[] = 'change=1';
        }
        $arg = implode('&', $ext);
        //$url = qualifiedURL($formatter->link_url('RecentChanges')); // FIXME
        //$url = preg_replace('/^https?:/', '', $url);
        $url = $formatter->link_url('RecentChanges');
        $postdata = "action=recentchanges/ajax" . ($arg ? '&' . $arg : '');
        $js .= $json->encode($rc_list) . ";\n";
        if ($use_diffwidth) {
            $js .= "var use_diffwidth = true;\n";
        } else {
            $js .= "var use_diffwidth = false;\n";
        }
        $js .= <<<EOF
function diff_width(size) {
    if (size < 0)
        size = -size;
    if (size < 5)
      return '';
    else if (size < 10)
      return 'display:inline-block;width:25px';
    else
      return 'display:inline-block;width:' + ~~(25 + 2*Math.sqrt(size)) + 'px';
}

function update_bookmark(time) {
    var url = "{$url}";
    if (rclist.length) {
      var timetag;
      if (typeof time == 'undefined') timetag = '';
      else timetag = '&time=' + time;

      var data = "{$postdata}";
      data += timetag + '&value=' + encodeURIComponent(json_encode(rclist));
      var txt = HTTPPost(url, data);
      var ret;
      if (txt == null) return;

      var icon_new = "{$icon_new}";
      var icon_updated = "{$icon_updated}";
      var icon_show = "{$icon_show}";
      var icon_diff = "{$icon_diff}";

      ret = window["eval"]("(" + txt + ")");
      var bookmark = ret['__-_-bookmark-_-__'];
      var jj = 0;
      for (var ii = 0; ii < rclist.length; ii++) {
        // update time
        var time = document.getElementById('time-' + ii);
        var tstr = time.firstChild.innerText;
        var d0 = Date.parse(tstr); // test
        if (isNaN(d0)) {
          // recalc time string
          var timestamp = time.href.match(/time=(\\d+)/);
          tstr = timesago(timestamp[1], "{$date_fmt}", {$tz_offset});
          if (tstr != null)
            time.firstChild.innerText = tstr;
        }

        var item = document.getElementById('title-' + ii);
        var title = item.getAttribute('title');
        if (rclist[jj] != title) {
          var re = new RegExp("^.*" + url_prefix + '/');
          title = decodeURIComponent(item.href.replace(re, ''));
        }

        if (ret[title] && ret[title]['state'] == 'deleted') { jj++; continue; }

        if (rclist[jj] == title && ret[title]) {
          var icon = document.getElementById('icon-' + ii);
          var state = document.createElement('SPAN');
          if (ret[title]['state'] == 'new') {
            state.innerHTML = icon_new;
            state.setAttribute('class', 'new');
            icon.href = icon.href.replace(/action=(diff|info)((?:&|&amp;)date=\\d+)?/, 'action=info');
            icon.innerHTML = icon_show;
          } else {
            state.innerHTML = icon_updated;
            state.setAttribute('class', 'updated');
            icon.href = icon.href.replace(/action=(diff|info)((?:&|&amp;)date=\\d+)?/, 'action=diff&date=' + bookmark);
            icon.innerHTML = icon_diff;
          }

          // remove previous icon
          if (item.firstChild.nextSibling)
            item.removeChild(item.firstChild.nextSibling);
          item.appendChild(state); // add updated / new icon

          var change = document.getElementById('change-' + ii);
          if (!change) continue;
          var diff = document.getElementById('diff-' + ii);
          var nodiff = !diff;

          // remove previous diff info
          if (change.lastChild && change.lastChild.tagName == 'SPAN')
            change.removeChild(change.lastChild);
          else if (diff && diff.lastChild)
            diff.removeChild(diff.lastChild);

          // add diff info
          var diff0 = document.createElement('SPAN');
          if (ret[title]['add']) {
            var add = document.createElement('SPAN');
            var add2 = document.createElement('SPAN');
            add.setAttribute('class', 'diff-added');
            var txt = document.createTextNode('+' + ret[title]['add']);
            add2.appendChild(txt);
            add.appendChild(add2);
            diff0.appendChild(add);
            if (use_diffwidth)
            add.style.cssText = diff_width(ret[title]['add']);
          }
          if (ret[title]['del']) {
            var del = document.createElement('SPAN');
            var del2 = document.createElement('SPAN');
            del.setAttribute('class', 'diff-removed');
            var txt = document.createTextNode(ret[title]['del']);
            del2.appendChild(txt);
            del.appendChild(del2);
            diff0.appendChild(del);
            if (use_diffwidth)
            del.style.cssText = diff_width(ret[title]['del']);
          }
          if (nodiff)
            change.appendChild(diff0);
          else
            diff.appendChild(diff0);
          jj++;
        } else {
          if (item.firstChild.nextSibling)
            item.removeChild(item.firstChild.nextSibling);

          var change = document.getElementById('change-' + ii);
          if (!change) continue;
          var diff = document.getElementById('diff-' + ii);

          // remove diff info
          if (change.lastChild && change.lastChild.tagName == 'SPAN')
            change.removeChild(change.lastChild);
          else if (diff && diff.lastChild)
            diff.removeChild(diff.lastChild);

          // recover diff icon and link
          var icon = document.getElementById('icon-' + ii);
          if (icon && icon.firstChild) {
            var alt = icon.firstChild.getAttribute('alt');
            if (alt != 'D' && alt != '@') {
              icon.innerHTML = icon_diff;
            }
            // recover link
            icon.href = icon.href.replace(/action=(diff|info)(&date=\\d+)?/, 'action=diff');
          }
        }
      }
    }
}
if(window.addEventListener)window.addEventListener("load",update_bookmark,false);
else if(window.attachEvent)window.attachEvent("onload",update_bookmark);
/*]]>*/
</script>
EOF;
    } else {
        if (!empty($list)) {
            $out = '';
            foreach ($list as $k => $v) {
                $out .= '<li><span data-timestamp="' . $v[2] . '" class="date">' . $v[1] . '</span> ' . $v[0] . '</li>' . "\n";
            }
            //if (!empty($options['ajax'])) {
            //  return '<ul>'.$out.'</ul>';
            //}
        }
    }
    if (in_array($rctype, array('list', 'simple')) and $use_js) {
        static $rc_id = 1;
        $rcid = ' id="rc' . $rc_id . '"';
        $extra = '';
        if (!empty($opts['items'])) {
            $extra .= '&item=' . $opts['items'];
        }
        if (!empty($my_date_fmt)) {
            $extra .= '&datefmt=' . $my_date_fmt;
        }
        $url = $formatter->link_url('RecentChanges', "?action=recentchanges/ajax&type={$rctype}" . $extra);
        $js = <<<JS
<script type='text/javascript'>
/*<![CDATA[*/
(function() {
  var url = "{$url}";
  var txt = HTTPGet(url);
  var rc = document.getElementById("rc{$rc_id}");
  if (txt.substring(0,5) != 'false') {
    var m = null;
    if (m = txt.match(/<ul>[\\s\\S]*<\\/ul>/)) {
      rc.innerHTML = m[0];
    }
  }
})();
/*]]>*/
</script>
JS;
        $rc_id++;
    } else {
        if ($use_js and $rctype == 'board') {
            $js .= <<<JS
<script type='text/javascript'>
/*<![CDATA[*/
function toggle_log(el)
{
  var item = el.parentNode.parentNode; // container
  var log = item.nextSibling;
  if (log.tagName == undefined)
    log = log.nextSibling; // for IE6

  if (log.style.display == "none") {
    el.className = "close";
    log.style.display = "";
  } else {
    el.className = "open";
    log.style.display = "none";
  }
}
/*]]>*/
</script>
JS;
        }
    }
    $out = $btnlist . '<div class="recentChanges"' . $rcid . '>' . $rctitle . $template_bra . $out . $template_cat . $cat0 . '</div>' . $js . $rclog;
    $lc->update($rckey, $out);
    $lc->remove($rckey . '.lock');
    // unlock
    $rc->remove($rckey . '.lock');
    // unlock
    return $out;
}
Пример #7
0
function macro_FastSearch($formatter, $value = "", &$opts)
{
    global $DBInfo;
    $default_limit = isset($DBInfo->fastsearch_limit) ? $DBInfo->fastsearch_limit : 30;
    if ($value === true) {
        $needle = $value = $formatter->page->name;
    } else {
        # for MoinMoin compatibility with [[FullSearch("blah blah")]]
        $needle = $value = preg_replace("/^('|\")([^\\1]*)\\1/", "\\2", $value);
    }
    $needle = _preg_search_escape($needle);
    $pattern = '/' . $needle . '/i';
    $fneedle = str_replace('"', "&#34;", $needle);
    # XXX
    $url = $formatter->link_url($formatter->page->urlname);
    $arena = 'fullsearch';
    $check1 = 'checked="checked"';
    $check2 = $check3 = '';
    if (in_array($opts['arena'], array('titlesearch', 'fullsearch', 'pagelinks'))) {
        $check1 = '';
        $arena = $opts['arena'];
        if ($arena == 'fullsearch') {
            $check1 = 'checked="checked"';
        } else {
            if ($arena == 'titlesearch') {
                $check2 = 'checked="checked"';
            } else {
                $check3 = 'checked="checked"';
            }
        }
    }
    if (!empty($opts['backlinks'])) {
        $arena = 'pagelinks';
        $check1 = '';
        $check3 = 'checked="checked"';
    }
    $msg = _("Fast search");
    $msg2 = _("Display context of search results");
    $msg3 = _("Full text search");
    $msg4 = _("Title search");
    $msg5 = _("Link search");
    $form = <<<EOF
<form method='get' action='{$url}'>
   <input type='hidden' name='action' value='fastsearch' />
   <input name='value' size='30' value='{$fneedle}' />
   <span class='button'><input type='submit' class='button' value='{$msg}' /></span><br />
   <input type='checkbox' name='context' value='20' />{$msg2}<br />
   <input type='radio' name='arena' value='fullsearch' {$check1} />{$msg3}
   <input type='radio' name='arena' value='titlesearch' {$check2} />{$msg4}
   <input type='radio' name='arena' value='pagelinks' {$check3} />{$msg5}<br />
   </form>
EOF;
    if (!isset($needle[0]) or !empty($opts['form'])) {
        # or blah blah
        $opts['msg'] = _("No search text");
        return $form;
    } else {
        if (validate_needle($needle) === false) {
            $opts['msg'] = sprintf(_("Invalid search expression \"%s\""), $needle);
            return $form;
        }
    }
    $DB = new Indexer_dba($arena, "r", $DBInfo->dba_type);
    if ($DB->db == null) {
        $opts['msg'] = _("Couldn't open search database, sorry.");
        $opts['hits'] = array();
        $opts['hit'] = 0;
        $opts['all'] = 0;
        return '';
    }
    $opts['form'] = $form;
    $sc = new Cache_text("searchkey");
    if ($arena == "pagelinks") {
        $words = array($value);
    } else {
        $words = getTokens($value);
    }
    // $words=explode(' ', strtolower($value));
    $idx = array();
    $new_words = array();
    foreach ($words as $word) {
        if ($sc->exists($word)) {
            $searchkeys = $sc->fetch($word);
        } else {
            $searchkeys = $DB->_search($word);
            $sc->update($word, $searchkeys);
        }
        $new_words = array_merge($new_words, $searchkeys);
        $new_words = array_merge($idx, $DB->_search($word));
    }
    $words = array_merge($words, $new_words);
    //
    $word = array_shift($words);
    $idx = $DB->_fetchValues($word);
    foreach ($words as $word) {
        $ids = $DB->_fetchValues($word);
        // FIXME
        foreach ($ids as $id) {
            $idx[] = $id;
        }
    }
    $init_hits = array_count_values($idx);
    // initial hits
    $idx = array_keys($init_hits);
    //arsort($idx);
    $all_count = $DBInfo->getCounter();
    $pages = array();
    $hits = array();
    foreach ($idx as $id) {
        $key = $DB->_fetch($id);
        $pages[$id] = $key;
        $hits['_' . $key] = $init_hits[$id];
        // HACK. prefix '_' to numerical named pages
    }
    $DB->close();
    if (!empty($_GET['q']) and isset($_GET['q'][0])) {
        return $pages;
    }
    $context = !empty($opts['context']) ? $opts['context'] : 0;
    $limit = isset($opts['limit'][0]) ? $opts['limit'] : $default_limit;
    $contexts = array();
    if ($arena == 'fullsearch' || $arena == 'pagelinks') {
        $idx = 1;
        foreach ($pages as $page_name) {
            if (!empty($limit) and $idx > $limit) {
                break;
            }
            $p = new WikiPage($page_name);
            if (!$p->exists()) {
                continue;
            }
            $body = $p->_get_raw_body();
            $count = preg_match_all($pattern, $body, $matches);
            // more precisely count matches
            if ($context) {
                # search matching contexts
                $contexts[$page_name] = find_needle($body, $needle, '', $context);
            }
            $hits['_' . $page_name] = $count;
            // XXX hack for numerical named pages
            $idx++;
        }
    }
    //uasort($hits, 'strcasecmp');
    //$order = 0;
    //uasort($hits, create_function('$a, $b', 'return ' . ($order ? '' : '-') . '(strcasecmp($a, $b));'));
    $name = array_keys($hits);
    array_multisort($hits, SORT_DESC, $name, SORT_ASC);
    $opts['hits'] = $hits;
    $opts['hit'] = count($hits);
    $opts['all'] = $all_count;
    if (!empty($opts['call'])) {
        return $hits;
    }
    $out = "<!-- RESULT LIST START -->";
    // for search plugin
    $out .= "<ul>";
    $idx = 1;
    while (list($page_name, $count) = each($hits)) {
        $page_name = substr($page_name, 1);
        $out .= '<!-- RESULT ITEM START -->';
        // for search plugin
        $out .= '<li>' . $formatter->link_tag(_rawurlencode($page_name), "?action=highlight&amp;value=" . _urlencode($needle), $page_name, "tabindex='{$idx}'");
        if ($count > 1) {
            $out .= ' . . . . ' . sprintf($count == 1 ? _("%d match") : _("%d matches"), $count);
            if (!empty($contexts[$page_name])) {
                $out .= $contexts[$page_name];
            }
        }
        $out .= "</li>\n";
        $out .= '<!-- RESULT ITEM END -->';
        // for search plugin
        $idx++;
        if (!empty($limit) and $idx > $limit) {
            break;
        }
    }
    $out .= "</ul>\n";
    $out .= "<!-- RESULT LIST END -->";
    // for search plugin
    return $out;
}
Пример #8
0
    function send_header($header = "", $options = array())
    {
        global $DBInfo;
        $plain = 0;
        $media = 'media="screen"';
        if (isset($options['action'][0]) and $options['action'] == 'print') {
            $media = '';
        }
        if (empty($options['is_robot']) && isset($this->pi['#redirect'][0]) && !empty($options['pi'])) {
            $options['value'] = $this->pi['#redirect'];
            $options['redirect'] = 1;
            $this->pi['#redirect'] = '';
            do_goto($this, $options);
            return true;
        }
        $header = !empty($header) ? $header : (!empty($options['header']) ? $options['header'] : null);
        if (!empty($header)) {
            foreach ((array) $header as $head) {
                $this->header($head);
                if (preg_match("/^content\\-type: text\\//i", $head)) {
                    $plain = 1;
                }
            }
        }
        $mtime = isset($options['mtime']) ? $options['mtime'] : $this->page->mtime();
        if ($mtime > 0) {
            $modified = $mtime > 0 ? gmdate('Y-m-d\\TH:i:s', $mtime) . '+00:00' : null;
            $lastmod = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
            $meta_lastmod = '<meta http-equiv="last-modified" content="' . $lastmod . '" />' . "\n";
        }
        if (is_static_action($options) or !empty($DBInfo->use_conditional_get) and !empty($mtime) and empty($options['nolastmod']) and $this->page->is_static) {
            $this->header('Last-Modified: ' . $lastmod);
            $etag = $this->page->etag($options);
            if (!empty($options['etag'])) {
                $this->header('ETag: "' . $options['etag'] . '"');
            } else {
                $this->header('ETag: "' . $etag . '"');
            }
        }
        // custom headers
        if (!empty($DBInfo->site_headers)) {
            foreach ((array) $DBInfo->site_headers as $head) {
                $this->header($head);
            }
        }
        $content_type = isset($DBInfo->content_type[0]) ? $DBInfo->content_type : 'text/html';
        $force_charset = '';
        if (!empty($DBInfo->force_charset)) {
            $force_charset = '; charset=' . $DBInfo->charset;
        }
        if (!$plain) {
            $this->header('Content-type: ' . $content_type . $force_charset);
        }
        if (!empty($options['action_mode']) and $options['action_mode'] == 'ajax') {
            return true;
        }
        # disabled
        #$this->header("Vary: Accept-Encoding, Cookie");
        #if (strstr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') and function_exists('ob_gzhandler')) {
        #  ob_start('ob_gzhandler');
        #  $etag.= '.gzip';
        #}
        if (!empty($options['metatags'])) {
            $metatags = $options['metatags'];
        } else {
            $metatags = $DBInfo->metatags;
        }
        if (!empty($options['noindex']) || !empty($this->pi['#noindex']) || (!empty($mtime) and !empty($DBInfo->delayindex) and time() - $mtime < $DBInfo->delayindex)) {
            // delay indexing like as dokuwiki
            if (preg_match("/<meta\\s+name=('|\")?robots\\1[^>]+>/i", $metatags)) {
                $metatags = preg_replace("/<meta\\s+name=('|\")?robots\\1[^>]+>/i", '<meta name="robots" content="noindex,nofollow" />', $metatags);
            } else {
                $metatags .= '<meta name="robots" content="noindex,nofollow" />' . "\n";
            }
        }
        if (isset($DBInfo->metatags_extra)) {
            $metatags .= $DBInfo->metatags_extra;
        }
        $js = !empty($DBInfo->js) ? $DBInfo->js : '';
        if (!$plain) {
            if (isset($options['trail'])) {
                $this->set_trailer($options['trail'], $this->page->name);
            } else {
                if ($DBInfo->origin) {
                    $this->set_origin($this->page->name);
                }
            }
            # find upper page
            $up_separator = '/';
            if (!empty($this->use_namespace)) {
                $up_separator .= '|\\:';
            }
            $pos = 0;
            preg_match('@(' . $up_separator . ')@', $this->page->name, $sep);
            # NameSpace/SubPage or NameSpace:SubNameSpacePage
            if (isset($sep[1])) {
                $pos = strrpos($this->page->name, $sep[1]);
            }
            if ($pos > 0) {
                $upper = substr($this->page->urlname, 0, $pos);
            } else {
                if ($this->group) {
                    $upper = _urlencode(substr($this->page->name, strlen($this->group)));
                }
            }
            // setup keywords
            $keywords = '';
            if (!empty($this->pi['#keywords'])) {
                $keywords = _html_escape($this->pi['#keywords']);
            } else {
                $keys = array();
                $dummy = strip_tags($this->page->title);
                $keys = explode(' ', $dummy);
                $keys[] = $dummy;
                $keys = array_unique($keys);
                $keywords = implode(', ', $keys);
            }
            // add redirects as keywords
            if (!empty($DBInfo->use_redirects_as_keywords)) {
                $r = new Cache_Text('redirects');
                $redirects = $r->fetch($this->page->name);
                if ($redirects !== false) {
                    sort($redirects);
                    $keywords .= ', ' . _html_escape(implode(', ', $redirects));
                }
            }
            // add site specific keywords
            if (!empty($DBInfo->site_keywords)) {
                $keywords .= ', ' . $DBInfo->site_keywords;
            }
            $keywords = "<meta name=\"keywords\" content=\"{$keywords}\" />\n";
            # find sub pages
            if (empty($options['action']) and !empty($DBInfo->use_subindex)) {
                $scache = new Cache_text('subpages');
                if (!($subs = $scache->exists($this->page->name))) {
                    if (($p = strrpos($this->page->name, '/')) !== false) {
                        $rule = _preg_search_escape(substr($this->page->name, 0, $p));
                    } else {
                        $rule = _preg_search_escape($this->page->name);
                    }
                    $subs = $DBInfo->getLikePages('^' . $rule . '\\/', 1);
                    if ($subs) {
                        $scache->update($this->page->name, 1);
                    }
                }
                if (!empty($subs)) {
                    $subindices = '';
                    if (empty($DBInfo->use_ajax)) {
                        $subindices = '<div>' . $this->macro_repl('PageList', '', array('subdir' => 1)) . '</div>';
                        $btncls = 'class="close"';
                    } else {
                        $btncls = '';
                    }
                    $this->subindex = "<fieldset id='wikiSubIndex'>" . "<legend title='[+]' {$btncls} onclick='javascript:toggleSubIndex(\"wikiSubIndex\")'></legend>" . $subindices . "</fieldset>\n";
                }
            }
            if (!empty($options['.title'])) {
                $options['title'] = $options['.title'];
            } else {
                if (empty($options['title'])) {
                    $options['title'] = !empty($this->pi['#title']) ? $this->pi['#title'] : $this->page->title;
                    $options['title'] = _html_escape($options['title']);
                } else {
                    $options['title'] = strip_tags($options['title']);
                }
            }
            $theme_type = !empty($this->_newtheme) ? $this->_newtheme : '';
            if (empty($options['css_url'])) {
                $options['css_url'] = $DBInfo->css_url;
            }
            if (empty($this->pi['#nodtd']) and !isset($options['retstr']) and $theme_type != 2) {
                if (!empty($this->html5)) {
                    if (is_string($this->html5)) {
                        echo $this->html5;
                    } else {
                        echo '<!DOCTYPE html>', "\n", '<html xmlns="http://www.w3.org/1999/xhtml">', "\n";
                    }
                } else {
                    echo $DBInfo->doctype;
                }
            }
            if ($theme_type == 2 or isset($options['retstr'])) {
                ob_start();
            } else {
                echo "<head>\n";
            }
            echo '<meta http-equiv="Content-Type" content="' . $content_type . ';charset=' . $DBInfo->charset . "\" />\n";
            echo <<<JSHEAD
<script type="text/javascript">
/*<![CDATA[*/
_url_prefix="{$DBInfo->url_prefix}";
/*]]>*/
</script>
JSHEAD;
            echo $metatags, $js, "\n";
            echo $this->get_javascripts();
            echo $keywords;
            if (!empty($meta_lastmod)) {
                echo $meta_lastmod;
            }
            $sitename = !empty($DBInfo->title_sitename) ? $DBInfo->title_sitename : $DBInfo->sitename;
            if (!empty($DBInfo->title_msgstr)) {
                $site_title = sprintf($DBInfo->title_msgstr, $sitename, $options['title']);
            } else {
                $site_title = $options['title'] . ' - ' . $sitename;
            }
            // set OpenGraph information
            $act = !empty($options['action']) ? strtolower($options['action']) : 'show';
            $is_show = $act == 'show';
            $is_frontpage = $this->page->name == get_frontpage($DBInfo->lang);
            if (!$is_frontpage && !empty($DBInfo->frontpages) && in_array($this->page->name, $DBInfo->frontpages)) {
                $is_frontpage = true;
            }
            if (!empty($DBInfo->canonical_url)) {
                if (($p = strpos($DBInfo->canonical_url, '%s')) !== false) {
                    $page_url = sprintf($DBInfo->canonical_url, $this->page->urlname);
                } else {
                    $page_url = $DBInfo->canonical_url . $this->page->urlname;
                }
            } else {
                $page_url = qualifiedUrl($this->link_url($this->page->urlname));
            }
            if ($is_show && $this->page->exists()) {
                $oc = new Cache_text('opengraph');
                if ($this->refresh || ($val = $oc->fetch($this->page->name, $this->page->mtime())) === false) {
                    $val = array('description' => '', 'image' => '');
                    if (!empty($this->pi['#redirect'])) {
                        $desc = '#redirect ' . $this->pi['#redirect'];
                    } else {
                        $raw = $this->page->_get_raw_body();
                        if (!empty($this->pi['#description'])) {
                            $desc = $this->pi['#description'];
                        } else {
                            $cut_size = 2000;
                            if (!empty($DBInfo->get_description_cut_size)) {
                                $cut_size = $DBInfo->get_description_cut_size;
                            }
                            $cut = mb_strcut($raw, 0, $cut_size, $DBInfo->charset);
                            $desc = get_description($cut);
                            if ($desc !== false) {
                                $desc = mb_strcut($desc, 0, 200, $DBInfo->charset) . '...';
                            } else {
                                $desc = $this->page->name;
                            }
                        }
                    }
                    $val['description'] = _html_escape($desc);
                    if (!empty($this->pi['#image'])) {
                        if (preg_match('@^(ftp|https?)://@', $this->pi['#image'])) {
                            $page_image = $this->pi['#image'];
                        } else {
                            if (preg_match('@^attachment:("[^"]+"|[^\\s]+)@/', $this->pi['#image'], $m)) {
                                $image = $this->macro_repl('attachment', $m[1], array('link_url' => 1));
                                if ($image[0] != 'a') {
                                    $page_image = $image;
                                }
                            }
                        }
                    }
                    if (empty($page_image)) {
                        // extract the first image
                        $punct = '<>"\'}\\]\\|\\!';
                        if (preg_match_all('@(?<=\\b)((?:attachment:(?:"[^' . $punct . ']+"|[^\\s' . $punct . '?]+)|' . '(?:https?|ftp)://(?:[^\\s' . $punct . ']+)\\.(?:png|jpe?g|gif)))@', $raw, $m)) {
                            foreach ($m[1] as $img) {
                                if ($img[0] == 'a') {
                                    $img = substr($img, 11);
                                    // strip attachment:
                                    $image = $this->macro_repl('attachment', $img, array('link_url' => 1));
                                    if ($image[0] != 'a' && preg_match('@\\.(png|jpe?g|gif)$@i', $image)) {
                                        $page_image = $image;
                                        break;
                                    }
                                } else {
                                    $page_image = $img;
                                    break;
                                }
                            }
                        }
                    }
                    if (empty($page_image) && $is_frontpage) {
                        $val['image'] = qualifiedUrl($DBInfo->logo_img);
                    } else {
                        if (!empty($page_image)) {
                            $val['image'] = $page_image;
                        }
                    }
                    $oc->update($this->page->name, $val, time());
                }
                if (empty($this->no_ogp)) {
                    // for OpenGraph
                    echo '<meta property="og:url" content="' . $page_url . '" />', "\n";
                    echo '<meta property="og:site_name" content="' . $sitename . '" />', "\n";
                    echo '<meta property="og:title" content="' . $options['title'] . '" />', "\n";
                    if ($is_frontpage) {
                        echo '<meta property="og:type" content="website" />', "\n";
                    } else {
                        echo '<meta property="og:type" content="article" />', "\n";
                    }
                    if (!empty($val['image'])) {
                        echo '<meta property="og:image" content="', $val['image'], '" />', "\n";
                    }
                    if (!empty($val['description'])) {
                        echo '<meta property="og:description" content="' . $val['description'] . '" />', "\n";
                    }
                }
                // twitter card
                echo '<meta name="twitter:card" content="summary" />', "\n";
                if (!empty($DBInfo->twitter_id)) {
                    echo '<meta name="twitter:site" content="', $DBInfo->twitter_id, '">', "\n";
                }
                echo '<meta name="twitter:domain" content="', $sitename, '" />', "\n";
                echo '<meta name="twitter:title" content="', $options['title'], '">', "\n";
                echo '<meta name="twitter:url" content="', $page_url, '">', "\n";
                if (!empty($val['description'])) {
                    echo '<meta name="twitter:description" content="' . $val['description'] . '" />', "\n";
                }
                if (!empty($val['image'])) {
                    echo '<meta name="twitter:image:src" content="', $val['image'], '" />', "\n";
                }
                // support google sitelinks serachbox
                if (!empty($DBInfo->use_google_sitelinks)) {
                    if ($is_frontpage) {
                        if (!empty($DBInfo->canonical_url)) {
                            $site_url = $DBInfo->canonical_url;
                        } else {
                            $site_url = qualifiedUrl($this->link_url(''));
                        }
                        echo <<<SITELINK
<script type='application/ld+json'>
{"@context":"http://schema.org",
 "@type":"WebSite",
 "url":"{$site_url}",
 "name":"{$sitename}",
 "potentialAction":{
  "@type":"SearchAction",
  "target":"{$site_url}?goto={search_term}",
  "query-input":"required name=search_term"
 }
}
</script>

SITELINK;
                    }
                }
                echo <<<SCHEMA
<script type='application/ld+json'>
{"@context":"http://schema.org",
 "@type":"WebPage",
 "url":"{$page_url}",
 "dateModified":"{$modified}",
 "name":"{$options['title']}"
}
</script>

SCHEMA;
                if (!empty($val['description'])) {
                    echo '<meta name="description" content="' . $val['description'] . '" />', "\n";
                }
            }
            echo '  <title>', $site_title, "</title>\n";
            echo '  <link rel="canonical" href="', $page_url, '" />', "\n";
            # echo '<meta property="og:title" content="'.$options['title'].'" />',"\n";
            if (!empty($upper)) {
                echo '  <link rel="Up" href="', $this->link_url($upper), "\" />\n";
            }
            $raw_url = $this->link_url($this->page->urlname, "?action=raw");
            $print_url = $this->link_url($this->page->urlname, "?action=print");
            echo '  <link rel="Alternate" title="Wiki Markup" href="', $raw_url, "\" />\n";
            echo '  <link rel="Alternate" media="print" title="Print View" href="', $print_url, "\" />\n";
            $css_html = '';
            if ($options['css_url']) {
                $stamp = '?' . filemtime(__FILE__);
                $css_url = _html_escape($options['css_url']);
                $css_html = '  <link rel="stylesheet" type="text/css" ' . $media . ' href="' . $css_url . "\" />\n";
                if (!empty($DBInfo->custom_css) && file_exists($DBInfo->custom_css)) {
                    $css_html .= '  <link rel="stylesheet" media="screen" type="text/css" href="' . $DBInfo->url_prefix . '/' . $DBInfo->custom_css . "{$stamp}\" />\n";
                } else {
                    if (file_exists('./css/_user.css')) {
                        $css_html .= '  <link rel="stylesheet" media="screen" type="text/css" href="' . $DBInfo->url_prefix . "/css/_user.css{$stamp}\" />\n";
                    }
                }
            }
            echo kbd_handler(!empty($options['prefix']) ? $options['prefix'] : '');
            if (isset($this->_newtheme) and $this->_newtheme == 2 or isset($options['retstr'])) {
                $ret = ob_get_contents();
                ob_end_clean();
                if (isset($options['retstr'])) {
                    $options['retstr'] = $ret;
                }
                $this->header_html = $ret;
                $this->css_html = $css_html;
            } else {
                echo $css_html;
                echo "</head>\n";
            }
        }
        return true;
    }
Пример #9
0
 function getLikePages($needle, $limit = 100, $params = array())
 {
     if (!isset($needle[0])) {
         return false;
     }
     // null needle
     // escape \n char
     $needle = str_replace("\n", "", $needle);
     $total = file_get_contents($this->pagecnt);
     if ($total === false) {
         return false;
     }
     $flst = fopen($this->pagelst, 'r');
     if (!is_resource($flst)) {
         return false;
     }
     $pages = array();
     $pre = '.*';
     $suf = '.*';
     if ($needle[0] == '^') {
         $pre = '';
         $needle = substr($needle, 1);
     }
     if (substr($needle, -1) == '$') {
         $suf = '';
         $needle = substr($needle, 0, -1);
     }
     // check regex
     $test = validate_needle($needle);
     if (!$test) {
         $needle = preg_quote($needle);
     } else {
         $needle = _preg_search_escape($needle);
     }
     fseek($flst, 0, SEEK_END);
     $size = ftell($flst);
     fseek($flst, 0, SEEK_SET);
     $chunk = min(10240, intval($size / 10));
     $chunk = max($chunk, 8192);
     while (!feof($flst)) {
         $data = fread($flst, $chunk);
         $data .= fgets($flst, 2048);
         if (preg_match_all('/^' . $pre . '(?:' . $needle . ')' . $suf . '$/' . $this->_match_flags, $data, $match)) {
             $pages = array_merge($pages, $match[0]);
             if (!empty($limit) and count($pages) > $limit) {
                 if (empty($params['nocut'])) {
                     $pages = array_slice($pages, 0, $limit);
                 }
                 break;
             }
         }
     }
     fclose($flst);
     return $pages;
 }
Пример #10
0
 function getTwinPages($pagename, $mode = 1)
 {
     $norm = preg_replace('/\\s+/', '', $pagename);
     if ($norm == $pagename) {
         $nodb = !dba_exists($pagename, $this->metadb);
     } else {
         $nodb = !dba_exists($pagename, $this->metadb) && !dba_exists($norm, $this->metadb);
     }
     if (!$this->aux->hasPage($pagename) and $nodb) {
         if ($mode) {
             return array();
         }
         return false;
     }
     if (!$mode) {
         return true;
     }
     $twins = dba_fetch($pagename, $this->metadb);
     if ($twins == null) {
         $twins = dba_fetch($norm, $this->metadb);
     }
     $addons = $this->aux->getTwinPages($pagename, $mode);
     $ret = array();
     if ($twins) {
         $ret = "[wiki:" . str_replace(' ', ":{$pagename}] [wiki:", $twins) . ":{$pagename}]";
         $pagename = _preg_search_escape($pagename);
         $ret = preg_replace("/((:[^\\s]+){2})(\\:{$pagename})/", "\\1", $ret);
         $ret = explode(' ', $ret);
     }
     if ($addons) {
         $ret = array_merge($addons, $ret);
     }
     if (sizeof($ret) > 8) {
         if ($mode == 1) {
             return array("TwinPages:{$pagename}");
         }
         $ret = array_map(create_function('$a', 'return " * $a";'), $ret);
     }
     return $ret;
 }
Пример #11
0
function do_subscribe($formatter, $options)
{
    global $DBInfo;
    if (!$DBInfo->notify and 0) {
        # XXX
        $options['title'] = _("EmailNotification is not activated");
        $options['msg'] = _("If you want to subscribe this page please contact the WikiMaster to activate the e-mail notification");
        do_invalid($formatter, $options);
        return;
    }
    if ($options['id'] != 'Anonymous') {
        $udb =& $DBInfo->udb;
        $userinfo = $udb->getUser($options['id']);
        $email = $userinfo->info['email'];
        #$subs=$udb->getPageSubscribers($options[page]);
        if (!$email) {
            $title = _("Please enter your email address first.");
        }
    } else {
        $title = _("Please login or make your ID.");
    }
    if ($options['id'] == 'Anonymous' or !$email) {
        $formatter->send_header("", $options);
        $formatter->send_title($title, "", $options);
        $formatter->send_page("== " . _("Goto UserPreferences") . " ==\n" . _("If you want to subscribe this page, just make your ID and register your email address in the UserPreferences."));
        $formatter->send_footer();
        return;
    }
    if (isset($options['subscribed_pages'])) {
        $pages = preg_replace("/\n\\s*/", "\n", $options['subscribed_pages']);
        $pages = preg_replace("/\\s*\n/", "\n", $pages);
        $pages = explode("\n", $pages);
        $pages = array_unique($pages);
        $page_list = join("\t", $pages);
        $userinfo->info['subscribed_pages'] = $page_list;
        $udb->saveUser($userinfo);
        $title = _("Subscribe lists updated.");
        $formatter->send_header("", $options);
        $formatter->send_title($title, "", $options);
        $formatter->send_page("Goto [{$options['page']}]\n");
        $formatter->send_footer();
        return;
    }
    $plist = _preg_search_escape($userinfo->info['subscribed_pages']);
    $check = 1;
    if (trim($plist)) {
        $plists = explode("\t", $plist);
        $prule = '^' . join("\$|^", $plists) . '$';
        if (preg_match('/(' . $prule . ')/', _preg_search_escape($options['page']))) {
            $title = sprintf(_("\"%s\" is already subscribed."), $options['page']);
            $check = 0;
        }
    }
    $pages = explode("\t", $userinfo->info['subscribed_pages']);
    if ($check) {
        if (!in_array($options['page'], $pages)) {
            $pages[] = $options['page'];
        }
        $title = sprintf(_("Do you want to subscribe \"%s\" ?"), $options['page']);
    }
    $page_lists = join("\n", $pages);
    $formatter->send_header("", $options);
    $formatter->send_title($title, "", $options);
    $msg = _("Subscribed pages");
    print "<form method='post'>\n<table border='0'><tr>\n<th>{$msg} :</th><td><textarea name='subscribed_pages' cols='30' rows='5' value='' />{$page_lists}</textarea></td></tr>\n<tr><td></td><td>\n    <input type='hidden' name='action' value='subscribe' />\n    <input type='submit' value='Subscribe' />\n</td></tr>\n</table>\n    </form>";
    #  $formatter->send_page();
    $formatter->send_footer("", $options);
}