示例#1
0
 /**
  * Constructor.
  *
  * @param IContextSource $context
  * @param array $conds
  * @param string $className
  */
 public function __construct(IContextSource $context, array $conds, $className)
 {
     $this->conds = $conds;
     $this->className = $className;
     $this->context = $context;
     $this->mDefaultDirection = true;
     parent::__construct($context);
     $this->context->getOutput()->addModules('ep.pager');
 }
示例#2
0
 /**
  * Display a pager with articles.
  *
  * @since 0.1
  *
  * @param IContextSource $context
  * @param array $conditions
  */
 public static function displayPager(IContextSource $context, array $conditions = array())
 {
     $pager = new EPArticlePager($context, $conditions);
     if ($pager->getNumRows()) {
         $context->getOutput()->addHTML($pager->getFilterControl() . $pager->getNavigationBar() . $pager->getBody() . $pager->getNavigationBar() . $pager->getMultipleItemControl());
     } else {
         $context->getOutput()->addHTML($pager->getFilterControl(true));
         $context->getOutput()->addWikiMsg('ep-articles-noresults');
     }
 }
 public function includeAssets()
 {
     TranslationHelpers::addModules($this->context->getOutput());
     $pages = array();
     foreach ($this->collection->getTitles() as $title) {
         $pages[] = $title->getPrefixedDBKey();
     }
     $vars = array('trlKeys' => $pages);
     $this->context->getOutput()->addScript(Skin::makeVariablesScript($vars));
 }
 /**
  * @param $context IContextSource
  * @param $pageType
  */
 public static function addNavigationLinks(IContextSource $context, $pageType)
 {
     $linkDefs = array('home' => 'Special:AbuseFilter', 'recentchanges' => 'Special:AbuseFilter/history', 'examine' => 'Special:AbuseFilter/examine', 'log' => 'Special:AbuseLog');
     if ($context->getUser()->isAllowed('abusefilter-modify')) {
         $linkDefs = array_merge($linkDefs, array('test' => 'Special:AbuseFilter/test', 'tools' => 'Special:AbuseFilter/tools', 'import' => 'Special:AbuseFilter/import'));
     }
     // Save some translator work
     $msgOverrides = array('recentchanges' => 'abusefilter-filter-log');
     $links = array();
     foreach ($linkDefs as $name => $page) {
         // Give grep a chance to find the usages:
         // abusefilter-topnav-home, abusefilter-topnav-test, abusefilter-topnav-examine
         // abusefilter-topnav-log, abusefilter-topnav-tools, abusefilter-topnav-import
         $msgName = "abusefilter-topnav-{$name}";
         if (isset($msgOverrides[$name])) {
             $msgName = $msgOverrides[$name];
         }
         $msg = wfMessage($msgName)->parse();
         $title = Title::newFromText($page);
         if ($name == $pageType) {
             $links[] = Xml::tags('strong', null, $msg);
         } else {
             $links[] = Linker::link($title, $msg);
         }
     }
     $linkStr = wfMessage('parentheses', $context->getLanguage()->pipeList($links))->text();
     $linkStr = wfMessage('abusefilter-topnav')->parse() . " {$linkStr}";
     $linkStr = Xml::tags('div', array('class' => 'mw-abusefilter-navigation'), $linkStr);
     $context->getOutput()->setSubtitle($linkStr);
 }
示例#5
0
 private function main()
 {
     global $wgUseFileCache, $wgTitle, $wgUseAjax;
     wfProfileIn(__METHOD__);
     $request = $this->context->getRequest();
     // Send Ajax requests to the Ajax dispatcher.
     if ($wgUseAjax && $request->getVal('action', 'view') == 'ajax') {
         // Set a dummy title, because $wgTitle == null might break things
         $title = Title::makeTitle(NS_MAIN, 'AJAX');
         $this->context->setTitle($title);
         $wgTitle = $title;
         $dispatcher = new AjaxDispatcher();
         $dispatcher->performAction();
         wfProfileOut(__METHOD__);
         return;
     }
     // Get title from request parameters,
     // is set on the fly by parseTitle the first time.
     $title = $this->getTitle();
     $action = $this->getAction();
     $wgTitle = $title;
     if ($wgUseFileCache && $title->getNamespace() >= 0) {
         wfProfileIn('main-try-filecache');
         if (HTMLFileCache::useFileCache($this->context)) {
             // Try low-level file cache hit
             $cache = HTMLFileCache::newFromTitle($title, $action);
             if ($cache->isCacheGood()) {
                 // Check incoming headers to see if client has this cached
                 $timestamp = $cache->cacheTimestamp();
                 if (!$this->context->getOutput()->checkLastModified($timestamp)) {
                     $cache->loadFromFileCache($this->context);
                 }
                 // Do any stats increment/watchlist stuff
                 $this->context->getWikiPage()->doViewUpdates($this->context->getUser());
                 // Tell OutputPage that output is taken care of
                 $this->context->getOutput()->disable();
                 wfProfileOut('main-try-filecache');
                 wfProfileOut(__METHOD__);
                 return;
             }
         }
         wfProfileOut('main-try-filecache');
     }
     $this->performRequest();
     // Now commit any transactions, so that unreported errors after
     // output() don't roll back the whole DB transaction
     wfGetLBFactory()->commitMasterChanges();
     // Output everything!
     $this->context->getOutput()->output();
     wfProfileOut(__METHOD__);
 }
示例#6
0
 private function main()
 {
     global $wgUseFileCache, $wgTitle, $wgUseAjax;
     wfProfileIn(__METHOD__);
     $request = $this->context->getRequest();
     // Send Ajax requests to the Ajax dispatcher.
     if ($wgUseAjax && $request->getVal('action', 'view') == 'ajax') {
         // Set a dummy title, because $wgTitle == null might break things
         // Wikia change - start
         // @author macbre, wladek
         $title = Wikia::createTitleFromRequest($request);
         // Wikia change - end
         $this->context->setTitle($title);
         $wgTitle = $title;
         $dispatcher = new AjaxDispatcher();
         $dispatcher->performAction();
         wfProfileOut(__METHOD__);
         return;
     }
     // Get title from request parameters,
     // is set on the fly by parseTitle the first time.
     $title = $this->getTitle();
     $action = $this->getAction();
     $wgTitle = $title;
     if ($wgUseFileCache && $title->getNamespace() >= 0) {
         wfProfileIn('main-try-filecache');
         if (HTMLFileCache::useFileCache($this->context)) {
             // Try low-level file cache hit
             $cache = HTMLFileCache::newFromTitle($title, $action);
             if ($cache->isCacheGood()) {
                 // Check incoming headers to see if client has this cached
                 $timestamp = $cache->cacheTimestamp();
                 if (!$this->context->getOutput()->checkLastModified($timestamp)) {
                     $cache->loadFromFileCache($this->context);
                 }
                 // Do any stats increment/watchlist stuff
                 $this->context->getWikiPage()->doViewUpdates($this->context->getUser());
                 // Tell OutputPage that output is taken care of
                 $this->context->getOutput()->disable();
                 wfProfileOut('main-try-filecache');
                 wfProfileOut(__METHOD__);
                 return;
             }
         }
         wfProfileOut('main-try-filecache');
     }
     $this->performRequest();
     $this->finalCleanup();
     wfProfileOut(__METHOD__);
 }
