public function setup()
 {
     global $wgOut, $wgExtensionAssetsPath, $IP, $wgResourceModules, $wgAutoloadClasses, $wgHooks, $wgParser, $wgJQUploadFileMagic;
     // If attachments allowed in this page, add the module into the page
     if ($title = array_key_exists('title', $_GET) ? Title::newFromText($_GET['title']) : false) {
         $this->id = $title->getArticleID();
     }
     // Set up the #file parser-function
     $wgParser->setFunctionHook($wgJQUploadFileMagic, array($this, 'expandFile'), SFH_NO_HASH);
     // Allow overriding of the file ID
     Hooks::run('jQueryUploadSetId', array($title, &$this->id));
     // If attachments allowed in this page, add the module into the page
     $attach = is_object($title) && $this->id && !$title->isRedirect() && !array_key_exists('action', $_REQUEST) && $title->getNamespace() != 6;
     if ($attach) {
         Hooks::run('jQueryUploadAddAttachLink', array($title, &$attach));
     }
     if ($attach) {
         $this->head();
         $wgHooks['BeforePageDisplay'][] = $this;
     }
     // Add the extensions own js
     $path = $wgExtensionAssetsPath . str_replace("{$IP}/extensions", '', dirname($wgAutoloadClasses[__CLASS__]));
     $wgResourceModules['ext.jqueryupload']['remoteExtPath'] = $path;
     $wgOut->addModules('ext.jqueryupload');
     $wgOut->addStyle("{$path}/styles/jqueryupload.css");
 }
예제 #2
0
 /**
  * @since 1.16.3
  * @throws MWException
  * @param string $collationName
  * @return Collation
  */
 public static function factory($collationName)
 {
     switch ($collationName) {
         case 'uppercase':
             return new UppercaseCollation();
         case 'identity':
             return new IdentityCollation();
         case 'uca-default':
             return new IcuCollation('root');
         case 'xx-uca-ckb':
             return new CollationCkb();
         case 'xx-uca-et':
             return new CollationEt();
         default:
             $match = [];
             if (preg_match('/^uca-([a-z@=-]+)$/', $collationName, $match)) {
                 return new IcuCollation($match[1]);
             }
             # Provide a mechanism for extensions to hook in.
             $collationObject = null;
             Hooks::run('Collation::factory', [$collationName, &$collationObject]);
             if ($collationObject instanceof Collation) {
                 return $collationObject;
             }
             // If all else fails...
             throw new MWException(__METHOD__ . ": unknown collation type \"{$collationName}\"");
     }
 }
