public function execute() { $params = $this->extractRequestParams(); $rev1 = $this->revisionOrTitleOrId($params['fromrev'], $params['fromtitle'], $params['fromid']); $rev2 = $this->revisionOrTitleOrId($params['torev'], $params['totitle'], $params['toid']); $de = new DifferenceEngine($this->getContext(), $rev1, $rev2, null, true, false); $vals = array(); if (isset($params['fromtitle'])) { $vals['fromtitle'] = $params['fromtitle']; } if (isset($params['fromid'])) { $vals['fromid'] = $params['fromid']; } $vals['fromrevid'] = $rev1; if (isset($params['totitle'])) { $vals['totitle'] = $params['totitle']; } if (isset($params['toid'])) { $vals['toid'] = $params['toid']; } $vals['torevid'] = $rev2; $difftext = $de->getDiffBody(); if ($difftext === false) { $this->dieUsage('The diff cannot be retrieved. ' . 'Maybe one or both revisions do not exist or you do not have permission to view them.', 'baddiff'); } else { ApiResult::setContent($vals, $difftext); } $this->getResult()->addValue(null, $this->getModuleName(), $vals); }
public function execute() { $prop = null; extract($this->extractRequestParams()); foreach ($prop as $p) { switch ($p) { case 'general': global $wgSitename, $wgVersion, $wgCapitalLinks; $data = array(); $mainPage = Title::newFromText(wfMsgForContent('mainpage')); $data['mainpage'] = $mainPage->getText(); $data['base'] = $mainPage->getFullUrl(); $data['sitename'] = $wgSitename; $data['generator'] = "MediaWiki {$wgVersion}"; $data['case'] = $wgCapitalLinks ? 'first-letter' : 'case-sensitive'; // 'case-insensitive' option is reserved for future $this->getResult()->addValue('query', $p, $data); break; case 'namespaces': global $wgContLang; $data = array(); foreach ($wgContLang->getFormattedNamespaces() as $ns => $title) { $data[$ns] = array('id' => $ns); ApiResult::setContent($data[$ns], $title); } ApiResult::setIndexedTagName($data, 'ns'); $this->getResult()->addValue('query', $p, $data); break; default: ApiBase::dieDebug(__METHOD__, "Unknown prop={$p}"); } } }
public function execute() { global $wgUser; // Before doing anything at all, let's check permissions if (!$wgUser->isAllowed('codereview-use')) { $this->dieUsage('You don\'t have permission to view code paths', 'permissiondenied'); } $params = $this->extractRequestParams(); $repo = CodeRepository::newFromName($params['repo']); if (!$repo instanceof CodeRepository) { $this->dieUsage("Invalid repo ``{$params['repo']}''", 'invalidrepo'); } $this->addTables('code_paths'); $this->addFields('DISTINCT cp_path'); $this->addWhere(array('cp_repo_id' => $repo->getId())); $db = $this->getDB(); $this->addWhere('cp_path ' . $db->buildLike($params['path'], $db->anyString())); $this->addOption('USE INDEX', 'repo_path'); $this->addOption('LIMIT', 10); $res = $this->select(__METHOD__); $result = $this->getResult(); $data = array(); foreach ($res as $row) { $item = array(); ApiResult::setContent($item, $row->cp_path); $data[] = $item; } $result->setIndexedTagName($data, 'paths'); $result->addValue('query', $this->getModuleName(), $data); }
public function execute() { $this->addFields(array('el_from', 'el_to')); $this->addTables('externallinks'); $this->addWhereFld('el_from', array_keys($this->getPageSet()->getGoodTitles())); $db = $this->getDB(); $res = $this->select(__METHOD__); $data = array(); $lastId = 0; // database has no ID 0 while ($row = $db->fetchObject($res)) { if ($lastId != $row->el_from) { if ($lastId != 0) { $this->addPageSubItems($lastId, $data); $data = array(); } $lastId = $row->el_from; } $entry = array(); ApiResult::setContent($entry, $row->el_to); $data[] = $entry; } if ($lastId != 0) { $this->addPageSubItems($lastId, $data); } $db->freeResult($res); }
public function execute() { $this->addFields(array('ll_from', 'll_lang', 'll_title')); $this->addTables('langlinks'); $this->addWhereFld('ll_from', array_keys($this->getPageSet()->getGoodTitles())); $this->addOption('ORDER BY', "ll_from, ll_lang"); $res = $this->select(__METHOD__); $data = array(); $lastId = 0; // database has no ID 0 $db = $this->getDB(); while ($row = $db->fetchObject($res)) { if ($lastId != $row->ll_from) { if ($lastId != 0) { $this->addPageSubItems($lastId, $data); $data = array(); } $lastId = $row->ll_from; } $entry = array('lang' => $row->ll_lang); ApiResult::setContent($entry, $row->ll_title); $data[] = $entry; } if ($lastId != 0) { $this->addPageSubItems($lastId, $data); } $db->freeResult($res); }
/** * main function */ public function execute() { #--- blank variables $wikia = $group = $variable = null; extract($this->extractRequestParams()); #--- database instance $db =& $this->getDB(); $db->selectDB('wikicities'); list($tbl_cvg, $tbl_cvp, $tbl_cv) = $db->tableNamesN("city_variables_groups", "city_variables_pool", "city_variables"); if (!is_null($wikia)) { $this->addTables("{$tbl_cvp} JOIN {$tbl_cvg} ON cv_variable_group = cv_group_id JOIN {$tbl_cv} ON cv_id = cv_variable_id"); $this->addFields(array("cv_group_id", "cv_group_name")); $this->addWhereFld("cv_city_id", $wikia); if (!is_null($wikia)) { $this->addWhereFld("cv_id", $variable); } } else { $this->addTables("{$tbl_cvg}"); $this->addFields(array("cv_group_id", "cv_group_name")); } $data = array(); $res = $this->select(__METHOD__); while ($row = $db->fetchObject($res)) { $data[$row->cv_group_id] = array("id" => $row->cv_group_id, "name" => $row->cv_group_name); ApiResult::setContent($data[$row->cv_group_id], $row->cv_group_name); } $db->freeResult($res); $this->getResult()->setIndexedTagName($data, 'item'); $this->getResult()->addValue('query', $this->getModuleName(), $data); }
public function execute() { if ($this->getPageSet()->getGoodTitleCount() == 0) { return; } $params = $this->extractRequestParams(); $this->addFields(array('el_from', 'el_to')); $this->addTables('externallinks'); $this->addWhereFld('el_from', array_keys($this->getPageSet()->getGoodTitles())); // Don't order by el_from if it's constant in the WHERE clause if (count($this->getPageSet()->getGoodTitles()) != 1) { $this->addOption('ORDER BY', 'el_from'); } $this->addOption('LIMIT', $params['limit'] + 1); if (!is_null($params['offset'])) { $this->addOption('OFFSET', $params['offset']); } $res = $this->select(__METHOD__); $count = 0; foreach ($res as $row) { if (++$count > $params['limit']) { // We've reached the one extra which shows that // there are additional pages to be had. Stop here... $this->setContinueEnumParameter('offset', @$params['offset'] + $params['limit']); break; } $entry = array(); ApiResult::setContent($entry, $row->el_to); $fit = $this->addPageSubItem($row->el_from, $entry); if (!$fit) { $this->setContinueEnumParameter('offset', @$params['offset'] + $count - 1); break; } } }
public function execute() { if ($this->getPageSet()->getGoodTitleCount() == 0) { return; } $params = $this->extractRequestParams(); $this->addFields(array('ll_from', 'll_lang', 'll_title')); $this->addTables('langlinks'); $this->addWhereFld('ll_from', array_keys($this->getPageSet()->getGoodTitles())); if (!is_null($params['continue'])) { $cont = explode('|', $params['continue']); if (count($cont) != 2) { $this->dieUsage("Invalid continue param. You should pass the " . "original value returned by the previous query", "_badcontinue"); } $llfrom = intval($cont[0]); $lllang = $this->getDB()->strencode($cont[1]); $this->addWhere("ll_from > {$llfrom} OR " . "(ll_from = {$llfrom} AND " . "ll_lang >= '{$lllang}')"); } # Don't order by ll_from if it's constant in the WHERE clause if (count($this->getPageSet()->getGoodTitles()) == 1) { $this->addOption('ORDER BY', 'll_lang'); } else { $this->addOption('ORDER BY', 'll_from, ll_lang'); } $this->addOption('LIMIT', $params['limit'] + 1); $res = $this->select(__METHOD__); $data = array(); $lastId = 0; // database has no ID 0 $count = 0; $db = $this->getDB(); while ($row = $db->fetchObject($res)) { if (++$count > $params['limit']) { // We've reached the one extra which shows that // there are additional pages to be had. Stop here... $this->setContinueEnumParameter('continue', "{$row->ll_from}|{$row->ll_lang}"); break; } if ($lastId != $row->ll_from) { if ($lastId != 0) { $this->addPageSubItems($lastId, $data); $data = array(); } $lastId = $row->ll_from; } $entry = array('lang' => $row->ll_lang); ApiResult::setContent($entry, $row->ll_title); $data[] = $entry; } if ($lastId != 0) { $this->addPageSubItems($lastId, $data); } $db->freeResult($res); }
public function execute() { if ($this->getPageSet()->getGoodTitleCount() == 0) { return; } $params = $this->extractRequestParams(); $query = $params['query']; $protocol = ApiQueryExtLinksUsage::getProtocolPrefix($params['protocol']); $this->addFields(array('el_from', 'el_to')); $this->addTables('externallinks'); $this->addWhereFld('el_from', array_keys($this->getPageSet()->getGoodTitles())); $whereQuery = $this->prepareUrlQuerySearchString($query, $protocol); if ($whereQuery !== null) { $this->addWhere($whereQuery); } // Don't order by el_from if it's constant in the WHERE clause if (count($this->getPageSet()->getGoodTitles()) != 1) { $this->addOption('ORDER BY', 'el_from'); } // If we're querying all protocols, use DISTINCT to avoid repeating protocol-relative links twice if ($protocol === null) { $this->addOption('DISTINCT'); } $this->addOption('LIMIT', $params['limit'] + 1); $offset = isset($params['offset']) ? $params['offset'] : 0; if ($offset) { $this->addOption('OFFSET', $params['offset']); } $res = $this->select(__METHOD__); $count = 0; foreach ($res as $row) { if (++$count > $params['limit']) { // We've reached the one extra which shows that // there are additional pages to be had. Stop here... $this->setContinueEnumParameter('offset', $offset + $params['limit']); break; } $entry = array(); $to = $row->el_to; // expand protocol-relative urls if ($params['expandurl']) { $to = wfExpandUrl($to, PROTO_CANONICAL); } ApiResult::setContent($entry, $to); $fit = $this->addPageSubItem($row->el_from, $entry); if (!$fit) { $this->setContinueEnumParameter('offset', $offset + $count - 1); break; } } }
public function execute() { if ($this->getPageSet()->getGoodTitleCount() == 0) { return; } $params = $this->extractRequestParams(); $this->addFields(array('iwl_from', 'iwl_prefix', 'iwl_title')); $this->addTables('iwlinks'); $this->addWhereFld('iwl_from', array_keys($this->getPageSet()->getGoodTitles())); if (!is_null($params['continue'])) { $cont = explode('|', $params['continue']); if (count($cont) != 3) { $this->dieUsage('Invalid continue param. You should pass the ' . 'original value returned by the previous query', '_badcontinue'); } $iwlfrom = intval($cont[0]); $iwlprefix = $this->getDB()->strencode($cont[1]); $iwltitle = $this->getDB()->strencode($this->titleToKey($cont[2])); $this->addWhere("iwl_from > {$iwlfrom} OR " . "(iwl_from = {$iwlfrom} AND " . "(iwl_prefix > '{$iwlprefix}' OR " . "(iwl_prefix = '{$iwlprefix}' AND " . "iwl_title >= '{$iwltitle}')))"); } // Don't order by iwl_from if it's constant in the WHERE clause if (count($this->getPageSet()->getGoodTitles()) == 1) { $this->addOption('ORDER BY', 'iwl_prefix'); } else { $this->addOption('ORDER BY', 'iwl_from, iwl_prefix'); } $this->addOption('LIMIT', $params['limit'] + 1); $res = $this->select(__METHOD__); $count = 0; foreach ($res as $row) { if (++$count > $params['limit']) { // We've reached the one extra which shows that // there are additional pages to be had. Stop here... $this->setContinueEnumParameter('continue', "{$row->iwl_from}|{$row->iwl_prefix}|{$row->iwl_title}"); break; } $entry = array('prefix' => $row->iwl_prefix); if (!is_null($params['url'])) { $title = Title::newFromText("{$row->iwl_prefix}:{$row->iwl_title}"); if ($title) { $entry['url'] = $title->getFullURL(); } } ApiResult::setContent($entry, $row->iwl_title); $fit = $this->addPageSubItem($row->iwl_from, $entry); if (!$fit) { $this->setContinueEnumParameter('continue', "{$row->iwl_from}|{$row->iwl_prefix}|{$row->iwl_title}"); break; } } }
public function execute() { if ($this->getPageSet()->getGoodTitleCount() == 0) { return; } $params = $this->extractRequestParams(); $this->addFields(array('el_from', 'el_to')); $this->addTables('externallinks'); $this->addWhereFld('el_from', array_keys($this->getPageSet()->getGoodTitles())); # Don't order by el_from if it's constant in the WHERE clause if (count($this->getPageSet()->getGoodTitles()) != 1) { $this->addOption('ORDER BY', 'el_from'); } $this->addOption('LIMIT', $params['limit'] + 1); if (!is_null($params['offset'])) { $this->addOption('OFFSET', $params['offset']); } $db = $this->getDB(); $res = $this->select(__METHOD__); $data = array(); $lastId = 0; // database has no ID 0 $count = 0; while ($row = $db->fetchObject($res)) { if (++$count > $params['limit']) { // We've reached the one extra which shows that // there are additional pages to be had. Stop here... $this->setContinueEnumParameter('offset', @$params['offset'] + $params['limit']); break; } if ($lastId != $row->el_from) { if ($lastId != 0) { $this->addPageSubItems($lastId, $data); $data = array(); } $lastId = $row->el_from; } $entry = array(); ApiResult::setContent($entry, $row->el_to); $data[] = $entry; } if ($lastId != 0) { $this->addPageSubItems($lastId, $data); } $db->freeResult($res); }
public function execute() { $params = $this->extractRequestParams(); $title = Title::newFromText($params['title']); if (!$title) { $this->dieUsage('Invalid title', 'invalidtitle'); } $handle = new MessageHandle($title); if (!$handle->isValid()) { $this->dieUsage('Title does not correspond to a translatable message', 'nomessagefortitle'); } $namespace = $title->getNamespace(); $pageInfo = self::getTranslations($handle); $result = $this->getResult(); $count = 0; foreach ($pageInfo as $key => $info) { if (++$count <= $params['offset']) { continue; } $tTitle = Title::makeTitle($namespace, $key); $tHandle = new MessageHandle($tTitle); $data = array('title' => $tTitle->getPrefixedText(), 'language' => $tHandle->getCode(), 'lasttranslator' => $info[1]); $fuzzy = MessageHandle::hasFuzzyString($info[0]) || $tHandle->isFuzzy(); if ($fuzzy) { $data['fuzzy'] = 'fuzzy'; } $translation = str_replace(TRANSLATE_FUZZY, '', $info[0]); if (defined('ApiResult::META_CONTENT')) { ApiResult::setContentValue($data, 'translation', $translation); } else { ApiResult::setContent($data, $translation); } $fit = $result->addValue(array('query', $this->getModuleName()), null, $data); if (!$fit) { $this->setContinueEnumParameter('offset', $count); break; } } if (defined('ApiResult::META_CONTENT')) { $result->addIndexedTagName(array('query', $this->getModuleName()), 'message'); } else { $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'message'); } }
protected function appendVariables($property) { $data = array(); foreach ($this->variablesList as $id => $variableName) { $data[$id] = array('id' => $variableName); $value = array_key_exists($variableName, $GLOBALS) && !is_null($GLOBALS[$variableName]) ? $GLOBALS[$variableName] : ""; if (is_array($value)) { $loop = 0; foreach ($value as $key => $v) { $data[$id]["value" . $loop] = array('id' => $key); ApiResult::setContent($data[$id]["value" . $loop], $v); $loop++; } } else { ApiResult::setContent($data[$id], $value); } } $result = $this->getResult(); $result->setIndexedTagName($data, $property); $result->addValue('query', $property, $data); }
public function execute() { $params = $this->extractRequestParams(); $titles = $this->getPageSet()->getGoodTitles(); if (count($titles) == 0) return; $this->addTables( 'page_props' ); $this->addFields( array( 'pp_page', 'pp_value' ) ); $this->addWhere( array( 'pp_page' => array_keys( $titles ), 'pp_propname' => 'templateinfo' ) ); if ( !is_null( $params['continue'] ) ) { $fromid = intval( $params['continue'] ); $this->addWhere( "pp_page >= $fromid" ); } $this->addOption( 'ORDER BY', 'pp_page' ); $res = $this->select(__METHOD__); while ( $row = $this->getDB()->fetchObject( $res ) ) { $vals = array( ); $template_info = $row->pp_value; // determine whether this is actual XML or an error // message by checking whether the first character // is '<' - this is an interim solution until there's // a better storage format in place if (substr($template_info, 0, 1) == '<') ApiResult::setContent( $vals, $row->pp_value ); else // add error message as an "error=" attribute $vals['error'] = $row->pp_value; $fit = $this->addPageSubItems( $row->pp_page, $vals ); if( !$fit ) { $this->setContinueEnumParameter( 'continue', $row->pp_page ); break; } } }
public function execute() { // Cache may vary on $wgUser because ParserOptions gets data from it $this->getMain()->setCacheMode('anon-public-user-private'); // Get parameters $params = $this->extractRequestParams(); // Create title for parser $title_obj = Title::newFromText($params['title']); if (!$title_obj || $title_obj->isExternal()) { $this->dieUsageMsg(array('invalidtitle', $params['title'])); } $result = $this->getResult(); // Parse text global $wgParser; $options = ParserOptions::newFromContext($this->getContext()); if ($params['includecomments']) { $options->setRemoveComments(false); } if ($params['generatexml']) { $wgParser->startExternalParse($title_obj, $options, OT_PREPROCESS); $dom = $wgParser->preprocessToDom($params['text']); if (is_callable(array($dom, 'saveXML'))) { $xml = $dom->saveXML(); } else { $xml = $dom->__toString(); } $xml_result = array(); ApiResult::setContent($xml_result, $xml); $result->addValue(null, 'parsetree', $xml_result); } $retval = $wgParser->preprocess($params['text'], $title_obj, $options); // Return result $retval_array = array(); ApiResult::setContent($retval_array, $retval); $result->addValue(null, $this->getModuleName(), $retval_array); }
/** * Set warning section for this module. Users should monitor this * section to notice any changes in API. Multiple calls to this * function will result in the warning messages being separated by * newlines * @param $warning string Warning message */ public function setWarning($warning) { $data = $this->getResult()->getData(); if (isset($data['warnings'][$this->getModuleName()])) { // Don't add duplicate warnings $warn_regex = preg_quote($warning, '/'); if (preg_match("/{$warn_regex}(\\n|\$)/", $data['warnings'][$this->getModuleName()]['*'])) { return; } $oldwarning = $data['warnings'][$this->getModuleName()]['*']; // If there is a warning already, append it to the existing one $warning = "{$oldwarning}\n{$warning}"; $this->getResult()->unsetValue('warnings', $this->getModuleName()); } $msg = array(); ApiResult::setContent($msg, $warning); $this->getResult()->disableSizeCheck(); $this->getResult()->addValue('warnings', $this->getModuleName(), $msg); $this->getResult()->enableSizeCheck(); }
public function appendSkins($property) { $data = array(); foreach (Skin::getSkinNames() as $name => $displayName) { $skin = array('code' => $name); ApiResult::setContent($skin, $displayName); $data[] = $skin; } $this->getResult()->setIndexedTagName($data, 'skin'); return $this->getResult()->addValue('query', $property, $data); }
protected function appendNamespaceAliases($property) { global $wgNamespaceAliases; $data = array(); foreach ($wgNamespaceAliases as $title => $ns) { $item = array('id' => $ns); ApiResult::setContent($item, strtr($title, '_', ' ')); $data[] = $item; } $this->getResult()->setIndexedTagName($data, 'ns'); $this->getResult()->addValue('query', $property, $data); }
/** * Replace the result data with the information about an exception. * Returns the error code * @param $e Exception * @return string */ protected function substituteResultWithError($e) { $result = $this->getResult(); // Printer may not be initialized if the extractRequestParams() fails for the main module if (!isset($this->mPrinter)) { // The printer has not been created yet. Try to manually get formatter value. $value = $this->getRequest()->getVal('format', self::API_DEFAULT_FORMAT); if (!in_array($value, $this->mFormatNames)) { $value = self::API_DEFAULT_FORMAT; } $this->mPrinter = $this->createPrinterByName($value); if ($this->mPrinter->getNeedsRawData()) { $result->setRawMode(); } } if ($e instanceof UsageException) { // User entered incorrect parameters - print usage screen $errMessage = $e->getMessageArray(); // Only print the help message when this is for the developer, not runtime if ($this->mPrinter->getWantsHelp() || $this->mAction == 'help') { ApiResult::setContent($errMessage, $this->makeHelpMsg()); } } else { global $wgShowSQLErrors, $wgShowExceptionDetails; // Something is seriously wrong if ($e instanceof DBQueryError && !$wgShowSQLErrors) { $info = 'Database query error'; } else { $info = "Exception Caught: {$e->getMessage()}"; } $errMessage = array('code' => 'internal_api_error_' . get_class($e), 'info' => $info); ApiResult::setContent($errMessage, $wgShowExceptionDetails ? "\n\n{$e->getTraceAsString()}\n\n" : ''); } $result->reset(); $result->disableSizeCheck(); // Re-add the id $requestid = $this->getParameter('requestid'); if (!is_null($requestid)) { $result->addValue(null, 'requestid', $requestid); } // servedby is especially useful when debugging errors $result->addValue(null, 'servedby', wfHostName()); $result->addValue(null, 'error', $errMessage); return $errMessage['code']; }
private function formatCss($css) { $result = array(); foreach ($css as $file => $link) { $entry = array(); $entry['file'] = $file; ApiResult::setContent($entry, $link); $result[] = $entry; } return $result; }
public function execute() { $params = $this->extractRequestParams(); global $wgLang; $oldLang = null; if (!is_null($params['lang'])) { $oldLang = $wgLang; // Keep $wgLang for restore later $wgLang = Language::factory($params['lang']); } $prop = array_flip((array) $params['prop']); // Determine which messages should we print if (in_array('*', $params['messages'])) { $message_names = array_keys(Language::getMessagesFor('en')); sort($message_names); $messages_target = $message_names; } else { $messages_target = $params['messages']; } // Filter messages if (isset($params['filter'])) { $messages_filtered = array(); foreach ($messages_target as $message) { // !== is used because filter can be at the beginning of the string if (strpos($message, $params['filter']) !== false) { $messages_filtered[] = $message; } } $messages_target = $messages_filtered; } // Get all requested messages and print the result $skip = !is_null($params['from']); $useto = !is_null($params['to']); $result = $this->getResult(); foreach ($messages_target as $message) { // Skip all messages up to $params['from'] if ($skip && $message === $params['from']) { $skip = false; } if ($useto && $message > $params['to']) { break; } if (!$skip) { $a = array('name' => $message); $args = null; if (isset($params['args']) && count($params['args']) != 0) { $args = $params['args']; } // Check if the parser is enabled: if ($params['enableparser']) { $msg = wfMsgExt($message, array('parsemag'), $args); } elseif ($args) { $msgString = wfMsgGetKey($message, true, false, false); $msg = wfMsgReplaceArgs($msgString, $args); } else { $msg = wfMsgGetKey($message, true, false, false); } if (wfEmptyMsg($message, $msg)) { $a['missing'] = ''; } else { ApiResult::setContent($a, $msg); if (isset($prop['default'])) { $default = wfMsgGetKey($message, false, false, false); if ($default !== $msg) { if (wfEmptyMsg($message, $default)) { $a['defaultmissing'] = ''; } else { $a['default'] = $default; } } } } $fit = $result->addValue(array('query', $this->getModuleName()), null, $a); if (!$fit) { $this->setContinueEnumParameter('from', $message); break; } } } $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'message'); if (!is_null($oldLang)) { $wgLang = $oldLang; // Restore $oldLang } }
public function execute() { global $wgUser; // Before doing anything at all, let's check permissions if (!$wgUser->isAllowed('deletedhistory')) { $this->dieUsage('You don\'t have permission to view deleted revision information', 'permissiondenied'); } $db = $this->getDB(); $params = $this->extractRequestParams(false); $prop = array_flip($params['prop']); $fld_revid = isset($prop['revid']); $fld_user = isset($prop['user']); $fld_comment = isset($prop['comment']); $fld_minor = isset($prop['minor']); $fld_len = isset($prop['len']); $fld_content = isset($prop['content']); $fld_token = isset($prop['token']); $result = $this->getResult(); $pageSet = $this->getPageSet(); $titles = $pageSet->getTitles(); $data = array(); $this->addTables('archive'); $this->addFields(array('ar_title', 'ar_namespace', 'ar_timestamp')); if ($fld_revid) { $this->addFields('ar_rev_id'); } if ($fld_user) { $this->addFields('ar_user_text'); } if ($fld_comment) { $this->addFields('ar_comment'); } if ($fld_minor) { $this->addFields('ar_minor_edit'); } if ($fld_len) { $this->addFields('ar_len'); } if ($fld_content) { $this->addTables('text'); $this->addFields(array('ar_text', 'ar_text_id', 'old_text', 'old_flags')); $this->addWhere('ar_text_id = old_id'); // This also means stricter restrictions if (!$wgUser->isAllowed('undelete')) { $this->dieUsage('You don\'t have permission to view deleted revision content', 'permissiondenied'); } } // Check limits $userMax = $fld_content ? ApiBase::LIMIT_SML1 : ApiBase::LIMIT_BIG1; $botMax = $fld_content ? ApiBase::LIMIT_SML2 : ApiBase::LIMIT_BIG2; if ($limit == 'max') { $limit = $this->getMain()->canApiHighLimits() ? $botMax : $userMax; $this->getResult()->addValue('limits', 'limit', $limit); } $this->validateLimit('limit', $params['limit'], 1, $userMax, $botMax); if ($fld_token) { // Undelete tokens are identical for all pages, so we cache one here $token = $wgUser->editToken(); } // We need a custom WHERE clause that matches all titles. if (count($titles) > 0) { $lb = new LinkBatch($titles); $where = $lb->constructSet('ar', $db); $this->addWhere($where); } $this->addOption('LIMIT', $params['limit'] + 1); $this->addWhereRange('ar_timestamp', $params['dir'], $params['start'], $params['end']); if (isset($params['namespace'])) { $this->addWhereFld('ar_namespace', $params['namespace']); } $res = $this->select(__METHOD__); $pages = array(); $count = 0; // First populate the $pages array while ($row = $db->fetchObject($res)) { if ($count++ == $params['limit']) { // We've had enough $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ar_timestamp)); break; } $rev = array(); $rev['timestamp'] = wfTimestamp(TS_ISO_8601, $row->ar_timestamp); if ($fld_revid) { $rev['revid'] = $row->ar_rev_id; } if ($fld_user) { $rev['user'] = $row->ar_user_text; } if ($fld_comment) { $rev['comment'] = $row->ar_comment; } if ($fld_minor) { if ($row->ar_minor_edit == 1) { $rev['minor'] = ''; } } if ($fld_len) { $rev['len'] = $row->ar_len; } if ($fld_content) { ApiResult::setContent($rev, Revision::getRevisionText($row)); } $t = Title::makeTitle($row->ar_namespace, $row->ar_title); if (!isset($pages[$t->getPrefixedText()])) { $pages[$t->getPrefixedText()] = array('title' => $t->getPrefixedText(), 'ns' => intval($row->ar_namespace), 'revisions' => array($rev)); if ($fld_token) { $pages[$t->getPrefixedText()]['token'] = $token; } } else { $pages[$t->getPrefixedText()]['revisions'][] = $rev; } } $db->freeResult($res); // We don't want entire pagenames as keys, so let's make this array indexed foreach ($pages as $page) { $result->setIndexedTagName($page['revisions'], 'rev'); $data[] = $page; } $result->setIndexedTagName($data, 'page'); $result->addValue('query', $this->getModuleName(), $data); }
private function extractRowInfo($row) { $revision = new Revision($row); $title = $revision->getTitle(); $vals = array(); if ($this->fld_ids) { $vals['revid'] = intval($revision->getId()); // $vals['oldid'] = intval( $row->rev_text_id ); // todo: should this be exposed? if (!is_null($revision->getParentId())) { $vals['parentid'] = intval($revision->getParentId()); } } if ($this->fld_flags && $revision->isMinor()) { $vals['minor'] = ''; } if ($this->fld_user || $this->fld_userid) { if ($revision->isDeleted(Revision::DELETED_USER)) { $vals['userhidden'] = ''; } else { if ($this->fld_user) { $vals['user'] = $revision->getUserText(); } $userid = $revision->getUser(); if (!$userid) { $vals['anon'] = ''; } if ($this->fld_userid) { $vals['userid'] = $userid; } } } if ($this->fld_timestamp) { $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $revision->getTimestamp()); } if ($this->fld_size) { if (!is_null($revision->getSize())) { $vals['size'] = intval($revision->getSize()); } else { $vals['size'] = 0; } } if ($this->fld_sha1) { if ($revision->getSha1() != '') { $vals['sha1'] = wfBaseConvert($revision->getSha1(), 36, 16, 40); } else { $vals['sha1'] = ''; } } if ($this->fld_comment || $this->fld_parsedcomment) { if ($revision->isDeleted(Revision::DELETED_COMMENT)) { $vals['commenthidden'] = ''; } else { $comment = $revision->getComment(); if ($this->fld_comment) { $vals['comment'] = $comment; } if ($this->fld_parsedcomment) { $vals['parsedcomment'] = Linker::formatComment($comment, $title); } } } if ($this->fld_tags) { if ($row->ts_tags) { $tags = explode(',', $row->ts_tags); $this->getResult()->setIndexedTagName($tags, 'tag'); $vals['tags'] = $tags; } else { $vals['tags'] = array(); } } if (!is_null($this->token)) { $tokenFunctions = $this->getTokenFunctions(); foreach ($this->token as $t) { $val = call_user_func($tokenFunctions[$t], $title->getArticleID(), $title, $revision); if ($val === false) { $this->setWarning("Action '{$t}' is not allowed for the current user"); } else { $vals[$t . 'token'] = $val; } } } $text = null; global $wgParser; if ($this->fld_content || !is_null($this->difftotext)) { $text = $revision->getText(); // Expand templates after getting section content because // template-added sections don't count and Parser::preprocess() // will have less input if ($this->section !== false) { $text = $wgParser->getSection($text, $this->section, false); if ($text === false) { $this->dieUsage("There is no section {$this->section} in r" . $revision->getId(), 'nosuchsection'); } } } if ($this->fld_content && !$revision->isDeleted(Revision::DELETED_TEXT)) { if ($this->generateXML) { $wgParser->startExternalParse($title, ParserOptions::newFromContext($this->getContext()), OT_PREPROCESS); $dom = $wgParser->preprocessToDom($text); if (is_callable(array($dom, 'saveXML'))) { $xml = $dom->saveXML(); } else { $xml = $dom->__toString(); } $vals['parsetree'] = $xml; } if ($this->expandTemplates && !$this->parseContent) { $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext())); } if ($this->parseContent) { $text = $wgParser->parse($text, $title, ParserOptions::newFromContext($this->getContext()))->getText(); } ApiResult::setContent($vals, $text); } elseif ($this->fld_content) { $vals['texthidden'] = ''; } if (!is_null($this->diffto) || !is_null($this->difftotext)) { global $wgAPIMaxUncachedDiffs; static $n = 0; // Number of uncached diffs we've had if ($n < $wgAPIMaxUncachedDiffs) { $vals['diff'] = array(); $context = new DerivativeContext($this->getContext()); $context->setTitle($title); if (!is_null($this->difftotext)) { $engine = new DifferenceEngine($context); $engine->setText($text, $this->difftotext); } else { $engine = new DifferenceEngine($context, $revision->getID(), $this->diffto); $vals['diff']['from'] = $engine->getOldid(); $vals['diff']['to'] = $engine->getNewid(); } $difftext = $engine->getDiffBody(); ApiResult::setContent($vals['diff'], $difftext); if (!$engine->wasCacheHit()) { $n++; } } else { $vals['diff']['notcached'] = ''; } } return $vals; }
private function extractRowInfo($row) { $revision = new Revision($row); $title = $revision->getTitle(); $vals = array(); if ($this->fld_ids) { $vals['revid'] = intval($revision->getId()); // $vals['oldid'] = intval( $row->rev_text_id ); // todo: should this be exposed? if (!is_null($revision->getParentId())) { $vals['parentid'] = intval($revision->getParentId()); } } if ($this->fld_flags && $revision->isMinor()) { $vals['minor'] = ''; } if ($this->fld_user || $this->fld_userid) { if ($revision->isDeleted(Revision::DELETED_USER)) { $vals['userhidden'] = ''; } else { if ($this->fld_user) { $vals['user'] = $revision->getUserText(); } $userid = $revision->getUser(); if (!$userid) { $vals['anon'] = ''; } if ($this->fld_userid) { $vals['userid'] = $userid; } } } if ($this->fld_timestamp) { $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $revision->getTimestamp()); } if ($this->fld_size) { if (!is_null($revision->getSize())) { $vals['size'] = intval($revision->getSize()); } else { $vals['size'] = 0; } } if ($this->fld_sha1 && !$revision->isDeleted(Revision::DELETED_TEXT)) { if ($revision->getSha1() != '') { $vals['sha1'] = wfBaseConvert($revision->getSha1(), 36, 16, 40); } else { $vals['sha1'] = ''; } } elseif ($this->fld_sha1) { $vals['sha1hidden'] = ''; } if ($this->fld_contentmodel) { $vals['contentmodel'] = $revision->getContentModel(); } if ($this->fld_comment || $this->fld_parsedcomment) { if ($revision->isDeleted(Revision::DELETED_COMMENT)) { $vals['commenthidden'] = ''; } else { $comment = $revision->getComment(); if ($this->fld_comment) { $vals['comment'] = $comment; } if ($this->fld_parsedcomment) { $vals['parsedcomment'] = Linker::formatComment($comment, $title); } } } if ($this->fld_tags) { if ($row->ts_tags) { $tags = explode(',', $row->ts_tags); $this->getResult()->setIndexedTagName($tags, 'tag'); $vals['tags'] = $tags; } else { $vals['tags'] = array(); } } if (!is_null($this->token)) { $tokenFunctions = $this->getTokenFunctions(); foreach ($this->token as $t) { $val = call_user_func($tokenFunctions[$t], $title->getArticleID(), $title, $revision); if ($val === false) { $this->setWarning("Action '{$t}' is not allowed for the current user"); } else { $vals[$t . 'token'] = $val; } } } $content = null; global $wgParser; if ($this->fld_content || !is_null($this->diffto) || !is_null($this->difftotext)) { $content = $revision->getContent(); // Expand templates after getting section content because // template-added sections don't count and Parser::preprocess() // will have less input if ($content && $this->section !== false) { $content = $content->getSection($this->section, false); if (!$content) { $this->dieUsage("There is no section {$this->section} in r" . $revision->getId(), 'nosuchsection'); } } } if ($this->fld_content && $content && !$revision->isDeleted(Revision::DELETED_TEXT)) { $text = null; if ($this->generateXML) { if ($content->getModel() === CONTENT_MODEL_WIKITEXT) { $t = $content->getNativeData(); # note: don't set $text $wgParser->startExternalParse($title, ParserOptions::newFromContext($this->getContext()), OT_PREPROCESS); $dom = $wgParser->preprocessToDom($t); if (is_callable(array($dom, 'saveXML'))) { $xml = $dom->saveXML(); } else { $xml = $dom->__toString(); } $vals['parsetree'] = $xml; } else { $this->setWarning("Conversion to XML is supported for wikitext only, " . $title->getPrefixedDBkey() . " uses content model " . $content->getModel() . ")"); } } if ($this->expandTemplates && !$this->parseContent) { #XXX: implement template expansion for all content types in ContentHandler? if ($content->getModel() === CONTENT_MODEL_WIKITEXT) { $text = $content->getNativeData(); $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext())); } else { $this->setWarning("Template expansion is supported for wikitext only, " . $title->getPrefixedDBkey() . " uses content model " . $content->getModel() . ")"); $text = false; } } if ($this->parseContent) { $po = $content->getParserOutput($title, $revision->getId(), ParserOptions::newFromContext($this->getContext())); $text = $po->getText(); } if ($text === null) { $format = $this->contentFormat ? $this->contentFormat : $content->getDefaultFormat(); $model = $content->getModel(); if (!$content->isSupportedFormat($format)) { $name = $title->getPrefixedDBkey(); $this->dieUsage("The requested format {$this->contentFormat} is not supported " . "for content model {$model} used by {$name}", 'badformat'); } $text = $content->serialize($format); // always include format and model. // Format is needed to deserialize, model is needed to interpret. $vals['contentformat'] = $format; $vals['contentmodel'] = $model; } if ($text !== false) { ApiResult::setContent($vals, $text); } } elseif ($this->fld_content) { if ($revision->isDeleted(Revision::DELETED_TEXT)) { $vals['texthidden'] = ''; } else { $vals['textmissing'] = ''; } } if (!is_null($this->diffto) || !is_null($this->difftotext)) { global $wgAPIMaxUncachedDiffs; static $n = 0; // Number of uncached diffs we've had if (is_null($content)) { $vals['textmissing'] = ''; } elseif ($n < $wgAPIMaxUncachedDiffs) { $vals['diff'] = array(); $context = new DerivativeContext($this->getContext()); $context->setTitle($title); $handler = $revision->getContentHandler(); if (!is_null($this->difftotext)) { $model = $title->getContentModel(); if ($this->contentFormat && !ContentHandler::getForModelID($model)->isSupportedFormat($this->contentFormat)) { $name = $title->getPrefixedDBkey(); $this->dieUsage("The requested format {$this->contentFormat} is not supported for " . "content model {$model} used by {$name}", 'badformat'); } $difftocontent = ContentHandler::makeContent($this->difftotext, $title, $model, $this->contentFormat); $engine = $handler->createDifferenceEngine($context); $engine->setContent($content, $difftocontent); } else { $engine = $handler->createDifferenceEngine($context, $revision->getID(), $this->diffto); $vals['diff']['from'] = $engine->getOldid(); $vals['diff']['to'] = $engine->getNewid(); } $difftext = $engine->getDiffBody(); ApiResult::setContent($vals['diff'], $difftext); if (!$engine->wasCacheHit()) { $n++; } } else { $vals['diff']['notcached'] = ''; } } return $vals; }
public function execute() { // Cache may vary on $wgUser because ParserOptions gets data from it $this->getMain()->setCacheMode('anon-public-user-private'); // Get parameters $params = $this->extractRequestParams(); $this->requireMaxOneParameter($params, 'prop', 'generatexml'); if ($params['prop'] === null) { $this->logFeatureUsage('action=expandtemplates&!prop'); $this->setWarning('Because no values have been specified for the prop parameter, a ' . 'legacy format has been used for the output. This format is deprecated, and in ' . 'the future, a default value will be set for the prop parameter, causing the new' . 'format to always be used.'); $prop = array(); } else { $prop = array_flip($params['prop']); } // Create title for parser $title_obj = Title::newFromText($params['title']); if (!$title_obj || $title_obj->isExternal()) { $this->dieUsageMsg(array('invalidtitle', $params['title'])); } $result = $this->getResult(); // Parse text global $wgParser; $options = ParserOptions::newFromContext($this->getContext()); if ($params['includecomments']) { $options->setRemoveComments(false); } $retval = array(); if (isset($prop['parsetree']) || $params['generatexml']) { if (!isset($prop['parsetree'])) { $this->logFeatureUsage('action=expandtemplates&generatexml'); } $wgParser->startExternalParse($title_obj, $options, OT_PREPROCESS); $dom = $wgParser->preprocessToDom($params['text']); if (is_callable(array($dom, 'saveXML'))) { $xml = $dom->saveXML(); } else { $xml = $dom->__toString(); } if (isset($prop['parsetree'])) { unset($prop['parsetree']); $retval['parsetree'] = $xml; } else { // the old way $xml_result = array(); ApiResult::setContent($xml_result, $xml); $result->addValue(null, 'parsetree', $xml_result); } } // if they didn't want any output except (probably) the parse tree, // then don't bother actually fully expanding it if ($prop || $params['prop'] === null) { $wgParser->startExternalParse($title_obj, $options, OT_PREPROCESS); $frame = $wgParser->getPreprocessor()->newFrame(); $wikitext = $wgParser->preprocess($params['text'], $title_obj, $options, null, $frame); if ($params['prop'] === null) { // the old way ApiResult::setContent($retval, $wikitext); } else { if (isset($prop['categories'])) { $categories = $wgParser->getOutput()->getCategories(); if (!empty($categories)) { $categories_result = array(); foreach ($categories as $category => $sortkey) { $entry = array(); $entry['sortkey'] = $sortkey; ApiResult::setContent($entry, $category); $categories_result[] = $entry; } $result->setIndexedTagName($categories_result, 'category'); $retval['categories'] = $categories_result; } } if (isset($prop['volatile']) && $frame->isVolatile()) { $retval['volatile'] = ''; } if (isset($prop['ttl']) && $frame->getTTL() !== null) { $retval['ttl'] = $frame->getTTL(); } if (isset($prop['wikitext'])) { $retval['wikitext'] = $wikitext; } } } $result->setSubelements($retval, array('wikitext', 'parsetree')); $result->addValue(null, $this->getModuleName(), $retval); }
public function execute() { if ($this->getPageSet()->getGoodTitleCount() == 0) { return; } $params = $this->extractRequestParams(); if (isset($params['title']) && !isset($params['lang'])) { $this->dieUsageMsg(array('missingparam', 'lang')); } $this->addFields(array('ll_from', 'll_lang', 'll_title')); $this->addTables('langlinks'); $this->addWhereFld('ll_from', array_keys($this->getPageSet()->getGoodTitles())); if (!is_null($params['continue'])) { $cont = explode('|', $params['continue']); $this->dieContinueUsageIf(count($cont) != 2); $op = $params['dir'] == 'descending' ? '<' : '>'; $llfrom = intval($cont[0]); $lllang = $this->getDB()->addQuotes($cont[1]); $this->addWhere("ll_from {$op} {$llfrom} OR " . "(ll_from = {$llfrom} AND " . "ll_lang {$op}= {$lllang})"); } //FIXME: (follow-up) To allow extensions to add to the language links, we need // to load them all, add the extra links, then apply paging. // Should not be terrible, it's not going to be more than a few hundred links. // Note that, since (ll_from, ll_lang) is a unique key, we don't need // to sort by ll_title to ensure deterministic ordering. $sort = $params['dir'] == 'descending' ? ' DESC' : ''; if (isset($params['lang'])) { $this->addWhereFld('ll_lang', $params['lang']); if (isset($params['title'])) { $this->addWhereFld('ll_title', $params['title']); } $this->addOption('ORDER BY', 'll_from' . $sort); } else { // Don't order by ll_from if it's constant in the WHERE clause if (count($this->getPageSet()->getGoodTitles()) == 1) { $this->addOption('ORDER BY', 'll_lang' . $sort); } else { $this->addOption('ORDER BY', array('ll_from' . $sort, 'll_lang' . $sort)); } } $this->addOption('LIMIT', $params['limit'] + 1); $res = $this->select(__METHOD__); $count = 0; foreach ($res as $row) { if (++$count > $params['limit']) { // We've reached the one extra which shows that // there are additional pages to be had. Stop here... $this->setContinueEnumParameter('continue', "{$row->ll_from}|{$row->ll_lang}"); break; } $entry = array('lang' => $row->ll_lang); if ($params['url']) { $title = Title::newFromText("{$row->ll_lang}:{$row->ll_title}"); if ($title) { $entry['url'] = wfExpandUrl($title->getFullURL(), PROTO_CURRENT); } } ApiResult::setContent($entry, $row->ll_title); $fit = $this->addPageSubItem($row->ll_from, $entry); if (!$fit) { $this->setContinueEnumParameter('continue', "{$row->ll_from}|{$row->ll_lang}"); break; } } }
public function execute() { global $wgUser; // Before doing anything at all, let's check permissions if (!$wgUser->isAllowed('deletedhistory')) { $this->dieUsage('You don\'t have permission to view deleted revision information', 'permissiondenied'); } $db = $this->getDB(); $params = $this->extractRequestParams(false); $prop = array_flip($params['prop']); $fld_revid = isset($prop['revid']); $fld_user = isset($prop['user']); $fld_comment = isset($prop['comment']); $fld_minor = isset($prop['minor']); $fld_len = isset($prop['len']); $fld_content = isset($prop['content']); $fld_token = isset($prop['token']); $result = $this->getResult(); $pageSet = $this->getPageSet(); $titles = $pageSet->getTitles(); $data = array(); // This module operates in three modes: // 'revs': List deleted revs for certain titles // 'user': List deleted revs by a certain user // 'all': List all deleted revs $mode = 'all'; if (count($titles) > 0) { $mode = 'revs'; } else { if (!is_null($params['user'])) { $mode = 'user'; } } if (!is_null($params['user']) && !is_null($params['excludeuser'])) { $this->dieUsage('user and excludeuser cannot be used together', 'badparams'); } $this->addTables('archive'); $this->addWhere('ar_deleted = 0'); $this->addFields(array('ar_title', 'ar_namespace', 'ar_timestamp')); if ($fld_revid) { $this->addFields('ar_rev_id'); } if ($fld_user) { $this->addFields('ar_user_text'); } if ($fld_comment) { $this->addFields('ar_comment'); } if ($fld_minor) { $this->addFields('ar_minor_edit'); } if ($fld_len) { $this->addFields('ar_len'); } if ($fld_content) { $this->addTables('text'); $this->addFields(array('ar_text', 'ar_text_id', 'old_text', 'old_flags')); $this->addWhere('ar_text_id = old_id'); // This also means stricter restrictions if (!$wgUser->isAllowed('undelete')) { $this->dieUsage('You don\'t have permission to view deleted revision content', 'permissiondenied'); } } // Check limits $userMax = $fld_content ? ApiBase::LIMIT_SML1 : ApiBase::LIMIT_BIG1; $botMax = $fld_content ? ApiBase::LIMIT_SML2 : ApiBase::LIMIT_BIG2; $limit = $params['limit']; if ($limit == 'max') { $limit = $this->getMain()->canApiHighLimits() ? $botMax : $userMax; $this->getResult()->addValue('limits', $this->getModuleName(), $limit); } $this->validateLimit('limit', $limit, 1, $userMax, $botMax); if ($fld_token) { // Undelete tokens are identical for all pages, so we cache one here $token = $wgUser->editToken(); } // We need a custom WHERE clause that matches all titles. if ($mode == 'revs') { $lb = new LinkBatch($titles); $where = $lb->constructSet('ar', $db); $this->addWhere($where); } elseif ($mode == 'all') { $this->addWhereFld('ar_namespace', $params['namespace']); if (!is_null($params['from'])) { $from = $this->getDB()->strencode($this->titleToKey($params['from'])); $this->addWhere("ar_title >= '{$from}'"); } } if (!is_null($params['user'])) { $this->addWhereFld('ar_user_text', $params['user']); } elseif (!is_null($params['excludeuser'])) { $this->addWhere('ar_user_text != ' . $this->getDB()->addQuotes($params['excludeuser'])); } if (!is_null($params['continue']) && ($mode == 'all' || $mode == 'revs')) { $cont = explode('|', $params['continue']); if (count($cont) != 3) { $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "badcontinue"); } $ns = intval($cont[0]); $title = $this->getDB()->strencode($this->titleToKey($cont[1])); $ts = $this->getDB()->strencode($cont[2]); $op = $params['dir'] == 'newer' ? '>' : '<'; $this->addWhere("ar_namespace {$op} {$ns} OR " . "(ar_namespace = {$ns} AND " . "(ar_title {$op} '{$title}' OR " . "(ar_title = '{$title}' AND " . "ar_timestamp = '{$ts}')))"); } $this->addOption('LIMIT', $limit + 1); $this->addOption('USE INDEX', array('archive' => $mode == 'user' ? 'usertext_timestamp' : 'name_title_timestamp')); if ($mode == 'all') { if ($params['unique']) { $this->addOption('GROUP BY', 'ar_title'); $this->addOption('ORDER BY', 'ar_title'); } else { $this->addOption('ORDER BY', 'ar_title, ar_timestamp'); } } else { if ($mode == 'revs') { // Sort by ns and title in the same order as timestamp for efficiency $this->addWhereRange('ar_namespace', $params['dir'], null, null); $this->addWhereRange('ar_title', $params['dir'], null, null); } $this->addWhereRange('ar_timestamp', $params['dir'], $params['start'], $params['end']); } $res = $this->select(__METHOD__); $pageMap = array(); // Maps ns&title to (fake) pageid $count = 0; $newPageID = 0; while ($row = $db->fetchObject($res)) { if (++$count > $limit) { // We've had enough if ($mode == 'all' || $mode == 'revs') { $this->setContinueEnumParameter('continue', intval($row->ar_namespace) . '|' . $this->keyToTitle($row->ar_title) . '|' . $row->ar_timestamp); } else { $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ar_timestamp)); } break; } $rev = array(); $rev['timestamp'] = wfTimestamp(TS_ISO_8601, $row->ar_timestamp); if ($fld_revid) { $rev['revid'] = intval($row->ar_rev_id); } if ($fld_user) { $rev['user'] = $row->ar_user_text; } if ($fld_comment) { $rev['comment'] = $row->ar_comment; } if ($fld_minor) { if ($row->ar_minor_edit == 1) { $rev['minor'] = ''; } } if ($fld_len) { $rev['len'] = $row->ar_len; } if ($fld_content) { ApiResult::setContent($rev, Revision::getRevisionText($row)); } if (!isset($pageMap[$row->ar_namespace][$row->ar_title])) { $pageID = $newPageID++; $pageMap[$row->ar_namespace][$row->ar_title] = $pageID; $t = Title::makeTitle($row->ar_namespace, $row->ar_title); $a['revisions'] = array($rev); $result->setIndexedTagName($a['revisions'], 'rev'); ApiQueryBase::addTitleInfo($a, $t); if ($fld_token) { $a['token'] = $token; } $fit = $result->addValue(array('query', $this->getModuleName()), $pageID, $a); } else { $pageID = $pageMap[$row->ar_namespace][$row->ar_title]; $fit = $result->addValue(array('query', $this->getModuleName(), $pageID, 'revisions'), null, $rev); } if (!$fit) { if ($mode == 'all' || $mode == 'revs') { $this->setContinueEnumParameter('continue', intval($row->ar_namespace) . '|' . $this->keyToTitle($row->ar_title) . '|' . $row->ar_timestamp); } else { $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ar_timestamp)); } break; } } $db->freeResult($res); $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'page'); }
/** * @param $pageSet ApiPageSet Pages to be exported * @param $result ApiResult Result to output to */ private function doExport($pageSet, $result) { $exportTitles = array(); $titles = $pageSet->getGoodTitles(); if (count($titles)) { $user = $this->getUser(); /** @var $title Title */ foreach ($titles as $title) { if ($title->userCan('read', $user)) { $exportTitles[] = $title; } } } $exporter = new WikiExporter($this->getDB()); // WikiExporter writes to stdout, so catch its // output with an ob ob_start(); $exporter->openStream(); foreach ($exportTitles as $title) { $exporter->pageByTitle($title); } $exporter->closeStream(); $exportxml = ob_get_contents(); ob_end_clean(); // Don't check the size of exported stuff // It's not continuable, so it would cause more // problems than it'd solve $result->disableSizeCheck(); if ($this->mParams['exportnowrap']) { $result->reset(); // Raw formatter will handle this $result->addValue(null, 'text', $exportxml); $result->addValue(null, 'mime', 'text/xml'); } else { $r = array(); ApiResult::setContent($r, $exportxml); $result->addValue('query', 'export', $r); } $result->enableSizeCheck(); }
private function getPopularPages() { global $wgDBname; #--- blank variables $page = $date = null; #--- initial parameters (dbname, limit, offset ...) extract($this->getInitialParams()); #--- request parameters () extract($this->extractRequestParams()); $this->initCacheKey($lcache_key, __METHOD__); try { #--- database instance $db =& $this->getDB(); $db->selectDB(!defined(WIKIA_API_QUERY_DBNAME) ? WIKIA_API_QUERY_DBNAME : $wgDBname); if (is_null($db)) { //throw new DBConnectionError($db, 'Connection error'); throw new WikiaApiQueryError(0); } /* revision was added for Gamespot project - they need last_edit timestamp */ /* its a hack, a better way would be to make wkpoppages an API generator */ /* Nef @ 20071026 */ $this->addTables(array("page_visited", "page", "revision")); $this->addFields(array('article_id', 'page_title', 'rev_timestamp AS last_edit', 'count as sum_cnt')); $this->addWhere(" page_id = article_id "); $this->addWhere(" rev_id = page_latest "); #--- identifier of page if (!is_null($page)) { if (!$this->isInt($page)) { throw new WikiaApiQueryError(1); } $this->setCacheKey($lcache_key, 'P', $page); $this->addWhereFld("page_id", $page); } #--- if (!empty($ctime)) { if (!$this->isInt($ctime)) { throw new WikiaApiQueryError(1); } } #--- limit if (!empty($limit)) { //WikiaApiQuery::DEF_LIMIT if (!$this->isInt($limit)) { throw new WikiaApiQueryError(1); } $this->addOption("LIMIT", $limit); $this->setCacheKey($lcache_key, 'L', $limit); } #--- offset if (!empty($offset)) { //WikiaApiQuery::DEF_LIMIT_COUNT if (!$this->isInt($offset)) { throw new WikiaApiQueryError(1); } $this->addOption("OFFSET", $offset); $this->setCacheKey($lcache_key, 'LO', $offset); } #--- order by $this->addOption("ORDER BY", "sum_cnt desc"); #--- group by #$this->addOption( "GROUP BY", "article_id" ); $data = array(); // check data from cache ... $cached = $this->getDataFromCache($lcache_key); if (!is_array($cached)) { $res = $this->select(__METHOD__); while ($row = $db->fetchObject($res)) { $data[$row->article_id] = array("id" => $row->article_id, "title" => $row->page_title, "last_edit" => wfTimestamp(TS_ISO_8601, $row->last_edit), "counter" => $row->sum_cnt); ApiResult::setContent($data[$row->article_id], $row->page_title); } $db->freeResult($res); $this->saveCacheData($lcache_key, $data, $ctime); } else { // ... cached $data = $cached; } } catch (WikiaApiQueryError $e) { // getText(); } catch (DBQueryError $e) { $e = new WikiaApiQueryError(0, 'Query error: ' . $e->getText()); } catch (DBConnectionError $e) { $e = new WikiaApiQueryError(0, 'DB connection error: ' . $e->getText()); } catch (DBError $e) { $e = new WikiaApiQueryError(0, 'Error in database: ' . $e->getLogMessage()); } // is exception if (isset($e)) { $data = $e->getText(); $this->getResult()->setIndexedTagName($data, 'fault'); } else { $this->getResult()->setIndexedTagName($data, 'item'); } $this->getResult()->addValue('query', $this->getModuleName(), $data); }
/** * @param $resultPageSet ApiPageSet */ private function run($resultPageSet = null) { $db = $this->getDB(); $params = $this->extractRequestParams(); $this->addTables('category'); $this->addFields('cat_title'); if (!is_null($params['continue'])) { $cont = explode('|', $params['continue']); $this->dieContinueUsageIf(count($cont) != 1); $op = $params['dir'] == 'descending' ? '<' : '>'; $cont_from = $db->addQuotes($cont[0]); $this->addWhere("cat_title {$op}= {$cont_from}"); } $dir = $params['dir'] == 'descending' ? 'older' : 'newer'; $from = is_null($params['from']) ? null : $this->titlePartToKey($params['from']); $to = is_null($params['to']) ? null : $this->titlePartToKey($params['to']); $this->addWhereRange('cat_title', $dir, $from, $to); $min = $params['min']; $max = $params['max']; if ($dir == 'newer') { $this->addWhereRange('cat_pages', 'newer', $min, $max); } else { $this->addWhereRange('cat_pages', 'older', $max, $min); } if (isset($params['prefix'])) { $this->addWhere('cat_title' . $db->buildLike($this->titlePartToKey($params['prefix']), $db->anyString())); } $this->addOption('LIMIT', $params['limit'] + 1); $sort = $params['dir'] == 'descending' ? ' DESC' : ''; $this->addOption('ORDER BY', 'cat_title' . $sort); $prop = array_flip($params['prop']); $this->addFieldsIf(array('cat_pages', 'cat_subcats', 'cat_files'), isset($prop['size'])); if (isset($prop['hidden'])) { $this->addTables(array('page', 'page_props')); $this->addJoinConds(array('page' => array('LEFT JOIN', array('page_namespace' => NS_CATEGORY, 'page_title=cat_title')), 'page_props' => array('LEFT JOIN', array('pp_page=page_id', 'pp_propname' => 'hiddencat')))); $this->addFields(array('cat_hidden' => 'pp_propname')); } $res = $this->select(__METHOD__); $pages = array(); $result = $this->getResult(); $count = 0; foreach ($res as $row) { if (++$count > $params['limit']) { // We've reached the one extra which shows that there are additional cats to be had. Stop here... $this->setContinueEnumParameter('continue', $row->cat_title); break; } // Normalize titles $titleObj = Title::makeTitle(NS_CATEGORY, $row->cat_title); if (!is_null($resultPageSet)) { $pages[] = $titleObj; } else { $item = array(); ApiResult::setContent($item, $titleObj->getText()); if (isset($prop['size'])) { $item['size'] = intval($row->cat_pages); $item['pages'] = $row->cat_pages - $row->cat_subcats - $row->cat_files; $item['files'] = intval($row->cat_files); $item['subcats'] = intval($row->cat_subcats); } if (isset($prop['hidden']) && $row->cat_hidden) { $item['hidden'] = ''; } $fit = $result->addValue(array('query', $this->getModuleName()), null, $item); if (!$fit) { $this->setContinueEnumParameter('continue', $row->cat_title); break; } } } if (is_null($resultPageSet)) { $result->setIndexedTagName_internal(array('query', $this->getModuleName()), 'c'); } else { $resultPageSet->populateFromTitles($pages); } }