r45690 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r45689‎ | r45690 | r45691 >
Date:00:18, 13 January 2009
Author:ipye
Status:deferred
Tags:
Comment:
Merge commit 'origin/ian-luca'
Modified paths:
  • /trunk/extensions/WikiTrust/mediawiki/extensions/Trust/README-remote (added) (history)
  • /trunk/extensions/WikiTrust/mediawiki/extensions/Trust/RemoteTrust.php (added) (history)
  • /trunk/extensions/WikiTrust/mediawiki/extensions/Trust/Trust.php (modified) (history)

Diff [purge]

Index: trunk/extensions/WikiTrust/mediawiki/extensions/Trust/RemoteTrust.php
@@ -0,0 +1,675 @@
 2+<?php
 3+
 4+# Copyright (c) 2007,2008 Luca de Alfaro
 5+# Copyright (c) 2007,2008 Ian Pye
 6+# Copyright (c) 2007 Jason Benterou
 7+#
 8+# This program is free software; you can redistribute it and/or
 9+# modify it under the terms of the GNU General Public License as
 10+# published by the Free Software Foundation; either version 2 of the
 11+# License, or (at your option) any later version.
 12+
 13+# This program is distributed in the hope that it will be useful, but
 14+# WITHOUT ANY WARRANTY; without even the implied warranty of
 15+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 16+# General Public License for more details.
 17+
 18+# You should have received a copy of the GNU General Public License
 19+# along with this program; if not, write to the Free Software
 20+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 21+# USA
 22+
 23+## MW extension
 24+# This defines a custom MW function to map trust values to HTML markup
 25+#
 26+# Uses Tool Tip JS library under the LGPL.
 27+# http://www.walterzorn.com/tooltip/tooltip_e.htm
 28+
 29+ // Turn old style errors into exceptions.
 30+function exception_error_handler($errno, $errstr, $errfile, $errline ) {
 31+ throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
 32+}
 33+
 34+ // But only for warnings.
 35+set_error_handler("exception_error_handler", E_WARNING);
 36+
 37+class TextTrust extends TrustBase {
 38+
 39+ ## Types of analysis to perform.
 40+ const TRUST_EVAL_VOTE = 0;
 41+ const TRUST_EVAL_EDIT = 10;
 42+ const TRUST_EVAL_MISSING = 15;
 43+
 44+ ## the css tag to use
 45+ const TRUST_CSS_TAG = "background-color"; ## color the background
 46+ #$TRUST_CSS_TAG = "color"; ## color just the text
 47+
 48+ ## ColorText is called multiple times, but we only want to color true text.
 49+ const DIFF_TOKEN_TO_COLOR = "Lin";
 50+
 51+ ## Trust normalization values;
 52+ const MAX_TRUST_VALUE = 9;
 53+ const MIN_TRUST_VALUE = 0;
 54+ const TRUST_MULTIPLIER = 10;
 55+
 56+ ## Token to split trust and origin values on
 57+ const TRUST_SPLIT_TOKEN = ',';
 58+
 59+ ## Token to be replaed with <
 60+ const TRUST_OPEN_TOKEN = "QQampo:";
 61+
 62+ ## Token to be replaed with >
 63+ const TRUST_CLOSE_TOKEN = ":ampc:";
 64+
 65+ ## Server forms
 66+ const NOT_FOUND_TEXT_TOKEN = "TEXT_NOT_FOUND";
 67+ const TRUST_COLOR_TOKEN = "<!--trust-->";
 68+
 69+ ## Context for communicating with the trust server
 70+ const TRUST_TIMEOUT = 10;
 71+
 72+ ## default values for variables found from LocalSettings.php
 73+ var $DEFAULTS = array(
 74+ 'wgShowVoteButton' => false,
 75+ 'wgVoteText' => "I believe this information is correct",
 76+ 'wgThankYouForVoting' => "Thank you for your vote.",
 77+ 'wgNoTrustExplanation' =>
 78+ "<p><center><b>There is no trust information available for this text yet.</b></center></p>",
 79+ 'wgTrustCmd' => "eval_online_wiki",
 80+ 'wgVoteRev' => "vote_revision",
 81+ 'wgTrustLog' => "/dev/null",
 82+ 'wgTrustDebugLog' => "/dev/null",
 83+ 'wgRepSpeed' => 1.0,
 84+ 'wgNotPartExplanation' => "This page is not part of the trust coloring experement",
 85+ 'wgTrustTabText' => "Show Trust",
 86+ 'wgTrustExplanation' =>
 87+ "<p><center><b>This is a product of the text trust algoruthm.</b></center></p>",
 88+ 'wgContentServerURL' => "http://localhost:4444/?"
 89+ );
 90+
 91+ ## Median Value of Trust
 92+ var $median = 1.0;
 93+
 94+ ## Number of times a revision is looked at.
 95+ var $times_rev_loaded = 0;
 96+
 97+ ## Load the article we are talking about
 98+ var $title;
 99+
 100+ ## Only color the text once.
 101+ var $colored = false;
 102+
 103+ ## Don't close the first opening span tag
 104+ var $first_span = true;
 105+
 106+ ## And the same for origin tags
 107+ var $first_origin = true;
 108+
 109+ ## And the last revision of the title
 110+ var $current_rev;
 111+
 112+ ## Only add the scripts once.
 113+ var $scripts_added = false;
 114+
 115+ ## Should we do all the fancy trust processing?
 116+ var $trust_engaged = false;
 117+
 118+ ## map trust values to html color codes
 119+ var $COLORS = array(
 120+ "trust0",
 121+ "trust1",
 122+ "trust2",
 123+ "trust3",
 124+ "trust4",
 125+ "trust5",
 126+ "trust6",
 127+ "trust7",
 128+ "trust9",
 129+ "trust10",
 130+ );
 131+
 132+ ## Only write a new trust tag when the trust changes.
 133+ var $current_trust = "trust0";
 134+
 135+ var $trustJS = '
 136+<script type="text/javascript">/*<![CDATA[*/
 137+var ctrlState = false;
 138+function showOrigin(revnum) {
 139+ document.location.href = wgScriptPath + "/index.php?title=" + encodeURIComponent(wgPageName) + "&diff=" + encodeURIComponent(revnum);
 140+}
 141+
 142+// The Vote functionality
 143+function voteCallback(http_request){
 144+ if ((http_request.readyState == 4) && (http_request.status == 200)) {
 145+ document.getElementById("vote-button-done").style.visibility = "visible";
 146+ document.getElementById("vote-button").style.visibility = "hidden";
 147+ // alert(http_request.responseText);
 148+ return true;
 149+ } else {
 150+ alert(http_request.responseText);
 151+ return false;
 152+ }
 153+}
 154+
 155+function getQueryVariable(variable) {
 156+ var query = window.location.search.substring(1);
 157+ var vars = query.split("&");
 158+ for (var i=0;i<vars.length;i++) {
 159+ var pair = vars[i].split("=");
 160+ if (pair[0] == variable) {
 161+ return pair[1];
 162+ }
 163+ }
 164+ return "";
 165+}
 166+
 167+function startVote(){
 168+
 169+ var revID = getQueryVariable("oldid");
 170+ if (revID == ""){
 171+ revID = getQueryVariable("diff");
 172+ if (revID == ""){
 173+ revID = wgCurRevisionId;
 174+ }
 175+ }
 176+
 177+ return sajax_do_call( "TextTrust::handleVote", [wgUserName, wgArticleId, revID, wgPageName] , voteCallback );
 178+}
 179+
 180+/*]]>*/</script>';
 181+
 182+ var $trustCSS = '
 183+<style type="text/css">/*<![CDATA[*/
 184+.trust0 {
 185+ background-color: #FFB947;
 186+}
 187+
 188+.trust1 {
 189+ background-color: #FFC05C;
 190+}
 191+
 192+.trust2 {
 193+ background-color: #FFC870;
 194+}
 195+
 196+.trust3 {
 197+ background-color: #FFD085;
 198+}
 199+
 200+.trust4 {
 201+ background-color: #FFD899;
 202+}
 203+
 204+.trust5 {
 205+ background-color: #FFE0AD;
 206+}
 207+
 208+.trust6 {
 209+ background-color: #FFE8C2;
 210+}
 211+
 212+.trust7 {
 213+ background-color: #FFEFD6;
 214+}
 215+
 216+.trust8 {
 217+ background-color: #FFF7EB;
 218+}
 219+
 220+.trust9 {
 221+ background-color: #FFFFFF;
 222+}
 223+
 224+.trust10 {
 225+ background-color: #FFFFFF;
 226+}
 227+
 228+#vote-button-done {
 229+ visibility: hidden;
 230+ position: absolute;
 231+ top: 10px;
 232+ left: 500px;
 233+}
 234+
 235+#vote-button {
 236+ position: absolute;
 237+ top: 10px;
 238+ left: 500px;
 239+}
 240+
 241+/*]]>*/</style>';
 242+
 243+ public static function &singleton( )
 244+ { return parent::singleton( ); }
 245+
 246+ public function TextTrust(){
 247+ parent::__construct( );
 248+ global $wgExtensionCredits, $wgShowVoteButton, $wgVoteText, $wgThankYouForVoting;
 249+ global $wgNoTrustExplanation, $wgTrustCmd, $wgVoteRev, $wgTrustLog, $wgTrustDebugLog, $wgRepSpeed;
 250+ global $wgTrustTabText, $wgTrustExplanation, $wgNotPartExplanation, $wgContentServerURL;
 251+
 252+ //Add default values if globals not set.
 253+ if(!$wgShowVoteButton)
 254+ $wgShowVoteButton = $this->DEFAULTS['wgShowVoteButton'];
 255+ if(!$wgVoteText)
 256+ $wgVoteText = $this->DEFAULTS['wgVoteText' ];
 257+ if(!$wgThankYouForVoting)
 258+ $wgThankYouForVoting = $this->DEFAULTS['wgThankYouForVoting'];
 259+ if(!$wgNoTrustExplanation)
 260+ $wgNoTrustExplanation = $this->DEFAULTS['wgNoTrustExplanation'];
 261+ if(!$wgNotPartExplanation)
 262+ $wgNotPartExplanation = $this->DEFAULTS['wgNotPartExplanation'];
 263+ if(!$wgTrustCmd)
 264+ $wgTrustCmd = $this->DEFAULTS['wgTrustCmd' ];
 265+ if(!$wgVoteRev)
 266+ $wgVoteRev = $this->DEFAULTS['wgVoteRev'];
 267+ if(!$wgTrustLog)
 268+ $wgTrustLog = $this->DEFAULTS['wgTrustLog'];
 269+ if(!$wgTrustDebugLog)
 270+ $wgTrustDebugLog = $this->DEFAULTS['wgTrustDebugLog'];
 271+ if(!$wgRepSpeed)
 272+ $wgRepSpeed = $this->DEFAULTS['wgRepSpeed'];
 273+ if(!$wgTrustTabText)
 274+ $wgTrustTabText = $this->DEFAULTS['wgTrustTabText'];
 275+ if(!$wgTrustExplanation)
 276+ $wgTrustExplanation = $this->DEFAULTS['wgTrustExplanation'];
 277+ if(!$wgContentServerURL)
 278+ $wgContentServerURL = $this->DEFAULTS['wgContentServerURL'];
 279+
 280+# Define a setup function
 281+ $wgExtensionFunctions[] = 'ucscColorTrust_Setup';
 282+
 283+# Credits
 284+ $wgExtensionCredits['parserhook'][] = array(
 285+ 'name' => 'Trust Coloring',
 286+ 'author' =>'Ian Pye',
 287+ 'url' =>
 288+ 'http://trust.cse.ucsc.edu',
 289+ 'description' => 'This Extension
 290+colors text according to trust.'
 291+ );
 292+ }
 293+
 294+ // Sets the extension hooks.
 295+ public function setup() {
 296+ parent::setup();
 297+ global $wgHooks, $wgParser, $wgRequest, $wgUseAjax, $wgShowVoteButton, $wgAjaxExportList, $wgUser;
 298+
 299+# Code which takes the "I vote" action.
 300+# This has to be statically called.
 301+ if($wgUseAjax && $wgShowVoteButton){
 302+ $wgAjaxExportList[] = "TextTrust::handleVote";
 303+ }
 304+
 305+ // Is the user opting to use wikitrust?
 306+ $tname = "gadget-WikiTrust";
 307+ if (!$wgUser->getOption( $tname ) ) {
 308+ return;
 309+ }
 310+
 311+# Updater fiered when updating to a new version of MW.
 312+ $wgHooks['LoadExtensionSchemaUpdates'][] = array(&$this, 'updateDB');
 313+
 314+# And add and extra tab.
 315+ $wgHooks['SkinTemplateTabs'][] = array(&$this, 'ucscTrustTemplate');
 316+
 317+# If the trust tab is not selected, or some other tabs are don't worry about things any more.
 318+ if(!$wgRequest->getVal('trust') || $wgRequest->getVal('action')){
 319+ $this->trust_engaged = false;
 320+ return;
 321+ }
 322+ $this->trust_engaged = true;
 323+
 324+# Add trust CSS and JS
 325+ $wgHooks['OutputPageBeforeHTML'][] = array( &$this, 'ucscColorTrust_OP');
 326+
 327+# Add a hook to initialise the magic words
 328+ $wgHooks['LanguageGetMagic'][] = array( &$this, 'ucscColorTrust_Magic');
 329+
 330+# Set a function hook associating the blame and trust words with a callback function
 331+ $wgParser->setFunctionHook( 't', array( &$this, 'ucscColorTrust_Render'));
 332+
 333+# After everything, make the blame info work
 334+ $wgHooks['ParserAfterTidy'][] = array( &$this, 'ucscOrigin_Finalize');
 335+ }
 336+
 337+ /**
 338+ * Update the DB when MW is updated.
 339+ * This assums that the db has permissions to create tables.
 340+ */
 341+ function updateDB(){
 342+ // Create only those tables missing.
 343+ // Create the needed tables, if neccesary.
 344+ // Pull in the create scripts.
 345+ require_once("TrustUpdateScripts.inc");
 346+
 347+ $db =& wfGetDB( DB_MASTER );
 348+
 349+ // First check to see what tables have already been created.
 350+ $res = $db->query("show tables");
 351+ while ($row = $db->fetchRow($res)){
 352+ $db_tables[$row[0]] = True;
 353+ }
 354+
 355+ foreach ($create_scripts as $table => $scripts) {
 356+ if (!$db_tables[$table]){
 357+ foreach ($scripts as $script){
 358+ $db->query($script);
 359+ }
 360+ }
 361+ }
 362+ }
 363+
 364+ /**
 365+ Records the vote.
 366+ Called via ajax, so this must be static.
 367+ */
 368+ static function handleVote($user_name_raw, $page_id_raw = 0, $rev_id_raw = 0, $page_title = ""){
 369+
 370+ global $wgContentServerURL;
 371+ $response = new AjaxResponse("0");
 372+
 373+ $dbr =& wfGetDB( DB_SLAVE );
 374+
 375+ $userName = $dbr->strencode($user_name_raw, $dbr);
 376+ $page_id = $dbr->strencode($page_id_raw, $dbr);
 377+ $rev_id = $dbr->strencode($rev_id_raw, $dbr);
 378+
 379+ if($page_id){
 380+ // First, look up the id numbers from the page and user strings
 381+ $res = $dbr->select('user', array('user_id'), array('user_name' => $userName), array());
 382+ if ($res){
 383+ $row = $dbr->fetchRow($res);
 384+ $user_id = $row['user_id'];
 385+ if (!$user_id) {
 386+ $user_id = 0;
 387+ }
 388+ }
 389+ $dbr->freeResult( $res );
 390+
 391+ $ctx = stream_context_create(
 392+ array('http' => array(
 393+ 'timeout' =>
 394+ self::TRUST_TIMEOUT
 395+ )
 396+ )
 397+ );
 398+
 399+ $vote_str = ("Voting at " . $wgContentServerURL . "vote=1&rev=$rev_id&page=$page_id&user=$user_id&page_title=$page_title&time=" . wfTimestampNow());
 400+ $colored_text = file_get_contents($wgContentServerURL . "vote=1&rev=$rev_id&page=$page_id&user=$user_id&page_title=$page_title&time=" .
 401+ wfTimestampNow(), 0, $ctx);
 402+ $response = new AjaxResponse($vote_str);
 403+ }
 404+ return $response;
 405+ }
 406+
 407+ /**
 408+ Called just before rendering HTML.
 409+ We add the coloring scripts here.
 410+ */
 411+ function ucscColorTrust_OP(&$out, &$text){
 412+ if (!$this->scripts_added){ // Only add the scripts once.
 413+ $out->addScript($this->trustJS);
 414+ $out->addScript($this->trustCSS);
 415+ $this->scripts_added = true;
 416+ }
 417+ return true;
 418+ }
 419+
 420+# Actually add the tab.
 421+ function ucscTrustTemplate($skin, &$content_actions) {
 422+
 423+ global $wgTrustTabText, $wgRequest;
 424+ if (!isset($wgTrustTabText)){
 425+ $wgTrustTabText = "trust";
 426+ }
 427+
 428+ if ($wgRequest->getVal('action')){
 429+ // we don't want trust for actions.
 430+ return true;
 431+ }
 432+
 433+ if ($wgRequest->getVal('diff')){
 434+ // or for diffs
 435+ return true;
 436+ }
 437+
 438+ $trust_qs = $_SERVER['QUERY_STRING'];
 439+ if($trust_qs){
 440+ $trust_qs = "?" . $trust_qs . "&trust=t";
 441+ } else {
 442+ $trust_qs .= "?trust=t";
 443+ }
 444+
 445+ $content_actions['trust'] = array ( 'class' => '',
 446+ 'text' => $wgTrustTabText,
 447+ 'href' =>
 448+ $_SERVER['PHP_SELF'] . $trust_qs );
 449+
 450+ if($wgRequest->getVal('trust')){
 451+ $content_actions['trust']['class'] = 'selected';
 452+ $content_actions['nstab-main']['class'] = '';
 453+ $content_actions['nstab-main']['href'] .= '';
 454+ } else {
 455+ $content_actions['trust']['href'] .= '';
 456+ }
 457+ return true;
 458+ }
 459+
 460+ /**
 461+ If colored text exists, use it instead of the normal text,
 462+ but only if the trust tab is selected.
 463+ */
 464+ function ucscSeeIfColored(&$parser, &$text, &$strip_state = Null) {
 465+ global $wgRequest, $wgTrustExplanation, $wgUseAjax, $wgShowVoteButton, $wgDBprefix, $wgNoTrustExplanation, $wgVoteText, $wgThankYouForVoting, $wgNotPartExplanation, $wgContentServerURL;
 466+
 467+ // Get the db.
 468+ $dbr =& wfGetDB( DB_SLAVE );
 469+
 470+ // Do we use a DB prefix?
 471+ $prefix = ($wgDBprefix)? "-db_prefix " . $dbr->strencode($wgDBprefix): "";
 472+
 473+ // Text for showing the "I like it" button
 474+ $voteitText = "";
 475+ if ($wgUseAjax && $wgShowVoteButton){
 476+ $voteitText = "
 477+".self::TRUST_OPEN_TOKEN."div id='vote-button'".self::TRUST_CLOSE_TOKEN."".self::TRUST_OPEN_TOKEN."input type='button' name='vote' value='" . $wgVoteText . "' onclick='startVote()' /".self::TRUST_CLOSE_TOKEN."".self::TRUST_OPEN_TOKEN."/div".self::TRUST_CLOSE_TOKEN."
 478+".self::TRUST_OPEN_TOKEN."div id='vote-button-done'".self::TRUST_CLOSE_TOKEN.$wgThankYouForVoting.self::TRUST_OPEN_TOKEN."/div".self::TRUST_CLOSE_TOKEN."
 479+";
 480+ }
 481+
 482+ // Return if trust is not selected.
 483+ if (!$this->trust_engaged)
 484+ return true;
 485+
 486+ // Save the title object, if it is not already present
 487+ if (!$this->title){
 488+ $this->title = $parser->getTitle();
 489+ }
 490+
 491+ // count the number of times we load this text
 492+ $this->times_rev_loaded++;
 493+
 494+ // Load the current revision id.
 495+ if (!$this->current_rev){
 496+ if ($parser->mRevisionId){
 497+ $this->current_rev = $parser->mRevisionId;
 498+ } else {
 499+ // Sometimes the revisionId field is not filled in.
 500+ $this->current_rev = $this->title->getPreviousRevisionID( PHP_INT_MAX );
 501+ }
 502+ }
 503+
 504+ /**
 505+ This method is being called multiple times for each page.
 506+ We only pull the colored text for the first time through.
 507+ */
 508+ if ($this->colored){
 509+ return true;
 510+ }
 511+
 512+ if ($wgRequest->getVal('diff')){
 513+ // For diffs, look for the absence of the diff token instead of counting
 514+ if(substr($text,0,3) == self::DIFF_TOKEN_TO_COLOR){
 515+ return true;
 516+ }
 517+ }
 518+
 519+ // if we made it here, we are going to color some text
 520+ $this->colored = true;
 521+
 522+ // Check to see if this page is part of the coloring project.
 523+ // Disabled for now.
 524+ //if (!strstr($text, self::TRUST_COLOR_TOKEN)){
 525+ // $text = $wgNotPartExplanation . "\n" . $text;
 526+ // return true;
 527+ //}
 528+
 529+ // Get the page id and other data
 530+ $colored_text="";
 531+ $page_id=0;
 532+ $rev_timestamp="";
 533+ $rev_user=0;
 534+ $res = $dbr->select('revision', array('rev_page', 'rev_timestamp', 'rev_user'), array('rev_id' => $this->current_rev), array());
 535+ if ($res){
 536+ $row = $dbr->fetchRow($res);
 537+ $page_id = $row['rev_page'];
 538+ $rev_user = $row['rev_user'];
 539+ $rev_timestamp = $row['rev_timestamp'];
 540+ if (!$page_id) {
 541+ $page_id = 0;
 542+ }
 543+ }
 544+ $dbr->freeResult( $res );
 545+
 546+ $page_title = $_GET['title'];
 547+ $ctx = stream_context_create(
 548+ array('http' => array(
 549+ 'timeout' =>
 550+ self::TRUST_TIMEOUT
 551+ )
 552+ )
 553+ );
 554+ try {
 555+ // Should we do doing this via HTTPS?
 556+ $colored_raw = (file_get_contents($wgContentServerURL . "rev=" . $this->current_rev . "&page=$page_id&page_title=$page_title&time=$rev_timestamp&user=$rev_user", 0, $ctx));
 557+ } catch (Exception $e) {
 558+ $colored_raw = "";
 559+ }
 560+
 561+ if ($colored_raw && $colored_raw != self::NOT_FOUND_TEXT_TOKEN){
 562+ // Work around because of issues with php's built in
 563+ // gzip function.
 564+ $f = tempnam('/tmp', 'gz_fix');
 565+ file_put_contents($f, $colored_raw);
 566+ $colored_raw = file_get_contents('compress.zlib://' . $f);
 567+ unlink($f);
 568+
 569+ // Pick off the median value first.
 570+ $colored_data = explode(",", $colored_raw, 2);
 571+ $colored_text = $colored_data[1];
 572+ if (preg_match("/^[+-]?(([0-9]+)|([0-9]*\.[0-9]+|[0-9]+\.[0-9]*)|
 573+ (([0-9]+|([0-9]*\.[0-9]+|[0-9]+\.[0-9]*))[eE][+-]?[0-9]+))$/", $colored_data[0])){
 574+ $this->median = $colored_data[0];
 575+ }
 576+
 577+ // First, make sure that there are not any instances of our tokens in the colored_text
 578+ $colored_text = str_replace(self::TRUST_OPEN_TOKEN, "", $colored_text);
 579+ $colored_text = str_replace(self::TRUST_CLOSE_TOKEN, "", $colored_text);
 580+
 581+ $colored_text = preg_replace("/&apos;/", "'", $colored_text, -1);
 582+
 583+ $colored_text = preg_replace("/&amp;/", "&", $colored_text, -1);
 584+
 585+ $colored_text = preg_replace("/&lt;/", self::TRUST_OPEN_TOKEN, $colored_text, -1);
 586+ $colored_text = preg_replace("/&gt;/", self::TRUST_CLOSE_TOKEN, $colored_text, -1);
 587+
 588+ // Now update the text.
 589+ $text = $voteitText . $colored_text . "\n" . $wgTrustExplanation;
 590+ } else {
 591+ // Return a message about the missing text.
 592+ $text = $wgNoTrustExplanation . "\n" . $text;
 593+ }
 594+
 595+ return true;
 596+ }
 597+
 598+ /* Register the tags we are intersted in expanding. */
 599+ function ucscColorTrust_Magic( &$magicWords, $langCode ) {
 600+ $magicWords[ 't' ] = array( 0, 't' );
 601+ return true;
 602+ }
 603+
 604+ /* Pull in any colored text. Also handle closing tags. */
 605+ function ucscOrigin_Finalize(&$parser, &$text) {
 606+ global $wgScriptPath, $IP, $wgOut;
 607+
 608+ if(!$this->colored){
 609+ // This is to handle caching problems.
 610+ if (!strstr($text, "This page has been accessed")){
 611+ $colored_text = $text;
 612+ $this->ucscSeeIfColored($parser, $colored_text);
 613+ $text = $wgOut->parse( $colored_text );
 614+ } else {
 615+ $colored_text = $text;
 616+ $this->ucscSeeIfColored($parser, $colored_text);
 617+ $wgOut->mBodytext = $wgOut->parse( $colored_text );
 618+ }
 619+ }
 620+
 621+ $count = 0;
 622+ $text = '<script type="text/javascript" src="'.$wgScriptPath.'/extensions/Trust/js/wz_tooltip.js"></script>' . $text;
 623+ $text = preg_replace('/' . self::TRUST_OPEN_TOKEN . '/', "<", $text, -1, $count);
 624+ $text = preg_replace('/' . self::TRUST_CLOSE_TOKEN .'/', ">", $text, -1, $count);
 625+ $text = preg_replace('/<\/p>/', "</span></p>", $text, -1, $count);
 626+ $text = preg_replace('/<p><\/span>/', "<p>", $text, -1, $count);
 627+ $text = preg_replace('/<li><\/span>/', "<li>", $text, -1, $count);
 628+
 629+ return true;
 630+ }
 631+
 632+ /* Text Trust */
 633+ function ucscColorTrust_Render( &$parser, $combinedValue = "0,0,0" ) {
 634+
 635+ // Split the value into trust and origin information.
 636+ // 0 = trust
 637+ // 1 = origin
 638+ // 2 = contributing author
 639+ $splitVals = explode(self::TRUST_SPLIT_TOKEN, $combinedValue);
 640+
 641+ $class = $this->computeColorFromFloat($splitVals[0]);
 642+ $output = self::TRUST_OPEN_TOKEN . "span class=\"$class\""
 643+ . "onmouseover=\"Tip('".$splitVals[2]."')\" onmouseout=\"UnTip()\""
 644+ . "onclick=\"showOrigin("
 645+ . $splitVals[1] . ")\"" . self::TRUST_CLOSE_TOKEN;
 646+
 647+ $this->current_trust = $class;
 648+ if ($this->first_span){
 649+ $this->first_span = false;
 650+ } else {
 651+ $output = self::TRUST_OPEN_TOKEN . "/span" . self::TRUST_CLOSE_TOKEN . $output;
 652+ }
 653+
 654+ return array ( $output, "noparse" => false, "isHTML" => false );
 655+ }
 656+
 657+ /**
 658+ Maps from the online trust values to the css trust values.
 659+ Normalize the value for growing wikis.
 660+ */
 661+ function computeColorFromFloat($trust){
 662+ $normalized_value = min(self::MAX_TRUST_VALUE, max(self::MIN_TRUST_VALUE,
 663+ (($trust + .5) * self::TRUST_MULTIPLIER)
 664+ / $this->median));
 665+ return $this->computeColor3($normalized_value);
 666+ }
 667+
 668+ /* Maps a trust value to a HTML color representing the trust value. */
 669+ function computeColor3($fTrustValue){
 670+ return $this->COLORS[$fTrustValue];
 671+ }
 672+}
 673+
 674+TextTrust::singleton();
 675+
 676+?>
