2025 RationalWiki 'Oregon Plan' Fundraiser

There is no RationalWiki without you. We are a small non-profit with no staff—we are hundreds of volunteers who document pseudoscience and crankery around the world every day. We will never allow ads because we must remain independent. We cannot rely on big donors with corresponding big agendas. We are not the largest website around, but we believe we play an important role in defending truth and objectivity.

Fighting pseudoscience isn't free.
We are 100% user-supported! Help and donate $5, $10, $20 or whatever you can today with PayPal Logo.png!
Donations so far: $10064.65Goal: $10000

User:Nx/Extensions/wigo3/wigo3.php

From RationalWiki
Jump to navigation Jump to search
<?php

# This extension requires a table in the database, create it with the following mysql command:
# replace varbinary with varchar depending on wiki setup
# create table /*$wgDBprefix*/wigovote (id varbinary(255) NOT NULL, voter_name varbinary(255) NOT NULL, vote int NOT NULL default 0, timestamp varbinary(14), PRIMARY KEY (id,voter_name)) /*$wgDBTableOptions*/;

if ( !defined( 'MEDIAWIKI' ) ) {
	exit;
}

# store ips instead of usernames for logged in users too
$wgWigo3ConfigStoreIPs = true;

$wgExtensionCredits['parserhook'][] = array(
        'name' => 'WIGO Voting Extension',
        'author' => '[http://rationalwiki.com/wiki/User:Nx Nx]',
        'url' => 'http://rationalwiki.com/',
        'description' => 'Up/down voting system.',
        'version' => '3.5'
);

$wgWigoIP = dirname( __FILE__ );
$wgExtensionMessagesFiles['wigo3'] = "$wgWigoIP/wigo3.i18n.php";

//Avoid unstubbing $wgParser on setHook() too early on modern (1.12+) MW versions, as per r35980
if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
	$wgHooks['ParserFirstCallInit'][] = 'wigo3init';
} else { // Otherwise do things the old fashioned way
	$wgExtensionFunctions[] = 'wigo3init';
}

$wgHooks['AjaxAddScript'][] = 'wigo3addjs';

global $wgUseAjax;
if ($wgUseAjax)
{
  $wgAjaxExportList[] = "wigovote";
  $wgAjaxExportList[] = "wigovote2";
  $wgAjaxExportList[] = "wigoinvalidate";
}

function wigo3init() {
  global $wgParser;
  wfLoadExtensionMessages('wigo3');
  $wgParser->setHook('vote','wigo3render');
  $wgParser->setHook('votecp','wigo3rendercp');
  $wgParser->setHook('capture','wigo3rendercapture');
  return true;
}

function wigo3addjs($out) {
  global $wgJsMimeType, $wgScriptPath;
  $out->addScript("<script type=\"{$wgJsMimeType}\" src=\"{$wgScriptPath}/extensions/wigo3/js/wigo3.js\"></script>");
  return true;
}

function wigoinvalidate($pagename)
{
  //$pagename is wgPageName from javascript  
  $title = Title::newFromText($pagename);
  if ($title->invalidateCache() === true) {
    $dbw = wfGetDB(DB_MASTER);
    $dbw->commit();
    return "ok";
  } else {
    return "notok";
  }
}

/*
kept for compatibility
*/
function wigovote($pollid, $vote, $min=-1, $max=1)
{
  $dbw = wfGetDB(DB_MASTER);
  global $wgUser, $wgWigo3ConfigStoreIPs;
  $voter = $wgWigo3ConfigStoreIPs ? getenv ("REMOTE_ADDR") : $wgUser->getName();
  $result = $dbw->replace('wigovote',array('id','voter_name'),array('id' => $pollid, 'voter_name' => $voter, 'vote' => $vote, 'timestamp' => wfTimestampNow()),'wigovote');
  $res = $dbw->select('wigovote',array('sum(vote)','count(vote)'),array('id' => $pollid, "vote >= {$min}", "vote <= {$max}"),'wigovote',array('GROUP BY' => 'id'));
  $row = $res->fetchRow();
  $vote = $row['sum(vote)'];
  $countvotes = $row['count(vote)'];
  wfLoadExtensionMessages('wigo3');
  $totalvotes = wfMsgExt('wigovotestotal',array('parsemag'),array($countvotes));
  $res->free();
  $dbw->commit();
  $dbw->close();
  return "$pollid:$vote:$countvotes:$totalvotes:$result";
}