예제 #3
0
 /**
  * @param array $params
  * @param Config $mainConfig
  * @return array
  */
 public static function applyDefaultParameters(array $params, Config $mainConfig)
 {
     $logger = LoggerFactory::getInstance('Mime');
     $params += ['typeFile' => $mainConfig->get('MimeTypeFile'), 'infoFile' => $mainConfig->get('MimeInfoFile'), 'xmlTypes' => $mainConfig->get('XMLMimeTypes'), 'guessCallback' => function ($mimeAnalyzer, &$head, &$tail, $file, &$mime) use($logger) {
         // Also test DjVu
         $deja = new DjVuImage($file);
         if ($deja->isValid()) {
             $logger->info(__METHOD__ . ": detected {$file} as image/vnd.djvu\n");
             $mime = 'image/vnd.djvu';
             return;
         }
         // Some strings by reference for performance - assuming well-behaved hooks
         Hooks::run('MimeMagicGuessFromContent', [$mimeAnalyzer, &$head, &$tail, $file, &$mime]);
     }, 'extCallback' => function ($mimeAnalyzer, $ext, &$mime) {
         // Media handling extensions can improve the MIME detected
         Hooks::run('MimeMagicImproveFromExtension', [$mimeAnalyzer, $ext, &$mime]);
     }, 'initCallback' => function ($mimeAnalyzer) {
         // Allow media handling extensions adding MIME-types and MIME-info
         Hooks::run('MimeMagicInit', [$mimeAnalyzer]);
     }, 'logger' => $logger];
     if ($params['infoFile'] === 'includes/mime.info') {
         $params['infoFile'] = __DIR__ . "/libs/mime/mime.info";
     }
     if ($params['typeFile'] === 'includes/mime.types') {
         $params['typeFile'] = __DIR__ . "/libs/mime/mime.types";
     }
     $detectorCmd = $mainConfig->get('MimeDetectorCommand');
     if ($detectorCmd) {
         $params['detectCallback'] = function ($file) use($detectorCmd) {
             return wfShellExec("{$detectorCmd} " . wfEscapeShellArg($file));
         };
     }
     return $params;
 }
 /**
  * @param ResourceLoaderContext $context
  * @return array
  */
 protected function getConfigSettings($context)
 {
     $hash = $context->getHash();
     if (isset($this->configVars[$hash])) {
         return $this->configVars[$hash];
     }
     global $wgContLang;
     $mainPage = Title::newMainPage();
     /**
      * Namespace related preparation
      * - wgNamespaceIds: Key-value pairs of all localized, canonical and aliases for namespaces.
      * - wgCaseSensitiveNamespaces: Array of namespaces that are case-sensitive.
      */
     $namespaceIds = $wgContLang->getNamespaceIds();
     $caseSensitiveNamespaces = array();
     foreach (MWNamespace::getCanonicalNamespaces() as $index => $name) {
         $namespaceIds[$wgContLang->lc($name)] = $index;
         if (!MWNamespace::isCapitalized($index)) {
             $caseSensitiveNamespaces[] = $index;
         }
     }
     $conf = $this->getConfig();
     // Build list of variables
     $vars = array('wgLoadScript' => wfScript('load'), 'debug' => $context->getDebug(), 'skin' => $context->getSkin(), 'stylepath' => $conf->get('StylePath'), 'wgUrlProtocols' => wfUrlProtocols(), 'wgArticlePath' => $conf->get('ArticlePath'), 'wgScriptPath' => $conf->get('ScriptPath'), 'wgScriptExtension' => '.php', 'wgScript' => wfScript(), 'wgSearchType' => $conf->get('SearchType'), 'wgVariantArticlePath' => $conf->get('VariantArticlePath'), 'wgActionPaths' => (object) $conf->get('ActionPaths'), 'wgServer' => $conf->get('Server'), 'wgServerName' => $conf->get('ServerName'), 'wgUserLanguage' => $context->getLanguage(), 'wgContentLanguage' => $wgContLang->getCode(), 'wgTranslateNumerals' => $conf->get('TranslateNumerals'), 'wgVersion' => $conf->get('Version'), 'wgEnableAPI' => $conf->get('EnableAPI'), 'wgEnableWriteAPI' => $conf->get('EnableWriteAPI'), 'wgMainPageTitle' => $mainPage->getPrefixedText(), 'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(), 'wgNamespaceIds' => $namespaceIds, 'wgContentNamespaces' => MWNamespace::getContentNamespaces(), 'wgSiteName' => $conf->get('Sitename'), 'wgDBname' => $conf->get('DBname'), 'wgExtraSignatureNamespaces' => $conf->get('ExtraSignatureNamespaces'), 'wgAvailableSkins' => Skin::getSkinNames(), 'wgExtensionAssetsPath' => $conf->get('ExtensionAssetsPath'), 'wgCookiePrefix' => $conf->get('CookiePrefix'), 'wgCookieDomain' => $conf->get('CookieDomain'), 'wgCookiePath' => $conf->get('CookiePath'), 'wgCookieExpiration' => $conf->get('CookieExpiration'), 'wgResourceLoaderMaxQueryLength' => $conf->get('ResourceLoaderMaxQueryLength'), 'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces, 'wgLegalTitleChars' => Title::convertByteClassToUnicodeClass(Title::legalChars()), 'wgResourceLoaderStorageVersion' => $conf->get('ResourceLoaderStorageVersion'), 'wgResourceLoaderStorageEnabled' => $conf->get('ResourceLoaderStorageEnabled'), 'wgResourceLoaderLegacyModules' => self::getLegacyModules(), 'wgForeignUploadTargets' => $conf->get('ForeignUploadTargets'), 'wgEnableUploads' => $conf->get('EnableUploads'));
     Hooks::run('ResourceLoaderGetConfigVars', array(&$vars));
     $this->configVars[$hash] = $vars;
     return $this->configVars[$hash];
 }
 public function execute()
 {
     if (!$this->getUser()->isLoggedIn()) {
         $this->dieUsage('Must be logged in to remove authentication data', 'notloggedin');
     }
     $params = $this->extractRequestParams();
     $manager = AuthManager::singleton();
     // Check security-sensitive operation status
     ApiAuthManagerHelper::newForModule($this)->securitySensitiveOperation($this->operation);
     // Fetch the request. No need to load from the request, so don't use
     // ApiAuthManagerHelper's method.
     $blacklist = $this->authAction === AuthManager::ACTION_REMOVE ? array_flip($this->getConfig()->get('RemoveCredentialsBlacklist')) : [];
     $reqs = array_filter($manager->getAuthenticationRequests($this->authAction, $this->getUser()), function ($req) use($params, $blacklist) {
         return $req->getUniqueId() === $params['request'] && !isset($blacklist[get_class($req)]);
     });
     if (count($reqs) !== 1) {
         $this->dieUsage('Failed to create change request', 'badrequest');
     }
     $req = reset($reqs);
     // Perform the removal
     $status = $manager->allowsAuthenticationDataChange($req, true);
     Hooks::run('ChangeAuthenticationDataAudit', [$req, $status]);
     if (!$status->isGood()) {
         $this->dieStatus($status);
     }
     $manager->changeAuthenticationData($req);
     $this->getResult()->addValue(null, $this->getModuleName(), ['status' => 'success']);
 }
