function getQueryInfo() { $dbr = wfGetDB( DB_SLAVE ); $page_ns_index = MWNamespace::getCanonicalIndex( strtolower( str_replace( ' ', '_', $this->page_namespace ) ) ); // Construct subqueries $pagesWithScansSubquery = $dbr->selectSQLText( array( 'templatelinks', 'page' ), 'DISTINCT tl_from', array( 'page_id=tl_from', 'tl_namespace' => $page_ns_index, 'page_namespace' => NS_MAIN ) ); // Exclude disambiguation pages too $dt = $this->disambiguation_templates( $dbr ); $disambigPagesSubquery = $dbr->selectSQLText( array( 'page', 'templatelinks' ), 'page_id', array( 'page_id=tl_from', 'page_namespace' => NS_MAIN, $dt ) ); return array( 'tables' => 'page', 'fields' => array( "'PagesWithoutScans' AS type", 'page_namespace AS namespace', 'page_title AS title', 'page_len AS value' ), 'conds' => array( 'page_namespace' => NS_MAIN, 'page_is_redirect' => 0, "page_id NOT IN ($pagesWithScansSubquery)", "page_id NOT IN ($disambigPagesSubquery)" ), 'options' => array( 'USE INDEX' => 'page_len' ) ); }
public function getQueryInfo() { $conds = array(); if ($this->searchTerm) { if ($this->searchList !== null) { $index_namespace = $this->index_namespace; $index_ns_index = MWNamespace::getCanonicalIndex(strtolower(str_replace(' ', '_', $index_namespace))); $conds = array('page_namespace' => $index_ns_index); if ($this->searchList) { $conds['page_title'] = $this->searchList; } else { // If not pages were found do not return results $conds[] = 'false'; } } else { $conds = null; } } return array('tables' => array('pr_index', 'page'), 'fields' => array('page_title AS title', '2*pr_q4+pr_q3 AS value', 'pr_count', 'pr_q0', 'pr_q1', 'pr_q2', 'pr_q3', 'pr_q4'), 'conds' => $conds, 'options' => array(), 'join_conds' => array('page' => array('LEFT JOIN', 'page_id=pr_page_id'))); }
static function ns($parser, $part1 = '') { global $wgContLang; $found = false; if (intval($part1) || $part1 == "0") { $text = $wgContLang->getNsText(intval($part1)); $found = true; } else { $param = str_replace(' ', '_', strtolower($part1)); $index = MWNamespace::getCanonicalIndex(strtolower($param)); if (!is_null($index)) { $text = $wgContLang->getNsText($index); $found = true; } } if ($found) { return $text; } else { return array('found' => false); } }
public function execute() { global $wgTranslateMessageNamespaces; $namespace = $this->getOption('namespace', $wgTranslateMessageNamespaces); if (is_string($namespace)) { if (!MWNamespace::exists($namespace)) { $namespace = MWNamespace::getCanonicalIndex($namespace); if ($namespace === null) { $this->error('Bad namespace', true); } } } $db = wfGetDB(DB_MASTER); $tables = array('page', 'text', 'revision'); $fields = array('page_id', 'page_title', 'page_namespace', 'rev_id', 'old_text', 'old_flags'); $conds = array('page_latest = rev_id', 'old_id = rev_text_id', 'page_namespace' => $namespace); $limit = 100; $offset = 0; while (true) { $inserts = array(); $this->output('.', 0); $options = array('LIMIT' => $limit, 'OFFSET' => $offset); $res = $db->select($tables, $fields, $conds, __METHOD__, $options); if (!$res->numRows()) { break; } foreach ($res as $r) { $text = Revision::getRevisionText($r); if (strpos($text, TRANSLATE_FUZZY) !== false) { $inserts[] = array('rt_page' => $r->page_id, 'rt_revision' => $r->rev_id, 'rt_type' => RevTag::getType('fuzzy')); } } $offset += $limit; $db->replace('revtag', 'rt_type_page_revision', $inserts, __METHOD__); } }
function createPage() { $expressionNameSpaceId = MWNamespace::getCanonicalIndex('expression'); wfDebug( "NS ID: $expressionNameSpaceId \n" ); return createPage( $expressionNameSpaceId, getPageTitle( $this->spelling ) ); }
function getNamespaceID($namespace) { if ($namespace == "") { return 0; } else { $ns = new MWNamespace(); return $ns->getCanonicalIndex(trim(strtolower($namespace))); } }
/** * Constructor. * * @since 0.1 * * @param integer $id Set to null when creating a new group. * @param string $name * @param array $categories List of category names * @param array $namespaces List of namespace names or IDs * @param array $properties List of property names * @param array $concepts List of concept names * @param array $customTexts List of custom texts */ public function __construct($id, $name, array $categories, array $namespaces, array $properties, array $concepts, array $customTexts) { $this->id = $id; $this->name = $name; $this->categories = $categories; $this->properties = $properties; $this->concepts = $concepts; $this->customTexts = $customTexts; foreach ($namespaces as $ns) { if (preg_match("/^-?([0-9])+\$/", $ns)) { $this->namespaces[] = $ns; } elseif ($ns == '' || strtolower($ns) == 'main') { $this->namespaces[] = 0; } else { $ns = MWNamespace::getCanonicalIndex(strtolower($ns)); if (!is_null($ns)) { $this->namespaces[] = $ns; } } } }
function __construct(IContextSource $context, $templatetext, $argv, $parser) { global $wgContLang; $this->title = $context->getTitle(); $this->skin = $context->getSkin(); $this->parser = $parser; $this->templatetext = $templatetext; if (!is_null($this->templatetext)) { $this->templatetext = trim($this->templatetext); if ($this->templatetext == '') { $this->templatetext = null; } } $this->usetemplate = !is_null($this->templatetext); $this->templateparser = null; $this->templateoptions = null; #$template = @$argv['template']; #if ( $this->usetemplate ) { #print "<pre>$templatetitle</pre>"; $this->templateparser = $parser; #$this->templateparser = clone $parser; #$this->templateparser->setOutputType( Parser::OT_HTML ); $this->templateoptions = new ParserOptions(); $this->templateoptions->setEditSection(false); $this->templateoptions->setNumberHeadings(false); $this->templateoptions->setRemoveComments(true); //$this->templateoptions->setUseDynamicDates( false ); // removed in mw 1.21 $this->templateoptions->setInterwikiMagic(true); //strip interlanguage-links $this->templateoptions->setAllowSpecialInclusion(false); #$this->templatetitle = Title::newFromText( $template, NS_TEMPLATE ); #$templatetext = $templateparser->fetchTemplate( $templatetitle ); #print "<pre>$templatetext</pre>"; #$templateoptions->setRemoveComments( true ); #$templateoptions->setMaxIncludeSize( self::MAX_INCLUDE_SIZE ); #} if (!$this->usetemplate) { $this->changelist = new OldChangesList($this->skin); } #$this->feedId = @$argv['id']; $this->prefix = @$argv['prefix']; $this->postfix = @$argv['postfix']; $this->limit = @$argv['limit']; if (!$this->limit) { $this->limit = 10; } elseif ($this->limit > 100) { $this->limit = 100; } $this->unique = @$argv['unique']; if ($this->unique === 'false' || $this->unique === 'no' || $this->unique === '0') { $this->unique = false; } $this->namespaces = @$argv['namespaces']; if (!is_null($this->namespaces)) { $this->namespaces = preg_split('!\\s*(\\|\\s*)+!', trim($this->namespaces)); foreach ($this->namespaces as $i => $ns) { $ns = $wgContLang->lc($ns); if ($ns === '-' || $ns === '0' || $ns === 'main' || $ns === 'article') { $this->namespaces[$i] = 0; } else { $this->namespaces[$i] = MWNamespace::getCanonicalIndex($ns); if ($this->namespaces[$i] === false || $this->namespaces[$i] === null) { $this->namespaces[$i] = $wgContLang->getNsIndex($ns); } } if ($this->namespaces[$i] === false || $this->namespaces[$i] === null) { unset($this->namespaces[$i]); } } } $this->categories = @$argv['categories']; if (!is_null($this->categories)) { $this->categories = preg_split('!\\s*(\\|\\s*)+!', trim($this->categories)); foreach ($this->categories as $i => $n) { $t = Title::makeTitleSafe(NS_CATEGORY, $n); $n = $t->getDBkey(); $this->categories[$i] = $n; } } $this->pubtrigger = @$argv['trigger']; if ($this->pubtrigger) { $this->publication = true; } else { $this->publication = false; } $this->permalinks = @$argv['permalinks']; if ($this->permalinks === 'false' || $this->permalinks === 'no' || $this->permalinks === '0') { $this->permalinks = false; } $this->nominor = @$argv['nominor']; if ($this->nominor === 'false' || $this->nominor === 'no' || $this->nominor === '0') { $this->nominor = false; } $this->nobot = @$argv['nobot']; if ($this->nobot === 'false' || $this->nobot === 'no' || $this->nobot === '0') { $this->nobot = false; } $this->noanon = @$argv['noanon']; if ($this->noanon === 'false' || $this->noanon === 'no' || $this->noanon === '0') { $this->noanon = false; } $this->notalk = @$argv['notalk']; if ($this->notalk === 'false' || $this->notalk === 'no' || $this->notalk === '0') { $this->notalk = false; } $this->onlypatrolled = @$argv['onlypatrolled']; if ($this->onlypatrolled === 'false' || $this->onlypatrolled === 'no' || $this->onlypatrolled === '0') { $this->onlypatrolled = false; } $this->onlynew = @$argv['onlynew']; if ($this->onlynew === 'false' || $this->onlynew === 'no' || $this->onlynew === '0') { $this->onlynew = false; } $this->types = array(RC_EDIT, RC_NEW); /* this doesn't work right if ( $unique ) { $group[] = 'rc_namespace AND rc_title'; } */ }
public function execute($par = null) { global $wgOut, $wgRequest, $wgServer, $wgWikiFeedsSettings, $wgUser; $request = isset($par) ? $par : $wgRequest->getText('request'); if (!$request) { $wgOut->addWikiText(wfMsg('wikifeeds_mainpage')); // do special voodoo if private watchlist is enabled if ($wgWikiFeedsSettings['watchlistPrivate'] && $wgUser->isLoggedIn()) { if (!$wgUser->getOption('watchlistToken')) { $token = md5(microtime() . $wgUser->getID()); $wgUser->setOption('watchlistToken', $token); $wgUser->saveSettings(); } $token = $wgUser->getOption('watchlistToken'); $privateFeedUrl = Title::newFromText('WikiFeeds/atom/watchlist/user/' . $wgUser->getName() . '/token/' . $token, NS_SPECIAL); // and display blurb about token $wgOut->addWikiText(wfMsg('wikifeeds_tokeninfo', $token, $privateFeedUrl->getFullUrl())); } } else { $arr = explode('/', $request); //might have a valid request for a feed if (count($arr) >= 2) { $format = null; $feed = null; $count = self::DEFAULT_COUNT; $namespace = null; $params = array(); $areSane = true; if (strtolower($arr[0]) == 'atom') { $format = GenericXmlSyndicationFeed::FORMAT_ATOM10; } else { if (strtolower($arr[0]) == 'rss') { $format = GenericXmlSyndicationFeed::FORMAT_RSS20; } else { $wgOut->addWikiText(wfMsg('wikifeeds_unknownformat')); $areSane = false; } } switch (strtolower($arr[1])) { case 'newestarticles': $feed = self::FEED_NEWESTARTICLES; break; case 'recentarticlechanges': $feed = self::FEED_RECENTARTICLECHANGES; break; case 'recentuserchanges': $feed = self::FEED_RECENTUSERCHANGES; break; case 'newestuserarticles': $feed = self::FEED_NEWESTARTICLESBYUSER; break; case 'watchlist': $feed = self::FEED_USERWATCHLIST; break; case 'recentcategorychanges': $feed = self::FEED_RECENTCATEGORYCHANGES; break; case 'newestcategoryarticles': $feed = self::FEED_NEWESTCATEGORYARTICLES; break; case 'recentchangesnotincategory': $feed = self::FEED_RECENTCHANGESNOTINCATEGORY; break; case 'newestarticlesnotincategory': $feed = self::FEED_NEWESTARTICLESNOTINCATEGORY; break; default: $wgOut->addWikiText(wfMsg('wikifeeds_unknownfeed')); $areSane = false; } //now we look for additional parameters if (count($arr) > 3 && count($arr) % 2 == 0) { for ($i = 2; $i < count($arr); $i += 2) { $params[$arr[$i]] = $arr[$i + 1]; } } //if we are dealing with a category feed, we need a category specified if ($feed === self::FEED_RECENTCATEGORYCHANGES || $feed === self::FEED_NEWESTCATEGORYARTICLES || $feed === self::FEED_RECENTCHANGESNOTINCATEGORY || $feed === self::FEED_NEWESTARTICLESNOTINCATEGORY) { if (!array_key_exists('category', $params)) { $wgOut->addWikiText(wfMsg('wikifeeds_undefinedcategory')); $areSane = false; } else { //verify category is valid if (!$this->categoryExists($params['category'])) { $wgOut->addWikiText(wfMsg('wikifeeds_categorynoexist')); $areSane = false; } } } //if we are asking for a user feed, we need the user parameter if ($feed === self::FEED_RECENTUSERCHANGES || $feed === self::FEED_USERWATCHLIST || $feed === self::FEED_NEWESTARTICLESBYUSER) { if (!array_key_exists('user', $params)) { $wgOut->addWikiText(wfMsg('wikifeeds_undefineduser')); $areSane = false; } else { //verify the user exists $userId = User::idFromName($params['user']); if (is_null($userId) || $userId === 0) { $wgOut->addWikiText(wfMsg('wikifeeds_unknownuser')); $areSane = false; } else { if ($feed === self::FEED_USERWATCHLIST && $wgWikiFeedsSettings['watchlistPrivate']) { if (!array_key_exists('token', $params)) { $wgOut->addWikiText(wfMsg('wikifeeds_nowatchlisttoken')); $areSane = false; } else { $token = $params['token']; // verify token is sane $user = User::newFromId($userId); if ($token != $user->getOption('watchlistToken')) { $wgOut->addWikiText(wfMsg('wikifeeds_invalidwatchlisttoken')); $areSane = false; } } } } } } if (array_key_exists('count', $params) && ctype_digit($params['count']) && $params['count'] > 0) { $count = $params['count']; } if (array_key_exists('namespace', $params)) { $ns = $params['namespace']; if (ctype_digit($ns) && MWNamespace::exists($ns)) { // parameter is a number $namespace = $ns; } else { if (MWNamespace::exists(MWNamespace::getCanonicalIndex($ns))) { // parameter is a text $namespace = MWNamespace::getCanonicalIndex($ns); } else { if (strtolower($ns) == 'main' || $ns == '0') { // parameter is MAIN namespace (ns_id:0) $namespace = 0; } else { //namespace does not exist, show nothing $wgOut->addWikiText(wfMsg('wikifeeds_namespacenoexist')); $areSane = false; $namespace = "NULL"; } } } } if (array_key_exists('unique', $params) && $params['count'] != 'false') { $unique = true; } else { $unique = false; } //we are sane, so let's create a feed if ($areSane) { $wgOut->disable(); //if we successfully fetched a feed from the cache if ($this->_settings['cacheEnable'] && ($cached = $this->_cacheFetchFeed($feed, $format, $params))) { //$cached is an array containing feed text and some metadata header('Content-Type: ' . $cached['content-type']); print $cached['content']; } else { //no cache was hit, assemble the feed $Feed = new GenericXmlSyndicationFeed($format); switch ($feed) { case self::FEED_NEWESTARTICLES: $this->makeNewestArticles($Feed, $namespace, $count); break; case self::FEED_RECENTARTICLECHANGES: $this->makeRecentArticleChanges($Feed, $namespace, $count, $unique); break; case self::FEED_NEWESTARTICLESBYUSER: $this->makeNewestArticleByUser($Feed, $params['user'], $namespace, $count); break; case self::FEED_RECENTUSERCHANGES: $this->makeRecentUserChanges($Feed, $params['user'], $namespace, $count); break; case self::FEED_USERWATCHLIST: $this->makeUserWatchlist($Feed, $params['user'], $namespace, $count); break; case self::FEED_RECENTCATEGORYCHANGES: $this->makeRecentCategoryPageChanges($Feed, $params['category'], $namespace, $count); break; case self::FEED_NEWESTCATEGORYARTICLES: $this->makeNewestArticlesInCategory($Feed, $params['category'], $namespace, $count); break; case self::FEED_RECENTCHANGESNOTINCATEGORY: $this->makeRecentPageChangesNotInCategory($Feed, $params['category'], $namespace, $count); break; case self::FEED_NEWESTARTICLESNOTINCATEGORY: $this->makeNewestArticlesNotInCategory($Feed, $params['category'], $namespace, $count); break; default: echo 'unknown feed'; } $feedDate = 0; foreach ($Feed->items as $i) { if ($i->mArticle->mTimestamp > $feedDate) { $feedDate = $i->mArticle->mTimestamp; } } $Feed->lastUpdated = wfTimestamp(TS_UNIX, $feedDate); $Feed->linkSelf = $wgServer . $_SERVER['REQUEST_URI']; $Feed->sendOutput(); //finally, cache the feed if ($this->_settings['cacheEnable']) { $this->_cacheSaveFeed($Feed, $feed, $format, $params); } } } } } $this->setHeaders(); }
/** * Get a list of suggested titles * * @param WebRequest $request * @return bool|Object|string * * @author Inez Korczyński <*****@*****.**> * @author Robert Elwell <*****@*****.**> */ static function getLinkSuggest(WebRequest $request) { global $wgContLang, $wgContentNamespaces, $wgMemc, $wgLinkSuggestLimit; $measurement = T::start(__FUNCTION__); wfProfileIn(__METHOD__); $isMobile = F::app()->checkSkin('wikiamobile'); // trim passed query and replace spaces by underscores // - this is how MediaWiki store article titles in database $query = urldecode(trim($request->getText('query'))); $query = str_replace(' ', '_', $query); if ($isMobile) { $key = wfMemcKey(__METHOD__, md5($query . '_' . $request->getText('format') . $request->getText('nospecial', '')), 'WikiaMobile'); } else { $key = wfMemcKey(__METHOD__, md5($query . '_' . $request->getText('format') . $request->getText('nospecial', ''))); } if (strlen($query) < 3) { // enforce minimum character limit on server side $out = self::getEmptyResponse($request->getText('format')); } else { if ($cached = $wgMemc->get($key)) { $out = $cached; } } if (isset($out)) { wfProfileOut(__METHOD__); return $out; } // Allow the calling-code to specify a namespace to search in (which at the moment, could be overridden by having prefixed text in the input field). // NOTE: This extension does parse titles to try to find things in other namespaces, but that actually doesn't work in practice because jQuery // Autocomplete will stop making requests after it finds 0 results. So if you start to type "Category" and there is no page beginning // with "Cate", it will not even make the call to LinkSuggest. $namespace = $request->getVal('ns'); // explode passed query by ':' to get namespace and article title $queryParts = explode(':', $query, 2); if (count($queryParts) == 2) { $query = $queryParts[1]; $namespaceName = $queryParts[0]; // try to get the index by canonical name first $namespace = MWNamespace::getCanonicalIndex(strtolower($namespaceName)); if ($namespace == null) { // if we failed, try looking through localized namespace names $namespace = array_search(ucfirst($namespaceName), $wgContLang->getNamespaces()); if (empty($namespace)) { // getting here means our "namespace" is not real and can only be part of the title $query = $namespaceName . ':' . $query; } } if ($namespace !== null && $query === '') { $out = self::getEmptyResponse($request->getText('format')); wfProfileOut(__METHOD__); return $out; } } // which namespaces to search in? if (empty($namespace)) { // search only within content namespaces (BugId:4625) - default behaviour $namespaces = $wgContentNamespaces; } else { // search only within a given namespace $namespaces = array($namespace); } //limit the result only to this namespace $namespaceFilter = $request->getVal('nsfilter'); if (strlen($namespaceFilter) > 0) { $namespaces = array($namespaceFilter); } if (!empty($namespaceFilter) && $namespace != $namespaceFilter) { $out = self::getEmptyResponse($request->getText('format')); wfProfileOut(__METHOD__); return $out; } $query = addslashes($query); $db = wfGetDB(DB_SLAVE, 'search'); $redirects = array(); $results = array(); $exactMatchRow = null; $queryLower = strtolower($query); $sql1Measurement = T::start([__FUNCTION__, "sql-1"]); $res = $db->select(array('querycache', 'page'), array('page_namespace', 'page_title', 'page_is_redirect'), array('qc_title = page_title', 'qc_namespace = page_namespace', 'page_is_redirect = 0', 'qc_type' => 'Mostlinked', "(qc_title LIKE '{$query}%' or LOWER(qc_title) LIKE '{$queryLower}%')", 'qc_namespace' => $namespaces), __METHOD__, array('ORDER BY' => 'qc_value DESC', 'LIMIT' => $wgLinkSuggestLimit)); self::formatResults($db, $res, $query, $redirects, $results, $exactMatchRow); $sql1Measurement->stop(); if (count($namespaces) > 0) { $commaJoinedNamespaces = count($namespaces) > 1 ? array_shift($namespaces) . ', ' . implode(', ', $namespaces) : $namespaces[0]; } $pageNamespaceClause = isset($commaJoinedNamespaces) ? 'page_namespace IN (' . $commaJoinedNamespaces . ') AND ' : ''; if (count($results) < $wgLinkSuggestLimit) { /** * @var string $pageTitlePrefilter this condition is able to use name_title index. It's added only for performance reasons. * It uses fact that page titles can't start with lowercase letter. */ $pageTitlePrefilter = ""; if (strlen($queryLower) >= 2) { $pageTitlePrefilter = "(\n\t\t\t\t\t\t\t( page_title " . $db->buildLike(strtoupper($queryLower[0]) . strtolower($queryLower[1]), $db->anyString()) . " ) OR\n\t\t\t\t\t\t\t( page_title " . $db->buildLike(strtoupper($queryLower[0]) . strtoupper($queryLower[1]), $db->anyString()) . " ) ) AND "; } else { if (strlen($queryLower) >= 1) { $pageTitlePrefilter = "( page_title " . $db->buildLike(strtoupper($queryLower[0]), $db->anyString()) . " ) AND "; } } // TODO: use $db->select helper method $sql = "SELECT page_len, page_id, page_title, rd_title, page_namespace, rd_namespace, page_is_redirect\n\t\t\t\t\t\tFROM page\n\t\t\t\t\t\tLEFT JOIN redirect ON page_is_redirect = 1 AND page_id = rd_from\n\t\t\t\t\t\tLEFT JOIN querycache ON qc_title = page_title AND qc_type = 'BrokenRedirects'\n\t\t\t\t\t\tWHERE {$pageTitlePrefilter} {$pageNamespaceClause} (LOWER(page_title) LIKE '{$queryLower}%')\n\t\t\t\t\t\t\tAND qc_type IS NULL\n\t\t\t\t\t\tLIMIT " . $wgLinkSuggestLimit * 3; // we fetch 3 times more results to leave out redirects to the same page $sql2Measurement = T::start([__FUNCTION__, "sql-2"]); $res = $db->query($sql, __METHOD__); self::formatResults($db, $res, $query, $redirects, $results, $exactMatchRow); $sql2Measurement->stop(); } if ($exactMatchRow !== null) { /* @var StdClass $exactMatchRow */ $row = $exactMatchRow; $titleFormatted = self::formatTitle($row->page_namespace, $row->page_title); if ($row->page_is_redirect == 0) { // remove any instances of original array's value $resultsFlipped = array_flip($results); unset($resultsFlipped[$titleFormatted]); $results = array_flip($resultsFlipped); array_unshift($results, $titleFormatted); $flippedRedirs = array_flip($redirects); if (isset($flippedRedirs[$titleFormatted])) { unset($redirects[$flippedRedirs[$titleFormatted]]); } } else { $redirTitleFormatted = self::formatTitle($row->page_namespace, $row->rd_title); // remove any instances of original array's value $resultsFlipped = array_flip($results); unset($resultsFlipped[$redirTitleFormatted]); $results = array_flip($resultsFlipped); array_unshift($results, $redirTitleFormatted); $redirects[$redirTitleFormatted] = $titleFormatted; } } $db->freeResult($res); if ($request->getText('nospecial', 0) != 1) { // bugid 29988: include special pages // (registered in SpecialPage::$mList, not in the DB like a normal page) if ($namespaces == array('-1') && strlen($query) > 0) { $specialPagesByAlpha = SpecialPageFactory::getList(); $specialPagesByAlpha = get_object_vars($specialPagesByAlpha); ksort($specialPagesByAlpha, SORT_STRING); array_walk($specialPagesByAlpha, function ($val, $key) use(&$results, $query) { if (strtolower(substr($key, 0, strlen($query))) === strtolower($query)) { $results[] = self::formatTitle('-1', $key); } }); } } // Overwrite canonical title with redirect title for all formats self::replaceResultIfRedirected($results, $redirects); $format = $request->getText('format'); if ($format == 'json') { $result_values = array_values($results); if ($isMobile) { $out = json_encode(array(array_splice($result_values, 0, 10), array_splice($redirects, -1, 1))); } else { $out = json_encode(array('query' => $request->getText('query'), 'suggestions' => $result_values, 'redirects' => $redirects)); } } elseif ($format == 'array') { $out = $results; } else { // legacy: LinkSuggest.js uses plain text $out = implode("\n", $results); } // 15 minutes times four (one hour, but easier to slice and dice) $wgMemc->set($key, $out, 4 * 900); wfProfileOut(__METHOD__); return $out; }
/** * AJAX callback function * * @return $ar Array of link suggestions */ function getLinkSuggest() { global $wgRequest, $wgContLang, $wgContentNamespaces; // trim passed query and replace spaces by underscores // - this is how MediaWiki stores article titles in database $query = urldecode(trim($wgRequest->getText('query'))); $query = str_replace(' ', '_', $query); // explode passed query by ':' to get namespace and article title $queryParts = explode(':', $query, 2); if (count($queryParts) == 2) { $query = $queryParts[1]; $namespaceName = $queryParts[0]; // try to get the index by canonical name first $namespace = MWNamespace::getCanonicalIndex(strtolower($namespaceName)); if ($namespace == null) { // if we failed, try looking through localized namespace names $namespace = array_search(ucfirst($namespaceName), $wgContLang->getNamespaces()); if (empty($namespace)) { // getting here means our "namespace" is not real and can only // be a part of the title $query = $namespaceName . ':' . $query; } } } // list of namespaces to search in if (empty($namespace)) { // search only within content namespaces - default behaviour $namespaces = $wgContentNamespaces; } else { // search only within a namespace from query $namespaces = $namespace; } $results = array(); $dbr = wfGetDB(DB_SLAVE); $query = $dbr->strencode(mb_strtolower($query)); $res = $dbr->select(array('querycache', 'page'), array('qc_namespace', 'qc_title'), array('qc_title = page_title', 'qc_namespace = page_namespace', 'page_is_redirect = 0', 'qc_type' => 'Mostlinked', "LOWER(qc_title) LIKE '{$query}%'", 'qc_namespace' => $namespaces), __METHOD__, array('ORDER BY' => 'qc_value DESC', 'LIMIT' => 10)); foreach ($res as $row) { $results[] = wfLinkSuggestFormatTitle($row->qc_namespace, $row->qc_title); } $res = $dbr->select('page', array('page_namespace', 'page_title'), array("LOWER(page_title) LIKE '{$query}%'", 'page_is_redirect' => 0, 'page_namespace' => $namespaces), __METHOD__, array('ORDER BY' => 'page_title ASC', 'LIMIT' => 15 - count($results))); foreach ($res as $row) { $results[] = wfLinkSuggestFormatTitle($row->page_namespace, $row->page_title); } $results = array_unique($results); $format = $wgRequest->getText('format'); if ($format == 'json') { $out = json_encode(array('query' => $wgRequest->getText('query'), 'suggestions' => array_values($results))); } else { $out = implode("\n", $results); } $ar = new AjaxResponse($out); $ar->setCacheDuration(60 * 60); // cache results for one hour // set proper content type to ease development if ($format == 'json') { $ar->setContentType('application/json; charset=utf-8'); } else { $ar->setContentType('text/plain; charset=utf-8'); } return $ar; }
/** * In main namespace, display the proofreading status of transcluded pages. * * @param $out Object: OutputPage object */ private static function prepareArticle( $out ) { global $wgUser; $id = $out->getTitle()->mArticleID; if( $id == -1 ) { return true; } list( $page_namespace, $index_namespace ) = self::getPageAndIndexNamespace(); $page_ns_index = MWNamespace::getCanonicalIndex( strtolower( str_replace( ' ', '_', $page_namespace ) ) ); $index_ns_index = MWNamespace::getCanonicalIndex( strtolower( str_replace( ' ', '_', $index_namespace ) ) ); if( $page_ns_index == null || $index_ns_index == null ) { return true; } $dbr = wfGetDB( DB_SLAVE ); // find the index page $indextitle = null; $res = $dbr->select( array( 'templatelinks' ), array( 'tl_title AS title' ), array( 'tl_from' => $id, 'tl_namespace' => $page_ns_index ), __METHOD__, array( 'LIMIT' => 1 ) ); if( $res && $dbr->numRows( $res ) > 0 ) { $row = $dbr->fetchObject( $res ); $res2 = $dbr->select( array( 'pagelinks', 'page' ), array( 'page_title AS title' ), array( 'pl_title' => $row->title, 'pl_namespace' => $page_ns_index, 'page_namespace' => $index_ns_index ), __METHOD__, array( 'LIMIT' => 1 ), array( 'page' => array( 'LEFT JOIN', 'page_id=pl_from' ) ) ); if( $res2 && $dbr->numRows( $res2 ) > 0 ) { $row = $dbr->fetchObject( $res2 ); $indextitle = $row->title; } } if( isset( $out->is_toc ) && $out->is_toc ) { if ( $indextitle ) { $res = $dbr->select( array( 'pr_index', 'page' ), array( 'pr_count', 'pr_q0', 'pr_q1', 'pr_q2', 'pr_q3', 'pr_q4' ), array( 'page_title' => $indextitle, 'page_namespace' => $index_ns_index ), __METHOD__, null, array( 'page' => array( 'LEFT JOIN', 'page_id=pr_page_id' ) ) ); $row = $dbr->fetchObject( $res ); if( $row ) { $n0 = $row->pr_q0; $n1 = $row->pr_q1; $n2 = $row->pr_q2; $n3 = $row->pr_q3; $n4 = $row->pr_q4; $n = $row->pr_count; $ne = $n - ( $n0 + $n1 + $n2 + $n3 + $n4 ); } } } else { // count transclusions from page namespace $res = $dbr->select( array( 'templatelinks', 'page' ), array( 'COUNT(page_id) AS count' ), array( 'tl_from' => $id, 'tl_namespace' => $page_ns_index ), __METHOD__, null, array( 'page' => array( 'LEFT JOIN', 'page_title=tl_title AND page_namespace=tl_namespace' ) ) ); if( $res && $dbr->numRows( $res ) > 0 ) { $row = $dbr->fetchObject( $res ); $n = $row->count; } // find the proofreading status of transclusions $queryArr = array( 'tables' => array( 'templatelinks', 'page', 'categorylinks' ), 'fields' => array( 'COUNT(page_id) AS count' ), 'conds' => array( 'tl_from' => $id, 'tl_namespace' => $page_ns_index, 'cl_to' => '' ), 'joins' => array( 'page' => array( 'LEFT JOIN', 'page_title=tl_title AND page_namespace=tl_namespace' ), 'categorylinks' => array( 'LEFT JOIN', 'cl_from=page_id' ), ) ); $n0 = self::query_count( $dbr, $queryArr, 'proofreadpage_quality0_category' ); $n2 = self::query_count( $dbr, $queryArr, 'proofreadpage_quality2_category' ); $n3 = self::query_count( $dbr, $queryArr, 'proofreadpage_quality3_category' ); $n4 = self::query_count( $dbr, $queryArr, 'proofreadpage_quality4_category' ); // quality1 is the default value $n1 = $n - $n0 - $n2 - $n3 - $n4; $ne = 0; } if( $n == 0 ) { return true; } if( $indextitle ) { $sk = $wgUser->getSkin(); $nt = Title::makeTitleSafe( $index_ns_index, $indextitle ); $indexlink = $sk->link( $nt, wfMsg( 'proofreadpage_source' ), array( 'title' => wfMsg( 'proofreadpage_source_message' ) ) ); $out->addInlineScript( ResourceLoader::makeConfigSetScript( array( 'proofreadpage_source_href' => $indexlink ) ) ); $out->addModules( 'ext.proofreadpage.article' ); } $q0 = $n0 * 100 / $n; $q1 = $n1 * 100 / $n; $q2 = $n2 * 100 / $n; $q3 = $n3 * 100 / $n; $q4 = $n4 * 100 / $n; $qe = $ne * 100 / $n; $void_cell = $ne ? "<td align=center style='border-style:dotted;border-width:1px;' width=\"{$qe}\"></td>" : ''; $output = "<table class=\"pr_quality\" style=\"line-height:40%;\" border=0 cellpadding=0 cellspacing=0 ><tr> <td align=center > </td> <td align=center class='quality4' width=\"$q4\"></td> <td align=center class='quality3' width=\"$q3\"></td> <td align=center class='quality2' width=\"$q2\"></td> <td align=center class='quality1' width=\"$q1\"></td> <td align=center class='quality0' width=\"$q0\"></td> $void_cell </tr></table>"; $out->setSubtitle( $out->getSubtitle() . $output ); return true; }
/** * Just used when debugging **/ public function debug() { return substr($this->fullpagename, 0, strpos($this->fullpagename, ':')) . MWNamespace::getCanonicalIndex(strtolower(substr($this->fullpagename, 0, strpos($this->fullpagename, ':')))) . MWNamespace::getCanonicalName($this->NS_id) . $this->NS_name; }
public static function getPermissionsStringsForDB() { $perms = self::getPermissions(); $nsIDs = array(); foreach ($perms['Namespaces'] as $ns) { if (strtolower($ns) == 'main') { $ns = ''; } $nsIDs[] = MWNamespace::getCanonicalIndex(strtolower($ns)); } // using array of categories from $perms, create array of category // names in the same form as categorylinks.cl_to // FIXME: is mysql_real_escape_string the way to go? of does MW have something built in? $catCols = array(); foreach ($perms['Categories'] as $cat) { $catObj = Category::newFromName($cat); $catCols[] = "'" . mysql_real_escape_string($catObj->getName()) . "'"; } $pgIDs = array(); foreach ($perms['Pages'] as $pg) { $title = Title::newFromText($pg); $pgIDs[] = $title->getArticleID(); } return array(count($nsIDs) > 0 ? implode(',', $nsIDs) : false, count($catCols) > 0 ? implode(',', $catCols) : false, count($pgIDs) > 0 ? implode(',', $pgIDs) : false); }
function getLinkSuggest() { global $wgRequest, $wgContLang, $wgCityId, $wgExternalDatawareDB, $wgContentNamespaces, $wgMemc, $wgLinkSuggestLimit; wfProfileIn(__METHOD__); $isMobile = F::app()->checkSkin('wikiamobile'); // trim passed query and replace spaces by underscores // - this is how MediaWiki store article titles in database $query = urldecode(trim($wgRequest->getText('query'))); $query = str_replace(' ', '_', $query); if ($isMobile) { $key = wfMemcKey(__METHOD__, md5($query . '_' . $wgRequest->getText('format') . $wgRequest->getText('nospecial', '')), 'WikiaMobile'); } else { $key = wfMemcKey(__METHOD__, md5($query . '_' . $wgRequest->getText('format') . $wgRequest->getText('nospecial', ''))); } if (strlen($query) < 3) { // enforce minimum character limit on server side $out = $wgRequest->getText('format') == 'json' ? json_encode(array('suggestions' => array(), 'redirects' => array())) : ''; } else { if (false && ($cached = $wgMemc->get($key))) { $out = $cached; } } if (isset($out)) { return linkSuggestAjaxResponse($out); } // Allow the calling-code to specify a namespace to search in (which at the moment, could be overridden by having prefixed text in the input field). // NOTE: This extension does parse titles to try to find things in other namespaces, but that actually doesn't work in practice because jQuery // Autocomplete will stop making requests after it finds 0 results. So if you start to type "Category" and there is no page beginning // with "Cate", it will not even make the call to LinkSuggest. $namespace = $wgRequest->getVal('ns'); // explode passed query by ':' to get namespace and article title $queryParts = explode(':', $query, 2); if (count($queryParts) == 2) { $query = $queryParts[1]; $namespaceName = $queryParts[0]; // try to get the index by canonical name first $namespace = MWNamespace::getCanonicalIndex(strtolower($namespaceName)); if ($namespace == null) { // if we failed, try looking through localized namespace names $namespace = array_search(ucfirst($namespaceName), $wgContLang->getNamespaces()); if (empty($namespace)) { // getting here means our "namespace" is not real and can only be part of the title $query = $namespaceName . ':' . $query; } } if ($namespace !== null && $query === '') { $out = $wgRequest->getText('format') == 'json' ? json_encode(array('suggestions' => array(), 'redirects' => array())) : ''; return linkSuggestAjaxResponse($out); } } // which namespaces to search in? if (empty($namespace)) { // search only within content namespaces (BugId:4625) - default behaviour $namespaces = $wgContentNamespaces; } else { // search only within a given namespace $namespaces = array($namespace); } $query = addslashes($query); $db = wfGetDB(DB_SLAVE, 'search'); $redirects = array(); $results = array(); $exactMatchRow = null; $queryLower = strtolower($query); $res = $db->select(array('querycache', 'page'), array('page_namespace', 'page_title', 'page_is_redirect'), array('qc_title = page_title', 'qc_namespace = page_namespace', 'page_is_redirect = 0', 'qc_type' => 'Mostlinked', "(qc_title LIKE '{$query}%' or LOWER(qc_title) LIKE '{$queryLower}%')", 'qc_namespace' => $namespaces), __METHOD__, array('ORDER BY' => 'qc_value DESC', 'LIMIT' => $wgLinkSuggestLimit)); linkSuggestFormatResults($db, $res, $query, $redirects, $results, $exactMatchRow); if (count($namespaces) > 0) { $commaJoinedNamespaces = count($namespaces) > 1 ? array_shift($namespaces) . ', ' . implode(', ', $namespaces) : $namespaces[0]; } $pageNamespaceClause = isset($commaJoinedNamespaces) ? 'page_namespace IN (' . $commaJoinedNamespaces . ') AND ' : ''; if (count($results) < $wgLinkSuggestLimit) { $sql = "SELECT page_len, page_id, page_title, rd_title, page_namespace, page_is_redirect\n\n\t\t\t\tFROM page IGNORE INDEX (`name_title`)\n\n\t\t\t\tLEFT JOIN redirect ON page_is_redirect = 1 AND page_id = rd_from\n\n\t\t\t\tWHERE {$pageNamespaceClause} (page_title LIKE '{$query}%' or LOWER(page_title) LIKE '{$queryLower}%')\n\n\t\t\t\tLIMIT " . $wgLinkSuggestLimit * 3; $res = $db->query($sql); linkSuggestFormatResults($db, $res, $query, $redirects, $results, $exactMatchRow); } if ($exactMatchRow !== null) { $row = $exactMatchRow; $titleFormatted = wfLinkSuggestFormatTitle($row->page_namespace, $row->page_title); if ($row->page_is_redirect == 0) { // remove any instances of original array's value $resultsFlipped = array_flip($results); unset($resultsFlipped[$titleFormatted]); $results = array_flip($resultsFlipped); array_unshift($results, $titleFormatted); $flippedRedirs = array_flip($redirects); if (isset($flippedRedirs[$titleFormatted])) { unset($redirects[$flippedRedirs[$titleFormatted]]); } } else { $redirTitleFormatted = wfLinkSuggestFormatTitle($row->page_namespace, $row->rd_title); // remove any instances of original array's value $resultsFlipped = array_flip($results); unset($resultsFlipped[$redirTitleFormatted]); $results = array_flip($resultsFlipped); array_unshift($results, $redirTitleFormatted); $redirects[$redirTitleFormatted] = $titleFormatted; } } $db->freeResult($res); if ($wgRequest->getText('nospecial', 0) != 1) { // bugid 29988: include special pages // (registered in SpecialPage::$mList, not in the DB like a normal page) if ($namespaces == array('-1') && strlen($query) > 0) { $specialPagesByAlpha = SpecialPageFactory::getList(); $specialPagesByAlpha = get_object_vars($specialPagesByAlpha); ksort($specialPagesByAlpha, SORT_STRING); array_walk($specialPagesByAlpha, function ($val, $key) use(&$results, $query) { if (strtolower(substr($key, 0, strlen($query))) === strtolower($query)) { $results[] = wfLinkSuggestFormatTitle('-1', $key); } }); } } $format = $wgRequest->getText('format'); if ($format == 'json') { $result_values = array_values($results); if ($isMobile) { $out = json_encode(array(array_splice($result_values, 0, 10), array_splice($redirects, -1, 1))); } else { $out = json_encode(array('query' => $wgRequest->getText('query'), 'suggestions' => $result_values, 'redirects' => $redirects)); } // legacy: LinkSuggest.js uses this } else { // Overwrite canonical title with redirect title for ($i = 0; $i < count($results); $i++) { if (isset($redirects[$results[$i]])) { $results[$i] = $redirects[$results[$i]]; } } $out = implode("\n", $results); } // 15 minutes times four (one hour, but easier to slice and dice) $wgMemc->set($key, $out, 4 * 900); wfProfileOut(__METHOD__); return linkSuggestAjaxResponse($out); }
/** * Get a namespace key by value, case insensitive. Canonical namespace * names override custom ones defined for the current language. * * @param $text String * @return mixed An integer if $text is a valid value otherwise false */ function getNsIndex($text) { $lctext = $this->lc($text); if (($ns = MWNamespace::getCanonicalIndex($lctext)) !== null) { return $ns; } $ids = $this->getNamespaceIds(); return isset($ids[$lctext]) ? $ids[$lctext] : false; }
$wgMessagesDirs['CreatePage'] = __DIR__ . '/i18n'; $wgExtensionMessagesFiles['CreatePage'] = __DIR__ . '/CreatePage.i18n.php'; $wgExtensionMessagesFiles['CreatePageAlias'] = __DIR__ . '/CreatePage.alias.php'; $wgExtensionMessagesFiles['CreatePageMagic'] = __DIR__ . '/CreatePage.magic.php'; $wgAutoloadClasses['SpecialCreatePageRedirect'] = __DIR__ . '/SpecialCreatePageRedirect.php'; $wgSpecialPages['CreatePageRedirect'] = 'SpecialCreatePageRedirect'; $wgResourceModules['ext.createPage'] = array('scripts' => 'modules/createPage.searchSuggest.js', 'dependencies' => 'mediawiki.searchSuggest', 'localBasePath' => __DIR__, 'remoteExtPath' => 'CreatePage'); $wgHooks['ParserFirstCallInit'][] = function (Parser &$parser) { $parser->setFunctionHook('createpage', function (Parser $parser, PPFrame $frame, array $args) { $html = Html::openElement('form', array('action' => SpecialPage::getTitleFor('CreatePageRedirect')->getLocalURL(), 'method' => 'post', 'style' => 'display: inline', 'class' => 'createpageform')); $html .= Html::input('pagename', array_key_exists(1, $args) ? trim($frame->expand($args[1])) : '', 'text', array('class' => 'pagenameinput')); if (array_key_exists(0, $args)) { $namespaceText = trim($frame->expand($args[0])); $attribs = array(); // Find the ID of this namespace, if there is one. $namespaceID = MWNamespace::getCanonicalIndex(strtolower($namespaceText)); if ($namespaceID != 0) { $attribs['nsid'] = $namespaceID; } $html .= Html::hidden('pagens', $namespaceText, $attribs); } $html .= ' '; $html .= Html::input('createpage', array_key_exists(2, $args) ? trim($frame->expand($args[2])) : wfMessage('cp-create')->text(), 'submit'); if (array_key_exists(3, $args)) { $html .= Html::hidden('preload', trim($frame->expand($args[3]))); } $html .= '</form>'; return $parser->insertStripItem($html); }, Parser::SFH_OBJECT_ARGS); return true; };