/*
voting function for up-down wigo only
*/
function wigovote2($pollid, $vote)
{
  /*store the vote*/
  $dbw = wfGetDB(DB_MASTER);
  global $wgUser, $wgWigo3ConfigStoreIPs;
  $voter = $wgWigo3ConfigStoreIPs ? getenv ("REMOTE_ADDR") : $wgUser->getName();
  $result = $dbw->replace('wigovote',array('id','voter_name'),array('id' => $pollid, 'voter_name' => $voter, 'vote' => $vote, 'timestamp' => wfTimestampNow()),'wigovote');
  $dbw->commit();
  
  /*get updated data to update page*/
  $plus = 0;
  $minus = 0;
  $zero = 0;
  $myvote = -2;

  wigo3getvotes($pollid, $plus, $minus, $zero,$voter,$myvote);
  
  wfLoadExtensionMessages('wigo3');
  $totalvotes = $plus + $minus + $zero;
  $totaltooltip = wfMsgExt('wigovotestotald',array('parsemag'),array($totalvotes,$plus,$zero,$minus));
/*  $totalup = wfMsgExt('wigovotestotal',array('parsemag'),array($plus));
  $totaldown = wfMsgExt('wigovotestotal',array('parsemag'),array($minus));
  $totalneutral = wfMsgExt('wigovotestotal',array('parsemag'),array($zero));*/
  $distribtitle = wfMsgExt('wigovotedistrib',array('parsemag'),array($plus,$zero,$minus));
  return "$pollid:$plus:$minus:$zero:$totalvotes:$totaltooltip:$distribtitle:$myvote:$result";
}

function wigo3getvotes($voteid, &$plus, &$minus, &$zero, $voter, &$myvote) {
  $dbr = wfGetDB(DB_SLAVE);
  $res = $dbr->select('wigovote',
                      array('sum(case vote when 1 then 1 else 0 end) as plus',
                            'sum(case vote when -1 then 1 else 0 end) as minus',
                            'sum(case vote when 0 then 1 else 0 end) as zero'),
                      array('id' => $voteid),__FUNCTION__);
  if ($row = $res->fetchRow())
  {
    $plus = $row['plus'];
    $minus = $row['minus'];
    $zero = $row['zero'];
  }
  if ($plus == null) {
    $plus = 0;
  }
  if ($minus == null) {
    $minus = 0;
  }
  if ($zero == null) {
    $zero = 0;
  }
  $res->free();
  //myvote does not work with caching
/*  $myvote = $dbr->selectField('wigovote','vote',array('id' => $voteid, 'voter_name' => $voter),__FUNCTION__);
  if ($myvote === false) {
    $myvote = -2;
  }*/
  $myvote = -2;
}

function wigo3rendercp($input, $args, $parser) {
  return wigo3render($input, $args, $parser,true);
}