예제 #6
0
 /**
  * Show a return link or redirect to it.
  * Extensions can change where the link should point or inject content into the page
  * (which will change it from redirect to link mode).
  *
  * @param string $type One of the following:
  *    - error: display a return to link ignoring $wgRedirectOnLogin
  *    - success: display a return to link using $wgRedirectOnLogin if needed
  *    - successredirect: send an HTTP redirect using $wgRedirectOnLogin if needed
  * @param string $returnTo
  * @param array|string $returnToQuery
  * @param bool $stickHTTPS Keep redirect link on HTTPS
  */
 public function showReturnToPage($type, $returnTo = '', $returnToQuery = '', $stickHTTPS = false)
 {
     global $wgRedirectOnLogin, $wgSecureLogin;
     if ($type !== 'error' && $wgRedirectOnLogin !== null) {
         $returnTo = $wgRedirectOnLogin;
         $returnToQuery = [];
     } elseif (is_string($returnToQuery)) {
         $returnToQuery = wfCgiToArray($returnToQuery);
     }
     // Allow modification of redirect behavior
     Hooks::run('PostLoginRedirect', [&$returnTo, &$returnToQuery, &$type]);
     $returnToTitle = Title::newFromText($returnTo) ?: Title::newMainPage();
     if ($wgSecureLogin && !$stickHTTPS) {
         $options = ['http'];
         $proto = PROTO_HTTP;
     } elseif ($wgSecureLogin) {
         $options = ['https'];
         $proto = PROTO_HTTPS;
     } else {
         $options = [];
         $proto = PROTO_RELATIVE;
     }
     if ($type === 'successredirect') {
         $redirectUrl = $returnToTitle->getFullURL($returnToQuery, false, $proto);
         $this->getOutput()->redirect($redirectUrl);
     } else {
         $this->getOutput()->addReturnTo($returnToTitle, $returnToQuery, null, $options);
     }
 }
 /**
  * Transforms content to be mobile friendly version.
  * Filters out various elements and runs the MobileFormatter.
  * @param OutputPage $out
  * @param string $mode mobile mode, i.e. stable or beta
  *
  * @return string
  */
 public static function DOMParse(OutputPage $out, $text = null, $isBeta = false)
 {
     $html = $text ? $text : $out->getHTML();
     $context = MobileContext::singleton();
     $formatter = MobileFormatter::newFromContext($context, $html);
     Hooks::run('MobileFrontendBeforeDOM', array($context, $formatter));
     $title = $out->getTitle();
     $isSpecialPage = $title->isSpecialPage();
     $formatter->enableExpandableSections($out->canUseWikiPage() && $out->getWikiPage()->getContentModel() == CONTENT_MODEL_WIKITEXT && array_search($title->getNamespace(), $context->getMFConfig()->get('MFNamespacesWithoutCollapsibleSections')) === false && $context->getRequest()->getText('action', 'view') == 'view');
     if ($context->getContentTransformations()) {
         // Remove images if they're disabled from special pages, but don't transform otherwise
         $formatter->filterContent(!$isSpecialPage);
     }
     $contentHtml = $formatter->getText();
     // If the page is a user page which has not been created, then let the
     // user know about it with pretty graphics and different texts depending
     // on whether the user is the owner of the page or not.
     if ($isBeta && $title->inNamespace(NS_USER) && !$title->isSubpage()) {
         $pageUserId = User::idFromName($title->getText());
         if ($pageUserId && !$title->exists()) {
             $pageUser = User::newFromId($pageUserId);
             $contentHtml = ExtMobileFrontend::getUserPageContent($out, $pageUser);
         }
     }
     return $contentHtml;
 }
 public function execute()
 {
     if (!class_exists('CentralAuthUser')) {
         $this->error("CentralAuth isn't enabled on this wiki\n", 1);
     }
     $username = $this->getArg(0);
     $user = User::newFromName($username);
     if ($user === false) {
         $this->error("'{$username}' is an invalid username\n", 1);
     }
     // Normalize username
     $username = $user->getName();
     if ($user->getId()) {
         $this->error("User '{$username}' already exists\n", 1);
     } else {
         global $wgAuth;
         $central = CentralAuthUser::getInstance($user);
         if (!$central->exists()) {
             $this->error("No such global user: '******'\n", 1);
         }
         $user->loadDefaults($username);
         $user->addToDatabase();
         $wgAuth->initUser($user, true);
         $wgAuth->updateUser($user);
         # Notify hooks (e.g. Newuserlog)
         Hooks::run('AuthPluginAutoCreate', array($user));
         # Update user count
         $ssUpdate = new SiteStatsUpdate(0, 0, 0, 0, 1);
         $ssUpdate->doUpdate();
         $this->output("User '{$username}' created\n");
     }
 }