示例#7
0
 private function main()
 {
     global $wgUseFileCache, $wgTitle, $wgUseAjax;
     wfProfileIn(__METHOD__);
     # Set title from request parameters
     $wgTitle = $this->getTitle();
     $action = $this->getAction();
     $user = $this->context->getUser();
     # Send Ajax requests to the Ajax dispatcher.
     if ($wgUseAjax && $action == 'ajax') {
         $dispatcher = new AjaxDispatcher();
         $dispatcher->performAction();
         wfProfileOut(__METHOD__);
         return;
     }
     if ($wgUseFileCache && $wgTitle->getNamespace() != NS_SPECIAL) {
         wfProfileIn('main-try-filecache');
         // Raw pages should handle cache control on their own,
         // even when using file cache. This reduces hits from clients.
         if (HTMLFileCache::useFileCache()) {
             /* Try low-level file cache hit */
             $cache = new HTMLFileCache($wgTitle, $action);
             if ($cache->isFileCacheGood()) {
                 /* Check incoming headers to see if client has this cached */
                 $timestamp = $cache->fileCacheTime();
                 if (!$this->context->getOutput()->checkLastModified($timestamp)) {
                     $cache->loadFromFileCache();
                 }
                 # Do any stats increment/watchlist stuff
                 $article = WikiPage::factory($wgTitle);
                 $article->doViewUpdates($user);
                 # Tell OutputPage that output is taken care of
                 $this->context->getOutput()->disable();
                 wfProfileOut('main-try-filecache');
                 wfProfileOut(__METHOD__);
                 return;
             }
         }
         wfProfileOut('main-try-filecache');
     }
     $this->performRequest();
     $this->finalCleanup();
     wfProfileOut(__METHOD__);
 }
 /**
  * @param IContextSource $context
  *
  * @return string HTML
  */
 public function getHtml(IContextSource $context)
 {
     $context->getOutput()->addModules('ext.translate.statsbar');
     $total = $this->stats[MessageGroupStats::TOTAL];
     $proofread = $this->stats[MessageGroupStats::PROOFREAD];
     $translated = $this->stats[MessageGroupStats::TRANSLATED];
     $fuzzy = $this->stats[MessageGroupStats::FUZZY];
     if (!$total) {
         $untranslated = null;
         $wproofread = $wtranslated = $wfuzzy = $wuntranslated = 0;
     } else {
         // Proofread is subset of translated
         $untranslated = $total - $translated - $fuzzy;
         $wproofread = round(100 * $proofread / $total, 2);
         $wtranslated = round(100 * ($translated - $proofread) / $total, 2);
         $wfuzzy = round(100 * $fuzzy / $total, 2);
         $wuntranslated = round(100 - $wproofread - $wtranslated - $wfuzzy, 2);
     }
     return Html::rawElement('div', array('class' => 'tux-statsbar', 'data-total' => $total, 'data-group' => $this->group, 'data-language' => $this->language), Html::element('span', array('class' => 'tux-proofread', 'style' => "width: {$wproofread}%", 'data-proofread' => $proofread)) . Html::element('span', array('class' => 'tux-translated', 'style' => "width: {$wtranslated}%", 'data-translated' => $translated)) . Html::element('span', array('class' => 'tux-fuzzy', 'style' => "width: {$wfuzzy}%", 'data-fuzzy' => $fuzzy)) . Html::element('span', array('class' => 'tux-untranslated', 'style' => "width: {$wuntranslated}%", 'data-untranslated' => $untranslated)));
 }
示例#9
0
 private function main()
 {
     global $wgUseFileCache, $wgTitle, $wgUseAjax;
     wfProfileIn(__METHOD__);
     $request = $this->context->getRequest();
     // Send Ajax requests to the Ajax dispatcher.
     if ($wgUseAjax && $request->getVal('action', 'view') == 'ajax') {
         // Set a dummy title, because $wgTitle == null might break things
         $title = Title::makeTitle(NS_MAIN, 'AJAX');
         $this->context->setTitle($title);
         $wgTitle = $title;
         $dispatcher = new AjaxDispatcher();
         $dispatcher->performAction();
         wfProfileOut(__METHOD__);
         return;
     }
     // Get title from request parameters,
     // is set on the fly by parseTitle the first time.
     $title = $this->getTitle();
     $action = $this->getAction();
     $wgTitle = $title;
     // If the user has forceHTTPS set to true, or if the user
     // is in a group requiring HTTPS, or if they have the HTTPS
     // preference set, redirect them to HTTPS.
     // Note: Do this after $wgTitle is setup, otherwise the hooks run from
     // isLoggedIn() will do all sorts of weird stuff.
     if (($request->getCookie('forceHTTPS', '') || $request->getCookie('forceHTTPS') || $this->context->getUser()->isLoggedIn() && $this->context->getUser()->requiresHTTPS()) && $request->getProtocol() == 'http') {
         $oldUrl = $request->getFullRequestURL();
         $redirUrl = str_replace('http://', 'https://', $oldUrl);
         if ($request->wasPosted()) {
             // This is weird and we'd hope it almost never happens. This
             // means that a POST came in via HTTP and policy requires us
             // redirecting to HTTPS. It's likely such a request is going
             // to fail due to post data being lost, but let's try anyway
             // and just log the instance.
             //
             // @todo @fixme See if we could issue a 307 or 308 here, need
             // to see how clients (automated & browser) behave when we do
             wfDebugLog('RedirectedPosts', "Redirected from HTTP to HTTPS: {$oldUrl}");
         }
         // Setup dummy Title, otherwise OutputPage::redirect will fail
         $title = Title::newFromText(NS_MAIN, 'REDIR');
         $this->context->setTitle($title);
         $output = $this->context->getOutput();
         // Since we only do this redir to change proto, always send a vary header
         $output->addVaryHeader('X-Forwarded-Proto');
         $output->redirect($redirUrl);
         $output->output();
         wfProfileOut(__METHOD__);
         return;
     }
     if ($wgUseFileCache && $title->getNamespace() >= 0) {
         wfProfileIn('main-try-filecache');
         if (HTMLFileCache::useFileCache($this->context)) {
             // Try low-level file cache hit
             $cache = HTMLFileCache::newFromTitle($title, $action);
             if ($cache->isCacheGood()) {
                 // Check incoming headers to see if client has this cached
                 $timestamp = $cache->cacheTimestamp();
                 if (!$this->context->getOutput()->checkLastModified($timestamp)) {
                     $cache->loadFromFileCache($this->context);
                 }
                 // Do any stats increment/watchlist stuff
                 // Assume we're viewing the latest revision (this should always be the case with file cache)
                 $this->context->getWikiPage()->doViewUpdates($this->context->getUser());
                 // Tell OutputPage that output is taken care of
                 $this->context->getOutput()->disable();
                 wfProfileOut('main-try-filecache');
                 wfProfileOut(__METHOD__);
                 return;
             }
         }
         wfProfileOut('main-try-filecache');
     }
     // Actually do the work of the request and build up any output
     $this->performRequest();
     // Either all DB and deferred updates should happen or none.
     // The later should not be cancelled due to client disconnect.
     ignore_user_abort(true);
     // Now commit any transactions, so that unreported errors after
     // output() don't roll back the whole DB transaction
     wfGetLBFactory()->commitMasterChanges();
     // Output everything!
     $this->context->getOutput()->output();
     wfProfileOut(__METHOD__);
 }
