function macro_BBS($formatter, $value, $options = array()) { global $DBInfo; # set defaults $ncount = 20; # default $bname = $formatter->page->name; $nid = ''; # check options $args = preg_split('/\\s*,\\s*/', $value); foreach ($args as $arg) { $arg = trim($arg); if ($arg == '') { continue; } if (($p = strpos($arg, '=')) !== false) { $k = substr($arg, 0, $p); $v = substr($arg, $p + 1); if ($k == 'no') { $nid = $v; } else { if ($k == 'mode') { $options['mode'] = $v; } } } else { if ($arg == 'mode') { } else { if ($arg == (int) $arg . "") { $ncount = $arg; } else { $bname = $arg; } } } } $bpage = _rawurlencode($bname); $nid = $nid ? $nid : $_GET['no']; $nids = array(); if ($nid) { $nids = preg_split('/\\s+/', $nid); rsort($nids); } $options['p'] = $_GET['p'] > 0 ? $_GET['p'] : 1; $options['c'] = $ncount != 20 ? $ncount : ''; $options['p'] = intval($options['p']); # is it exists ? if (!$DBInfo->hasPage($bname)) { return _("This bbs does not exists yet. Please save this page first"); } # load a config file $conf0 = array(); if (file_exists('config/bbs.' . $bname . '.php')) { $confname = 'bbs.' . $bname . '.php'; $conf0 = _load_php_vars('config/bbs.default.php'); } else { $confname = 'bbs.default.php'; } $conf = _load_php_vars('config/' . $confname); $conf = array_merge($conf0, $conf); $conf['data_dir'] = $DBInfo->data_dir; $conf['dba_type'] = $DBInfo->dba_type; if (!$DBInfo->use_bbs) { return '[[BBS]]'; } #if ($DBInfo->use_bbs == 1); #if ($DBInfo->use_bbs == 2); $MyBBS = new BBS_text($bname, $conf); // XXX if ($options['new'] and $MyBBS) { return $MyBBS; } if (!$MyBBS) { return '[[BBS]]'; } $msg = ''; $btn = array(); # read messages # $formatter->baserule[] = "/^((-=)+-?\$)/"; $formatter->baserule[] = "/ comment #(\\d+)\\b/"; $formatter->baserule[] = "/\\[reply (\\d+)\\]/"; $formatter->baserepl[] = "<hr />\n"; $formatter->baserepl[] = " comment [#c\\1 #\\1]"; $formatter->baserepl[] = "<script type='text/javascript'><!--\n" . " addReplyLink(\\1); //--></script>"; $msg = ''; $narticle = sizeof($nids); $js = ''; if ($nid and $narticle == 1 and $options['mode'] == 'simple') { $nid = $nids[0]; if (!$nid or !$MyBBS->hasPage($nid)) { return '[[BBS(error)]]'; } include_once 'lib/metadata.php'; $body = $MyBBS->getPage($nid); list($metas, $body) = _get_metadata($body); $img = ''; if ($MyBBS->use_attach) { $cache = new Cache_text('attachments'); $attachs = $cache->fetch($MyBBS->bbsname . ':' . $nid); if (preg_match('/^attachment:([^\\?]+)(\\?.*)?$/', $attachs[0], $m)) { $img = $formatter->macro_repl('Attachment', $m[1] . '?thumbwidth=100'); } $subject = $formatter->link_tag($bpage, "?no={$nid}", $metas['Subject']); } $out = "<div class='simpleView'><table>\n" . "<tr><td class='img'>" . $img . "</td><td class='subject'>" . $subject . '</td></tr>' . "<tr><td colspan='2'></td>\n</tr></table></div>"; return $out; } foreach ($nids as $nid) { if (!$nid or !$MyBBS->hasPage($nid)) { continue; } $fields = array('Name', 'Subject', 'Date', 'Email', 'HomePage', 'IP', 'Keywords'); include_once 'lib/metadata.php'; #Name: wkpark #Subject: Oh well #Date: 2006-04-29 42:04:39 #Email: wkpark@gmail.com #HomePage: #IP: 2xx.xxx.xxx.x $body = $MyBBS->getPage($nid); if ($body != null) { $options['nosisters'] = 1; $MyBBS->counter->incCounter($nid, $options); list($metas, $body) = _get_metadata($body); $boundary = strtoupper(md5("COMMENT")); # XXX $copy = $body; list($comment, $copy) = explode("----" . $boundary . "\n", $copy, 2); while (!empty($comment)) { list($comment, $copy) = explode("----" . $boundary . "\n", $copy, 2); if (preg_match('/^Comment-Id:\\s*(\\d+)/i', $comment, $m)) { list($myhead, $my) = explode("\n\n", $comment, 2); $hidden .= '<pre style="display:none;" id="comment_text_' . $m[1] . '">' . _html_escape($my) . '</pre>'; } } ob_start(); # add some basic rule/repl for bts $rule = "/-{4}(?:" . $boundary . ")?\nComment-Id:\\s*(\\d+)\n" . "From:\\s*([^\n]+)\nDate:\\s*([^\n]+)\n\n/im"; $repl = "----\n'''Comment-Id:''' [#c\\1][#c\\1 #\\1] by \\2 on [[DateTime(\\3)]] [reply \\1]\n\n"; $body = preg_replace($rule, $repl, $body); $formatter->quote_style = 'bbs-comment'; $options['usemeta'] = 1; # $q_save = $formatter->self_query; $query = '?no=' . $nid . '&p=' . $options['p']; $formatter->self_query = $query; $save = $formatter->preview; $formatter->preview = 1; $save_markup = $formatter->format; ob_start(); if ($conf['default_markup']) { $formatter->pi['#format'] = $conf['default_markup']; } $formatter->send_page($body, $options); $body = ob_get_contents(); ob_end_clean(); $formatter->pi['#format'] = $save_markup; $formatter->self_query = $q_save; $msg .= "<div class='bbsArticle'>" . '<div class="head"><h2>' . _("No") . ' ' . $nid . ': ' . $metas['Subject'] . '</h2></div>' . '<div class="body">' . '<div class="extra"> @ ' . $metas['Date'] . ' (' . _mask_hostname($metas['IP'], 3) . ')</div>' . '<div class="user"><h3>' . $metas['Name'] . '</h3></div>' . '<div class="article">' . $body . "</div>\n</div>\n" . '<div class="foot"><div></div></div>' . "</div>\n"; $snid = $nid; $btn['edit'] = $formatter->link_tag($bpage, "?action=bbs&mode=edit&no=" . $nid, '<span>' . _("Edit") . '</span>', 'class="button"'); $btn['delete'] = $formatter->link_tag($bpage, "?action=bbs&mode=delete&no=" . $nid, '<span>' . _("Delete") . '</span>', 'class="button"'); if ($narticle == 1 and $conf['use_comment']) { $opts['action'] = 'bbs'; $opts['no'] = $nid; $opts['p'] = $options['p']; $opts['mode'] = 'comment'; $opts['nopreview'] = 1; $p = new WikiPage($bname . ':' . $opts['no'], $options); $opts['datestamp'] = $p->mtime(); $comment = $formatter->macro_repl('Comment', 'usemeta', $opts); unset($opts['no']); # XXX } $msg .= '<div class="bbsComment">' . $comment . '</div><div class="bbsArticleBtn">' . implode(" ", $btn) . '</div>'; unset($btn['delete']); unset($btn['edit']); $title = str_replace('"', '\\"', $metas['Subject']); $js .= <<<JS <script type="text/javascript"> /*<![CDATA[*/ document.title+=" [" + {$snid} + "] - " + "{$title}"; /*]]>*/ </script> JS; } } if (!empty($msg) and !$_GET['p']) { return $msg; } if (1) { # XXX $nochk = _("Please check article numbers."); $js .= <<<JS <script type='text/javascript'> /*<![CDATA[*/ function send_list(obj,mode) { var tmp=""; var i, chk=false; form=obj.parentNode.parentNode; for(i=0;i< form.length;i++) { if(form[i].type!="checkbox") continue; if(form[i].checked) { tmp+=form[i].value+" "; chk=true; } } if(chk==true) { form.no.value = tmp.substr(0,tmp.length-1); if (mode!=undefined) { form.elements.action.value = 'bbs'; form.elements.mode.value = mode; } else { form.removeChild(form.elements.mode); form.removeChild(form.elements.action); } form.submit(); return false; } alert ("{$nochk}"); return false; } /*]]>*/ </script> JS; } # get list $options['perpage'] = $ncount; $list = $MyBBS->getList($ncount, $options); # get total number of articles $tot = $MyBBS->getCount(); $pages = intval($tot / $ncount); if ($tot % $ncount) { $pages++; } if ($options['mode'] == 'rss') { $rss = '<' . '?xml version="1.0" encoding="utf-8"?>' . "\n" . '<rss version="2.0">' . "\n"; $rss .= "<channel>\n<title>" . $DBInfo->sitename . ": </title>\n"; $rss .= "<link>" . qualifiedUrl($formatter->link_url($bpage)) . "</link>\n"; $rss .= "<description></description>\n"; $rss .= "<pubDate>" . gmdate('D, j M Y H:i:s', time()) . " +0000</pubDate>\n"; foreach ($list as $l) { $item = "<item>\n"; $item .= "<title><![CDATA[" . $l[7] . "]]></title>\n"; $item .= "<link>" . qualifiedUrl($formatter->link_url($bpage, "?no={$l['0']}")) . "</link>\n"; $item .= "<author><![CDATA[" . $l[3] . "]]></author>\n"; $item .= "<description><![CDATA[" . $l[3] . "]]></description>\n"; $item .= "<pubDate>" . gmdate('D, j M Y H:i:s', $l[2]) . " +0000</pubDate>\n</item>\n"; $rss .= $item; } $rss .= "</channel>\n</rss>\n"; return $rss; } else { if ($options['mode'] == 'simple') { $simple = "<div class='bbsSimple'><table class='bbsSimple'>\n"; foreach ($list as $l) { $date = date("Y-m-d", $l[2]); $my = $l[7]; $title = ''; if (function_exists('mb_strimwidth') and strlen($l[7]) > 60) { $title = 'title="' . $l[7] . '"'; $my = mb_strimwidth($l[7], 0, 40, '...', $DBInfo->charset); } $simple .= "<tr><td class='date'>[" . $date . "]</td><td>" . $formatter->link_tag($bpage, "?no={$l['0']}" . $extra, $my, $title) . '</td></tr>'; } $simple .= "<tr><td colspan='2' class='more'>" . $formatter->link_tag($bpage, "", _("More") . '»') . "</td>\n</tr>\n"; $simple .= "</table>"; return $simple; } } if ($pages > 1) { $pnut = _get_pagelist($formatter, $pages, '?' . $extra . ($extra ? '&p=' : 'p='), $options['p'], $ncount); } else { $pnut = "<div class='clear'></div>"; } $extra = $options['p'] ? '&p=' . $options['p'] : ''; #$head=array(_("no"),'C',_("Title"),_("Name"),_("Date"),_("Hit")); #$out.="<col width='3%' class='num' /><col width='1%' class='check' /><col width='63%' class='title' /><col width='14%' /><col width='13%' /><col width='7%' class='hit' />\n"; #$out.='<thead><tr><th>'.implode("</th><th>",$head)."</th></tr><thead>\n"; #$out.="<tbody>\n"; $item = array(); foreach ($list as $l) { $nid =& $l[0]; $ip =& $l[1]; $date = date("Y-m-d", $l[2]); $user = $l[3]; $subject = $formatter->link_tag($bpage, "?no={$nid}" . $extra, $l[7]); $hit = $MyBBS->counter->pageCounter($nid); $chk = '<input type="checkbox" value="' . $nid . '">'; #$item=array(in_array($nid,$nids) ? '<strong>»</strong>':$nid,$chk,$subject,$user,$date,$hit); $item[] = array('num' => in_array($nid, $nids) ? '<strong>»</strong>' : $nid, 'check' => $chk, 'subject' => $subject, 'name' => $user, 'date' => $date, 'hit' => $hit); ##$tmp='<tr><td>'.implode("</td><td>",$item)."</td></tr>\n"; #$tmp="<tr><td class='no'>$item[0]</td><td class='check'>$item[1]</td>". # "<td class='title'>$item[2]</td><td class='name'>$item[3]</td>". # "<td class='date'>$item[4]</td><td class='hit'>$item[5]</td>". # "</tr>\n"; #$out.=$tmp; } $formatter->_vars['item'] =& $item; $out .= $formatter->include_theme('plugin/BBS/default', 'list', array()); #$out.= $formatter->include_theme('plugin/BBS/default_tpl','list',array()); #$out.= $formatter->processor_repl('tpl_','',array('path'=>'theme/plugin/BBS/blue_tpl/list.tpl')); #$out.="</tbody>\n"; $btn['new'] = $formatter->link_tag($bpage, "?action=bbs&mode=edit", '<span>' . _("New") . '</span>', 'class="button"'); unset($btn['edit']); $bn['view'] = $formatter->link_tag($bpage, "", '<span>' . _("Read") . '</span>', 'onclick="return send_list(this)" onfocus="blur()" class="button"'); $bn['delete'] = $formatter->link_tag($bpage, "", '<span>' . _("Delete") . '</span>', 'onclick="return send_list(this,\'delete\')" onfocus="blur()" class="button"'); $del = "<div class='bbsAdminBtn'>" . implode(" ", $bn) . "</div>\n"; $btns = "<div class='bbsBtn'>" . implode(" ", $btn) . "</div>\n"; $lnk = $formatter->link_url($bpage, '?action=bbs'); $form0 = "<form method='get' action='{$lnk}'>\n"; $form1 = '<input type="hidden" name="no" />'; if ($options['p']) { $form1 .= '<input type="hidden" name="p" value="' . $options['p'] . "\" />\n"; } $form1 .= '<input type="hidden" name="mode" />' . '<input type="hidden" name="action" />'; $form1 .= "</form>\n"; $pnut = "<div class='pnut'>{$pnut}</div>"; $info = '<div class="bbsRSS">' . sprintf(_("Total %s articles."), '<strong>' . $tot . '</strong>') . ' ' . $formatter->link_tag($bpage, '?action=bbs&mode=rss', $formatter->icon['rss']) . '</div>'; return $info . $pnut . $msg . $js . $form0 . $out . $del . $form1 . $pnut . $btns; }
function _parse_rlog($formatter, $log, $options = array()) { global $DBInfo; $tz_offset = $formatter->tz_offset; if (!empty($DBInfo->wikimasters) and is_array($DBInfo->wikimasters) and in_array($options['id'], $DBInfo->wikimasters)) { $admin = 1; } if (!empty($options['info_actions'])) { $actions = $options['info_actions']; } else { if (isset($DBInfo->info_actions)) { $actions = $DBInfo->info_actions; } else { $actions = array('recall' => 'view', 'raw' => 'source', 'diff' => 'diff'); } } if (!$formatter->page->exists() && !in_array('revert', $actions)) { $actions['revert'] = 'revert'; } if (!empty($DBInfo->use_avatar)) { if (is_string($DBInfo->use_avatar)) { $type = $DBInfo->use_avatar; } else { $type = 'identicon'; } $avatarlink = qualifiedUrl($formatter->link_url('', '?action=' . $type . '&seed=')); } $ipicon = '<img src="' . $DBInfo->imgs_dir . '/misc/ip.png" />'; $members = $DBInfo->members; // do not check admin member users $user = $DBInfo->user; $ismember = $user->is_member; $diff_action = null; if (isset($actions['diff'])) { $diff_action = _($actions['diff']); unset($actions['diff']); } $state = 0; $flag = 0; $time_current = time(); $simple = !empty($options['simple']) ? 1 : 0; $url = $formatter->link_url($formatter->page->urlname); $diff_btn = _("Compare"); $out = "<div class='wikiInfo'>\n"; if (!empty($options['title'])) { $out .= $options['title']; } else { $out .= "<h2>" . _("Revision History") . "</h2>\n"; } $out .= "<form id='infoform' method='get' action='{$url}'>"; $out .= "<div><table class='info'><thead><tr>\n"; $out .= "<th>" . _("Ver.") . "</th><th>" . _("Date") . "</th>" . "<th>" . _("Changes") . "</th>" . "<th>" . _("Editor") . "</th>" . "<th><button type='submit'><span>{$diff_btn}</span></button></th>\n"; if (!$simple) { if (!empty($actions)) { $out .= "<th>" . _("View") . "</th>"; } if (isset($admin)) { $out .= "<th>" . _("admin.") . "</th>"; } } $out .= "</tr>\n</thead>\n"; $out .= "<tbody>\n"; $users = array(); $rr = 0; #foreach ($lines as $line) { $count = 0; $showcount = (!empty($options['count']) and $options['count'] > 5) ? $options['count'] : 10; $line = ''; $ok = 0; $log .= "\n"; // hack $ii = 0; for (; !empty($line) or !empty($log); list($line, $log) = explode("\n", $log, 2)) { if (!$state) { if (!preg_match("/^---/", $line)) { continue; } else { $state = 1; continue; } } if ($state == 1 and $ok == 1) { if (!empty($options['action'])) { $act = $options['action']; } else { $act = 'info'; } $lnk = $formatter->link_to('?action=' . $act . '&rev=' . $rev, _("Show next revisions"), ' class="button small"'); $out .= '<tr><td colspan="2"></td><td colspan="' . (!empty($admin) ? 5 : 4) . '">' . $lnk . '</td></tr>'; break; } switch ($state) { case 1: $rr++; preg_match("/^revision ([0-9a-f\\.]+)\\s*/", $line, $match); $rev = $match[1]; if (isset($match[2]) and preg_match("/\\./", $match[2])) { $state = 0; break; } $state = 2; break; case 2: $change = ''; $inf = preg_replace("/date:\\s([0-9\\/:\\s]+)(;\\s+author:.*;\\s+state:.*;)?/", "\\1", $line); if (strstr($inf, 'lines:') !== FALSE) { list($inf, $change) = explode('lines:', $inf, 2); } if (!empty($options['ago'])) { if (preg_match('/^[0-9]+$/', $inf)) { $rrev = '#' . $rr; $ed_time = $inf; $inf = gmdate("Y-m-d H:i:s", $ed_time + $tz_offset); } else { $ed_time = strtotime($inf . ' GMT'); } $time_diff = (int) ($time_current - $ed_time) / 60; if ($time_diff > 1440 * 31) { $inf = gmdate("Y-m-d H:i:s", strtotime($inf . ' GMT') + $tz_offset); } else { if (($time_diff = $time_diff / 60) > 24) { $day = (int) ($time_diff / 24); if ($day == 1) { $inf = _("Yesterday"); } else { $inf = sprintf(_("%s days ago"), (int) ($time_diff / 24)); } } else { if ($time_diff > 1) { $inf = sprintf(_("%s hours ago"), (int) $time_diff); } else { $inf = sprintf(_("%s min ago"), $time_diff % 60); } } } } else { if (preg_match('/^[0-9]+$/', $inf)) { $rrev = '#' . $rr; $ed_time = $inf; $inf = gmdate("Y-m-d H:i:s", $inf + $tz_offset); } else { if ($tz_offset != '') { $inf = gmdate("Y-m-d H:i:s", strtotime($inf . ' GMT') + $tz_offset); } else { $inf = date("Y-m-d H:i:s", strtotime($inf)); } // localtime } } $inf = $formatter->link_to("?action=recall&rev={$rev}", $inf); $change = preg_replace("/\\+(\\d+)\\s\\-(\\d+)/", "<span class='diff-added'><span>+\\1</span></span><span class='diff-removed'><span>-\\2</span></span>", $change); $state = 3; break; case 3: $dummy = explode(';;', $line, 3); $ip = $dummy[0]; $realip = $lastip = $ip; if (($p = strpos($ip, ',')) !== false) { // IP addresses via proxies $realip = substr($ip, 0, $p); $tmp = explode(',', $ip); $lastip = $ip = array_pop($tmp); } $user = trim($dummy[1]); if (($p = strpos($user, ' ')) !== false) { // XXX $user = substr($user, 0, $p); } else { if (substr($user, 0, 9) == 'Anonymous') { $user = '******'; } } if (!empty($DBInfo->use_avatar)) { $crypted = crypt($ip, $ip); $mylnk = preg_replace('/seed=/', 'seed=' . $crypted, $avatarlink); $avatar = '<img src="' . $mylnk . '" style="width:16px;height:16px;vertical-align:middle" alt="avatar" />'; } else { $avatar = ''; } if ($user and $user != 'Anonymous') { if (array_key_exists($user, $users)) { $ip = $users[$user]; } else { if (!empty($DBInfo->use_nick)) { $u = $DBInfo->udb->getUser($user); if (!empty($u->info['nick'])) { if ($DBInfo->interwiki['User']) { $ip = $formatter->link_repl('[wiki:User:'******' ' . $u->info['nick'] . ']'); } else { if (!empty($u->info['home'])) { $ip = $formatter->link_repl('[' . $u->info['home'] . ' ' . $u->info['nick'] . ']'); } else { $ip = $formatter->link_repl('[wiki:' . $user . ' ' . $u->info['nick'] . ']'); } } } $ip = $avatar . $ip; $users[$user] = $ip; } else { if (strpos($user, ' ') !== false) { $ip = $avatar . $formatter->link_repl($user); $users[$user] = $ip; } else { if (empty($DBInfo->no_wikihomepage)) { if (empty($DBInfo->use_hostname) or $DBInfo->hasPage($user)) { $ip = $avatar . $formatter->link_tag($user); } else { $ip = $avatar . $user; } $users[$user] = $ip; } } } } } if (empty($users[$user])) { $rip = $ip; $u = $user; if ($u == 'Anonymous') { $u = $ip; } if (isset($DBInfo->interwiki['Whois'])) { $wip = "<a href='" . $DBInfo->interwiki['Whois'] . "{$ip}' target='_blank'>{$ipicon}</a>"; } else { $wip = "<a href='?action=whois&q=" . $ip . "' target='_blank'>{$ipicon}</a>"; } if ($ismember) { if (!empty($DBInfo->use_admin_user_url)) { $u = '<a href="' . $DBInfo->use_admin_user_url . $u . '">' . $u . '</a>'; } if (!in_array($user, $members)) { $ip = $u . $wip; } else { $ip = $u; } } else { if (empty($DBInfo->show_hosts)) { $ip = $user; } else { if (!empty($DBInfo->mask_hostname)) { if ($user == 'Anonymous') { $ip = _mask_hostname($ip); } else { $ip = $user; } } else { if (!empty($members) and in_array($u, $members)) { $ip = $user; } else { if (!empty($avatar)) { if ($user == 'Anonymous') { $u = _($user); } $ip = $u; } else { $ip = $u . $wip; } } } } } $ip = $avatar . $ip; if ($user != 'Anonymous') { $users[$user] = $ip; } else { $users[$rip] = $ip; } } $comment = !empty($dummy[2]) ? _stripslashes($dummy[2]) : ''; if ($realip != $lastip) { $via = '<span class="via-proxy">' . $realip . '</span>'; $comment = isset($comment[0]) ? $via . ' ' . $comment : $via; } $state = 4; break; case 4: if (!$rev) { break; } $rowspan = 1; if (!$simple and $comment) { $rowspan = 2; } $rrev = !empty($rrev) ? $rrev : $formatter->link_to("?action=recall&rev={$rev}", $rev); $alt = $ii++ % 2 == 0 ? ' class="alt"' : ''; $out .= "<tr{$alt}>\n"; $out .= "<th class='rev' valign='top' rowspan={$rowspan}>{$rrev}</th><td nowrap='nowrap' class='date'>{$inf}</td><td class='change'>{$change}</td><td class='author'>{$ip} </td>"; $rrev = ''; $achecked = ""; $bchecked = ""; if ($flag == 1) { $achecked = "checked "; } else { if (!$flag) { $bchecked = "checked "; } } $onclick = "onclick='ToggleRev(this)'"; $out .= "<th nowrap='nowrap' class='check'><input type='radio' name='rev' value='{$rev}' {$achecked} {$onclick} />\n"; $out .= "<input type='radio' name='rev2' value='{$rev}' {$bchecked} {$onclick} /></th>"; if (!$simple) { $out .= "<td nowrap='nowrap' class='view'>"; foreach ($actions as $k => $v) { $k = is_numeric($k) ? $v : $k; $out .= $formatter->link_to("?action={$k}&rev={$rev}", _($v), ' class="button-small"') . ' '; } if ($flag) { if ($diff_action) { $out .= " " . $formatter->link_to("?action=diff&rev={$rev}", $diff_action, ' class="button-small"'); } $out .= "</td>"; if (isset($admin)) { $out .= "<td><input type='checkbox' name='range[{$flag}]' value='{$rev}' /></td>"; } } else { $out .= "</td>"; if (isset($admin)) { $out .= "<td><input type='image' src='{$DBInfo->imgs_dir}/smile/checkmark.png' onClick=\"ToggleAll('infoform');return false;\"/></td>"; } } } $out .= "</tr>\n"; if (!$simple and $comment) { $out .= "<tr class='log'><td colspan='" . (!empty($admin) ? 6 : 5) . "'><p>{$comment} </p></td></tr>\n"; } $state = 1; $flag++; $count++; if ((empty($options['all']) or $options['all'] != 1) and $count >= $showcount) { $ok = 1; } break; } } if (!$simple and !empty($admin)) { $out .= "<tr><td colspan='" . (!empty($admin) ? 7 : 6) . "' align='right'><input type='checkbox' name='show' checked='checked' />" . _("show only") . ' '; if ($DBInfo->security->is_protected("rcspurge", $options)) { $out .= "<input type='password' name='passwd'>"; } $out .= "<input type='submit' name='rcspurge' value='" . _("purge") . "'></td></tr>"; } $out .= "<input type='hidden' name='action' value='diff'/>\n</tbody></table></div></form>\n"; $out .= "<script type='text/javascript' src='{$DBInfo->url_prefix}/local/checkbox.js'></script></div>\n"; return $out; }
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 macro_RecentChanges($formatter, $value = '', $options = '') { global $DBInfo, $Config; // get members to hide log $members = $DBInfo->members; $checknew = 1; $checkchange = 0; $template_bra = ""; $template = '"$icon $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 . '&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 $title @ $day $date by $user $count $extra<br />\\n"'; } else { $template = '"$icon $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 = '&days=' . $days; $daysago = $opts['ago'] ? $daysago . '&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 . '&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&date={$bookmark}", $formatter->icon['diff']); $updated = ' ' . $formatter->link_tag($pageurl, "?action=diff&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 .= '&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 . "&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 . "&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 . "&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 = " <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)((?:&|&)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)((?:&|&)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; }
function _render_stat($formatter, $retval, $params = array()) { global $DBInfo; $show_table = false; if (empty($DBInfo->stat_no_show_all) || in_array($params['id'], $DBInfo->members)) { $show_table = true; } extract($retval); // basic information $total_lines = $formatter->page->lines(); $orig_author = $author; $count_revs = count($revs); $count_users = count($users); // parameters $first_contribution_author_ratio = 85; //echo '<pre>'; //print_r($users); $authors = array_keys($users); $edits = array(); $user_adds = array(); $user_dels = array(); $orig_lines = $total_lines; $total_adds = 0; $total_dels = 0; foreach ($authors as $n) { $edits[$n] = $users[$n]['edit']; $user_adds[$n] = $users[$n]['add']; $user_dels[$n] = $users[$n]['del']; $total_adds += $users[$n]['add']; $total_dels += $users[$n]['del']; } $orig_lines -= $total_adds - $total_dels; // fix original author info. if ($rev === '1.1') { $users[$orig_author]['add'] += $orig_lines; $user_adds[$orig_author] += $orig_lines; } $adds[$count_revs - 1] = $orig_lines; $total_adds += $orig_lines; //echo "<pre>"; //print_r($adds); //print_r($dels); //print_r($edits); //echo '</pre>'; // sort by edits arsort($edits); $contribs = array(); $total_edits = $count_revs; $mean_edits = $count_revs / $count_users; $max_edits = $users[$authors[0]]['edit']; $mean_adds = $total_adds / $count_users; $mean_dels = $total_dels / $count_users; foreach ($edits as $u => $c) { $point = _calc_contrib_points($c, $total_edits, $max_edits, $mean_edits, $user_adds[$u], $user_dels[$u], $total_lines, $mean_adds, $mean_dels); $count = sprintf("%4.1f %%", round($point * 100, 1)); $contribs[$u] = $count; } $authors = $others = array_keys($edits); array_shift($others); if (isset($params['retval'])) { $ret = array('total_revs' => $count_revs, 'initial_rev' => $rev, 'original_author' => $orig_author, 'total_editors' => $count_users, 'contributions' => $contribs); if ($count_users == 1) { $ret['first_author'] = $orig_author; } else { if ($contribs[$authors[0]] > $first_contribution_author_ratio) { $ret['first_author'] = $authors[0]; } } $params['retval'] = $ret; return 0; } foreach ($others as $u) { $contribs[$u] .= ' (<span class="diff-added">' . sprintf("%4.1f", round($user_adds[$u] / $user_adds[$authors[0]] * 100, 2)); $contribs[$u] .= '</span>/'; $contribs[$u] .= '<span class="diff-removed">' . sprintf("%4.1f", round($user_dels[$u] / $user_dels[$authors[0]] * 100, 2)); $contribs[$u] .= '</span>)'; } $u = preg_match('/^([0-9]+\\.){3}[0-9]+$/', $orig_author) ? _mask_hostname($orig_author) : $orig_author; $ou = $count_users == 1 ? $orig_author : $authors[0]; $ou = preg_match('/^([0-9]+\\.){3}[0-9]+$/', $ou) ? _mask_hostname($ou) : $ou; $out = "<div class='wikiInfo'><h2>" . _("Revision Statistics") . "</h2>\n"; $out .= '<h3>' . sprintf(_("Total %d revisions"), $count_revs) . ', '; $out .= sprintf(_("Total %d editors"), sizeof($users)) . '</h3>' . "\n"; $out .= '<table class="wiki center">'; $out .= '<tr><th>' . _("Initial revision") . '</th><td>' . $rev . '</td></tr>' . "\n"; $out .= '<tr><th>' . _("Original Author") . '</th><td>' . $u . '</td></tr>' . "\n"; if ($count_users == 1 && $show_table) { $out .= '<tr><th>' . _("First Contribution Author") . '</th><td>' . $ou . '</td></tr>' . "\n"; } else { if ($show_table && $contribs[$authors[0]] > $first_contribution_author_ratio) { $out .= '<tr><th>' . _("First Contribution Author") . '</th><td>' . $ou . '</td></tr>' . "\n"; } } $out .= '</table> <br />' . "\n"; if ($show_table) { $out .= '<table class="wiki center"><tr><th>' . _("User") . '</th><th>' . _("Add") . '</th><th>' . _("Del") . '</th><th>' . _("Edit") . '</th><th>' . _("Contributions") . '</th><th>' . _("IP") . '</th></tr>'; foreach ($edits as $u => $c) { $v = $users[$u]; $ips = array_map('_mask_hostname', array_keys($v['ip'])); $uu = preg_match('/^([0-9]+\\.){3}[0-9]+$/', $u) ? _mask_hostname($u) : $u; $out .= '<tr><td>' . $uu . '</td><td><span class="diff-added">+' . $v['add'] . '</span></td><td>' . '<span class="diff-removed"> -' . $v['del'] . '</span></td><td> ' . $v['edit'] . "</td>"; $out .= '<td>' . $contribs[$u] . '</td>'; $out .= '<td>' . implode(', ', $ips) . "</td></tr>\n"; } $out .= '</table>'; } // binning $c = sizeof($times); $min = intval($times[$c - 1] / 3600) * 3600; $max = intval($times[0] / 3600) * 3600; $range = $max - $min; if ($c > 50) { $bin = $range / 20; $szbin = 20; } else { if ($c > 20) { $bin = $range / 10; $szbin = 10; } else { if ($c > 5) { $bin = $range / 5; $szbin = 5; } else { $bin = $range / $c; $szbin = $c; } } } $add_bins = array(); $del_bins = array(); $sum = array(); for ($i = 0; $i <= $szbin; $i++) { $add_bins[$i] = 0; $del_bins[$i] = 0; $sum[$i] = 0; } for ($i = $c - 1; $i >= 0; $i--) { $j = intval(($times[$i] - $min) / $bin); $add_bins[$j] += $adds[$i]; $del_bins[$j] -= $dels[$i]; $sum[$j] += -$adds[$i] + $dels[$i]; } $sum[$szbin] = $total_lines; for ($i = $szbin - 1; $i >= 0; $i--) { $sum[$i] += $sum[$i + 1]; } $barchart = ''; $labels = array(); for ($j = 0; $j <= $szbin; $j++) { $labels[$j] = gmdate('Y-m-d', $j * $bin + $min); } $lab = '["' . implode('","', $labels) . '"]'; $add = '[' . implode(',', $add_bins) . ']'; $del = '[' . implode(',', $del_bins) . ']'; $sum = '[' . implode(',', $sum) . ']'; $barchart = <<<EOS <script type='text/javascript'> (function() { var data = { labels : {$lab}, datasets : [ { label : "added lines", fillColor : "rgba(0,220,0,0.0)", strokeColor : "rgba(0,220,0,0.8)", pointColor : "rgba(0,220,0,0.6)", highlightFill : "rgba(0,220,0,0)", highlightStroke : "rgba(0,220,0,1)", data : {$add} }, { label : "deleted lines", fillColor : "rgba(220,0,0,0.0)", strokeColor : "rgba(220,0,0,0.8)", pointColor : "rgba(220,0,0,0.6)", highlightFill : "rgba(220,0,0,0.75)", highlightStroke : "rgba(220,0,0,1)", data : {$del} }, { label : "total lines", fillColor : "rgba(0,220,220,0.0)", strokeColor : "rgba(0,220,220,0.8)", pointColor : "rgba(0,220,220,0.7)", highlightFill : "rgba(0,220,220,0)", highlightStroke : "rgba(0,220,220,1)", data : {$sum} } ] }; // onload var oldOnload = window.onload; window.onload = function(ev) { try { oldOnload(); } catch(e) {}; var ctx = document.getElementById("info-stat").getContext("2d"); window.myBar = new Chart(ctx).Line(data, { scaleBeginAtZero:false, scaleIntegersOnly:false,responsive:true }); }; })(); </script> EOS; $dump = ''; for ($j = 0; $j < $szbin; $j++) { $dump .= 'add= ' . $add_bins[$j] . ', del= ' . $del_bins[$j] . ', sum= ' . $sum[$j] . "\n"; } return $out . "<div class='info-stat'><canvas id='info-stat'></canvas>" . $barchart; }
function do_blame($formatter, $params) { global $DBInfo; $rev = ''; $option = ''; if (!empty($params['rev'])) { if (preg_match('/^\\d\\.\\d+$/', $params['rev'])) { $rev = $params['rev']; $option = ' -r' . $rev; } } if (!$formatter->page->exists()) { $params['msg'] = _("Error: Page Not found !"); do_invalid($formatter, $params); return; } $formatter->send_header('', $params); if (isset($rev[0])) { $params['.title'] = sprintf(_("Blame r%s"), $rev); } else { $params['.title'] = sprintf(_("Blame of %s page"), _html_escape($formatter->page->name)); } $key = $DBInfo->getPageKey($formatter->page->name); // FIXME call blame $fp = popen("blame -x,v/ {$option} " . $key, 'r'); //.' '.$formatter->NULL, 'r'); $out = ''; if (is_resource($fp)) { while (!feof($fp)) { $line = fgets($fp, 2048); $out .= $line; } pclose($fp); } $formatter->send_title($title, '', $params); $lines = explode("\n", $out); $end = array_pop($lines); if ($end != '') { array_push($lines, $end); } $u =& $DBInfo->user; $is_member = $u->is_member; // members $members = $DBInfo->members; // check modified blame or not if (($p = strpos($lines[0], "\t")) !== false && $p < 23) { $sep = "@\t@"; $count = 5; } else { $sep = "@\\s+@"; $count = 4; } $ipicon = '<img src="' . $DBInfo->imgs_dir . '/misc/ip.png" />'; if (!empty($DBInfo->use_avatar)) { if (is_string($DBInfo->use_avatar)) { $type = $DBInfo->use_avatar; } else { $type = 'identicon'; } $avatarlink = qualifiedUrl($formatter->link_url('', '?action=' . $type . '&seed=')); } echo '<div class="wikiBlame"><table>'; $ov = ''; $alts = array('', ' alt'); $j = 0; $ii = 1; $blame_url = $formatter->link_url($formatter->page->urlname, '?action=blame&rev='); foreach ($lines as $line) { $tmp = preg_split($sep, $line, $count); $v = trim($tmp[0]); if ($count == 4) { $u = trim($tmp[1], '('); $t = trim($tmp[2], '):'); $l = $tmp[3]; } else { $ip = $tmp[1]; $u = $tmp[2]; $t = $tmp[3]; $l = $tmp[4]; if (!empty($DBInfo->use_avatar)) { $crypted = crypt($ip, $ip); $mylnk = preg_replace('/seed=/', 'seed=' . $crypted, $avatarlink); $avatar = '<img src="' . $mylnk . '" style="width:16px;height:16px;vertical-align:middle" alt="avatar" />'; } else { $avatar = ''; } if ($u == 'Anonymous') { if (!$is_member) { $avatar . ($u = _mask_hostname($ip, 2)); } else { if (isset($DBInfo->interwiki['Whois'])) { $wip = "<a href='" . $DBInfo->interwiki['Whois'] . "{$ip}' target='_blank'>{$ipicon}</a>"; } else { $wip = "<a href='?action=whois&q=" . $ip . "' target='_blank'>{$ipicon}</a>"; } $u = $ip; if (!empty($DBInfo->use_admin_user_url)) { $u = '<a href="' . $DBInfo->use_admin_user_url . $u . '">' . $u . '</a>'; } $u = $avatar . $u . $wip; } } else { if (isset($DBInfo->interwiki['Whois'])) { $wip = "<a href='" . $DBInfo->interwiki['Whois'] . "{$ip}' target='_blank'>{$ipicon}</a>"; } else { $wip = "<a href='?action=whois&q=" . $ip . "' target='_blank'>{$ipicon}</a>"; } if ($is_member) { if (!in_array($u, $members)) { $u = $avatar . $u . $wip; } else { $u = $avatar . $u; } } else { $u = $avatar . $u; } } $t = date('y-m-d', $t); } if ($ov != $v) { $alt = $alts[++$j % 2]; } else { $alt = ''; } $link = '<a href="' . $blame_url . $v . '">' . $v . '</a>'; echo '<tr><td class="version' . $alt . '">r' . $link, '</td> <td class="author' . $alt . '">', "{$u}", '</td> <td class="date' . $alt . '">', $t, '</td><td class="line">' . $ii . '</td><td class="src' . $alt . '">' . str_replace('<', '<', $l) . '</td></tr>'; $ov = $v; $ii++; } echo '</table></div>'; $formatter->send_footer('', $params); return; }