Exemple #1
0
 /**
  * Open a connection to the master server with the admin rights.
  * @return Database
  * @access private
  */
 function newConnection()
 {
     $lb = wfGetLBFactory()->newMainLB();
     $db = $lb->getConnection(DB_MASTER);
     $this->loadBalancers[] = $lb;
     return $db;
 }
 public function process()
 {
     // Erweiterung der Elternfunktion process()
     $post = $this->request->data('post');
     $get = $this->request->data('get');
     unset($get['title']);
     // dirty MediaWiki fix: /wiki/foo -> /w/index.php?title=foo
     if (isset($get['allowed_filetarpathes'])) {
         $this->echoJson(self::$allowed_filetarpathes);
         exit;
     }
     if (!empty($this->request->file())) {
         $this->handleChunk();
         if (isset($this->returnData)) {
             $this->echoJson($this->returnData);
         }
         // Fehlermeldung "Uncommitted DB writes": MediaWiki mag es wahrscheinlich nicht,
         // wenn man exit() aufruft. vgl. http://stackoverflow.com/a/22695318
         $lb = wfGetLBFactory();
         $lb->shutdown();
         exit;
         # prevent MediaWiki to output something
     } elseif (!empty($get)) {
         $this->handleTestChunk();
         if (isset($this->returnData)) {
             $this->echoJson($this->returnData);
         }
         exit;
         # prevent MediaWiki to output something
     }
     $this->pruneChunks(true);
     # [true=always|false=random base]. Other option is to implement a cron script
 }
 /**
  * @return \LoadBalancer
  */
 public function getLB()
 {
     if ($this->cluster !== false) {
         return wfGetLBFactory()->getExternalLB($this->cluster, $this->wiki);
     } else {
         return wfGetLB($this->wiki);
     }
 }
 /**
  * @param array $updates Array of arrays each containing two keys, 'primaryKey'
  *  and 'changes'. primaryKey must contain a map of column names to values
  *  sufficient to uniquely identify the row changes must contain a map of column
  *  names to update values to apply to the row.
  */
 public function write(array $updates)
 {
     $this->db->begin();
     foreach ($updates as $update) {
         $this->db->update($this->table, $update['changes'], $update['primaryKey'], __METHOD__);
     }
     $this->db->commit();
     wfGetLBFactory()->waitForReplication();
 }
 /**
  * Wrapper function for wfGetDB
  *
  * @param $db int Index of the connection to get
  * @param $groups mixed Query groups.
  * @param $wiki string|bool The wiki ID, or false for the current wiki
  * @return DatabaseBase
  */
 public static function getDB($db, $groups = array(), $wiki = false)
 {
     global $wgEchoCluster;
     // Use the external db defined for Echo
     if ($wgEchoCluster) {
         $lb = wfGetLBFactory()->getExternalLB($wgEchoCluster, $wiki);
     } else {
         $lb = wfGetLB($wiki);
     }
     return $lb->getConnection($db, $groups, $wiki);
 }
 function run()
 {
     if (!empty($this->params['mainDbMasterPos'])) {
         wfGetLB()->waitFor($this->params['mainDbMasterPos']);
     }
     if (!empty($this->params['echoDbMasterPos'])) {
         global $wgEchoCluster;
         wfGetLBFactory()->getExternalLB($wgEchoCluster)->waitFor($this->params['echoDbMasterPos']);
     }
     EchoNotificationController::notify($this->event, false);
     return true;
 }
 public function execute()
 {
     wfProfileIn(__METHOD__);
     //run the download:
     Http::doSessionIdDownload($this->getOption('sid'), $this->getOption('usk'));
     // close up shop:
     // Execute any deferred updates
     wfDoUpdates();
     // Log what the user did, for book-keeping purposes.
     wfLogProfilingData();
     // Shut down the database before exit
     wfGetLBFactory()->shutdown();
     wfProfileOut(__METHOD__);
 }
	function getOpenIDStore( $storeType, $prefix, $options ) {
		global $wgOut, $wgMemc, $wgDBtype;

		switch ( $storeType ) {

		case 'file':
			# Auto-create path if it doesn't exist
			if ( !is_dir( $options['path'] ) ) {
				if ( !mkdir( $options['path'], 0770, true ) ) {
					$wgOut->showErrorPage( 'openidconfigerror', 'openidconfigerrortext' );
					return null;
				}
			}
			return new Auth_OpenID_FileStore( $options['path'] );

		case 'db':
			if ( $wgDBtype == 'sqlite' ) {
				$db = new MediaWikiOpenIDDatabaseConnection( wfGetDB( DB_MASTER ) );
				require_once( 'Auth/OpenID/SQLiteStore.php' );
				return new Auth_OpenID_SQLiteStore( $db );
			} else {
				$lb = wfGetLBFactory()->newMainLB();
				$db = new MediaWikiOpenIDDatabaseConnection( $lb->getConnection( DB_MASTER ) );
				switch( $wgDBtype ) {
				case 'mysql':
					require_once( 'Auth/OpenID/MySQLStore.php' );
					return new Auth_OpenID_MySQLStore( $db );
				case 'postgres':
					require_once( 'Auth/OpenID/PostgreSQLStore.php' );
					return new Auth_OpenID_PostgreSQLStore( $db );
				default:
					$wgOut->showErrorPage( 'openidconfigerror', 'openidconfigerrortext' );
					return null;
				}
			}

		case 'memcached':
			return new MediaWikiOpenIDMemcachedStore( $wgMemc );

		 default:
			$wgOut->showErrorPage( 'openidconfigerror', 'openidconfigerrortext' );
		}
	}