function wigo3render($input, $args, $parser, $cp = false) {
  //disabled to improve performance
  //$parser->disableCache();
  $voteid = $args['poll'];
  if (!$voteid)
  {
    static $err = null;
    if (is_null($err)) {
      wfLoadExtensionMessages('wigo3');
      $err = wfMsg('wigoerror');
    }
    $output = $parser->recursiveTagParse($input);
    return "<p><span style='color:red;'>{$err}</span> {$output}</p>";
  }
  
  $plus = 0;
  $minus = 0;
  $zero = 0;
  $myvote = -2;
  global $wgUser, $wgWigo3ConfigStoreIPs;
  $voter = $wgWigo3ConfigStoreIPs ? getenv ("REMOTE_ADDR") : $wgUser->getName();
  wigo3getvotes($voteid,$plus,$minus,$zero,$voter,$myvote);
  $votes = $plus - $minus;
  $countvotes = $plus + $minus + $zero;

  //backwards compatible img tag handling
  if (!$cp && array_key_exists('img',$args) && (!strcmp($args['img'],'on') || !strcmp($args['img'],'expanded'))) {
    $input = preg_replace('/\[[^\]]*conservapedia\.com[^\]]*\]/i',
                          "$0<sup>[[:Image:{$args['poll']}_x.png|img]]</sup>",$input);
    $x = 0;
    do {
      $input = preg_replace('/(<sup>\[\[:Image:' . $args['poll'] . '_)x(\.png\|img\]\]<\/sup>)/',
                          "$1 {$x}$2", $input,1,$count);
      ++$x;
    } while ($count);
  }

  $output = $parser->recursiveTagParse($input);  
  //votecp img tag handling
  if ($cp)
  {
    $matchi = preg_match_all('/(<a[^>]*href="([^"]*conservapedia\.com[^"]*)"[^>]*>(?:[^<]|<[^\/]|<\/[^a]|<\/a[^>])*<\/a>)(?!<span class="wigocapture">)/i', $output,$matches,PREG_OFFSET_CAPTURE);
    if ($matchi > 0) $newoutput = substr($output,0,$matches[1][0][1]);
    for ($i=0; $i<$matchi;++$i) {
      //performance impact of sha1 is 1.2x
      $imgname = 'capture_' /*. $args['poll'] . '_'*/ . /*crc32*/ /*md5*/ sha1($matches[2][$i][0]) . '.png';
      $text = $matches[1][$i][0];
      $img = $parser->recursiveTagParse("<span class=\"wigocapture\"><sup>[[:Image:$imgname|img]]</sup></span>");
      $nextlength = (($i == $matchi-1) ? (strlen($output) - ($matches[1][$i][1] + strlen($text))) : ($matches[1][$i+1][1] - ($matches[1][$i][1] + strlen($text))));
      $newoutput .= substr($output,$matches[1][$i][1],strlen($text)) . $img . 
                    substr($output,$matches[1][$i][1]+strlen($text),$nextlength);
    }
    if ($matchi > 0) $output = $newoutput;  
  }  

  //wfMsgExt resets the parser state if the message contains a parser function, breaking for example references. recursiveTagParse doesn't.
  wfLoadExtensionMessages('wigo3');
  //$totalvotes = wfMsgExt('wigovotestotald',array('parsemag'),array($countvotes,$plus,$zero,$minus));
  $totalvotes = htmlspecialchars($parser->recursiveTagParse(wfMsgNoTrans('wigovotestotald',array($countvotes,$plus,$zero,$minus))));
/*  $totalup = wfMsgExt('wigovotestotal',array('parsemag'),array($plus));
  $totaldown = wfMsgExt('wigovotestotal',array('parsemag'),array($minus));
  $totalneutral = wfMsgExt('wigovotestotal',array('parsemag'),array($zero));*/
  //$distribtitle = wfMsgExt('wigovotedistrib',array('parsemag'),array($plus,$zero,$minus));
  $distribtitle = htmlspecialchars($parser->recursiveTagParse(wfMsgNoTrans('wigovotedistrib',array($plus,$zero,$minus))));
  if ($countvotes != 0) {
    $uppercent = ($plus / $countvotes) * 100;
    $downpercent = ($minus / $countvotes) * 100;
    $neutralpercent = ($zero / $countvotes) * 100;
  } else {
    $uppercent = 0;
    $downpercent = 0;
    $neutralpercent = 0;
  }
  
  if ($uppercent != 0) {
    $uppercent .= "%";
  }
  if ($neutralpercent != 0) {
    $neutralpercent .= "%";
  }
  if ($downpercent != 0) {
    $downpercent .= "%";
  }
  
  if (array_key_exists('closed',$args) && strcasecmp($args['closed'],"yes") === 0) {
    return "<table class=\"vote\" cellspacing=\"2\" cellpadding=\"2\" border=\"0\">" .
              "<tr>" .
                "<td style=\"white-space:nowrap;\">" .
                    "<table id=\"{$voteid}-dist\" class=\"wigodistribution\" style=\"width:48px; height:6px; border:1px solid grey; margin:0; padding:0; border-spacing:0;\" title=\"{$distribtitle}\">" .
                      "<tr>" .
                        "<td class=\"wigodist-up\" style=\"border:none; background-color:limegreen; margin:0; padding:0; width:{$uppercent}; height:100%; " . ($totalvotes == 0 ? "display:none;" : "") . "\"></td>" . 
                        "<td class=\"wigodist-neutral\" style=\"border:none; background-color:orange; margin:0; padding:0; width:{$neutralpercent}; height:100%; " . ($totalvotes == 0 ? "display:none;" : "") . "\"></td>" . 
                        "<td class=\"wigodist-down\" style=\"border:none; background-color:red; margin:0; padding:0; width:{$downpercent}; height:100%; " . ($totalvotes == 0 ? "display:none;" : "") . "\"></td>" . 
                    "</tr></table>" .
                "</td>" .
                "<td style=\"min-width:25px; text-align:center;\">" .
                  "<span id=\"{$voteid}\" title=\"{$totalvotes}\">{$votes}</span>" .
                "</td>" .
                "<td style=\"vertical-align:middle;\">" .
                  "<!--$voteid-->$output" .
                "</td>" .
              "</tr>" .
            "</table>";
  } else {
    //get up-down images
    //static improves performance a bit
    static $up = null;
    static $down = null;
    static $reset = null;
    static $altup = null;
    static $altdown = null;
    static $altreset = null;
    static $titleup = null;
    static $titledown = null;
    static $titlereset = null;

    if ( is_null($up) || is_null($down) || is_null($reset) 
         || is_null($altup) || is_null($altdown) || is_null($altreset) 
         || is_null($titleup) || is_null($titledown) || is_null($titlereset) ) {
      wfLoadExtensionMessages('wigo3');
      $up = wfFindFile(wfMsg('wigouparrow'));
      $up = $up ? $up->getFullUrl() : '';
      $down = wfFindFile(wfMsg('wigodownarrow'));
      $down = $down ? $down->getFullUrl() : '';
      $reset = wfFindFile(wfMsg('wigoresetvote'));
      $reset = $reset ? $reset->getFullUrl() : '';
      $altup = wfMsgHtml('wigoaltup');
      $altdown = wfMsgHtml('wigoaltdown');
      $altreset = wfMsgHtml('wigoaltreset');
      $titleup = wfMsgHtml('wigotitleup');
      $titledown = wfMsgHtml('wigotitledown');
      $titlereset = wfMsgHtml('wigotitlereset');
    }

    return "<table class=\"vote\" cellspacing=\"2\" cellpadding=\"2\" border=\"0\">" .
              "<tr>" .
                "<td style=\"white-space:nowrap;\">" .
                  "<a " . "href=\"javascript:wigovoteup('{$voteid}')\" id=\"{$voteid}-up\" class=\"wigobutton wigoupbutton " . ($myvote == 1 ? "myvotebutton" : "") . " \">" .
                    "<img alt=\"{$altup}\" title=\"{$titleup}\" src=\"$up\"></img></a>" .
                  "<a " . "href=\"javascript:wigovotereset('{$voteid}')\" id=\"{$voteid}-neutral\" class=\"wigobutton wigoneutralbutton " . ($myvote == 0 ? "myvotebutton" : "") . " \">" .
                    "<img alt=\"{$altreset}\" title=\"{$titlereset}\" src=\"$reset\"></img></a>" .
                  "<a " . "href=\"javascript:wigovotedown('{$voteid}')\" id=\"{$voteid}-down\" class=\"wigobutton wigodownbutton " . ($myvote == -1 ? "myvotebutton" : "") . " \">" .
                    "<img alt=\"{$altdown}\" title=\"{$titledown}\" src=\"$down\"></img></a>" .
                    "<table id=\"{$voteid}-dist\" class=\"wigodistribution\" style=\"width:100%; height:6px; border:1px solid grey; margin:0; padding:0; border-spacing:0;\" title=\"{$distribtitle}\">" .
                      "<tr>" .
                        "<td class=\"wigodist-up\" style=\"border:none; background-color:limegreen; margin:0; padding:0; width:{$uppercent}; height:100%; " . ($totalvotes == 0 ? "display:none;" : "") . "\"></td>" . 
                        "<td class=\"wigodist-neutral\" style=\"border:none; background-color:orange; margin:0; padding:0; width:{$neutralpercent}; height:100%; " . ($totalvotes == 0 ? "display:none;" : "") . "\"></td>" . 
                        "<td class=\"wigodist-down\" style=\"border:none; background-color:red; margin:0; padding:0; width:{$downpercent}; height:100%; " . ($totalvotes == 0 ? "display:none;" : "") . "\"></td>" . 
                    "</tr></table>" .
                "</td>" .
                "<td style=\"min-width:25px; text-align:center;\">" .
                  "<span id=\"{$voteid}\" title=\"{$totalvotes}\">{$votes}</span>" .
                "</td>" .
                "<td style=\"vertical-align:middle;\">" .
                  "<!--$voteid-->$output" .
                "</td>" .
              "</tr>" .
            "</table>";
  }
}

