MediaWiki  master
ApiQueryProtectedTitles.php
Go to the documentation of this file.
1 <?php
27 
34 
36  private $commentStore;
37 
39  private $commentFormatter;
40 
47  public function __construct(
48  ApiQuery $query,
49  $moduleName,
50  CommentStore $commentStore,
51  RowCommentFormatter $commentFormatter
52  ) {
53  parent::__construct( $query, $moduleName, 'pt' );
54  $this->commentStore = $commentStore;
55  $this->commentFormatter = $commentFormatter;
56  }
57 
58  public function execute() {
59  $this->run();
60  }
61 
62  public function executeGenerator( $resultPageSet ) {
63  $this->run( $resultPageSet );
64  }
65 
70  private function run( $resultPageSet = null ) {
71  $params = $this->extractRequestParams();
72 
73  $this->addTables( 'protected_titles' );
74  $this->addFields( [ 'pt_namespace', 'pt_title', 'pt_timestamp' ] );
75 
76  $prop = array_fill_keys( $params['prop'], true );
77  $this->addFieldsIf( 'pt_user', isset( $prop['user'] ) || isset( $prop['userid'] ) );
78  $this->addFieldsIf( 'pt_expiry', isset( $prop['expiry'] ) );
79  $this->addFieldsIf( 'pt_create_perm', isset( $prop['level'] ) );
80 
81  if ( isset( $prop['comment'] ) || isset( $prop['parsedcomment'] ) ) {
82  $commentQuery = $this->commentStore->getJoin( 'pt_reason' );
83  $this->addTables( $commentQuery['tables'] );
84  $this->addFields( $commentQuery['fields'] );
85  $this->addJoinConds( $commentQuery['joins'] );
86  }
87 
88  $this->addTimestampWhereRange( 'pt_timestamp', $params['dir'], $params['start'], $params['end'] );
89  $this->addWhereFld( 'pt_namespace', $params['namespace'] );
90  $this->addWhereFld( 'pt_create_perm', $params['level'] );
91 
92  // Include in ORDER BY for uniqueness
93  $this->addWhereRange( 'pt_namespace', $params['dir'], null, null );
94  $this->addWhereRange( 'pt_title', $params['dir'], null, null );
95 
96  if ( $params['continue'] !== null ) {
97  $cont = explode( '|', $params['continue'] );
98  $this->dieContinueUsageIf( count( $cont ) != 3 );
99  $op = ( $params['dir'] === 'newer' ? '>' : '<' );
100  $db = $this->getDB();
101  $continueTimestamp = $db->addQuotes( $db->timestamp( $cont[0] ) );
102  $continueNs = (int)$cont[1];
103  $this->dieContinueUsageIf( $continueNs != $cont[1] );
104  $continueTitle = $db->addQuotes( $cont[2] );
105  $this->addWhere( "pt_timestamp $op $continueTimestamp OR " .
106  "(pt_timestamp = $continueTimestamp AND " .
107  "(pt_namespace $op $continueNs OR " .
108  "(pt_namespace = $continueNs AND " .
109  "pt_title $op= $continueTitle)))"
110  );
111  }
112 
113  if ( isset( $prop['user'] ) ) {
114  $this->addTables( 'user' );
115  $this->addFields( 'user_name' );
116  $this->addJoinConds( [ 'user' => [ 'LEFT JOIN',
117  'user_id=pt_user'
118  ] ] );
119  }
120 
121  $this->addOption( 'LIMIT', $params['limit'] + 1 );
122  $res = $this->select( __METHOD__ );
123 
124  if ( $resultPageSet === null ) {
125  $this->executeGenderCacheFromResultWrapper( $res, __METHOD__, 'pt' );
126  if ( isset( $prop['parsedcomment'] ) ) {
127  $formattedComments = $this->commentFormatter->formatItems(
128  $this->commentFormatter->rows( $res )
129  ->commentKey( 'pt_reason' )
130  ->namespaceField( 'pt_namespace' )
131  ->titleField( 'pt_title' )
132  );
133  }
134  }
135 
136  $count = 0;
137  $result = $this->getResult();
138 
139  $titles = [];
140 
141  foreach ( $res as $rowOffset => $row ) {
142  if ( ++$count > $params['limit'] ) {
143  // We've reached the one extra which shows that there are
144  // additional pages to be had. Stop here...
145  $this->setContinueEnumParameter( 'continue',
146  "$row->pt_timestamp|$row->pt_namespace|$row->pt_title"
147  );
148  break;
149  }
150 
151  $title = Title::makeTitle( $row->pt_namespace, $row->pt_title );
152  if ( $resultPageSet === null ) {
153  $vals = [];
155  if ( isset( $prop['timestamp'] ) ) {
156  $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $row->pt_timestamp );
157  }
158 
159  if ( isset( $prop['user'] ) && $row->user_name !== null ) {
160  $vals['user'] = $row->user_name;
161  }
162 
163  if ( isset( $prop['userid'] ) || /*B/C*/isset( $prop['user'] ) ) {
164  $vals['userid'] = (int)$row->pt_user;
165  }
166 
167  if ( isset( $prop['comment'] ) ) {
168  $vals['comment'] = $this->commentStore->getComment( 'pt_reason', $row )->text;
169  }
170 
171  if ( isset( $prop['parsedcomment'] ) ) {
172  // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
173  $vals['parsedcomment'] = $formattedComments[$rowOffset];
174  }
175 
176  if ( isset( $prop['expiry'] ) ) {
177  $vals['expiry'] = ApiResult::formatExpiry( $row->pt_expiry );
178  }
179 
180  if ( isset( $prop['level'] ) ) {
181  $vals['level'] = $row->pt_create_perm;
182  }
183 
184  $fit = $result->addValue( [ 'query', $this->getModuleName() ], null, $vals );
185  if ( !$fit ) {
186  $this->setContinueEnumParameter( 'continue',
187  "$row->pt_timestamp|$row->pt_namespace|$row->pt_title"
188  );
189  break;
190  }
191  } else {
192  $titles[] = $title;
193  }
194  }
195 
196  if ( $resultPageSet === null ) {
197  $result->addIndexedTagName(
198  [ 'query', $this->getModuleName() ],
199  $this->getModulePrefix()
200  );
201  } else {
202  $resultPageSet->populateFromTitles( $titles );
203  }
204  }
205 
206  public function getCacheMode( $params ) {
207  if ( $params['prop'] !== null && in_array( 'parsedcomment', $params['prop'] ) ) {
208  // formatComment() calls wfMessage() among other things
209  return 'anon-public-user-private';
210  } else {
211  return 'public';
212  }
213  }
214 
215  public function getAllowedParams() {
216  return [
217  'namespace' => [
218  ParamValidator::PARAM_ISMULTI => true,
219  ParamValidator::PARAM_TYPE => 'namespace',
220  ],
221  'level' => [
222  ParamValidator::PARAM_ISMULTI => true,
223  ParamValidator::PARAM_TYPE => array_diff(
224  $this->getConfig()->get( MainConfigNames::RestrictionLevels ), [ '' ] )
225  ],
226  'limit' => [
227  ParamValidator::PARAM_DEFAULT => 10,
228  ParamValidator::PARAM_TYPE => 'limit',
229  IntegerDef::PARAM_MIN => 1,
230  IntegerDef::PARAM_MAX => ApiBase::LIMIT_BIG1,
231  IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_BIG2
232  ],
233  'dir' => [
234  ParamValidator::PARAM_DEFAULT => 'older',
235  ParamValidator::PARAM_TYPE => [
236  'newer',
237  'older'
238  ],
239  ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
240  ],
241  'start' => [
242  ParamValidator::PARAM_TYPE => 'timestamp'
243  ],
244  'end' => [
245  ParamValidator::PARAM_TYPE => 'timestamp'
246  ],
247  'prop' => [
248  ParamValidator::PARAM_ISMULTI => true,
249  ParamValidator::PARAM_DEFAULT => 'timestamp|level',
250  ParamValidator::PARAM_TYPE => [
251  'timestamp',
252  'user',
253  'userid',
254  'comment',
255  'parsedcomment',
256  'expiry',
257  'level'
258  ],
260  ],
261  'continue' => [
262  ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
263  ],
264  ];
265  }
266 
267  protected function getExamplesMessages() {
268  return [
269  'action=query&list=protectedtitles'
270  => 'apihelp-query+protectedtitles-example-simple',
271  'action=query&generator=protectedtitles&gptnamespace=0&prop=linkshere'
272  => 'apihelp-query+protectedtitles-example-generator',
273  ];
274  }
275 
276  public function getHelpUrls() {
277  return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Protectedtitles';
278  }
279 }
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:506
dieContinueUsageIf( $condition)
Die with the 'badcontinue' error.
Definition: ApiBase.php:1650
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, this is an array mapping those values to $msg...
Definition: ApiBase.php:196
const LIMIT_BIG1
Fast query, standard limit.
Definition: ApiBase.php:221
getResult()
Get the result object.
Definition: ApiBase.php:629
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition: ApiBase.php:765
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition: ApiBase.php:163
const LIMIT_BIG2
Fast query, apihighlimits limit.
Definition: ApiBase.php:223
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:498
static addTitleInfo(&$arr, $title, $prefix='')
Add information (title and namespace) about a Title object to a result 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.
addFields( $value)
Add a set of fields to select to the internal array.
addOption( $name, $value=null)
Add an option such as LIMIT or USE INDEX.
addTables( $tables, $alias=null)
Add a set of tables to the internal array.
addTimestampWhereRange( $field, $dir, $start, $end, $sort=true)
Add a WHERE clause corresponding to a range, similar to addWhereRange, but converts $start and $end t...
getDB()
Get the Query database connection (read-only)
executeGenderCacheFromResultWrapper(IResultWrapper $res, $fname=__METHOD__, $fieldPrefix='page')
Preprocess the result set to fill the GenderCache with the necessary information before using self::a...
select( $method, $extraQuery=[], array &$hookData=null)
Execute a SELECT query based on the values in the internal arrays.
addFieldsIf( $value, $condition)
Same as addFields(), but add the fields only if a condition is met.
addJoinConds( $join_conds)
Add a set of JOIN conditions to the internal array.
addWhereFld( $field, $value)
Equivalent to addWhere( [ $field => $value ] )
addWhere( $value)
Add a set of WHERE clauses to the internal array.
setContinueEnumParameter( $paramName, $paramValue)
Overridden to set the generator param if in generator mode.
Query module to enumerate all create-protected pages.
getCacheMode( $params)
Get the cache mode for the data generated by this module.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
getHelpUrls()
Return links to more detailed help pages about the module.
executeGenerator( $resultPageSet)
Execute this module as a generator.
__construct(ApiQuery $query, $moduleName, CommentStore $commentStore, RowCommentFormatter $commentFormatter)
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
getExamplesMessages()
Returns usage examples for this module.
This is the main query class.
Definition: ApiQuery.php:41
static formatExpiry( $expiry, $infinity='infinity')
Format an expiry timestamp for API output.
Definition: ApiResult.php:1199
Handle database storage of comments such as edit summaries and log reasons.
This is basically a CommentFormatter with a CommentStore dependency, allowing it to retrieve comment ...
A class containing constants representing the names of configuration variables.
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:638
Service for formatting and validating API parameters.
Type definition for integer types.
Definition: IntegerDef.php:23