function macro_Category($formatter, $value = '', $params = array()) { if (!isset($formatter->categories)) { $formatter->categories = array(); } if (isset($value[0])) { // add a backlink $tmp = $formatter->word_repl('[[' . $value . ']]'); // is it a category link if (preg_match('@' . $formatter->category_regex . '@', $value)) { $formatter->categories[] = $value; return '<span></span>'; } // not a category link return $tmp; } $cc = new Cache_Text('categories'); if (count($formatter->categories) > 0) { if (!$formatter->preview) { $cc->update($formatter->page->name, $formatter->categories); } $categories = $formatter->categories; } else { if ($formatter->page->exists()) { $categories = $cc->fetch($formatter->page->name); } else { $cc->remove($formatter->page->name); $categories = array(); } } if (!empty($params['call']) || !empty($params['.call'])) { return $categories; } if (empty($categories)) { return ''; } $out = '<div class="wikiCategory">'; $out .= '<h2>' . _("Category") . '</h2>'; $out .= '<ul>'; foreach ($categories as $cat) { if (preg_match('@' . $formatter->category_regex . '@', $cat, $m)) { // strip category prefix if (isset($m[1])) { $text = $m[1]; } else { $text = substr($cat, strlen($m[0])); } $tmp = $formatter->word_repl('[[' . $cat . ']]', $text); $out .= '<li>' . $tmp . '</li>' . "\n"; } } $out .= '</ul></div>'; return $out; }
function macro_WikimediaCommons($formatter, $value, $params = array()) { global $DBInfo, $Config; $args = array(); if (($p = strpos($value, ',')) !== false) { $arg = substr($value, $p + 1); $value = substr($value, 0, $p); $arg = preg_replace('@\\s*,\\s*@', ',', $arg); $arg = preg_replace('@\\s*=\\s*@', '=', $arg); $args = explode(',', $arg); } if (!empty($params['attr'])) { $args = array_merge($args, (array) $params['attr']); } $data = array('action' => 'query', 'prop' => 'imageinfo', 'iiprop' => 'extmetadata|url', 'format' => 'json', 'rawcontinue' => '1'); // default API url $api_url = 'https://commons.wikimedia.org/w/api.php'; // check full url if (preg_match('@^https?://upload\\.wikimedia\\.org/wikipedia/(?:(en|commons)/)?(thumb/)?./../([^/]+\\.(?:gif|jpe?g|png|svg))(?(2)/(\\d+px)-\\3)@', $value, $m)) { // WikiMedia $remain = substr($value, strlen($m[0])); if (!empty($m[1]) && in_array($m[1], array('en'))) { $api_url = 'https://' . $m[1] . '.wikipedia.org/w/api.php'; } $value = urldecode($m[3]); if (!empty($m[4])) { $width = intval($m[4]); } $data['titles'] = 'Image:' . $value; $data['iiprop'] = 'extmetadata|url'; } else { if (preg_match('@^https?://((?:[^.]+)\\.(?:wikimedia|wikipedia)\\.org)/wiki/(?:Image|File):([^/]+\\.(?:gif|jpe?g|png|svg))$@', $value, $m)) { // WikiMedia or WikiPedia $api_url = 'https://' . $m[1] . '/w/api.php'; $value = urldecode($m[2]); $data['titles'] = 'Image:' . $value; $data['iiprop'] = 'extmetadata|url'; $source = _("WikiMedia Commons"); } else { if (preg_match('@^https?://([^.]+)\\.wikia\\.com/wiki/(?:Image|File):(.*\\.(?:gif|jpe?g|png|svg))@', $value, $m)) { $src = 'wikia.'; // Wikia $api_url = 'https://' . $m[1] . '.wikia.com/api.php'; $value = urldecode($m[2]); $data['titles'] = 'Image:' . $value; $data['iiprop'] = 'url|user|size|comment'; $source = _("Wikia"); } else { if (preg_match('@^https?://.*\\.wikia\\..*/([^/]+)/images/./../([^/]+\\.(?:gif|jpe?g|png|svg))@', $value, $m)) { $src = 'wikia.'; // Wikia $api_url = 'https://' . $m[1] . '.wikia.com/api.php'; $value = urldecode($m[2]); $data['titles'] = 'Image:' . $value; $data['iiprop'] = 'url|user|size|comment'; $source = _("Wikia"); } else { $value = urldecode($value); $data['titles'] = 'Image:' . $value; $data['iiprop'] = 'extmetadata|url'; $source = _("WikiMedia Commons"); } } } } $styles = array(); foreach ($args as $arg) { $k = $v = ''; if (($p = strpos($arg, '=')) !== false) { $k = substr($arg, 0, $p); $k = trim($k); $v = substr($arg, $p + 1); $v = trim($v, '"\''); } else { continue; } $k = strtolower($k); switch ($k) { case 'width': case 'height': if (preg_match('@^(\\d+)(px|%)?$@', $v, $m)) { if (isset($m[2]) && $m[2] == '%') { $styles[$k] = $v; } else { $styles[$k] = $v; ${$k} = intval($m[1]); } } break; case 'align': $v = strtolower($v); if (in_array($v, array('left', 'right', 'center'))) { $addClass = ' img' . ucfirst($v); } break; } } $common = new Cache_Text('wikicommons'); $key = $value . $src; if (isset($width)) { $key .= $width; } if (isset($height)) { $key .= '.h' . $height; } if (!empty($formatter->refresh) || ($images = $common->fetch($key)) === false) { if (!empty($width)) { $data['iiurlwidth'] = min(1280, $width); } else { if (!empty($height)) { $data['iiurlheight'] = min(1280, $height); } else { // default image width $data['iiurlwidth'] = 640; } } require_once dirname(__FILE__) . '/../lib/HTTPClient.php'; $http = new HTTPClient(); $save = ini_get('max_execution_time'); set_time_limit(0); // support proxy if (!empty($DBInfo->proxy_host)) { $http->proxy_host = $DBInfo->proxy_host; if (!empty($DBInfo->proxy_port)) { $http->proxy_port = $DBInfo->proxy_port; } } $http->sendRequest($api_url, $data, 'POST'); set_time_limit($save); // FIXME if ($http->status != 200) { return ''; } $res = json_decode($http->resp_body); $images = $res->query->pages; $common->update($key, $images); } $image = current($images); $image_url = $image->imageinfo[0]->thumburl; $desc_url = $image->imageinfo[0]->descriptionurl; if (empty($styles['width']) && !empty($image->imageinfo[0]->thumbwidth)) { $styles['width'] = $image->imageinfo[0]->thumbwidth . 'px'; } $attrs = array(); $keys = array('width', 'height'); foreach ($keys as $key) { if (isset($styles[$key])) { $attrs[] = $key . '="' . $styles[$key] . '"'; unset($styles[$key]); } } $attr = ''; if (count($attrs)) { $attr = ' ' . implode(' ', $attrs); } $style = ''; foreach ($styles as $k => $v) { $style .= $k . ':' . $v . ';'; } if (!empty($style)) { $style = ' style="' . $style . '"'; } if (!empty($image->imageinfo[0]->extmetadata)) { $copyright = $image->imageinfo[0]->extmetadata->Copyrighted->value; $description = $image->imageinfo[0]->extmetadata->ImageDescription->value; $author = $image->imageinfo[0]->extmetadata->Artist->value; $license = $image->imageinfo[0]->extmetadata->License->value; $comment = ''; } else { if (!empty($image->imageinfo[0]->user)) { // Wikia case $copyright = 'True'; $author = sprintf(_("Uploaded by %s"), $image->imageinfo[0]->user); $license = ''; $description = $image->imageinfo[0]->comment; } else { // not found return false; } } if (!empty($formatter->fetch_images) && !empty($image_url)) { $image_url = $formatter->fetch_action . str_replace(array('&', '?'), array('%26', '%3f'), $image_url); // use thumbnails ? if (!empty($formatter->use_thumb_by_default)) { $image_url .= '&thumbwidth=' . $formatter->thumb_width; } } $copyrighted = $copyright == 'True'; $info = ($copyrighted ? '© ' : '(ɔ) ') . $author; if ($copyrighted && isset($license[0])) { $info .= " ({$license})"; } $out = '<div class="externalImage">'; if (empty($addClass)) { $cls = ' class="' . $addClass . '"'; } $out .= "<div" . $cls . "><img src='{$image_url}'{$style}{$attr}>"; $out .= "<div class='info'>" . $info . $comment . ' from ' . "<a href='{$desc_url}' target='_blank'>{$source}</a></div>"; $out .= "</div>"; if (!empty($DBInfo->wikimediacommons_use_description) && !empty($description)) { $out .= '<div class="desc">' . $description . '</div>'; } $out .= "</div>\n"; return $out; }
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&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; }
function do_ipinfo($formatter, $params = array()) { global $DBInfo, $Config; $u = $DBInfo->user; $list = ''; $myip = ''; $mask = 24; $masks = array(24, 25, 16, 18, 8); $ttls = array(1800 => '30 minutes', 3600 => '1 hour', 7200 => '2 hours', 10800 => '3 hours', 21600 => '6 hours', 43200 => '12 hours', 1 => '1 day', 2 => '2 days', 7 => '7 days', 30 => '1 month', 60 => '2 month', 182 => '6 month', 365 => '1 year'); $reasons = array(100 => _("Vandalism"), 150 => _("Abusing"), 200 => _("Incompatible License"), 210 => _("CCL BY"), 220 => _("CCL NC"), 300 => _("Discussion needed"), 400 => _("Robot"), 500 => _("Testing")); if (!empty($params['q'])) { $tmp = normalize_network($params['q']); $myip = $params['q']; if ($tmp === false) { $params['msg'] = sprintf(_("Invalid IP Address %s"), $ip); $params['q'] = ''; } else { $myip = $params['q'] = $ip = $tmp[0]; if ($tmp[1] != 32) { $netmask = $tmp[1]; } } } $control_action = false; if (!empty($params['q']) && isset($_POST) && !empty($params['button_block'])) { $control_action = 'block'; } else { if (!empty($params['q']) && !empty($params['toggle'])) { $control_action = 'toggle'; $params['ttl'] = -1; // HACK to toggle block staus } else { if (!empty($params['q']) && !empty($params['remove'])) { if (in_array($u->id, $DBInfo->owners)) { $control_action = 'remove'; } else { $control_action = 'reset'; } $params['ttl'] = -1; // HACK } } } while ($u->is_member && $control_action !== false) { // check parameters // TTL check if (!empty($params['reason']) and array_key_exists($params['reason'], $reasons)) { $reason = $params['reason']; } if (!empty($params['comment'])) { $comment = $params['comment']; } $ttl = !empty($params['ttl']) ? (int) $params['ttl'] : 1800; // default 30 minutes if (in_array($u->id, $DBInfo->owners)) { $ttl = !empty($params['ttl']) ? $params['ttl'] : 0; // default for owners } else { if ($ttl >= 60) { $ttl = 1800; } } if ($ttl < 0) { $ttl = 1; } else { if ($ttl <= 365) { // days to seconds $ttl = $ttl * 60 * 60 * 24; } } if ($ttl >= 0 && !in_array($u->id, $DBInfo->owners)) { if (empty($comment) && empty($reason)) { $params['msg'] = _("Please select block reason"); break; } } $netmask = !empty($params['netmask']) ? (int) $params['netmask'] : $netmask; if ($netmask >= 32) { $netmask = ''; } $try = $ip; if (!empty($netmask)) { $try .= '/' . $netmask; } $tmp = normalize_network($try); if ($tmp === false) { if (empty($netmask)) { $params['msg'] = sprintf(_("Not a valid IP address: %s"), $try); } else { $params['msg'] = sprintf(_("Not a valid IP range: %s"), $try); } } else { // prepare to return $ret = array(); $retval = array(); $ret['retval'] =& $retval; if ($tmp[1] == 32) { // normalized IP $ip = $tmp[0]; // abusefilter cache $arena = 'abusefilter'; $ac = new Cache_Text('abusefilter'); // fetch monitor information $info = $ac->fetch($ip, 0, $ret); if ($info === false) { $new_info = array('create' => 0, 'delete' => 0, 'revert' => 0, 'save' => 0, 'edit' => 0, 'add_lines' => 0, 'del_lines' => 0, 'add_chars' => 0, 'del_chars' => 0); $new_info['id'] = $ip; $new_info['suspended'] = true; } else { $new_info = $info; $new_info['id'] = $ip; } } else { // normalized IP $ip = $tmp[0] . '/' . $tmp[1]; // ipblock cache $arena = 'ipblock'; $ac = new Cache_Text('ipblock'); // fetch monitor information $info = $ac->fetch($ip, 0, $ret); if ($info === false) { $new_info['id'] = $ip; $new_info['suspended'] = true; } else { $new_info = $info; $new_info['id'] = $ip; } } if (!empty($reason)) { $new_info['reason'] = $reason; } if (!empty($comment)) { // upate comments $comments = array(); if (!empty($info['comment'])) { $comments = explode("\n", $new_info['comment']); } $comments[] = date('Y-m-d H:i', time()) . "\t" . $u->id . "\t" . $comment; if (sizeof($comments) > 100) { array_shift($comments); } $new_info['comment'] = implode("\n", $comments); } if ($ttl == 1) { if ($control_action == 'reset') { $new_info['suspended'] = false; } else { if ($control_action == 'toggle') { $new_info['suspended'] = !$new_info['suspended']; } } $newttl = $retval['ttl'] - (time() - $retval['mtime']); if ($newttl < 0) { $newttl = 0; } if ($control_action == 'remove') { $ac->remove($ip); } else { $ac->update($ip, $new_info, $newttl); } } else { $new_info['suspended'] = true; $ac->update($ip, $new_info, $ttl); } if ($control_action == 'toggle') { $params['msg'] = sprintf(_("Successfully Toggle Block status: %s"), $try); } else { if ($control_action == 'reset') { $params['msg'] = sprintf(_("Successfully Enable IP (range) status: %s"), $try); } else { if ($control_action == 'remove') { $params['msg'] = sprintf(_("Successfully Removed IP range: %s"), $try); } else { if (!empty($netmask)) { $params['msg'] = sprintf(_("Successfully Blocked IP range: %s"), $try); } else { $params['msg'] = sprintf(_("Successfully Blocked IP address: %s"), $try); } } } } } break; } if (!empty($params['q']) && empty($params['button_block'])) { // search $retval = array(); $ret = array('retval' => &$retval); $try = $params['q']; $cache = 'abusefilter'; if (!empty($netmask)) { $try .= '/' . $netmask; $cache = 'ipblock'; } // try to find blocked IP or IP range $ac = new Cache_Text($cache); $info = $ac->fetch($try, 0, $ret); if ($info === false) { // get temporary blocked IP ranges $blocked = get_cached_temporary_blacklist(); $res = search_network($blocked, $params['q'], $ret); $permenant = false; if ($res === false) { // search blacklist ranges $res = search_network($Config['ruleset']['blacklist.ranges'], $params['q'], $ret); $permenant = true; } if ($res) { list($network, $netmask) = explode('/', $retval); if ($netmask == 32) { $title = _("Temporary blocked IP (range) found") . ' : ' . $network; } else { $found = $retval; if ($permenant) { $title = _("Permenantly blocked IP range found") . ' : ' . $found; // show all temporary blocked list $list = macro_IpInfo($formatter); } else { $title = _("Temporary blocked IP range found") . ' : ' . $found; // retrieve found $ac = new Cache_Text('ipblock'); $info = $ac->fetch($found, 0, $ret); if ($info !== false) { $info['ttl'] = $retval['ttl']; $info['mtime'] = $retval['mtime']; $list = macro_IpInfo($formatter, '', array('info' => $info)); } } } } else { $title = _("IP (range) is not found"); // show all temporary blocked list $list = macro_IpInfo($formatter); } } else { $info['ttl'] = $retval['ttl']; $info['mtime'] = $retval['mtime']; $list = macro_IpInfo($formatter, '', array('info' => $info)); $title = _("Temporary blocked IP found") . ' : ' . $params['q']; } } else { if ($u->is_member) { $opt = 'range'; if (!empty($params['static'])) { $opt = 'static'; } if (!empty($params['all'])) { $opt = ''; } $list = macro_IpInfo($formatter, $opt); } else { if (!$u->is_member) { $myip = $params['q'] = $_SERVER['REMOTE_ADDR']; } } } $params['.title'] = _("IP Information"); if (!empty($title)) { $params['title'] = $title; } else { if (!empty($params['q'])) { $params['title'] = sprintf(_("%s: IP Information"), $params['q']); } } $formatter->send_header('', $params); $formatter->send_title($title, '', $params); $searchform = <<<FORM <form method='post' action=''> <label>Search</label>: <input type='text' name='q' value='{$myip}' placeholder='IP or IP range' /> <input type='submit' name='button_search' value='search' /><br /> <input type='hidden' name='action' value='ipinfo' /> </form> FORM; echo '<h2>' . _("Temporary blocked IPs") . '</h2>', "\n"; echo $searchform; echo $list; echo $searchform; echo '<h2>' . _("Input IP or IP range") . '</h2>', "\n"; $mask_select = '<select name="netmask"><option value="">-- ' . _("Netmask") . ' --</option>' . "\n"; foreach ($masks as $m) { $selected = ''; if ($m == $netmask) { $selected = ' selected="selected"'; } $mask_select .= '<option value="' . $m . '"' . $selected . '>' . "\n"; $mask_select .= $m . ' : '; $c = 1 << 32 - $m; if ($c > 1) { $c -= 2; } $mask_select .= number_format($c) . ' IPs'; $mask_select .= '</option>' . "\n"; } $mask_select .= '</select>' . "\n"; $ttl_select = '<select name="ttl"><option value="0">-- ' . _("Expire") . ' --</option>' . "\n"; foreach ($ttls as $time => $str) { $ttl_select .= '<option value="' . $time . '">' . $str . '</option>' . "\n"; } $ttl_select .= '</select>' . "\n"; $reason_select = '<select name="reason"><option value="">-- ' . _("Block reason") . ' --</option>' . "\n"; foreach ($reasons as $code => $str) { $reason_select .= '<option value="' . $code . '">' . $str . '</option>' . "\n"; } $reason_select .= '</select>' . "\n"; $ip_lab = _("IP Address"); $net_lab = _("Netmask (i.e. 24)"); $ttl_lab = _("Expire"); $block_btn = _("Block IP"); echo <<<FORM <form method='post' action=''> <table class='wiki'><tr><th>{$ip_lab}</th> <th>{$net_lab}</th> <th>{$ttl_lab}</th> </tr> <tr> <td><input type='text' name='q' value='{$myip}' /></td> <td> {$mask_select} </td> <td> {$ttl_select} </td> </tr> <tr><td>{$reason_select}</td><td colspan='2'><input type='text' name='comment' size='50' /></td></tr> </table> FORM; echo <<<FORM <input type='hidden' name='action' value='ipinfo' /> <input type='submit' name='button_block' value='{$block_btn}' /> </form> FORM; $formatter->send_footer('', $params); }
function do_rss_rc($formatter, $options) { global $DBInfo, $Config; // get members to hide log $members = $DBInfo->members; $days = !empty($DBInfo->rc_days) ? $DBInfo->rc_days : RSS_DEFAULT_DAYS; $options['quick'] = 1; if (!empty($options['c'])) { $options['items'] = $options['c']; } $lines = $DBInfo->editlog_raw_lines($days, $options); if (!empty($DBInfo->rss_rc_options)) { $opts = $DBInfo->rss_rc_options; $opts = explode(',', $opts); foreach ($opts as $opt) { $options[$opt] = 1; // FIXME } } // HTTP conditional get $mtime = $DBInfo->mtime(); $lastmod = gmdate('D, d M Y H:i:s \\G\\M\\T', $mtime); $cache_ttl = !empty($DBInfo->rss_rc_ttl) ? $DBInfo->rss_rc_ttl : 60; /* 60 seconds */ // make etag based on some options and mtime. $check_opts = array('quick', 'items', 'oe', 'diffs', 'raw', 'nomsg', 'summary'); $check = array(); foreach ($check_opts as $c) { if (isset($options[$c])) { $check[$c] = $options[$c]; } } $etag = md5($mtime . $DBInfo->logo_img . serialize($check) . $cache_ttl . $options['id']); $headers = array(); $headers[] = 'Pragma: cache'; $maxage = $cache_ttl; $public = 'public'; if ($options['id'] != 'Anonymous') { $public = 'private'; } $headers[] = 'Cache-Control: ' . $public . ', max-age=' . $maxage; $headers[] = 'Last-Modified: ' . $lastmod; $headers[] = 'ETag: "' . $etag . '"'; $need = http_need_cond_request($mtime, $lastmod, $etag); if (!$need) { $headers[] = 'HTTP/1.0 304 Not Modified'; } foreach ($headers as $h) { header($h); } if (!$need) { @ob_end_clean(); return; } $cache = new Cache_Text('rss_rc'); $cache_delay = min($cache_ttl, 30); $mtime = $cache->mtime($etag); $val = false; if (empty($formatter->refresh)) { if (($val = $cache->fetch($etag)) !== false and $DBInfo->checkUpdated($mtime, $cache_delay)) { header("Content-Type: text/xml"); echo $val; return; } } // need to update cache if ($val !== false and $cache->exists($etag . '.lock')) { header("Content-Type: text/xml"); echo $val . '<!-- cached at ' . date('Y-m-d H:i:s', $mtime) . ' -->'; return; } if ($cache->exists($etag . '.lock')) { header("Content-Type: text/xml"); echo ''; return; } $cache->update($etag . '.lock', array('lock'), 5); // 5s lock $time_current = time(); # $secs_per_day= 60*60*24; # $days_to_show= 30; # $time_cutoff= $time_current - ($days_to_show * $secs_per_day); $URL = qualifiedURL($formatter->prefix); $img_url = qualifiedURL($DBInfo->logo_img); $url = qualifiedUrl($formatter->link_url("RecentChanges")); $channel = <<<CHANNEL <channel rdf:about="{$URL}"> <title>{$DBInfo->sitename}</title> <link>{$url}</link> <description>RecentChanges at {$DBInfo->sitename}</description> <image rdf:resource="{$img_url}"></image> <items> <rdf:Seq> CHANNEL; $items = ""; $ratchet_day = FALSE; if (!$lines) { $lines = array(); } foreach ($lines as $line) { $parts = explode("\t", $line); $page_name = $DBInfo->keyToPagename($parts[0]); // hide log if (!empty($members) && !in_array($options['id'], $members) && !empty($Config['ruleset']['hidelog'])) { if (in_array($page_name, $Config['ruleset']['hidelog'])) { continue; } } $addr = $parts[1]; $ed_time = $parts[2]; $user = $parts[4]; $log = _stripslashes($parts[5]); $act = rtrim($parts[6]); # if ($ed_time < $time_cutoff) # break; $url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name))); $diff_url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name), '?action=diff')); $extra = "<br /><a href='{$diff_url}'>" . _("show changes") . "</a>\n"; if (!$DBInfo->hasPage($page_name)) { $status = 'deleted'; $html = '<![CDATA[' . "<a href='{$url}'>" . $page_name . "</a> is deleted" . ']]>' . "\n"; } else { $status = 'updated'; if (!empty($options['diffs'])) { $p = new WikiPage($page_name); $f = new Formatter($p); $options['raw'] = 1; $options['nomsg'] = 1; $html = $f->macro_repl('Diff', '', $options); if (!$html) { ob_start(); $f->send_page('', array('fixpath' => 1)); #$f->send_page(''); $html = ob_get_contents(); ob_end_clean(); $extra = ''; } $html = str_replace(']', ']', $html); $html = "<![CDATA[" . $html . $extra . "]]>"; #$html=strtr($html.$extra,array('&'=>'&','<'=>'<')); } else { if (!empty($options['summary'])) { $p = new WikiPage($page_name); $f = new Formatter($p); $f->section_edit = 0; $f->sister_on = 0; $f->perma_icon = ''; $options['nomsg'] = 1; $b = $p->_get_raw_body(); $chunks = preg_split('/\\n#{4,}/', $b); # summary breaker is #### ob_start(); if ($chunks) { $f->send_page($chunks[0], array('fixpath' => 1)); } else { $f->send_page('', array('fixpath' => 1)); } #$f->send_page(''); $html = ob_get_contents(); ob_end_clean(); $chunks = preg_split('/<!-- break -->/', $html); # <!-- break --> if ($chunks[0]) { $html = $chunks[0]; } $html = str_replace(']', ']', $html); $html = "<![CDATA[" . $html . "]]>"; } else { $html = str_replace('&', '&', $log); } } } $zone = "+00:00"; $date = gmdate("Y-m-d\\TH:i:s", $ed_time) . $zone; #$datetag = gmdate("YmdHis",$ed_time); $channel .= "<rdf:li rdf:resource=\"{$url}\"></rdf:li>\n"; $valid_page_name = preg_replace('/&(?!#?\\w+;)/', '&', _html_escape($page_name)); $items .= "<item rdf:about=\"{$url}\">\n"; $items .= " <title>{$valid_page_name}</title>\n"; $items .= " <link>{$url}</link>\n"; $items .= " <description>{$html}</description>\n"; $items .= " <dc:date>{$date}</dc:date>\n"; $items .= "<dc:creator>{$user}</dc:creator>\n"; $items .= "<dc:contributor>{$user}</dc:contributor>\n"; # $items.=" <dc:contributor>\n <rdf:Description>\n" # ." <rdf:value>$user</rdf:value>\n" # ." </rdf:Description>\n </dc:contributor>\n"; $items .= " <wiki:status>{$status}</wiki:status>\n"; $items .= " <wiki:diff>{$diff_url}</wiki:diff>\n"; $items .= "</item>\n"; } $url = qualifiedUrl($formatter->link_url($DBInfo->frontpage)); $channel .= <<<FOOT </rdf:Seq> </items> </channel> <image rdf:about="{$img_url}"> <title>{$DBInfo->sitename}</title> <link>{$url}</link> <url>{$img_url}</url> </image> FOOT; $url = qualifiedUrl($formatter->link_url("FindPage")); $form = <<<FORM <textinput> <title>Search</title> <link>{$url}</link> <name>goto</name> </textinput> FORM; $new = ""; if (!empty($options['oe']) and strtolower($options['oe']) != $DBInfo->charset) { $charset = $options['oe']; if (function_exists('iconv')) { $out = $head . $channel . $items . $form; $new = iconv($DBInfo->charset, $charset, $out); if (!$new) { $charset = $DBInfo->charset; } } } else { $charset = $DBInfo->charset; } $head = <<<HEAD <?xml version="1.0" encoding="{$charset}"?> <?xml-stylesheet href="{$DBInfo->url_prefix}/css/_feed.css" type="text/css"?> <rdf:RDF xmlns="http://purl.org/rss/1.0/" \txmlns:wiki="http://purl.org/rss/1.0/modules/wiki/" \txmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" \txmlns:xlink="http://www.w3.org/1999/xlink" \txmlns:dc="http://purl.org/dc/elements/1.1/"> <!-- Add "diffs=1" to add change diffs to the description of each items. Add "summary=1" to add summary to the description of each items. Add "oe=utf-8" to convert the charset of this rss to UTF-8. --> HEAD; header("Content-Type: text/xml"); if ($new) { $out = $head . $new; } else { $out = $head . $channel . $items . $form; } $out .= "</rdf:RDF>\n"; echo $out; $cache->update($etag, $out); $cache->remove($etag . '.lock'); }
function do_contributors($formatter, $options) { global $DBInfo, $Config; if (!$formatter->page->exists()) { $formatter->send_header('', $options); $title = _("Page not found."); $formatter->send_title($title, '', $options); $formatter->send_footer('', $options); return; } // get contributors $params = array(); $retval = array(); $params['retval'] =& $retval; if (!empty($DBInfo->version_class)) { $cache = new Cache_Text('infostat'); if (!$formatter->refresh and $cache->exists($formatter->page->name)) { $retval = $cache->fetch($formatter->page->name); } if (empty($retval)) { $version = $DBInfo->lazyLoad('version', $DBInfo); $out = $version->rlog($formatter->page->name, '', '', '-z'); $retval = array(); if (!isset($out[0])) { $msg = _("No older revisions available"); $info = "<h2>{$msg}</h2>"; } else { $params = array(); $params['all'] = 1; $params['id'] = $options['id']; $params['retval'] =& $retval; $ret = _stat_rlog($formatter, $out, $params); } if (!empty($retval)) { $cache->update($formatter->page->name, $retval); } } } $formatter->send_header('', $options); $title = _("Contributors of this page"); $formatter->send_title($title, '', $options); // do not check admin member users $user = $DBInfo->user; $ismember = $user->is_member; $total = count($retval['revs']); $total_lab = _("Total Revisions"); $initial = $retval['rev']; $init_lab = _("Initial Revision"); $contrib_lab = _("User"); $edit_lab = _("Edit Count"); echo <<<HEAD <div class="wikiInfo"> <table class="wiki center"> <tr> <th>{$total_lab}</th><th>{$total}</th> </tr> <tr> <th>{$init_lab}</th><th>r{$initial}</th> </tr> <tr> <th>{$contrib_lab}</th><th>{$edit_lab}</th> </tr> HEAD; $opt = intval($Config['mask_hostname']); // sort users $authors = array_keys($retval['users']); $edits = array(); foreach ($authors as $n) { if ($retval['users'][$n]['edit'] > 0) { $edits[$n] = $retval['users'][$n]['edit']; } } // sort by edits arsort($edits); foreach ($edits as $u => $c) { if (!$ismember && preg_match('/^([0-9]+\\.){3}[0-9]+$/', $u)) { $u = _mask_hostname($u, $opt); } else { $u = $formatter->link_tag($formatter->page->urlname, '?action=userinfo&q=' . $u, $u); } echo "<tr><td>", $u, "</td><td>", $c, "</td></tr>\n"; } echo "</table></div>"; $formatter->send_footer('', $options); return; }
function do_userinfo($formatter, $options) { global $DBInfo; $user =& $DBInfo->user; $min_ttl = !empty($DBInfo->user_suspend_time_default) ? intval($DBInfo->user_suspend_time_default) : 60 * 30; $formatter->send_header('', $options); $allowed = $DBInfo->security_class == 'acl' && $DBInfo->security->is_allowed($options['action'], $options); $ismember = $user->is_member; $suspend = !empty($options['suspend']) ? true : false; $pause = !empty($options['pause']) ? true : false; $comment_btn = !empty($options['comment_btn']) ? true : false; $comment = !empty($options['comment']) ? trim($options['comment']) : ''; $uids = (array) $options['uid']; if ($user->id == 'Anonymous') { $myid = $_SERVER['REMOTE_ADDR']; } else { $myid = $user->id; } if (!$ismember && $allowed) { // not a member users $suspend = false; if (empty($comment)) { $comment_btn = false; } else { $comment_btn = true; } // a normal user can pause himself if (sizeof($uids) > 1 || $uids[0] != $myid) { $pause = false; } // reset type $options['type'] = ''; } // cleanup comment $comment = strtr($comment, array("\n" => ' ', "\t" => ' ')); $comment = _html_escape($comment); // FIXME only owners can delete/suspend users $can_delete_user = in_array($user->id, $DBInfo->owners); if ($allowed || $ismember) { if (isset($_POST) and empty($options['act']) and isset($options['uid'])) { $udb =& $DBInfo->udb; $type = !empty($options['type']) ? $options['type'] : ''; if (!in_array($type, array('wait', 'del'))) { $type = ''; } // normal user not allowed to suspend, delete user if (!$can_delete_user) { $suspend = false; $type = ''; } $change = array(); if ($can_delete_user and !$pause and !$comment_btn) { foreach ($uids as $uid) { $uid = _stripslashes($uid); if ($type == 'del' || $type == 'wait' || $suspend) { $ret = $udb->activateUser($uid, $suspend); } else { $ret = $udb->delUser($uid); } if ($ret) { $change[] = $uid; } } } else { if ($comment_btn and !empty($comment)) { $mb = new Cache_Text('msgboard'); foreach ($uids as $uid) { $info = $mb->fetch($uid, 0); $ttl = 0; if ($info === false) { $info = array(); $info['comment'] = ''; } // add comment if (!empty($comment)) { // upate comments $comments = array(); if (!empty($info['comment'])) { $comments = explode("\n", $info['comment']); } $comments[] = date('Y-m-d H:i', time()) . "\t" . $myid . "\t" . $comment; if ($uid == '127.0.0.1' and sizeof($comments) > 500) { array_shift($comments); } else { if (sizeof($comments) > 1000) { array_shift($comments); } } $info['comment'] = implode("\n", $comments); } $mb->update($uid, $info); $change[] = $uid; } } else { if (!empty($uids) && $pause) { // user can suspend temporary himself if ($ismember || sizeof($uids) == 1 && $uid == $user->id) { $change = $uids; } } } } if (!empty($change)) { $changed = implode(',', $change); if ($suspend) { $options['msg'] = sprintf(_("User \"%s\" are suspended !"), _html_escape($changed)); } else { if ($pause) { $options['msg'] = sprintf(_("User \"%s\" are temporary suspended !"), _html_escape($changed)); } else { if ($type == 'del' || $type == 'wait') { $options['msg'] = sprintf(_("User \"%s\" are activated !"), _html_escape($changed)); } else { if ($comment_btn) { $options['msg'] = sprintf(_("Message added to \"%s\"."), _html_escape($changed)); } else { $options['msg'] = sprintf(_("User \"%s\" are deleted !"), _html_escape($changed)); } } } } } if ((!$suspend and $type == 'del' || $type == 'wait' or $pause) and !empty($change)) { // make users temporary suspdended 5-minutes // or temporary suspdended 30 minutes for newly suspended user // abusefilter cache $ac = new Cache_Text('abusefilter'); // prepare to return $ret = array(); $retval = array(); $ret['retval'] =& $retval; foreach ($change as $q) { // fetch monitor information $info = $ac->fetch($q, 0, $ret); $ttl = 0; if ($info === false) { $new_info = array('create' => 0, 'delete' => 0, 'revert' => 0, 'save' => 0, 'edit' => 0, 'add_lines' => 0, 'del_lines' => 0, 'add_chars' => 0, 'del_chars' => 0); $new_info['id'] = $q; if ($pause) { $ttl = $min_ttl; } else { $ttl = 60 * 5; } } else { $new_info = $info; $ttl = $retval['ttl'] - (time() - $retval['mtime']); $new_info['id'] = $q; if ($pause) { $addttl = $min_ttl; } else { $addttl = 60 * 5; } if ($ttl < $addttl) { $ttl = $addttl; } } $new_info['suspended'] = true; // add comment if (!empty($comment)) { // add comment $comments = array(); if (!empty($new_info['comment'])) { $comments = explode("\n", $new_info['comment']); } $comments[] = date('Y-m-d H:i', time()) . "\t" . $user->id . "\t" . $comment; if ($q == '127.0.0.1' and sizeof($comments) > 10) { array_shift($comments); } else { if (sizeof($comments) > 5) { array_shift($comments); } } $new_info['comment'] = implode("\n", $comments); } $ac->update($q, $new_info, $ttl); } } } $list = macro_UserInfo($formatter, '', $options); } else { $options['msg'] = sprintf(_("You are not allowed to \"%s\" !"), "userinfo"); $list = ''; } $options['.title'] = _("User Information"); $formatter->send_title('', '', $options); print $list; $formatter->send_footer('', $options); return; }
$ii = 1; while (($file = readdir($handle)) !== false) { if (is_dir($DBInfo->text_dir . "/" . $file)) { continue; } $pagename = $DBInfo->keyToPagename($file); print "* [{$ii}] {$pagename} "; $ii++; $p = $DBInfo->getPage($pagename); $formatter->page = $p; $raw = $p->_get_raw_body(); $pagelinks = get_pagelinks($formatter, $raw); $cache->update($pagename, $pagelinks); foreach ($pagelinks as $a) { if (!isset($a[0])) { continue; } $bl = $bc->fetch($a); if (!is_array($bl)) { $bl = array(); } $bl = array_merge($bl, array($pagename)); $bc->update($a, $bl); } print ' ' . count($pagelinks) . "\n"; //if ($ii == 1000) break; } closedir($handle); $options['timer']->Check("done"); echo $options['timer']->Write(); // vim:et:sts=4:sw=4:
function do_atom($formatter, $options) { global $DBInfo, $Config; global $_release; define('ATOM_DEFAULT_DAYS', 7); // get members to hide log $members = $DBInfo->members; $days = $DBInfo->rc_days ? $DBInfo->rc_days : ATOM_DEFAULT_DAYS; $options['quick'] = 1; if ($options['c']) { $options['items'] = $options['c']; } $lines = $DBInfo->editlog_raw_lines($days, $options); // HTTP conditional get $mtime = $DBInfo->mtime(); $lastmod = gmdate('D, d M Y H:i:s \\G\\M\\T', $mtime); $cache_ttl = !empty($DBInfo->atom_ttl) ? $DBInfo->atom_ttl : 60 * 30; /* 30 minutes */ // make etag based on some options and mtime. $check_opts = array('quick', 'items', 'c'); $check = array(); foreach ($check_opts as $c) { if (isset($options[$c])) { $check[$c] = $options[$c]; } } $etag = md5($mtime . $DBInfo->logo_img . serialize($check) . $cache_ttl . $options['id']); $headers = array(); $headers[] = 'Pragma: cache'; $maxage = $cache_ttl; $public = 'public'; if ($options['id'] != 'Anonymous') { $public = 'private'; } $headers[] = 'Cache-Control: ' . $public . ', max-age=' . $maxage; $headers[] = 'Last-Modified: ' . $lastmod; $headers[] = 'ETag: "' . $etag . '"'; $need = http_need_cond_request($mtime, $lastmod, $etag); if (!$need) { $headers[] = 'HTTP/1.0 304 Not Modified'; } foreach ($headers as $h) { header($h); } if (!$need) { @ob_end_clean(); return; } $cache = new Cache_Text('atom'); $cache_delay = min($cache_ttl, 30); $mtime = $cache->mtime($etag); $time_current = time(); $val = false; if (empty($formatter->refresh)) { if (($val = $cache->fetch($etag)) !== false and $DBInfo->checkUpdated($mtime, $cache_delay)) { header("Content-Type: application/xml"); echo $val; return; } } // need to update cache if ($val !== false and $cache->exists($etag . '.lock')) { header("Content-Type: application/xml"); echo $val . '<!-- cached at ' . date('Y-m-d H:i:s', $mtime) . ' -->'; return; } if ($cache->exists($etag . '.lock')) { header("Content-Type: application/xml"); echo ''; return; } $cache->update($etag . '.lock', array('lock'), 30); // 30s lock $URL = qualifiedURL($formatter->prefix); $img_url = qualifiedURL($DBInfo->logo_img); $url = qualifiedUrl($formatter->link_url($DBInfo->frontpage)); $surl = qualifiedUrl($formatter->link_url($options['page'] . '?action=atom')); $channel = <<<CHANNEL <title>{$DBInfo->sitename}</title> <link href="{$url}"></link> <link rel="self" type="application/atom+xml" href="{$surl}" /> <subtitle>RecentChanges at {$DBInfo->sitename}</subtitle> <generator version="{$_release}">MoniWiki Atom feeder</generator> CHANNEL; $items = ""; $ratchet_day = FALSE; if (!$lines) { $lines = array(); } foreach ($lines as $line) { $parts = explode("\t", $line); $page_name = $DBInfo->keyToPagename($parts[0]); // hide log if (!empty($members) && !in_array($options['id'], $members) && !empty($Config['ruleset']['hidelog'])) { if (in_array($page_name, $Config['ruleset']['hidelog'])) { continue; } } $addr = $parts[1]; $ed_time = $parts[2]; $user = $parts[4]; $user_uri = ''; if ($user != 'Anonymous' && $DBInfo->hasPage($user)) { $user_uri = $formatter->link_url(_rawurlencode($user), "", $user); $user_uri = '<uri>' . $user_uri . '</uri>'; } $log = _stripslashes($parts[5]); $act = rtrim($parts[6]); $url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name))); $diff_url = qualifiedUrl($formatter->link_url(_rawurlencode($page_name), '?action=diff')); $extra = "<br /><a href='{$diff_url}'>" . _("show changes") . "</a>\n"; $content = ''; if (!$DBInfo->hasPage($page_name)) { $status = 'deleted'; $content = "<content type='html'><a href='{$url}'>{$page_name}</a> is deleted</content>\n"; } else { $status = 'updated'; if ($options['diffs']) { $p = new WikiPage($page_name); $f = new Formatter($p); $options['raw'] = 1; $options['nomsg'] = 1; $html = $f->macro_repl('Diff', '', $options); if (!$html) { ob_start(); $f->send_page('', array('fixpath' => 1)); #$f->send_page(''); $html = ob_get_contents(); ob_end_clean(); $extra = ''; } $content = " <content type='xhtml'><div xmlns='http://www.w3.org/1999/xhtml'>{$html}</content>\n"; } else { if ($log) { $html = str_replace('&', '&', $log); $content = "<content type='text'>" . $html . "</content>\n"; } else { $content = "<content type='text'>updated</content>\n"; } } } $zone = '+00:00'; $date = gmdate("Y-m-d\\TH:i:s", $ed_time) . $zone; if (!isset($updated)) { $updated = $date; } #$datetag = gmdate("YmdHis",$ed_time); $valid_page_name = str_replace('&', '&', $page_name); $items .= "<entry>\n"; $items .= " <title>{$valid_page_name}</title>\n"; $items .= " <link href='{$url}'></link>\n"; $items .= ' ' . $content; $items .= " <author><name>{$user}</name>{$user_uri}</author>\n"; $items .= " <updated>{$date}</updated>\n"; $items .= " <contributor><name>{$user}</name>{$user_uri}</contributor>\n"; $items .= "</entry>\n"; } $updated = " <updated>{$updated}</updated>\n"; $new = ""; if ($options['oe'] and strtolower($options['oe']) != $DBInfo->charset) { $charset = $options['oe']; if (function_exists('iconv')) { $out = $head . $channel . $items . $form; $new = iconv($DBInfo->charset, $charset, $out); if (!$new) { $charset = $DBInfo->charset; } } } else { $charset = $DBInfo->charset; } $head = <<<HEAD <?xml version="1.0" encoding="{$charset}"?> <!--<?xml-stylesheet href="{$DBInfo->url_prefix}/css/_feed.css" type="text/css"?>--> <feed xmlns="http://www.w3.org/2005/Atom"> <!-- Add "diffs=1" to add change diffs to the description of each items. Add "oe=utf-8" to convert the charset of this rss to UTF-8. --> HEAD; header("Content-Type: application/xml"); $out = ''; if ($new) { $out = $head . $new; } else { $out = $head . $channel . $updated . $items . $form; } $out .= "</feed>\n"; echo $out; $cache->update($etag, $out); $cache->remove($etag . '.lock'); }
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; }
function macro_Stat($formatter, $value, $options = array()) { global $DBInfo; if (!empty($DBInfo->version_class)) { $cache = new Cache_Text('infostat'); $retval = array(); if (!$formatter->refresh and $cache->exists($formatter->page->name)) { $retval = $cache->fetch($formatter->page->name); } if (empty($retval)) { $version = $DBInfo->lazyLoad('version', $DBInfo); $out = $version->rlog($formatter->page->name, '', '', '-z'); $retval = array(); if (!isset($out[0])) { $msg = _("No older revisions available"); $info = "<h2>{$msg}</h2>"; } else { $params = array(); $params['all'] = 1; $params['id'] = $options['id']; $params['retval'] =& $retval; $ret = _stat_rlog($formatter, $out, $params); } if (!empty($retval)) { $cache->update($formatter->page->name, $retval); } } $merge_ip = true; if (!empty($DBInfo->stat_no_merge_ip_users) && empty($options['merge_ip_users'])) { $merge_ip = false; } if ($merge_ip) { $users =& $retval['users']; foreach ($users as $k => $v) { foreach ($v['ip'] as $ip => $dummy) { $users[$k]['add'] += $users[$ip]['add']; $users[$k]['del'] += $users[$ip]['del']; $users[$k]['edit'] += $users[$ip]['edit']; $users[$k]['rev'] = array_merge($users[$k]['rev'], $users[$ip]['rev']); unset($users[$ip]); } } } if (!empty($retval)) { if (isset($options['retval'])) { $info = _render_stat($formatter, $retval, $options); return $info; } else { $info = _render_stat($formatter, $retval, $options); } $formatter->register_javascripts('js/chart/Chart.min.js'); } if (isset($options['retval'])) { return -1; } } else { $msg = _("Version info is not available in this wiki"); $info = "<h2>{$msg}</h2>"; } if (isset($options['retval'])) { return -1; } return $info; }
function do_editlogbin($formatter, $params = array()) { global $Config, $DBInfo; $cache = new Cache_Text('editlogbin'); if (!empty($params['title'])) { if (!$DBInfo->hasPage($params['title'])) { unset($params['title']); } } $args = array(); $user = !empty($params['q']) ? $params['q'] : ''; $start = !empty($params['start']) ? $params['start'] : ''; $domain = !empty($params['domain']) ? $params['domain'] : ''; $title = !empty($params['title']) ? $params['title'] : ''; // get timestamp $oldest_stamp = !empty($Config['editlogbin_datetime_oldest']) ? strtotime($Config['editlogbin_datetime_oldest']) : strtotime('-1 year'); if ($oldest_stamp < strtotime('-10 years')) { // too old $oldest_stamp = strtotime('-1 year'); } if (!empty($start)) { if (is_numeric($start)) { // timestamp $from = $start; } else { $from = strtotime($start); } // convert to timestamp } else { $from = $oldest_stamp; } // restrict range $params['until'] = null; // reset if ($from < $oldest_stamp) { $max_range = !empty($Config['editlogbin_datetime_max_range']) ? strtotime($Config['editlogbin_datetime_max_range'], $from) : strtotime('1 year', $from); $params['until'] = $max_range; } //echo date('Y.m.d H.i.s', $params['until']); $mtime = $DBInfo->mtime(); $key = $user . '.' . $from . '.' . $domain . '.' . $title . $mtime; if (empty($formatter->refresh) && ($val = $cache->fetch($key)) !== false) { header('Content-Type: text/plain'); echo json_encode($val['data']); return; } $fp = fopen($Config['editlog_name'], 'r'); $seek = _editlog_seek($fp, $from); $data = _editlog_binning($fp, $seek, $from, 60 * 60 * 24, $params); fclose($fp); header('Content-Type: text/plain'); $cache->update($key, $data, 60 * 60 * 24); // TTL to 24 hour echo json_encode($data['data']); }
function macro_WikimediaCommons($formatter, $value, $params = array()) { global $DBInfo, $Config; // FIXME urldecode for some cases $value = urldecode($value); if (($p = strpos($value, ',')) !== false) { $arg = substr($value, $p + 1); $value = substr($value, 0, $p); $arg = preg_replace('@\\s*,\\s*@', ',', $arg); $arg = preg_replace('@\\s*=\\s*@', '=', $arg); $args = explode(',', $arg); } // check full url if (preg_match('@^https?://upload\\.wikimedia\\.org/wikipedia/commons/(thumb/)?./../([^/]+\\.(?:gif|jpe?g|png|svg))(?(1)/(\\d+px)-\\2)@', $value, $m)) { $remain = substr($value, strlen($m[0])); $value = $m[2]; if (!empty($m[3])) { $width = intval($m[3]); } } $styles = array(); foreach ($args as $arg) { $k = $v = ''; if (($p = strpos($arg, '=')) !== false) { $k = substr($arg, 0, $p); $v = substr($arg, $p + 1); } else { continue; } $k = strtolower($k); switch ($k) { case 'width': case 'height': if (preg_match('@^(\\d+)(px|%)?$@', $v, $m)) { if (isset($m[2]) && $m[2] == '%') { $styles[$k] = $v; } else { $styles[$k] = $v; ${$k} = intval($m[1]); } } break; case 'align': $v = strtolower($v); if (in_array($v, array('left', 'right', 'center'))) { $addClass = ' img' . ucfirst($v); } break; } } $common = new Cache_Text('wikicommons'); $key = $value; if (isset($width)) { $key .= $width; } if (isset($height)) { $key .= '.h' . $height; } if (!empty($formatter->refresh) || ($images = $common->fetch($key)) === false) { $api_url = 'https://commons.wikimedia.org/w/api.php'; $data = array('action' => 'query', 'titles' => 'Image:' . $value, 'prop' => 'imageinfo', 'iiprop' => 'extmetadata|url', 'format' => 'json', 'rawcontinue' => '1'); if (!empty($width)) { $data['iiurlwidth'] = min(1280, $width); } else { if (!empty($height)) { $data['iiurlheight'] = min(1280, $height); } else { // default image width $data['iiurlwidth'] = 640; } } require_once dirname(__FILE__) . '/../lib/HTTPClient.php'; $http = new HTTPClient(); $save = ini_get('max_execution_time'); set_time_limit(0); $http->sendRequest($api_url, $data, 'POST'); set_time_limit($save); // FIXME if ($http->status != 200) { return ''; } $res = json_decode($http->resp_body); $images = $res->query->pages; $common->update($key, $images); } $image = current($images); $image_url = $image->imageinfo[0]->thumburl; $desc_url = $image->imageinfo[0]->descriptionurl; if (empty($styles['width'])) { $styles['width'] = $image->imageinfo[0]->thumbwidth . 'px'; } $style = ''; foreach ($styles as $k => $v) { $style .= $k . ':' . $v . ';'; } if (!empty($style)) { $style = ' style="' . $style . '"'; } $copyright = $image->imageinfo[0]->extmetadata->Copyrighted->value; $description = $image->imageinfo[0]->extmetadata->ImageDescription->value; $author = $image->imageinfo[0]->extmetadata->Artist->value; $license = $image->imageinfo[0]->extmetadata->License->value; if (!empty($formatter->fetch_images) && !empty($image_url)) { $image_url = $formatter->fetch_action . str_replace(array('&', '?'), array('%26', '%3f'), $image_url); // use thumbnails ? if (!empty($formatter->use_thumb_by_default)) { $image_url .= '&thumbwidth=' . $formatter->thumb_width; } } $copyrighted = $copyright == 'True'; $info = ($copyrighted ? '©' : '(ɔ) ') . $author; if ($copyrighted) { $info .= " ({$license})"; } $out = '<div class="externalImage">'; if (empty($addClass)) { $cls = ' class="' . $addClass . '"'; } $out .= "<div" . $cls . "><img src='{$image_url}'{$style}>"; $out .= "<div class='info'>" . $info . ' from ' . "<a href='{$desc_url}' target='_blank'>WikiMedia Commons</a></div>"; $out .= "</div>"; if (!empty($DBInfo->wikimediacommons_use_description) && !empty($description)) { $out .= '<div class="desc">' . $description . '</div>'; } $out .= "</div>\n"; return $out; }
function _index($formatter, $pages, $params = array()) { global $Config; if (isset($GLOBALS['.index_id'])) { $GLOBALS['.index_id']++; $index_id = $GLOBALS['.index_id']; } else { $index_id = $GLOBALS['.index_id'] = 0; } $anchor = 'index-anchor' . $index_id; $count = !empty($params['.count']) ? true : false; if ($count) { $cc = new Cache_Text('category'); $bc = new Cache_Text('backlinks'); } $keys = array(); $key = ''; $out = ''; $redirect = ''; $n = 0; foreach ($pages as $page => $info) { // redirect case if ($info == -2) { $urlname = _urlencode($page); $redirect .= '<li>' . $formatter->link_tag($urlname, '', _html_escape($page)); $redirect .= " <span class='redirectIcon'><span>" . _("Redirect page") . "</span></span>\n"; $redirect .= "</li>\n"; $n++; continue; } else { if (is_int($info)) { $title = $page; } else { $title = $info; } } $pkey = get_key("{$title}"); if ($key != $pkey) { if (isset($pkey[0])) { $keys[] = $pkey; } $key = $pkey; if (isset($out[0])) { $out .= "</ul></div>"; } $out .= "<div><a name='{$key}'></a><h2><a href='#{$anchor}'>{$key}</a></h2>\n"; $out .= "<ul>"; } $urlname = _urlencode($page); $extra = ''; // count subpages if ($count) { // get backlinks mtime $mtime = $bc->mtime($page); // get category counter info $cci = $cc->fetch($page, $mtime); if ($formatter->refresh || $cci === false) { // count backlinks $links = $bc->fetch($page); $c = 0; $p = 0; foreach ($links as $link) { if (preg_match('@' . $Config['category_regex'] . '@', $link)) { $c++; } else { $p++; } } // update cotegory counter info $cci = array('C' => $c, 'P' => $p); $cc->update($page, $cci); } // mediawiki like category status: Category (XX C, YY P) $tmp = array(); if (!empty($cci['C'])) { $tmp[] = $cci['C'] . ' C'; } if (!empty($cci['P'])) { $tmp[] = $cci['P'] . ' P'; } if (isset($tmp[0])) { $extra = ' (' . implode(', ', $tmp) . ')'; } } $out .= '<li>' . $formatter->link_tag($urlname, '', _html_escape($title)); $out .= $extra; if ($info == -2) { $out .= " <span class='redirectIcon'><span>" . _("Redirect page") . "</span></span>\n"; } $out .= "</li>\n"; $n++; } $out .= "</ul></div>\n"; $keys = array_unique($keys); $index = array(); foreach ($keys as $key) { $name = strval($key); $tag = '#' . $key; if ($name == 'Others') { $name = _("Others"); } $index[] = "<a href='{$tag}'>{$name}</a>"; } $str = implode(' | ', $index); if (isset($redirect[0])) { $redirect = '<div><h2>' . _("Redirects") . '</h2><ul>' . $redirect . '</ul></div>'; } if ($n > 10) { $attr = " class='index-group'"; } else { $attr = ''; } if ($n > 0) { return "<div style='text-align:center'><a name='{$anchor}'></a>{$str}</div>\n<div{$attr}>{$redirect}{$out}</div>"; } else { return false; } }
function ajax_pagecount($formater, $params) { global $DBInfo, $Config; $rc = new Cache_Text('redirect'); $redirects = 0; $sc = new Cache_Text('settings'); if (($redirects = $sc->fetch('redirect')) === false) { $rc = new Cache_Text('redirect'); $redirects = 0; if (method_exists($rc, 'count')) { $redirects = $rc->count(); } $sc->update('redirect', $redirects, 60 * 60 * 24); } $maxage = !empty($Config['proxy_maxage']) ? ', s-maxage=' . $Config['proxy_maxage'] : ''; header('Content-Type: text/plain'); header('Cache-Control: public' . $maxage . ',must-revalidate,post-check=0, pre-check=0'); $count = $DBInfo->getCounter(); echo '{pagecount:' . $count . ',redirect:' . $redirects . '}'; }
function cached_editlogbin($formatter, $params = array()) { global $Config, $DBInfo; $cache = new Cache_Text('editlogbin'); if (!empty($params['title'])) { if (!$DBInfo->hasPage($params['title'])) { unset($params['title']); } } $args = array(); $user = !empty($params['q']) ? $params['q'] : ''; $start = !empty($params['start']) ? $params['start'] : ''; $domain = !empty($params['domain']) ? $params['domain'] : ''; $title = !empty($params['title']) ? $params['title'] : ''; // get timestamp $oldest_stamp = !empty($params['.oldest']) ? strtotime($params['.oldest']) : strtotime('-1 year'); // round timestamp $tmp = date('Y-m-d 00:00:00', $oldest_stamp); $oldest_stamp = strtotime($tmp); if (!empty($start)) { if (is_numeric($start)) { // timestamp $from = $start; } else { $from = strtotime($start); } // convert to timestamp } else { $from = !empty($params['.max_range']) ? strtotime('-' . $params['.max_range']) : strtotime('-1 year'); // restrict range $params['until'] = null; // reset } // round timestamp $tmp = date('Y-m-d 23:59:59', $from); $from = strtotime($tmp); $max_range = !empty($params['.max_range']) ? strtotime($params['.max_range'], $from) : strtotime('1 year', $from); $params['until'] = $max_range; if ($params['until'] > time()) { $params['until'] = null; } //echo date('Y.m.d H.i.s', $params['until']); $mtime = $DBInfo->mtime(); $key = $user . '.' . $from . '.' . $domain . '.' . $title . $mtime; if (empty($formatter->refresh) && ($data = $cache->fetch($key)) !== false) { return $data; } $fp = fopen($Config['editlog_name'], 'r'); $seek = _editlog_seek($fp, $from); $data = _editlog_binning($fp, $seek, $from, 60 * 60 * 24, $params); fclose($fp); $cache->update($key, $data, 60 * 60 * 24); // TTL to 24 hour return $data; }
function macro_PageSort($formatter, $value = '', $params = array()) { global $DBInfo; $cache = new Cache_Text('persist', array('depth' => 0)); $ismember = $DBInfo->user->is_member; $refresh = $formatter->refresh && $ismember; if (!empty($params['sortby']) && in_array($params['sortby'], array('date', 'hits'))) { if ($params['sortby'] == 'date') { $sortby = PAGESIZE_SORTBY_DATE; $cachekey = 'pagedate'; } else { $sortby = PAGESIZE_SORTBY_HITS; $cachekey = 'pagehits'; } } else { $sortby = PAGESIZE_SORTBY_SIZE; $cachekey = 'pagesize'; } if ($refresh || ($info = $cache->fetch($cachekey)) === false) { set_time_limit(0); if ($sortby == PAGESIZE_SORTBY_HITS) { $cutoff = !empty($DBInfo->counter_cutoff) ? $DBInfo->counter_cutoff : 50; $hits = $DBInfo->counter->getPageHits(-1, 0, $cutoff); $pages = array(); foreach ($hits as $k => $v) { $pages[$k . "\t" . $v] = $v; } } else { $handle = opendir($DBInfo->text_dir); if (!is_resource($handle)) { return sprintf(_("Can't open %s\n"), $DBInfo->text_dir); } $j = 0; $cnt = 0; $pages = array(); while (($file = readdir($handle)) !== false) { $j++; if ($file[0] == '.' || in_array($file, array('RCS', 'CVS'))) { continue; } $pagefile = $DBInfo->text_dir . '/' . $file; if (is_dir($pagefile)) { continue; } $pagename = $DBInfo->keyToPagename($file); $sz = $val = filesize($pagefile); if ($sortby == PAGESIZE_SORTBY_DATE) { $val = filemtime($pagefile); } $key = $pagename . "\t" . $val; if ($sz > 11 && $sz < 4096) { // check redirects $fp = fopen($pagefile, 'r'); if (!is_resource($fp)) { continue; } $pi = fgets($fp, 11); if (isset($pi[0]) && $pi[0] == '#' && preg_match('@^#redirect\\s@i', $pi)) { fclose($fp); continue; } fclose($fp); } $pages[$key] = $val; $cnt++; } closedir($handle); } // sort if ($sortby != PAGESIZE_SORTBY_SIZE) { arsort($pages); } else { asort($pages); } $keys = array_keys($pages); $raw = implode("\n", $keys); // save sorted page list $cache->update($cachekey . '.raw', $raw); // write index file $idxfile = $cache->cache_path . '/' . $cache->getKey($cachekey . '.idx'); $fp = fopen($idxfile, 'a+b'); ftruncate($fp, 0); $idx = ''; $i = 0; $idx = pack('N', 0); $len = 0; for ($i = 1; $i < sizeof($keys); $i++) { $pos = strlen($keys[$i - 1]) + 1; // strlen($name) + strlen("\n"); $len += $pos; $idx .= pack('N', $len); if ($i % 500 == 0) { fwrite($fp, $idx); $idx = ''; } } if (isset($idx[0])) { fwrite($fp, $idx); } fclose($fp); $info = array('count' => $cnt); // save some info. $cache->update($cachekey, $info, 60 * 60 * 12); // set TTL } if (!empty($params['.call'])) { return $info; } $offset = 0; $limit = 200; if (!empty($params['offset'])) { $offset = intval($params['offset']); } $off = $offset; if (!empty($params['reverse'])) { $off = $info['count'] - $offset; $off -= $limit; } $seek = 0; $rawfile = $cache->cache_path . '/' . $cache->getKey($cachekey . '.raw'); $fp = fopen($rawfile, 'r'); while ($off > 0) { $idxfile = $cache->cache_path . '/' . $cache->getKey($cachekey . '.idx'); $ip = fopen($idxfile, 'rb'); if (!is_resource($ip)) { break; } // ignore fseek($ip, $off * 4); $dum = unpack('N', fread($ip, 4)); $seek = $dum[1]; fclose($ip); fseek($fp, $seek); break; } $lst = array(); for ($j = 0; $j < $limit; $j++) { $raw = fgets($fp, 2048); if ($raw === false) { break; } list($page, $val) = explode("\t", $raw, 2); $item = '<li>' . $formatter->link_tag($page); if ($sortby == PAGESIZE_SORTBY_DATE) { $item .= ' (' . date('Y-m-d H:i', $val) . ')</li>' . "\n"; } else { if ($sortby == PAGESIZE_SORTBY_SIZE) { $item .= ' (' . $val . ' Bytes)</li>' . "\n"; } else { $item .= ' (' . $val . ' Hits)</li>' . "\n"; } } $lst[] = $item; } fclose($fp); // next query string $q = '&offset=' . ($offset + $limit); if (!empty($params['reverse'])) { $lst = array_reverse($lst); $q .= '&reverse=1'; } if ($sortby == PAGESIZE_SORTBY_DATE) { $q .= '&sortby=date'; } else { if ($sortby == PAGESIZE_SORTBY_HITS) { $q .= '&sortby=hits'; } } $out = '<ul>'; $out .= implode($lst); $out .= '</ul>'; $out .= $formatter->link_to("?action=pagesort{$q}", _("Show next page")); return $out; }
function cache_instructions($pi, $params = array()) { global $Config; global $DBInfo; $pagename = $this->name; // update aliases if (!empty($Config['use_alias'])) { $ac = new Cache_text('alias'); // is it removed ? if ($ac->exists($pagename) and empty($pi['#alias']) and empty($pi['#title'])) { // remove aliases store_aliases($pagename, array()); } else { if (!$ac->exists($pagename) or $ac->mtime($pagename) < $this->mtime() or !empty($_GET['update_alias'])) { $as = array(); // parse #alias if (!empty($pi['#alias'])) { $as = get_csv($pi['#alias']); } // add #title as a alias if (!empty($pi['#title'])) { $as[] = $pi['#title']; } // update aliases store_aliases($pagename, $as); } } } // update #redirect $rc = new Cache_Text('redirect'); $old = $rc->fetch($pagename); if ($old or isset($pi['#redirect'][0])) { // update invert redirect index $rc2 = new Cache_Text('redirects'); if (!empty($params['refresh']) or $old != $pi['#redirect']) { // update direct cache $rc->update($pagename, $pi['#redirect']); $nr = $pi['#redirect']; if (($p = strpos($nr, '#')) > 0) { // get pagename only //$anchor = substr($nr, $p); $nr = substr($nr, 0, $p); } if (!isset($nr[0])) { $rc->remove($pagename); } else { if (!preg_match('@^https?://@', $nr)) { // not a URL redirect // add redirect links $redirects = $rc2->fetch($nr); if (empty($redirects)) { $redirects = array(); } $redirects = array_merge($redirects, array($pagename)); $rc2->update($nr, $redirects); } } while ($old != '' and $old != false) { // get pagename only if (($p = strpos($old, '#')) > 0) { //$anchor = substr($old, $p); $old = substr($old, 0, $p); } if ($nr == $old) { break; } // check A#s-1 ~ A#s-2 redirects // delete redirect links $l = $rc2->fetch($old); if ($l !== false and is_array($l)) { $redirects = array_diff($l, array($pagename)); if (empty($redirects)) { $rc2->remove($old); } else { $rc2->update($old, $redirects); } } break; } } } if (!empty($Config['use_keywords']) or !empty($Config['use_tagging']) or !empty($_GET['update_keywords'])) { $tcache = new Cache_text('keyword'); $cache = new Cache_text('keywords'); $cur = $tcache->fetch($pagename); if (empty($cur)) { $cur = array(); } $keys = array(); if (empty($pi['#keywords'])) { $tcache->remove($pagename); } else { $keys = explode(',', $pi['#keywords']); $keys = array_map('trim', $keys); if (!$tcache->exists($pagename) or $tcache->mtime($pagename) < $this->mtime() or !empty($_GET['update_keywords'])) { $tcache->update($pagename, $keys); } } $adds = array_diff($keys, $cur); $dels = array_diff($cur, $keys); // merge new keywords foreach ($adds as $a) { if (!isset($a[0])) { continue; } $l = $cache->fetch($a); if (!is_array($l)) { $l = array(); } $l = array_merge($l, array($pagename)); $cache->update($a, $l); } // remove deleted keywords foreach ($dels as $d) { if (!isset($d[0])) { continue; } $l = $cache->fetch($d); if (!is_array($l)) { $l = array(); } $l = array_diff($l, array($pagename)); $cache->update($d, $l); } } if (!empty($pi['#title']) and !empty($Config['use_titlecache'])) { $tc = new Cache_text('title'); $old = $tc->fetch($pagename); if (!isset($pi['#title'])) { $tc->remove($pagename); } else { if ($old != $pi['#title'] or !$tcache->exists($pagename) or !empty($_GET['update_title'])) { $tc->update($pagename, $pi['#title']); } } } return; }