示例#10
0
 /**
  * Get the OutputPage being used for this instance.
  * IndexPager extends ContextSource as of 1.19.
  *
  * @since 0.1
  *
  * @return OutputPage
  */
 public function getOutput()
 {
     return $this->context->getOutput();
 }
 private function main()
 {
     global $wgTitle;
     $request = $this->context->getRequest();
     // Send Ajax requests to the Ajax dispatcher.
     if ($this->config->get('UseAjax') && $request->getVal('action') === 'ajax') {
         // Set a dummy title, because $wgTitle == null might break things
         $title = Title::makeTitle(NS_SPECIAL, 'Badtitle/performing an AJAX call in ' . __METHOD__);
         $this->context->setTitle($title);
         $wgTitle = $title;
         $dispatcher = new AjaxDispatcher($this->config);
         $dispatcher->performAction($this->context->getUser());
         return;
     }
     // Get title from request parameters,
     // is set on the fly by parseTitle the first time.
     $title = $this->getTitle();
     $action = $this->getAction();
     $wgTitle = $title;
     $trxProfiler = Profiler::instance()->getTransactionProfiler();
     $trxProfiler->setLogger(LoggerFactory::getInstance('DBPerformance'));
     // Aside from rollback, master queries should not happen on GET requests.
     // Periodic or "in passing" updates on GET should use the job queue.
     if (!$request->wasPosted() && in_array($action, array('view', 'edit', 'history'))) {
         $trxProfiler->setExpectation('masterConns', 0, __METHOD__);
         $trxProfiler->setExpectation('writes', 0, __METHOD__);
     } else {
         $trxProfiler->setExpectation('maxAffected', 500, __METHOD__);
     }
     // If the user has forceHTTPS set to true, or if the user
     // is in a group requiring HTTPS, or if they have the HTTPS
     // preference set, redirect them to HTTPS.
     // Note: Do this after $wgTitle is setup, otherwise the hooks run from
     // isLoggedIn() will do all sorts of weird stuff.
     if ($request->getProtocol() == 'http' && ($request->getCookie('forceHTTPS', '') || $request->getCookie('forceHTTPS') || $this->context->getUser()->isLoggedIn() && $this->context->getUser()->requiresHTTPS())) {
         $oldUrl = $request->getFullRequestURL();
         $redirUrl = preg_replace('#^http://#', 'https://', $oldUrl);
         // ATTENTION: This hook is likely to be removed soon due to overall design of the system.
         if (Hooks::run('BeforeHttpsRedirect', array($this->context, &$redirUrl))) {
             if ($request->wasPosted()) {
                 // This is weird and we'd hope it almost never happens. This
                 // means that a POST came in via HTTP and policy requires us
                 // redirecting to HTTPS. It's likely such a request is going
                 // to fail due to post data being lost, but let's try anyway
                 // and just log the instance.
                 //
                 // @todo FIXME: See if we could issue a 307 or 308 here, need
                 // to see how clients (automated & browser) behave when we do
                 wfDebugLog('RedirectedPosts', "Redirected from HTTP to HTTPS: {$oldUrl}");
             }
             // Setup dummy Title, otherwise OutputPage::redirect will fail
             $title = Title::newFromText('REDIR', NS_MAIN);
             $this->context->setTitle($title);
             $output = $this->context->getOutput();
             // Since we only do this redir to change proto, always send a vary header
             $output->addVaryHeader('X-Forwarded-Proto');
             $output->redirect($redirUrl);
             $output->output();
             return;
         }
     }
     if ($this->config->get('UseFileCache') && $title->getNamespace() >= 0) {
         if (HTMLFileCache::useFileCache($this->context)) {
             // Try low-level file cache hit
             $cache = new HTMLFileCache($title, $action);
             if ($cache->isCacheGood()) {
                 // Check incoming headers to see if client has this cached
                 $timestamp = $cache->cacheTimestamp();
                 if (!$this->context->getOutput()->checkLastModified($timestamp)) {
                     $cache->loadFromFileCache($this->context);
                 }
                 // Do any stats increment/watchlist stuff
                 // Assume we're viewing the latest revision (this should always be the case with file cache)
                 $this->context->getWikiPage()->doViewUpdates($this->context->getUser());
                 // Tell OutputPage that output is taken care of
                 $this->context->getOutput()->disable();
                 return;
             }
         }
     }
     // Actually do the work of the request and build up any output
     $this->performRequest();
     // Either all DB and deferred updates should happen or none.
     // The later should not be cancelled due to client disconnect.
     ignore_user_abort(true);
     // Now commit any transactions, so that unreported errors after
     // output() don't roll back the whole DB transaction
     wfGetLBFactory()->commitMasterChanges();
     // Output everything!
     $this->context->getOutput()->output();
 }