예제 #9
0
 /**
  * Format a line using the old system (aka without any javascript).
  *
  * @param RecentChange $rc Passed by reference
  * @param bool $watched (default false)
  * @param int $linenumber (default null)
  *
  * @return string|bool
  */
 public function recentChangesLine(&$rc, $watched = false, $linenumber = null)
 {
     $classes = array();
     // use mw-line-even/mw-line-odd class only if linenumber is given (feature from bug 14468)
     if ($linenumber) {
         if ($linenumber & 1) {
             $classes[] = 'mw-line-odd';
         } else {
             $classes[] = 'mw-line-even';
         }
     }
     // Indicate watched status on the line to allow for more
     // comprehensive styling.
     $classes[] = $watched && $rc->mAttribs['rc_timestamp'] >= $watched ? 'mw-changeslist-line-watched' : 'mw-changeslist-line-not-watched';
     $html = $this->formatChangeLine($rc, $classes, $watched);
     if ($this->watchlist) {
         $classes[] = Sanitizer::escapeClass('watchlist-' . $rc->mAttribs['rc_namespace'] . '-' . $rc->mAttribs['rc_title']);
     }
     if (!Hooks::run('OldChangesListRecentChangesLine', array(&$this, &$html, $rc, &$classes))) {
         return false;
     }
     $dateheader = '';
     // $html now contains only <li>...</li>, for hooks' convenience.
     $this->insertDateHeader($dateheader, $rc->mAttribs['rc_timestamp']);
     return "{$dateheader}<li class=\"" . implode(' ', $classes) . "\">" . $html . "</li>\n";
 }
예제 #10
0
 public function execute($par)
 {
     $this->setHeaders();
     $this->getOutput()->addModuleStyles('mediawiki.special');
     $this->edits = SiteStats::edits();
     $this->good = SiteStats::articles();
     $this->images = SiteStats::images();
     $this->total = SiteStats::pages();
     $this->users = SiteStats::users();
     $this->activeUsers = SiteStats::activeUsers();
     $this->hook = '';
     $text = Xml::openElement('table', ['class' => 'wikitable mw-statistics-table']);
     # Statistic - pages
     $text .= $this->getPageStats();
     # Statistic - edits
     $text .= $this->getEditStats();
     # Statistic - users
     $text .= $this->getUserStats();
     # Statistic - usergroups
     $text .= $this->getGroupStats();
     # Statistic - other
     $extraStats = [];
     if (Hooks::run('SpecialStatsAddExtra', [&$extraStats, $this->getContext()])) {
         $text .= $this->getOtherStats($extraStats);
     }
     $text .= Xml::closeElement('table');
     # Customizable footer
     $footer = $this->msg('statistics-footer');
     if (!$footer->isBlank()) {
         $text .= "\n" . $footer->parse();
     }
     $this->getOutput()->addHTML($text);
 }
