MediaWiki  master
SpecialLinkSearch.php
Go to the documentation of this file.
1 <?php
30 
37  private $mungedQuery = false;
39  private $mQuery;
41  private $mNs;
43  private $mProt;
44 
45  private function setParams( $params ) {
46  $this->mQuery = $params['query'];
47  $this->mNs = $params['namespace'];
48  $this->mProt = $params['protocol'];
49  }
50 
55  public function __construct(
58  ) {
59  parent::__construct( 'LinkSearch' );
60  $this->setDBLoadBalancer( $loadBalancer );
61  $this->setLinkBatchFactory( $linkBatchFactory );
62  }
63 
64  public function isCacheable() {
65  return false;
66  }
67 
68  public function execute( $par ) {
69  $this->setHeaders();
70  $this->outputHeader();
71 
72  $out = $this->getOutput();
73  $out->setPreventClickjacking( false );
74 
75  $request = $this->getRequest();
76  $target = $request->getVal( 'target', $par );
77  $namespace = $request->getIntOrNull( 'namespace' );
78 
79  $protocols_list = [];
80  foreach ( $this->getConfig()->get( MainConfigNames::UrlProtocols ) as $prot ) {
81  if ( $prot !== '//' ) {
82  $protocols_list[] = $prot;
83  }
84  }
85 
86  $target2 = Parser::normalizeLinkUrl( $target );
87  // Get protocol, default is http://
88  $protocol = 'http://';
89  $bits = wfParseUrl( $target );
90  if ( isset( $bits['scheme'] ) && isset( $bits['delimiter'] ) ) {
91  $protocol = $bits['scheme'] . $bits['delimiter'];
92  // Make sure wfParseUrl() didn't make some well-intended correction in the
93  // protocol
94  if ( str_starts_with( strtolower( $target ), strtolower( $protocol ) ) ) {
95  $target2 = substr( $target, strlen( $protocol ) );
96  } else {
97  // If it did, let LinkFilter::makeLikeArray() handle this
98  $protocol = '';
99  }
100  }
101 
102  $out->addWikiMsg(
103  'linksearch-text',
104  '<nowiki>' . $this->getLanguage()->commaList( $protocols_list ) . '</nowiki>',
105  count( $protocols_list )
106  );
107  $fields = [
108  'target' => [
109  'type' => 'text',
110  'name' => 'target',
111  'id' => 'target',
112  'size' => 50,
113  'label-message' => 'linksearch-pat',
114  'default' => $target,
115  'dir' => 'ltr',
116  ]
117  ];
118  if ( !$this->getConfig()->get( MainConfigNames::MiserMode ) ) {
119  $fields += [
120  'namespace' => [
121  'type' => 'namespaceselect',
122  'name' => 'namespace',
123  'label-message' => 'linksearch-ns',
124  'default' => $namespace,
125  'id' => 'namespace',
126  'all' => '',
127  'cssclass' => 'namespaceselector',
128  ],
129  ];
130  }
131  $hiddenFields = [
132  'title' => $this->getPageTitle()->getPrefixedDBkey(),
133  ];
134  $htmlForm = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
135  $htmlForm->addHiddenFields( $hiddenFields );
136  $htmlForm->setSubmitTextMsg( 'linksearch-ok' );
137  $htmlForm->setWrapperLegendMsg( 'linksearch' );
138  $htmlForm->setAction( wfScript() );
139  $htmlForm->setMethod( 'get' );
140  $htmlForm->prepareForm()->displayForm( false );
141  $this->addHelpLink( 'Help:Linksearch' );
142 
143  if ( $target != '' ) {
144  $this->setParams( [
145  'query' => $target2,
146  'namespace' => $namespace,
147  'protocol' => $protocol ] );
148  parent::execute( $par );
149  if ( $this->mungedQuery === false ) {
150  $out->addWikiMsg( 'linksearch-error' );
151  }
152  }
153  }
154 
159  public function isSyndicated() {
160  return false;
161  }
162 
163  protected function linkParameters() {
164  $params = [];
165  $params['target'] = $this->mProt . $this->mQuery;
166  if ( $this->mNs !== null && !$this->getConfig()->get( MainConfigNames::MiserMode ) ) {
167  $params['namespace'] = $this->mNs;
168  }
169 
170  return $params;
171  }
172 
173  public function getQueryInfo() {
174  $dbr = $this->getDBLoadBalancer()->getConnectionRef( ILoadBalancer::DB_REPLICA );
175 
176  $orderBy = [];
177  if ( $this->mQuery === '*' && $this->mProt !== '' ) {
178  $this->mungedQuery = [
179  'el_index_60' . $dbr->buildLike( $this->mProt, $dbr->anyString() ),
180  ];
181  } else {
182  $this->mungedQuery = LinkFilter::getQueryConditions( $this->mQuery, [
183  'protocol' => $this->mProt,
184  'oneWildcard' => true,
185  'db' => $dbr
186  ] );
187  if ( $this->mungedQuery === false ) {
188  // Invalid query; return no results
189  return [ 'tables' => 'page', 'fields' => 'page_id', 'conds' => '0=1' ];
190  }
191  $orderBy[] = 'el_index_60';
192  }
193 
194  $orderBy[] = 'el_id';
195 
196  $retval = [
197  'tables' => [ 'page', 'externallinks' ],
198  'fields' => [
199  'namespace' => 'page_namespace',
200  'title' => 'page_title',
201  'value' => 'el_index',
202  'url' => 'el_to'
203  ],
204  'conds' => array_merge(
205  [
206  'page_id = el_from',
207  ],
208  $this->mungedQuery
209  ),
210  'options' => [ 'ORDER BY' => $orderBy ]
211  ];
212 
213  if ( $this->mNs !== null && !$this->getConfig()->get( MainConfigNames::MiserMode ) ) {
214  $retval['conds']['page_namespace'] = $this->mNs;
215  }
216 
217  return $retval;
218  }
219 
226  public function preprocessResults( $db, $res ) {
228  }
229 
235  public function formatResult( $skin, $result ) {
236  $title = new TitleValue( (int)$result->namespace, $result->title );
237  $pageLink = $this->getLinkRenderer()->makeLink( $title );
238 
239  $url = $result->url;
240  $urlLink = Linker::makeExternalLink( $url, $url );
241 
242  return $this->msg( 'linksearch-line' )->rawParams( $urlLink, $pageLink )->escaped();
243  }
244 
250  protected function getOrderFields() {
251  return [];
252  }
253 
254  protected function getGroupName() {
255  return 'pages';
256  }
257 
265  protected function getMaxResults() {
266  return max( parent::getMaxResults(), 60000 );
267  }
268 }
wfParseUrl( $url)
parse_url() work-alike, but non-broken.
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
static factory( $displayFormat, $descriptor, IContextSource $context, $messagePrefix='')
Construct a HTMLForm object for given display type.
Definition: HTMLForm.php:338
static getQueryConditions( $filterEntry, array $options=[])
Return query conditions which will match the specified string.
Definition: LinkFilter.php:256
static makeExternalLink( $url, $text, $escape=true, $linktype='', $attribs=[], $title=null)
Make an external link.
Definition: Linker.php:1038
A class containing constants representing the names of configuration variables.
static normalizeLinkUrl( $url)
Replace unusual escape codes in a URL with their equivalent characters.
Definition: Parser.php:2314
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:877
setDBLoadBalancer(ILoadBalancer $loadBalancer)
Definition: QueryPage.php:895
LinkBatchFactory null $linkBatchFactory
Definition: QueryPage.php:75
setLinkBatchFactory(LinkBatchFactory $linkBatchFactory)
Definition: QueryPage.php:136
getDBLoadBalancer()
Definition: QueryPage.php:903
ILoadBalancer null $loadBalancer
Definition: QueryPage.php:72
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
__construct(ILoadBalancer $loadBalancer, LinkBatchFactory $linkBatchFactory)
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...
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:39
Database cluster connection, tracking, load balancing, and transaction manager interface.
Result wrapper for grabbing data queried from an IDatabase object.
const DB_REPLICA
Definition: defines.php:25