示例#12
0
 /**
  * Just like executePath() but will override global variables and execute
  * the page in "inclusion" mode. Returns true if the execution was
  * successful or false if there was no such special page, or a title object
  * if it was a redirect.
  *
  * Also saves the current $wgTitle, $wgOut, $wgRequest, $wgUser and $wgLang
  * variables so that the special page will get the context it'd expect on a
  * normal request, and then restores them to their previous values after.
  *
  * @param $title Title
  * @param $context IContextSource
  *
  * @return String: HTML fragment
  */
 static function capturePath(Title $title, IContextSource $context)
 {
     global $wgOut, $wgTitle, $wgRequest, $wgUser, $wgLang;
     // Save current globals
     $oldTitle = $wgTitle;
     $oldOut = $wgOut;
     $oldRequest = $wgRequest;
     $oldUser = $wgUser;
     $oldLang = $wgLang;
     // Set the globals to the current context
     $wgTitle = $title;
     $wgOut = $context->getOutput();
     $wgRequest = $context->getRequest();
     $wgUser = $context->getUser();
     $wgLang = $context->getLanguage();
     // The useful part
     $ret = self::executePath($title, $context, true);
     // And restore the old globals
     $wgTitle = $oldTitle;
     $wgOut = $oldOut;
     $wgRequest = $oldRequest;
     $wgUser = $oldUser;
     $wgLang = $oldLang;
     return $ret;
 }
示例#13
0
 /**
  * Adds a control to add a term org to the provided context.
  * Additional arguments can be provided to set the default values for the control fields.
  *
  * @since 0.1
  *
  * @param IContextSource $context
  * @param array $args
  *
  * @return boolean
  */
 public static function displayAddNewControl(IContextSource $context, array $args)
 {
     if (!$context->getUser()->isAllowed('ep-course')) {
         return false;
     }
     $out = $context->getOutput();
     $out->addModules('ep.addcourse');
     $out->addHTML(Html::openElement('form', array('method' => 'post', 'action' => self::getTitleFor('NAME_PLACEHOLDER')->getLocalURL(array('action' => 'edit')))));
     $out->addHTML('<fieldset>');
     $out->addHTML('<legend>' . wfMsgHtml('ep-courses-addnew') . '</legend>');
     $out->addElement('p', array(), wfMsg('ep-courses-namedoc'));
     $out->addElement('label', array('for' => 'neworg'), wfMsg('ep-courses-neworg'));
     $select = new XmlSelect('neworg', 'neworg', array_key_exists('org', $args) ? $args['org'] : false);
     $select->addOptions(EPOrg::getOrgOptions());
     $out->addHTML($select->getHTML());
     $out->addHTML('&#160;' . Xml::inputLabel(wfMsg('ep-courses-newname'), 'newname', 'newname', 20, array_key_exists('name', $args) ? $args['name'] : false));
     $out->addHTML('&#160;' . Xml::inputLabel(wfMsg('ep-courses-newterm'), 'newterm', 'newterm', 10, array_key_exists('term', $args) ? $args['term'] : false));
     $out->addHTML('&#160;' . Html::input('addnewcourse', wfMsg('ep-courses-add'), 'submit', array('disabled' => 'disabled', 'class' => 'ep-course-add')));
     $out->addHTML(Html::hidden('isnew', 1));
     $out->addHTML('</fieldset></form>');
     return true;
 }
示例#14
0
 /**
  * Adds a navigation menu with the provided links.
  * Links should be provided in an array with:
  * label => Title (object)
  * 
  * @since 0.1
  * 
  * @param IContextSource $context
  * @param array $items
  */
 public static function displayNavigation(IContextSource $context, array $items = array())
 {
     $links = array();
     foreach ($items as $label => $data) {
         if (is_array($data)) {
             $target = array_shift($data);
             $attribs = $data;
         } else {
             $target = $data;
             $attribs = array();
         }
         $links[] = Linker::linkKnown($target, htmlspecialchars($label), $attribs);
     }
     $context->getOutput()->addHTML(Html::rawElement('p', array(), $context->getLanguage()->pipeList($links)));
 }
 /**
  * Returns the tool links for this mentor.
  * 
  * @since 0.1
  * 
  * @param IContextSource $context
  * @param EPCourse|null $course
  * 
  * @return string
  */
 public function getToolLinks(IContextSource $context, EPCourse $course = null)
 {
     $links = array();
     $links[] = Linker::userTalkLink($this->getUser()->getId(), $this->getUser()->getName());
     $links[] = Linker::link(SpecialPage::getTitleFor('Contributions', $this->getUser()->getName()), wfMsgHtml('contribslink'));
     if (!is_null($course) && ($context->getUser()->isAllowed('ep-instructor') || $this->getUser()->getId() == $context->getUser()->getId())) {
         $links[] = Html::element('a', array('href' => '#', 'class' => 'ep-instructor-remove', 'data-courseid' => $course->getId(), 'data-coursename' => $course->getField('name'), 'data-userid' => $this->getUser()->getId(), 'data-username' => $this->getUser()->getName(), 'data-bestname' => $this->getName()), wfMsg('ep-instructor-remove'));
         $context->getOutput()->addModules('ep.instructor');
     }
     return ' <span class="mw-usertoollinks">(' . $context->getLanguage()->pipeList($links) . ')</span>';
 }
 /**
  * Hook to provide syntax highlighting for API pretty-printed output
  *
  * @param IContextSource $context
  * @param string $text
  * @param string $mime
  * @param string $format
  * @since MW 1.24
  */
 public static function onApiFormatHighlight(IContextSource $context, $text, $mime, $format)
 {
     if (!isset(self::$mimeLexers[$mime])) {
         return true;
     }
     $lexer = self::$mimeLexers[$mime];
     $status = self::highlight($text, $lexer);
     if (!$status->isOK()) {
         return true;
     }
     $out = $status->getValue();
     if (preg_match('/^<pre([^>]*)>/i', $out, $m)) {
         $attrs = Sanitizer::decodeTagAttributes($m[1]);
         $attrs['class'] .= ' api-pretty-content';
         $encodedAttrs = Sanitizer::safeEncodeTagAttributes($attrs);
         $out = '<pre' . $encodedAttrs . '>' . substr($out, strlen($m[0]));
     }
     $output = $context->getOutput();
     $output->addModuleStyles('ext.pygments');
     $output->addHTML('<div dir="ltr">' . $out . '</div>');
     // Inform MediaWiki that we have parsed this page and it shouldn't mess with it.
     return false;
 }
