public function getDisplayNameMessage(\IContextSource $context) { if ($this->getType() === self::TYPE_FEATURED) { return $context->msg('cx-suggestionlist-featured'); } return new \RawMessage($this->getName()); }
/** * Return a link to the edit page, with the text * saying "view source" if the user can't edit the page * * @param Title $titleObj * @return string */ private function buildEditLink(Title $titleObj) { if ($titleObj->quickUserCan('edit', $this->context->getUser())) { $linkMsg = 'editlink'; } else { $linkMsg = 'viewsourcelink'; } return $this->linkRenderer->makeLink($titleObj, $this->context->msg($linkMsg)->text(), [], ['action' => 'edit']); }
public function contents() { $optional = $this->context->msg('translate-optional')->escaped(); $this->doLinkBatch(); $sourceLang = Language::factory($this->group->getSourceLanguage()); $targetLang = Language::factory($this->collection->getLanguage()); $titleMap = $this->collection->keys(); $output = ''; $this->collection->initMessages(); // Just to be sure /** * @var TMessage $m */ foreach ($this->collection as $key => $m) { $tools = array(); /** * @var Title $title */ $title = $titleMap[$key]; $original = $m->definition(); $translation = $m->translation(); $hasTranslation = $translation !== null; if ($hasTranslation) { $message = $translation; $extraAttribs = self::getLanguageAttributes($targetLang); } else { $message = $original; $extraAttribs = self::getLanguageAttributes($sourceLang); } Hooks::run('TranslateFormatMessageBeforeTable', array(&$message, $m, $this->group, $targetLang, &$extraAttribs)); // Using Html::element( a ) because Linker::link is memory hog. // It takes about 20 KiB per call, and that times 5000 is quite // a lot of memory. $niceTitle = htmlspecialchars($this->context->getLanguage()->truncate($title->getPrefixedText(), -35)); $linkAttribs = array('href' => $title->getLocalUrl(array('action' => 'edit'))); $linkAttribs += TranslationEditPage::jsEdit($title, $this->group->getId()); $tools['edit'] = Html::element('a', $linkAttribs, $niceTitle); $anchor = 'msg_' . $key; $anchor = Xml::element('a', array('id' => $anchor, 'href' => "#{$anchor}"), "↓"); $extra = ''; if ($m->hasTag('optional')) { $extra = '<br />' . $optional; } $tqeData = $extraAttribs + array('data-title' => $title->getPrefixedText(), 'data-group' => $this->group->getId(), 'id' => 'tqe-anchor-' . substr(sha1($title->getPrefixedText()), 0, 12), 'class' => 'tqe-inlineeditable ' . ($hasTranslation ? 'translated' : 'untranslated')); $button = $this->getReviewButton($m); $status = $this->getReviewStatus($m); $leftColumn = $button . $anchor . $tools['edit'] . $extra . $status; if ($this->reviewMode) { $output .= Xml::tags('tr', array('class' => 'orig'), Xml::tags('td', array('rowspan' => '2'), $leftColumn) . Xml::tags('td', self::getLanguageAttributes($sourceLang), TranslateUtils::convertWhiteSpaceToHTML($original))); $output .= Xml::tags('tr', null, Xml::tags('td', $tqeData, TranslateUtils::convertWhiteSpaceToHTML($message))); } else { $output .= Xml::tags('tr', array('class' => 'def'), Xml::tags('td', null, $leftColumn) . Xml::tags('td', $tqeData, TranslateUtils::convertWhiteSpaceToHTML($message))); } $output .= "\n"; } return $output; }
/** * Prepare the label for a protection selector option * * @param string $permission Permission required * @return string */ private function getOptionLabel($permission) { if ($permission == '') { return $this->mContext->msg('protect-default')->text(); } else { // Messages: protect-level-autoconfirmed, protect-level-sysop $msg = $this->mContext->msg("protect-level-{$permission}"); if ($msg->exists()) { return $msg->text(); } return $this->mContext->msg('protect-fallback', $permission)->text(); } }
public static function onGetEmailAuthentication(User &$user, IContextSource $context, &$disableEmailPrefs, &$emailauthenticated) { if ($user->getEmail()) { $emailTimestamp = $user->getEmailAuthenticationTimestamp(); $optionNewEmail = $user->getGlobalAttribute('new_email'); $msgKeyPrefixEmail = empty($optionNewEmail) && !$emailTimestamp ? 'usersignup-user-pref-unconfirmed-' : 'usersignup-user-pref-'; if (empty($optionNewEmail) && $emailTimestamp) { $lang = $context->getLanguage(); $displayUser = $context->getUser(); $time = $lang->userTimeAndDate($emailTimestamp, $displayUser); $d = $lang->userDate($emailTimestamp, $displayUser); $t = $lang->userTime($emailTimestamp, $displayUser); $emailauthenticated = $context->msg($msgKeyPrefixEmail . 'emailauthenticated', $time, $d, $t)->parse() . '<br />'; $disableEmailPrefs = false; } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg($msgKeyPrefixEmail . 'emailnotauthenticated', array($optionNewEmail))->parse() . '<br />' . Linker::linkKnown(SpecialPage::getTitleFor('Confirmemail'), $context->msg('usersignup-user-pref-emailconfirmlink')->escaped()) . '<br />'; } } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg('usersignup-user-pref-noemailprefs')->escaped(); } return true; }
function toHtml(IContextSource $context) { return $context->msg($this->getDbKey())->parse(); }
/** * Returns a message that notifies the user he/she is looking at * a cached version of the page, including a refresh link. * * @since 1.20 * * @param IContextSource $context * @param boolean $includePurgeLink * * @return string */ public function getCachedNotice(IContextSource $context, $includePurgeLink = true) { if ($this->cacheExpiry < 86400 * 3650) { $message = $context->msg('cachedspecial-viewing-cached-ttl', $context->getLanguage()->formatDuration($this->cacheExpiry))->escaped(); } else { $message = $context->msg('cachedspecial-viewing-cached-ts')->escaped(); } if ($includePurgeLink) { $refreshArgs = $context->getRequest()->getQueryValues(); unset($refreshArgs['title']); $refreshArgs['action'] = 'purge'; $subPage = $context->getTitle()->getFullText(); $subPage = explode('/', $subPage, 2); $subPage = count($subPage) > 1 ? $subPage[1] : false; $message .= ' ' . Linker::link($context->getTitle($subPage), $context->msg('cachedspecial-refresh-now')->escaped(), array(), $refreshArgs); } return $message; }
protected function acceptRequest(IContextSource $context) { global $wgAuth, $wgAccountRequestTypes, $wgConfirmAccountSaveInfo; global $wgConfirmAccountRequestFormItems, $wgConfirmAccountFSRepos; $formConfig = $wgConfirmAccountRequestFormItems; // convience $accReq = $this->accountReq; // convenience # Now create user and check if the name is valid $user = User::newFromName($this->userName, 'creatable'); if (!$user) { return array('accountconf_invalid_name', $context->msg('noname')->escaped()); } # Check if account name is already in use if (0 != $user->idForName() || $wgAuth->userExists($user->getName())) { return array('accountconf_user_exists', $context->msg('userexists')->escaped()); } $dbw = wfGetDB(DB_MASTER); $dbw->begin(); # Make a random password $p = User::randomPassword(); # Insert the new user into the DB... $tokenExpires = $accReq->getEmailTokenExpires(); $authenticated = $accReq->getEmailAuthTimestamp(); $params = array('real_name' => $accReq->getRealName(), 'newpassword' => User::crypt($p), 'email' => $accReq->getEmail(), 'email_authenticated' => $dbw->timestampOrNull($authenticated), 'email_token_expires' => $dbw->timestamp($tokenExpires), 'email_token' => $accReq->getEmailToken()); $user = User::createNew($user->getName(), $params); # Grant any necessary rights (exclude blank or dummy groups) $group = self::getGroupFromType($this->type); if ($group != '' && $group != 'user' && $group != '*') { $user->addGroup($group); } $acd_id = null; // used for rollback cleanup # Save account request data to credentials system if ($wgConfirmAccountSaveInfo) { $key = $accReq->getFileStorageKey(); # Copy any attached files to new storage group if ($formConfig['CV']['enabled'] && $key) { $repoOld = new FSRepo($wgConfirmAccountFSRepos['accountreqs']); $repoNew = new FSRepo($wgConfirmAccountFSRepos['accountcreds']); $pathRel = UserAccountRequest::relPathFromKey($key); $oldPath = $repoOld->getZonePath('public') . '/' . $pathRel; $triplet = array($oldPath, 'public', $pathRel); $status = $repoNew->storeBatch(array($triplet)); // copy! if (!$status->isOK()) { $dbw->rollback(); # DELETE new rows in case there was a COMMIT somewhere $this->acceptRequest_rollback($dbw, $user->getId(), $acd_id); return array('accountconf_copyfailed', $context->getOutput()->parse($status->getWikiText())); } } $acd_id = $dbw->nextSequenceValue('account_credentials_acd_id_seq'); # Move request data into a separate table $dbw->insert('account_credentials', array('acd_user_id' => $user->getID(), 'acd_real_name' => $accReq->getRealName(), 'acd_email' => $accReq->getEmail(), 'acd_email_authenticated' => $dbw->timestampOrNull($authenticated), 'acd_bio' => $accReq->getBio(), 'acd_notes' => $accReq->getNotes(), 'acd_urls' => $accReq->getUrls(), 'acd_ip' => $accReq->getIP(), 'acd_xff' => $accReq->getXFF(), 'acd_agent' => $accReq->getAgent(), 'acd_filename' => $accReq->getFileName(), 'acd_storage_key' => $accReq->getFileStorageKey(), 'acd_areas' => $accReq->getAreas('flat'), 'acd_registration' => $dbw->timestamp($accReq->getRegistration()), 'acd_accepted' => $dbw->timestamp(), 'acd_user' => $this->admin->getID(), 'acd_comment' => $this->reason, 'acd_id' => $acd_id), __METHOD__); if (is_null($acd_id)) { $acd_id = $dbw->insertId(); // set $acd_id to ID inserted } } # Add to global user login system (if there is one) if (!$wgAuth->addUser($user, $p, $accReq->getEmail(), $accReq->getRealName())) { $dbw->rollback(); # DELETE new rows in case there was a COMMIT somewhere $this->acceptRequest_rollback($dbw, $user->getId(), $acd_id); return array('accountconf_externaldberror', $context->msg('externaldberror')->escaped()); } # OK, now remove the request from the queue $accReq->remove(); # Commit this if we make past the CentralAuth system # and the groups are added. Next step is sending out an # email, which we cannot take back... $dbw->commit(); # Prepare a temporary password email... if ($this->reason != '') { $msg = "confirmaccount-email-body2-pos{$this->type}"; # If the user is in a group and there is a welcome for that group, use it if ($group && !wfEmptyMsg($msg)) { $ebody = $context->msg($msg, $user->getName(), $p, $this->reason)->inContentLanguage()->text(); # Use standard if none found... } else { $ebody = $context->msg('confirmaccount-email-body2', $user->getName(), $p, $this->reason)->inContentLanguage()->text(); } } else { $msg = "confirmaccount-email-body-pos{$this->type}"; # If the user is in a group and there is a welcome for that group, use it if ($group && !$context->msg($msg)->isDisabled()) { $ebody = $context->msg($msg, $user->getName(), $p, $this->reason)->inContentLanguage()->text(); # Use standard if none found... } else { $ebody = $context->msg('confirmaccount-email-body', $user->getName(), $p, $this->reason)->inContentLanguage()->text(); } } # Actually send out the email (@TODO: rollback on failure including $wgAuth) $result = $user->sendMail($context->msg('confirmaccount-email-subj')->inContentLanguage()->text(), $ebody); # Update user count $ssUpdate = new SiteStatsUpdate(0, 0, 0, 0, 1); $ssUpdate->doUpdate(); # Safe to hook/log now... wfRunHooks('AddNewAccount', array($user, false)); $user->addNewUserLogEntry(); # Clear cache for notice of how many account requests there are ConfirmAccount::clearAccountRequestCountCache(); # Delete any attached file and don't stop the whole process if this fails if ($formConfig['CV']['enabled']) { $key = $accReq->getFileStorageKey(); if ($key) { $repoOld = new FSRepo($wgConfirmAccountFSRepos['accountreqs']); $pathRel = UserAccountRequest::relPathFromKey($key); $oldPath = $repoOld->getZonePath('public') . '/' . $pathRel; if ($repoOld->fileExists($oldPath)) { $repoOld->getBackend()->delete(array('src' => $oldPath)); // delete! } } } # Start up the user's userpages if set to do so. # Will not append, so previous content will be blanked. $this->createUserPage($user); # Greet the new user if set to do so. $this->createUserTalkPage($user); return array(true, null); }
/** * Return the legend displayed within the fieldset * @todo This should not be static, then we can drop the parameter * @todo Not called by anything, should be called by doHeader() * * @param $context the object available as $this in non-static functions * @return string */ public static function makeLegend(IContextSource $context) { global $wgRecentChangesFlags; $user = $context->getUser(); # The legend showing what the letters and stuff mean $legend = Xml::openElement('dl') . "\n"; # Iterates through them and gets the messages for both letter and tooltip $legendItems = $wgRecentChangesFlags; if (!$user->useRCPatrol()) { unset($legendItems['unpatrolled']); } foreach ($legendItems as $key => $legendInfo) { # generate items of the legend $label = $legendInfo['title']; $letter = $legendInfo['letter']; $cssClass = isset($legendInfo['class']) ? $legendInfo['class'] : $key; $legend .= Xml::element('dt', array('class' => $cssClass), $context->msg($letter)->text()) . "\n"; if ($key === 'newpage') { $legend .= Xml::openElement('dd'); $legend .= $context->msg($label)->escaped(); $legend .= ' ' . $context->msg('recentchanges-legend-newpage')->parse(); $legend .= Xml::closeElement('dd') . "\n"; } else { $legend .= Xml::element('dd', array(), $context->msg($label)->text()) . "\n"; } } # (+-123) $legend .= Xml::tags('dt', array('class' => 'mw-plusminus-pos'), $context->msg('recentchanges-legend-plusminus')->parse()) . "\n"; $legend .= Xml::element('dd', array('class' => 'mw-changeslist-legend-plusminus'), $context->msg('recentchanges-label-plusminus')->text()) . "\n"; $legend .= Xml::closeElement('dl') . "\n"; # Collapsibility $legend = '<div class="mw-changeslist-legend">' . $context->msg('recentchanges-legend-heading')->parse() . '<div class="mw-collapsible-content">' . $legend . '</div>' . '</div>'; return $legend; }
/** * Generate help for the specified modules * * Help is placed into the OutputPage object returned by * $context->getOutput(). * * Recognized options include: * - headerlevel: (int) Header tag level * - nolead: (bool) Skip the inclusion of api-help-lead * - noheader: (bool) Skip the inclusion of the top-level section headers * - submodules: (bool) Include help for submodules of the current module * - recursivesubmodules: (bool) Include help for submodules recursively * - helptitle: (string) Title to link for additional modules' help. Should contain $1. * - toc: (bool) Include a table of contents * * @param IContextSource $context * @param ApiBase[]|ApiBase $modules * @param array $options Formatting options (described above) * @return string */ public static function getHelp(IContextSource $context, $modules, array $options) { global $wgContLang; if (!is_array($modules)) { $modules = array($modules); } $out = $context->getOutput(); $out->addModuleStyles('mediawiki.hlist'); $out->addModuleStyles('mediawiki.apihelp'); if (!empty($options['toc'])) { $out->addModules('mediawiki.toc'); } $out->setPageTitle($context->msg('api-help-title')); $cache = ObjectCache::getMainWANInstance(); $cacheKey = null; if (count($modules) == 1 && $modules[0] instanceof ApiMain && $options['recursivesubmodules'] && $context->getLanguage() === $wgContLang) { $cacheHelpTimeout = $context->getConfig()->get('APICacheHelpTimeout'); if ($cacheHelpTimeout > 0) { // Get help text from cache if present $cacheKey = wfMemcKey('apihelp', $modules[0]->getModulePath(), (int) (!empty($options['toc'])), str_replace(' ', '_', SpecialVersion::getVersion('nodb'))); $cached = $cache->get($cacheKey); if ($cached) { $out->addHTML($cached); return; } } } if ($out->getHTML() !== '') { // Don't save to cache, there's someone else's content in the page // already $cacheKey = null; } $options['recursivesubmodules'] = !empty($options['recursivesubmodules']); $options['submodules'] = $options['recursivesubmodules'] || !empty($options['submodules']); // Prepend lead if (empty($options['nolead'])) { $msg = $context->msg('api-help-lead'); if (!$msg->isDisabled()) { $out->addHTML($msg->parseAsBlock()); } } $haveModules = array(); $html = self::getHelpInternal($context, $modules, $options, $haveModules); if (!empty($options['toc']) && $haveModules) { $out->addHTML(Linker::generateTOC($haveModules, $context->getLanguage())); } $out->addHTML($html); $helptitle = isset($options['helptitle']) ? $options['helptitle'] : null; $html = self::fixHelpLinks($out->getHTML(), $helptitle, $haveModules); $out->clearHTML(); $out->addHTML($html); if ($cacheKey !== null) { $cache->set($cacheKey, $out->getHTML(), $cacheHelpTimeout); } }
/** * Really send a mail. Permissions should have been checked using * getPermissionsError(). It is probably also a good * idea to check the edit token and ping limiter in advance. * * @param array $data * @param IContextSource $context * @return Status|string|bool Status object, or potentially a String on error * or maybe even true on success if anything uses the EmailUser hook. */ public static function submit(array $data, IContextSource $context) { $config = $context->getConfig(); $target = self::getTarget($data['Target']); if (!$target instanceof User) { // Messages used here: notargettext, noemailtext, nowikiemailtext return $context->msg($target . 'text')->parseAsBlock(); } $to = MailAddress::newFromUser($target); $from = MailAddress::newFromUser($context->getUser()); $subject = $data['Subject']; $text = $data['Text']; // Add a standard footer and trim up trailing newlines $text = rtrim($text) . "\n\n-- \n"; $text .= $context->msg('emailuserfooter', $from->name, $to->name)->inContentLanguage()->text(); $error = ''; if (!Hooks::run('EmailUser', array(&$to, &$from, &$subject, &$text, &$error))) { return $error; } if ($config->get('UserEmailUseReplyTo')) { /** * Put the generic wiki autogenerated address in the From: * header and reserve the user for Reply-To. * * This is a bit ugly, but will serve to differentiate * wiki-borne mails from direct mails and protects against * SPF and bounce problems with some mailers (see below). */ $mailFrom = new MailAddress($config->get('PasswordSender'), wfMessage('emailsender')->inContentLanguage()->text()); $replyTo = $from; } else { /** * Put the sending user's e-mail address in the From: header. * * This is clean-looking and convenient, but has issues. * One is that it doesn't as clearly differentiate the wiki mail * from "directly" sent mails. * * Another is that some mailers (like sSMTP) will use the From * address as the envelope sender as well. For open sites this * can cause mails to be flunked for SPF violations (since the * wiki server isn't an authorized sender for various users' * domains) as well as creating a privacy issue as bounces * containing the recipient's e-mail address may get sent to * the sending user. */ $mailFrom = $from; $replyTo = null; } $status = UserMailer::send($to, $mailFrom, $subject, $text, array('replyTo' => $replyTo)); if (!$status->isGood()) { return $status; } else { // if the user requested a copy of this mail, do this now, // unless they are emailing themselves, in which case one // copy of the message is sufficient. if ($data['CCMe'] && $to != $from) { $cc_subject = $context->msg('emailccsubject')->rawParams($target->getName(), $subject)->text(); // target and sender are equal, because this is the CC for the sender Hooks::run('EmailUserCC', array(&$from, &$from, &$cc_subject, &$text)); $ccStatus = UserMailer::send($from, $from, $cc_subject, $text); $status->merge($ccStatus); } Hooks::run('EmailUserComplete', array($to, $from, $subject, $text)); return $status; } }
/** * Return the legend displayed within the fieldset * @todo This should not be static, then we can drop the parameter * @todo Not called by anything, should be called by doHeader() * * @param IContextSource $context The object available as $this in non-static functions * @return string */ public static function makeLegend(IContextSource $context) { $user = $context->getUser(); # The legend showing what the letters and stuff mean $legend = Html::openElement('dl') . "\n"; # Iterates through them and gets the messages for both letter and tooltip $legendItems = $context->getConfig()->get('RecentChangesFlags'); if (!($user->useRCPatrol() || $user->useNPPatrol())) { unset($legendItems['unpatrolled']); } foreach ($legendItems as $key => $item) { # generate items of the legend $label = isset($item['legend']) ? $item['legend'] : $item['title']; $letter = $item['letter']; $cssClass = isset($item['class']) ? $item['class'] : $key; $legend .= Html::element('dt', array('class' => $cssClass), $context->msg($letter)->text()) . "\n" . Html::rawElement('dd', array(), $context->msg($label)->parse()) . "\n"; } # (+-123) $legend .= Html::rawElement('dt', array('class' => 'mw-plusminus-pos'), $context->msg('recentchanges-legend-plusminus')->parse()) . "\n"; $legend .= Html::element('dd', array('class' => 'mw-changeslist-legend-plusminus'), $context->msg('recentchanges-label-plusminus')->text()) . "\n"; $legend .= Html::closeElement('dl') . "\n"; # Collapsibility $legend = '<div class="mw-changeslist-legend">' . $context->msg('recentchanges-legend-heading')->parse() . '<div class="mw-collapsible-content">' . $legend . '</div>' . '</div>'; return $legend; }
/** * Edit a Collaboration Hub via the edit API * @param $title Title * @param $displayName string * @param $icon string * @param $colour string * @param $introduction string * @param $footer string * @param $content array * @param $summary string Message key for edit summary * @param $context IContextSource The calling context * @return Status */ public static function edit(Title $title, $displayName, $image, $colour, $introduction, $footer, $content, $summary, IContextSource $context) { $contentBlock = ['display_name' => $displayName, 'introduction' => $introduction, 'footer' => $footer, 'image' => $image, 'colour' => $colour, 'content' => $content]; // TODO Do content $jsonText = FormatJson::encode($contentBlock); if ($jsonText === null) { return Status::newFatal('collaborationkit-hub-edit-tojsonerror'); } // Ensure that a valid context is provided to the API in unit tests $der = new DerivativeContext($context); $request = new DerivativeRequest($context->getRequest(), ['action' => 'edit', 'title' => $title->getFullText(), 'contentmodel' => 'CollaborationHubContent', 'text' => $jsonText, 'summary' => $summary, 'token' => $context->getUser()->getEditToken()], true); $der->setRequest($request); try { $api = new ApiMain($der, true); $api->execute(); } catch (UsageException $e) { return Status::newFatal($context->msg('collaborationkit-hub-edit-apierror', $e->getCodeString())); } return Status::newGood(); }
/** * Set locking and hiding settings for a Global User and log the changes made. * * @param $setLocked Bool|null * true = lock * false = unlock * null = don't change * @param $setHidden String|null * hidden level, one of the HIDDEN_ constants * null = don't change * @param $reason String reason for hiding * @param $context IContextSource * @return Status */ public function adminLockHide($setLocked, $setHidden, $reason, IContextSource $context) { $isLocked = $this->isLocked(); $oldHiddenLevel = $this->getHiddenLevel(); $lockStatus = $hideStatus = null; $added = array(); $removed = array(); if (is_null($setLocked)) { $setLocked = $isLocked; } elseif (!$context->getUser()->isAllowed('centralauth-lock')) { return Status::newFatal('centralauth-admin-not-authorized'); } if (is_null($setHidden)) { $setHidden = $oldHiddenLevel; } elseif ($setHidden != self::HIDDEN_NONE || $oldHiddenLevel != self::HIDDEN_NONE) { if (!$context->getUser()->isAllowed('centralauth-oversight')) { return Status::newFatal('centralauth-admin-not-authorized'); } elseif ($this->getGlobalEditCount() > self::HIDE_CONTRIBLIMIT) { return Status::newFatal($context->msg('centralauth-admin-too-many-edits', $this->mName)->numParams(self::HIDE_CONTRIBLIMIT)); } } $returnStatus = Status::newGood(); $hiddenLevels = array(self::HIDDEN_NONE, self::HIDDEN_LISTS, self::HIDDEN_OVERSIGHT); if (!in_array($setHidden, $hiddenLevels)) { $setHidden = self::HIDDEN_NONE; } if (!$isLocked && $setLocked) { $lockStatus = $this->adminLock(); $added[] = $context->msg('centralauth-log-status-locked')->inContentLanguage()->text(); } elseif ($isLocked && !$setLocked) { $lockStatus = $this->adminUnlock(); $removed[] = $context->msg('centralauth-log-status-locked')->inContentLanguage()->text(); } if ($oldHiddenLevel != $setHidden) { $hideStatus = $this->adminSetHidden($setHidden); switch ($setHidden) { case self::HIDDEN_NONE: if ($oldHiddenLevel == self::HIDDEN_OVERSIGHT) { $removed[] = $context->msg('centralauth-log-status-oversighted')->inContentLanguage()->text(); } else { $removed[] = $context->msg('centralauth-log-status-hidden')->inContentLanguage()->text(); } break; case self::HIDDEN_LISTS: $added[] = $context->msg('centralauth-log-status-hidden')->inContentLanguage()->text(); if ($oldHiddenLevel == self::HIDDEN_OVERSIGHT) { $removed[] = $context->msg('centralauth-log-status-oversighted')->inContentLanguage()->text(); } break; case self::HIDDEN_OVERSIGHT: $added[] = $context->msg('centralauth-log-status-oversighted')->inContentLanguage()->text(); if ($oldHiddenLevel == self::HIDDEN_LISTS) { $removed[] = $context->msg('centralauth-log-status-hidden')->inContentLanguage()->text(); } break; } if ($setHidden == self::HIDDEN_OVERSIGHT) { $this->suppress($reason); } elseif ($oldHiddenLevel == self::HIDDEN_OVERSIGHT) { $this->unsuppress($reason); } } $good = (is_null($lockStatus) || $lockStatus->isGood()) && (is_null($hideStatus) || $hideStatus->isGood()); // Setup Status object to return all of the information for logging if ($good && (count($added) || count($removed))) { $added = count($added) ? implode(', ', $added) : $context->msg('centralauth-log-status-none')->inContentLanguage()->text(); $removed = count($removed) ? implode(', ', $removed) : $context->msg('centralauth-log-status-none')->inContentLanguage()->text(); $returnStatus->successCount = count($added) + count($removed); $returnStatus->success['added'] = $added; $returnStatus->success['removed'] = $removed; $this->logAction('setstatus', $reason, $returnStatus->success, $setHidden != self::HIDDEN_NONE); } elseif (!$good) { if (!is_null($lockStatus) && !$lockStatus->isGood()) { $returnStatus->merge($lockStatus); } if (!is_null($hideStatus) && !$hideStatus->isGood()) { $returnStatus->merge($hideStatus); } } return $returnStatus; }
/** * @param $title Title * @param $summary string * @param $context IContextSource * @todo rework this to use a generic CollaborationList editor function once it exists */ public static function postMemberList(Title $title, $summary, IContextSource $context) { $username = $context->getUser()->getName(); $collabList = self::makeMemberList($username, $context->msg('collaborationkit-hub-members-description')); // Ensure that a valid context is provided to the API in unit tests $der = new DerivativeContext($context); $request = new DerivativeRequest($context->getRequest(), ['action' => 'edit', 'title' => $title->getFullText(), 'contentmodel' => 'CollaborationListContent', 'contentformat' => 'application/json', 'text' => $collabList->serialize(), 'summary' => $summary, 'token' => $context->getUser()->getEditToken()], true); $der->setRequest($request); try { $api = new ApiMain($der, true); $api->execute(); } catch (UsageException $e) { return Status::newFatal($context->msg('collaborationkit-hub-edit-apierror', $e->getCodeString())); } return Status::newGood(); }
/** * Get the key and parameters for the corresponding error message. * * @since 1.22 * @param IContextSource $context * @return array */ public function getPermissionsError(IContextSource $context) { $blocker = $this->getBlocker(); if ($blocker instanceof User) { // local user $blockerUserpage = $blocker->getUserPage(); $link = "[[{$blockerUserpage->getPrefixedText()}|{$blockerUserpage->getText()}]]"; } else { // foreign user $link = $blocker; } $reason = $this->mReason; if ($reason == '') { $reason = $context->msg('blockednoreason')->text(); } /* $ip returns who *is* being blocked, $intended contains who was meant to be blocked. * This could be a username, an IP range, or a single IP. */ $intended = $this->getTarget(); $lang = $context->getLanguage(); return array($this->mAuto ? 'autoblockedtext' : 'blockedtext', $link, $reason, $context->getRequest()->getIP(), $this->getByName(), $this->getId(), $lang->formatExpiry($this->mExpiry), (string) $intended, $lang->userTimeAndDate($this->mTimestamp, $context->getUser())); }
/** * @param IContextSource $context * @return array */ static function getTimezoneOptions(IContextSource $context) { $opt = array(); $localTZoffset = $context->getConfig()->get('LocalTZoffset'); $timeZoneList = self::getTimeZoneList($context->getLanguage()); $timestamp = MWTimestamp::getLocalInstance(); // Check that the LocalTZoffset is the same as the local time zone offset if ($localTZoffset == $timestamp->format('Z') / 60) { $timezoneName = $timestamp->getTimezone()->getName(); // Localize timezone if (isset($timeZoneList[$timezoneName])) { $timezoneName = $timeZoneList[$timezoneName]['name']; } $server_tz_msg = $context->msg('timezoneuseserverdefault', $timezoneName)->text(); } else { $tzstring = sprintf('%+03d:%02d', floor($localTZoffset / 60), abs($localTZoffset) % 60); $server_tz_msg = $context->msg('timezoneuseserverdefault', $tzstring)->text(); } $opt[$server_tz_msg] = "System|{$localTZoffset}"; $opt[$context->msg('timezoneuseoffset')->text()] = 'other'; $opt[$context->msg('guesstimezone')->text()] = 'guess'; foreach ($timeZoneList as $timeZoneInfo) { $region = $timeZoneInfo['region']; if (!isset($opt[$region])) { $opt[$region] = array(); } $opt[$region][$timeZoneInfo['name']] = $timeZoneInfo['timecorrection']; } return $opt; }
protected function addEditNotices() { global $wgOut; $editNotices = $this->mTitle->getEditNotices($this->oldid); if (count($editNotices)) { $wgOut->addHTML(implode("\n", $editNotices)); } else { $msg = $this->context->msg('editnotice-notext'); if (!$msg->isDisabled()) { $wgOut->addHTML('<div class="mw-editnotice-notext">' . $msg->parseAsBlock() . '</div>'); } } }
/** * Get a message saying that an invalid title was encountered. * This should be called after a method like Title::makeTitleSafe() returned * a value indicating that the title object is invalid. * * @param $context IContextSource context to use to get the messages * @param $namespace int Namespace number * @param $title string Text of the title, without the namespace part */ public static function getInvalidTitleDescription(IContextSource $context, $namespace, $title) { global $wgContLang; // First we check whether the namespace exists or not. if (MWNamespace::exists($namespace)) { if ($namespace == NS_MAIN) { $name = $context->msg('blanknamespace')->text(); } else { $name = $wgContLang->getFormattedNsText($namespace); } return $context->msg('invalidtitle-knownnamespace', $namespace, $name, $title)->text(); } else { return $context->msg('invalidtitle-unknownnamespace', $namespace, $title)->text(); } }
/** * Attempt to validate and submit this data to the DB * @param $context IContextSource * @return array( true or error key string, html error msg or null ) */ public function submit(IContextSource $context) { global $wgAuth, $wgAccountRequestThrottle, $wgMemc, $wgContLang; global $wgConfirmAccountRequestFormItems; $formConfig = $wgConfirmAccountRequestFormItems; // convience $reqUser = $this->requester; # Make sure that basic permissions are checked $block = ConfirmAccount::getAccountRequestBlock($reqUser); if ($block) { return array('accountreq_permission_denied', $context->msg('badaccess-group0')->escaped()); } elseif (wfReadOnly()) { return array('accountreq_readonly', $context->msg('badaccess-group0')->escaped()); } # Now create a dummy user ($u) and check if it is valid if ($this->userName === '') { return array('accountreq_no_name', $context->msg('noname')->escaped()); } $u = User::newFromName($this->userName, 'creatable'); if (!$u) { return array('accountreq_invalid_name', $context->msg('noname')->escaped()); } # No request spamming... if ($wgAccountRequestThrottle && $reqUser->isPingLimitable()) { $key = wfMemcKey('acctrequest', 'ip', $this->ip); $value = (int) $wgMemc->get($key); if ($value > $wgAccountRequestThrottle) { return array('accountreq_throttled', $context->msg('acct_request_throttle_hit', $wgAccountRequestThrottle)->text()); } } # Make sure user agrees to policy here if ($formConfig['TermsOfService']['enabled'] && !$this->tosAccepted) { return array('acct_request_skipped_tos', $context->msg('requestaccount-agree')->escaped()); } # Validate email address if (!Sanitizer::validateEmail($this->email)) { return array('acct_request_invalid_email', $context->msg('invalidemailaddress')->escaped()); } # Check if biography is long enough if ($formConfig['Biography']['enabled'] && str_word_count($this->bio) < $formConfig['Biography']['minWords']) { $minWords = $formConfig['Biography']['minWords']; return array('acct_request_short_bio', $context->msg('requestaccount-tooshort')->numParams($minWords)->text()); } # Per security reasons, file dir cannot be pulled from client, # so ask them to resubmit it then... # If the extra fields are off, then uploads are off $allowFiles = $formConfig['CV']['enabled']; if ($allowFiles && $this->attachmentPrevName && !$this->attachmentSrcName) { # If the user is submitting forgotAttachment as true with no file, # then they saw the notice and choose not to re-select the file. # Assume that they don't want to send one anymore. if (!$this->attachmentDidNotForget) { $this->attachmentPrevName = ''; $this->attachmentDidNotForget = 0; return array(false, $context->msg('requestaccount-resub')->escaped()); } } # Check if already in use if (0 != $u->idForName() || $wgAuth->userExists($u->getName())) { return array('accountreq_username_exists', $context->msg('userexists')->escaped()); } # Set email and real name $u->setEmail($this->email); $u->setRealName($this->realName); $dbw = wfGetDB(DB_MASTER); $dbw->begin(); // ready to acquire locks # Check pending accounts for name use if (!UserAccountRequest::acquireUsername($u->getName())) { $dbw->rollback(); return array('accountreq_username_pending', $context->msg('requestaccount-inuse')->escaped()); } # Check if someone else has an account request with the same email if (!UserAccountRequest::acquireEmail($u->getEmail())) { $dbw->rollback(); return array('acct_request_email_exists', $context->msg('requestaccount-emaildup')->escaped()); } # Process upload... if ($allowFiles && $this->attachmentSrcName) { global $wgAccountRequestExts, $wgConfirmAccountFSRepos; $ext = explode('.', $this->attachmentSrcName); $finalExt = $ext[count($ext) - 1]; # File must have size. if (trim($this->attachmentSrcName) == '' || empty($this->attachmentSize)) { $this->attachmentPrevName = ''; $dbw->rollback(); return array('acct_request_empty_file', $context->msg('emptyfile')->escaped()); } # Look at the contents of the file; if we can recognize the # type but it's corrupt or data of the wrong type, we should # probably not accept it. if (!in_array($finalExt, $wgAccountRequestExts)) { $this->attachmentPrevName = ''; $dbw->rollback(); return array('acct_request_bad_file_ext', $context->msg('requestaccount-exts')->escaped()); } $veri = ConfirmAccount::verifyAttachment($this->attachmentTempPath, $finalExt); if (!$veri->isGood()) { $this->attachmentPrevName = ''; $dbw->rollback(); return array('acct_request_corrupt_file', $context->msg('verification-error')->escaped()); } # Start a transaction, move file from temp to account request directory. $repo = new FSRepo($wgConfirmAccountFSRepos['accountreqs']); $key = sha1_file($this->attachmentTempPath) . '.' . $finalExt; $pathRel = UserAccountRequest::relPathFromKey($key); $triplet = array($this->attachmentTempPath, 'public', $pathRel); $status = $repo->storeBatch(array($triplet), FSRepo::OVERWRITE_SAME); // save! if (!$status->isOk()) { $dbw->rollback(); return array('acct_request_file_store_error', $context->msg('filecopyerror', $this->attachmentTempPath, $pathRel)->escaped()); } } $expires = null; // passed by reference $token = ConfirmAccount::getConfirmationToken($u, $expires); # Insert into pending requests... $req = UserAccountRequest::newFromArray(array('name' => $u->getName(), 'email' => $u->getEmail(), 'real_name' => $u->getRealName(), 'registration' => $this->registration, 'bio' => $this->bio, 'notes' => $this->notes, 'urls' => $this->urls, 'filename' => isset($this->attachmentSrcName) ? $this->attachmentSrcName : null, 'type' => $this->type, 'areas' => $this->areas, 'storage_key' => isset($key) ? $key : null, 'comment' => '', 'email_token' => md5($token), 'email_token_expires' => $expires, 'ip' => $this->ip, 'xff' => $this->xff, 'agent' => $this->agent)); $req->insertOn(); # Send confirmation, required! $result = ConfirmAccount::sendConfirmationMail($u, $this->ip, $token, $expires); if (!$result->isOK()) { $dbw->rollback(); // nevermind if (isset($repo) && isset($pathRel)) { // remove attachment $repo->cleanupBatch(array(array('public', $pathRel))); } $param = $context->getOutput()->parse($result->getWikiText()); return array('acct_request_mail_failed', $context->msg('mailerror')->rawParams($param)->escaped()); } $dbw->commit(); # Clear cache for notice of how many account requests there are ConfirmAccount::clearAccountRequestCountCache(); # No request spamming... if ($wgAccountRequestThrottle && $reqUser->isPingLimitable()) { $ip = $context->getRequest()->getIP(); $key = wfMemcKey('acctrequest', 'ip', $ip); $value = $wgMemc->incr($key); if (!$value) { $wgMemc->set($key, 1, 86400); } } # Done! return array(true, null); }
/** * @param $context IContextSource * @return array */ static function getTimezoneOptions( IContextSource $context ) { $opt = array(); global $wgLocalTZoffset; $timestamp = MWTimestamp::getLocalInstance(); // Check that $wgLocalTZoffset is the same as the local time zone offset if ( $wgLocalTZoffset == $timestamp->format( 'Z' ) / 60 ) { $server_tz_msg = $context->msg( 'timezoneuseserverdefault', $timestamp->getTimezone()->getName() )->text(); } else { $tzstring = sprintf( '%+03d:%02d', floor( $wgLocalTZoffset / 60 ), abs( $wgLocalTZoffset ) % 60 ); $server_tz_msg = $context->msg( 'timezoneuseserverdefault', $tzstring )->text(); } $opt[$server_tz_msg] = "System|$wgLocalTZoffset"; $opt[$context->msg( 'timezoneuseoffset' )->text()] = 'other'; $opt[$context->msg( 'guesstimezone' )->text()] = 'guess'; if ( function_exists( 'timezone_identifiers_list' ) ) { # Read timezone list $tzs = timezone_identifiers_list(); sort( $tzs ); $tzRegions = array(); $tzRegions['Africa'] = $context->msg( 'timezoneregion-africa' )->text(); $tzRegions['America'] = $context->msg( 'timezoneregion-america' )->text(); $tzRegions['Antarctica'] = $context->msg( 'timezoneregion-antarctica' )->text(); $tzRegions['Arctic'] = $context->msg( 'timezoneregion-arctic' )->text(); $tzRegions['Asia'] = $context->msg( 'timezoneregion-asia' )->text(); $tzRegions['Atlantic'] = $context->msg( 'timezoneregion-atlantic' )->text(); $tzRegions['Australia'] = $context->msg( 'timezoneregion-australia' )->text(); $tzRegions['Europe'] = $context->msg( 'timezoneregion-europe' )->text(); $tzRegions['Indian'] = $context->msg( 'timezoneregion-indian' )->text(); $tzRegions['Pacific'] = $context->msg( 'timezoneregion-pacific' )->text(); asort( $tzRegions ); $prefill = array_fill_keys( array_values( $tzRegions ), array() ); $opt = array_merge( $opt, $prefill ); $now = date_create( 'now' ); foreach ( $tzs as $tz ) { $z = explode( '/', $tz, 2 ); # timezone_identifiers_list() returns a number of # backwards-compatibility entries. This filters them out of the # list presented to the user. if ( count( $z ) != 2 || !array_key_exists( $z[0], $tzRegions ) ) { continue; } # Localize region $z[0] = $tzRegions[$z[0]]; $minDiff = floor( timezone_offset_get( timezone_open( $tz ), $now ) / 60 ); $display = str_replace( '_', ' ', $z[0] . '/' . $z[1] ); $value = "ZoneInfo|$minDiff|$tz"; $opt[$z[0]][$display] = $value; } } return $opt; }
/** * Get a short description for a tag. * * Checks if message key "mediawiki:tag-$tag" exists. If it does not, * returns the HTML-escaped tag name. Uses the message if the message * exists, provided it is not disabled. If the message is disabled, * we consider the tag hidden, and return false. * * @param string $tag Tag * @param IContextSource $context * @return string|bool Tag description or false if tag is to be hidden. * @since 1.25 Returns false if tag is to be hidden. */ public static function tagDescription($tag, IContextSource $context) { $msg = $context->msg("tag-{$tag}"); if (!$msg->exists()) { // No such message, so return the HTML-escaped tag name. return htmlspecialchars($tag); } if ($msg->isDisabled()) { // The message exists but is disabled, hide the tag. return false; } // Message exists and isn't disabled, use it. return $msg->parse(); }