Exemple #9
0
 /**
  * @return DatabaseBase
  */
 protected function getDB()
 {
     if (!isset($this->db)) {
         # If server connection info was given, use that
         if ($this->serverInfo) {
             $this->lb = new LoadBalancer(array('servers' => array($this->serverInfo)));
             $this->db = $this->lb->getConnection(DB_MASTER);
             $this->db->clearFlag(DBO_TRX);
         } else {
             # We must keep a separate connection to MySQL in order to avoid deadlocks
             # However, SQLite has an opposite behaviour.
             # @todo Investigate behaviour for other databases
             if (wfGetDB(DB_MASTER)->getType() == 'sqlite') {
                 $this->db = wfGetDB(DB_MASTER);
             } else {
                 $this->lb = wfGetLBFactory()->newMainLB();
                 $this->db = $this->lb->getConnection(DB_MASTER);
                 $this->db->clearFlag(DBO_TRX);
             }
         }
     }
     return $this->db;
 }
 public function testDoUpdatesCLI()
 {
     $this->setMwGlobals('wgCommandLineMode', true);
     $updates = ['1' => "deferred update 1;\n", '2' => "deferred update 2;\n", '2-1' => "deferred update 1 within deferred update 2;\n", '2-2' => "deferred update 2 within deferred update 2;\n", '3' => "deferred update 3;\n", '3-1' => "deferred update 1 within deferred update 3;\n", '3-2' => "deferred update 2 within deferred update 3;\n", '3-1-1' => "deferred update 1 within deferred update 1 within deferred update 3;\n", '3-2-1' => "deferred update 1 within deferred update 2 with deferred update 3;\n"];
     wfGetLBFactory()->commitMasterChanges(__METHOD__);
     // clear anything
     DeferredUpdates::addCallableUpdate(function () use($updates) {
         echo $updates['1'];
     });
     DeferredUpdates::addCallableUpdate(function () use($updates) {
         echo $updates['2'];
         DeferredUpdates::addCallableUpdate(function () use($updates) {
             echo $updates['2-1'];
         });
         DeferredUpdates::addCallableUpdate(function () use($updates) {
             echo $updates['2-2'];
         });
     });
     DeferredUpdates::addCallableUpdate(function () use($updates) {
         echo $updates['3'];
         DeferredUpdates::addCallableUpdate(function () use($updates) {
             echo $updates['3-1'];
             DeferredUpdates::addCallableUpdate(function () use($updates) {
                 echo $updates['3-1-1'];
             });
         });
         DeferredUpdates::addCallableUpdate(function () use($updates) {
             echo $updates['3-2'];
             DeferredUpdates::addCallableUpdate(function () use($updates) {
                 echo $updates['3-2-1'];
             });
         });
     });
     $this->expectOutputString(implode('', $updates));
     DeferredUpdates::doUpdates();
 }
Exemple #11
0
 public function execute()
 {
     $wiki = $this->getOption('wikidb') ?: false;
     // Get the appropriate load balancer (for this wiki)
     if ($this->hasOption('cluster')) {
         $lb = wfGetLBFactory()->getExternalLB($this->getOption('cluster'), $wiki);
     } else {
         $lb = wfGetLB($wiki);
     }
     // Figure out which server to use
     if ($this->hasOption('slave')) {
         $server = $this->getOption('slave');
         if ($server === 'any') {
             $index = DB_SLAVE;
         } else {
             $index = null;
             for ($i = 0; $i < $lb->getServerCount(); ++$i) {
                 if ($lb->getServerName($i) === $server) {
                     $index = $i;
                     break;
                 }
             }
             if ($index === null) {
                 $this->error("No slave server configured with the name '{$server}'.", 1);
             }
         }
     } else {
         $index = DB_MASTER;
     }
     // Get a DB handle (with this wiki's DB selected) from the appropriate load balancer
     $db = $lb->getConnection($index, array(), $wiki);
     if ($this->hasOption('slave') && $db->getLBInfo('master') !== null) {
         $this->error("The server selected ({$db->getServer()}) is not a slave.", 1);
     }
     if ($this->hasArg(0)) {
         $file = fopen($this->getArg(0), 'r');
         if (!$file) {
             $this->error("Unable to open input file", true);
         }
         $error = $db->sourceStream($file, false, array($this, 'sqlPrintResult'));
         if ($error !== true) {
             $this->error($error, true);
         } else {
             exit(0);
         }
     }
     $useReadline = function_exists('readline_add_history') && Maintenance::posix_isatty(0);
     if ($useReadline) {
         global $IP;
         $historyFile = isset($_ENV['HOME']) ? "{$_ENV['HOME']}/.mwsql_history" : "{$IP}/maintenance/.mwsql_history";
         readline_read_history($historyFile);
     }
     $wholeLine = '';
     $newPrompt = '> ';
     $prompt = $newPrompt;
     while (($line = Maintenance::readconsole($prompt)) !== false) {
         if (!$line) {
             # User simply pressed return key
             continue;
         }
         $done = $db->streamStatementEnd($wholeLine, $line);
         $wholeLine .= $line;
         if (!$done) {
             $wholeLine .= ' ';
             $prompt = '    -> ';
             continue;
         }
         if ($useReadline) {
             # Delimiter is eated by streamStatementEnd, we add it
             # up in the history (bug 37020)
             readline_add_history($wholeLine . $db->getDelimiter());
             readline_write_history($historyFile);
         }
         try {
             $res = $db->query($wholeLine);
             $this->sqlPrintResult($res, $db);
             $prompt = $newPrompt;
             $wholeLine = '';
         } catch (DBQueryError $e) {
             $doDie = !Maintenance::posix_isatty(0);
             $this->error($e, $doDie);
         }
     }
     wfWaitForSlaves();
 }
