MediaWiki  master
SpecialLinkSearch.php
Go to the documentation of this file.
1 <?php
31 
38  private $mungedQuery = false;
40  private $mQuery;
42  private $mNs;
44  private $mProt;
45 
47  private $urlUtils;
48 
49  private function setParams( $params ) {
50  $this->mQuery = $params['query'];
51  $this->mNs = $params['namespace'];
52  $this->mProt = $params['protocol'];
53  }
54 
60  public function __construct(
61  ILoadBalancer $loadBalancer,
62  LinkBatchFactory $linkBatchFactory,
63  UrlUtils $urlUtils
64  ) {
65  parent::__construct( 'LinkSearch' );
66  $this->setDBLoadBalancer( $loadBalancer );
67  $this->setLinkBatchFactory( $linkBatchFactory );
68  $this->urlUtils = $urlUtils;
69  }
70 
71  public function isCacheable() {
72  return false;
73  }
74 
75  public function execute( $par ) {
76  $this->setHeaders();
77  $this->outputHeader();
78 
79  $out = $this->getOutput();
80  $out->setPreventClickjacking( false );
81 
82  $request = $this->getRequest();
83  $target = $request->getVal( 'target', $par ?? '' );
84  $namespace = $request->getIntOrNull( 'namespace' );
85 
86  $protocols_list = [];
87  foreach ( $this->getConfig()->get( MainConfigNames::UrlProtocols ) as $prot ) {
88  if ( $prot !== '//' ) {
89  $protocols_list[] = $prot;
90  }
91  }
92 
93  $target2 = Parser::normalizeLinkUrl( $target );
94  // Get protocol, default is http://
95  $protocol = 'http://';
96  $bits = $this->urlUtils->parse( $target );
97  if ( isset( $bits['scheme'] ) && isset( $bits['delimiter'] ) ) {
98  $protocol = $bits['scheme'] . $bits['delimiter'];
99  // Make sure UrlUtils::parse() didn't make some well-intended correction in the protocol
100  if ( str_starts_with( strtolower( $target ), strtolower( $protocol ) ) ) {
101  $target2 = substr( $target, strlen( $protocol ) );
102  } else {
103  // If it did, let LinkFilter::makeLikeArray() handle this
104  $protocol = '';
105  }
106  }
107 
108  $out->addWikiMsg(
109  'linksearch-text',
110  '<nowiki>' . $this->getLanguage()->commaList( $protocols_list ) . '</nowiki>',
111  count( $protocols_list )
112  );
113  $fields = [
114  'target' => [
115  'type' => 'text',
116  'name' => 'target',
117  'id' => 'target',
118  'size' => 50,
119  'label-message' => 'linksearch-pat',
120  'default' => $target,
121  'dir' => 'ltr',
122  ]
123  ];
124  if ( !$this->getConfig()->get( MainConfigNames::MiserMode ) ) {
125  $fields += [
126  'namespace' => [
127  'type' => 'namespaceselect',
128  'name' => 'namespace',
129  'label-message' => 'linksearch-ns',
130  'default' => $namespace,
131  'id' => 'namespace',
132  'all' => '',
133  'cssclass' => 'namespaceselector',
134  ],
135  ];
136  }
137  $htmlForm = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
138  $htmlForm->setSubmitTextMsg( 'linksearch-ok' );
139  $htmlForm->setWrapperLegendMsg( 'linksearch' );
140  $htmlForm->setTitle( $this->getPageTitle() );
141  $htmlForm->setMethod( 'get' );
142  $htmlForm->prepareForm()->displayForm( false );
143  $this->addHelpLink( 'Help:Linksearch' );
144 
145  if ( $target != '' ) {
146  $this->setParams( [
147  'query' => $target2,
148  'namespace' => $namespace,
149  'protocol' => $protocol ] );
150  parent::execute( $par );
151  if ( $this->mungedQuery === false ) {
152  $out->addWikiMsg( 'linksearch-error' );
153  }
154  }
155  }
156 
161  public function isSyndicated() {
162  return false;
163  }
164 
165  protected function linkParameters() {
166  $params = [];
167  $params['target'] = $this->mProt . $this->mQuery;
168  if ( $this->mNs !== null && !$this->getConfig()->get( MainConfigNames::MiserMode ) ) {
169  $params['namespace'] = $this->mNs;
170  }
171 
172  return $params;
173  }
174 
175  public function getQueryInfo() {
176  $dbr = $this->getDBLoadBalancer()->getConnectionRef( ILoadBalancer::DB_REPLICA );
177 
178  $orderBy = [];
179  if ( $this->mQuery === '*' && $this->mProt !== '' ) {
180  $this->mungedQuery = [
181  'el_index_60' . $dbr->buildLike( $this->mProt, $dbr->anyString() ),
182  ];
183  } else {
184  $this->mungedQuery = LinkFilter::getQueryConditions( $this->mQuery, [
185  'protocol' => $this->mProt,
186  'oneWildcard' => true,
187  'db' => $dbr
188  ] );
189  if ( $this->mungedQuery === false ) {
190  // Invalid query; return no results
191  return [ 'tables' => 'page', 'fields' => 'page_id', 'conds' => '0=1' ];
192  }
193  $orderBy[] = 'el_index_60';
194  }
195 
196  $orderBy[] = 'el_id';
197 
198  $retval = [
199  'tables' => [ 'page', 'externallinks' ],
200  'fields' => [
201  'namespace' => 'page_namespace',
202  'title' => 'page_title',
203  'value' => 'el_index',
204  'url' => 'el_to'
205  ],
206  'conds' => array_merge(
207  [
208  'page_id = el_from',
209  ],
210  $this->mungedQuery
211  ),
212  'options' => [ 'ORDER BY' => $orderBy ]
213  ];
214 
215  if ( $this->mNs !== null && !$this->getConfig()->get( MainConfigNames::MiserMode ) ) {
216  $retval['conds']['page_namespace'] = $this->mNs;
217  }
218 
219  return $retval;
220  }
221 
228  public function preprocessResults( $db, $res ) {
230  }
231 
237  public function formatResult( $skin, $result ) {
238  $title = new TitleValue( (int)$result->namespace, $result->title );
239  $pageLink = $this->getLinkRenderer()->makeLink( $title );
240 
241  $url = $result->url;
242  $urlLink = Linker::makeExternalLink( $url, $url );
243 
244  return $this->msg( 'linksearch-line' )->rawParams( $urlLink, $pageLink )->escaped();
245  }
246 
252  protected function getOrderFields() {
253  return [];
254  }
255 
256  protected function getGroupName() {
257  return 'pages';
258  }
259 
267  protected function getMaxResults() {
268  return max( parent::getMaxResults(), 60000 );
269  }
270 }
static factory( $displayFormat, $descriptor, IContextSource $context, $messagePrefix='')
Construct a HTMLForm object for given display type.
Definition: HTMLForm.php:349
static getQueryConditions( $filterEntry, array $options=[])
Return query conditions which will match the specified string.
Definition: LinkFilter.php:253
static makeExternalLink( $url, $text, $escape=true, $linktype='', $attribs=[], $title=null)
Make an external link.
Definition: Linker.php:1006
A class containing constants representing the names of configuration variables.
A service to expand, parse, and otherwise manipulate URLs.
Definition: UrlUtils.php:17
static normalizeLinkUrl( $url)
Replace unusual escape codes in a URL with their equivalent characters.
Definition: Parser.php:2305
This is a class for doing query pages; since they're almost all the same, we factor out some of the f...
Definition: QueryPage.php:42
executeLBFromResultWrapper(IResultWrapper $res, $ns=null)
Creates a new LinkBatch object, adds all pages from the passed result wrapper (MUST include title and...
Definition: QueryPage.php:898
setDBLoadBalancer(ILoadBalancer $loadBalancer)
Definition: QueryPage.php:916
setLinkBatchFactory(LinkBatchFactory $linkBatchFactory)
Definition: QueryPage.php:136
getDBLoadBalancer()
Definition: QueryPage.php:924
Special:LinkSearch to search the external-links table.
execute( $par)
This is the actual workhorse.
isSyndicated()
Disable RSS/Atom feeds.
getOrderFields()
Override to squash the ORDER BY.
linkParameters()
If using extra form wheely-dealies, return a set of parameters here as an associative array.
formatResult( $skin, $result)
getMaxResults()
enwiki complained about low limits on this special page
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
isCacheable()
Is the output of this query cacheable? Non-cacheable expensive pages will be disabled in miser mode a...
__construct(ILoadBalancer $loadBalancer, LinkBatchFactory $linkBatchFactory, UrlUtils $urlUtils)
preprocessResults( $db, $res)
Pre-fill the link cache.
getQueryInfo()
Subclasses return an SQL query here, formatted as an array with the following keys: tables => Table(s...
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getOutput()
Get the OutputPage being used for this instance.
getContext()
Gets the context this SpecialPage is executed in.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getConfig()
Shortcut to get main config object.
getRequest()
Get the WebRequest being used for this instance.
getPageTitle( $subpage=false)
Get a self-referential title object.
getLanguage()
Shortcut to get user's language.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Represents a page (or page fragment) title within MediaWiki.
Definition: TitleValue.php:40
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:40
Create and track the database connections and transactions for a given database cluster.
Result wrapper for grabbing data queried from an IDatabase object.
const DB_REPLICA
Definition: defines.php:26