Property changes on: trunk/extensions/WikiTrust/mediawiki/extensions/Trust/RemoteTrust.php
___________________________________________________________________
Added: svn:eol-style
1677 + native
Index: trunk/extensions/WikiTrust/mediawiki/extensions/Trust/README-remote
@@ -0,0 +1,51 @@
 2+Instructions for running WikiTrust as a remote process on another
 3+server.
 4+
 5+It may be the case that you want to run WikiTrust split across
 6+multiple servers, where the base MW instalation lives on a web server,
 7+while the processing happens on one or more compute servers.
 8+
 9+MediwWiki Setup:
 10+
 11+Install the MW extenion as before, but instead of this line in
 12+LocalSettings.php,
 13+
 14+require_once( $IP . "/extensions/Trust/Trust.php" );
 15+
 16+Use this line:
 17+
 18+require_once( $IP . "/extensions/Trust/TrustRemote.php" );
 19+
 20+Also, add this variable to LocalSettings.php:
 21+$wgContentServerURL = "http://localhost:4444/?";
 22+
 23+This specifies the server and port to query when requesting colored
 24+markup. Note the presence of the final "?" charactor in the url.
 25+
 26+Next, because RemoteTrust uses the Gadgets extenion
 27+(http://www.mediawiki.org/wiki/Extension:Gadgets), you first need to
 28+install this extension. Gadgest allows indevedual users to turn
 29+WikiTrust on and off.
 30+
 31+Lastly, add this line
 32+
 33+* WikiTrust|wikitrust.js
 34+
 35+To the page MediaWiki:Gadgets-definition.
 36+
 37+This installs WikiTrust as a Gadget.
 38+
 39+Server Setup.
 40+
 41+Currently remote WikiTrust is self contained.
 42+
 43+All that is required is the same pattern of
 44+
 45+$ make all
 46+or
 47+$ make allopt
 48+
 49+Launch the server process with ./analysis/server, and the processing
 50+program with ./analysis/dispatcher.
 51+
 52+
Index: trunk/extensions/WikiTrust/mediawiki/extensions/Trust/Trust.php
@@ -25,15 +25,8 @@
2626 # Uses Tool Tip JS library under the LGPL.
2727 # http://www.walterzorn.com/tooltip/tooltip_e.htm
2828
29 - // Turn old style errors into exceptions.
30 -function exception_error_handler($errno, $errstr, $errfile, $errline ) {
31 - throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
32 -}
33 -
34 - // But only for warnings.
35 -set_error_handler("exception_error_handler", E_WARNING);
36 -
37 -class TextTrust extends TrustBase {
 29+class TextTrust extends TrustBase
 30+{
3831
3932 ## Types of analysis to perform.
4033 const TRUST_EVAL_VOTE = 0;
@@ -61,14 +54,6 @@
6255 ## Token to be replaed with >
6356 const TRUST_CLOSE_TOKEN = ":ampc:";
6457
65 - ## Server forms
66 - const NOT_FOUND_TEXT_TOKEN = "TEXT_NOT_FOUND";
67 - const TRUST_COLOR_TOKEN = "<!--trust-->";
68 - const CONTENT_URL = "http://localhost:4444/?";
69 -
70 - ## Context for communicating with the trust server
71 - const TRUST_TIMEOUT = 10;
72 -
7358 ## default values for variables found from LocalSettings.php
7459 var $DEFAULTS = array(
7560 'wgShowVoteButton' => false,
@@ -81,14 +66,13 @@
8267 'wgTrustLog' => "/dev/null",
8368 'wgTrustDebugLog' => "/dev/null",
8469 'wgRepSpeed' => 1.0,
85 - 'wgNotPartExplanation' => "This page is not part of the trust coloring experement",
8670 'wgTrustTabText' => "Show Trust",
8771 'wgTrustExplanation' =>
8872 "<p><center><b>This is a product of the text trust algoruthm.</b></center></p>",
8973 );
9074
9175 ## Median Value of Trust
92 - var $median = 1.0;
 76+ var $median = 0.0;
9377
9478 ## Number of times a revision is looked at.
9579 var $times_rev_loaded = 0;
@@ -143,7 +127,7 @@
144128 if ((http_request.readyState == 4) && (http_request.status == 200)) {
145129 document.getElementById("vote-button-done").style.visibility = "visible";
146130 document.getElementById("vote-button").style.visibility = "hidden";
147 - // alert(http_request.responseText);
 131+ //alert(http_request.responseText);
148132 return true;
149133 } else {
150134 alert(http_request.responseText);
@@ -173,7 +157,7 @@
174158 }
175159 }
176160
177 - return sajax_do_call( "TextTrust::handleVote", [wgUserName, wgArticleId, revID, wgPageName] , voteCallback );
 161+ return sajax_do_call( "TextTrust::handleVote", [wgUserName, wgArticleId, revID] , voteCallback );
178162 }
179163
180164 /*]]>*/</script>';
@@ -242,95 +226,97 @@
243227 public static function &singleton( )
244228 { return parent::singleton( ); }
245229
246 - public function TextTrust(){
247 - parent::__construct( );
248 - global $wgExtensionCredits, $wgShowVoteButton, $wgVoteText, $wgThankYouForVoting;
249 - global $wgNoTrustExplanation, $wgTrustCmd, $wgVoteRev, $wgTrustLog, $wgTrustDebugLog, $wgRepSpeed;
250 - global $wgTrustTabText, $wgTrustExplanation, $wgNotPartExplanation;
251 -
252 - //Add default values if globals not set.
253 - if(!$wgShowVoteButton)
254 - $wgShowVoteButton = $this->DEFAULTS['wgShowVoteButton'];
255 - if(!$wgVoteText)
256 - $wgVoteText = $this->DEFAULTS['wgVoteText' ];
257 - if(!$wgThankYouForVoting)
258 - $wgThankYouForVoting = $this->DEFAULTS['wgThankYouForVoting'];
259 - if(!$wgNoTrustExplanation)
260 - $wgNoTrustExplanation = $this->DEFAULTS['wgNoTrustExplanation'];
261 - if(!$wgNotPartExplanation)
262 - $wgNotPartExplanation = $this->DEFAULTS['wgNotPartExplanation'];
263 - if(!$wgTrustCmd)
264 - $wgTrustCmd = $this->DEFAULTS['wgTrustCmd' ];
265 - if(!$wgVoteRev)
266 - $wgVoteRev = $this->DEFAULTS['wgVoteRev'];
267 - if(!$wgTrustLog)
268 - $wgTrustLog = $this->DEFAULTS['wgTrustLog'];
269 - if(!$wgTrustDebugLog)
270 - $wgTrustDebugLog = $this->DEFAULTS['wgTrustDebugLog'];
271 - if(!$wgRepSpeed)
272 - $wgRepSpeed = $this->DEFAULTS['wgRepSpeed'];
273 - if(!$wgTrustTabText)
274 - $wgTrustTabText = $this->DEFAULTS['wgTrustTabText'];
275 - if(!$wgTrustExplanation)
276 - $wgTrustExplanation = $this->DEFAULTS['wgTrustExplanation'];
277 -
 230+ public function TextTrust()
 231+ {
 232+ parent::__construct( );
 233+ global $wgExtensionCredits, $wgShowVoteButton, $wgVoteText, $wgThankYouForVoting;
 234+ global $wgNoTrustExplanation, $wgTrustCmd, $wgVoteRev, $wgTrustLog, $wgTrustDebugLog, $wgRepSpeed;
 235+ global $wgTrustTabText, $wgTrustExplanation;
 236+
 237+ //Add default values if globals not set.
 238+ if(!$wgShowVoteButton)
 239+ $wgShowVoteButton = $this->DEFAULTS['wgShowVoteButton'];
 240+ if(!$wgVoteText)
 241+ $wgVoteText = $this->DEFAULTS['wgVoteText' ];
 242+ if(!$wgThankYouForVoting)
 243+ $wgThankYouForVoting = $this->DEFAULTS['wgThankYouForVoting'];
 244+ if(!$wgNoTrustExplanation)
 245+ $wgNoTrustExplanation = $this->DEFAULTS['wgNoTrustExplanation'];
 246+ if(!$wgTrustCmd)
 247+ $wgTrustCmd = $this->DEFAULTS['wgTrustCmd' ];
 248+ if(!$wgVoteRev)
 249+ $wgVoteRev = $this->DEFAULTS['wgVoteRev'];
 250+ if(!$wgTrustLog)
 251+ $wgTrustLog = $this->DEFAULTS['wgTrustLog'];
 252+ if(!$wgTrustDebugLog)
 253+ $wgTrustDebugLog = $this->DEFAULTS['wgTrustDebugLog'];
 254+ if(!$wgRepSpeed)
 255+ $wgRepSpeed = $this->DEFAULTS['wgRepSpeed'];
 256+ if(!$wgTrustTabText)
 257+ $wgTrustTabText = $this->DEFAULTS['wgTrustTabText'];
 258+ if(!$wgTrustExplanation)
 259+ $wgTrustExplanation = $this->DEFAULTS['wgTrustExplanation'];
 260+
278261 # Define a setup function
279 - $wgExtensionFunctions[] = 'ucscColorTrust_Setup';
280 -
 262+ $wgExtensionFunctions[] = 'ucscColorTrust_Setup';
 263+
281264 # Credits
282 - $wgExtensionCredits['parserhook'][] = array(
283 - 'name' => 'Trust Coloring',
284 - 'author' =>'Ian Pye',
285 - 'url' =>
286 - 'http://trust.cse.ucsc.edu',
287 - 'description' => 'This Extension
 265+ $wgExtensionCredits['parserhook'][] = array(
 266+ 'name' => 'Trust Coloring',
 267+ 'author' =>'Ian Pye',
 268+ 'url' =>
 269+ 'http://trust.cse.ucsc.edu',
 270+ 'description' => 'This Extension
288271 colors text according to trust.'
289 - );
 272+ );
290273 }
291274
292 - // Sets the extension hooks.
293 - public function setup() {
 275+ public function setup()
 276+ {
294277 parent::setup();
295 - global $wgHooks, $wgParser, $wgRequest, $wgUseAjax, $wgShowVoteButton, $wgAjaxExportList, $wgUser;
296 -
 278+ global $wgHooks, $wgParser, $wgRequest, $wgUseAjax, $wgShowVoteButton, $wgAjaxExportList;
 279+
297280 # Code which takes the "I vote" action.
298281 # This has to be statically called.
299282 if($wgUseAjax && $wgShowVoteButton){
300283 $wgAjaxExportList[] = "TextTrust::handleVote";
301284 }
302285
303 - // Is the user opting to use wikitrust?
304 - $tname = "gadget-WikiTrust";
305 - if (!$wgUser->getOption( $tname ) ) {
306 - return;
307 - }
308 -
309286 # Updater fiered when updating to a new version of MW.
310 - $wgHooks['LoadExtensionSchemaUpdates'][] = array(&$this, 'updateDB');
311 -
 287+ $wgHooks['LoadExtensionSchemaUpdates'][] = array( &$this, 'updateDB');
 288+
312289 # And add and extra tab.
313 - $wgHooks['SkinTemplateTabs'][] = array(&$this, 'ucscTrustTemplate');
314 -
 290+ $wgHooks['SkinTemplateTabs'][] = array( &$this, 'ucscTrustTemplate');
 291+
 292+# And add a hook so the colored text is found.
 293+ $wgHooks['ParserBeforeStrip'][] = array( &$this, 'ucscSeeIfColored');
 294+
 295+# Color saved text
 296+ $wgHooks['ArticleSaveComplete'][] = array( &$this, 'ucscRunColoring');
 297+
315298 # If the trust tab is not selected, or some other tabs are don't worry about things any more.
316299 if(!$wgRequest->getVal('trust') || $wgRequest->getVal('action')){
317300 $this->trust_engaged = false;
318301 return;
319302 }
320303 $this->trust_engaged = true;
321 -
 304+
322305 # Add trust CSS and JS
323306 $wgHooks['OutputPageBeforeHTML'][] = array( &$this, 'ucscColorTrust_OP');
324 -
 307+
325308 # Add a hook to initialise the magic words
326309 $wgHooks['LanguageGetMagic'][] = array( &$this, 'ucscColorTrust_Magic');
327 -
 310+
328311 # Set a function hook associating the blame and trust words with a callback function
329312 $wgParser->setFunctionHook( 't', array( &$this, 'ucscColorTrust_Render'));
330 -
 313+
331314 # After everything, make the blame info work
332315 $wgHooks['ParserAfterTidy'][] = array( &$this, 'ucscOrigin_Finalize');
 316+
 317+# Pull the median value
 318+ $this->update_median();
333319 }
334 -
 320+
335321 /**
336322 * Update the DB when MW is updated.
337323 * This assums that the db has permissions to create tables.
@@ -340,7 +326,7 @@
341327 // Create the needed tables, if neccesary.
342328 // Pull in the create scripts.
343329 require_once("TrustUpdateScripts.inc");
344 -
 330+
345331 $db =& wfGetDB( DB_MASTER );
346332
347333 // First check to see what tables have already been created.
@@ -348,7 +334,7 @@
349335 while ($row = $db->fetchRow($res)){
350336 $db_tables[$row[0]] = True;
351337 }
352 -
 338+
353339 foreach ($create_scripts as $table => $scripts) {
354340 if (!$db_tables[$table]){
355341 foreach ($scripts as $script){
@@ -358,16 +344,29 @@
359345 }
360346 }
361347
 348+ /**
 349+ * Turns an ASCII string into an octal encoded one.
 350+ * Call like this: TextTrust::prepareOutput("This is a test");
 351+ */
 352+ static function prepareOutput($command){
 353+ $escaped = "";
 354+ foreach (str_split($command) as $c ){
 355+ $escaped .= sprintf("\\0o%03o", ord($c));
 356+ }
 357+ return $escaped;
 358+ }
 359+
362360 /**
363 - Records the vote.
 361+ Run the vote executable.
 362+
364363 Called via ajax, so this must be static.
365364 */
366 - static function handleVote($user_name_raw, $page_id_raw = 0, $rev_id_raw = 0, $page_title = ""){
 365+ static function handleVote($user_name_raw, $page_id_raw = 0, $rev_id_raw = 0){
367366
368367 $response = new AjaxResponse("0");
369 -
 368+
370369 $dbr =& wfGetDB( DB_SLAVE );
371 -
 370+
372371 $userName = $dbr->strencode($user_name_raw, $dbr);
373372 $page_id = $dbr->strencode($page_id_raw, $dbr);
374373 $rev_id = $dbr->strencode($rev_id_raw, $dbr);
@@ -382,24 +381,35 @@
383382 $user_id = 0;
384383 }
385384 }
386 - $dbr->freeResult( $res );
387 -
388 - $ctx = stream_context_create(
389 - array('http' => array(
390 - 'timeout' =>
391 - self::TRUST_TIMEOUT
392 - )
393 - )
394 - );
395 -
396 - $vote_str = ("Voting at " . self::CONTENT_URL . "vote=1&rev=$rev_id&page=$page_id&user=$user_id&page_title=$page_title&time=" . wfTimestampNow());
397 - $colored_text = file_get_contents(self::CONTENT_URL . "vote=1&rev=$rev_id&page=$page_id&user=$user_id&page_title=$page_title&time=" .
398 - wfTimestampNow(), 0, $ctx);
399 - $response = new AjaxResponse($vote_str);
 385+ $dbr->freeResult( $res );
 386+
 387+ // Now see if this user has not already voted, and count the vote if its the first time though.
 388+ $res = $dbr->select('wikitrust_vote', array('revision_id'), array('revision_id' => $rev_id, 'voter_id' => $user_id), array());
 389+ if ($res){
 390+ $row = $dbr->fetchRow($res);
 391+ if(!$row['revision_id']){
 392+
 393+ $insert_vals = array("revision_id" => $rev_id,
 394+ "page_id" => $page_id ,
 395+ "voter_id" => $user_id,
 396+ "voted_on" => wfTimestampNow()
 397+ );
 398+ $dbw =& wfGetDB( DB_MASTER );
 399+ if ($dbw->insert( 'wikitrust_vote', $insert_vals)){
 400+ $dbw->commit();
 401+ $response = new AjaxResponse(implode ( ",", $insert_vals));
 402+ self::runEvalEdit(self::TRUST_EVAL_VOTE, $rev_id, $page_id, $user_id); // Launch the evaluation of the vote.
 403+ }
 404+ } else {
 405+ $response = new AjaxResponse("Already Voted");
 406+ }
 407+ $dbr->freeResult( $res );
 408+ }
400409 }
 410+
401411 return $response;
402412 }
403 -
 413+
404414 /**
405415 Called just before rendering HTML.
406416 We add the coloring scripts here.
@@ -412,259 +422,269 @@
413423 }
414424 return true;
415425 }
416 -
 426+
 427+ /**
 428+ Updated the cached median reputation value.
 429+ */
 430+ function update_median(){
 431+ $dbr =& wfGetDB( DB_SLAVE );
 432+ $res = $dbr->select('wikitrust_global', 'median', array(), array());
 433+ if ($res){
 434+ $row = $dbr->fetchRow($res);
 435+ $this->median = $row['median'];
 436+ }
 437+ $dbr->freeResult( $res );
 438+
 439+ // check for divide by 0 errors.
 440+ if ($this->median == 0)
 441+ $this->median = 1;
 442+
 443+ return $this->median;
 444+ }
 445+
 446+ /**
 447+ * Actually run the eval edit program.
 448+ * Returns -1 on error, the process id of the launched eval process otherwise.
 449+ */
 450+ private static function runEvalEdit($eval_type = self::TRUST_EVAL_EDIT, $rev_id = -1, $page_id = -1, $voter_id = -1){
 451+
 452+ global $wgDBname, $wgDBuser, $wgDBpassword, $wgDBserver, $wgDBtype, $wgTrustCmd, $wgTrustLog, $wgTrustDebugLog, $wgRepSpeed, $wgDBprefix;
 453+
 454+ $process = -1;
 455+ $command = "";
 456+ // Get the db.
 457+ $dbr =& wfGetDB( DB_SLAVE );
 458+
 459+ // Do we use a DB prefix?
 460+ $prefix = ($wgDBprefix)? "-db_prefix " . $dbr->strencode($wgDBprefix): "";
 461+
 462+ switch ($eval_type) {
 463+ case self::TRUST_EVAL_EDIT:
 464+ $command = escapeshellcmd("$wgTrustCmd -rep_speed $wgRepSpeed -log_file $wgTrustLog -db_host $wgDBserver -db_user $wgDBuser -db_pass $wgDBpassword -db_name $wgDBname $prefix") . " &";
 465+ break;
 466+ case self::TRUST_EVAL_VOTE:
 467+ if ($rev_id == -1 || $page_id == -1 || $voter_id == -1)
 468+ return -1;
 469+ $command = escapeshellcmd("$wgTrustCmd -eval_vote -rev_id " . $dbr->strencode($rev_id) . " -voter_id " . $dbr->strencode($voter_id) . " -page_id " . $dbr->strencode($page_id) . " -rep_speed $wgRepSpeed -log_file $wgTrustLog -db_host $wgDBserver -db_user $wgDBuser -db_pass $wgDBpassword -db_name $wgDBname $prefix") . " &";
 470+ break;
 471+ case self::TRUST_EVAL_MISSING:
 472+ $command = escapeshellcmd("$wgTrustCmd -rev_id " . $dbr->strencode($rev_id) . " -rep_speed $wgRepSpeed -log_file $wgTrustLog -db_host $wgDBserver -db_user $wgDBuser -db_pass $wgDBpassword -db_name $wgDBname $prefix") . " &";
 473+ break;
 474+ }
 475+
 476+ $descriptorspec = array(
 477+ 0 => array("pipe", "r"), // stdin is a pipe that the child will read from
 478+ 1 => array("file", escapeshellcmd($wgTrustDebugLog), "a"), // stdout is a pipe that the child will write to
 479+ 2 => array("file", escapeshellcmd($wgTrustDebugLog), "a") // stderr is a file to write to
 480+ );
 481+ $cwd = '/tmp';
 482+ $env = array();
 483+ $process = proc_open($command, $descriptorspec, $pipes, $cwd, $env);
 484+
 485+ return $process;
 486+ }
 487+
 488+/*
 489+ Code to fork and exec a new process to color any new revisions.
 490+ Called after any edits are made.
 491+*/
 492+ function ucscRunColoring(&$article, &$user, &$text, &$summary, $minor, $watch, $sectionanchor, &$flags, $revision) {
 493+ if (self::runEvalEdit(self::TRUST_EVAL_EDIT) >= 0)
 494+ return true;
 495+ return false;
 496+ }
 497+
417498 # Actually add the tab.
418 - function ucscTrustTemplate($skin, &$content_actions) {
419 -
420 - global $wgTrustTabText, $wgRequest;
421 - if (!isset($wgTrustTabText)){
422 - $wgTrustTabText = "trust";
423 - }
424 -
425 - if ($wgRequest->getVal('action')){
426 - // we don't want trust for actions.
427 - return true;
428 - }
429 -
430 - if ($wgRequest->getVal('diff')){
431 - // or for diffs
432 - return true;
433 - }
434 -
435 - $trust_qs = $_SERVER['QUERY_STRING'];
436 - if($trust_qs){
437 - $trust_qs = "?" . $trust_qs . "&trust=t";
438 - } else {
439 - $trust_qs .= "?trust=t";
440 - }
441 -
442 - $content_actions['trust'] = array ( 'class' => '',
443 - 'text' => $wgTrustTabText,
444 - 'href' =>
445 - $_SERVER['PHP_SELF'] . $trust_qs );
446 -
447 - if($wgRequest->getVal('trust')){
448 - $content_actions['trust']['class'] = 'selected';
449 - $content_actions['nstab-main']['class'] = '';
450 - $content_actions['nstab-main']['href'] .= '';
451 - } else {
452 - $content_actions['trust']['href'] .= '';
453 - }
454 - return true;
455 - }
 499+ function ucscTrustTemplate($skin, &$content_actions) {
456500
457 - /**
458 - If colored text exists, use it instead of the normal text,
459 - but only if the trust tab is selected.
460 - */
461 - function ucscSeeIfColored(&$parser, &$text, &$strip_state = Null) {
462 - global $wgRequest, $wgTrustExplanation, $wgUseAjax, $wgShowVoteButton, $wgDBprefix, $wgNoTrustExplanation, $wgVoteText, $wgThankYouForVoting, $wgNotPartExplanation;
463 -
464 - // Get the db.
465 - $dbr =& wfGetDB( DB_SLAVE );
466 -
467 - // Do we use a DB prefix?
468 - $prefix = ($wgDBprefix)? "-db_prefix " . $dbr->strencode($wgDBprefix): "";
469 -
470 - // Text for showing the "I like it" button
471 - $voteitText = "";
472 - if ($wgUseAjax && $wgShowVoteButton){
473 - $voteitText = "
 501+ global $wgTrustTabText, $wgRequest;
 502+ if (!isset($wgTrustTabText)){
 503+ $wgTrustTabText = "trust";
 504+ }
 505+
 506+ if ($wgRequest->getVal('action')){
 507+ // we don't want trust for actions.
 508+ return true;
 509+ }
 510+
 511+ $trust_qs = $_SERVER['QUERY_STRING'];
 512+ if($trust_qs){
 513+ $trust_qs = "?" . $trust_qs . "&trust=t";
 514+ } else {
 515+ $trust_qs .= "?trust=t";
 516+ }
 517+
 518+ $content_actions['trust'] = array ( 'class' => '',
 519+ 'text' => $wgTrustTabText,
 520+ 'href' =>
 521+ $_SERVER['PHP_SELF'] . $trust_qs );
 522+
 523+ if($wgRequest->getVal('trust')){
 524+ $content_actions['trust']['class'] = 'selected';
 525+ $content_actions['nstab-main']['class'] = '';
 526+ $content_actions['nstab-main']['href'] .= '';
 527+ } else {
 528+ $content_actions['trust']['href'] .= '';
 529+ }
 530+ return true;
 531+ }
 532+
 533+ /**
 534+ If colored text exists, use it instead of the normal text,
 535+ but only if the trust tab is selected.
 536+
 537+ TODO: Make this function work with caching turned on.
 538+ */
 539+ function ucscSeeIfColored(&$parser, &$text, &$strip_state) {
 540+ global $wgRequest, $wgTrustExplanation, $wgUseAjax, $wgShowVoteButton, $wgDBprefix, $wgNoTrustExplanation, $wgVoteText, $wgThankYouForVoting;
 541+
 542+ // Turn off caching for this instanching for this instance.
 543+ $parser->disableCache();
 544+
 545+ // Get the db.
 546+ $dbr =& wfGetDB( DB_SLAVE );
 547+
 548+ // Do we use a DB prefix?
 549+ $prefix = ($wgDBprefix)? "-db_prefix " . $dbr->strencode($wgDBprefix): "";
 550+
 551+ // Text for showing the "I like it" button
 552+ $voteitText = "";
 553+ if ($wgUseAjax && $wgShowVoteButton){
 554+ $voteitText = "
474555 ".self::TRUST_OPEN_TOKEN."div id='vote-button'".self::TRUST_CLOSE_TOKEN."".self::TRUST_OPEN_TOKEN."input type='button' name='vote' value='" . $wgVoteText . "' onclick='startVote()' /".self::TRUST_CLOSE_TOKEN."".self::TRUST_OPEN_TOKEN."/div".self::TRUST_CLOSE_TOKEN."
475556 ".self::TRUST_OPEN_TOKEN."div id='vote-button-done'".self::TRUST_CLOSE_TOKEN.$wgThankYouForVoting.self::TRUST_OPEN_TOKEN."/div".self::TRUST_CLOSE_TOKEN."
476557 ";
477 - }
 558+ }
478559
479 - // Return if trust is not selected.
480 - if (!$this->trust_engaged)
481 - return true;
 560+ // Return if trust is not selected.
 561+ if (!$this->trust_engaged)
 562+ return true;
482563
483 - // Save the title object, if it is not already present
484 - if (!$this->title){
485 - $this->title = $parser->getTitle();
486 - }
 564+ // Save the title object, if it is not already present
 565+ if (!$this->title){
 566+ $this->title = $parser->getTitle();
 567+ }
487568
488 - // count the number of times we load this text
489 - $this->times_rev_loaded++;
 569+ // count the number of times we load this text
 570+ $this->times_rev_loaded++;
490571
491 - // Load the current revision id.
492 - if (!$this->current_rev){
493 - if ($parser->mRevisionId){
494 - $this->current_rev = $parser->mRevisionId;
495 - } else {
496 - // Sometimes the revisionId field is not filled in.
497 - $this->current_rev = $this->title->getPreviousRevisionID( PHP_INT_MAX );
498 - }
499 - }
500 -
501 - /**
502 - This method is being called multiple times for each page.
503 - We only pull the colored text for the first time through.
504 - */
505 - if ($this->colored){
506 - return true;
507 - }
508 -
509 - if ($wgRequest->getVal('diff')){
510 - // For diffs, look for the absence of the diff token instead of counting
511 - if(substr($text,0,3) == self::DIFF_TOKEN_TO_COLOR){
512 - return true;
513 - }
514 - }
515 -
516 - // if we made it here, we are going to color some text
517 - $this->colored = true;
518 -
519 - // Check to see if this page is part of the coloring project.
520 - // Disabled for now.
521 - //if (!strstr($text, self::TRUST_COLOR_TOKEN)){
522 - // $text = $wgNotPartExplanation . "\n" . $text;
523 - // return true;
524 - //}
525 -
526 - // Get the page id and other data
527 - $colored_text="";
528 - $page_id=0;
529 - $rev_timestamp="";
530 - $rev_user=0;
531 - $res = $dbr->select('revision', array('rev_page', 'rev_timestamp', 'rev_user'), array('rev_id' => $this->current_rev), array());
532 - if ($res){
533 - $row = $dbr->fetchRow($res);
534 - $page_id = $row['rev_page'];
535 - $rev_user = $row['rev_user'];
536 - $rev_timestamp = $row['rev_timestamp'];
537 - if (!$page_id) {
538 - $page_id = 0;
539 - }
540 - }
541 - $dbr->freeResult( $res );
542 -
543 - $page_title = $_GET['title'];
544 - $ctx = stream_context_create(
545 - array('http' => array(
546 - 'timeout' =>
547 - self::TRUST_TIMEOUT
548 - )
549 - )
550 - );
551 - try {
552 - // Should we do doing this via HTTPS?
553 - $colored_raw = (file_get_contents(self::CONTENT_URL . "rev=" . $this->current_rev . "&page=$page_id&page_title=$page_title&time=$rev_timestamp&user=$rev_user", 0, $ctx));
554 - } catch (Exception $e) {
555 - $colored_raw = "";
556 - }
557 -
558 - if ($colored_raw && $colored_raw != self::NOT_FOUND_TEXT_TOKEN){
559 - // Work around because of issues with php's built in
560 - // gzip function.
561 - $f = tempnam('/tmp', 'gz_fix');
562 - file_put_contents($f, $colored_raw);
563 - $colored_raw = file_get_contents('compress.zlib://' . $f);
564 - unlink($f);
565 -
566 - // Pick off the median value first.
567 - $colored_data = explode(",", $colored_raw, 2);
568 - $colored_text = $colored_data[1];
569 - if (preg_match("/^[+-]?(([0-9]+)|([0-9]*\.[0-9]+|[0-9]+\.[0-9]*)|
570 - (([0-9]+|([0-9]*\.[0-9]+|[0-9]+\.[0-9]*))[eE][+-]?[0-9]+))$/", $colored_data[0])){
571 - $this->median = $colored_data[0];
572 - }
573 -
574 - // First, make sure that there are not any instances of our tokens in the colored_text
575 - $colored_text = str_replace(self::TRUST_OPEN_TOKEN, "", $colored_text);
576 - $colored_text = str_replace(self::TRUST_CLOSE_TOKEN, "", $colored_text);
577 -
578 - $colored_text = preg_replace("/&apos;/", "'", $colored_text, -1);
579 -
580 - $colored_text = preg_replace("/&amp;/", "&", $colored_text, -1);
581 -
582 - $colored_text = preg_replace("/&lt;/", self::TRUST_OPEN_TOKEN, $colored_text, -1);
583 - $colored_text = preg_replace("/&gt;/", self::TRUST_CLOSE_TOKEN, $colored_text, -1);
584 -
585 - // Now update the text.
586 - $text = $voteitText . $colored_text . "\n" . $wgTrustExplanation;
587 - } else {
588 - // Return a message about the missing text.
589 - $text = $wgNoTrustExplanation . "\n" . $text;
590 - }
591 -
 572+ // Load the current revision id.
 573+ if (!$this->current_rev){
 574+ if ($parser->mRevisionId){
 575+ $this->current_rev = $parser->mRevisionId;
 576+ } else {
 577+ // Sometimes the revisionId field is not filled in.
 578+ $this->current_rev = $this->title->getPreviousRevisionID( PHP_INT_MAX );
 579+ }
 580+ }
 581+
 582+ /**
 583+ This method is being called multiple times for each page.
 584+ We only pull the colored text for the first time through.
 585+ */
 586+ if ($this->colored){
592587 return true;
593588 }
594 -
595 - /* Register the tags we are intersted in expanding. */
596 - function ucscColorTrust_Magic( &$magicWords, $langCode ) {
597 - $magicWords[ 't' ] = array( 0, 't' );
 589+
 590+ if (strstr($text, "{{ns:project}}")) {
598591 return true;
599592 }
600 -
601 - /* Pull in any colored text. Also handle closing tags. */
602 - function ucscOrigin_Finalize(&$parser, &$text) {
603 - global $wgScriptPath, $IP, $wgOut;
604 -
605 - if(!$this->colored){
606 - // This is to handle caching problems.
607 - if (!strstr($text, "This page has been accessed")){
608 - $colored_text = $text;
609 - $this->ucscSeeIfColored($parser, $colored_text);
610 - $text = $wgOut->parse( $colored_text );
611 - } else {
612 - $colored_text = $text;
613 - $this->ucscSeeIfColored($parser, $colored_text);
614 - $wgOut->mBodytext = $wgOut->parse( $colored_text );
615 - }
616 - }
617 -
618 - $count = 0;
619 - $text = '<script type="text/javascript" src="'.$wgScriptPath.'/extensions/Trust/js/wz_tooltip.js"></script>' . $text;
620 - $text = preg_replace('/' . self::TRUST_OPEN_TOKEN . '/', "<", $text, -1, $count);
621 - $text = preg_replace('/' . self::TRUST_CLOSE_TOKEN .'/', ">", $text, -1, $count);
622 - $text = preg_replace('/<\/p>/', "</span></p>", $text, -1, $count);
623 - $text = preg_replace('/<p><\/span>/', "<p>", $text, -1, $count);
624 - $text = preg_replace('/<li><\/span>/', "<li>", $text, -1, $count);
625 -
626 - return true;
627 - }
628 -
629 - /* Text Trust */
630 - function ucscColorTrust_Render( &$parser, $combinedValue = "0,0,0" ) {
631 -
632 - // Split the value into trust and origin information.
633 - // 0 = trust
634 - // 1 = origin
635 - // 2 = contributing author
636 - $splitVals = explode(self::TRUST_SPLIT_TOKEN, $combinedValue);
637 -
638 - $class = $this->computeColorFromFloat($splitVals[0]);
639 - $output = self::TRUST_OPEN_TOKEN . "span class=\"$class\""
640 - . "onmouseover=\"Tip('".$splitVals[2]."')\" onmouseout=\"UnTip()\""
641 - . "onclick=\"showOrigin("
642 - . $splitVals[1] . ")\"" . self::TRUST_CLOSE_TOKEN;
643 -
644 - $this->current_trust = $class;
645 - if ($this->first_span){
646 - $this->first_span = false;
647 - } else {
648 - $output = self::TRUST_OPEN_TOKEN . "/span" . self::TRUST_CLOSE_TOKEN . $output;
 593+
 594+ if ($wgRequest->getVal('diff')){
 595+ // For diffs, look for the absence of the diff token instead of counting
 596+ if(substr($text,0,3) == self::DIFF_TOKEN_TO_COLOR){
 597+ return true;
649598 }
650 -
651 - return array ( $output, "noparse" => false, "isHTML" => false );
652599 }
 600+
 601+ // if we made it here, we are going to color some text
 602+ $this->colored = true;
 603+
 604+ $res = $dbr->select('wikitrust_colored_markup', 'revision_text',
 605+ array( 'revision_id' => $this->current_rev ), array());
 606+ if ($res){
 607+ $row = $dbr->fetchRow($res);
 608+ $colored_text = $row[0];
 609+ if ($colored_text){
 610+ // First, make sure that there are not any instances of our tokens in the colored_text
 611+ $colored_text = str_replace(self::TRUST_OPEN_TOKEN, "", $colored_text);
 612+ $colored_text = str_replace(self::TRUST_CLOSE_TOKEN, "", $colored_text);
 613+
 614+ // Now update the text.
 615+ $text = $voteitText . $colored_text . "\n" . $wgTrustExplanation;
 616+ } else {
 617+ // If the colored text is missing, generate it in the background.
 618+ // For now, return a message about the missing text.
 619+ self::runEvalEdit(self::TRUST_EVAL_MISSING);
 620+ $text = $wgNoTrustExplanation . "\n" . $text;
 621+ }
 622+ } else {
 623+ return false;
 624+ }
 625+ $dbr->freeResult( $res );
 626+ return true;
 627+ }
653628
654 - /**
655 - Maps from the online trust values to the css trust values.
656 - Normalize the value for growing wikis.
657 - */
658 - function computeColorFromFloat($trust){
659 - $normalized_value = min(self::MAX_TRUST_VALUE, max(self::MIN_TRUST_VALUE,
660 - (($trust + .5) * self::TRUST_MULTIPLIER)
661 - / $this->median));
662 - return $this->computeColor3($normalized_value);
663 - }
 629+ /* Register the tags we are intersted in expanding. */
 630+ function ucscColorTrust_Magic( &$magicWords, $langCode ) {
 631+ $magicWords[ 't' ] = array( 0, 't' );
 632+ return true;
 633+ }
 634+
 635+ /* Turn the finished trust info into a span tag. Also handle closing tags. */
 636+ function ucscOrigin_Finalize(&$parser, &$text) {
 637+ global $wgScriptPath;
 638+ $count = 0;
 639+ $text = '<script type="text/javascript" src="'.$wgScriptPath.'/extensions/Trust/js/wz_tooltip.js"></script>' . $text;
 640+ $text = preg_replace('/' . self::TRUST_OPEN_TOKEN . '/', "<", $text, -1, $count);
 641+ $text = preg_replace('/' . self::TRUST_CLOSE_TOKEN .'/', ">", $text, -1, $count);
 642+ $text = preg_replace('/<\/p>/', "</span></p>", $text, -1, $count);
 643+ $text = preg_replace('/<p><\/span>/', "<p>", $text, -1, $count);
 644+ $text = preg_replace('/<li><\/span>/', "<li>", $text, -1, $count);
664645
665 - /* Maps a trust value to a HTML color representing the trust value. */
666 - function computeColor3($fTrustValue){
667 - return $this->COLORS[$fTrustValue];
668 - }
 646+ return true;
 647+ }
 648+
 649+ /* Text Trust */
 650+ function ucscColorTrust_Render( &$parser, $combinedValue = "0,0,0" ) {
 651+
 652+ // Split the value into trust and origin information.
 653+ // 0 = trust
 654+ // 1 = origin
 655+ // 2 = contributing author
 656+ $splitVals = explode(self::TRUST_SPLIT_TOKEN, $combinedValue);
 657+
 658+ $class = $this->computeColorFromFloat($splitVals[0]);
 659+ $output = self::TRUST_OPEN_TOKEN . "span class=\"$class\""
 660+ . "onmouseover=\"Tip('".$splitVals[2]."')\" onmouseout=\"UnTip()\""
 661+ . "onclick=\"showOrigin("
 662+ . $splitVals[1] . ")\"" . self::TRUST_CLOSE_TOKEN;
 663+
 664+ $this->current_trust = $class;
 665+ if ($this->first_span){
 666+ $this->first_span = false;
 667+ } else {
 668+ $output = self::TRUST_OPEN_TOKEN . "/span" . self::TRUST_CLOSE_TOKEN . $output;
 669+ }
 670+
 671+ return array ( $output, "noparse" => false, "isHTML" => false );
 672+ }
 673+
 674+ /**
 675+ Maps from the online trust values to the css trust values.
 676+ Normalize the value for growing wikis.
 677+ */
 678+ function computeColorFromFloat($trust){
 679+ $normalized_value = min(self::MAX_TRUST_VALUE, max(self::MIN_TRUST_VALUE,
 680+ (($trust + .5) * self::TRUST_MULTIPLIER)
 681+ / $this->median));
 682+ return $this->computeColor3($normalized_value);
 683+ }
 684+
 685+ /* Maps a trust value to a HTML color representing the trust value. */
 686+ function computeColor3($fTrustValue){
 687+ return $this->COLORS[$fTrustValue];
 688+ }
669689 }
670690
671691 TextTrust::singleton();

Status & tagging log