Exemple #12
0
 /**
  * Ends this task peacefully
  */
 public function restInPeace()
 {
     // Do any deferred jobs
     DeferredUpdates::doUpdates('commit');
     // Execute a job from the queue
     $this->doJobs();
     // Log profiling data, e.g. in the database or UDP
     wfLogProfilingData();
     // Commit and close up!
     $factory = wfGetLBFactory();
     $factory->commitMasterChanges();
     $factory->shutdown();
     wfDebug("Request ended normally\n");
 }
Exemple #13
0
 /**
  * setWFVariables
  *
  * add all default variables into city_variables table
  *
  * @author Krzysztof Krzyzaniak <*****@*****.**>
  * @author Piotr Molski <*****@*****.**>
  * @access private
  *
  */
 private function setWFVariables()
 {
     // WF Variables containter
     $this->mWFSettingVars = array();
     $this->mWFSettingVars['wgSitename'] = $this->mNewWiki->sitename;
     $this->mWFSettingVars['wgLogo'] = self::DEFAULT_WIKI_LOGO;
     $this->mWFSettingVars['wgUploadPath'] = $this->mNewWiki->images_url;
     $this->mWFSettingVars['wgUploadDirectory'] = $this->mNewWiki->images_dir;
     $this->mWFSettingVars['wgDBname'] = $this->mNewWiki->dbname;
     $this->mWFSettingVars['wgLocalInterwiki'] = $this->mNewWiki->sitename;
     $this->mWFSettingVars['wgLanguageCode'] = $this->mNewWiki->language;
     $this->mWFSettingVars['wgServer'] = rtrim($this->mNewWiki->url, "/");
     $this->mWFSettingVars['wgEnableSectionEdit'] = true;
     $this->mWFSettingVars['wgEnableSwiftFileBackend'] = true;
     $this->mWFSettingVars['wgOasisLoadCommonCSS'] = true;
     if ($this->getInitialNjordExtValue()) {
         $this->mWFSettingVars['wgEnableNjordExt'] = true;
     }
     // rt#60223: colon allowed in sitename, breaks project namespace
     if (mb_strpos($this->mWFSettingVars['wgSitename'], ':') !== false) {
         $this->mWFSettingVars['wgMetaNamespace'] = str_replace(array(':', ' '), array('', '_'), $this->mWFSettingVars['wgSitename']);
     }
     if (self::ACTIVE_CLUSTER) {
         wfGetLBFactory()->sectionsByDB[$this->mNewWiki->dbname] = $this->mWFSettingVars['wgDBcluster'] = self::ACTIVE_CLUSTER;
     }
     $oRes = $this->mDBw->select("city_variables_pool", array("cv_id, cv_name"), array("cv_name in ('" . implode("', '", array_keys($this->mWFSettingVars)) . "')"), __METHOD__);
     $this->mWFVars = array();
     while ($oRow = $this->mDBw->fetchObject($oRes)) {
         $this->mWFVars[$oRow->cv_name] = $oRow->cv_id;
     }
     $this->mDBw->freeResult($oRes);
     foreach ($this->mWFSettingVars as $variable => $value) {
         /**
          * first, get id of variable
          */
         $cv_id = 0;
         if (isset($this->mWFVars[$variable])) {
             $cv_id = $this->mWFVars[$variable];
         }
         /**
          * then, insert value for wikia
          */
         if (!empty($cv_id)) {
             $this->mDBw->insert("city_variables", array("cv_value" => serialize($value), "cv_city_id" => $this->mNewWiki->city_id, "cv_variable_id" => $cv_id), __METHOD__);
         }
     }
 }
 /**
  * If there are any open database transactions, roll them back and log
  * the stack trace of the exception that should have been caught so the
  * transaction could be aborted properly.
  *
  * @since 1.23
  * @param Exception|Throwable $e
  */
 public static function rollbackMasterChangesAndLog($e)
 {
     $factory = wfGetLBFactory();
     if ($factory->hasMasterChanges()) {
         $logger = LoggerFactory::getInstance('Bug56269');
         $logger->warning('Exception thrown with an uncommited database transaction: ' . self::getLogMessage($e), self::getLogContext($e));
         $factory->rollbackMasterChanges(__METHOD__);
     }
 }
 /**
  * If there are any open database transactions, roll them back and log
  * the stack trace of the exception that should have been caught so the
  * transaction could be aborted properly.
  *
  * @since 1.23
  * @param Exception $e
  */
 public static function rollbackMasterChangesAndLog(Exception $e)
 {
     $factory = wfGetLBFactory();
     if ($factory->hasMasterChanges()) {
         wfDebugLog('Bug56269', 'Exception thrown with an uncommited database transaction: ' . MWExceptionHandler::getLogMessage($e) . "\n" . $e->getTraceAsString());
         $factory->rollbackMasterChanges();
     }
 }