示例#17
0
 /**
  * Save submitted protection form
  *
  * @return bool Success
  */
 function save()
 {
     # Permission check!
     if ($this->disabled) {
         $this->show();
         return false;
     }
     $request = $this->mContext->getRequest();
     $user = $this->mContext->getUser();
     $out = $this->mContext->getOutput();
     $token = $request->getVal('wpEditToken');
     if (!$user->matchEditToken($token, ['protect', $this->mTitle->getPrefixedDBkey()])) {
         $this->show(['sessionfailure']);
         return false;
     }
     # Create reason string. Use list and/or custom string.
     $reasonstr = $this->mReasonSelection;
     if ($reasonstr != 'other' && $this->mReason != '') {
         // Entry from drop down menu + additional comment
         $reasonstr .= $this->mContext->msg('colon-separator')->text() . $this->mReason;
     } elseif ($reasonstr == 'other') {
         $reasonstr = $this->mReason;
     }
     $expiry = [];
     foreach ($this->mApplicableTypes as $action) {
         $expiry[$action] = $this->getExpiry($action);
         if (empty($this->mRestrictions[$action])) {
             continue;
             // unprotected
         }
         if (!$expiry[$action]) {
             $this->show(['protect_expiry_invalid']);
             return false;
         }
         if ($expiry[$action] < wfTimestampNow()) {
             $this->show(['protect_expiry_old']);
             return false;
         }
     }
     $this->mCascade = $request->getBool('mwProtect-cascade');
     $status = $this->mArticle->doUpdateRestrictions($this->mRestrictions, $expiry, $this->mCascade, $reasonstr, $user);
     if (!$status->isOK()) {
         $this->show($out->parseInline($status->getWikiText()));
         return false;
     }
     /**
      * Give extensions a change to handle added form items
      *
      * @since 1.19 you can (and you should) return false to abort saving;
      *             you can also return an array of message name and its parameters
      */
     $errorMsg = '';
     if (!Hooks::run('ProtectionForm::save', [$this->mArticle, &$errorMsg, $reasonstr])) {
         if ($errorMsg == '') {
             $errorMsg = ['hookaborted'];
         }
     }
     if ($errorMsg != '') {
         $this->show($errorMsg);
         return false;
     }
     WatchAction::doWatchOrUnwatch($request->getCheck('mwProtectWatch'), $this->mTitle, $user);
     return true;
 }
 /**
  * Hook to provide syntax highlighting for API pretty-printed output
  *
  * @param IContextSource $context
  * @param string $text
  * @param string $mime
  * @param string $format
  * @since MW 1.24
  */
 public static function apiFormatHighlight(IContextSource $context, $text, $mime, $format)
 {
     switch ($mime) {
         case 'text/javascript':
         case 'application/json':
             $lang = 'javascript';
             break;
         case 'text/xml':
             $lang = 'xml';
             break;
         default:
             // Don't know how to handle this
             return true;
     }
     $geshi = self::prepare($text, $lang);
     if ($geshi instanceof GeSHi) {
         $out = $geshi->parse_code();
         if (!$geshi->error()) {
             if (preg_match('/^<pre([^>]*)>/i', $out, $m)) {
                 $attrs = Sanitizer::decodeTagAttributes($m[1]);
                 $attrs['class'] .= ' api-pretty-content';
                 $out = '<pre' . Sanitizer::safeEncodeTagAttributes($attrs) . '>' . substr($out, strlen($m[0]));
             }
             $output = $context->getOutput();
             $output->addModuleStyles(array("ext.geshi.language.{$lang}", 'ext.geshi.local'));
             $output->addHTML("<div dir=\"ltr\">{$out}</div>");
             // Inform MediaWiki that we have parsed this page and it shouldn't mess with it.
             return false;
         }
     }
     // Bottle out
     return true;
 }
示例#19
0
 private function main()
 {
     global $wgTitle;
     $output = $this->context->getOutput();
     $request = $this->context->getRequest();
     // Send Ajax requests to the Ajax dispatcher.
     if ($this->config->get('UseAjax') && $request->getVal('action') === 'ajax') {
         // Set a dummy title, because $wgTitle == null might break things
         $title = Title::makeTitle(NS_SPECIAL, 'Badtitle/performing an AJAX call in ' . __METHOD__);
         $this->context->setTitle($title);
         $wgTitle = $title;
         $dispatcher = new AjaxDispatcher($this->config);
         $dispatcher->performAction($this->context->getUser());
         return;
     }
     // Get title from request parameters,
     // is set on the fly by parseTitle the first time.
     $title = $this->getTitle();
     $action = $this->getAction();
     $wgTitle = $title;
     // Set DB query expectations for this HTTP request
     $trxLimits = $this->config->get('TrxProfilerLimits');
     $trxProfiler = Profiler::instance()->getTransactionProfiler();
     $trxProfiler->setLogger(LoggerFactory::getInstance('DBPerformance'));
     if ($request->hasSafeMethod()) {
         $trxProfiler->setExpectations($trxLimits['GET'], __METHOD__);
     } else {
         $trxProfiler->setExpectations($trxLimits['POST'], __METHOD__);
     }
     // If the user has forceHTTPS set to true, or if the user
     // is in a group requiring HTTPS, or if they have the HTTPS
     // preference set, redirect them to HTTPS.
     // Note: Do this after $wgTitle is setup, otherwise the hooks run from
     // isLoggedIn() will do all sorts of weird stuff.
     if ($request->getProtocol() == 'http' && preg_match('#^https://#', wfExpandUrl($request->getRequestURL(), PROTO_HTTPS)) && ($request->getSession()->shouldForceHTTPS() || $request->getCookie('forceHTTPS', '') || $request->getCookie('forceHTTPS') || $this->context->getUser()->isLoggedIn() && $this->context->getUser()->requiresHTTPS())) {
         $oldUrl = $request->getFullRequestURL();
         $redirUrl = preg_replace('#^http://#', 'https://', $oldUrl);
         // ATTENTION: This hook is likely to be removed soon due to overall design of the system.
         if (Hooks::run('BeforeHttpsRedirect', [$this->context, &$redirUrl])) {
             if ($request->wasPosted()) {
                 // This is weird and we'd hope it almost never happens. This
                 // means that a POST came in via HTTP and policy requires us
                 // redirecting to HTTPS. It's likely such a request is going
                 // to fail due to post data being lost, but let's try anyway
                 // and just log the instance.
                 // @todo FIXME: See if we could issue a 307 or 308 here, need
                 // to see how clients (automated & browser) behave when we do
                 wfDebugLog('RedirectedPosts', "Redirected from HTTP to HTTPS: {$oldUrl}");
             }
             // Setup dummy Title, otherwise OutputPage::redirect will fail
             $title = Title::newFromText('REDIR', NS_MAIN);
             $this->context->setTitle($title);
             // Since we only do this redir to change proto, always send a vary header
             $output->addVaryHeader('X-Forwarded-Proto');
             $output->redirect($redirUrl);
             $output->output();
             return;
         }
     }
     if ($title->canExist() && HTMLFileCache::useFileCache($this->context)) {
         // Try low-level file cache hit
         $cache = new HTMLFileCache($title, $action);
         if ($cache->isCacheGood()) {
             // Check incoming headers to see if client has this cached
             $timestamp = $cache->cacheTimestamp();
             if (!$output->checkLastModified($timestamp)) {
                 $cache->loadFromFileCache($this->context);
             }
             // Do any stats increment/watchlist stuff, assuming user is viewing the
             // latest revision (which should always be the case for file cache)
             $this->context->getWikiPage()->doViewUpdates($this->context->getUser());
             // Tell OutputPage that output is taken care of
             $output->disable();
             return;
         }
     }
     // Actually do the work of the request and build up any output
     $this->performRequest();
     // GUI-ify and stash the page output in MediaWiki::doPreOutputCommit() while
     // ChronologyProtector synchronizes DB positions or slaves accross all datacenters.
     $buffer = null;
     $outputWork = function () use($output, &$buffer) {
         if ($buffer === null) {
             $buffer = $output->output(true);
         }
         return $buffer;
     };
     // Now commit any transactions, so that unreported errors after
     // output() don't roll back the whole DB transaction and so that
     // we avoid having both success and error text in the response
     $this->doPreOutputCommit($outputWork);
     // Now send the actual output
     print $outputWork();
 }
