MediaWiki REL1_34
SpecialLinkSearch.php
Go to the documentation of this file.
1<?php
27
34 private $mungedQuery = false;
36 private $mQuery;
38 private $mNs;
40 private $mProt;
41
42 function setParams( $params ) {
43 $this->mQuery = $params['query'];
44 $this->mNs = $params['namespace'];
45 $this->mProt = $params['protocol'];
46 }
47
48 function __construct( $name = 'LinkSearch' ) {
49 parent::__construct( $name );
50
51 // Since we don't control the constructor parameters, we can't inject services that way.
52 // Instead, we initialize services in the execute() method, and allow them to be overridden
53 // using the setServices() method.
54 }
55
56 function isCacheable() {
57 return false;
58 }
59
60 public function execute( $par ) {
61 $this->setHeaders();
62 $this->outputHeader();
63
64 $out = $this->getOutput();
65 $out->allowClickjacking();
66
67 $request = $this->getRequest();
68 $target = $request->getVal( 'target', $par );
69 $namespace = $request->getIntOrNull( 'namespace' );
70
71 $protocols_list = [];
72 foreach ( $this->getConfig()->get( 'UrlProtocols' ) as $prot ) {
73 if ( $prot !== '//' ) {
74 $protocols_list[] = $prot;
75 }
76 }
77
78 $target2 = Parser::normalizeLinkUrl( $target );
79 // Get protocol, default is http://
80 $protocol = 'http://';
81 $bits = wfParseUrl( $target );
82 if ( isset( $bits['scheme'] ) && isset( $bits['delimiter'] ) ) {
83 $protocol = $bits['scheme'] . $bits['delimiter'];
84 // Make sure wfParseUrl() didn't make some well-intended correction in the
85 // protocol
86 if ( strcasecmp( $protocol, substr( $target, 0, strlen( $protocol ) ) ) === 0 ) {
87 $target2 = substr( $target, strlen( $protocol ) );
88 } else {
89 // If it did, let LinkFilter::makeLikeArray() handle this
90 $protocol = '';
91 }
92 }
93
94 $out->addWikiMsg(
95 'linksearch-text',
96 '<nowiki>' . $this->getLanguage()->commaList( $protocols_list ) . '</nowiki>',
97 count( $protocols_list )
98 );
99 $fields = [
100 'target' => [
101 'type' => 'text',
102 'name' => 'target',
103 'id' => 'target',
104 'size' => 50,
105 'label-message' => 'linksearch-pat',
106 'default' => $target,
107 'dir' => 'ltr',
108 ]
109 ];
110 if ( !$this->getConfig()->get( 'MiserMode' ) ) {
111 $fields += [
112 'namespace' => [
113 'type' => 'namespaceselect',
114 'name' => 'namespace',
115 'label-message' => 'linksearch-ns',
116 'default' => $namespace,
117 'id' => 'namespace',
118 'all' => '',
119 'cssclass' => 'namespaceselector',
120 ],
121 ];
122 }
123 $hiddenFields = [
124 'title' => $this->getPageTitle()->getPrefixedDBkey(),
125 ];
126 $htmlForm = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
127 $htmlForm->addHiddenFields( $hiddenFields );
128 $htmlForm->setSubmitTextMsg( 'linksearch-ok' );
129 $htmlForm->setWrapperLegendMsg( 'linksearch' );
130 $htmlForm->setAction( wfScript() );
131 $htmlForm->setMethod( 'get' );
132 $htmlForm->prepareForm()->displayForm( false );
133 $this->addHelpLink( 'Help:Linksearch' );
134
135 if ( $target != '' ) {
136 $this->setParams( [
137 'query' => $target2,
138 'namespace' => $namespace,
139 'protocol' => $protocol ] );
140 parent::execute( $par );
141 if ( $this->mungedQuery === false ) {
142 $out->addWikiMsg( 'linksearch-error' );
143 }
144 }
145 }
146
151 function isSyndicated() {
152 return false;
153 }
154
155 function linkParameters() {
156 $params = [];
157 $params['target'] = $this->mProt . $this->mQuery;
158 if ( $this->mNs !== null && !$this->getConfig()->get( 'MiserMode' ) ) {
159 $params['namespace'] = $this->mNs;
160 }
161
162 return $params;
163 }
164
165 public function getQueryInfo() {
167
168 if ( $this->mQuery === '*' && $this->mProt !== '' ) {
169 $this->mungedQuery = [
170 'el_index_60' . $dbr->buildLike( $this->mProt, $dbr->anyString() ),
171 ];
172 } else {
173 $this->mungedQuery = LinkFilter::getQueryConditions( $this->mQuery, [
174 'protocol' => $this->mProt,
175 'oneWildcard' => true,
176 'db' => $dbr
177 ] );
178 }
179 if ( $this->mungedQuery === false ) {
180 // Invalid query; return no results
181 return [ 'tables' => 'page', 'fields' => 'page_id', 'conds' => '0=1' ];
182 }
183
184 $orderBy = [];
185 // @phan-suppress-next-line PhanTypeMismatchDimFetch
186 if ( !isset( $this->mungedQuery['el_index_60'] ) ) {
187 $orderBy[] = 'el_index_60';
188 }
189 $orderBy[] = 'el_id';
190
191 $retval = [
192 'tables' => [ 'page', 'externallinks' ],
193 'fields' => [
194 'namespace' => 'page_namespace',
195 'title' => 'page_title',
196 'value' => 'el_index',
197 'url' => 'el_to'
198 ],
199 'conds' => array_merge(
200 [
201 'page_id = el_from',
202 ],
203 $this->mungedQuery
204 ),
205 'options' => [ 'ORDER BY' => $orderBy ]
206 ];
207
208 if ( $this->mNs !== null && !$this->getConfig()->get( 'MiserMode' ) ) {
209 $retval['conds']['page_namespace'] = $this->mNs;
210 }
211
212 return $retval;
213 }
214
221 function preprocessResults( $db, $res ) {
223 }
224
230 function formatResult( $skin, $result ) {
231 $title = new TitleValue( (int)$result->namespace, $result->title );
232 $pageLink = $this->getLinkRenderer()->makeLink( $title );
233
234 $url = $result->url;
235 $urlLink = Linker::makeExternalLink( $url, $url );
236
237 return $this->msg( 'linksearch-line' )->rawParams( $urlLink, $pageLink )->escaped();
238 }
239
245 function getOrderFields() {
246 return [];
247 }
248
249 protected function getGroupName() {
250 return 'redirects';
251 }
252
260 protected function getMaxResults() {
261 return max( parent::getMaxResults(), 60000 );
262 }
263}
wfParseUrl( $url)
parse_url() work-alike, but non-broken.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
static getQueryConditions( $filterEntry, array $options=[])
Return query conditions which will match the specified string.
static makeExternalLink( $url, $text, $escape=true, $linktype='', $attribs=[], $title=null)
Make an external link.
Definition Linker.php:848
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:36
executeLBFromResultWrapper(IResultWrapper $res, $ns=null)
Creates a new LinkBatch object, adds all pages from the passed result wrapper (MUST include title and...
Special:LinkSearch to search the external-links table.
__construct( $name='LinkSearch')
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...
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.
Basic database interface for live and lazy-loaded relation database handles.
Definition IDatabase.php:38
Result wrapper for grabbing data queried from an IDatabase object.
const DB_REPLICA
Definition defines.php:25