Exemple #16
0
 public function execute()
 {
     // Get a DB handle (with this wiki's DB select) from the appropriate load balancer
     if ($this->hasOption('cluster')) {
         $lb = wfGetLBFactory()->getExternalLB($this->getOption('cluster'));
         $dbw = $lb->getConnection(DB_MASTER);
         // master for external LB
     } else {
         $dbw = wfGetDB(DB_MASTER);
         // master for primary LB for this wiki
     }
     if ($this->hasArg(0)) {
         $file = fopen($this->getArg(0), 'r');
         if (!$file) {
             $this->error("Unable to open input file", true);
         }
         $error = $dbw->sourceStream($file, false, array($this, 'sqlPrintResult'));
         if ($error !== true) {
             $this->error($error, true);
         } else {
             exit(0);
         }
     }
     $useReadline = function_exists('readline_add_history') && Maintenance::posix_isatty(0);
     if ($useReadline) {
         global $IP;
         $historyFile = isset($_ENV['HOME']) ? "{$_ENV['HOME']}/.mwsql_history" : "{$IP}/maintenance/.mwsql_history";
         readline_read_history($historyFile);
     }
     $wholeLine = '';
     $newPrompt = '> ';
     $prompt = $newPrompt;
     while (($line = Maintenance::readconsole($prompt)) !== false) {
         if (!$line) {
             # User simply pressed return key
             continue;
         }
         $done = $dbw->streamStatementEnd($wholeLine, $line);
         $wholeLine .= $line;
         if (!$done) {
             $wholeLine .= ' ';
             $prompt = '    -> ';
             continue;
         }
         if ($useReadline) {
             # Delimiter is eated by streamStatementEnd, we add it
             # up in the history (bug 37020)
             readline_add_history($wholeLine . $dbw->getDelimiter());
             readline_write_history($historyFile);
         }
         try {
             $res = $dbw->query($wholeLine);
             $this->sqlPrintResult($res, $dbw);
             $prompt = $newPrompt;
             $wholeLine = '';
         } catch (DBQueryError $e) {
             $doDie = !Maintenance::posix_isatty(0);
             $this->error($e, $doDie);
         }
     }
     wfWaitForSlaves();
 }
Exemple #17
0
}
if (strcmp("{$wgScriptPath}/api{$wgScriptExtension}", $url)) {
    wfHttpError(403, 'Forbidden', 'API must be accessed through the primary script entry point.');
    return;
}
// Verify that the API has not been disabled
if (!$wgEnableAPI) {
    echo 'MediaWiki API is not enabled for this site. Add the following line to your LocalSettings.php';
    echo '<pre><b>$wgEnableAPI=true;</b></pre>';
    die(1);
}
// So extensions can check whether they're running in API mode
define('MW_API', true);
// Set a dummy $wgTitle, because $wgTitle == null breaks various things
// In a perfect world this wouldn't be necessary
$wgTitle = Title::newFromText('API');
/* Construct an ApiMain with the arguments passed via the URL. What we get back
 * is some form of an ApiMain, possibly even one that produces an error message,
 * but we don't care here, as that is handled by the ctor.
 */
$processor = new ApiMain($wgRequest, $wgEnableWriteAPI);
// Process data & print results
$processor->execute();
// Execute any deferred updates
wfDoUpdates();
// Log what the user did, for book-keeping purposes.
wfProfileOut('api.php');
wfLogProfilingData();
// Shut down the database
wfGetLBFactory()->shutdown();
Exemple #18
0
 /**
  * @param int $index (DB_SLAVE/DB_MASTER)
  * @return DBConnRef
  */
 protected function getDB($index)
 {
     $lb = $this->cluster !== false ? wfGetLBFactory()->getExternalLB($this->cluster, $this->wiki) : wfGetLB($this->wiki);
     return $lb->getConnectionRef($index, array(), $this->wiki);
 }