예제 #11
0
 /**
  * @param string|number|null|bool $sectionId
  * @param Content $with
  * @param string $sectionTitle
  *
  * @throws MWException
  * @return Content
  *
  * @see Content::replaceSection()
  */
 public function replaceSection($sectionId, Content $with, $sectionTitle = '')
 {
     $myModelId = $this->getModel();
     $sectionModelId = $with->getModel();
     if ($sectionModelId != $myModelId) {
         throw new MWException("Incompatible content model for section: " . "document uses {$myModelId} but " . "section uses {$sectionModelId}.");
     }
     $oldtext = $this->getNativeData();
     $text = $with->getNativeData();
     if (strval($sectionId) === '') {
         return $with;
         # XXX: copy first?
     }
     if ($sectionId === 'new') {
         # Inserting a new section
         $subject = $sectionTitle ? wfMessage('newsectionheaderdefaultlevel')->rawParams($sectionTitle)->inContentLanguage()->text() . "\n\n" : '';
         if (Hooks::run('PlaceNewSection', array($this, $oldtext, $subject, &$text))) {
             $text = strlen(trim($oldtext)) > 0 ? "{$oldtext}\n\n{$subject}{$text}" : "{$subject}{$text}";
         }
     } else {
         # Replacing an existing section; roll out the big guns
         global $wgParser;
         $text = $wgParser->replaceSection($oldtext, $sectionId, $text);
     }
     $newContent = new static($text);
     return $newContent;
 }
예제 #12
0
 /**
  * Loads skin and user CSS files.
  * @param OutputPage $out
  */
 function setupSkinUserCss(OutputPage $out)
 {
     parent::setupSkinUserCss($out);
     $styles = array('mediawiki.skinning.interface', 'skins.vector.styles');
     Hooks::run('SkinVectorStyleModules', array($this, &$styles));
     $out->addModuleStyles($styles);
 }
예제 #13
0
 public function __construct()
 {
     parent::__construct();
     $paths = [];
     // Autodiscover extension unit tests
     $registry = ExtensionRegistry::getInstance();
     foreach ($registry->getAllThings() as $info) {
         $paths[] = dirname($info['path']) . '/tests/phpunit';
     }
     // Extensions can return a list of files or directories
     Hooks::run('UnitTestsList', [&$paths]);
     foreach (array_unique($paths) as $path) {
         if (is_dir($path)) {
             // If the path is a directory, search for test cases.
             // @since 1.24
             $suffixes = ['Test.php'];
             $fileIterator = new File_Iterator_Facade();
             $matchingFiles = $fileIterator->getFilesAsArray($path, $suffixes);
             $this->addTestFiles($matchingFiles);
         } elseif (file_exists($path)) {
             // Add a single test case or suite class
             $this->addTestFile($path);
         }
     }
     if (!$paths) {
         $this->addTest(new DummyExtensionsTest('testNothing'));
     }
 }
예제 #14
0
 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'], '&amp;') !== 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();
 }
예제 #15
0
 private function getTokenTypes()
 {
     // If we're in a mode that breaks the same-origin policy, no tokens can
     // be obtained
     if ($this->lacksSameOriginSecurity()) {
         return [];
     }
     static $types = null;
     if ($types) {
         return $types;
     }
     $types = ['patrol' => ['ApiQueryRecentChanges', 'getPatrolToken']];
     $names = ['edit', 'delete', 'protect', 'move', 'block', 'unblock', 'email', 'import', 'watch', 'options'];
     foreach ($names as $name) {
         $types[$name] = ['ApiQueryInfo', 'get' . ucfirst($name) . 'Token'];
     }
     Hooks::run('ApiTokensGetTokenTypes', [&$types]);
     // For forwards-compat, copy any token types from ApiQueryTokens that
     // we don't already have something for.
     $user = $this->getUser();
     $request = $this->getRequest();
     foreach (ApiQueryTokens::getTokenTypeSalts() as $name => $salt) {
         if (!isset($types[$name])) {
             $types[$name] = function () use($salt, $user, $request) {
                 return ApiQueryTokens::getToken($user, $request->getSession(), $salt)->toString();
             };
         }
     }
     ksort($types);
     return $types;
 }
예제 #16
0
 protected function setup($par)
 {
     // Options
     $opts = new FormOptions();
     $this->opts = $opts;
     // bind
     $opts->add('hideliu', false);
     $opts->add('hidepatrolled', $this->getUser()->getBoolOption('newpageshidepatrolled'));
     $opts->add('hidebots', false);
     $opts->add('hideredirs', true);
     $opts->add('limit', $this->getUser()->getIntOption('rclimit'));
     $opts->add('offset', '');
     $opts->add('namespace', '0');
     $opts->add('username', '');
     $opts->add('feed', '');
     $opts->add('tagfilter', '');
     $opts->add('invert', false);
     $this->customFilters = [];
     Hooks::run('SpecialNewPagesFilters', [$this, &$this->customFilters]);
     foreach ($this->customFilters as $key => $params) {
         $opts->add($key, $params['default']);
     }
     // Set values
     $opts->fetchValuesFromRequest($this->getRequest());
     if ($par) {
         $this->parseParams($par);
     }
     // Validate
     $opts->validateIntBounds('limit', 0, 5000);
 }