function wigo3rendercapture($input, $args, $parser) {
  $output = $parser->recursiveTagParse($input);
  $matchi = preg_match_all('/(<a[^>]*href="([^"]*)"[^>]*>(?:[^<]|<[^\/]|<\/[^a]|<\/a[^>])*<\/a>)(?!<span class="wigocapture">)/i', $output,$matches,PREG_OFFSET_CAPTURE);
  if ($matchi > 0) $newoutput = substr($output,0,$matches[1][0][1]);
  for ($i=0; $i<$matchi;++$i) {
    $imgname = 'capture_' /*. $args['poll'] . '_'*/ . /*crc32*/ /*md5*/ sha1($matches[2][$i][0]) . '.png';
    $text = $matches[1][$i][0];
    $img = $parser->recursiveTagParse("<span class=\"wigocapture\"><sup>[[:Image:$imgname|img]]</sup></span>");
    $nextlength = (($i == $matchi-1) ? (strlen($output) - ($matches[1][$i][1] + strlen($text))) : ($matches[1][$i+1][1] - ($matches[1][$i][1] + strlen($text))));
    $newoutput .= substr($output,$matches[1][$i][1],strlen($text)) . $img . 
                  substr($output,$matches[1][$i][1]+strlen($text),$nextlength);
  }
  if ($matchi > 0) $output = $newoutput;
  return $output;
}