/** * @param ApiPageSet $resultPageSet * @return void */ private function run($resultPageSet = null) { $params = $this->extractRequestParams(); $query = $params['query']; $protocol = self::getProtocolPrefix($params['protocol']); $this->addTables(['page', 'externallinks']); // must be in this order for 'USE INDEX' $this->addOption('USE INDEX', 'el_index'); $this->addWhere('page_id=el_from'); $miser_ns = []; if ($this->getConfig()->get('MiserMode')) { $miser_ns = $params['namespace']; } else { $this->addWhereFld('page_namespace', $params['namespace']); } // Normalize query to match the normalization applied for the externallinks table $query = Parser::normalizeLinkUrl($query); $whereQuery = $this->prepareUrlQuerySearchString($query, $protocol); if ($whereQuery !== null) { $this->addWhere($whereQuery); } $prop = array_flip($params['prop']); $fld_ids = isset($prop['ids']); $fld_title = isset($prop['title']); $fld_url = isset($prop['url']); if (is_null($resultPageSet)) { $this->addFields(['page_id', 'page_namespace', 'page_title']); $this->addFieldsIf('el_to', $fld_url); } else { $this->addFields($resultPageSet->getPageTableFields()); } $limit = $params['limit']; $offset = $params['offset']; $this->addOption('LIMIT', $limit + 1); if (isset($offset)) { $this->addOption('OFFSET', $offset); } $res = $this->select(__METHOD__); $result = $this->getResult(); $count = 0; foreach ($res as $row) { if (++$count > $limit) { // We've reached the one extra which shows that there are // additional pages to be had. Stop here... $this->setContinueEnumParameter('offset', $offset + $limit); break; } if (count($miser_ns) && !in_array($row->page_namespace, $miser_ns)) { continue; } if (is_null($resultPageSet)) { $vals = [ApiResult::META_TYPE => 'assoc']; if ($fld_ids) { $vals['pageid'] = intval($row->page_id); } if ($fld_title) { $title = Title::makeTitle($row->page_namespace, $row->page_title); ApiQueryBase::addTitleInfo($vals, $title); } if ($fld_url) { $to = $row->el_to; // expand protocol-relative urls if ($params['expandurl']) { $to = wfExpandUrl($to, PROTO_CANONICAL); } $vals['url'] = $to; } $fit = $result->addValue(['query', $this->getModuleName()], null, $vals); if (!$fit) { $this->setContinueEnumParameter('offset', $offset + $count - 1); break; } } else { $resultPageSet->processDbRow($row); } } if (is_null($resultPageSet)) { $result->addIndexedTagName(['query', $this->getModuleName()], $this->getModulePrefix()); } }
/** * @dataProvider provideNormalizeLinkUrl * @covers Parser::normalizeLinkUrl * @covers Parser::normalizeUrlComponent */ public function testNormalizeLinkUrl($explanation, $url, $expected) { $this->assertEquals($expected, Parser::normalizeLinkUrl($url), $explanation); }
public function execute($par) { $this->initServices(); $this->setHeaders(); $this->outputHeader(); $out = $this->getOutput(); $out->allowClickjacking(); $request = $this->getRequest(); $target = $request->getVal('target', $par); $namespace = $request->getIntOrNull('namespace'); $protocols_list = []; foreach ($this->getConfig()->get('UrlProtocols') as $prot) { if ($prot !== '//') { $protocols_list[] = $prot; } } $target2 = $target; // Get protocol, default is http:// $protocol = 'http://'; $bits = wfParseUrl($target); if (isset($bits['scheme']) && isset($bits['delimiter'])) { $protocol = $bits['scheme'] . $bits['delimiter']; // Make sure wfParseUrl() didn't make some well-intended correction in the // protocol if (strcasecmp($protocol, substr($target, 0, strlen($protocol))) === 0) { $target2 = substr($target, strlen($protocol)); } else { // If it did, let LinkFilter::makeLikeArray() handle this $protocol = ''; } } $out->addWikiMsg('linksearch-text', '<nowiki>' . $this->getLanguage()->commaList($protocols_list) . '</nowiki>', count($protocols_list)); $fields = ['target' => ['type' => 'text', 'name' => 'target', 'id' => 'target', 'size' => 50, 'label-message' => 'linksearch-pat', 'default' => $target, 'dir' => 'ltr']]; if (!$this->getConfig()->get('MiserMode')) { $fields += ['namespace' => ['type' => 'namespaceselect', 'name' => 'namespace', 'label-message' => 'linksearch-ns', 'default' => $namespace, 'id' => 'namespace', 'all' => '', 'cssclass' => 'namespaceselector']]; } $hiddenFields = ['title' => $this->getPageTitle()->getPrefixedDBkey()]; $htmlForm = HTMLForm::factory('ooui', $fields, $this->getContext()); $htmlForm->addHiddenFields($hiddenFields); $htmlForm->setSubmitTextMsg('linksearch-ok'); $htmlForm->setWrapperLegendMsg('linksearch'); $htmlForm->setAction(wfScript()); $htmlForm->setMethod('get'); $htmlForm->prepareForm()->displayForm(false); $this->addHelpLink('Help:Linksearch'); if ($target != '') { $this->setParams(['query' => Parser::normalizeLinkUrl($target2), 'namespace' => $namespace, 'protocol' => $protocol]); parent::execute($par); if ($this->mungedQuery === false) { $out->addWikiMsg('linksearch-error'); } } }