MediaWiki  1.23.14
ApiMain.php
Go to the documentation of this file.
1 <?php
41 class ApiMain extends ApiBase {
45  const API_DEFAULT_FORMAT = 'xmlfm';
46 
50  private static $Modules = array(
51  'login' => 'ApiLogin',
52  'logout' => 'ApiLogout',
53  'createaccount' => 'ApiCreateAccount',
54  'query' => 'ApiQuery',
55  'expandtemplates' => 'ApiExpandTemplates',
56  'parse' => 'ApiParse',
57  'opensearch' => 'ApiOpenSearch',
58  'feedcontributions' => 'ApiFeedContributions',
59  'feedrecentchanges' => 'ApiFeedRecentChanges',
60  'feedwatchlist' => 'ApiFeedWatchlist',
61  'help' => 'ApiHelp',
62  'paraminfo' => 'ApiParamInfo',
63  'rsd' => 'ApiRsd',
64  'compare' => 'ApiComparePages',
65  'tokens' => 'ApiTokens',
66 
67  // Write modules
68  'purge' => 'ApiPurge',
69  'setnotificationtimestamp' => 'ApiSetNotificationTimestamp',
70  'rollback' => 'ApiRollback',
71  'delete' => 'ApiDelete',
72  'undelete' => 'ApiUndelete',
73  'protect' => 'ApiProtect',
74  'block' => 'ApiBlock',
75  'unblock' => 'ApiUnblock',
76  'move' => 'ApiMove',
77  'edit' => 'ApiEditPage',
78  'upload' => 'ApiUpload',
79  'filerevert' => 'ApiFileRevert',
80  'emailuser' => 'ApiEmailUser',
81  'watch' => 'ApiWatch',
82  'patrol' => 'ApiPatrol',
83  'import' => 'ApiImport',
84  'userrights' => 'ApiUserrights',
85  'options' => 'ApiOptions',
86  'imagerotate' => 'ApiImageRotate',
87  'revisiondelete' => 'ApiRevisionDelete',
88  );
89 
93  private static $Formats = array(
94  'json' => 'ApiFormatJson',
95  'jsonfm' => 'ApiFormatJson',
96  'php' => 'ApiFormatPhp',
97  'phpfm' => 'ApiFormatPhp',
98  'wddx' => 'ApiFormatWddx',
99  'wddxfm' => 'ApiFormatWddx',
100  'xml' => 'ApiFormatXml',
101  'xmlfm' => 'ApiFormatXml',
102  'yaml' => 'ApiFormatYaml',
103  'yamlfm' => 'ApiFormatYaml',
104  'rawfm' => 'ApiFormatJson',
105  'txt' => 'ApiFormatTxt',
106  'txtfm' => 'ApiFormatTxt',
107  'dbg' => 'ApiFormatDbg',
108  'dbgfm' => 'ApiFormatDbg',
109  'dump' => 'ApiFormatDump',
110  'dumpfm' => 'ApiFormatDump',
111  'none' => 'ApiFormatNone',
112  );
113 
114  // @codingStandardsIgnoreStart String contenation on "msg" not allowed to break long line
121  private static $mRights = array(
122  'writeapi' => array(
123  'msg' => 'Use of the write API',
124  'params' => array()
125  ),
126  'apihighlimits' => array(
127  'msg' => 'Use higher limits in API queries (Slow queries: $1 results; Fast queries: $2 results). The limits for slow queries also apply to multivalue parameters.',
129  )
130  );
131  // @codingStandardsIgnoreEnd
132 
136  private $mPrinter;
137 
139  private $mAction;
140  private $mEnableWrite;
142 
143  private $mCacheMode = 'private';
144  private $mCacheControl = array();
145  private $mParamsUsed = array();
146 
148  private $lacksSameOriginSecurity = null;
149 
157  public function __construct( $context = null, $enableWrite = false ) {
158  if ( $context === null ) {
160  } elseif ( $context instanceof WebRequest ) {
161  // BC for pre-1.19
162  $request = $context;
164  }
165  // We set a derivative context so we can change stuff later
166  $this->setContext( new DerivativeContext( $context ) );
167 
168  if ( isset( $request ) ) {
169  $this->getContext()->setRequest( $request );
170  }
171 
172  $this->mInternalMode = ( $this->getRequest() instanceof FauxRequest );
173 
174  // Special handling for the main module: $parent === $this
175  parent::__construct( $this, $this->mInternalMode ? 'main_int' : 'main' );
176 
177  if ( !$this->mInternalMode ) {
178  // Impose module restrictions.
179  // If the current user cannot read,
180  // Remove all modules other than login
181  global $wgUser;
182 
183  if ( $this->getVal( 'callback' ) !== null ) {
184  // JSON callback allows cross-site reads.
185  // For safety, strip user credentials.
186  wfDebug( "API: stripping user credentials for JSON callback\n" );
187  $wgUser = new User();
188  $this->getContext()->setUser( $wgUser );
189  }
190  }
191 
192  global $wgAPIModules, $wgAPIFormatModules;
193  $this->mModuleMgr = new ApiModuleManager( $this );
194  $this->mModuleMgr->addModules( self::$Modules, 'action' );
195  $this->mModuleMgr->addModules( $wgAPIModules, 'action' );
196  $this->mModuleMgr->addModules( self::$Formats, 'format' );
197  $this->mModuleMgr->addModules( $wgAPIFormatModules, 'format' );
198 
199  $this->mResult = new ApiResult( $this );
200  $this->mEnableWrite = $enableWrite;
201 
202  $this->mSquidMaxage = -1; // flag for executeActionWithErrorHandling()
203  $this->mCommit = false;
204  }
205 
210  public function isInternalMode() {
211  return $this->mInternalMode;
212  }
213 
219  public function getResult() {
220  return $this->mResult;
221  }
222 
227  public function lacksSameOriginSecurity() {
228  if ( $this->lacksSameOriginSecurity !== null ) {
230  }
231 
232  $request = $this->getRequest();
233 
234  // JSONP mode
235  if ( $request->getVal( 'callback' ) !== null ) {
236  $this->lacksSameOriginSecurity = true;
237  return true;
238  }
239 
240  // Header to be used from XMLHTTPRequest when the request might
241  // otherwise be used for XSS.
242  if ( $request->getHeader( 'Treat-as-Untrusted' ) !== false ) {
243  $this->lacksSameOriginSecurity = true;
244  return true;
245  }
246 
247  // Allow extensions to override.
248  $this->lacksSameOriginSecurity = !Hooks::run( 'RequestHasSameOriginSecurity', array( $request ) );
250  }
251 
257  public function getModule() {
258  return $this->mModule;
259  }
260 
266  public function getPrinter() {
267  return $this->mPrinter;
268  }
269 
275  public function setCacheMaxAge( $maxage ) {
276  $this->setCacheControl( array(
277  'max-age' => $maxage,
278  's-maxage' => $maxage
279  ) );
280  }
281 
307  public function setCacheMode( $mode ) {
308  if ( !in_array( $mode, array( 'private', 'public', 'anon-public-user-private' ) ) ) {
309  wfDebug( __METHOD__ . ": unrecognised cache mode \"$mode\"\n" );
310 
311  // Ignore for forwards-compatibility
312  return;
313  }
314 
315  if ( !User::isEveryoneAllowed( 'read' ) ) {
316  // Private wiki, only private headers
317  if ( $mode !== 'private' ) {
318  wfDebug( __METHOD__ . ": ignoring request for $mode cache mode, private wiki\n" );
319 
320  return;
321  }
322  }
323 
324  wfDebug( __METHOD__ . ": setting cache mode $mode\n" );
325  $this->mCacheMode = $mode;
326  }
327 
338  public function setCacheControl( $directives ) {
339  $this->mCacheControl = $directives + $this->mCacheControl;
340  }
341 
349  public function createPrinterByName( $format ) {
350  $printer = $this->mModuleMgr->getModule( $format, 'format' );
351  if ( $printer === null ) {
352  $this->dieUsage( "Unrecognized format: {$format}", 'unknown_format' );
353  }
354 
355  return $printer;
356  }
357 
361  public function execute() {
362  $this->profileIn();
363  if ( $this->mInternalMode ) {
364  $this->executeAction();
365  } else {
367  }
368 
369  $this->profileOut();
370  }
371 
376  protected function executeActionWithErrorHandling() {
377  // Verify the CORS header before executing the action
378  if ( !$this->handleCORS() ) {
379  // handleCORS() has sent a 403, abort
380  return;
381  }
382 
383  // Exit here if the request method was OPTIONS
384  // (assume there will be a followup GET or POST)
385  if ( $this->getRequest()->getMethod() === 'OPTIONS' ) {
386  return;
387  }
388 
389  // In case an error occurs during data output,
390  // clear the output buffer and print just the error information
391  ob_start();
392 
393  $t = microtime( true );
394  try {
395  $this->executeAction();
396  } catch ( Exception $e ) {
397  $this->handleException( $e );
398  }
399 
400  // Log the request whether or not there was an error
401  $this->logRequest( microtime( true ) - $t );
402 
403  // Send cache headers after any code which might generate an error, to
404  // avoid sending public cache headers for errors.
405  $this->sendCacheHeaders();
406 
407  if ( $this->mPrinter->getIsHtml() && !$this->mPrinter->isDisabled() ) {
408  echo wfReportTime();
409  }
410 
411  ob_end_flush();
412  }
413 
420  protected function handleException( Exception $e ) {
421  // Bug 63145: Rollback any open database transactions
422  if ( !( $e instanceof UsageException ) ) {
423  // UsageExceptions are intentional, so don't rollback if that's the case
425  }
426 
427  // Allow extra cleanup and logging
428  wfRunHooks( 'ApiMain::onException', array( $this, $e ) );
429 
430  // Log it
431  if ( !( $e instanceof UsageException ) ) {
433  }
434 
435  // Handle any kind of exception by outputting properly formatted error message.
436  // If this fails, an unhandled exception should be thrown so that global error
437  // handler will process and log it.
438 
439  $errCode = $this->substituteResultWithError( $e );
440 
441  // Error results should not be cached
442  $this->setCacheMode( 'private' );
443 
444  $response = $this->getRequest()->response();
445  $headerStr = 'MediaWiki-API-Error: ' . $errCode;
446  if ( $e->getCode() === 0 ) {
447  $response->header( $headerStr );
448  } else {
449  $response->header( $headerStr, true, $e->getCode() );
450  }
451 
452  // Reset and print just the error message
453  ob_clean();
454 
455  // If the error occurred during printing, do a printer->profileOut()
456  $this->mPrinter->safeProfileOut();
457  $this->printResult( true );
458  }
459 
469  public static function handleApiBeforeMainException( Exception $e ) {
470  ob_start();
471 
472  try {
473  $main = new self( RequestContext::getMain(), false );
474  $main->handleException( $e );
475  } catch ( Exception $e2 ) {
476  // Nope, even that didn't work. Punt.
477  throw $e;
478  }
479 
480  // Log the request and reset cache headers
481  $main->logRequest( 0 );
482  $main->sendCacheHeaders();
483 
484  ob_end_flush();
485  }
486 
499  protected function handleCORS() {
500  global $wgCrossSiteAJAXdomains, $wgCrossSiteAJAXdomainExceptions;
501 
502  $originParam = $this->getParameter( 'origin' ); // defaults to null
503  if ( $originParam === null ) {
504  // No origin parameter, nothing to do
505  return true;
506  }
507 
508  $request = $this->getRequest();
509  $response = $request->response();
510  // Origin: header is a space-separated list of origins, check all of them
511  $originHeader = $request->getHeader( 'Origin' );
512  if ( $originHeader === false ) {
513  $origins = array();
514  } else {
515  $origins = explode( ' ', $originHeader );
516  }
517 
518  if ( !in_array( $originParam, $origins ) ) {
519  // origin parameter set but incorrect
520  // Send a 403 response
521  $message = HttpStatus::getMessage( 403 );
522  $response->header( "HTTP/1.1 403 $message", true, 403 );
523  $response->header( 'Cache-Control: no-cache' );
524  echo "'origin' parameter does not match Origin header\n";
525 
526  return false;
527  }
528 
529  $matchOrigin = self::matchOrigin(
530  $originParam,
531  $wgCrossSiteAJAXdomains,
532  $wgCrossSiteAJAXdomainExceptions
533  );
534 
535  if ( $matchOrigin ) {
536  $response->header( "Access-Control-Allow-Origin: $originParam" );
537  $response->header( 'Access-Control-Allow-Credentials: true' );
538  $this->getOutput()->addVaryHeader( 'Origin' );
539  }
540 
541  return true;
542  }
543 
552  protected static function matchOrigin( $value, $rules, $exceptions ) {
553  foreach ( $rules as $rule ) {
554  if ( preg_match( self::wildcardToRegex( $rule ), $value ) ) {
555  // Rule matches, check exceptions
556  foreach ( $exceptions as $exc ) {
557  if ( preg_match( self::wildcardToRegex( $exc ), $value ) ) {
558  return false;
559  }
560  }
561 
562  return true;
563  }
564  }
565 
566  return false;
567  }
568 
577  protected static function wildcardToRegex( $wildcard ) {
578  $wildcard = preg_quote( $wildcard, '/' );
579  $wildcard = str_replace(
580  array( '\*', '\?' ),
581  array( '.*?', '.' ),
582  $wildcard
583  );
584 
585  return "/^https?:\/\/$wildcard$/";
586  }
587 
588  protected function sendCacheHeaders() {
589  global $wgUseXVO, $wgVaryOnXFP;
590  $response = $this->getRequest()->response();
591  $out = $this->getOutput();
592 
593  $out->addVaryHeader( 'Treat-as-Untrusted' );
594 
595  if ( $wgVaryOnXFP ) {
596  $out->addVaryHeader( 'X-Forwarded-Proto' );
597  }
598 
599  if ( $this->mCacheMode == 'private' ) {
600  $response->header( 'Cache-Control: private' );
601 
602  return;
603  }
604 
605  if ( $this->mCacheMode == 'anon-public-user-private' ) {
606  $out->addVaryHeader( 'Cookie' );
607  $response->header( $out->getVaryHeader() );
608  if ( $wgUseXVO ) {
609  $response->header( $out->getXVO() );
610  if ( $out->haveCacheVaryCookies() ) {
611  // Logged in, mark this request private
612  $response->header( 'Cache-Control: private' );
613 
614  return;
615  }
616  // Logged out, send normal public headers below
617  } elseif ( session_id() != '' ) {
618  // Logged in or otherwise has session (e.g. anonymous users who have edited)
619  // Mark request private
620  $response->header( 'Cache-Control: private' );
621 
622  return;
623  } // else no XVO and anonymous, send public headers below
624  }
625 
626  // Send public headers
627  $response->header( $out->getVaryHeader() );
628  if ( $wgUseXVO ) {
629  $response->header( $out->getXVO() );
630  }
631 
632  // If nobody called setCacheMaxAge(), use the (s)maxage parameters
633  if ( !isset( $this->mCacheControl['s-maxage'] ) ) {
634  $this->mCacheControl['s-maxage'] = $this->getParameter( 'smaxage' );
635  }
636  if ( !isset( $this->mCacheControl['max-age'] ) ) {
637  $this->mCacheControl['max-age'] = $this->getParameter( 'maxage' );
638  }
639 
640  if ( !$this->mCacheControl['s-maxage'] && !$this->mCacheControl['max-age'] ) {
641  // Public cache not requested
642  // Sending a Vary header in this case is harmless, and protects us
643  // against conditional calls of setCacheMaxAge().
644  $response->header( 'Cache-Control: private' );
645 
646  return;
647  }
648 
649  $this->mCacheControl['public'] = true;
650 
651  // Send an Expires header
652  $maxAge = min( $this->mCacheControl['s-maxage'], $this->mCacheControl['max-age'] );
653  $expiryUnixTime = ( $maxAge == 0 ? 1 : time() + $maxAge );
654  $response->header( 'Expires: ' . wfTimestamp( TS_RFC2822, $expiryUnixTime ) );
655 
656  // Construct the Cache-Control header
657  $ccHeader = '';
658  $separator = '';
659  foreach ( $this->mCacheControl as $name => $value ) {
660  if ( is_bool( $value ) ) {
661  if ( $value ) {
662  $ccHeader .= $separator . $name;
663  $separator = ', ';
664  }
665  } else {
666  $ccHeader .= $separator . "$name=$value";
667  $separator = ', ';
668  }
669  }
670 
671  $response->header( "Cache-Control: $ccHeader" );
672  }
673 
680  protected function substituteResultWithError( $e ) {
681  global $wgShowHostnames;
682 
683  $result = $this->getResult();
684 
685  // Printer may not be initialized if the extractRequestParams() fails for the main module
686  if ( !isset( $this->mPrinter ) ) {
687  // The printer has not been created yet. Try to manually get formatter value.
688  $value = $this->getRequest()->getVal( 'format', self::API_DEFAULT_FORMAT );
689  if ( !$this->mModuleMgr->isDefined( $value, 'format' ) ) {
691  }
692 
693  $this->mPrinter = $this->createPrinterByName( $value );
694  }
695 
696  // Printer may not be able to handle errors. This is particularly
697  // likely if the module returns something for getCustomPrinter().
698  if ( !$this->mPrinter->canPrintErrors() ) {
699  $this->mPrinter->safeProfileOut();
700  $this->mPrinter = $this->createPrinterByName( self::API_DEFAULT_FORMAT );
701  }
702 
703  // Update raw mode flag for the selected printer.
704  $result->setRawMode( $this->mPrinter->getNeedsRawData() );
705 
706  if ( $e instanceof UsageException ) {
707  // User entered incorrect parameters - print usage screen
708  $errMessage = $e->getMessageArray();
709 
710  // Only print the help message when this is for the developer, not runtime
711  if ( $this->mPrinter->getWantsHelp() || $this->mAction == 'help' ) {
712  ApiResult::setContent( $errMessage, $this->makeHelpMsg() );
713  }
714  } else {
715  global $wgShowSQLErrors, $wgShowExceptionDetails;
716  // Something is seriously wrong
717  if ( ( $e instanceof DBQueryError ) && !$wgShowSQLErrors ) {
718  $info = 'Database query error';
719  } else {
720  $info = "Exception Caught: {$e->getMessage()}";
721  }
722 
723  $errMessage = array(
724  'code' => 'internal_api_error_' . get_class( $e ),
725  'info' => $info,
726  );
728  $errMessage,
729  $wgShowExceptionDetails ? "\n\n{$e->getTraceAsString()}\n\n" : ''
730  );
731  }
732 
733  // Remember all the warnings to re-add them later
734  $oldResult = $result->getData();
735  $warnings = isset( $oldResult['warnings'] ) ? $oldResult['warnings'] : null;
736 
737  $result->reset();
738  $result->disableSizeCheck();
739  // Re-add the id
740  $requestid = $this->getParameter( 'requestid' );
741  if ( !is_null( $requestid ) ) {
742  $result->addValue( null, 'requestid', $requestid );
743  }
744  if ( $wgShowHostnames ) {
745  // servedby is especially useful when debugging errors
746  $result->addValue( null, 'servedby', wfHostName() );
747  }
748  if ( $warnings !== null ) {
749  $result->addValue( null, 'warnings', $warnings );
750  }
751 
752  $result->addValue( null, 'error', $errMessage );
753 
754  return $errMessage['code'];
755  }
756 
761  protected function setupExecuteAction() {
762  global $wgShowHostnames;
763 
764  // First add the id to the top element
765  $result = $this->getResult();
766  $requestid = $this->getParameter( 'requestid' );
767  if ( !is_null( $requestid ) ) {
768  $result->addValue( null, 'requestid', $requestid );
769  }
770 
771  if ( $wgShowHostnames ) {
772  $servedby = $this->getParameter( 'servedby' );
773  if ( $servedby ) {
774  $result->addValue( null, 'servedby', wfHostName() );
775  }
776  }
777 
778  $params = $this->extractRequestParams();
779 
780  $this->mAction = $params['action'];
781 
782  if ( !is_string( $this->mAction ) ) {
783  $this->dieUsage( 'The API requires a valid action parameter', 'unknown_action' );
784  }
785 
786  return $params;
787  }
788 
793  protected function setupModule() {
794  // Instantiate the module requested by the user
795  $module = $this->mModuleMgr->getModule( $this->mAction, 'action' );
796  if ( $module === null ) {
797  $this->dieUsage( 'The API requires a valid action parameter', 'unknown_action' );
798  }
799  $moduleParams = $module->extractRequestParams();
800 
801  // Die if token required, but not provided
802  $salt = $module->getTokenSalt();
803  if ( $salt !== false ) {
804  if ( !isset( $moduleParams['token'] ) ) {
805  $this->dieUsageMsg( array( 'missingparam', 'token' ) );
806  }
807 
808  if ( !$this->getUser()->matchEditToken(
809  $moduleParams['token'],
810  $salt,
811  $this->getContext()->getRequest() )
812  ) {
813  $this->dieUsageMsg( 'sessionfailure' );
814  }
815  }
816 
817  return $module;
818  }
819 
826  protected function checkMaxLag( $module, $params ) {
827  if ( $module->shouldCheckMaxlag() && isset( $params['maxlag'] ) ) {
828  // Check for maxlag
829  global $wgShowHostnames;
830  $maxLag = $params['maxlag'];
831  list( $host, $lag ) = wfGetLB()->getMaxLag();
832  if ( $lag > $maxLag ) {
833  $response = $this->getRequest()->response();
834 
835  $response->header( 'Retry-After: ' . max( intval( $maxLag ), 5 ) );
836  $response->header( 'X-Database-Lag: ' . intval( $lag ) );
837 
838  if ( $wgShowHostnames ) {
839  $this->dieUsage( "Waiting for $host: $lag seconds lagged", 'maxlag' );
840  }
841 
842  $this->dieUsage( "Waiting for a database server: $lag seconds lagged", 'maxlag' );
843  }
844  }
845 
846  return true;
847  }
848 
853  protected function checkExecutePermissions( $module ) {
854  $user = $this->getUser();
855  if ( $module->isReadMode() && !User::isEveryoneAllowed( 'read' ) &&
856  !$user->isAllowed( 'read' )
857  ) {
858  $this->dieUsageMsg( 'readrequired' );
859  }
860  if ( $module->isWriteMode() ) {
861  if ( !$this->mEnableWrite ) {
862  $this->dieUsageMsg( 'writedisabled' );
863  }
864  if ( !$user->isAllowed( 'writeapi' ) ) {
865  $this->dieUsageMsg( 'writerequired' );
866  }
867  if ( wfReadOnly() ) {
868  $this->dieReadOnly();
869  }
870  }
871 
872  // Allow extensions to stop execution for arbitrary reasons.
873  $message = false;
874  if ( !wfRunHooks( 'ApiCheckCanExecute', array( $module, $user, &$message ) ) ) {
875  $this->dieUsageMsg( $message );
876  }
877  }
878 
883  protected function checkAsserts( $params ) {
884  if ( isset( $params['assert'] ) ) {
885  $user = $this->getUser();
886  switch ( $params['assert'] ) {
887  case 'user':
888  if ( $user->isAnon() ) {
889  $this->dieUsage( 'Assertion that the user is logged in failed', 'assertuserfailed' );
890  }
891  break;
892  case 'bot':
893  if ( !$user->isAllowed( 'bot' ) ) {
894  $this->dieUsage( 'Assertion that the user has the bot right failed', 'assertbotfailed' );
895  }
896  break;
897  }
898  }
899  }
900 
906  protected function setupExternalResponse( $module, $params ) {
907  if ( !$this->getRequest()->wasPosted() && $module->mustBePosted() ) {
908  // Module requires POST. GET request might still be allowed
909  // if $wgDebugApi is true, otherwise fail.
910  $this->dieUsageMsgOrDebug( array( 'mustbeposted', $this->mAction ) );
911  }
912 
913  // See if custom printer is used
914  $this->mPrinter = $module->getCustomPrinter();
915  if ( is_null( $this->mPrinter ) ) {
916  // Create an appropriate printer
917  $this->mPrinter = $this->createPrinterByName( $params['format'] );
918  }
919 
920  if ( $this->mPrinter->getNeedsRawData() ) {
921  $this->getResult()->setRawMode();
922  }
923  }
924 
928  protected function executeAction() {
929  $params = $this->setupExecuteAction();
930  $module = $this->setupModule();
931  $this->mModule = $module;
932 
933  $this->checkExecutePermissions( $module );
934 
935  if ( !$this->checkMaxLag( $module, $params ) ) {
936  return;
937  }
938 
939  if ( !$this->mInternalMode ) {
940  $this->setupExternalResponse( $module, $params );
941  }
942 
943  $this->checkAsserts( $params );
944 
945  // Execute
946  $module->profileIn();
947  $module->execute();
948  wfRunHooks( 'APIAfterExecute', array( &$module ) );
949  $module->profileOut();
950 
951  $this->reportUnusedParams();
952 
953  if ( !$this->mInternalMode ) {
954  //append Debug information
956 
957  // Print result data
958  $this->printResult( false );
959  }
960  }
961 
966  protected function logRequest( $time ) {
967  $request = $this->getRequest();
968  $milliseconds = $time === null ? '?' : round( $time * 1000 );
969  $s = 'API' .
970  ' ' . $request->getMethod() .
971  ' ' . wfUrlencode( str_replace( ' ', '_', $this->getUser()->getName() ) ) .
972  ' ' . $request->getIP() .
973  ' T=' . $milliseconds . 'ms';
974  foreach ( $this->getParamsUsed() as $name ) {
975  $value = $request->getVal( $name );
976  if ( $value === null ) {
977  continue;
978  }
979  $s .= ' ' . $name . '=';
980  if ( strlen( $value ) > 256 ) {
981  $encValue = $this->encodeRequestLogValue( substr( $value, 0, 256 ) );
982  $s .= $encValue . '[...]';
983  } else {
984  $s .= $this->encodeRequestLogValue( $value );
985  }
986  }
987  $s .= "\n";
988  wfDebugLog( 'api', $s, 'private' );
989  }
990 
994  protected function encodeRequestLogValue( $s ) {
995  static $table;
996  if ( !$table ) {
997  $chars = ';@$!*(),/:';
998  $numChars = strlen( $chars );
999  for ( $i = 0; $i < $numChars; $i++ ) {
1000  $table[rawurlencode( $chars[$i] )] = $chars[$i];
1001  }
1002  }
1003 
1004  return strtr( rawurlencode( $s ), $table );
1005  }
1006 
1010  protected function getParamsUsed() {
1011  return array_keys( $this->mParamsUsed );
1012  }
1013 
1017  public function getVal( $name, $default = null ) {
1018  $this->mParamsUsed[$name] = true;
1019 
1020  return $this->getRequest()->getVal( $name, $default );
1021  }
1022 
1027  public function getCheck( $name ) {
1028  $this->mParamsUsed[$name] = true;
1029 
1030  return $this->getRequest()->getCheck( $name );
1031  }
1032 
1040  public function getUpload( $name ) {
1041  $this->mParamsUsed[$name] = true;
1042 
1043  return $this->getRequest()->getUpload( $name );
1044  }
1045 
1050  protected function reportUnusedParams() {
1051  $paramsUsed = $this->getParamsUsed();
1052  $allParams = $this->getRequest()->getValueNames();
1053 
1054  if ( !$this->mInternalMode ) {
1055  // Printer has not yet executed; don't warn that its parameters are unused
1056  $printerParams = array_map(
1057  array( $this->mPrinter, 'encodeParamName' ),
1058  array_keys( $this->mPrinter->getFinalParams() ?: array() )
1059  );
1060  $unusedParams = array_diff( $allParams, $paramsUsed, $printerParams );
1061  } else {
1062  $unusedParams = array_diff( $allParams, $paramsUsed );
1063  }
1064 
1065  if ( count( $unusedParams ) ) {
1066  $s = count( $unusedParams ) > 1 ? 's' : '';
1067  $this->setWarning( "Unrecognized parameter$s: '" . implode( $unusedParams, "', '" ) . "'" );
1068  }
1069  }
1070 
1076  protected function printResult( $isError ) {
1077  global $wgDebugAPI;
1078  if ( $wgDebugAPI !== false ) {
1079  $this->setWarning( 'SECURITY WARNING: $wgDebugAPI is enabled' );
1080  }
1081 
1082  $this->getResult()->cleanUpUTF8();
1083  $printer = $this->mPrinter;
1084  $printer->profileIn();
1085 
1091  $isHelp = $isError || $this->mAction == 'help';
1092  $printer->setUnescapeAmps( $isHelp && $printer->getFormat() == 'XML' && $printer->getIsHtml() );
1093 
1094  $printer->initPrinter( $isHelp );
1095 
1096  $printer->execute();
1097  $printer->closePrinter();
1098  $printer->profileOut();
1099  }
1100 
1104  public function isReadMode() {
1105  return false;
1106  }
1107 
1113  public function getAllowedParams() {
1114  return array(
1115  'format' => array(
1117  ApiBase::PARAM_TYPE => $this->mModuleMgr->getNames( 'format' )
1118  ),
1119  'action' => array(
1120  ApiBase::PARAM_DFLT => 'help',
1121  ApiBase::PARAM_TYPE => $this->mModuleMgr->getNames( 'action' )
1122  ),
1123  'maxlag' => array(
1124  ApiBase::PARAM_TYPE => 'integer'
1125  ),
1126  'smaxage' => array(
1127  ApiBase::PARAM_TYPE => 'integer',
1128  ApiBase::PARAM_DFLT => 0
1129  ),
1130  'maxage' => array(
1131  ApiBase::PARAM_TYPE => 'integer',
1132  ApiBase::PARAM_DFLT => 0
1133  ),
1134  'assert' => array(
1135  ApiBase::PARAM_TYPE => array( 'user', 'bot' )
1136  ),
1137  'requestid' => null,
1138  'servedby' => false,
1139  'origin' => null,
1140  );
1141  }
1142 
1148  public function getParamDescription() {
1149  return array(
1150  'format' => 'The format of the output',
1151  'action' => 'What action you would like to perform. See below for module help',
1152  'maxlag' => array(
1153  'Maximum lag can be used when MediaWiki is installed on a database replicated cluster.',
1154  'To save actions causing any more site replication lag, this parameter can make the client',
1155  'wait until the replication lag is less than the specified value.',
1156  'In case of a replag error, error code "maxlag" is returned, with the message like',
1157  '"Waiting for $host: $lag seconds lagged\n".',
1158  'See https://www.mediawiki.org/wiki/Manual:Maxlag_parameter for more information',
1159  ),
1160  'smaxage' => 'Set the s-maxage header to this many seconds. Errors are never cached',
1161  'maxage' => 'Set the max-age header to this many seconds. Errors are never cached',
1162  'assert' => 'Verify the user is logged in if set to "user", or has the bot userright if "bot"',
1163  'requestid' => 'Request ID to distinguish requests. This will just be output back to you',
1164  'servedby' => 'Include the hostname that served the request in the ' .
1165  'results. Unconditionally shown on error',
1166  'origin' => array(
1167  'When accessing the API using a cross-domain AJAX request (CORS), set this to the',
1168  'originating domain. This must be included in any pre-flight request, and',
1169  'therefore must be part of the request URI (not the POST body). This must match',
1170  'one of the origins in the Origin: header exactly, so it has to be set to ',
1171  'something like http://en.wikipedia.org or https://meta.wikimedia.org . If this',
1172  'parameter does not match the Origin: header, a 403 response will be returned. If',
1173  'this parameter matches the Origin: header and the origin is whitelisted, an',
1174  'Access-Control-Allow-Origin header will be set.',
1175  ),
1176  );
1177  }
1178 
1184  public function getDescription() {
1185  return array(
1186  '',
1187  '',
1188  '**********************************************************************************************',
1189  '** **',
1190  '** This is an auto-generated MediaWiki API documentation page **',
1191  '** **',
1192  '** Documentation and Examples: **',
1193  '** https://www.mediawiki.org/wiki/API **',
1194  '** **',
1195  '**********************************************************************************************',
1196  '',
1197  'Status: All features shown on this page should be working, but the API',
1198  ' is still in active development, and may change at any time.',
1199  ' Make sure to monitor our mailing list for any updates.',
1200  '',
1201  'Erroneous requests: When erroneous requests are sent to the API, a HTTP header will be sent',
1202  ' with the key "MediaWiki-API-Error" and then both the value of the',
1203  ' header and the error code sent back will be set to the same value.',
1204  '',
1205  ' In the case of an invalid action being passed, these will have a value',
1206  ' of "unknown_action".',
1207  '',
1208  ' For more information see https://www.mediawiki.org' .
1209  '/wiki/API:Errors_and_warnings',
1210  '',
1211  'Documentation: https://www.mediawiki.org/wiki/API:Main_page',
1212  'FAQ https://www.mediawiki.org/wiki/API:FAQ',
1213  'Mailing list: https://lists.wikimedia.org/mailman/listinfo/mediawiki-api',
1214  'Api Announcements: https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce',
1215  'Bugs & Requests: https://bugzilla.wikimedia.org/buglist.cgi?component=API&' .
1216  'bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=bugs.delta_ts',
1217  '',
1218  '',
1219  '',
1220  '',
1221  '',
1222  );
1223  }
1224 
1228  public function getPossibleErrors() {
1229  return array_merge( parent::getPossibleErrors(), array(
1230  array( 'readonlytext' ),
1231  array( 'code' => 'unknown_format', 'info' => 'Unrecognized format: format' ),
1232  array( 'code' => 'unknown_action', 'info' => 'The API requires a valid action parameter' ),
1233  array( 'code' => 'maxlag', 'info' => 'Waiting for host: x seconds lagged' ),
1234  array( 'code' => 'maxlag', 'info' => 'Waiting for a database server: x seconds lagged' ),
1235  array( 'code' => 'assertuserfailed', 'info' => 'Assertion that the user is logged in failed' ),
1236  array(
1237  'code' => 'assertbotfailed',
1238  'info' => 'Assertion that the user has the bot right failed'
1239  ),
1240  ) );
1241  }
1242 
1247  protected function getCredits() {
1248  return array(
1249  'API developers:',
1250  ' Roan Kattouw (lead developer Sep 2007-2009)',
1251  ' Victor Vasiliev',
1252  ' Bryan Tong Minh',
1253  ' Sam Reed',
1254  ' Yuri Astrakhan (creator, lead developer Sep 2006-Sep 2007, 2012-present)',
1255  '',
1256  'Please send your comments, suggestions and questions to mediawiki-api@lists.wikimedia.org',
1257  'or file a bug report at https://bugzilla.wikimedia.org/'
1258  );
1259  }
1260 
1266  public function setHelp( $help = true ) {
1267  $this->mPrinter->setHelp( $help );
1268  }
1269 
1275  public function makeHelpMsg() {
1276  global $wgMemc, $wgAPICacheHelpTimeout;
1277  $this->setHelp();
1278  // Get help text from cache if present
1279  $key = wfMemcKey( 'apihelp', $this->getModuleName(),
1280  str_replace( ' ', '_', SpecialVersion::getVersion( 'nodb' ) ) );
1281  if ( $wgAPICacheHelpTimeout > 0 ) {
1282  $cached = $wgMemc->get( $key );
1283  if ( $cached ) {
1284  return $cached;
1285  }
1286  }
1287  $retval = $this->reallyMakeHelpMsg();
1288  if ( $wgAPICacheHelpTimeout > 0 ) {
1289  $wgMemc->set( $key, $retval, $wgAPICacheHelpTimeout );
1290  }
1291 
1292  return $retval;
1293  }
1294 
1298  public function reallyMakeHelpMsg() {
1299  $this->setHelp();
1300 
1301  // Use parent to make default message for the main module
1302  $msg = parent::makeHelpMsg();
1303 
1304  $astriks = str_repeat( '*** ', 14 );
1305  $msg .= "\n\n$astriks Modules $astriks\n\n";
1306 
1307  foreach ( $this->mModuleMgr->getNames( 'action' ) as $name ) {
1308  $module = $this->mModuleMgr->getModule( $name );
1309  $msg .= self::makeHelpMsgHeader( $module, 'action' );
1310 
1311  $msg2 = $module->makeHelpMsg();
1312  if ( $msg2 !== false ) {
1313  $msg .= $msg2;
1314  }
1315  $msg .= "\n";
1316  }
1317 
1318  $msg .= "\n$astriks Permissions $astriks\n\n";
1319  foreach ( self::$mRights as $right => $rightMsg ) {
1321  $msg .= "* " . $right . " *\n " . wfMsgReplaceArgs( $rightMsg['msg'], $rightMsg['params'] ) .
1322  "\nGranted to:\n " . str_replace( '*', 'all', implode( ', ', $groups ) ) . "\n\n";
1323  }
1324 
1325  $msg .= "\n$astriks Formats $astriks\n\n";
1326  foreach ( $this->mModuleMgr->getNames( 'format' ) as $name ) {
1327  $module = $this->mModuleMgr->getModule( $name );
1328  $msg .= self::makeHelpMsgHeader( $module, 'format' );
1329  $msg2 = $module->makeHelpMsg();
1330  if ( $msg2 !== false ) {
1331  $msg .= $msg2;
1332  }
1333  $msg .= "\n";
1334  }
1335 
1336  $msg .= "\n*** Credits: ***\n " . implode( "\n ", $this->getCredits() ) . "\n";
1337 
1338  return $msg;
1339  }
1340 
1347  public static function makeHelpMsgHeader( $module, $paramName ) {
1348  $modulePrefix = $module->getModulePrefix();
1349  if ( strval( $modulePrefix ) !== '' ) {
1350  $modulePrefix = "($modulePrefix) ";
1351  }
1352 
1353  return "* $paramName={$module->getModuleName()} $modulePrefix*";
1354  }
1355 
1356  private $mCanApiHighLimits = null;
1357 
1362  public function canApiHighLimits() {
1363  if ( !isset( $this->mCanApiHighLimits ) ) {
1364  $this->mCanApiHighLimits = $this->getUser()->isAllowed( 'apihighlimits' );
1365  }
1366 
1367  return $this->mCanApiHighLimits;
1368  }
1369 
1375  public function getShowVersions() {
1376  wfDeprecated( __METHOD__, '1.21' );
1377 
1378  return false;
1379  }
1380 
1385  public function getModuleManager() {
1386  return $this->mModuleMgr;
1387  }
1388 
1398  protected function addModule( $name, $class ) {
1399  $this->getModuleManager()->addModule( $name, 'action', $class );
1400  }
1401 
1410  protected function addFormat( $name, $class ) {
1411  $this->getModuleManager()->addModule( $name, 'format', $class );
1412  }
1413 
1419  function getModules() {
1420  return $this->getModuleManager()->getNamesWithClasses( 'action' );
1421  }
1422 
1430  public function getFormats() {
1431  return $this->getModuleManager()->getNamesWithClasses( 'format' );
1432  }
1433 }
1434 
1441 class UsageException extends MWException {
1442 
1443  private $mCodestr;
1444 
1448  private $mExtraData;
1449 
1456  public function __construct( $message, $codestr, $code = 0, $extradata = null ) {
1457  parent::__construct( $message, $code );
1458  $this->mCodestr = $codestr;
1459  $this->mExtraData = $extradata;
1460  }
1461 
1465  public function getCodeString() {
1466  return $this->mCodestr;
1467  }
1468 
1472  public function getMessageArray() {
1473  $result = array(
1474  'code' => $this->mCodestr,
1475  'info' => $this->getMessage()
1476  );
1477  if ( is_array( $this->mExtraData ) ) {
1478  $result = array_merge( $result, $this->mExtraData );
1479  }
1480 
1481  return $result;
1482  }
1483 
1487  public function __toString() {
1488  return "{$this->getCodeString()}: {$this->getMessage()}";
1489  }
1490 }
ApiMain\getDescription
getDescription()
See ApiBase for description.
Definition: ApiMain.php:1182
ApiBase\dieUsageMsgOrDebug
dieUsageMsgOrDebug( $error)
Will only set a warning instead of failing if the global $wgDebugAPI is set to true.
Definition: ApiBase.php:1969
ApiMain\executeActionWithErrorHandling
executeActionWithErrorHandling()
Execute an action, and in case of an error, erase whatever partial results have been accumulated,...
Definition: ApiMain.php:374
ApiMain
This is the main API class, used for both external and internal processing.
Definition: ApiMain.php:41
ContextSource\$context
IContextSource $context
Definition: ContextSource.php:33
$wgUser
$wgUser
Definition: Setup.php:572
$result
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message. Please note the header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item. $reader:XMLReader object $logInfo:Array of information Return false to stop further processing of the tag 'ImportHandlePageXMLTag':When parsing a XML tag in a page. $reader:XMLReader object $pageInfo:Array of information Return false to stop further processing of the tag 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision. $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information Return false to stop further processing of the tag 'ImportHandleToplevelXMLTag':When parsing a top level XML tag. $reader:XMLReader object Return false to stop further processing of the tag 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload. $reader:XMLReader object $revisionInfo:Array of information Return false to stop further processing of the tag 'InfoAction':When building information to display on the action=info page. $context:IContextSource object & $pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect. $title:Title object for the current page $request:WebRequest $ignoreRedirect:boolean to skip redirect check $target:Title/string of redirect target $article:Article object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not. Return true without providing an interwiki to continue interwiki search. $prefix:interwiki prefix we are looking for. & $iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InternalParseBeforeSanitize':during Parser 's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings. Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InternalParseBeforeLinks':during Parser 's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InvalidateEmailComplete':Called after a user 's email has been invalidated successfully. $user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification. Callee may modify $url and $query, URL will be constructed as $url . $query & $url:URL to index.php & $query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) $article:article(object) being checked 'IsTrustedProxy':Override the result of wfIsTrustedProxy() $ip:IP being check $result:Change this value to override the result of wfIsTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from & $allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of User::isValidEmailAddr(), for instance to return false if the domain name doesn 't match your organization. $addr:The e-mail address entered by the user & $result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user & $result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we 're looking for a messages file for & $file:The messages file path, you can override this to change the location. 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces. Do not use this hook to add namespaces. Use CanonicalNamespaces for that. & $namespaces:Array of namespaces indexed by their numbers 'LanguageGetMagic':DEPRECATED, use $magicWords in a file listed in $wgExtensionMessagesFiles instead. Use this to define synonyms of magic words depending of the language $magicExtensions:associative array of magic words synonyms $lang:language code(string) 'LanguageGetSpecialPageAliases':DEPRECATED, use $specialPageAliases in a file listed in $wgExtensionMessagesFiles instead. Use to define aliases of special pages names depending of the language $specialPageAliases:associative array of magic words synonyms $lang:language code(string) 'LanguageGetTranslatedLanguageNames':Provide translated language names. & $names:array of language code=> language name $code language of the preferred translations 'LanguageLinks':Manipulate a page 's language links. This is called in various places to allow extensions to define the effective language links for a page. $title:The page 's Title. & $links:Associative array mapping language codes to prefixed links of the form "language:title". & $linkFlags:Associative array mapping prefixed links to arrays of flags. Currently unused, but planned to provide support for marking individual language links in the UI, e.g. for featured articles. 'LinkBegin':Used when generating internal and interwiki links in Linker::link(), before processing starts. Return false to skip default processing and return $ret. See documentation for Linker::link() for details on the expected meanings of parameters. $skin:the Skin object $target:the Title that the link is pointing to & $html:the contents that the< a > tag should have(raw HTML) $result
Definition: hooks.txt:1528
FauxRequest
WebRequest clone which takes values from a provided array.
Definition: WebRequest.php:1275
ContextSource\getContext
getContext()
Get the RequestContext object.
Definition: ContextSource.php:40
ApiMain\getCredits
getCredits()
Returns an array of strings with credits for the API.
Definition: ApiMain.php:1245
ApiMain\sendCacheHeaders
sendCacheHeaders()
Definition: ApiMain.php:586
$request
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled also a ContextSource error or success you ll probably need to make sure the header is varied on WebRequest $request
Definition: hooks.txt:1961
ApiMain\$mAction
$mAction
Definition: ApiMain.php:138
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
ApiMain\getModules
getModules()
Get the array mapping module names to class names.
Definition: ApiMain.php:1417
ApiMain\$mSquidMaxage
$mSquidMaxage
Definition: ApiMain.php:140
$response
$response
Definition: opensearch_desc.php:32
ApiMain\getParamsUsed
getParamsUsed()
Get the request parameters used in the course of the preceding execute() request.
Definition: ApiMain.php:1008
ApiResult\setContent
static setContent(&$arr, $value, $subElemName=null)
Adds a content element to an array.
Definition: ApiResult.php:201
ApiMain\getVal
getVal( $name, $default=null)
Get a request value, and register the fact that it was used, for logging.
Definition: ApiMain.php:1015
$wgMemc
globals will be eliminated from MediaWiki replaced by an application object which would be passed to constructors Whether that would be an convenient solution remains to be but certainly PHP makes such object oriented programming models easier than they were in previous versions For the time being MediaWiki programmers will have to work in an environment with some global context At the time of globals were initialised on startup by MediaWiki of these were configuration which are documented in DefaultSettings php There is no comprehensive documentation for the remaining however some of the most important ones are listed below They are typically initialised either in index php or in Setup php For a description of the see design txt $wgTitle Title object created from the request URL $wgOut OutputPage object for HTTP response $wgUser User object for the user associated with the current request $wgLang Language object selected by user preferences $wgContLang Language object associated with the wiki being viewed $wgParser Parser object Parser extensions register their hooks here $wgRequest WebRequest to get request data $wgMemc
Definition: globals.txt:25
wfGetLB
wfGetLB( $wiki=false)
Get a load balancer object.
Definition: GlobalFunctions.php:3724
ApiBase\dieUsageMsg
dieUsageMsg( $error)
Output the error message related to a certain array.
Definition: ApiBase.php:1953
ApiMain\$Modules
static $Modules
List of available modules: action name => module class.
Definition: ApiMain.php:50
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:2530
ApiBase\PARAM_TYPE
const PARAM_TYPE
Definition: ApiBase.php:50
ApiFormatBase
This is the abstract base class for API formatters.
Definition: ApiFormatBase.php:32
wfDebugLog
wfDebugLog( $logGroup, $text, $dest='all')
Send a line to a supplementary debug log file, if configured, or main debug log if not.
Definition: GlobalFunctions.php:1087
wfUrlencode
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
Definition: GlobalFunctions.php:377
ApiMain\isReadMode
isReadMode()
Definition: ApiMain.php:1102
ApiMain\handleCORS
handleCORS()
Check the &origin= query parameter against the Origin: HTTP header and respond appropriately.
Definition: ApiMain.php:497
$time
see documentation in includes Linker php for Linker::makeImageLink & $time
Definition: hooks.txt:1358
ApiMain\handleApiBeforeMainException
static handleApiBeforeMainException(Exception $e)
Handle an exception from the ApiBeforeMain hook.
Definition: ApiMain.php:467
$right
return false if a UserGetRights hook might remove the named right $right
Definition: hooks.txt:2809
ApiMain\getShowVersions
getShowVersions()
Check whether the user wants us to show version information in the API help.
Definition: ApiMain.php:1373
$params
$params
Definition: styleTest.css.php:40
ApiMain\lacksSameOriginSecurity
lacksSameOriginSecurity()
Get the security flag for the current request.
Definition: ApiMain.php:225
UsageException\getMessageArray
getMessageArray()
Definition: ApiMain.php:1469
wfReadOnly
wfReadOnly()
Check whether the wiki is in read-only mode.
Definition: GlobalFunctions.php:1360
wfMsgReplaceArgs
wfMsgReplaceArgs( $message, $args)
Replace message parameter keys on the given formatted output.
Definition: GlobalFunctions.php:1637
$s
$s
Definition: mergeMessageFileList.php:156
ContextSource\getRequest
getRequest()
Get the WebRequest object.
Definition: ContextSource.php:77
ApiMain\encodeRequestLogValue
encodeRequestLogValue( $s)
Encode a value in a format suitable for a space-separated log line.
Definition: ApiMain.php:992
ContextSource\getUser
getUser()
Get the User object.
Definition: ContextSource.php:132
UsageException\$mExtraData
null array $mExtraData
Definition: ApiMain.php:1445
ApiMain\makeHelpMsg
makeHelpMsg()
Override the parent to generate help messages for all available modules.
Definition: ApiMain.php:1273
ApiMain\matchOrigin
static matchOrigin( $value, $rules, $exceptions)
Attempt to match an Origin header against a set of rules and a set of exceptions.
Definition: ApiMain.php:550
ApiMain\$mRights
static $mRights
List of user roles that are specifically relevant to the API.
Definition: ApiMain.php:121
ApiBase
This abstract class implements many basic API functions, and is the base of all API classes.
Definition: ApiBase.php:42
ApiMain\getModule
getModule()
Get the API module object.
Definition: ApiMain.php:255
ApiBase\profileOut
profileOut()
End module profiling.
Definition: ApiBase.php:2237
DerivativeContext
An IContextSource implementation which will inherit context from another source but allow individual ...
Definition: DerivativeContext.php:32
MWException
MediaWiki exception.
Definition: MWException.php:26
wfMemcKey
wfMemcKey()
Get a cache key.
Definition: GlobalFunctions.php:3635
$out
$out
Definition: UtfNormalGenerate.php:167
ApiMain\getParamDescription
getParamDescription()
See ApiBase for description.
Definition: ApiMain.php:1146
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
Definition: GlobalFunctions.php:1174
DBQueryError
Definition: DatabaseError.php:306
ApiMain\setupExecuteAction
setupExecuteAction()
Set up for the execution.
Definition: ApiMain.php:759
ApiResult
This class represents the result of the API operations.
Definition: ApiResult.php:44
ApiMain\$mResult
$mResult
Definition: ApiMain.php:137
UsageException
This exception will be thrown when dieUsage is called to stop module execution.
Definition: ApiMain.php:1439
ApiMain\addFormat
addFormat( $name, $class)
Add or overwrite an output format for this ApiMain.
Definition: ApiMain.php:1408
ApiMain\$lacksSameOriginSecurity
bool null $lacksSameOriginSecurity
Cached return value from self::lacksSameOriginSecurity() *.
Definition: ApiMain.php:146
ContextSource\getOutput
getOutput()
Get the OutputPage object.
Definition: ContextSource.php:122
ApiMain\getResult
getResult()
Get the ApiResult object associated with current request.
Definition: ApiMain.php:217
UsageException\__toString
__toString()
Definition: ApiMain.php:1484
wfRunHooks
wfRunHooks( $event, array $args=array(), $deprecatedVersion=null)
Call hook functions defined in $wgHooks.
Definition: GlobalFunctions.php:4066
ApiMain\checkMaxLag
checkMaxLag( $module, $params)
Check the max lag if necessary.
Definition: ApiMain.php:824
ApiMain\setCacheControl
setCacheControl( $directives)
Set directives (key/value pairs) for the Cache-Control header.
Definition: ApiMain.php:336
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
ApiMain\getAllowedParams
getAllowedParams()
See ApiBase for description.
Definition: ApiMain.php:1111
ApiMain\setupExternalResponse
setupExternalResponse( $module, $params)
Check POST for external response and setup result printer.
Definition: ApiMain.php:904
ApiMain\createPrinterByName
createPrinterByName( $format)
Create an instance of an output formatter by its name.
Definition: ApiMain.php:347
ApiMain\getModuleManager
getModuleManager()
Overrides to return this instance's module manager.
Definition: ApiMain.php:1383
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
ApiMain\$mCanApiHighLimits
$mCanApiHighLimits
Definition: ApiMain.php:1354
ContextSource\setContext
setContext(IContextSource $context)
Set the IContextSource object.
Definition: ContextSource.php:57
ApiMain\canApiHighLimits
canApiHighLimits()
Check whether the current user is allowed to use high limits.
Definition: ApiMain.php:1360
list
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
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:188
ApiMain\$mPrinter
ApiFormatBase $mPrinter
Definition: ApiMain.php:135
ApiMain\$mModule
$mModule
Definition: ApiMain.php:140
ApiModuleManager
This class holds a list of modules and handles instantiation.
Definition: ApiModuleManager.php:34
wfDebug
wfDebug( $text, $dest='all')
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:980
ApiMain\checkAsserts
checkAsserts( $params)
Check asserts of the user's rights.
Definition: ApiMain.php:881
ApiBase\extractRequestParams
extractRequestParams( $parseLimit=true)
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition: ApiBase.php:707
ApiMain\$mCacheMode
$mCacheMode
Definition: ApiMain.php:142
MWDebug\appendDebugInfoToApiResult
static appendDebugInfoToApiResult(IContextSource $context, ApiResult $result)
Append the debug info to given ApiResult.
Definition: Debug.php:491
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:336
UsageException\$mCodestr
$mCodestr
Definition: ApiMain.php:1441
ApiMain\$mInternalMode
$mInternalMode
Definition: ApiMain.php:140
$value
$value
Definition: styleTest.css.php:45
ApiMain\wildcardToRegex
static wildcardToRegex( $wildcard)
Helper function to convert wildcard string into a regex '*' => '.
Definition: ApiMain.php:575
ApiMain\checkExecutePermissions
checkExecutePermissions( $module)
Check for sufficient permissions to execute.
Definition: ApiMain.php:851
ApiMain\reallyMakeHelpMsg
reallyMakeHelpMsg()
Definition: ApiMain.php:1296
ApiBase\LIMIT_SML2
const LIMIT_SML2
Definition: ApiBase.php:81
ApiBase\dieUsage
dieUsage( $description, $errorCode, $httpRespCode=0, $extradata=null)
Throw a UsageException, which will (if uncaught) call the main module's error handler and die with an...
Definition: ApiBase.php:1383
ApiBase\dieReadOnly
dieReadOnly()
Helper function for readonly errors.
Definition: ApiBase.php:1943
ApiMain\__construct
__construct( $context=null, $enableWrite=false)
Constructs an instance of ApiMain that utilizes the module and format specified by $request.
Definition: ApiMain.php:155
ApiMain\reportUnusedParams
reportUnusedParams()
Report unused parameters, so the client gets a hint in case it gave us parameters we don't know,...
Definition: ApiMain.php:1048
ApiMain\execute
execute()
Execute api request.
Definition: ApiMain.php:359
ApiMain\logRequest
logRequest( $time)
Log the preceding request.
Definition: ApiMain.php:964
ApiMain\$Formats
static $Formats
List of available formats: format name => format class.
Definition: ApiMain.php:93
ApiMain\substituteResultWithError
substituteResultWithError( $e)
Replace the result data with the information about an exception.
Definition: ApiMain.php:678
RequestContext\getMain
static getMain()
Static methods.
Definition: RequestContext.php:420
HttpStatus\getMessage
static getMessage( $code)
Get the message associated with HTTP response code $code.
Definition: HttpStatus.php:37
$exceptions
$exceptions
Definition: Utf8Test.php:72
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:237
Hooks\run
static run( $event, array $args=array(), $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:136
ApiMain\getCheck
getCheck( $name)
Get a boolean request value, and register the fact that the parameter was used, for logging.
Definition: ApiMain.php:1025
UsageException\getCodeString
getCodeString()
Definition: ApiMain.php:1462
wfReportTime
wfReportTime()
Returns a script tag that stores the amount of time it took MediaWiki to handle the request in millis...
Definition: GlobalFunctions.php:1873
ApiBase\profileIn
profileIn()
Start module profiling.
Definition: ApiBase.php:2226
WebRequest
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form,...
Definition: WebRequest.php:38
ApiMain\makeHelpMsgHeader
static makeHelpMsgHeader( $module, $paramName)
Definition: ApiMain.php:1345
ApiMain\$mEnableWrite
$mEnableWrite
Definition: ApiMain.php:139
ApiBase\setWarning
setWarning( $warning)
Set warning section for this module.
Definition: ApiBase.php:245
User\isEveryoneAllowed
static isEveryoneAllowed( $right)
Check if all users have the given permission.
Definition: User.php:4163
UsageException\__construct
__construct( $message, $codestr, $code=0, $extradata=null)
Definition: ApiMain.php:1453
ApiBase\LIMIT_BIG2
const LIMIT_BIG2
Definition: ApiBase.php:79
ApiMain\API_DEFAULT_FORMAT
const API_DEFAULT_FORMAT
When no format parameter is given, this format will be used.
Definition: ApiMain.php:45
ApiMain\addModule
addModule( $name, $class)
Add or overwrite a module in this ApiMain instance.
Definition: ApiMain.php:1396
ApiMain\setHelp
setHelp( $help=true)
Sets whether the pretty-printer should format bold and $italics$.
Definition: ApiMain.php:1264
ApiMain\printResult
printResult( $isError)
Print results using the current printer.
Definition: ApiMain.php:1074
ApiMain\getUpload
getUpload( $name)
Get a request upload, and register the fact that it was used, for logging.
Definition: ApiMain.php:1038
MWExceptionHandler\rollbackMasterChangesAndLog
static rollbackMasterChangesAndLog(Exception $e)
If there are any open database transactions, roll them back and log the stack trace of the exception ...
Definition: MWExceptionHandler.php:111
ApiBase\PARAM_DFLT
const PARAM_DFLT
Definition: ApiBase.php:46
ApiBase\getParameter
getParameter( $paramName, $parseLimit=true)
Get a value for the given parameter.
Definition: ApiBase.php:731
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
ApiMain\getPossibleErrors
getPossibleErrors()
Definition: ApiMain.php:1226
ApiBase\getModuleName
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:148
User
User
Definition: All_system_messages.txt:425
ApiMain\executeAction
executeAction()
Execute the actual module, without any error handling.
Definition: ApiMain.php:926
ApiMain\setupModule
setupModule()
Set up the module for response.
Definition: ApiMain.php:791
$help
$help
Definition: mcc.php:31
MWExceptionHandler\logException
static logException(Exception $e)
Log an exception to the exception log (if enabled).
Definition: MWExceptionHandler.php:351
ApiMain\$mCacheControl
$mCacheControl
Definition: ApiMain.php:143
$t
$t
Definition: testCompression.php:65
ApiMain\handleException
handleException(Exception $e)
Handle an exception as an API response.
Definition: ApiMain.php:418
ApiMain\isInternalMode
isInternalMode()
Return true if the API was started by other PHP code using FauxRequest.
Definition: ApiMain.php:208
ApiMain\$mParamsUsed
$mParamsUsed
Definition: ApiMain.php:144
ApiMain\$mModuleMgr
$mModuleMgr
Definition: ApiMain.php:137
ApiMain\setCacheMaxAge
setCacheMaxAge( $maxage)
Set how long the response should be cached.
Definition: ApiMain.php:273
$retval
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account incomplete not yet checked for validity & $retval
Definition: hooks.txt:237
ApiMain\setCacheMode
setCacheMode( $mode)
Set the type of caching headers which will be sent.
Definition: ApiMain.php:305
TS_RFC2822
const TS_RFC2822
RFC 2822 format, for E-mail and HTTP headers.
Definition: GlobalFunctions.php:2488
ApiMain\getPrinter
getPrinter()
Get the result formatter object.
Definition: ApiMain.php:264
User\getGroupsWithPermission
static getGroupsWithPermission( $role)
Get all the groups who have a given permission.
Definition: User.php:4127
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:1632
SpecialVersion\getVersion
static getVersion( $flags='')
Return a string of the MediaWiki version with SVN revision if available.
Definition: SpecialVersion.php:246
ApiMain\getFormats
getFormats()
Returns the list of supported formats in form ( 'format' => 'ClassName' )
Definition: ApiMain.php:1428