Exemple #19
0
 /**
  * Ends this task peacefully
  */
 function restInPeace()
 {
     wfLogProfilingData();
     // Commit and close up!
     $factory = wfGetLBFactory();
     $factory->commitMasterChanges();
     $factory->shutdown();
     wfDebug("Request ended normally\n");
 }
 /**
  * Get a master connection to the logging DB
  *
  * @return DatabaseBase
  * @throws DBError
  */
 protected function getMasterDB()
 {
     if (!$this->dbw) {
         // Get a separate connection in autocommit mode
         $lb = wfGetLBFactory()->newMainLB();
         $this->dbw = $lb->getConnection(DB_MASTER, array(), $this->wiki);
         $this->dbw->clearFlag(DBO_TRX);
     }
     return $this->dbw;
 }
Exemple #21
0
 protected function prepareEnvironment()
 {
     global $wgCaches, $wgMemc;
     // Don't share DB or memcached connections
     wfGetLBFactory()->destroyInstance();
     $wgCaches = array();
     unset($wgMemc);
 }
Exemple #22
0
 /**
  * Issue a commit on all masters who are currently in a transaction and have
  * made changes to the database. It also supports sometimes waiting for the
  * local wiki's slaves to catch up. See the documentation for
  * $wgJobSerialCommitThreshold for more.
  *
  * @param Job $job
  * @throws DBError
  */
 private function commitMasterChanges(Job $job)
 {
     global $wgJobSerialCommitThreshold;
     $lb = wfGetLB(wfWikiID());
     if ($wgJobSerialCommitThreshold !== false) {
         // Generally, there is one master connection to the local DB
         $dbwSerial = $lb->getAnyOpenConnection($lb->getWriterIndex());
     } else {
         $dbwSerial = false;
     }
     if (!$dbwSerial || !$dbwSerial->namedLocksEnqueue() || $dbwSerial->pendingWriteQueryDuration() < $wgJobSerialCommitThreshold) {
         // Writes are all to foreign DBs, named locks don't form queues,
         // or $wgJobSerialCommitThreshold is not reached; commit changes now
         wfGetLBFactory()->commitMasterChanges();
         return;
     }
     $ms = intval(1000 * $dbwSerial->pendingWriteQueryDuration());
     $msg = $job->toString() . " COMMIT ENQUEUED [{$ms}ms of writes]";
     $this->logger->warning($msg);
     $this->debugCallback($msg);
     // Wait for an exclusive lock to commit
     if (!$dbwSerial->lock('jobrunner-serial-commit', __METHOD__, 30)) {
         // This will trigger a rollback in the main loop
         throw new DBError($dbwSerial, "Timed out waiting on commit queue.");
     }
     // Wait for the generic slave to catch up
     $pos = $lb->getMasterPos();
     if ($pos) {
         $lb->waitForOne($pos);
     }
     $fname = __METHOD__;
     // Re-ping all masters with transactions. This throws DBError if some
     // connection died while waiting on locks/slaves, triggering a rollback.
     wfGetLBFactory()->forEachLB(function (LoadBalancer $lb) use($fname) {
         $lb->forEachOpenConnection(function (IDatabase $conn) use($fname) {
             if ($conn->writesOrCallbacksPending()) {
                 $conn->query("SELECT 1", $fname);
             }
         });
     });
     // Actually commit the DB master changes
     wfGetLBFactory()->commitMasterChanges();
     // Release the lock
     $dbwSerial->unlock('jobrunner-serial-commit', __METHOD__);
 }
Exemple #23
0
/**
 *
 */
