Ejemplo n.º 1
0
 function execute($par)
 {
     global $wgRequest, $wgContLang, $wgOut, $wgSpamBlacklistArticle, $wgUser, $wgScript;
     $title = Title::newFromDBKey($wgRequest->getVal('target'));
     $diff = $wgRequest->getVal('diff2');
     $rcid = $wgRequest->getVal('rcid');
     $rdfrom = $wgRequest->getVal('rdfrom');
     $wgOut->setHTMLTitle(wfMsg('pagetitle', 'Spam Tool'));
     // can the user even edit this?
     $sb = Title::newFromDBKey($wgSpamBlacklistArticle);
     if (!$sb->userCanEdit()) {
         $wgOut->addHTML(wfMsg('spamdifftool_cantedit'));
         return;
     }
     // do the processing
     if ($wgRequest->wasPosted()) {
         if ($wgRequest->getVal('confirm', null) != null) {
             $t = Title::newFromDBKey($wgSpamBlacklistArticle);
             $a = new Article($t);
             $text = $a->getContent();
             // insert the before the <pre> at the bottom  if there is one
             $i = strrpos($text, "</pre>");
             if ($i !== false) {
                 $text = substr($text, 0, $i) . $wgRequest->getVal('newurls') . "\n" . substr($text, $i);
             } else {
                 $text .= "\n" . $wgRequest->getVal('newurls');
             }
             $watch = false;
             if ($wgUser->getID() > 0) {
                 $watch = $wgUser->isWatched($t);
             }
             $a->updateArticle($text, wfMsg('spamdifftool_summary'), false, $watch);
             $returnto = $wgRequest->getVal('returnto', null);
             if ($returnto != null && $returnto != '') {
                 $wgOut->redirect($wgScript . "?" . urldecode($returnto));
             }
             // clear the redirect set by updateArticle
             return;
         }
         $vals = $wgRequest->getValues();
         $text = '';
         $urls = array();
         $source = wfMsgForContent('top_level_domains');
         $tlds = split("\n", $source);
         foreach ($vals as $key => $value) {
             if (strpos($key, "http://") === 0) {
                 $url = str_replace("%2E", ".", $key);
                 if ($value == 'none') {
                     continue;
                 }
                 switch ($value) {
                     case 'domain':
                         $t = "";
                         foreach ($tlds as $tld) {
                             if (preg_match("/" . $tld . "/i", $url)) {
                                 $t = $tld;
                                 $url = preg_replace("/" . $tld . "/i", "", $url, 1);
                                 break;
                             }
                         }
                         $url = preg_replace("@^http://([^/]*\\.)?([^./]+\\.[^./]+).*\$@", "\$2", $url);
                         $url = str_replace(".", "\\.", $url);
                         // escape the periods
                         $url .= $t;
                         break;
                     case 'subdomain':
                         $url = str_replace("http://", "", $url);
                         $url = str_replace(".", "\\.", $url);
                         // escape the periods
                         $url = preg_replace("/^([^\\/]*)\\/.*/", "\$1", $url);
                         // trim everything after the slash
                         break;
                     case 'dir':
                         $url = str_replace("http://", "", $url);
                         $url = preg_replace("@^([^/]*\\.)?([^./]+\\.[^./]+(/[^/?]*)?).*\$@", "\$1\$2", $url);
                         // trim everything after the slash
                         $url = preg_replace("/^(.*)\\/\$/", "\$1", $url);
                         // trim trailing / if one exists
                         $url = str_replace(".", "\\.", $url);
                         // escape the periods
                         $url = str_replace("/", "\\/", $url);
                         // escape the slashes
                         break;
                 }
                 if (!isset($urls[$url])) {
                     $text .= "{$url}\n";
                     $urls[$url] = true;
                 }
             }
         }
         if (trim($text) == '') {
             $wgOut->addHTML(wfMsg('spamdifftool_notext', $wgScript . "?" . urldecode($wgRequest->getVal('returnto'))));
             return;
         }
         $wgOut->addHTML("<form method=POST>\n\t\t\t\t\t<input type='hidden' name='confirm' value='true'>\n\t\t\t\t\t<input type='hidden' name='newurls' value=\"" . htmlspecialchars($text) . "\">\n\t\t\t\t\t<input type='hidden' name='returnto' value=\"" . htmlspecialchars($wgRequest->getVal('returnto')) . "\">\n\t\t\t\t");
         $wgOut->addHTML(wfMsg('spamdifftool_confirm') . "<pre style='padding: 10px'>{$text}</pre>");
         $wgOut->addHTML("</table><input type=submit value=\"" . htmlspecialchars(wfMsg('submit')) . "\"></form>");
         return;
     }
     if (!is_null($diff)) {
         require_once 'DifferenceEngine.php';
         // Get the last edit not by this guy
         $current = Revision::newFromTitle($title);
         $dbw = wfGetDB(DB_MASTER);
         $user = intval($current->getUser());
         $user_text = $dbw->addQuotes($current->getUserText());
         $s = $dbw->selectRow('revision', array('rev_id', 'rev_timestamp'), array('rev_page' => $current->getPage(), "rev_user <> {$user} OR rev_user_text <> {$user_text}"), $fname, array('USE INDEX' => 'page_timestamp', 'ORDER BY' => 'rev_timestamp DESC'));
         if ($s) {
             // set oldid
             $oldid = $s->rev_id;
         }
         if ($wgRequest->getVal('oldid2') < $oldid) {
             $oldid = $wgRequest->getVal('oldid2');
         }
         $de = new DifferenceEngine($title, $oldid, $diff, $rcid);
         $de->loadText();
         $otext = $de->mOldtext;
         $ntext = $de->mNewtext;
         $ota = explode("\n", $wgContLang->segmentForDiff($otext));
         $nta = explode("\n", $wgContLang->segmentForDiff($ntext));
         $diffs = new Diff($ota, $nta);
         foreach ($diffs->edits as $edit) {
             if ($edit->type != 'copy' && $edit->closing != "") {
                 $text .= implode("\n", $edit->closing) . "\n";
             }
         }
     } else {
         if ($title != "") {
             $a = new Article($title);
             $text = $a->getContent(true);
         }
     }
     $matches = array();
     $preg = "/http:\\/\\/[^] \n'\"\\>\\<]*/im";
     preg_match_all($preg, $text, $matches);
     if (sizeof($matches[0]) == 0) {
         $wgOut->addHTML(wfMsg('spamdifftool_no_urls_detected', $wgScript . "?" . urldecode($wgRequest->getVal('returnto'))));
         return;
     }
     $wgOut->addHTML("\n\t\t\t<form method='POST'>\n\t\t\t\t\t<input type='hidden' name='returnto' value=\"" . htmlspecialchars($wgRequest->getVal('returnto')) . "\">\n\t\t\t\t<style type='text/css'>\n\t\t\t\t\t\ttd.spam-url-row {\n\t\t\t\t\t\t\tborder: 1px solid #ccc;\n\t\t\t\t\t\t}\n\t\t\t\t</style> " . wfMsg('spamdifftool_urls_detected') . "\n\t\t\t<br/><br/><table cellpadding='5px' width='100%'>");
     $urls = array();
     foreach ($matches as $match) {
         foreach ($match as $url) {
             if (isset($urls[$url])) {
                 continue;
             }
             // avoid dupes
             $urls[$url] = true;
             $name = htmlspecialchars(str_replace(".", "%2E", $url));
             $wgOut->addHTML("<tr>\n\t\t\t\t\t<td class='spam-url-row'><b>{$url}</b><br/>\n\t\t\t\t\t" . wfMsg('spamdifftool_block') . " &nbsp;&nbsp;\n\t\t\t\t\t<INPUT type='radio' name=\"" . $name . "\"\tvalue='domain' checked> " . wfMsg('spamdifftool_option_domain') . "\n\t\t\t\t\t<INPUT type='radio' name=\"" . $name . "\"\tvalue='subdomain'> " . wfMsg('spamdifftool_option_subdomain') . "\n\t\t\t\t\t<INPUT type='radio' name=\"" . $name . "\"\tvalue='dir'>" . wfMsg('spamdifftool_option_directory') . "\n\t\t\t\t\t<INPUT type='radio' name=\"" . $name . "\"\tvalue='none'>" . wfMsg('spamdifftool_option_none') . "\n\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t\t");
         }
     }
     $wgOut->addHTML("</table><input type=submit value=\"" . htmlspecialchars(wfMsg('submit')) . "\"></form>");
     // DifferenceEngine directly fetched the revision:
     $RevIdFetched = $de->mNewid;
 }
	/**
	 * Generates a diff txt
	 * @param Title $title
	 * @return string
	 */
	function generateDiffBodyTxt( $title ) {
		$revision = Revision::newFromTitle( $title, 0 );
		$diff = new DifferenceEngine( $title, $revision->getId(), 'prev' );
		// The getDiffBody() method generates html, so let's generate the txt diff manualy:
		global $wgContLang;
		$diff->loadText();
		$otext = str_replace( "\r\n", "\n", $diff->mOldtext );
		$ntext = str_replace( "\r\n", "\n", $diff->mNewtext );
		$ota = explode( "\n", $wgContLang->segmentForDiff( $otext ) );
		$nta = explode( "\n", $wgContLang->segmentForDiff( $ntext ) );
		// We use here the php diff engine included in MediaWiki
		$diffs = new Diff( $ota, $nta );
		// And we ask for a txt formatted diff
		$formatter = new UnifiedDiffFormatter();
		$diff_text = $wgContLang->unsegmentForDiff( $formatter->format( $diffs ) );
		return $diff_text;
	}
	function execute( $par ) {
		global $wgRequest, $wgContLang, $wgOut, $wgUser,
			$wgScript, $wgSpamBlacklistArticle;

		

		$this->setHeaders();

		// can the user even edit this?
		$sb = Title::newFromText( $wgSpamBlacklistArticle );
		if ( !$sb->userCan( 'edit' ) ) {
			$wgOut->addWikiMsg( 'spamdifftool_cantedit' );
			return;
		}

		$this->outputHeader();

		$title = Title::newFromText( $wgRequest->getVal( 'target' ) );
		$diff = $wgRequest->getVal( 'diff2' );
		$rcid = $wgRequest->getVal( 'rcid' );
		$rdfrom = $wgRequest->getVal( 'rdfrom' );

		// do the processing
		if ( $wgRequest->wasPosted() ) {
			if ( $wgRequest->getCheck( 'confirm' ) ) {
				$a = new Article( $sb );
				$text = '';
				$insert = true;
				// make sure this page exists
				if ( $sb->getArticleID() > 0 ) {
					$text = $a->getContent();
					$insert = false;
				}

				// insert the before the <pre> at the bottom  if there is one
				$i = strrpos( $text, '</pre>' );
				if ( $i !== false ) {
					$text = substr( $text, 0, $i )
							. $wgRequest->getVal( 'newurls' )
							. "\n" . substr( $text, $i );
				} else {  
					$text .= "\n" . $wgRequest->getVal( 'newurls' );
				}
				$a->doEdit( $text, wfMsgForContent( 'spamdifftool_summary' ), EDIT_DEFER_UPDATES | EDIT_AUTOSUMMARY );
				$returnto = $wgRequest->getVal( 'returnto' );
				if ( $returnto != null && $returnto != '' )
					$wgOut->redirect( $wgScript . "?" . urldecode( $returnto ) );
				return;
			}
			$vals = $wgRequest->getValues();
			$text = ''; 
			foreach ( $vals as $key => $value ) {
				if ( strpos( $key, 'http://' ) === 0 ) {
					$url = str_replace( '%2E', '.', $key );
					if ( $value == 'none' ) continue;
					switch ( $value ) {
						case 'domain':
							$url = str_replace( 'http://', '', $url );
							$url = preg_replace( '/(.*[^\/])*\/.*/', '$1', $url ); // trim everything after the slash
							$k = explode( '\.', $url );
							$url = $k[sizeof($k) - 2] . '.' . $k[sizeof($k) - 1];
							$url = str_replace( '.', '\.', $url ); // escape the periods
							break;
						case 'subdomain':
							$url = str_replace( 'http://', '', $url );
							$url = str_replace( '.', '\.', $url ); // escape the periods
							$url = preg_replace( '/^([^\/]*)\/.*/', '$1', $url ); // trim everything after the slash
							break;
						case 'dir':
							$url = str_replace( 'http://', '', $url );
							$url = str_replace( '.', '\.', $url ); // escape the periods
							$url = str_replace( '/', '\/', $url ); // escape the slashes
							break;
					}
					$text .= "$url\n";
				}
			}
			if ( trim( $text ) == '' ) {
				$wgOut->addHTML( wfMsg( 'spamdifftool_notext', $wgScript . "?" . urldecode( $wgRequest->getVal( 'returnto' ) ) ) );
				return;
			}
			$wgOut->addHTML(
				Xml::openElement( 'form', array( 'method' => 'post' ) ) . "\n" .
				Html::Hidden( 'confirm', 'true' ) .
				Html::Hidden( 'newurls', $text ) .
				Html::Hidden( 'returnto', $wgRequest->getVal( 'returnto' ) ) . "\n" .
				wfMsg( 'spamdifftool_confirm',
					'http://www.mediawiki.org/w/index.php?title=Extension_talk:SpamDiffTool&action=edit&section=new' ) .
				"\n<pre>$text</pre>\n" .
				Xml::closeElement( 'table' ) . "\n" .
				Xml::submitButton( wfMsg( 'spamdifftool_submit_buttom' ) ) . "\n" .
				Xml::closeElement( 'form' )
			);
			return;
		}

		if ( !$title ) {
			$wgOut->addWikiMsg( 'spamdifftool-no-title' );
			return;
		}

		if ( !is_null( $diff ) ) {
			# Get the last edit not by this guy
			$current = Revision::newFromTitle( $title );
			$dbw = wfGetDB( DB_MASTER );
			$user = intval( $current->getUser() );
			$user_text = $dbw->addQuotes( $current->getUserText() );
			$s = $dbw->selectRow( 'revision',
				//array( 'min(rev_id)', 'rev_timestamp' ),
				array( 'min(rev_id) as rev_id' ),
				array(
					'rev_page' => $current->getPage(),
					"rev_user <> {$user} OR rev_user_text <> {$user_text}",
					$diff != "" ? "rev_id <  $diff" : '1 = 1', // sure - why not!
				), __METHOD__,
				array(
					'USE INDEX' => 'page_timestamp',
					'ORDER BY'  => 'rev_timestamp DESC' )
				);
			if ( $s ) {
				// set oldid
				$oldid = $s->rev_id;
			}

			// new diff object to extract the revision texts
			if ( $rcid != '' ) {
				$de = new DifferenceEngine( $title, $oldid, $diff, $rcid );
			} else {
				$de = new DifferenceEngine( $title, $oldid, $diff);
			}

			$de->loadText();
			$otext = $de->mOldtext;
			$ntext = $de->mNewtext;
			$ota = explode( "\n", $wgContLang->segmentForDiff( $otext ) );
			$nta = explode( "\n", $wgContLang->segmentForDiff( $ntext ) );
			$diffs = new Diff( $ota, $nta );

			// iterate over the edits and get all of the changed text
			$text = '';
			foreach ( $diffs->edits as $edit ) {
				if ( $edit->type != 'copy' ) {
					$text .= implode( "\n", $edit->closing ) . "\n";
				}
			}
		} else {
			$a = new Article( $title );
			$text = $a->getContent( true );
		}

		$matches = array();
		$preg = "/http:\/\/[^] \n'\"]*/";
		preg_match_all( $preg, $text, $matches );

		if ( !count( $matches[0] ) ) {
			$wgOut->addHTML( wfMsg( 'spamdifftool_no_urls_detected', $wgScript . "?" . urldecode( $wgRequest->getVal( 'returnto' ) ) ) );
			return;
		}

		$wgOut->addWikiMsg( 'spamdifftool_urls_detected' );
		$wgOut->addInlineStyle( 'td.spam-url-row { border: 1px solid #ccc; }' );

		$wgOut->addHTML(
			Xml::openElement( 'form', array( 'method' => 'post' ) ) . "\n" .
			Html::Hidden( 'returnto', $wgRequest->getVal( 'returnto' ) ) . "\n" .
			Xml::openElement( 'table', array( 'cellpadding' => 5, 'width' => '100%' ) ) . "\n"
		);

		$urls = array();
		foreach ( $matches as $match ) {
			foreach ( $match as $url ) {
				if ( isset( $urls[$url] ) ) continue; // avoid dupes
				$urls[$url] = true;
				$name = htmlspecialchars( str_replace( ".", "%2E", $url ) );
				$wgOut->addHTML(
					Xml::tags( 'tr', array(),
						Xml::tags( 'td', array( 'class' => 'spam-url-row' ),
							"<b>$url</b><br />" . wfMsgHtml( 'spamdifftool_block' ) . "&#160;&#160;" .
							Xml::radioLabel( wfMsg( 'spamdifftool_option_domain'), $name, 'domain', '{$name}-domain', true ) . "\n" .
							Xml::radioLabel( wfMsg( 'spamdifftool_option_subdomain' ), $name, 'subdomain', '{$name}-subdomain' ) . "\n" .
							Xml::radioLabel( wfMsg( 'spamdifftool_option_directory' ), $name, 'dir', '{$name}-dir' ) . "\n" .
							Xml::radioLabel( wfMsg( 'spamdifftool_option_none' ), $name, 'none', '{$name}-none' ) . "\n"
						)
					)
				);
			}
		}

		$wgOut->addHTML(
			Xml::closeElement( 'table' ) . "\n" .
			Xml::submitButton( wfMsg( 'spamdifftool_submit_buttom' ) ) . "\n" .
			Xml::closeElement( 'form' )
		);
	}