MediaWiki master
ApiQueryProtectedTitles.php
Go to the documentation of this file.
1<?php
9namespace MediaWiki\Api;
10
17use Wikimedia\Timestamp\TimestampFormat as TS;
18
25
26 public function __construct(
27 ApiQuery $query,
28 string $moduleName,
29 private readonly CommentStore $commentStore,
30 private readonly RowCommentFormatter $commentFormatter,
31 ) {
32 parent::__construct( $query, $moduleName, 'pt' );
33 }
34
35 public function execute() {
36 $this->run();
37 }
38
40 public function executeGenerator( $resultPageSet ) {
41 $this->run( $resultPageSet );
42 }
43
48 private function run( $resultPageSet = null ) {
49 $params = $this->extractRequestParams();
50
51 $this->addTables( 'protected_titles' );
52 $this->addFields( [ 'pt_namespace', 'pt_title', 'pt_timestamp' ] );
53
54 $prop = array_fill_keys( $params['prop'], true );
55 $this->addFieldsIf( 'pt_user', isset( $prop['user'] ) || isset( $prop['userid'] ) );
56 $this->addFieldsIf( 'pt_expiry', isset( $prop['expiry'] ) );
57 $this->addFieldsIf( 'pt_create_perm', isset( $prop['level'] ) );
58
59 if ( isset( $prop['comment'] ) || isset( $prop['parsedcomment'] ) ) {
60 $commentQuery = $this->commentStore->getJoin( 'pt_reason' );
61 $this->addTables( $commentQuery['tables'] );
62 $this->addFields( $commentQuery['fields'] );
63 $this->addJoinConds( $commentQuery['joins'] );
64 }
65
66 $this->addTimestampWhereRange( 'pt_timestamp', $params['dir'], $params['start'], $params['end'] );
67 $this->addWhereFld( 'pt_namespace', $params['namespace'] );
68 $this->addWhereFld( 'pt_create_perm', $params['level'] );
69
70 // Include in ORDER BY for uniqueness
71 $this->addWhereRange( 'pt_namespace', $params['dir'], null, null );
72 $this->addWhereRange( 'pt_title', $params['dir'], null, null );
73
74 if ( $params['continue'] !== null ) {
75 $cont = $this->parseContinueParamOrDie( $params['continue'], [ 'timestamp', 'int', 'string' ] );
76 $op = ( $params['dir'] === 'newer' ? '>=' : '<=' );
77 $db = $this->getDB();
78 $this->addWhere( $db->buildComparison( $op, [
79 'pt_timestamp' => $db->timestamp( $cont[0] ),
80 'pt_namespace' => $cont[1],
81 'pt_title' => $cont[2],
82 ] ) );
83 }
84
85 if ( isset( $prop['user'] ) ) {
86 $this->addTables( 'user' );
87 $this->addFields( 'user_name' );
88 $this->addJoinConds( [ 'user' => [ 'LEFT JOIN',
89 'user_id=pt_user'
90 ] ] );
91 }
92
93 $this->addOption( 'LIMIT', $params['limit'] + 1 );
94 $res = $this->select( __METHOD__ );
95
96 if ( $resultPageSet === null ) {
97 $this->executeGenderCacheFromResultWrapper( $res, __METHOD__, 'pt' );
98 if ( isset( $prop['parsedcomment'] ) ) {
99 $formattedComments = $this->commentFormatter->formatItems(
100 $this->commentFormatter->rows( $res )
101 ->commentKey( 'pt_reason' )
102 ->namespaceField( 'pt_namespace' )
103 ->titleField( 'pt_title' )
104 );
105 }
106 }
107
108 $count = 0;
109 $result = $this->getResult();
110
111 $titles = [];
112
113 foreach ( $res as $rowOffset => $row ) {
114 if ( ++$count > $params['limit'] ) {
115 // We've reached the one extra which shows that there are
116 // additional pages to be had. Stop here...
117 $this->setContinueEnumParameter( 'continue',
118 "$row->pt_timestamp|$row->pt_namespace|$row->pt_title"
119 );
120 break;
121 }
122
123 $title = Title::makeTitle( $row->pt_namespace, $row->pt_title );
124 if ( $resultPageSet === null ) {
125 $vals = [];
126 ApiQueryBase::addTitleInfo( $vals, $title );
127 if ( isset( $prop['timestamp'] ) ) {
128 $vals['timestamp'] = wfTimestamp( TS::ISO_8601, $row->pt_timestamp );
129 }
130
131 if ( isset( $prop['user'] ) && $row->user_name !== null ) {
132 $vals['user'] = $row->user_name;
133 }
134
135 if ( isset( $prop['userid'] ) || /*B/C*/isset( $prop['user'] ) ) {
136 $vals['userid'] = (int)$row->pt_user;
137 }
138
139 if ( isset( $prop['comment'] ) ) {
140 $vals['comment'] = $this->commentStore->getComment( 'pt_reason', $row )->text;
141 }
142
143 if ( isset( $prop['parsedcomment'] ) ) {
144 $vals['parsedcomment'] = $formattedComments[$rowOffset];
145 }
146
147 if ( isset( $prop['expiry'] ) ) {
148 $vals['expiry'] = ApiResult::formatExpiry( $row->pt_expiry );
149 }
150
151 if ( isset( $prop['level'] ) ) {
152 $vals['level'] = $row->pt_create_perm;
153 }
154
155 $fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $vals );
156 if ( !$fit ) {
157 $this->setContinueEnumParameter( 'continue',
158 "$row->pt_timestamp|$row->pt_namespace|$row->pt_title"
159 );
160 break;
161 }
162 } else {
163 $titles[] = $title;
164 }
165 }
166
167 if ( $resultPageSet === null ) {
168 $result->addIndexedTagName(
169 [ 'query', $this->getModuleName() ],
170 $this->getModulePrefix()
171 );
172 } else {
173 $resultPageSet->populateFromTitles( $titles );
174 }
175 }
176
178 public function getCacheMode( $params ) {
179 if ( $params['prop'] !== null && in_array( 'parsedcomment', $params['prop'] ) ) {
180 // MediaWiki\CommentFormatter\CommentFormatter::formatItems() calls wfMessage() among other things
181 return 'anon-public-user-private';
182 } else {
183 return 'public';
184 }
185 }
186
188 public function getAllowedParams() {
189 return [
190 'namespace' => [
191 ParamValidator::PARAM_ISMULTI => true,
192 ParamValidator::PARAM_TYPE => 'namespace',
193 ],
194 'level' => [
195 ParamValidator::PARAM_ISMULTI => true,
196 ParamValidator::PARAM_TYPE => array_diff(
197 $this->getConfig()->get( MainConfigNames::RestrictionLevels ), [ '' ] )
198 ],
199 'limit' => [
200 ParamValidator::PARAM_DEFAULT => 10,
201 ParamValidator::PARAM_TYPE => 'limit',
202 IntegerDef::PARAM_MIN => 1,
203 IntegerDef::PARAM_MAX => ApiBase::LIMIT_BIG1,
204 IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_BIG2
205 ],
206 'dir' => [
207 ParamValidator::PARAM_DEFAULT => 'older',
208 ParamValidator::PARAM_TYPE => [
209 'newer',
210 'older'
211 ],
212 ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
214 'newer' => 'api-help-paramvalue-direction-newer',
215 'older' => 'api-help-paramvalue-direction-older',
216 ],
217 ],
218 'start' => [
219 ParamValidator::PARAM_TYPE => 'timestamp'
220 ],
221 'end' => [
222 ParamValidator::PARAM_TYPE => 'timestamp'
223 ],
224 'prop' => [
225 ParamValidator::PARAM_ISMULTI => true,
226 ParamValidator::PARAM_DEFAULT => 'timestamp|level',
227 ParamValidator::PARAM_TYPE => [
228 'timestamp',
229 'user',
230 'userid',
231 'comment',
232 'parsedcomment',
233 'expiry',
234 'level'
235 ],
237 ],
238 'continue' => [
239 ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
240 ],
241 ];
242 }
243
245 protected function getExamplesMessages() {
246 return [
247 'action=query&list=protectedtitles'
248 => 'apihelp-query+protectedtitles-example-simple',
249 'action=query&generator=protectedtitles&gptnamespace=0&prop=linkshere'
250 => 'apihelp-query+protectedtitles-example-generator',
251 ];
252 }
253
255 public function getHelpUrls() {
256 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Protectedtitles';
257 }
258}
259
261class_alias( ApiQueryProtectedTitles::class, 'ApiQueryProtectedTitles' );
wfTimestamp( $outputtype=TS::UNIX, $ts=0)
Get a timestamp string in one of various formats.
getModulePrefix()
Get parameter prefix (usually two letters or an empty string).
Definition ApiBase.php:566
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:557
parseContinueParamOrDie(string $continue, array $types)
Parse the 'continue' parameter in the usual format and validate the types of each part,...
Definition ApiBase.php:1707
getResult()
Get the result object.
Definition ApiBase.php:696
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, or 'string' with PARAM_ISMULTI,...
Definition ApiBase.php:206
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition ApiBase.php:166
const LIMIT_BIG2
Fast query, apihighlimits limit.
Definition ApiBase.php:233
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:837
const LIMIT_BIG1
Fast query, standard limit.
Definition ApiBase.php:231
addOption( $name, $value=null)
Add an option such as LIMIT or USE INDEX.
addFieldsIf( $value, $condition)
Same as addFields(), but add the fields only if a condition is met.
static addTitleInfo(&$arr, $title, $prefix='')
Add information (title and namespace) about a Title object to a result array.
addTables( $tables, $alias=null)
Add a set of tables to the internal array.
addJoinConds( $join_conds)
Add a set of JOIN conditions to the internal array.
getDB()
Get the Query database connection (read-only).
select( $method, $extraQuery=[], ?array &$hookData=null)
Execute a SELECT query based on the values in the internal arrays.
addWhere( $value)
Add a set of WHERE clauses to the internal array.
executeGenderCacheFromResultWrapper(IResultWrapper $res, $fname=__METHOD__, $fieldPrefix='page')
Preprocess the result set to fill the GenderCache with the necessary information before using self::a...
addTimestampWhereRange( $field, $dir, $start, $end, $sort=true)
Add a WHERE clause corresponding to a range, similar to addWhereRange, but converts $start and $end t...
addWhereFld( $field, $value)
Equivalent to addWhere( [ $field => $value ] )
addFields( $value)
Add a set of fields to select to the internal array.
addWhereRange( $field, $dir, $start, $end, $sort=true)
Add a WHERE clause corresponding to a range, and an ORDER BY clause to sort in the right direction.
setContinueEnumParameter( $paramName, $paramValue)
Overridden to set the generator param if in generator mode.
Query module to enumerate all create-protected pages.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
getCacheMode( $params)
Get the cache mode for the data generated by this module.Override this in the module subclass....
getHelpUrls()
Return links to more detailed help pages about the module.1.25, returning boolean false is deprecated...
getExamplesMessages()
Returns usage examples for this module.Return value has query strings as keys, with values being eith...
__construct(ApiQuery $query, string $moduleName, private readonly CommentStore $commentStore, private readonly RowCommentFormatter $commentFormatter,)
executeGenerator( $resultPageSet)
Execute this module as a generator.
This is the main query class.
Definition ApiQuery.php:36
static formatExpiry( $expiry, $infinity='infinity')
Format an expiry timestamp for API output.
This is basically a CommentFormatter with a CommentStore dependency, allowing it to retrieve comment ...
Handle database storage of comments such as edit summaries and log reasons.
makeTitle( $linkId)
Convert a link ID to a Title.to override Title
A class containing constants representing the names of configuration variables.
const RestrictionLevels
Name constant for the RestrictionLevels setting, for use with Config::get()
Represents a title within MediaWiki.
Definition Title.php:69
Service for formatting and validating API parameters.
Type definition for integer types.