function wfSpecialExport($page = '')
{
    global $wgOut, $wgRequest, $wgSitename, $wgExportAllowListContributors;
    global $wgExportAllowHistory, $wgExportMaxHistory;
    $curonly = true;
    $doexport = false;
    if ($wgRequest->getCheck('addcat')) {
        $page = $wgRequest->getText('pages');
        $catname = $wgRequest->getText('catname');
        if ($catname !== '' && $catname !== NULL && $catname !== false) {
            $t = Title::makeTitleSafe(NS_MAIN, $catname);
            if ($t) {
                /**
                 * @fixme This can lead to hitting memory limit for very large
                 * categories. Ideally we would do the lookup synchronously
                 * during the export in a single query.
                 */
                $catpages = wfExportGetPagesFromCategory($t);
                if ($catpages) {
                    $page .= "\n" . implode("\n", $catpages);
                }
            }
        }
    } else {
        if ($wgRequest->wasPosted() && $page == '') {
            $page = $wgRequest->getText('pages');
            $curonly = $wgRequest->getCheck('curonly');
            $rawOffset = $wgRequest->getVal('offset');
            if ($rawOffset) {
                $offset = wfTimestamp(TS_MW, $rawOffset);
            } else {
                $offset = null;
            }
            $limit = $wgRequest->getInt('limit');
            $dir = $wgRequest->getVal('dir');
            $history = array('dir' => 'asc', 'offset' => false, 'limit' => $wgExportMaxHistory);
            $historyCheck = $wgRequest->getCheck('history');
            if ($curonly) {
                $history = WikiExporter::CURRENT;
            } elseif (!$historyCheck) {
                if ($limit > 0 && $limit < $wgExportMaxHistory) {
                    $history['limit'] = $limit;
                }
                if (!is_null($offset)) {
                    $history['offset'] = $offset;
                }
                if (strtolower($dir) == 'desc') {
                    $history['dir'] = 'desc';
                }
            }
            if ($page != '') {
                $doexport = true;
            }
        } else {
            // Default to current-only for GET requests
            $page = $wgRequest->getText('pages', $page);
            $historyCheck = $wgRequest->getCheck('history');
            if ($historyCheck) {
                $history = WikiExporter::FULL;
            } else {
                $history = WikiExporter::CURRENT;
            }
            if ($page != '') {
                $doexport = true;
            }
        }
    }
    if (!$wgExportAllowHistory) {
        // Override
        $history = WikiExporter::CURRENT;
    }
    $list_authors = $wgRequest->getCheck('listauthors');
    if (!$curonly || !$wgExportAllowListContributors) {
        $list_authors = false;
    }
    if ($doexport) {
        $wgOut->disable();
        // Cancel output buffering and gzipping if set
        // This should provide safer streaming for pages with history
        wfResetOutputBuffers();
        header("Content-type: application/xml; charset=utf-8");
        if ($wgRequest->getCheck('wpDownload')) {
            // Provide a sane filename suggestion
            $filename = urlencode($wgSitename . '-' . wfTimestampNow() . '.xml');
            $wgRequest->response()->header("Content-disposition: attachment;filename={$filename}");
        }
        /* Split up the input and look up linked pages */
        $inputPages = array_filter(explode("\n", $page), 'wfFilterPage');
        $pageSet = array_flip($inputPages);
        if ($wgRequest->getCheck('templates')) {
            $pageSet = wfExportGetTemplates($inputPages, $pageSet);
        }
        /*
        // Enable this when we can do something useful exporting/importing image information. :)
        if( $wgRequest->getCheck( 'images' ) ) {
        	$pageSet = wfExportGetImages( $inputPages, $pageSet );
        }
        */
        $pages = array_keys($pageSet);
        /* Ok, let's get to it... */
        if ($history == WikiExporter::CURRENT) {
            $lb = false;
            $db = wfGetDB(DB_SLAVE);
            $buffer = WikiExporter::BUFFER;
        } else {
            // Use an unbuffered query; histories may be very long!
            $lb = wfGetLBFactory()->newMainLB();
            $db = $lb->getConnection(DB_SLAVE);
            $buffer = WikiExporter::STREAM;
            // This might take a while... :D
            wfSuppressWarnings();
            set_time_limit(0);
            wfRestoreWarnings();
        }
        $exporter = new WikiExporter($db, $history, $buffer);
        $exporter->list_authors = $list_authors;
        $exporter->openStream();
        foreach ($pages as $page) {
            /*
            			if( $wgExportMaxHistory && !$curonly ) {
            				$title = Title::newFromText( $page );
            				if( $title ) {
            					$count = Revision::countByTitle( $db, $title );
            					if( $count > $wgExportMaxHistory ) {
            						wfDebug( __FUNCTION__ .
            							": Skipped $page, $count revisions too big\n" );
            						continue;
            					}
            				}
            			}*/
            #Bug 8824: Only export pages the user can read
            $title = Title::newFromText($page);
            if (is_null($title)) {
                continue;
            }
            #TODO: perhaps output an <error> tag or something.
            if (!$title->userCanRead()) {
                continue;
            }
            #TODO: perhaps output an <error> tag or something.
            $exporter->pageByTitle($title);
        }
        $exporter->closeStream();
        if ($lb) {
            $lb->closeAll();
        }
        return;
    }
    $self = SpecialPage::getTitleFor('Export');
    $wgOut->addHTML(wfMsgExt('exporttext', 'parse'));
    $form = Xml::openElement('form', array('method' => 'post', 'action' => $self->getLocalUrl('action=submit')));
    $form .= Xml::inputLabel(wfMsg('export-addcattext'), 'catname', 'catname', 40) . '&nbsp;';
    $form .= Xml::submitButton(wfMsg('export-addcat'), array('name' => 'addcat')) . '<br />';
    $form .= Xml::openElement('textarea', array('name' => 'pages', 'cols' => 40, 'rows' => 10));
    $form .= htmlspecialchars($page);
    $form .= Xml::closeElement('textarea');
    $form .= '<br />';
    if ($wgExportAllowHistory) {
        $form .= Xml::checkLabel(wfMsg('exportcuronly'), 'curonly', 'curonly', true) . '<br />';
    } else {
        $wgOut->addHTML(wfMsgExt('exportnohistory', 'parse'));
    }
    $form .= Xml::checkLabel(wfMsg('export-templates'), 'templates', 'wpExportTemplates', false) . '<br />';
    // Enable this when we can do something useful exporting/importing image information. :)
    //$form .= Xml::checkLabel( wfMsg( 'export-images' ), 'images', 'wpExportImages', false ) . '<br />';
    $form .= Xml::checkLabel(wfMsg('export-download'), 'wpDownload', 'wpDownload', true) . '<br />';
    $form .= Xml::submitButton(wfMsg('export-submit'), array('accesskey' => 's'));
    $form .= Xml::closeElement('form');
    $wgOut->addHTML($form);
}
Exemple #24
0
DeferredUpdates::doUpdates();
// Log what the user did, for book-keeping purposes.
$endtime = microtime(true);
wfProfileOut('api.php');
wfLogProfilingData();
// Log the request
if ($wgAPIRequestLog) {
    $items = array(wfTimestamp(TS_MW), $endtime - $starttime, $wgRequest->getIP(), $wgRequest->getHeader('User-agent'));
    $items[] = $wgRequest->wasPosted() ? 'POST' : 'GET';
    if ($processor) {
        try {
            $manager = $processor->getModuleManager();
            $module = $manager->getModule($wgRequest->getVal('action'), 'action');
        } catch (Exception $ex) {
            $module = null;
        }
        if (!$module || $module->mustBePosted()) {
            $items[] = "action=" . $wgRequest->getVal('action');
        } else {
            $items[] = wfArrayToCgi($wgRequest->getValues());
        }
    } else {
        $items[] = "failed in ApiBeforeMain";
    }
    wfErrorLog(implode(',', $items) . "\n", $wgAPIRequestLog);
    wfDebug("Logged API request to {$wgAPIRequestLog}\n");
}
// Shut down the database.  foo()->bar() syntax is not supported in PHP4: we won't ever actually
// get here to worry about whether this should be = or =&, but the file has to parse properly.
$lb = wfGetLBFactory();
$lb->shutdown();
 /**
  * Gets a DB master connection for the given external cluster name
  * @param $cluster string
  * @return DatabaseBase
  */
 function getExtDB($cluster)
 {
     $lb = wfGetLBFactory()->getExternalLB($cluster);
     return $lb->getConnection(DB_MASTER);
 }
