Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

SpecialAsksql.php

Go to the documentation of this file.
00001 <?php 00002 # 00003 # If enabled through $wgAllowSysopQueries = true, this class 00004 # let users with sysop right the possibility to make sql queries 00005 # against the cur table. 00006 # Heavy queries could slow down the database specially for the 00007 # biggest wikis. 00008 00009 function wfSpecialAsksql() 00010 { 00011 global $wgUser, $wgOut, $wgRequest, $wgAllowSysopQueries; 00012 00013 if( !$wgAllowSysopQueries ) { 00014 $wgOut->errorpage( "nosuchspecialpage", "nospecialpagetext" ); 00015 return; 00016 } 00017 if( !$wgUser->isSysop() ) { 00018 $wgOut->sysopRequired(); 00019 return; 00020 } 00021 00022 if( $wgRequest->wasPosted() ) { 00023 $query = $wgRequest->getVal( 'wpSqlQuery' ); 00024 $action = $wgRequest->getVal( 'action' ); 00025 } else { 00026 $query = ""; 00027 $action = ""; 00028 } 00029 $f = new SqlQueryForm( $query); 00030 00031 if ( "submit" == $action ) { 00032 $f->doSubmit(); 00033 } else { 00034 $f->showForm( "" ); 00035 } 00036 } 00037 00038 class SqlQueryForm { 00039 var $query = ""; 00040 00041 function SqlQueryForm( $query ) { 00042 $this->query = $query; 00043 } 00044 00045 function showForm( $err ) 00046 { 00047 global $wgOut, $wgUser, $wgLang; 00048 global $wgLogQueries; 00049 00050 $wgOut->setPagetitle( wfMsg( "asksql" ) ); 00051 $note = wfMsg( "asksqltext" ); 00052 if($wgLogQueries) 00053 $note .= " " . wfMsg( "sqlislogged" ); 00054 $wgOut->addWikiText( $note ); 00055 00056 if ( "" != $err ) { 00057 $wgOut->addHTML( "<p><font color='red' size='+1'>" . htmlspecialchars($err) . "</font>\n" ); 00058 } 00059 if ( ! $this->query ) { $this->query = "SELECT ... FROM ... WHERE ..."; } 00060 $q = wfMsg( "sqlquery" ); 00061 $qb = wfMsg( "querybtn" ); 00062 $titleObj = Title::makeTitle( NS_SPECIAL, "Asksql" ); 00063 $action = $titleObj->escapeLocalURL( "action=submit" ); 00064 00065 $wgOut->addHTML( "<p> 00066 <form id=\"asksql\" method=\"post\" action=\"{$action}\"> 00067 <table border=0><tr> 00068 <td align=right>{$q}:</td> 00069 <td align=left> 00070 <textarea name=\"wpSqlQuery\" cols=80 rows=4 wrap=\"virtual\">" 00071 . htmlspecialchars($this->query) ." 00072 </textarea> 00073 </td> 00074 </tr><tr> 00075 <td>&nbsp;</td><td align=\"left\"> 00076 <input type=submit name=\"wpQueryBtn\" value=\"{$qb}\"> 00077 </td></tr></table> 00078 </form>\n" ); 00079 00080 } 00081 00082 function doSubmit() 00083 { 00084 global $wgOut, $wgUser, $wgServer, $wgScript, $wgArticlePath, $wgLang; 00085 global $wgDBserver, $wgDBsqluser, $wgDBsqlpassword, $wgDBname, $wgSqlTimeout; 00086 00087 # Use a limit, folks! 00088 $this->query = trim( $this->query ); 00089 if( preg_match( "/^SELECT/i", $this->query ) 00090 and !preg_match( "/LIMIT/i", $this->query ) ) { 00091 $this->query .= " LIMIT 100"; 00092 } 00093 $conn = Database::newFromParams( $wgDBserver, $wgDBsqluser, $wgDBsqlpassword, $wgDBname ); 00094 00095 $this->logQuery( $this->query ); 00096 00097 # Start timer, will kill the DB thread in $wgSqlTimeout seconds 00098 $conn->startTimer( $wgSqlTimeout ); 00099 $res = $conn->query( $this->query, "SpecialAsksql::doSubmit" ); 00100 $conn->stopTimer(); 00101 $this->logFinishedQuery(); 00102 00103 $n = 0; 00104 @$n = $conn->numFields( $res ); 00105 $titleList = false; 00106 00107 if ( $n ) { 00108 $k = array(); 00109 for ( $x = 0; $x < $n; ++$x ) { 00110 array_push( $k, $conn->fieldName( $res, $x ) ); 00111 } 00112 00113 if ( $n == 2 && in_array( "cur_title", $k ) && in_array( "cur_namespace", $k ) ) { 00114 $titleList = true; 00115 } 00116 00117 $a = array(); 00118 while ( $s = $conn->fetchObject( $res ) ) { 00119 array_push( $a, $s ); 00120 } 00121 $conn->freeResult( $res ); 00122 00123 if ( $titleList ) { 00124 $r = ""; 00125 foreach ( $a as $y ) { 00126 $sTitle = htmlspecialchars( $y->cur_title ); 00127 if ( $y->cur_namespace ) { 00128 $sNamespace = $wgLang->getNsText( $y->cur_namespace ); 00129 $link = "$sNamespace:$sTitle"; 00130 } else { 00131 $link = "$sTitle"; 00132 } 00133 $skin = $wgUser->getSkin(); 00134 $link = $skin->makeLink( $link ); 00135 $r .= "* [[$link]]<br>\n"; 00136 } 00137 } else { 00138 00139 $r = "<table border=1 bordercolor=black cellspacing=0 " . 00140 "cellpadding=2><tr>\n"; 00141 foreach ( $k as $x ) $r .= "<th>" . htmlspecialchars( $x ) . "</th>"; 00142 $r .= "</tr>\n"; 00143 00144 foreach ( $a as $y ) { 00145 $r .= "<tr>"; 00146 foreach ( $k as $x ) { 00147 $o = $y->$x ; 00148 if ( $x == "cur_title" or $x == "old_title" or $x == "rc_title") { 00149 $namespace = 0; 00150 if( $x == "cur_title" ) $namespace = $y->cur_namespace; 00151 if( $x == "old_title" ) $namespace = $y->old_namespace; 00152 if( $x == "rc_title" ) $namespace = $y->rc_namespace; 00153 if( $namespace ) $o = $wgLang->getNsText( $namespace ) . ":" . $o; 00154 $o = "<a href=\"" . wfLocalUrlE($o) . "\" class='internal'>" . 00155 htmlspecialchars( $y->$x ) . "</a>" ; 00156 } else { 00157 $o = htmlspecialchars( $o ); 00158 } 00159 $r .= "<td>" . $o . "</td>\n"; 00160 } 00161 $r .= "</tr>\n"; 00162 } 00163 $r .= "</table>\n"; 00164 } 00165 } 00166 $this->showForm( wfMsg( "querysuccessful" ) ); 00167 $wgOut->addHTML( "<hr>{$r}\n" ); 00168 } 00169 00170 function logQuery( $q ) { 00171 global $wgSqlLogFile, $wgLogQueries, $wgUser; 00172 if(!$wgLogQueries) return; 00173 00174 $f = fopen( $wgSqlLogFile, "a" ); 00175 fputs( $f, "\n\n" . wfTimestampNow() . 00176 " query by " . $wgUser->getName() . 00177 ":\n$q\n" ); 00178 fclose( $f ); 00179 $this->starttime = wfTime(); 00180 } 00181 00182 function logFinishedQuery() { 00183 global $wgSqlLogFile, $wgLogQueries; 00184 if(!$wgLogQueries) return; 00185 00186 $interval = wfTime() - $this->starttime; 00187 00188 $f = fopen( $wgSqlLogFile, "a" ); 00189 fputs( $f, "finished at " . wfTimestampNow() . "; took $interval secs\n" ); 00190 fclose( $f ); 00191 } 00192 00193 } 00194 00195 ?>

Generated on Tue Jun 29 23:40:07 2004 for Mediawiki by doxygen 1.3.7