/**
  * @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');
         }
     }
 }