function setupMicroID() { global $wgOut, $wgRequest, $wgHooks; $wgHooks['UserToggles'][] = 'MicroIDUserToggle'; $action = $wgRequest->getText('action', 'view'); if ($action == 'view') { $title = $wgRequest->getText('title'); if (!isset($title) || strlen($title) == 0) { # If there's no title, and Cache404 is in use, check using its stuff if (defined('CACHE404_VERSION')) { if ($_SERVER['REDIRECT_STATUS'] == 404) { $url = getRedirectUrl($_SERVER); if (isset($url)) { $title = cacheUrlToTitle($url); } } } else { $title = wfMsg('mainpage'); } } $nt = Title::newFromText($title); // If the page being viewed is a user page... if ($nt && $nt->getNamespace() == NS_USER && strpos($nt->getText(), '/') === false) { // If the user qualifies... wfDebug("MicroID: on User page " . $nt->getText() . "\n"); $user = User::newFromName($nt->getText()); if ($user && $user->getID() != 0 && $user->getEmail() && $user->isEmailConfirmed() && $user->getOption('microid')) { wfDebug("MicroID: on User page " . $nt->getText() . "\n"); $wgOut->addMeta('microid', MakeMicroID($user->getEmail(), $nt->getFullURL())); } } } }
function debug($msg) { wfDebug("{$msg}\n"); if ($this->debugLog) { $this->logToFile($msg, $this->debugLog); } }
/** * Constructor * @param $titleObj Title object that the diff is associated with * @param $old Integer old ID we want to show and diff with. * @param $new String either 'prev' or 'next'. * @param $rcid Integer ??? FIXME (default 0) * @param $refreshCache boolean If set, refreshes the diff cache * @param $unhide boolean If set, allow viewing deleted revs */ function __construct($titleObj = null, $old = 0, $new = 0, $rcid = 0, $refreshCache = false, $unhide = false) { if ($titleObj) { $this->mTitle = $titleObj; } else { global $wgTitle; $this->mTitle = $wgTitle; // @TODO: get rid of this } wfDebug("DifferenceEngine old '{$old}' new '{$new}' rcid '{$rcid}'\n"); if ('prev' === $new) { # Show diff between revision $old and the previous one. # Get previous one from DB. $this->mNewid = intval($old); $this->mOldid = $this->mTitle->getPreviousRevisionID($this->mNewid); } elseif ('next' === $new) { # Show diff between revision $old and the next one. # Get next one from DB. $this->mOldid = intval($old); $this->mNewid = $this->mTitle->getNextRevisionID($this->mOldid); if (false === $this->mNewid) { # if no result, NewId points to the newest old revision. The only newer # revision is cur, which is "0". $this->mNewid = 0; } } else { $this->mOldid = intval($old); $this->mNewid = intval($new); wfRunHooks('NewDifferenceEngine', array(&$titleObj, &$this->mOldid, &$this->mNewid, $old, $new)); } $this->mRcidMarkPatrolled = intval($rcid); # force it to be an integer $this->mRefreshCache = $refreshCache; $this->unhide = $unhide; }
/** * autoload - take a class name and attempt to load it * * @param string $className Name of class we're looking for. * @return bool Returning false is important on failure as * it allows Zend to try and look in other registered autoloaders * as well. */ static function autoload($className) { global $wgAutoloadClasses, $wgAutoloadLocalClasses; if (isset($wgAutoloadLocalClasses[$className])) { $filename = $wgAutoloadLocalClasses[$className]; } elseif (isset($wgAutoloadClasses[$className])) { $filename = $wgAutoloadClasses[$className]; } else { # Try a different capitalisation # The case can sometimes be wrong when unserializing PHP 4 objects $filename = false; $lowerClass = strtolower($className); foreach ($wgAutoloadLocalClasses as $class2 => $file2) { if (strtolower($class2) == $lowerClass) { $filename = $file2; } } if (!$filename) { if (function_exists('wfDebug')) { wfDebug("Class {$className} not found; skipped loading"); } # Give up return false; } } # Make an absolute path, this improves performance by avoiding some stat calls if (substr($filename, 0, 1) != '/' && substr($filename, 1, 1) != ':') { global $IP; $filename = "{$IP}/{$filename}"; } require $filename; return true; }
function profileOut($functionname) { $memory = memory_get_usage(); $time = $this->getTime(); global $wgDebugProfiling, $wgDebugFunctionEntry; if ($wgDebugFunctionEntry && function_exists('wfDebug')) { wfDebug(str_repeat(' ', count($this->mWorkStack) - 1) . 'Exiting ' . $functionname . "\n"); } $bit = array_pop($this->mWorkStack); if (!$bit) { wfDebug("Profiling error, !\$bit: {$functionname}\n"); } else { //if ($wgDebugProfiling) { if ($functionname == 'close') { $message = "Profile section ended by close(): {$bit[0]}\n"; wfDebug($message); $this->mStack[] = array($message, 0, 0, 0); } elseif ($bit[0] != $functionname) { $message = "Profiling error: in({$bit[0]}), out({$functionname})\n"; wfDebug($message); $this->mStack[] = array($message, 0, 0, 0); } //} $bit[] = $time; $bit[] = $memory; $this->mStack[] = $bit; } }
/** * Return a clause with the list of disambiguation templates. * This function was copied verbatim from specials/SpecialDisambiguations.php */ function disambiguation_templates( $dbr ) { $dMsgText = wfMsgForContent('disambiguationspage'); $linkBatch = new LinkBatch; # If the text can be treated as a title, use it verbatim. # Otherwise, pull the titles from the links table $dp = Title::newFromText($dMsgText); if( $dp ) { if($dp->getNamespace() != NS_TEMPLATE) { # FIXME we assume the disambiguation message is a template but # the page can potentially be from another namespace :/ wfDebug("Mediawiki:disambiguationspage message does not refer to a template!\n"); } $linkBatch->addObj( $dp ); } else { # Get all the templates linked from the Mediawiki:Disambiguationspage $disPageObj = Title::makeTitleSafe( NS_MEDIAWIKI, 'disambiguationspage' ); $res = $dbr->select( array('pagelinks', 'page'), 'pl_title', array('page_id = pl_from', 'pl_namespace' => NS_TEMPLATE, 'page_namespace' => $disPageObj->getNamespace(), 'page_title' => $disPageObj->getDBkey()), __METHOD__ ); foreach ( $res as $row ) { $linkBatch->addObj( Title::makeTitle( NS_TEMPLATE, $row->pl_title )); } } return $linkBatch->constructSet( 'tl', $dbr ); }
/** * Default parser tag renderer */ public static function jsonTagRender($input, array $args, Parser $parser, PPFrame $frame) { global $wgJsonData; $wgJsonData = new JsonData($frame->title); $json = $input; $goodschema = true; try { $schematext = $wgJsonData->getSchemaText(); } catch (JsonDataException $e) { $schematext = $wgJsonData->readJsonFromPredefined('openschema'); wfDebug(__METHOD__ . ": " . htmlspecialchars($e->getMessage()) . "\n"); $goodschema = false; } $schematitletext = $wgJsonData->getSchemaTitleText(); if ($goodschema && !is_null($schematitletext)) { // Register dependency in templatelinks, using technique (and a // little code) from http://www.mediawiki.org/wiki/Manual:Tag_extensions $schematitle = Title::newFromText($schematitletext); $schemarev = Revision::newFromTitle($schematitle); $schemaid = $schemarev ? $schemarev->getPage() : 0; $parser->mOutput->addTemplate($schematitle, $schemaid, $schemarev ? $schemarev->getId() : 0); } $data = json_decode($json, true); $schema = json_decode($schematext, true); $rootjson = new JsonTreeRef($data); $rootjson->attachSchema($schema); $markup = JsonDataMarkup::getMarkup($rootjson, 0); return $parser->recursiveTagParse($markup, $frame); }
/** * Hook: ParserBeforeStrip * @param $parser Parser * @param $text * @param $state * @return bool */ public static function renderTagPage($parser, &$text, $state) { $title = $parser->getTitle(); if (strpos($text, '<translate>') !== false) { try { $parse = TranslatablePage::newFromText($parser->getTitle(), $text)->getParse(); $text = $parse->getTranslationPageText(null); } catch (TPException $e) { // Show ugly preview without processed <translate> tags wfDebug('TPException caught; expected'); } } // Set display title $page = TranslatablePage::isTranslationPage($title); if (!$page) { return true; } list(, $code) = TranslateUtils::figureMessage($title->getText()); $name = $page->getPageDisplayTitle($code); if ($name) { $name = $parser->recursivePreprocess($name); $parser->getOutput()->setDisplayTitle($name); } // Disable edit section links $parser->getOptions()->setEditSection(false); return true; }
static function purge($urlArr) { $caller = self::getPurgeCaller(); wfDebug("Purging backtrace: " . wfGetAllCallers(false) . "\n"); // Filter urls into buckets based on service backend $buckets = array_reduce($urlArr, function ($carry, $item) use($caller) { global $wgPurgeVignetteUsingSurrogateKeys; wfDebug("Purging URL {$item} from {$caller} via Celery\n"); if (isset($wgPurgeVignetteUsingSurrogateKeys) && VignetteRequest::isVignetteUrl($item)) { $carry['vignette'][] = $item; } elseif (strstr($item, 'MercuryApi') !== false) { $carry['mercury'][] = $item; $carry['mediawiki'][] = $item; // TODO: we can remove this when mercury is only using internal cache } else { $carry['mediawiki'][] = $item; } return $carry; }, array('mediawiki' => [], 'vignette' => [], 'mercury' => [])); if (empty(CeleryPurge::$buckets)) { CeleryPurge::$buckets = $buckets; } else { CeleryPurge::$buckets = array_merge_recursive(CeleryPurge::$buckets, $buckets); } }
/** Open an SQLite database and return a resource handle to it * NOTE: only $dbName is used, the other parameters are irrelevant for SQLite databases */ function open($server, $user, $pass, $dbName) { $this->mConn = false; if ($dbName) { $file = $this->mDatabaseFile; try { if ($this->mFlags & DBO_PERSISTENT) { $this->mConn = new PDO("sqlite:{$file}", $user, $pass, array(PDO::ATTR_PERSISTENT => true)); } else { $this->mConn = new PDO("sqlite:{$file}", $user, $pass); } } catch (PDOException $e) { $err = $e->getMessage(); } if ($this->mConn === false) { wfDebug("DB connection error: {$err}\n"); if (!$this->mFailFunction) { throw new DBConnectionError($this, $err); } else { return false; } } $this->mOpened = $this->mConn; # set error codes only, don't raise exceptions $this->mConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); } return $this->mConn; }
/** * Add the old versions of the image to the batch */ function addOlds() { $archiveBase = 'archive'; $this->olds = array(); $this->oldCount = 0; $result = $this->db->select('oldimage', array('oi_archive_name', 'oi_deleted'), array('oi_name' => $this->oldName), __METHOD__); while ($row = $this->db->fetchObject($result)) { $oldName = $row->oi_archive_name; $bits = explode('!', $oldName, 2); if (count($bits) != 2) { wfDebug("Invalid old file name: {$oldName} \n"); continue; } list($timestamp, $filename) = $bits; if ($this->oldName != $filename) { wfDebug("Invalid old file name: {$oldName} \n"); continue; } $this->oldCount++; // Do we want to add those to oldCount? if ($row->oi_deleted & File::DELETED_FILE) { continue; } $this->olds[] = array("{$archiveBase}/{$this->oldHash}{$oldName}", "{$archiveBase}/{$this->newHash}{$timestamp}!{$this->newName}"); } $this->db->freeResult($result); }
/** * Constructor * @param $titleObj Title object that the diff is associated with * @param $old Integer: old ID we want to show and diff with. * @param $new String: either 'prev' or 'next'. * @param $rcid Integer: ??? FIXME (default 0) * @param $refreshCache boolean If set, refreshes the diff cache */ function DifferenceEngine($titleObj = null, $old = 0, $new = 0, $rcid = 0, $refreshCache = false) { $this->mTitle = $titleObj; wfDebug("DifferenceEngine old '{$old}' new '{$new}' rcid '{$rcid}'\n"); if ('prev' === $new) { # Show diff between revision $old and the previous one. # Get previous one from DB. # $this->mNewid = intval($old); $this->mOldid = $this->mTitle->getPreviousRevisionID($this->mNewid); } elseif ('next' === $new) { # Show diff between revision $old and the previous one. # Get previous one from DB. # $this->mOldid = intval($old); $this->mNewid = $this->mTitle->getNextRevisionID($this->mOldid); if (false === $this->mNewid) { # if no result, NewId points to the newest old revision. The only newer # revision is cur, which is "0". $this->mNewid = 0; } } else { $this->mOldid = intval($old); $this->mNewid = intval($new); } $this->mRcidMarkPatrolled = intval($rcid); # force it to be an integer $this->mRefreshCache = $refreshCache; }
/** * Delete files in the deleted directory if they are not referenced in the * filearchive table. This needs to be done in the repo because it needs to * interleave database locks with file operations, which is potentially a * remote operation. * @return FileRepoStatus */ function cleanupDeletedBatch($storageKeys) { $root = $this->getZonePath('deleted'); $dbw = $this->getMasterDB(); $status = $this->newGood(); $storageKeys = array_unique($storageKeys); foreach ($storageKeys as $key) { $hashPath = $this->getDeletedHashPath($key); $path = "{$root}/{$hashPath}{$key}"; $dbw->begin(); $inuse = $dbw->selectField('filearchive', '1', array('fa_storage_group' => 'deleted', 'fa_storage_key' => $key), __METHOD__, array('FOR UPDATE')); if (!$inuse) { wfDebug(__METHOD__ . ": deleting {$key}\n"); if (!@unlink($path)) { $status->error('undelete-cleanup-error', $path); $status->failCount++; } } else { wfDebug(__METHOD__ . ": {$key} still in use\n"); $status->successCount++; } $dbw->commit(); } return $status; }
private function sleep() { wfProfileIn(__METHOD__); wfDebug(sprintf("%s: sleeping for %d ms\n", __CLASS__, $this->mDelay)); usleep($this->mDelay * 1000); wfProfileOut(__METHOD__); }
function renderToolTip($input, $argv, &$parser) { $text = 'see tooltip'; $xoffset = 0; $yoffset = 0; foreach ($argv as $key => $value) { switch ($key) { case 'text': $text = $value; break; case 'x': $xoffset = intval($value); break; case 'y': $yoffset = intval($value); break; default: wfDebug(__METHOD__ . ": Requested '{$key} ==> {$value}'\n"); break; } } $output = ''; if ($input != '') { $tooltipid = uniqid('tooltipid'); $parentid = uniqid('parentid'); $output .= "<span id='{$tooltipid}' class='xstooltip'>" . $parser->unstrip($parser->recursiveTagParse($input), $parser->mStripState) . "</span>"; $output .= "<span id='{$parentid}' class='xstooltip_body' onmouseover=\"xstooltip_show('{$tooltipid}', '{$parentid}', {$xoffset}, {$yoffset});\" onmouseout=\"xstooltip_hide('{$tooltipid}');\">" . $parser->unstrip($parser->recursiveTagParse($text), $parser->mStripState) . "</span>"; } return $output; }
/** * Load time units localized for a particular language. Helper function for getUnits. * * @param string $code The language to return the list in * @return array an associative array of time unit codes and localized time units */ private static function loadLanguage($code) { if (!isset(self::$cache[$code])) { /* Load override for wrong or missing entries in cldr */ $override = __DIR__ . '/LocalNames/' . self::getOverrideFileName($code); if (Language::isValidBuiltInCode($code) && file_exists($override)) { $timeUnits = false; require $override; if (is_array($timeUnits)) { self::$cache[$code] = $timeUnits; } } $filename = __DIR__ . '/CldrNames/' . self::getFileName($code); if (Language::isValidBuiltInCode($code) && file_exists($filename)) { $timeUnits = false; require $filename; if (is_array($timeUnits)) { if (isset(self::$cache[$code])) { // Add to existing list of localized time units self::$cache[$code] = self::$cache[$code] + $timeUnits; } else { // No list exists, so create it self::$cache[$code] = $timeUnits; } } } else { wfDebug(__METHOD__ . ": Unable to load time units for {$filename}\n"); } if (!isset(self::$cache[$code])) { self::$cache[$code] = array(); } } return self::$cache[$code]; }
/** * Delete files in the deleted directory if they are not referenced in the * filearchive table. This needs to be done in the repo because it needs to * interleave database locks with file operations, which is potentially a * remote operation. * * @param $storageKeys array * * @return FileRepoStatus */ function cleanupDeletedBatch($storageKeys) { $backend = $this->backend; // convenience $root = $this->getZonePath('deleted'); $dbw = $this->getMasterDB(); $status = $this->newGood(); $storageKeys = array_unique($storageKeys); foreach ($storageKeys as $key) { $hashPath = $this->getDeletedHashPath($key); $path = "{$root}/{$hashPath}{$key}"; $dbw->begin(); // Check for usage in deleted/hidden files and pre-emptively // lock the key to avoid any future use until we are finished. $deleted = $this->deletedFileHasKey($key, 'lock'); $hidden = $this->hiddenFileHasKey($key, 'lock'); if (!$deleted && !$hidden) { // not in use now wfDebug(__METHOD__ . ": deleting {$key}\n"); $op = array('op' => 'delete', 'src' => $path); if (!$backend->doOperation($op)->isOK()) { $status->error('undelete-cleanup-error', $path); $status->failCount++; } } else { wfDebug(__METHOD__ . ": {$key} still in use\n"); $status->successCount++; } $dbw->commit(); } return $status; }
/** * Returns the gender for given username. * @param string $username or User: username * @param string $caller the calling method * @return String */ public function getGenderOf( $username, $caller = '' ) { global $wgUser; if ( $username instanceof User ) { $username = $username->getName(); } $username = self::normalizeUsername( $username ); if ( !isset( $this->cache[$username] ) ) { if ( $this->misses >= $this->missLimit && $wgUser->getName() !== $username ) { if ( $this->misses === $this->missLimit ) { $this->misses++; wfDebug( __METHOD__ . ": too many misses, returning default onwards\n" ); } return $this->getDefault(); } else { $this->misses++; $this->doQuery( $username, $caller ); } } /* Undefined if there is a valid username which for some reason doesn't * exist in the database. */ return isset( $this->cache[$username] ) ? $this->cache[$username] : $this->getDefault(); }
static function loadAndLazyInit() { wfDebug(__METHOD__ . ": reading site_stats from slave\n"); $row = self::doLoad(wfGetDB(DB_SLAVE)); if (!self::isSane($row)) { // Might have just been initialized during this request? Underflow? wfDebug(__METHOD__ . ": site_stats damaged or missing on slave\n"); $row = self::doLoad(wfGetDB(DB_MASTER)); } if (!self::isSane($row)) { // Normally the site_stats table is initialized at install time. // Some manual construction scenarios may leave the table empty or // broken, however, for instance when importing from a dump into a // clean schema with mwdumper. wfDebug(__METHOD__ . ": initializing damaged or missing site_stats\n"); global $IP; require_once "{$IP}/maintenance/initStats.inc"; ob_start(); wfInitStats(); ob_end_clean(); $row = self::doLoad(wfGetDB(DB_MASTER)); } if (!self::isSane($row)) { wfDebug(__METHOD__ . ": site_stats persistently nonsensical o_O\n"); } return $row; }
function parseQuery($filteredText, $fulltext) { global $wgContLang; $lc = SearchEngine::legalSearchChars(); $searchon = ''; $this->searchTerms = array(); # FIXME: This doesn't handle parenthetical expressions. if (preg_match_all('/([-+<>~]?)(([' . $lc . ']+)(\\*?)|"[^"]*")/', $filteredText, $m, PREG_SET_ORDER)) { foreach ($m as $terms) { if ($searchon !== '') { $searchon .= ' '; } if ($this->strictMatching && $terms[1] == '') { $terms[1] = '+'; } $searchon .= $terms[1] . $wgContLang->stripForSearch($terms[2]); if (!empty($terms[3])) { $regexp = preg_quote($terms[3], '/'); if ($terms[4]) { $regexp .= "[0-9A-Za-z_]+"; } } else { $regexp = preg_quote(str_replace('"', '', $terms[2]), '/'); } $this->searchTerms[] = $regexp; } wfDebug("Would search with '{$searchon}'\n"); wfDebug("Match with /\\b" . implode('\\b|\\b', $this->searchTerms) . "\\b/\n"); } else { wfDebug("Can't understand search query '{$this->filteredText}'\n"); } $searchon = preg_replace('/(\\s+)/', '&', $searchon); $searchon = $this->db->strencode($searchon); return $searchon; }
function sendEmail(&$u, &$content) { global $wgServer; wfLoadExtensionMessages('ThumbsEmailNotifications'); $email = $u->getEmail(); $userText = $u->getName(); $semi_rand = md5(time()); $mime_boundary = "==MULTIPART_BOUNDARY_{$semi_rand}"; $mime_boundary_header = chr(34) . $mime_boundary . chr(34); $userPageLink = self::getUserPageLink($userText); $html_text = wfMsg('tn_email_html', wfGetPad(''), $userPageLink, $content); $plain_text = wfMsg('tn_email_plain', $userText, $u->getTalkPage()->getFullURL()); $body = "This is a multi-part message in MIME format.\n\n--{$mime_boundary}\nContent-Type: text/plain; charset=us-ascii\nContent-Transfer-Encoding: 7bit\n\n{$plain_text}\n\n--{$mime_boundary}\nContent-Type: text/html; charset=us-ascii\nContent-Transfer-Encoding: 7bit\n\n{$html_text}"; $from = new MailAddress(wfMsg('aen_from')); $subject = "Congratulations! You just got a thumbs up"; $isDev = false; if (strpos($_SERVER['HOSTNAME'], "wikidiy.com") !== false || strpos($wgServer, "wikidiy.com") !== false) { wfDebug("AuthorEmailNotification in dev not notifying: TO: " . $userText . ",FROM: {$from_name}\n"); $isDev = true; $subject = "[FROM DEV] {$subject}"; } if (!$isDev) { $to = new MailAddress($email); UserMailer::send($to, $from, $subject, $body, null, "multipart/alternative;\n" . " boundary=" . $mime_boundary_header); } // send one to our test email account for debugging /* $to = new MailAddress ('*****@*****.**'); UserMailer::send($to, $from, $subject, $body, null, "multipart/alternative;\n" . " boundary=" . $mime_boundary_header) ; */ return true; }
function wfWikiaAbortAutoblock($autoblockip, $block) { if (!IP::isPublic($autoblockip)) { wfDebug("IP {$autoblockip} was prevented from being autoblocked by internal IP autoblock"); return false; } }
public function execute($params = false) { $sEditLinkText = wfMessage('bs-widget-edit')->text(); $oTitle = Title::makeTitle(NS_USER, RequestContext::getMain()->getUser()->getName() . '/Widgetbar'); $sEditLink = Linker::link($oTitle, Html::rawElement('span', array(), $sEditLinkText), array('id' => 'bs-widgetbar-edit', 'class' => 'icon-pencil clearfix'), array('action' => 'edit', 'preload' => '')); $aOut = array(); $aOut[] = '<div id="bs-widget-container" >'; $aOut[] = ' <div class="icon-plus" id="bs-widget-tab" title="' . wfMessage('bs-widget-container-tooltip')->text() . '" tabindex="100">[+/-]</div>'; $aOut[] = ' <div id="bs-flyout">'; $aOut[] = ' <h4 id="bs-flyout-heading">' . wfMessage('bs-widget-flyout-heading')->text() . '</h4>'; $aOut[] = ' <div id="bs-flyout-content">'; $aOut[] = ' <div id="bs-flyout-content-widgets">'; $aOut[] = ' <h4 id="bs-flyout-content-widgets-header">' . wfMessage("bs-widget-flyout-heading")->plain() . $sEditLink . '</h4>'; foreach ($this->_mWidgets as $oWidgetView) { if ($oWidgetView instanceof ViewWidget) { $aOut[] = $oWidgetView->execute(); } else { wfDebug(__METHOD__ . ': Invalid widget.'); } } $aOut[] = ' </div>'; $aOut[] = ' </div>'; $aOut[] = ' </div>'; $aOut[] = '</div>'; return implode("\n", $aOut); }
function execute($par) { /** * Some satellite ISPs use broken precaching schemes that log people out straight after * they're logged in (bug 17790). Luckily, there's a way to detect such requests. */ if (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '&') !== false) { wfDebug("Special:Userlogout request {$_SERVER['REQUEST_URI']} looks suspicious, denying.\n"); throw new HttpError(400, wfMessage('suspicious-userlogout'), wfMessage('loginerror')); } $this->setHeaders(); $this->outputHeader(); $user = $this->getUser(); $oldName = $user->getName(); $user->logout(); $out = $this->getOutput(); $out->addWikiMsg('logouttext'); // Hook. $injected_html = ''; wfRunHooks('UserLogoutComplete', array(&$user, &$injected_html, $oldName)); $out->addHTML($injected_html); $mReturnTo = $this->getRequest()->getVal('returnto'); $mReturnToQuery = $this->getRequest()->getVal('returntoquery'); $title = Title::newFromText($mReturnTo); if (!empty($title)) { $mResolvedReturnTo = strtolower(array_shift(SpecialPageFactory::resolveAlias($title->getDBKey()))); if (in_array($mResolvedReturnTo, array('userlogout', 'signup', 'connect'))) { $titleObj = Title::newMainPage(); $mReturnTo = $titleObj->getText(); $mReturnToQuery = ''; } } $out->returnToMain(false, $mReturnTo, $mReturnToQuery); }
function execute($par) { /** * Some satellite ISPs use broken precaching schemes that log people out straight after * they're logged in (bug 17790). Luckily, there's a way to detect such requests. */ if (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '&') !== false) { wfDebug("Special:Userlogout request {$_SERVER['REQUEST_URI']} looks suspicious, denying.\n"); throw new HttpError(400, $this->msg('suspicious-userlogout'), $this->msg('loginerror')); } $this->setHeaders(); $this->outputHeader(); // Make sure it's possible to log out $session = MediaWiki\Session\SessionManager::getGlobalSession(); if (!$session->canSetUser()) { throw new ErrorPageError('cannotlogoutnow-title', 'cannotlogoutnow-text', [$session->getProvider()->describe(RequestContext::getMain()->getLanguage())]); } $user = $this->getUser(); $oldName = $user->getName(); $user->logout(); $loginURL = SpecialPage::getTitleFor('Userlogin')->getFullURL($this->getRequest()->getValues('returnto', 'returntoquery')); $out = $this->getOutput(); $out->addWikiMsg('logouttext', $loginURL); // Hook. $injected_html = ''; Hooks::run('UserLogoutComplete', [&$user, &$injected_html, $oldName]); $out->addHTML($injected_html); $out->returnToMain(); }
function getQueryInfo() { $dbr = wfGetDB(DB_SLAVE); $dMsgText = wfMsgForContent('disambiguationspage'); $linkBatch = new LinkBatch(); # If the text can be treated as a title, use it verbatim. # Otherwise, pull the titles from the links table $dp = Title::newFromText($dMsgText); if ($dp) { if ($dp->getNamespace() != NS_TEMPLATE) { # @todo FIXME: We assume the disambiguation message is a template but # the page can potentially be from another namespace :/ wfDebug("Mediawiki:disambiguationspage message does not refer to a template!\n"); } $linkBatch->addObj($dp); } else { # Get all the templates linked from the Mediawiki:Disambiguationspage $disPageObj = Title::makeTitleSafe(NS_MEDIAWIKI, 'disambiguationspage'); $res = $dbr->select(array('pagelinks', 'page'), 'pl_title', array('page_id = pl_from', 'pl_namespace' => NS_TEMPLATE, 'page_namespace' => $disPageObj->getNamespace(), 'page_title' => $disPageObj->getDBkey()), __METHOD__); foreach ($res as $row) { $linkBatch->addObj(Title::makeTitle(NS_TEMPLATE, $row->pl_title)); } } $set = $linkBatch->constructSet('tl', $dbr); if ($set === false) { # We must always return a valid SQL query, but this way # the DB will always quickly return an empty result $set = 'FALSE'; wfDebug("Mediawiki:disambiguationspage message does not link to any templates!\n"); } // @todo FIXME: What are pagelinks and p2 doing here? return array('tables' => array('templatelinks', 'p1' => 'page', 'pagelinks', 'p2' => 'page'), 'fields' => array('p1.page_namespace AS namespace', 'p1.page_title AS title', 'pl_from AS value'), 'conds' => array($set, 'p1.page_id = tl_from', 'pl_namespace = p1.page_namespace', 'pl_title = p1.page_title', 'p2.page_id = pl_from', 'p2.page_namespace' => MWNamespace::getContentNamespaces())); }
function getSQL() { $dbr =& wfGetDB(DB_SLAVE); list($page, $pagelinks, $templatelinks) = $dbr->tableNamesN('page', 'pagelinks', 'templatelinks'); $dMsgText = wfMsgForContent('disambiguationspage'); $linkBatch = new LinkBatch(); # If the text can be treated as a title, use it verbatim. # Otherwise, pull the titles from the links table $dp = Title::newFromText($dMsgText); if ($dp) { if ($dp->getNamespace() != NS_TEMPLATE) { # FIXME we assume the disambiguation message is a template but # the page can potentially be from another namespace :/ wfDebug("Mediawiki:disambiguationspage message does not refer to a template!\n"); } $linkBatch->addObj($dp); } else { # Get all the templates linked from the Mediawiki:Disambiguationspage $disPageObj = $this->getDisambiguationPageObj(); $res = $dbr->select(array('pagelinks', 'page'), 'pl_title', array('page_id = pl_from', 'pl_namespace' => NS_TEMPLATE, 'page_namespace' => $disPageObj->getNamespace(), 'page_title' => $disPageObj->getDBkey()), 'DisambiguationsPage::getSQL'); while ($row = $dbr->fetchObject($res)) { $linkBatch->addObj(Title::makeTitle(NS_TEMPLATE, $row->pl_title)); } $dbr->freeResult($res); } $set = $linkBatch->constructSet('lb.tl', $dbr); if ($set === false) { $set = 'FALSE'; # We must always return a valid sql query, but this way DB will always quicly return an empty result wfDebug("Mediawiki:disambiguationspage message does not link to any templates!\n"); } $sql = "SELECT 'Disambiguations' AS \"type\", pb.page_namespace AS namespace," . " pb.page_title AS title, la.pl_from AS value" . " FROM {$templatelinks} AS lb, {$page} AS pb, {$pagelinks} AS la, {$page} AS pa" . " WHERE {$set}" . ' AND pa.page_id = la.pl_from' . ' AND pa.page_namespace = ' . NS_MAIN . ' AND pb.page_id = lb.tl_from' . ' AND pb.page_namespace = la.pl_namespace' . ' AND pb.page_title = la.pl_title' . ' ORDER BY lb.tl_namespace, lb.tl_title'; return $sql; }
function getRemoteTextSources(){ global $wgMemc; // Use descriptionCacheExpiry as our expire for timed text tracks info if ( $this->file->repo->descriptionCacheExpiry > 0 ) { wfDebug("Attempting to get text tracks from cache..."); $key = $this->file->repo->getLocalCacheKey( 'RemoteTextTracks', 'url', $this->file->getName() ); $obj = $wgMemc->get($key); if ($obj) { wfDebug("success!\n"); return $obj; } wfDebug("miss\n"); } wfDebug("Get text tracks from remote api \n"); $query = $this->getTextPagesQuery(); // Error in getting timed text namespace return empty array; if( $query === false ){ return array(); } $data = $this->file->repo->fetchImageQuery( $query ); if ( $data && $this->file->repo->descriptionCacheExpiry > 0 ) { $wgMemc->set( $key, $data, $this->file->repo->descriptionCacheExpiry ); } return $this->getTextTracksFromData( $data ); }
/** * Delete files in the deleted directory if they are not referenced in the * filearchive table. This needs to be done in the repo because it needs to * interleave database locks with file operations, which is potentially a * remote operation. * @return FileRepoStatus */ function cleanupDeletedBatch($storageKeys) { $root = $this->getZonePath('deleted'); $dbw = $this->getMasterDB(); $status = $this->newGood(); $storageKeys = array_unique($storageKeys); foreach ($storageKeys as $key) { $hashPath = $this->getDeletedHashPath($key); $path = "{$root}/{$hashPath}{$key}"; $dbw->begin(); $inuse = $dbw->selectField('filearchive', '1', array('fa_storage_group' => 'deleted', 'fa_storage_key' => $key), __METHOD__, array('FOR UPDATE')); if (!$inuse) { $sha1 = substr($key, 0, strcspn($key, '.')); $ext = substr($key, strcspn($key, '.') + 1); $ext = File::normalizeExtension($ext); $inuse = $dbw->selectField('oldimage', '1', array('oi_sha1' => $sha1, 'oi_archive_name ' . $dbw->buildLike($dbw->anyString(), ".{$ext}"), $dbw->bitAnd('oi_deleted', File::DELETED_FILE) => File::DELETED_FILE), __METHOD__, array('FOR UPDATE')); } if (!$inuse) { wfDebug(__METHOD__ . ": deleting {$key}\n"); if (!@unlink($path)) { $status->error('undelete-cleanup-error', $path); $status->failCount++; } } else { wfDebug(__METHOD__ . ": {$key} still in use\n"); $status->successCount++; } $dbw->commit(); } return $status; }
/** * Load country names localized for a particular language. * * @param string $code The language to return the list in * @return an associative array of country codes and localized country names */ private static function loadLanguage($code) { if (!isset(self::$cache[$code])) { wfProfileIn(__METHOD__ . '-recache'); /* Load override for wrong or missing entries in cldr */ $override = dirname(__FILE__) . '/LocalNames/' . self::getOverrideFileName($code); if (Language::isValidBuiltInCode($code) && file_exists($override)) { $countryNames = false; require $override; if (is_array($countryNames)) { self::$cache[$code] = $countryNames; } } $filename = dirname(__FILE__) . '/CldrNames/' . self::getFileName($code); if (Language::isValidBuiltInCode($code) && file_exists($filename)) { $countryNames = false; require $filename; if (is_array($countryNames)) { if (isset(self::$cache[$code])) { // Add to existing list of localized country names self::$cache[$code] = self::$cache[$code] + $countryNames; } else { // No list exists, so create it self::$cache[$code] = $countryNames; } } } else { wfDebug(__METHOD__ . ": Unable to load country names for {$filename}\n"); } wfProfileOut(__METHOD__ . '-recache'); } return isset(self::$cache[$code]) ? self::$cache[$code] : array(); }