Exemple #26
0
/**
 * Waits for the slaves to catch up to the master position
 *
 * Use this when updating very large numbers of rows, as in maintenance scripts,
 * to avoid causing too much lag. Of course, this is a no-op if there are no slaves.
 *
 * By default this waits on the main DB cluster of the current wiki.
 * If $cluster is set to "*" it will wait on all DB clusters, including
 * external ones. If the lag being waiting on is caused by the code that
 * does this check, it makes since to use $ifWritesSince, particularly if
 * cluster is "*", to avoid excess overhead.
 *
 * Never call this function after a big DB write that is still in a transaction.
 * This only makes sense after the possible lag inducing changes were committed.
 *
 * @param float|null $ifWritesSince Only wait if writes were done since this UNIX timestamp
 * @param string|bool $wiki Wiki identifier accepted by wfGetLB
 * @param string|bool $cluster Cluster name accepted by LBFactory. Default: false.
 * @param int|null $timeout Max wait time. Default: 1 day (cli), ~10 seconds (web)
 * @return bool Success (able to connect and no timeouts reached)
 */
function wfWaitForSlaves($ifWritesSince = null, $wiki = false, $cluster = false, $timeout = null)
{
    // B/C: first argument used to be "max seconds of lag"; ignore such values
    $ifWritesSince = $ifWritesSince > 1000000000.0 ? $ifWritesSince : null;
    if ($timeout === null) {
        $timeout = PHP_SAPI === 'cli' ? 86400 : 10;
    }
    // Figure out which clusters need to be checked
    /** @var LoadBalancer[] $lbs */
    $lbs = array();
    if ($cluster === '*') {
        wfGetLBFactory()->forEachLB(function (LoadBalancer $lb) use(&$lbs) {
            $lbs[] = $lb;
        });
    } elseif ($cluster !== false) {
        $lbs[] = wfGetLBFactory()->getExternalLB($cluster);
    } else {
        $lbs[] = wfGetLB($wiki);
    }
    // Get all the master positions of applicable DBs right now.
    // This can be faster since waiting on one cluster reduces the
    // time needed to wait on the next clusters.
    $masterPositions = array_fill(0, count($lbs), false);
    foreach ($lbs as $i => $lb) {
        if ($lb->getServerCount() <= 1) {
            // Bug 27975 - Don't try to wait for slaves if there are none
            // Prevents permission error when getting master position
            continue;
        } elseif ($ifWritesSince && $lb->lastMasterChangeTimestamp() < $ifWritesSince) {
            continue;
            // no writes since the last wait
        }
        $masterPositions[$i] = $lb->getMasterPos();
    }
    $ok = true;
    foreach ($lbs as $i => $lb) {
        if ($masterPositions[$i]) {
            // The DBMS may not support getMasterPos() or the whole
            // load balancer might be fake (e.g. $wgAllDBsAreLocalhost).
            $ok = $lb->waitForAll($masterPositions[$i], $timeout) && $ok;
        }
    }
    return $ok;
}
 /**
  * @param WikiPage $page
  * @param Revision $newRev
  * @throws MWException
  */
 protected function notifyUpdatesForRevision(WikiPage $page, Revision $newRev)
 {
     $config = RequestContext::getMain()->getConfig();
     $title = $page->getTitle();
     // Get the new revision
     if (!$newRev->getContent()) {
         return;
         // deleted?
     }
     // Get the prior revision (the same for null edits)
     if ($newRev->getParentId()) {
         $oldRev = Revision::newFromId($newRev->getParentId(), Revision::READ_LATEST);
         if (!$oldRev->getContent()) {
             return;
             // deleted?
         }
     } else {
         $oldRev = null;
     }
     // Parse the new revision and get the categories
     $categoryChanges = $this->getExplicitCategoriesChanges($title, $newRev, $oldRev);
     list($categoryInserts, $categoryDeletes) = $categoryChanges;
     if (!$categoryInserts && !$categoryDeletes) {
         return;
         // nothing to do
     }
     $dbw = wfGetDB(DB_MASTER);
     $catMembChange = new CategoryMembershipChange($title, $newRev);
     $catMembChange->checkTemplateLinks();
     $batchSize = $config->get('UpdateRowsPerQuery');
     $insertCount = 0;
     foreach ($categoryInserts as $categoryName) {
         $categoryTitle = Title::makeTitle(NS_CATEGORY, $categoryName);
         $catMembChange->triggerCategoryAddedNotification($categoryTitle);
         if ($insertCount++ && $insertCount % $batchSize == 0) {
             $dbw->commit(__METHOD__, 'flush');
             wfGetLBFactory()->waitForReplication();
         }
     }
     foreach ($categoryDeletes as $categoryName) {
         $categoryTitle = Title::makeTitle(NS_CATEGORY, $categoryName);
         $catMembChange->triggerCategoryRemovedNotification($categoryTitle);
         if ($insertCount++ && $insertCount++ % $batchSize == 0) {
             $dbw->commit(__METHOD__, 'flush');
             wfGetLBFactory()->waitForReplication();
         }
     }
 }