예제 #17
0
 function getQueryInfo()
 {
     $count = $this->getConfig()->get('WantedPagesThreshold') - 1;
     $query = ['tables' => ['pagelinks', 'pg1' => 'page', 'pg2' => 'page'], 'fields' => ['namespace' => 'pl_namespace', 'title' => 'pl_title', 'value' => 'COUNT(*)'], 'conds' => ['pg1.page_namespace IS NULL', "pl_namespace NOT IN ( '" . NS_USER . "', '" . NS_USER_TALK . "' )", "pg2.page_namespace != '" . NS_MEDIAWIKI . "'"], 'options' => ['HAVING' => ["COUNT(*) > {$count}", "COUNT(*) > SUM(pg2.page_is_redirect)"], 'GROUP BY' => ['pl_namespace', 'pl_title']], 'join_conds' => ['pg1' => ['LEFT JOIN', ['pg1.page_namespace = pl_namespace', 'pg1.page_title = pl_title']], 'pg2' => ['LEFT JOIN', 'pg2.page_id = pl_from']]];
     // Replacement for the WantedPages::getSQL hook
     Hooks::run('WantedPages::getQueryInfo', [&$this, &$query]);
     return $query;
 }
예제 #18
0
 public function execute()
 {
     $user = $this->getUser();
     $oldName = $user->getName();
     $user->logout();
     // Give extensions to do something after user logout
     $injected_html = '';
     Hooks::run('UserLogoutComplete', array(&$user, &$injected_html, $oldName));
 }
예제 #19
0
 function getQueryInfo()
 {
     $tables = ['page', 'pagelinks', 'templatelinks'];
     $conds = ['pl_namespace IS NULL', 'page_namespace' => MWNamespace::getContentNamespaces(), 'page_is_redirect' => 0, 'tl_namespace IS NULL'];
     $joinConds = ['pagelinks' => ['LEFT JOIN', ['pl_namespace = page_namespace', 'pl_title = page_title']], 'templatelinks' => ['LEFT JOIN', ['tl_namespace = page_namespace', 'tl_title = page_title']]];
     // Allow extensions to modify the query
     Hooks::run('LonelyPagesQuery', [&$tables, &$conds, &$joinConds]);
     return ['tables' => $tables, 'fields' => ['namespace' => 'page_namespace', 'title' => 'page_title', 'value' => 'page_title'], 'conds' => $conds, 'join_conds' => $joinConds];
 }
예제 #20
0
 function getQueryInfo()
 {
     $tables = array('page', 'pagelinks', 'templatelinks');
     $conds = array('pl_namespace IS NULL', 'page_namespace' => MWNamespace::getContentNamespaces(), 'page_is_redirect' => 0, 'tl_namespace IS NULL');
     $joinConds = array('pagelinks' => array('LEFT JOIN', array('pl_namespace = page_namespace', 'pl_title = page_title')), 'templatelinks' => array('LEFT JOIN', array('tl_namespace = page_namespace', 'tl_title = page_title')));
     // Allow extensions to modify the query
     Hooks::run('LonelyPagesQuery', array(&$tables, &$conds, &$joinConds));
     return array('tables' => $tables, 'fields' => array('namespace' => 'page_namespace', 'title' => 'page_title', 'value' => 'page_title'), 'conds' => $conds, 'join_conds' => $joinConds);
 }
 /**
  * Start render the page in template
  */
 public function execute()
 {
     $title = $this->getSkin()->getTitle();
     $this->isSpecialPage = $title->isSpecialPage();
     $this->isSpecialMobileMenuPage = $this->isSpecialPage && $title->equals(SpecialPage::getTitleFor('MobileMenu'));
     $this->isMainPage = $title->isMainPage();
     Hooks::run('MinervaPreRender', array($this));
     $this->render($this->data);
 }
예제 #22
0
 public function getQueryInfo()
 {
     $tables = ['page'];
     $conds = ['page_namespace' => MWNamespace::getContentNamespaces(), 'page_is_redirect' => 0];
     $joinConds = [];
     $options = ['USE INDEX' => ['page' => 'page_redirect_namespace_len']];
     // Allow extensions to modify the query
     Hooks::run('ShortPagesQuery', [&$tables, &$conds, &$joinConds, &$options]);
     return ['tables' => $tables, 'fields' => ['namespace' => 'page_namespace', 'title' => 'page_title', 'value' => 'page_len'], 'conds' => $conds, 'join_conds' => $joinConds, 'options' => $options];
 }
