#------------------------------------------------------------------------------
protected $mLastQuery = '';
+ protected $mDoneWrites = false;
protected $mPHPError = false;
protected $mServer, $mUser, $mPassword, $mConn = null, $mDBname;
/**
* Return the last query that went through Database::query()
- * @return string
+ * @return String
*/
function lastQuery() { return $this->mLastQuery; }
-
+
+
+ /**
+ * Returns true if the connection may have been used for write queries.
+ * Should return true if unsure.
+ */
+ function doneWrites() { return $this->mDoneWrites; }
+
/**
* Is a connection to the database open?
- * @return bool
+ * @return Boolean
*/
function isOpen() { return $this->mOpened; }
# Other functions
#------------------------------------------------------------------------------
- /**@{{
+ /**
* Constructor.
- * @param string $server database server host
- * @param string $user database user name
- * @param string $password database user password
- * @param string $dbname database name
- * @param failFunction
+ * @param $server String: database server host
+ * @param $user String: database user name
+ * @param $password String: database user password
+ * @param $dbName String: database name
+ * @param $failFunction
* @param $flags
* @param $tablePrefix String: database table prefixes. By default use the prefix gave in LocalSettings.php
*/
}
/**
- * @static
+ * Same as new Database( ... ), kept for backward compatibility
+ * @param $server String: database server host
+ * @param $user String: database user name
+ * @param $password String: database user password
+ * @param $dbName String: database name
* @param failFunction
* @param $flags
*/
/**
* Usually aborts on failure
* If the failFunction is set to a non-zero integer, returns success
+ * @param $server String: database server host
+ * @param $user String: database user name
+ * @param $password String: database user password
+ * @param $dbName String: database name
*/
function open( $server, $user, $password, $dbName ) {
- global $wguname, $wgAllDBsAreLocalhost;
+ global $wgAllDBsAreLocalhost;
wfProfileIn( __METHOD__ );
# Test for missing mysql.so
$success = @/**/mysql_select_db( $dbName, $this->mConn );
if ( !$success ) {
$error = "Error selecting database $dbName on server {$this->mServer} " .
- "from client host {$wguname['nodename']}\n";
+ "from client host " . wfHostname() . "\n";
wfLogDBError(" Error selecting database $dbName on server {$this->mServer} \n");
wfDebug( $error );
}
wfProfileOut( __METHOD__ );
return $success;
}
- /**@}}*/
protected function installErrorHandler() {
$this->mPHPError = false;
+ $this->htmlErrors = ini_set( 'html_errors', '0' );
set_error_handler( array( $this, 'connectionErrorHandler' ) );
}
protected function restoreErrorHandler() {
restore_error_handler();
- return $this->mPHPError;
+ if ( $this->htmlErrors !== false ) {
+ ini_set( 'html_errors', $this->htmlErrors );
+ }
+ if ( $this->mPHPError ) {
+ $error = preg_replace( '!\[<a.*</a>\]!', '', $this->mPHPError );
+ $error = preg_replace( '!^.*?:(.*)$!', '$1', $error );
+ return $error;
+ } else {
+ return false;
+ }
}
protected function connectionErrorHandler( $errno, $errstr ) {
* Closes a database connection.
* if it is open : commits any open transactions
*
- * @return bool operation success. true if already closed.
+ * @return Bool operation success. true if already closed.
*/
function close()
{
}
/**
- * @param string $error fallback error message, used if none is given by MySQL
+ * @param $error String: fallback error message, used if none is given by MySQL
*/
function reportConnectionError( $error = 'Unknown error' ) {
$myError = $this->lastError();
}
}
+ /**
+ * Determine whether a query writes to the DB.
+ * Should return true if unsure.
+ */
+ function isWriteQuery( $sql ) {
+ return !preg_match( '/^(?:SELECT|BEGIN|COMMIT|SET|SHOW)\b/i', $sql );
+ }
+
/**
* Usually aborts on failure. If errors are explicitly ignored, returns success.
*
* @param $sql String: SQL query
* @param $fname String: Name of the calling function, for profiling/SHOW PROCESSLIST
* comment (you can use __METHOD__ or add some extra info)
- * @param $tempIgnore Bool: Whether to avoid throwing an exception on errors...
+ * @param $tempIgnore Boolean: Whether to avoid throwing an exception on errors...
* maybe best to catch the exception instead?
* @return true for a successful write query, ResultWrapper object for a successful read query,
* or false on failure if $tempIgnore set
}
$this->mLastQuery = $sql;
+ if ( !$this->mDoneWrites && $this->isWriteQuery( $sql ) ) {
+ // Set a flag indicating that writes have been done
+ wfDebug( __METHOD__.": Writes done: $sql\n" );
+ $this->mDoneWrites = true;
+ }
# Add a comment for easy SHOW PROCESSLIST interpretation
#if ( $fname ) {
}
}
+ if ( istainted( $sql ) & TC_MYSQL ) {
+ throw new MWException( 'Tainted query found' );
+ }
+
# Do the query and handle errors
$ret = $this->doQuery( $commentedSql );
# Try reconnecting if the connection was lost
- if ( false === $ret && ( $this->lastErrno() == 2013 || $this->lastErrno() == 2006 ) ) {
+ if ( false === $ret && $this->wasErrorReissuable() ) {
# Transaction is gone, like it or not
$this->mTrxLevel = 0;
wfDebug( "Connection lost, reconnecting...\n" );
* The DBMS-dependent part of query()
* @param $sql String: SQL query.
* @return Result object to feed to fetchObject, fetchRow, ...; or false on failure
- * @access private
+ * @private
*/
/*private*/ function doQuery( $sql ) {
if( $this->bufferResults() ) {
}
/**
- * @param $error
- * @param $errno
- * @param $sql
- * @param string $fname
- * @param bool $tempIgnore
+ * @param $error String
+ * @param $errno Integer
+ * @param $sql String
+ * @param $fname String
+ * @param $tempIgnore Boolean
*/
function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
global $wgCommandLineMode;
/**
* Execute a prepared query with the various arguments
- * @param string $prepared the prepared sql
- * @param mixed $args Either an array here, or put scalars as varargs
+ * @param $prepared String: the prepared sql
+ * @param $args Mixed: Either an array here, or put scalars as varargs
*/
function execute( $prepared, $args = null ) {
if( !is_array( $args ) ) {
/**
* Prepare & execute an SQL statement, quoting and inserting arguments
* in the appropriate places.
- * @param string $query
- * @param string $args ...
+ * @param $query String
+ * @param $args ...
*/
function safeQuery( $query, $args = null ) {
$prepared = $this->prepare( $query, 'Database::safeQuery' );
/**
* For faking prepared SQL statements on DBs that don't support
* it directly.
- * @param string $preparedSql - a 'preparable' SQL statement
- * @param array $args - array of arguments to fill it with
+ * @param $preparedQuery String: a 'preparable' SQL statement
+ * @param $args Array of arguments to fill it with
* @return string executable SQL
*/
function fillPrepared( $preparedQuery, $args ) {
* The arguments should be in $this->preparedArgs and must not be touched
* while we're doing this.
*
- * @param array $matches
- * @return string
+ * @param $matches Array
+ * @return String
* @private
*/
function fillPreparedArg( $matches ) {
}
}
- /**#@+
- * @param mixed $res A SQL result
- */
/**
* Free a result object
+ * @param $res Mixed: A SQL result
*/
function freeResult( $res ) {
if ( $res instanceof ResultWrapper ) {
/**
* Get the number of rows in a result object
+ * @param $res Mixed: A SQL result
*/
function numRows( $res ) {
if ( $res instanceof ResultWrapper ) {
/**
* Get the number of fields in a result object
* See documentation for mysql_num_fields()
+ * @param $res Mixed: A SQL result
*/
function numFields( $res ) {
if ( $res instanceof ResultWrapper ) {
* Get a field name in a result object
* See documentation for mysql_field_name():
* http://www.php.net/mysql_field_name
+ * @param $res Mixed: A SQL result
+ * @param $n Integer
*/
function fieldName( $res, $n ) {
if ( $res instanceof ResultWrapper ) {
/**
* Change the position of the cursor in a result object
* See mysql_data_seek()
+ * @param $res Mixed: A SQL result
+ * @param $row Mixed: Either MySQL row or ResultWrapper
*/
function dataSeek( $res, $row ) {
if ( $res instanceof ResultWrapper ) {
* See mysql_affected_rows() for more details
*/
function affectedRows() { return mysql_affected_rows( $this->mConn ); }
- /**#@-*/ // end of template : @param $result
/**
* Simple UPDATE wrapper
* This function exists for historical reasons, Database::update() has a more standard
* calling convention and feature set
*/
- function set( $table, $var, $value, $cond, $fname = 'Database::set' )
- {
+ function set( $table, $var, $value, $cond, $fname = 'Database::set' ) {
$table = $this->tableName( $table );
$sql = "UPDATE $table SET $var = '" .
$this->strencode( $value ) . "' WHERE ($cond)";
$row = $this->fetchRow( $res );
if ( $row !== false ) {
$this->freeResult( $res );
- return $row[0];
+ return reset( $row );
} else {
return false;
}
*
* @private
*
- * @param array $options an associative array of options to be turned into
+ * @param $options Array: associative array of options to be turned into
* an SQL query, valid keys are listed in the function.
- * @return array
+ * @return Array
*/
function makeSelectOptions( $options ) {
$preLimitTail = $postLimitTail = '';
/**
* SELECT wrapper
*
- * @param mixed $table Array or string, table name(s) (prefix auto-added)
- * @param mixed $vars Array or string, field name(s) to be retrieved
- * @param mixed $conds Array or string, condition(s) for WHERE
- * @param string $fname Calling function name (use __METHOD__) for logs/profiling
- * @param array $options Associative array of options (e.g. array('GROUP BY' => 'page_title')),
- * see Database::makeSelectOptions code for list of supported stuff
- * @param array $join_conds Associative array of table join conditions (optional)
- * (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') )
+ * @param $table Mixed: Array or string, table name(s) (prefix auto-added)
+ * @param $vars Mixed: Array or string, field name(s) to be retrieved
+ * @param $conds Mixed: Array or string, condition(s) for WHERE
+ * @param $fname String: Calling function name (use __METHOD__) for logs/profiling
+ * @param $options Array: Associative array of options (e.g. array('GROUP BY' => 'page_title')),
+ * see Database::makeSelectOptions code for list of supported stuff
+ * @param $join_conds Array: Associative array of table join conditions (optional)
+ * (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') )
* @return mixed Database result resource (feed to Database::fetchObject or whatever), or false on failure
*/
function select( $table, $vars, $conds='', $fname = 'Database::select', $options = array(), $join_conds = array() )
/**
* SELECT wrapper
*
- * @param mixed $table Array or string, table name(s) (prefix auto-added)
- * @param mixed $vars Array or string, field name(s) to be retrieved
- * @param mixed $conds Array or string, condition(s) for WHERE
- * @param string $fname Calling function name (use __METHOD__) for logs/profiling
- * @param array $options Associative array of options (e.g. array('GROUP BY' => 'page_title')),
- * see Database::makeSelectOptions code for list of supported stuff
- * @param array $join_conds Associative array of table join conditions (optional)
- * (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') )
+ * @param $table Mixed: Array or string, table name(s) (prefix auto-added)
+ * @param $vars Mixed: Array or string, field name(s) to be retrieved
+ * @param $conds Mixed: Array or string, condition(s) for WHERE
+ * @param $fname String: Calling function name (use __METHOD__) for logs/profiling
+ * @param $options Array: Associative array of options (e.g. array('GROUP BY' => 'page_title')),
+ * see Database::makeSelectOptions code for list of supported stuff
+ * @param $join_conds Array: Associative array of table join conditions (optional)
+ * (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') )
* @return string, the SQL text
*/
function selectSQLText( $table, $vars, $conds='', $fname = 'Database::select', $options = array(), $join_conds = array() ) {
* Single row SELECT wrapper
* Aborts or returns FALSE on error
*
- * $vars: the selected variables
- * $conds: a condition map, terms are ANDed together.
+ * @param $table String: table name
+ * @param $vars String: the selected variables
+ * @param $conds Array: a condition map, terms are ANDed together.
* Items with numeric keys are taken to be literal conditions
* Takes an array of selected variables, and a condition map, which is ANDed
* e.g: selectRow( "page", array( "page_id" ), array( "page_namespace" =>
* NS_MAIN, "page_title" => "Astronomy" ) ) would return an object where
* $obj- >page_id is the ID of the Astronomy article
+ * @param $fname String: Calling functio name
+ * @param $options Array
+ * @param $join_conds Array
*
* @todo migrate documentation to phpdocumentor format
*/
* Removes most variables from an SQL query and replaces them with X or N for numbers.
* It's only slightly flawed. Don't use for anything important.
*
- * @param string $sql A SQL Query
- * @static
+ * @param $sql String: A SQL Query
*/
static function generalizeSQL( $sql ) {
# This does the same as the regexp below would do, but in such a way
# SHOW INDEX should work for 3.x and up:
# http://dev.mysql.com/doc/mysql/en/SHOW_INDEX.html
$table = $this->tableName( $table );
+ $index = $this->indexName( $index );
$sql = 'SHOW INDEX FROM '.$table;
$res = $this->query( $sql, $fname );
if ( !$res ) {
* Make UPDATE options for the Database::update function
*
* @private
- * @param array $options The options passed to Database::update
+ * @param $options Array: The options passed to Database::update
* @return string
*/
function makeUpdateOptions( $options ) {
/**
* UPDATE wrapper, takes a condition array and a SET array
*
- * @param string $table The table to UPDATE
- * @param array $values An array of values to SET
- * @param array $conds An array of conditions (WHERE). Use '*' to update all rows.
- * @param string $fname The Class::Function calling this function
- * (for the log)
- * @param array $options An array of UPDATE options, can be one or
+ * @param $table String: The table to UPDATE
+ * @param $values Array: An array of values to SET
+ * @param $conds Array: An array of conditions (WHERE). Use '*' to update all rows.
+ * @param $fname String: The Class::Function calling this function
+ * (for the log)
+ * @param $options Array: An array of UPDATE options, can be one or
* more of IGNORE, LOW_PRIORITY
- * @return bool
+ * @return Boolean
*/
function update( $table, $values, $conds, $fname = 'Database::update', $options = array() ) {
$table = $this->tableName( $table );
} else {
$list .= $field." IN (".$this->makeList($value).") ";
}
- } elseif( is_null($value) ) {
+ } elseif( $value === null ) {
if ( $mode == LIST_AND || $mode == LIST_OR ) {
$list .= "$field IS ";
} elseif ( $mode == LIST_SET ) {
* themselves. Pass the canonical name to such functions. This is only needed
* when calling query() directly.
*
- * @param string $name database table name
- * @return string full database name
+ * @param $name String: database table name
+ * @return String: full database name
*/
function tableName( $name ) {
global $wgSharedDB, $wgSharedPrefix, $wgSharedTables;
return implode(' ',array($straightJoins,$otherJoins) );
}
+ /**
+ * Get the name of an index in a given table
+ */
+ function indexName( $index ) {
+ // Backwards-compatibility hack
+ $renamed = array(
+ 'ar_usertext_timestamp' => 'usertext_timestamp',
+ 'un_user_id' => 'user_id',
+ 'un_user_ip' => 'user_ip',
+ );
+ if( isset( $renamed[$index] ) ) {
+ return $renamed[$index];
+ } else {
+ return $index;
+ }
+ }
+
/**
* Wrapper for addslashes()
- * @param string $s String to be slashed.
- * @return string slashed string.
+ * @param $s String: to be slashed.
+ * @return String: slashed string.
*/
function strencode( $s ) {
return mysql_real_escape_string( $s, $this->mConn );
* Otherwise returns as-is
*/
function addQuotes( $s ) {
- if ( is_null( $s ) ) {
+ if ( $s === null ) {
return 'NULL';
} else {
# This will also quote numeric values. This should be harmless,
* Escape string for safe LIKE usage
*/
function escapeLike( $s ) {
+ $s=str_replace('\\','\\\\',$s);
$s=$this->strencode( $s );
$s=str_replace(array('%','_'),array('\%','\_'),$s);
return $s;
* PostgreSQL doesn't have them and returns ""
*/
function useIndexClause( $index ) {
- return "FORCE INDEX ($index)";
+ return "FORCE INDEX (" . $this->indexName( $index ) . ")";
}
/**
*
* DO NOT put the join condition in $conds
*
- * @param string $delTable The table to delete from.
- * @param string $joinTable The other table.
- * @param string $delVar The variable to join on, in the first table.
- * @param string $joinVar The variable to join on, in the second table.
- * @param array $conds Condition array of field names mapped to variables, ANDed together in the WHERE clause
+ * @param $delTable String: The table to delete from.
+ * @param $joinTable String: The other table.
+ * @param $delVar String: The variable to join on, in the first table.
+ * @param $joinVar String: The variable to join on, in the second table.
+ * @param $conds Array: Condition array of field names mapped to variables, ANDed together in the WHERE clause
+ * @param $fname String: Calling function name (use __METHOD__) for logs/profiling
*/
function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname = 'Database::deleteJoin' ) {
if ( !$conds ) {
/**
* Construct a LIMIT query with optional offset
* This is used for query pages
- * $sql string SQL query we will append the limit too
- * $limit integer the SQL limit
- * $offset integer the SQL offset (default false)
+ * @param $sql String: SQL query we will append the limit too
+ * @param $limit Integer: the SQL limit
+ * @param $offset Integer the SQL offset (default false)
*/
function limitResult($sql, $limit, $offset=false) {
if( !is_numeric($limit) ) {
* Returns an SQL expression for a simple conditional.
* Uses IF on MySQL.
*
- * @param string $cond SQL expression which will result in a boolean value
- * @param string $trueVal SQL expression to return if true
- * @param string $falseVal SQL expression to return if false
- * @return string SQL fragment
+ * @param $cond String: SQL expression which will result in a boolean value
+ * @param $trueVal String: SQL expression to return if true
+ * @param $falseVal String: SQL expression to return if false
+ * @return String: SQL fragment
*/
function conditional( $cond, $trueVal, $falseVal ) {
return " IF($cond, $trueVal, $falseVal) ";
* Returns a comand for str_replace function in SQL query.
* Uses REPLACE() in MySQL
*
- * @param string $orig String or column to modify
- * @param string $old String or column to seek
- * @param string $new String or column to replace with
+ * @param $orig String: column to modify
+ * @param $old String: column to seek
+ * @param $new String: column to replace with
*/
function strreplace( $orig, $old, $new ) {
return "REPLACE({$orig}, {$old}, {$new})";
return $this->lastErrno() == 1213;
}
+ /**
+ * Determines if the last query error was something that should be dealt
+ * with by pinging the connection and reissuing the query
+ */
+ function wasErrorReissuable() {
+ return $this->lastErrno() == 2013 || $this->lastErrno() == 2006;
+ }
+
/**
* Perform a deadlock-prone transaction.
*
/**
* Do a SELECT MASTER_POS_WAIT()
*
- * @param string $file the binlog file
- * @param string $pos the binlog position
- * @param integer $timeout the maximum number of seconds to wait for synchronisation
+ * @param $pos MySQLMasterPos object
+ * @param $timeout Integer: the maximum number of seconds to wait for synchronisation
*/
function masterPosWait( MySQLMasterPos $pos, $timeout ) {
$fname = 'Database::masterPosWait';
$res = $this->query( 'SHOW SLAVE STATUS', 'Database::getSlavePos' );
$row = $this->fetchObject( $res );
if ( $row ) {
- return new MySQLMasterPos( $row->Master_Log_File, $row->Read_Master_Log_Pos );
+ $pos = isset($row->Exec_master_log_pos) ? $row->Exec_master_log_pos : $row->Exec_Master_Log_Pos;
+ return new MySQLMasterPos( $row->Relay_Master_Log_File, $pos );
} else {
return false;
}
}
/**
- * @return string wikitext of a link to the server software's web site
+ * @return String: wikitext of a link to the server software's web site
*/
function getSoftwareLink() {
return "[http://www.mysql.com/ MySQL]";
}
/**
- * @return string Version information from the database
+ * @return String: Version information from the database
*/
function getServerVersion() {
return mysql_get_server_info( $this->mConn );
* May be useful for very long batch queries such as
* full-wiki dumps, where a single query reads out
* over hours or days.
- * @param int $timeout in seconds
+ * @param $timeout Integer in seconds
*/
public function setTimeout( $timeout ) {
$this->query( "SET net_read_timeout=$timeout" );
/**
* Read and execute SQL commands from a file.
* Returns true on success, error string or exception on failure (depending on object's error ignore settings)
- * @param string $filename File name to open
- * @param callback $lineCallback Optional function called before reading each line
- * @param callback $resultCallback Optional function called for each MySQL result
+ * @param $filename String: File name to open
+ * @param $lineCallback Callback: Optional function called before reading each line
+ * @param $resultCallback Callback: Optional function called for each MySQL result
*/
function sourceFile( $filename, $lineCallback = false, $resultCallback = false ) {
$fp = fopen( $filename, 'r' );
/**
* Read and execute commands from an open file handle
* Returns true on success, error string or exception on failure (depending on object's error ignore settings)
- * @param string $fp File handle
- * @param callback $lineCallback Optional function called before reading each line
- * @param callback $resultCallback Optional function called for each MySQL result
+ * @param $fp String: File handle
+ * @param $lineCallback Callback: Optional function called before reading each line
+ * @param $resultCallback Callback: Optional function called for each MySQL result
*/
function sourceStream( $fp, $lineCallback = false, $resultCallback = false ) {
$cmd = "";
}
// Table prefixes
- $ins = preg_replace_callback( '/\/\*(?:\$wgDBprefix|_)\*\/([a-zA-Z_0-9]*)/',
- array( &$this, 'tableNameCallback' ), $ins );
+ $ins = preg_replace_callback( '!/\*(?:\$wgDBprefix|_)\*/([a-zA-Z_0-9]*)!',
+ array( $this, 'tableNameCallback' ), $ins );
+
+ // Index names
+ $ins = preg_replace_callback( '!/\*i\*/([a-zA-Z_0-9]*)!',
+ array( $this, 'indexNameCallback' ), $ins );
return $ins;
}
return $this->tableName( $matches[1] );
}
+ /**
+ * Index name callback
+ */
+ protected function indexNameCallback( $matches ) {
+ return $this->indexName( $matches[1] );
+ }
+
/*
* Build a concatenation list to feed into a SQL query
*/
* Abstracted from Filestore::lock() so child classes can implement for
* their own needs.
*
- * @param string $lockName Name of lock to aquire
- * @param string $method Name of method calling us
+ * @param $lockName String: Name of lock to aquire
+ * @param $method String: Name of method calling us
* @return bool
*/
public function lock( $lockName, $method ) {
* @todo fixme - Figure out a way to return a bool
* based on successful lock release.
*
- * @param string $lockName Name of lock to release
- * @param string $method Name of method calling us
+ * @param $lockName String: Name of lock to release
+ * @param $method String: Name of method calling us
*/
public function unlock( $lockName, $method ) {
$lockName = $this->addQuotes( $lockName );
* Get search engine class. All subclasses of this
* need to implement this if they wish to use searching.
*
- * @return string
+ * @return String
*/
public function getSearchEngine() {
return "SearchMySQL";
/**
* Construct a database error
- * @param Database $db The database object which threw the error
- * @param string $error A simple error message to be used for debugging
+ * @param $db Database object which threw the error
+ * @param $error A simple error message to be used for debugging
*/
function __construct( Database &$db, $error ) {
$this->db =& $db;
}
function getPageTitle() {
- global $wgSitename;
- return "$wgSitename has a problem";
+ global $wgSitename, $wgLang;
+ $header = "$wgSitename has a problem";
+ if ( $wgLang instanceof Language ) {
+ $header = htmlspecialchars( $wgLang->getMessage( 'dberr-header' ) );
+ }
+
+ return $header;
}
function getHTML() {
- global $wgTitle, $wgUseFileCache, $title, $wgInputEncoding;
- global $wgSitename, $wgServer, $wgMessageCache;
+ global $wgLang, $wgMessageCache, $wgUseFileCache;
- # I give up, Brion is right. Getting the message cache to work when there is no DB is tricky.
- # Hard coding strings instead.
+ $sorry = 'Sorry! This site is experiencing technical difficulties.';
+ $again = 'Try waiting a few minutes and reloading.';
+ $info = '(Can\'t contact the database server: $1)';
- $noconnect = "<p><strong>Sorry! This site is experiencing technical difficulties.</strong></p><p>Try waiting a few minutes and reloading.</p><p><small>(Can't contact the database server: $1)</small></p>";
- $mainpage = 'Main Page';
- $searchdisabled = <<<EOT
-<p style="margin: 1.5em 2em 1em">$wgSitename search is disabled for performance reasons. You can search via Google in the meantime.
-<span style="font-size: 89%; display: block; margin-left: .2em">Note that their indexes of $wgSitename content may be out of date.</span></p>',
-EOT;
-
- $googlesearch = "
-<!-- SiteSearch Google -->
-<FORM method=GET action=\"http://www.google.com/search\">
-<TABLE bgcolor=\"#FFFFFF\"><tr><td>
-<A HREF=\"http://www.google.com/\">
-<IMG SRC=\"http://www.google.com/logos/Logo_40wht.gif\"
-border=\"0\" ALT=\"Google\"></A>
-</td>
-<td>
-<INPUT TYPE=text name=q size=31 maxlength=255 value=\"$1\">
-<INPUT type=submit name=btnG VALUE=\"Google Search\">
-<font size=-1>
-<input type=hidden name=domains value=\"$wgServer\"><br /><input type=radio name=sitesearch value=\"\"> WWW <input type=radio name=sitesearch value=\"$wgServer\" checked> $wgServer <br />
-<input type='hidden' name='ie' value='$2'>
-<input type='hidden' name='oe' value='$2'>
-</font>
-</td></tr></TABLE>
-</FORM>
-<!-- SiteSearch Google -->";
- $cachederror = "The following is a cached copy of the requested page, and may not be up to date. ";
+ if ( $wgLang instanceof Language ) {
+ $sorry = htmlspecialchars( $wgLang->getMessage( 'dberr-problems' ) );
+ $again = htmlspecialchars( $wgLang->getMessage( 'dberr-again' ) );
+ $info = htmlspecialchars( $wgLang->getMessage( 'dberr-info' ) );
+ }
# No database access
if ( is_object( $wgMessageCache ) ) {
$this->error = $this->db->getProperty('mServer');
}
+ $noconnect = "<p><strong>$sorry</strong><br />$again</p><p><small>$info</small></p>";
$text = str_replace( '$1', $this->error, $noconnect );
/*
"</p>\n";
}*/
+ $extra = $this->searchForm();
+
if($wgUseFileCache) {
- if($wgTitle) {
- $t =& $wgTitle;
- } else {
- if($title) {
- $t = Title::newFromURL( $title );
- } elseif (@/**/$_REQUEST['search']) {
- $search = $_REQUEST['search'];
- return $searchdisabled .
- str_replace( array( '$1', '$2' ), array( htmlspecialchars( $search ),
- $wgInputEncoding ), $googlesearch );
- } else {
- $t = Title::newFromText( $mainpage );
- }
- }
+ $cache = $this->fileCachedPage();
+ if ( $cache !== null ) $extra = $cache;
+ }
- $cache = new HTMLFileCache( $t );
- if( $cache->isFileCached() ) {
- // @todo, FIXME: $msg is not defined on the next line.
- $msg = '<p style="color: red"><b>'.$text."<br />\n" .
- $cachederror . "</b></p>\n";
-
- $tag = '<div id="article">';
- $text = str_replace(
- $tag,
- $tag . $text,
- $cache->fetchPageText() );
- }
+ return $text . '<hr />' . $extra;
+ }
+
+ function searchForm() {
+ global $wgSitename, $wgServer, $wgLang, $wgInputEncoding;
+ $usegoogle = "You can try searching via Google in the meantime.";
+ $outofdate = "Note that their indexes of our content may be out of date.";
+ $googlesearch = "Search";
+
+ if ( $wgLang instanceof Language ) {
+ $usegoogle = htmlspecialchars( $wgLang->getMessage( 'dberr-usegoogle' ) );
+ $outofdate = htmlspecialchars( $wgLang->getMessage( 'dberr-outofdate' ) );
+ $googlesearch = htmlspecialchars( $wgLang->getMessage( 'searchbutton' ) );
}
- return $text;
+ $search = htmlspecialchars(@$_REQUEST['search']);
+
+ $trygoogle = <<<EOT
+<div style="margin: 1.5em">$usegoogle<br />
+<small>$outofdate</small></div>
+<!-- SiteSearch Google -->
+<form method="get" action="http://www.google.com/search" id="googlesearch">
+ <input type="hidden" name="domains" value="$wgServer" />
+ <input type="hidden" name="num" value="50" />
+ <input type="hidden" name="ie" value="$wgInputEncoding" />
+ <input type="hidden" name="oe" value="$wgInputEncoding" />
+
+ <img src="http://www.google.com/logos/Logo_40wht.gif" style="float:left; margin-left: 1.5em; margin-right: 1.5em;" />
+
+ <input type="text" name="q" size="31" maxlength="255" value="$search" />
+ <input type="submit" name="btnG" value="$googlesearch" />
+ <div>
+ <input type="radio" name="sitesearch" id="gwiki" value="$wgServer" checked="checked" /><label for="gwiki">$wgSitename</label>
+ <input type="radio" name="sitesearch" id="gWWW" value="" /><label for="gWWW">WWW</label>
+ </div>
+</form>
+<!-- SiteSearch Google -->
+EOT;
+ return $trygoogle;
}
+
+ function fileCachedPage() {
+ global $wgTitle, $title, $wgLang;
+
+ $cachederror = "The following is a cached copy of the requested page, and may not be up to date. ";
+ $mainpage = 'Main Page';
+ if ( $wgLang instanceof Language ) {
+ $cachederror = htmlspecialchars( $wgLang->getMessage( 'dberr-cachederror' ) );
+ $mainpage = htmlspecialchars( $wgLang->getMessage( 'mainpage' ) );
+ }
+
+ if($wgTitle) {
+ $t =& $wgTitle;
+ } elseif($title) {
+ $t = Title::newFromURL( $title );
+ } else {
+ $t = Title::newFromText( $mainpage );
+ }
+
+ $cache = new HTMLFileCache( $t );
+ if( $cache->isFileCached() ) {
+ $warning = "<div style='color:red;font-size:150%;font-weight:bold;'>$cachederror</div>";
+ return $warning . $cache->fetchPageText();
+ } else {
+ return '';
+ }
+ }
+
}
/**