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("/'/", "'", $colored_text, -1); |
| 582 | + |
| 583 | + $colored_text = preg_replace("/&/", "&", $colored_text, -1); |
| 584 | + |
| 585 | + $colored_text = preg_replace("/</", self::TRUST_OPEN_TOKEN, $colored_text, -1); |
| 586 | + $colored_text = preg_replace("/>/", 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 |
1 | 677 | + 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 @@ |
26 | 26 | # Uses Tool Tip JS library under the LGPL. |
27 | 27 | # http://www.walterzorn.com/tooltip/tooltip_e.htm |
28 | 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 { |
| 29 | +class TextTrust extends TrustBase |
| 30 | +{ |
38 | 31 | |
39 | 32 | ## Types of analysis to perform. |
40 | 33 | const TRUST_EVAL_VOTE = 0; |
— | — | @@ -61,14 +54,6 @@ |
62 | 55 | ## Token to be replaed with > |
63 | 56 | const TRUST_CLOSE_TOKEN = ":ampc:"; |
64 | 57 | |
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 | | - |
73 | 58 | ## default values for variables found from LocalSettings.php |
74 | 59 | var $DEFAULTS = array( |
75 | 60 | 'wgShowVoteButton' => false, |
— | — | @@ -81,14 +66,13 @@ |
82 | 67 | 'wgTrustLog' => "/dev/null", |
83 | 68 | 'wgTrustDebugLog' => "/dev/null", |
84 | 69 | 'wgRepSpeed' => 1.0, |
85 | | - 'wgNotPartExplanation' => "This page is not part of the trust coloring experement", |
86 | 70 | 'wgTrustTabText' => "Show Trust", |
87 | 71 | 'wgTrustExplanation' => |
88 | 72 | "<p><center><b>This is a product of the text trust algoruthm.</b></center></p>", |
89 | 73 | ); |
90 | 74 | |
91 | 75 | ## Median Value of Trust |
92 | | - var $median = 1.0; |
| 76 | + var $median = 0.0; |
93 | 77 | |
94 | 78 | ## Number of times a revision is looked at. |
95 | 79 | var $times_rev_loaded = 0; |
— | — | @@ -143,7 +127,7 @@ |
144 | 128 | if ((http_request.readyState == 4) && (http_request.status == 200)) { |
145 | 129 | document.getElementById("vote-button-done").style.visibility = "visible"; |
146 | 130 | document.getElementById("vote-button").style.visibility = "hidden"; |
147 | | - // alert(http_request.responseText); |
| 131 | + //alert(http_request.responseText); |
148 | 132 | return true; |
149 | 133 | } else { |
150 | 134 | alert(http_request.responseText); |
— | — | @@ -173,7 +157,7 @@ |
174 | 158 | } |
175 | 159 | } |
176 | 160 | |
177 | | - return sajax_do_call( "TextTrust::handleVote", [wgUserName, wgArticleId, revID, wgPageName] , voteCallback ); |
| 161 | + return sajax_do_call( "TextTrust::handleVote", [wgUserName, wgArticleId, revID] , voteCallback ); |
178 | 162 | } |
179 | 163 | |
180 | 164 | /*]]>*/</script>'; |
— | — | @@ -242,95 +226,97 @@ |
243 | 227 | public static function &singleton( ) |
244 | 228 | { return parent::singleton( ); } |
245 | 229 | |
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 | + |
278 | 261 | # Define a setup function |
279 | | - $wgExtensionFunctions[] = 'ucscColorTrust_Setup'; |
280 | | - |
| 262 | + $wgExtensionFunctions[] = 'ucscColorTrust_Setup'; |
| 263 | + |
281 | 264 | # 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 |
288 | 271 | colors text according to trust.' |
289 | | - ); |
| 272 | + ); |
290 | 273 | } |
291 | 274 | |
292 | | - // Sets the extension hooks. |
293 | | - public function setup() { |
| 275 | + public function setup() |
| 276 | + { |
294 | 277 | parent::setup(); |
295 | | - global $wgHooks, $wgParser, $wgRequest, $wgUseAjax, $wgShowVoteButton, $wgAjaxExportList, $wgUser; |
296 | | - |
| 278 | + global $wgHooks, $wgParser, $wgRequest, $wgUseAjax, $wgShowVoteButton, $wgAjaxExportList; |
| 279 | + |
297 | 280 | # Code which takes the "I vote" action. |
298 | 281 | # This has to be statically called. |
299 | 282 | if($wgUseAjax && $wgShowVoteButton){ |
300 | 283 | $wgAjaxExportList[] = "TextTrust::handleVote"; |
301 | 284 | } |
302 | 285 | |
303 | | - // Is the user opting to use wikitrust? |
304 | | - $tname = "gadget-WikiTrust"; |
305 | | - if (!$wgUser->getOption( $tname ) ) { |
306 | | - return; |
307 | | - } |
308 | | - |
309 | 286 | # Updater fiered when updating to a new version of MW. |
310 | | - $wgHooks['LoadExtensionSchemaUpdates'][] = array(&$this, 'updateDB'); |
311 | | - |
| 287 | + $wgHooks['LoadExtensionSchemaUpdates'][] = array( &$this, 'updateDB'); |
| 288 | + |
312 | 289 | # 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 | + |
315 | 298 | # If the trust tab is not selected, or some other tabs are don't worry about things any more. |
316 | 299 | if(!$wgRequest->getVal('trust') || $wgRequest->getVal('action')){ |
317 | 300 | $this->trust_engaged = false; |
318 | 301 | return; |
319 | 302 | } |
320 | 303 | $this->trust_engaged = true; |
321 | | - |
| 304 | + |
322 | 305 | # Add trust CSS and JS |
323 | 306 | $wgHooks['OutputPageBeforeHTML'][] = array( &$this, 'ucscColorTrust_OP'); |
324 | | - |
| 307 | + |
325 | 308 | # Add a hook to initialise the magic words |
326 | 309 | $wgHooks['LanguageGetMagic'][] = array( &$this, 'ucscColorTrust_Magic'); |
327 | | - |
| 310 | + |
328 | 311 | # Set a function hook associating the blame and trust words with a callback function |
329 | 312 | $wgParser->setFunctionHook( 't', array( &$this, 'ucscColorTrust_Render')); |
330 | | - |
| 313 | + |
331 | 314 | # After everything, make the blame info work |
332 | 315 | $wgHooks['ParserAfterTidy'][] = array( &$this, 'ucscOrigin_Finalize'); |
| 316 | + |
| 317 | +# Pull the median value |
| 318 | + $this->update_median(); |
333 | 319 | } |
334 | | - |
| 320 | + |
335 | 321 | /** |
336 | 322 | * Update the DB when MW is updated. |
337 | 323 | * This assums that the db has permissions to create tables. |
— | — | @@ -340,7 +326,7 @@ |
341 | 327 | // Create the needed tables, if neccesary. |
342 | 328 | // Pull in the create scripts. |
343 | 329 | require_once("TrustUpdateScripts.inc"); |
344 | | - |
| 330 | + |
345 | 331 | $db =& wfGetDB( DB_MASTER ); |
346 | 332 | |
347 | 333 | // First check to see what tables have already been created. |
— | — | @@ -348,7 +334,7 @@ |
349 | 335 | while ($row = $db->fetchRow($res)){ |
350 | 336 | $db_tables[$row[0]] = True; |
351 | 337 | } |
352 | | - |
| 338 | + |
353 | 339 | foreach ($create_scripts as $table => $scripts) { |
354 | 340 | if (!$db_tables[$table]){ |
355 | 341 | foreach ($scripts as $script){ |
— | — | @@ -358,16 +344,29 @@ |
359 | 345 | } |
360 | 346 | } |
361 | 347 | |
| 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 | + |
362 | 360 | /** |
363 | | - Records the vote. |
| 361 | + Run the vote executable. |
| 362 | + |
364 | 363 | Called via ajax, so this must be static. |
365 | 364 | */ |
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){ |
367 | 366 | |
368 | 367 | $response = new AjaxResponse("0"); |
369 | | - |
| 368 | + |
370 | 369 | $dbr =& wfGetDB( DB_SLAVE ); |
371 | | - |
| 370 | + |
372 | 371 | $userName = $dbr->strencode($user_name_raw, $dbr); |
373 | 372 | $page_id = $dbr->strencode($page_id_raw, $dbr); |
374 | 373 | $rev_id = $dbr->strencode($rev_id_raw, $dbr); |
— | — | @@ -382,24 +381,35 @@ |
383 | 382 | $user_id = 0; |
384 | 383 | } |
385 | 384 | } |
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 | + } |
400 | 409 | } |
| 410 | + |
401 | 411 | return $response; |
402 | 412 | } |
403 | | - |
| 413 | + |
404 | 414 | /** |
405 | 415 | Called just before rendering HTML. |
406 | 416 | We add the coloring scripts here. |
— | — | @@ -412,259 +422,269 @@ |
413 | 423 | } |
414 | 424 | return true; |
415 | 425 | } |
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 | + |
417 | 498 | # 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) { |
456 | 500 | |
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 = " |
474 | 555 | ".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." |
475 | 556 | ".self::TRUST_OPEN_TOKEN."div id='vote-button-done'".self::TRUST_CLOSE_TOKEN.$wgThankYouForVoting.self::TRUST_OPEN_TOKEN."/div".self::TRUST_CLOSE_TOKEN." |
476 | 557 | "; |
477 | | - } |
| 558 | + } |
478 | 559 | |
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; |
482 | 563 | |
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 | + } |
487 | 568 | |
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++; |
490 | 571 | |
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("/'/", "'", $colored_text, -1); |
579 | | - |
580 | | - $colored_text = preg_replace("/&/", "&", $colored_text, -1); |
581 | | - |
582 | | - $colored_text = preg_replace("/</", self::TRUST_OPEN_TOKEN, $colored_text, -1); |
583 | | - $colored_text = preg_replace("/>/", 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){ |
592 | 587 | return true; |
593 | 588 | } |
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}}")) { |
598 | 591 | return true; |
599 | 592 | } |
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; |
649 | 598 | } |
650 | | - |
651 | | - return array ( $output, "noparse" => false, "isHTML" => false ); |
652 | 599 | } |
| 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 | + } |
653 | 628 | |
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); |
664 | 645 | |
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 | + } |
669 | 689 | } |
670 | 690 | |
671 | 691 | TextTrust::singleton(); |