/** * OutputPageParserOutput hook handler * Disables TOC in output before it grabs HTML * @see https://www.mediawiki.org/wiki/Manual:Hooks/OutputPageParserOutput * * @param OutputPage $outputPage * @param ParserOutput $po * @return bool */ public static function onOutputPageParserOutput($outputPage, ParserOutput $po) { $context = MobileContext::singleton(); $mfUseWikibaseDescription = $context->getMFConfig()->get('MFUseWikibaseDescription'); if ($context->shouldDisplayMobileView()) { $outputPage->enableTOC(false); $outputPage->setProperty('MinervaTOC', $po->getTOCHTML() !== ''); if ($mfUseWikibaseDescription && $context->isBetaGroupMember()) { $item = $po->getProperty('wikibase_item'); if ($item) { $desc = ExtMobileFrontend::getWikibaseDescription($item); if ($desc) { $outputPage->setProperty('wgMFDescription', $desc); } } } } return true; }
/** * OutputPageParserOutput hook handler * Disables TOC in output before it grabs HTML * @see https://www.mediawiki.org/wiki/Manual:Hooks/OutputPageParserOutput * * @param OutputPage $outputPage * @param ParserOutput $po * @return bool */ public static function onOutputPageParserOutput($outputPage, ParserOutput $po) { global $wgMFWikibaseImageCategory; $context = MobileContext::singleton(); $isBeta = $context->isBetaGroupMember(); $mfUseWikibaseDescription = $context->getMFConfig()->get('MFUseWikibaseDescription'); if ($context->shouldDisplayMobileView()) { $outputPage->enableTOC(false); $outputPage->setProperty('MinervaTOC', $po->getTOCHTML() !== ''); if ($mfUseWikibaseDescription && $isBeta) { $item = $po->getProperty('wikibase_item'); if ($item) { $desc = ExtMobileFrontend::getWikibaseDescription($item); $category = ExtMobileFrontend::getWikibasePropertyValue($item, $wgMFWikibaseImageCategory); if ($desc) { $outputPage->setProperty('wgMFDescription', $desc); } if ($category) { $outputPage->setProperty('wgMFImagesCategory', $category); } } } // Enable wrapped sections $po->setText(ExtMobileFrontend::DOMParse($outputPage, $po->getText(), $isBeta)); } return true; }
/** * Execute the requested Api actions. * @todo: Write some unit tests for API results */ public function execute() { // Logged-in users' parser options depend on preferences $this->getMain()->setCacheMode('anon-public-user-private'); // Enough '*' keys in JSON!!! $isXml = $this->getMain()->isInternalMode() || $this->getMain()->getPrinter()->getFormat() == 'XML'; $textElement = $isXml ? '*' : 'text'; $params = $this->extractRequestParams(); $prop = array_flip($params['prop']); $sectionProp = array_flip($params['sectionprop']); $this->variant = $params['variant']; $this->followRedirects = $params['redirect'] == 'yes'; $this->noHeadings = $params['noheadings']; $this->noTransform = $params['notransform']; $onlyRequestedSections = $params['onlyrequestedsections']; $this->offset = $params['offset']; $this->maxlen = $params['maxlen']; if ($this->offset === 0 && $this->maxlen === 0) { $this->offset = -1; // Disable text splitting } elseif ($this->maxlen === 0) { $this->maxlen = PHP_INT_MAX; } $title = $this->makeTitle($params['page']); // See whether the actual page (or if enabled, the redirect target) is the main page $this->mainPage = $this->isMainPage($title); if ($this->mainPage && $this->noHeadings) { $this->noHeadings = false; $this->setWarning("``noheadings'' makes no sense on the main page, ignoring"); } if (isset($prop['normalizedtitle']) && $title->getPrefixedText() != $params['page']) { $this->getResult()->addValue(null, $this->getModuleName(), array('normalizedtitle' => $title->getPageLanguage()->convert($title->getPrefixedText()))); } $data = $this->getData($title, $params['noimages']); // Bug 73109: #getData will return an empty array if the title redirects to // a page in a virtual namespace (NS_SPECIAL, NS_MEDIA), so make sure that // the requested data exists too. if (isset($prop['lastmodified']) && isset($data['lastmodified'])) { $this->getResult()->addValue(null, $this->getModuleName(), array('lastmodified' => $data['lastmodified'])); } if (isset($prop['lastmodifiedby']) && isset($data['lastmodifiedby'])) { $this->getResult()->addValue(null, $this->getModuleName(), array('lastmodifiedby' => $data['lastmodifiedby'])); } if (isset($prop['revision']) && isset($data['revision'])) { $this->getResult()->addValue(null, $this->getModuleName(), array('revision' => $data['revision'])); } if (isset($prop['id']) && isset($data['id'])) { $this->getResult()->addValue(null, $this->getModuleName(), array('id' => $data['id'])); } if (isset($prop['languagecount']) && isset($data['languagecount'])) { $this->getResult()->addValue(null, $this->getModuleName(), array('languagecount' => $data['languagecount'])); } if (isset($prop['hasvariants']) && isset($data['hasvariants'])) { $this->getResult()->addValue(null, $this->getModuleName(), array('hasvariants' => $data['hasvariants'])); } if (isset($prop['displaytitle']) && isset($data['displaytitle'])) { $this->getResult()->addValue(null, $this->getModuleName(), array('displaytitle' => $data['displaytitle'])); } if (isset($prop['pageprops'])) { $propNames = $params['pageprops']; if ($propNames == '*' && isset($data['pageprops'])) { $pageProps = $data['pageprops']; } else { $propNames = explode('|', $propNames); $pageProps = array_intersect_key($data['pageprops'], array_flip($propNames)); } $this->getResult()->addValue(null, $this->getModuleName(), array('pageprops' => $pageProps)); } if (isset($prop['description']) && isset($data['pageprops']['wikibase_item'])) { $desc = ExtMobileFrontend::getWikibaseDescription($data['pageprops']['wikibase_item']); if ($desc) { $this->getResult()->addValue(null, $this->getModuleName(), array('description' => $desc)); } } if ($this->usePageImages) { $this->addPageImage($data, $params, $prop); } $result = array(); $missingSections = array(); if ($this->mainPage) { if ($onlyRequestedSections) { $requestedSections = self::parseSections($params['sections'], $data, $missingSections); } else { $requestedSections = array(0); } $this->getResult()->addValue(null, $this->getModuleName(), array('mainpage' => '')); } elseif (isset($params['sections'])) { $requestedSections = self::parseSections($params['sections'], $data, $missingSections); } else { $requestedSections = array(); } if (isset($data['sections'])) { if (isset($prop['sections'])) { $sectionCount = count($data['sections']); for ($i = 0; $i <= $sectionCount; $i++) { if (!isset($requestedSections[$i]) && $onlyRequestedSections) { continue; } $section = array(); if ($i > 0) { $section = array_intersect_key($data['sections'][$i - 1], $sectionProp); } $section['id'] = $i; if (isset($prop['text']) && isset($requestedSections[$i]) && isset($data['text'][$i])) { $section[$textElement] = $this->stringSplitter($this->prepareSection($data['text'][$i])); unset($requestedSections[$i]); } if (isset($data['refsections'][$i])) { $section['references'] = ''; } $result[] = $section; } $missingSections = array_keys($requestedSections); } else { foreach (array_keys($requestedSections) as $index) { $section = array('id' => $index); if (isset($data['text'][$index])) { $section[$textElement] = $this->stringSplitter($this->prepareSection($data['text'][$index])); } else { $missingSections[] = $index; } $result[] = $section; } } $this->getResult()->setIndexedTagName($result, 'section'); $this->getResult()->addValue(null, $this->getModuleName(), array('sections' => $result)); } if (isset($prop['protection'])) { $this->addProtection($title); } if (isset($prop['editable'])) { $user = $this->getUser(); if ($user->isAnon()) { // HACK: Anons receive cached information, so don't check blocked status for them // to avoid them receiving false positives. Currently there is no way to check // all permissions except blocked status from the Title class. $req = new FauxRequest(); $req->setIP('127.0.0.1'); $user = User::newFromSession($req); } $editable = $title->quickUserCan('edit', $user); if ($isXml) { $editable = intval($editable); } $this->getResult()->addValue(null, $this->getModuleName(), array('editable' => $editable)); } // https://bugzilla.wikimedia.org/show_bug.cgi?id=51586 // Inform ppl if the page is infested with LiquidThreads but that's the // only thing we support about it. if (class_exists('LqtDispatch') && LqtDispatch::isLqtPage($title)) { $this->getResult()->addValue(null, $this->getModuleName(), array('liquidthreads' => '')); } if (count($missingSections) && isset($prop['text'])) { $this->setWarning('Section(s) ' . implode(', ', $missingSections) . ' not found'); } if ($this->maxlen < 0) { // There is more data available $this->getResult()->addValue(null, $this->getModuleName(), array('continue-offset' => $params['offset'] + $params['maxlen'])); } }