MediaWiki REL1_30
ApiContinuationManager.php
Go to the documentation of this file.
1<?php
27 private $source;
28
29 private $allModules = [];
30 private $generatedModules = [];
31
32 private $continuationData = [];
35
36 private $generatorParams = [];
37 private $generatorDone = false;
38
45 public function __construct(
46 ApiBase $module, array $allModules = [], array $generatedModules = []
47 ) {
48 $this->source = get_class( $module );
49 $request = $module->getRequest();
50
51 $this->generatedModules = $generatedModules
52 ? array_combine( $generatedModules, $generatedModules )
53 : [];
54
55 $skip = [];
56 $continue = $request->getVal( 'continue', '' );
57 if ( $continue !== '' ) {
58 $continue = explode( '||', $continue );
59 if ( count( $continue ) !== 2 ) {
60 throw ApiUsageException::newWithMessage( $module->getMain(), 'apierror-badcontinue' );
61 }
62 $this->generatorDone = ( $continue[0] === '-' );
63 $skip = explode( '|', $continue[1] );
64 if ( !$this->generatorDone ) {
65 $params = explode( '|', $continue[0] );
66 if ( $params ) {
67 $this->generatorParams = array_intersect_key(
68 $request->getValues(),
69 array_flip( $params )
70 );
71 }
72 } else {
73 // When the generator is complete, don't run any modules that
74 // depend on it.
76 }
77 }
78
79 foreach ( $allModules as $module ) {
80 $name = $module->getModuleName();
81 if ( in_array( $name, $skip, true ) ) {
82 $this->allModules[$name] = false;
83 // Prevent spurious "unused parameter" warnings
84 $module->extractRequestParams();
85 } else {
86 $this->allModules[$name] = $module;
87 }
88 }
89 }
90
95 public function getSource() {
96 return $this->source;
97 }
98
103 public function isGeneratorDone() {
105 }
106
111 public function getRunModules() {
112 return array_values( array_filter( $this->allModules ) );
113 }
114
122 public function addContinueParam( ApiBase $module, $paramName, $paramValue ) {
123 $name = $module->getModuleName();
124 if ( !isset( $this->allModules[$name] ) ) {
125 throw new UnexpectedValueException(
126 "Module '$name' called " . __METHOD__ .
127 ' but was not passed to ' . __CLASS__ . '::__construct'
128 );
129 }
130 if ( !$this->allModules[$name] ) {
131 throw new UnexpectedValueException(
132 "Module '$name' was not supposed to have been executed, but " .
133 'it was executed anyway'
134 );
135 }
136 $paramName = $module->encodeParamName( $paramName );
137 if ( is_array( $paramValue ) ) {
138 $paramValue = implode( '|', $paramValue );
139 }
140 $this->continuationData[$name][$paramName] = $paramValue;
141 }
142
154 public function addGeneratorNonContinueParam( ApiBase $module, $paramName, $paramValue ) {
155 $name = $module->getModuleName();
156 $paramName = $module->encodeParamName( $paramName );
157 if ( is_array( $paramValue ) ) {
158 $paramValue = implode( '|', $paramValue );
159 }
160 $this->generatorNonContinuationData[$name][$paramName] = $paramValue;
161 }
162
169 public function addGeneratorContinueParam( ApiBase $module, $paramName, $paramValue ) {
170 $name = $module->getModuleName();
171 $paramName = $module->encodeParamName( $paramName );
172 if ( is_array( $paramValue ) ) {
173 $paramValue = implode( '|', $paramValue );
174 }
175 $this->generatorContinuationData[$name][$paramName] = $paramValue;
176 }
177
182 public function getRawContinuation() {
183 return array_merge_recursive( $this->continuationData, $this->generatorContinuationData );
184 }
185
191 public function getRawNonContinuation() {
193 }
194
199 public function getContinuation() {
200 $data = [];
201 $batchcomplete = false;
202
203 $finishedModules = array_diff(
204 array_keys( $this->allModules ),
205 array_keys( $this->continuationData )
206 );
207
208 // First, grab the non-generator-using continuation data
209 $continuationData = array_diff_key( $this->continuationData, $this->generatedModules );
210 foreach ( $continuationData as $module => $kvp ) {
211 $data += $kvp;
212 }
213
214 // Next, handle the generator-using continuation data
215 $continuationData = array_intersect_key( $this->continuationData, $this->generatedModules );
216 if ( $continuationData ) {
217 // Some modules are unfinished: include those params, and copy
218 // the generator params.
219 foreach ( $continuationData as $module => $kvp ) {
220 $data += $kvp;
221 }
222 $generatorParams = [];
223 foreach ( $this->generatorNonContinuationData as $kvp ) {
224 $generatorParams += $kvp;
225 }
227 $data += $generatorParams;
228 $generatorKeys = implode( '|', array_keys( $generatorParams ) );
229 } elseif ( $this->generatorContinuationData ) {
230 // All the generator-using modules are complete, but the
231 // generator isn't. Continue the generator and restart the
232 // generator-using modules
233 $generatorParams = [];
234 foreach ( $this->generatorContinuationData as $kvp ) {
235 $generatorParams += $kvp;
236 }
237 $data += $generatorParams;
238 $finishedModules = array_diff( $finishedModules, $this->generatedModules );
239 $generatorKeys = implode( '|', array_keys( $generatorParams ) );
240 $batchcomplete = true;
241 } else {
242 // Generator and prop modules are all done. Mark it so.
243 $generatorKeys = '-';
244 $batchcomplete = true;
245 }
246
247 // Set 'continue' if any continuation data is set or if the generator
248 // still needs to run
249 if ( $data || $generatorKeys !== '-' ) {
250 $data['continue'] = $generatorKeys . '||' . implode( '|', $finishedModules );
251 }
252
253 return [ $data, $batchcomplete ];
254 }
255
260 public function setContinuationIntoResult( ApiResult $result ) {
261 list( $data, $batchcomplete ) = $this->getContinuation();
262 if ( $data ) {
263 $result->addValue( null, 'continue', $data,
265 }
266 if ( $batchcomplete ) {
267 $result->addValue( null, 'batchcomplete', true,
269 }
270 }
271}
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:41
encodeParamName( $paramName)
This method mangles parameter name based on the prefix supplied to the constructor.
Definition ApiBase.php:721
getMain()
Get the main module.
Definition ApiBase.php:528
extractRequestParams( $parseLimit=true)
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:740
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:512
This manages continuation state.
addGeneratorNonContinueParam(ApiBase $module, $paramName, $paramValue)
Set the non-continuation parameter for the generator module.
isGeneratorDone()
Is the generator done?
addGeneratorContinueParam(ApiBase $module, $paramName, $paramValue)
Set the continuation parameter for the generator module.
setContinuationIntoResult(ApiResult $result)
Store the continuation data into the result.
getRunModules()
Get the list of modules that should actually be run.
addContinueParam(ApiBase $module, $paramName, $paramValue)
Set the continuation parameter for a module.
getSource()
Get the class that created this manager.
getRawNonContinuation()
Fetch raw non-continuation data.
__construct(ApiBase $module, array $allModules=[], array $generatedModules=[])
getContinuation()
Fetch continuation result data.
getRawContinuation()
Fetch raw continuation data.
This class represents the result of the API operations.
Definition ApiResult.php:33
const NO_SIZE_CHECK
For addValue() and similar functions, do not check size while adding a value Don't use this unless yo...
Definition ApiResult.php:56
const ADD_ON_TOP
For addValue(), setValue() and similar functions, if the value does not exist, add it as the first el...
Definition ApiResult.php:47
static newWithMessage(ApiBase $module=null, $msg, $code=null, $data=null, $httpCode=0)
getRequest()
Get the WebRequest object.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition deferred.txt:11
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g. with the RejectParserCacheValue hook) because MediaWiki won 't do it for you. & $defaults also a ContextSource after deleting those rows but within the same transaction you ll probably need to make sure the header is varied on $request
Definition hooks.txt:2775
Allows to change the fields on the form that will be generated $name
Definition hooks.txt:302
$params