Exemple #28
0
    require_once "{$IP}/vendor/autoload.php";
}
if (defined('MW_CONFIG_CALLBACK')) {
    # Use a callback function to configure MediaWiki
    call_user_func(MW_CONFIG_CALLBACK);
} else {
    // Require the configuration (probably LocalSettings.php)
    require $maintenance->loadSettings();
}
if ($maintenance->getDbType() === Maintenance::DB_NONE) {
    if ($wgLocalisationCacheConf['storeClass'] === false && ($wgLocalisationCacheConf['store'] == 'db' || $wgLocalisationCacheConf['store'] == 'detect' && !$wgCacheDirectory)) {
        $wgLocalisationCacheConf['storeClass'] = 'LCStoreNull';
    }
}
$maintenance->finalSetup();
// Some last includes
require_once "{$IP}/includes/Setup.php";
// Initialize main config instance
$maintenance->setConfig(ConfigFactory::getDefaultInstance()->makeConfig('main'));
// Do the work
$maintenance->execute();
// Potentially debug globals
$maintenance->globals();
// Perform deferred updates.
DeferredUpdates::doUpdates();
// log profiling info
wfLogProfilingData();
// Commit and close up!
$factory = wfGetLBFactory();
$factory->commitMasterChanges('doMaintenance');
$factory->shutdown();
Exemple #29
0
	/**
	 * Removes non-existing links from pages from pagelinks, imagelinks,
	 * categorylinks, templatelinks and externallinks tables.
	 *
	 * @param $maxLag
	 * @param $batchSize The size of deletion batches
	 *
	 * @author Merlijn van Deen <*****@*****.**>
	 */
	private function deleteLinksFromNonexistent( $maxLag = 0, $batchSize = 100 ) {
		wfWaitForSlaves( $maxLag );

		$dbw = wfGetDB( DB_MASTER );

		$lb = wfGetLBFactory()->newMainLB();
		$dbr = $lb->getConnection( DB_SLAVE );
		$dbr->bufferResults( false );

		$linksTables = array( // table name => page_id field
			'pagelinks' => 'pl_from',
			'imagelinks' => 'il_from',
			'categorylinks' => 'cl_from',
			'templatelinks' => 'tl_from',
			'externallinks' => 'el_from',
		);

		foreach ( $linksTables as $table => $field ) {
			$this->output( "Retrieving illegal entries from $table... " );

			// SELECT DISTINCT( $field ) FROM $table LEFT JOIN page ON $field=page_id WHERE page_id IS NULL;
			$results = $dbr->select( array( $table, 'page' ),
						  $field,
						  array('page_id' => null ),
						  __METHOD__,
						  'DISTINCT',
						  array( 'page' => array( 'LEFT JOIN', "$field=page_id"))
			);

			$counter = 0;
			$list = array();
			$this->output( "0.." );

			foreach( $results as $row ) {
				$counter++;
				$list[] = $row->$field;
				if ( ( $counter % $batchSize ) == 0 ) {
					wfWaitForSlaves(5);
					$dbw->delete( $table, array( $field => $list ), __METHOD__ );

					$this->output( $counter . ".." );
					$list = array();
				}
			}
			$this->output( $counter );
			if (count($list) > 0) {
				$dbw->delete( $table, array( $field => $list ), __METHOD__ );
			}
			$this->output( "\n" );
		}
		$lb->closeAll();
	}
Exemple #30
0
 protected function &getDB($cluster, $groups = [], $wiki = false)
 {
     $lb = wfGetLBFactory()->getExternalLB($cluster);
     return $lb->getConnection(DB_REPLICA);
 }