예제 #23
0
 /**
  * @param int $trials
  * @return string
  */
 private function benchHooks($trials = 10)
 {
     $start = microtime(true);
     for ($i = 0; $i < $trials; $i++) {
         Hooks::run('Test');
     }
     $delta = microtime(true) - $start;
     $pertrial = $delta / $trials;
     return sprintf("Took %6.3fms", $pertrial * 1000);
 }
 public function getData()
 {
     $translation = null;
     $title = $this->handle->getTitle();
     $translation = TranslateUtils::getMessageContent($this->handle->getKey(), $this->handle->getCode(), $title->getNamespace());
     Hooks::run('TranslatePrefillTranslation', array(&$translation, $this->handle));
     $fuzzy = MessageHandle::hasFuzzyString($translation) || $this->handle->isFuzzy();
     $translation = str_replace(TRANSLATE_FUZZY, '', $translation);
     return array('language' => $this->handle->getCode(), 'fuzzy' => $fuzzy, 'value' => $translation);
 }
예제 #25
0
 /**
  * Get a list of query page classes and their associated special pages,
  * for periodic updates.
  *
  * DO NOT CHANGE THIS LIST without testing that
  * maintenance/updateSpecialPages.php still works.
  * @return array
  */
 public static function getPages()
 {
     static $qp = null;
     if ($qp === null) {
         // QueryPage subclass, Special page name
         $qp = array(array('AncientPagesPage', 'Ancientpages'), array('BrokenRedirectsPage', 'BrokenRedirects'), array('DeadendPagesPage', 'Deadendpages'), array('DoubleRedirectsPage', 'DoubleRedirects'), array('FileDuplicateSearchPage', 'FileDuplicateSearch'), array('ListDuplicatedFilesPage', 'ListDuplicatedFiles'), array('LinkSearchPage', 'LinkSearch'), array('ListredirectsPage', 'Listredirects'), array('LonelyPagesPage', 'Lonelypages'), array('LongPagesPage', 'Longpages'), array('MediaStatisticsPage', 'MediaStatistics'), array('MIMEsearchPage', 'MIMEsearch'), array('MostcategoriesPage', 'Mostcategories'), array('MostimagesPage', 'Mostimages'), array('MostinterwikisPage', 'Mostinterwikis'), array('MostlinkedCategoriesPage', 'Mostlinkedcategories'), array('MostlinkedTemplatesPage', 'Mostlinkedtemplates'), array('MostlinkedPage', 'Mostlinked'), array('MostrevisionsPage', 'Mostrevisions'), array('FewestrevisionsPage', 'Fewestrevisions'), array('ShortPagesPage', 'Shortpages'), array('UncategorizedCategoriesPage', 'Uncategorizedcategories'), array('UncategorizedPagesPage', 'Uncategorizedpages'), array('UncategorizedImagesPage', 'Uncategorizedimages'), array('UncategorizedTemplatesPage', 'Uncategorizedtemplates'), array('UnusedCategoriesPage', 'Unusedcategories'), array('UnusedimagesPage', 'Unusedimages'), array('WantedCategoriesPage', 'Wantedcategories'), array('WantedFilesPage', 'Wantedfiles'), array('WantedPagesPage', 'Wantedpages'), array('WantedTemplatesPage', 'Wantedtemplates'), array('UnwatchedpagesPage', 'Unwatchedpages'), array('UnusedtemplatesPage', 'Unusedtemplates'), array('WithoutInterwikiPage', 'Withoutinterwiki'));
         Hooks::run('wgQueryPages', array(&$qp));
     }
     return $qp;
 }
예제 #26
0
 public function getQueryInfo()
 {
     $tables = array('page');
     $conds = array('page_namespace' => MWNamespace::getContentNamespaces(), 'page_is_redirect' => 0);
     $joinConds = array();
     $options = array('USE INDEX' => array('page' => 'page_redirect_namespace_len'));
     // Allow extensions to modify the query
     Hooks::run('ShortPagesQuery', array(&$tables, &$conds, &$joinConds, &$options));
     return array('tables' => $tables, 'fields' => array('namespace' => 'page_namespace', 'title' => 'page_title', 'value' => 'page_len'), 'conds' => $conds, 'join_conds' => $joinConds, 'options' => $options);
 }