示例#20
0
 /**
  * Read from cache to context output
  * @param IContextSource $context
  * @param integer $mode One of the HTMLFileCache::MODE_* constants
  * @return void
  */
 public function loadFromFileCache(IContextSource $context, $mode = self::MODE_NORMAL)
 {
     global $wgContLang;
     $config = MediaWikiServices::getInstance()->getMainConfig();
     wfDebug(__METHOD__ . "()\n");
     $filename = $this->cachePath();
     if ($mode === self::MODE_OUTAGE) {
         // Avoid DB errors for queries in sendCacheControl()
         $context->getTitle()->resetArticleID(0);
     }
     $context->getOutput()->sendCacheControl();
     header("Content-Type: {$config->get('MimeType')}; charset=UTF-8");
     header("Content-Language: {$wgContLang->getHtmlCode()}");
     if ($this->useGzip()) {
         if (wfClientAcceptsGzip()) {
             header('Content-Encoding: gzip');
             readfile($filename);
         } else {
             /* Send uncompressed */
             wfDebug(__METHOD__ . " uncompressing cache file and sending it\n");
             readgzfile($filename);
         }
     } else {
         readfile($filename);
     }
     $context->getOutput()->disable();
     // tell $wgOut that output is taken care of
 }
示例#21
0
 /**
  * Read from cache to context output
  * @param $context IContextSource
  * @return void
  */
 public function loadFromFileCache(IContextSource $context)
 {
     global $wgMimeType, $wgLanguageCode;
     wfDebug(__METHOD__ . "()\n");
     $filename = $this->cachePath();
     $context->getOutput()->sendCacheControl();
     header("Content-Type: {$wgMimeType}; charset=UTF-8");
     header("Content-Language: {$wgLanguageCode}");
     if ($this->useGzip()) {
         if (wfClientAcceptsGzip()) {
             header('Content-Encoding: gzip');
             readfile($filename);
         } else {
             /* Send uncompressed */
             wfDebug(__METHOD__ . " uncompressing cache file and sending it\n");
             readgzfile($filename);
         }
     } else {
         readfile($filename);
     }
     $context->getOutput()->disable();
     // tell $wgOut that output is taken care of
 }
示例#22
0
 /**
  * Adds a control to add a term org to the provided context.
  * Additional arguments can be provided to set the default values for the control fields.
  *
  * @since 0.1
  *
  * @param IContextSource $context
  * @param array $args
  *
  * @return boolean
  */
 public static function displayAddNewControl(IContextSource $context, array $args)
 {
     if (!$context->getUser()->isAllowed('ep-term')) {
         return false;
     }
     $out = $context->getOutput();
     $out->addHTML(Html::openElement('form', array('method' => 'post', 'action' => SpecialPage::getTitleFor('EditTerm')->getLocalURL())));
     $out->addHTML('<fieldset>');
     $out->addHTML('<legend>' . wfMsgHtml('ep-terms-addnew') . '</legend>');
     $out->addHTML(Html::element('p', array(), wfMsg('ep-terms-namedoc')));
     $out->addHTML(Html::element('label', array('for' => 'newcourse'), wfMsg('ep-terms-newcourse')));
     $select = new XmlSelect('newcourse', 'newcourse', array_key_exists('course', $args) ? $args['course'] : false);
     $select->addOptions(EPCourse::getCourseOptions());
     $out->addHTML($select->getHTML());
     $out->addHTML('&#160;' . Xml::inputLabel(wfMsg('ep-terms-newyear'), 'newyear', 'newyear', 10));
     $out->addHTML('&#160;' . Html::input('addnewterm', wfMsg('ep-terms-add'), 'submit'));
     $out->addHTML(Html::hidden('isnew', 1));
     $out->addHTML('</fieldset></form>');
     return true;
 }