예제 #27
0
 /**
  * Get the salts for known token types
  * @return (string|array)[] Returning a string will use that as the salt
  *  for User::getEditTokenObject() to fetch the token, which will give a
  *  LoggedOutEditToken (always "+\\") for anonymous users. Returning an
  *  array will use it as parameters to MediaWiki\\Session\\Session::getToken(),
  *  which will always return a full token even for anonymous users.
  */
 public static function getTokenTypeSalts()
 {
     static $salts = null;
     if (!$salts) {
         $salts = array('csrf' => '', 'watch' => 'watch', 'patrol' => 'patrol', 'rollback' => 'rollback', 'userrights' => 'userrights', 'login' => array('', 'login'), 'createaccount' => array('', 'createaccount'));
         Hooks::run('ApiQueryTokensRegisterTypes', array(&$salts));
         ksort($salts);
     }
     return $salts;
 }
예제 #28
0
 function getQueryInfo()
 {
     $conds = [];
     $conds['rc_new'] = 1;
     $namespace = $this->opts->getValue('namespace');
     $namespace = $namespace === 'all' ? false : intval($namespace);
     $username = $this->opts->getValue('username');
     $user = Title::makeTitleSafe(NS_USER, $username);
     $size = abs(intval($this->opts->getValue('size')));
     if ($size > 0) {
         if ($this->opts->getValue('size-mode') === 'max') {
             $conds[] = 'page_len <= ' . $size;
         } else {
             $conds[] = 'page_len >= ' . $size;
         }
     }
     $rcIndexes = [];
     if ($namespace !== false) {
         if ($this->opts->getValue('invert')) {
             $conds[] = 'rc_namespace != ' . $this->mDb->addQuotes($namespace);
         } else {
             $conds['rc_namespace'] = $namespace;
         }
     }
     if ($user) {
         $conds['rc_user_text'] = $user->getText();
         $rcIndexes = 'rc_user_text';
     } elseif (User::groupHasPermission('*', 'createpage') && $this->opts->getValue('hideliu')) {
         # If anons cannot make new pages, don't "exclude logged in users"!
         $conds['rc_user'] = 0;
     }
     # If this user cannot see patrolled edits or they are off, don't do dumb queries!
     if ($this->opts->getValue('hidepatrolled') && $this->getUser()->useNPPatrol()) {
         $conds['rc_patrolled'] = 0;
     }
     if ($this->opts->getValue('hidebots')) {
         $conds['rc_bot'] = 0;
     }
     if ($this->opts->getValue('hideredirs')) {
         $conds['page_is_redirect'] = 0;
     }
     // Allow changes to the New Pages query
     $tables = ['recentchanges', 'page'];
     $fields = ['rc_namespace', 'rc_title', 'rc_cur_id', 'rc_user', 'rc_user_text', 'rc_comment', 'rc_timestamp', 'rc_patrolled', 'rc_id', 'rc_deleted', 'length' => 'page_len', 'rev_id' => 'page_latest', 'rc_this_oldid', 'page_namespace', 'page_title'];
     $join_conds = ['page' => ['INNER JOIN', 'page_id=rc_cur_id']];
     Hooks::run('SpecialNewpagesConditions', [&$this, $this->opts, &$conds, &$tables, &$fields, &$join_conds]);
     $options = [];
     if ($rcIndexes) {
         $options = ['USE INDEX' => ['recentchanges' => $rcIndexes]];
     }
     $info = ['tables' => $tables, 'fields' => $fields, 'conds' => $conds, 'options' => $options, 'join_conds' => $join_conds];
     // Modify query for tags
     ChangeTags::modifyDisplayQuery($info['tables'], $info['fields'], $info['conds'], $info['join_conds'], $info['options'], $this->opts['tagfilter']);
     return $info;
 }
예제 #29
0
 /**
  * Make a list of searchable namespaces and their canonical names.
  * @return array Namespace ID => name
  */
 public function searchableNamespaces()
 {
     $arr = [];
     foreach ($this->language->getNamespaces() as $ns => $name) {
         if ($ns >= NS_MAIN) {
             $arr[$ns] = $name;
         }
     }
     Hooks::run('SearchableNamespaces', [&$arr]);
     return $arr;
 }
예제 #30
0
 /**
  * @param ResultWrapper $res A SQL result including at least page_namespace and
  *   page_title -- also can have page_id, page_len, page_is_redirect,
  *   page_latest (if those will be used).  See Title::newFromRow.
  * @return TitleArrayFromResult
  */
 static function newFromResult($res)
 {
     $array = null;
     if (!Hooks::run('TitleArrayFromResult', array(&$array, $res))) {
         return null;
     }
     if ($array === null) {
         $array = self::newFromResult_internal($res);
     }
     return $array;
 }