示例#23
0
 /**
  * Just like executePath() but will override global variables and execute
  * the page in "inclusion" mode. Returns true if the execution was
  * successful or false if there was no such special page, or a title object
  * if it was a redirect.
  *
  * Also saves the current $wgTitle, $wgOut, $wgRequest, $wgUser and $wgLang
  * variables so that the special page will get the context it'd expect on a
  * normal request, and then restores them to their previous values after.
  *
  * @param Title $title
  * @param IContextSource $context
  * @return string HTML fragment
  */
 public static function capturePath(Title $title, IContextSource $context)
 {
     global $wgTitle, $wgOut, $wgRequest, $wgUser, $wgLang;
     $main = RequestContext::getMain();
     // Save current globals and main context
     $glob = ['title' => $wgTitle, 'output' => $wgOut, 'request' => $wgRequest, 'user' => $wgUser, 'language' => $wgLang];
     $ctx = ['title' => $main->getTitle(), 'output' => $main->getOutput(), 'request' => $main->getRequest(), 'user' => $main->getUser(), 'language' => $main->getLanguage()];
     // Override
     $wgTitle = $title;
     $wgOut = $context->getOutput();
     $wgRequest = $context->getRequest();
     $wgUser = $context->getUser();
     $wgLang = $context->getLanguage();
     $main->setTitle($title);
     $main->setOutput($context->getOutput());
     $main->setRequest($context->getRequest());
     $main->setUser($context->getUser());
     $main->setLanguage($context->getLanguage());
     // The useful part
     $ret = self::executePath($title, $context, true);
     // Restore old globals and context
     $wgTitle = $glob['title'];
     $wgOut = $glob['output'];
     $wgRequest = $glob['request'];
     $wgUser = $glob['user'];
     $wgLang = $glob['language'];
     $main->setTitle($ctx['title']);
     $main->setOutput($ctx['output']);
     $main->setRequest($ctx['request']);
     $main->setUser($ctx['user']);
     $main->setLanguage($ctx['language']);
     return $ret;
 }
 /**
  * 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);
 }
 protected function acceptRequest(IContextSource $context)
 {
     global $wgAuth, $wgAccountRequestTypes, $wgConfirmAccountSaveInfo;
     global $wgAllowAccountRequestFiles, $wgConfirmAccountFSRepos;
     $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', wfMsgHtml('noname'));
     }
     # Check if account name is already in use
     if (0 != $user->idForName() || $wgAuth->userExists($user->getName())) {
         return array('accountconf_user_exists', wfMsgHtml('userexists'));
     }
     $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 ($wgAllowAccountRequestFiles && $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_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', wfMsgHtml('externaldberror'));
     }
     # 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 = wfMsgExt($msg, array('parsemag', 'content'), $user->getName(), $p, $this->reason);
             # Use standard if none found...
         } else {
             $ebody = wfMsgExt('confirmaccount-email-body2', array('parsemag', 'content'), $user->getName(), $p, $this->reason);
         }
     } 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 && !wfEmptyMsg($msg)) {
             $ebody = wfMsgExt($msg, array('parsemag', 'content'), $user->getName(), $p, $this->reason);
             # Use standard if none found...
         } else {
             $ebody = wfMsgExt('confirmaccount-email-body', array('parsemag', 'content'), $user->getName(), $p, $this->reason);
         }
     }
     # Actually send out the email (@TODO: rollback on failure including $wgAuth)
     $result = $user->sendMail(wfMsgForContent('confirmaccount-email-subj'), $ebody);
     /*
     if ( !$result->isOk() ) {
     	# DELETE new rows in case there was a COMMIT somewhere
     	$this->acceptRequest_rollback( $dbw, $user->getId(), $acd_id );
     	return array( 'accountconf_mailerror',
     		wfMsg( 'mailerror', $context->getOutput()->parse( $result->getWikiText() ) ) );
     }
     */
     # 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 ($wgAllowAccountRequestFiles) {
         $key = $accReq->getFileStorageKey();
         if ($key) {
             $repoOld = new FSRepo($wgConfirmAccountFSRepos['accountreqs']);
             $pathRel = UserAccountRequest::relPathFromKey($key);
             $oldPath = $repoOld->getZonePath('public') . '/' . $pathRel;
             if (file_exists($oldPath)) {
                 unlink($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);
 }
    /**
     * Build the input form
     *
     * @return string HTML form
     */
    function buildForm()
    {
        $user = $this->mContext->getUser();
        $output = $this->mContext->getOutput();
        $lang = $this->mContext->getLanguage();
        $cascadingRestrictionLevels = $this->mContext->getConfig()->get('CascadingRestrictionLevels');
        $out = '';
        if (!$this->disabled) {
            $output->addModules('mediawiki.legacy.protect');
            $output->addJsConfigVars('wgCascadeableLevels', $cascadingRestrictionLevels);
            $out .= Xml::openElement('form', array('method' => 'post', 'action' => $this->mTitle->getLocalURL('action=protect'), 'id' => 'mw-Protect-Form'));
        }
        $out .= Xml::openElement('fieldset') . Xml::element('legend', null, wfMessage('protect-legend')->text()) . Xml::openElement('table', array('id' => 'mwProtectSet')) . Xml::openElement('tbody');
        $scExpiryOptions = wfMessage('protect-expiry-options')->inContentLanguage()->text();
        $showProtectOptions = $scExpiryOptions !== '-' && !$this->disabled;
        // Not all languages have V_x <-> N_x relation
        foreach ($this->mRestrictions as $action => $selected) {
            // Messages:
            // restriction-edit, restriction-move, restriction-create, restriction-upload
            $msg = wfMessage('restriction-' . $action);
            $out .= "<tr><td>" . Xml::openElement('fieldset') . Xml::element('legend', null, $msg->exists() ? $msg->text() : $action) . Xml::openElement('table', array('id' => "mw-protect-table-{$action}")) . "<tr><td>" . $this->buildSelector($action, $selected) . "</td></tr><tr><td>";
            $mProtectexpiry = Xml::label(wfMessage('protectexpiry')->text(), "mwProtectExpirySelection-{$action}");
            $mProtectother = Xml::label(wfMessage('protect-othertime')->text(), "mwProtect-{$action}-expires");
            $expiryFormOptions = '';
            if ($this->mExistingExpiry[$action] && $this->mExistingExpiry[$action] != 'infinity') {
                $timestamp = $lang->timeanddate($this->mExistingExpiry[$action], true);
                $d = $lang->date($this->mExistingExpiry[$action], true);
                $t = $lang->time($this->mExistingExpiry[$action], true);
                $expiryFormOptions .= Xml::option(wfMessage('protect-existing-expiry', $timestamp, $d, $t)->text(), 'existing', $this->mExpirySelection[$action] == 'existing') . "\n";
            }
            $expiryFormOptions .= Xml::option(wfMessage('protect-othertime-op')->text(), "othertime") . "\n";
            foreach (explode(',', $scExpiryOptions) as $option) {
                if (strpos($option, ":") === false) {
                    $show = $value = $option;
                } else {
                    list($show, $value) = explode(":", $option);
                }
                $show = htmlspecialchars($show);
                $value = htmlspecialchars($value);
                $expiryFormOptions .= Xml::option($show, $value, $this->mExpirySelection[$action] === $value) . "\n";
            }
            # Add expiry dropdown
            if ($showProtectOptions && !$this->disabled) {
                $out .= "\n\t\t\t\t\t<table><tr>\n\t\t\t\t\t\t<td class='mw-label'>\n\t\t\t\t\t\t\t{$mProtectexpiry}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td class='mw-input'>" . Xml::tags('select', array('id' => "mwProtectExpirySelection-{$action}", 'name' => "wpProtectExpirySelection-{$action}", 'tabindex' => '2') + $this->disabledAttrib, $expiryFormOptions) . "</td>\n\t\t\t\t\t</tr></table>";
            }
            # Add custom expiry field
            $attribs = array('id' => "mwProtect-{$action}-expires") + $this->disabledAttrib;
            $out .= "<table><tr>\n\t\t\t\t\t<td class='mw-label'>" . $mProtectother . '</td>
					<td class="mw-input">' . Xml::input("mwProtect-expiry-{$action}", 50, $this->mExpiry[$action], $attribs) . '</td>
				</tr></table>';
            $out .= "</td></tr>" . Xml::closeElement('table') . Xml::closeElement('fieldset') . "</td></tr>";
        }
        # Give extensions a chance to add items to the form
        wfRunHooks('ProtectionForm::buildForm', array($this->mArticle, &$out));
        $out .= Xml::closeElement('tbody') . Xml::closeElement('table');
        // JavaScript will add another row with a value-chaining checkbox
        if ($this->mTitle->exists()) {
            $out .= Xml::openElement('table', array('id' => 'mw-protect-table2')) . Xml::openElement('tbody');
            $out .= '<tr>
					<td></td>
					<td class="mw-input">' . Xml::checkLabel(wfMessage('protect-cascade')->text(), 'mwProtect-cascade', 'mwProtect-cascade', $this->mCascade, $this->disabledAttrib) . "</td>\n\t\t\t\t</tr>\n";
            $out .= Xml::closeElement('tbody') . Xml::closeElement('table');
        }
        # Add manual and custom reason field/selects as well as submit
        if (!$this->disabled) {
            $mProtectreasonother = Xml::label(wfMessage('protectcomment')->text(), 'wpProtectReasonSelection');
            $mProtectreason = Xml::label(wfMessage('protect-otherreason')->text(), 'mwProtect-reason');
            $reasonDropDown = Xml::listDropDown('wpProtectReasonSelection', wfMessage('protect-dropdown')->inContentLanguage()->text(), wfMessage('protect-otherreason-op')->inContentLanguage()->text(), $this->mReasonSelection, 'mwProtect-reason', 4);
            $out .= Xml::openElement('table', array('id' => 'mw-protect-table3')) . Xml::openElement('tbody');
            $out .= "\n\t\t\t\t<tr>\n\t\t\t\t\t<td class='mw-label'>\n\t\t\t\t\t\t{$mProtectreasonother}\n\t\t\t\t\t</td>\n\t\t\t\t\t<td class='mw-input'>\n\t\t\t\t\t\t{$reasonDropDown}\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td class='mw-label'>\n\t\t\t\t\t\t{$mProtectreason}\n\t\t\t\t\t</td>\n\t\t\t\t\t<td class='mw-input'>" . Xml::input('mwProtect-reason', 60, $this->mReason, array('type' => 'text', 'id' => 'mwProtect-reason', 'maxlength' => 180)) . "</td>\n\t\t\t\t</tr>";
            # Disallow watching is user is not logged in
            if ($user->isLoggedIn()) {
                $out .= "\n\t\t\t\t<tr>\n\t\t\t\t\t<td></td>\n\t\t\t\t\t<td class='mw-input'>" . Xml::checkLabel(wfMessage('watchthis')->text(), 'mwProtectWatch', 'mwProtectWatch', $user->isWatched($this->mTitle) || $user->getOption('watchdefault')) . "</td>\n\t\t\t\t</tr>";
            }
            $out .= "\n\t\t\t\t<tr>\n\t\t\t\t\t<td></td>\n\t\t\t\t\t<td class='mw-submit'>" . Xml::submitButton(wfMessage('confirm')->text(), array('id' => 'mw-Protect-submit')) . "</td>\n\t\t\t\t</tr>\n";
            $out .= Xml::closeElement('tbody') . Xml::closeElement('table');
        }
        $out .= Xml::closeElement('fieldset');
        if ($user->isAllowed('editinterface')) {
            $title = Title::makeTitle(NS_MEDIAWIKI, 'Protect-dropdown');
            $link = Linker::link($title, wfMessage('protect-edit-reasonlist')->escaped(), array(), array('action' => 'edit'));
            $out .= '<p class="mw-protect-editreasons">' . $link . '</p>';
        }
        if (!$this->disabled) {
            $out .= Html::hidden('wpEditToken', $user->getEditToken(array('protect', $this->mTitle->getPrefixedDBkey())));
            $out .= Xml::closeElement('form');
        }
        return $out;
    }
示例#27
0
文件: ApiHelp.php 项目: paladox/2
 /**
  * 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);
     }
 }
示例#28
0
 /**
  * Execute a special page path.
  * The path may contain parameters, e.g. Special:Name/Params
  * Extracts the special page name and call the execute method, passing the parameters
  *
  * Returns a title object if the page is redirected, false if there was no such special
  * page, and true if it was successful.
  *
  * @param $title          Title object
  * @param $context        IContextSource
  * @param $including      Bool output is being captured for use in {{special:whatever}}
  *
  * @return bool
  */
 public static function executePath(Title &$title, IContextSource &$context, $including = false)
 {
     wfProfileIn(__METHOD__);
     // @todo FIXME: Redirects broken due to this call
     $bits = explode('/', $title->getDBkey(), 2);
     $name = $bits[0];
     if (!isset($bits[1])) {
         // bug 2087
         $par = null;
     } else {
         $par = $bits[1];
     }
     $page = self::getPage($name);
     // Nonexistent?
     if (!$page) {
         $context->getOutput()->setArticleRelated(false);
         $context->getOutput()->setRobotPolicy('noindex,nofollow');
         $context->getOutput()->setStatusCode(404);
         $context->getOutput()->showErrorPage('nosuchspecialpage', 'nospecialpagetext');
         wfProfileOut(__METHOD__);
         return false;
     }
     // Page exists, set the context
     $page->setContext($context);
     if (!$including) {
         // Redirect to canonical alias for GET commands
         // Not for POST, we'd lose the post data, so it's best to just distribute
         // the request. Such POST requests are possible for old extensions that
         // generate self-links without being aware that their default name has
         // changed.
         if ($name != $page->getLocalName() && !$context->getRequest()->wasPosted()) {
             $query = $context->getRequest()->getQueryValues();
             unset($query['title']);
             $query = wfArrayToCGI($query);
             $title = $page->getTitle($par);
             $url = $title->getFullUrl($query);
             $context->getOutput()->redirect($url);
             wfProfileOut(__METHOD__);
             return $title;
         } else {
             $context->setTitle($page->getTitle($par));
         }
     } elseif (!$page->isIncludable()) {
         wfProfileOut(__METHOD__);
         return false;
     }
     $page->including($including);
     // Execute special page
     $profName = 'Special:' . $page->getName();
     wfProfileIn($profName);
     $page->execute($par);
     wfProfileOut($profName);
     wfProfileOut(__METHOD__);
     return true;
 }