Remove ActionAjax
Bug: T42786 Change-Id: I8bda0c281e1f4abbffbddb80ac74a6d61a034d28
This commit is contained in:
parent
c3891f1db3
commit
9bcd3fdfa5
12 changed files with 19 additions and 397 deletions
|
|
@ -250,6 +250,7 @@ because of Phabricator reports.
|
|||
post-parse and can be included by providing 'includeDebugInfo' option
|
||||
to ParserOutput::getText. Thus, ParserOptions::enableLimitReport and
|
||||
::getEnableLimitReport methods were deprecated.
|
||||
* Ajax action that was deprecated in 1.27 now has been removed.
|
||||
* …
|
||||
|
||||
=== Deprecations in 1.38 ===
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ $wgAutoloadLocalClasses = [
|
|||
'AddChangeTag' => __DIR__ . '/maintenance/addChangeTag.php',
|
||||
'AddRFCandPMIDInterwiki' => __DIR__ . '/maintenance/addRFCandPMIDInterwiki.php',
|
||||
'AddSite' => __DIR__ . '/maintenance/addSite.php',
|
||||
'AjaxDispatcher' => __DIR__ . '/includes/AjaxDispatcher.php',
|
||||
'AjaxResponse' => __DIR__ . '/includes/AjaxResponse.php',
|
||||
'AllMessagesTablePager' => __DIR__ . '/includes/specials/pagers/AllMessagesTablePager.php',
|
||||
'AllTrans' => __DIR__ . '/maintenance/language/alltrans.php',
|
||||
'AlphabeticPager' => __DIR__ . '/includes/pager/AlphabeticPager.php',
|
||||
|
|
|
|||
|
|
@ -1,169 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Handle ajax requests and send them to the proper handler.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
* @ingroup Ajax
|
||||
*/
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
// Use superglobals, but since it's deprecated, it's not worth fixing
|
||||
// phpcs:disable MediaWiki.Usage.SuperGlobalsUsage.SuperGlobals
|
||||
|
||||
/**
|
||||
* @defgroup Ajax Ajax
|
||||
*/
|
||||
|
||||
/**
|
||||
* Object-Oriented Ajax functions.
|
||||
* @ingroup Ajax
|
||||
*/
|
||||
class AjaxDispatcher {
|
||||
/**
|
||||
* The way the request was made, either a 'get' or a 'post'
|
||||
* @var string
|
||||
*/
|
||||
private $mode;
|
||||
|
||||
/**
|
||||
* Name of the requested handler
|
||||
* @var string
|
||||
*/
|
||||
private $func_name;
|
||||
|
||||
/** Arguments passed
|
||||
* @var array
|
||||
*/
|
||||
private $args;
|
||||
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* Load up our object with user supplied data
|
||||
* @param Config $config
|
||||
*/
|
||||
public function __construct( Config $config ) {
|
||||
$this->config = $config;
|
||||
|
||||
$this->mode = "";
|
||||
|
||||
if ( !empty( $_GET["rs"] ) ) {
|
||||
$this->mode = "get";
|
||||
}
|
||||
|
||||
if ( !empty( $_POST["rs"] ) ) {
|
||||
$this->mode = "post";
|
||||
}
|
||||
|
||||
switch ( $this->mode ) {
|
||||
case 'get':
|
||||
$this->func_name = $_GET["rs"] ?? '';
|
||||
if ( !empty( $_GET["rsargs"] ) ) {
|
||||
$this->args = $_GET["rsargs"];
|
||||
} else {
|
||||
$this->args = [];
|
||||
}
|
||||
break;
|
||||
case 'post':
|
||||
$this->func_name = $_POST["rs"] ?? '';
|
||||
if ( !empty( $_POST["rsargs"] ) ) {
|
||||
$this->args = $_POST["rsargs"];
|
||||
} else {
|
||||
$this->args = [];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
# Or we could throw an exception:
|
||||
# throw new MWException( __METHOD__ . ' called without any data (mode empty).' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass the request to our internal function.
|
||||
* BEWARE! Data are passed as they have been supplied by the user,
|
||||
* they should be carefully handled in the function processing the
|
||||
* request.
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function performAction( User $user ) {
|
||||
if ( empty( $this->mode ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
|
||||
if ( !in_array( $this->func_name, $this->config->get( 'AjaxExportList' ) ) ) {
|
||||
wfDebug( __METHOD__ . ' Bad Request for unknown function ' . $this->func_name );
|
||||
wfHttpError(
|
||||
400,
|
||||
'Bad Request',
|
||||
"unknown function " . $this->func_name
|
||||
);
|
||||
} elseif ( !$permissionManager->isEveryoneAllowed( 'read' ) &&
|
||||
!$permissionManager->userHasRight( $user, 'read' )
|
||||
) {
|
||||
wfHttpError(
|
||||
403,
|
||||
'Forbidden',
|
||||
'You are not allowed to view pages.' );
|
||||
} else {
|
||||
wfDebug( __METHOD__ . ' dispatching ' . $this->func_name );
|
||||
try {
|
||||
$result = call_user_func_array( $this->func_name, $this->args );
|
||||
|
||||
if ( $result === false || $result === null ) {
|
||||
wfDebug( __METHOD__ . ' ERROR while dispatching ' .
|
||||
$this->func_name . "(" . var_export( $this->args, true ) . "): " .
|
||||
"no data returned" );
|
||||
|
||||
wfHttpError( 500, 'Internal Error',
|
||||
"{$this->func_name} returned no data" );
|
||||
} else {
|
||||
if ( is_string( $result ) ) {
|
||||
$result = new AjaxResponse( $result );
|
||||
}
|
||||
|
||||
// Make sure DB commit succeeds before sending a response
|
||||
$lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
|
||||
$lbFactory->commitPrimaryChanges( __METHOD__ );
|
||||
|
||||
$result->sendHeaders();
|
||||
$result->printText();
|
||||
|
||||
wfDebug( __METHOD__ . ' dispatch complete for ' . $this->func_name );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
wfDebug( __METHOD__ . ' ERROR while dispatching ' .
|
||||
$this->func_name . "(" . var_export( $this->args, true ) . "): " .
|
||||
get_class( $e ) . ": " . $e->getMessage() );
|
||||
|
||||
if ( !headers_sent() ) {
|
||||
wfHttpError( 500, 'Internal Error',
|
||||
$e->getMessage() );
|
||||
} else {
|
||||
print $e->getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Response handler for Ajax requests.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
* @ingroup Ajax
|
||||
*/
|
||||
use MediaWiki\MediaWikiServices;
|
||||
|
||||
/**
|
||||
* Handle responses for Ajax requests (send headers, print
|
||||
* content, that sort of thing)
|
||||
*
|
||||
* @ingroup Ajax
|
||||
*/
|
||||
class AjaxResponse {
|
||||
/**
|
||||
* Number of seconds to get the response cached by a proxy
|
||||
* @var int
|
||||
*/
|
||||
private $mCacheDuration;
|
||||
|
||||
/**
|
||||
* HTTP header Content-Type
|
||||
* @var string
|
||||
*/
|
||||
private $mContentType;
|
||||
|
||||
/**
|
||||
* Disables output. Can be set by calling $AjaxResponse->disable()
|
||||
* @var bool
|
||||
*/
|
||||
private $mDisabled;
|
||||
|
||||
/**
|
||||
* Date for the HTTP header Last-modified
|
||||
* @var string|bool
|
||||
*/
|
||||
private $mLastModified;
|
||||
|
||||
/**
|
||||
* HTTP response code
|
||||
* @var int|string
|
||||
*/
|
||||
private $mResponseCode;
|
||||
|
||||
/**
|
||||
* HTTP Vary header
|
||||
* @var string
|
||||
*/
|
||||
private $mVary;
|
||||
|
||||
/**
|
||||
* Content of our HTTP response
|
||||
* @var string
|
||||
*/
|
||||
private $mText;
|
||||
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
private $mConfig;
|
||||
|
||||
/**
|
||||
* @param string|null $text
|
||||
* @param Config|null $config
|
||||
*/
|
||||
public function __construct( $text = null, Config $config = null ) {
|
||||
$this->mCacheDuration = null;
|
||||
$this->mVary = null;
|
||||
$this->mConfig = $config ?: MediaWikiServices::getInstance()->getMainConfig();
|
||||
|
||||
$this->mDisabled = false;
|
||||
$this->mText = '';
|
||||
$this->mResponseCode = 200;
|
||||
$this->mLastModified = false;
|
||||
$this->mContentType = 'application/x-wiki';
|
||||
|
||||
if ( $text ) {
|
||||
$this->addText( $text );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HTTP response code
|
||||
* @param int|string $code
|
||||
*/
|
||||
public function setResponseCode( $code ) {
|
||||
$this->mResponseCode = $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HTTP header Content-Type
|
||||
* @param string $type
|
||||
*/
|
||||
public function setContentType( $type ) {
|
||||
$this->mContentType = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable output.
|
||||
*/
|
||||
public function disable() {
|
||||
$this->mDisabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add content to the response
|
||||
* @param string $text
|
||||
*/
|
||||
public function addText( $text ) {
|
||||
if ( !$this->mDisabled && $text ) {
|
||||
$this->mText .= $text;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output text
|
||||
*/
|
||||
public function printText() {
|
||||
if ( !$this->mDisabled ) {
|
||||
print $this->mText;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the header and output it
|
||||
*/
|
||||
public function sendHeaders() {
|
||||
if ( $this->mResponseCode ) {
|
||||
// For back-compat, it is supported that mResponseCode be a string like " 200 OK"
|
||||
// (with leading space and the status message after). Cast response code to an integer
|
||||
// to take advantage of PHP's conversion rules which will turn " 200 OK" into 200.
|
||||
// https://www.php.net/manual/en/language.types.string.php#language.types.string.conversion
|
||||
$n = intval( trim( $this->mResponseCode ) );
|
||||
HttpStatus::header( $n );
|
||||
}
|
||||
|
||||
header( "Content-Type: " . $this->mContentType );
|
||||
|
||||
if ( $this->mLastModified ) {
|
||||
header( "Last-Modified: " . $this->mLastModified );
|
||||
} else {
|
||||
header( "Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . " GMT" );
|
||||
}
|
||||
|
||||
if ( $this->mCacheDuration ) {
|
||||
# If CDN caches are configured, tell them to cache the response,
|
||||
# and tell the client to always check with the CDN. Otherwise,
|
||||
# tell the client to use a cached copy, without a way to purge it.
|
||||
if ( $this->mConfig->get( 'UseCdn' ) ) {
|
||||
# Expect explicit purge of the proxy cache, but require end user agents
|
||||
# to revalidate against the proxy on each visit.
|
||||
header( 'Cache-Control: s-maxage=' . $this->mCacheDuration . ', must-revalidate, max-age=0' );
|
||||
} else {
|
||||
# Let the client do the caching. Cache is not purged.
|
||||
header( "Expires: " . gmdate( "D, d M Y H:i:s", time() + $this->mCacheDuration ) . " GMT" );
|
||||
header( "Cache-Control: s-maxage={$this->mCacheDuration}," .
|
||||
"public,max-age={$this->mCacheDuration}" );
|
||||
}
|
||||
|
||||
} else {
|
||||
# always expired, always modified
|
||||
header( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" ); // Date in the past
|
||||
header( "Cache-Control: no-cache, must-revalidate" ); // HTTP/1.1
|
||||
header( "Pragma: no-cache" ); // HTTP/1.0
|
||||
}
|
||||
|
||||
if ( $this->mVary ) {
|
||||
header( "Vary: " . $this->mVary );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9212,12 +9212,8 @@ $wgExemptFromUserRobotsControl = null;
|
|||
// endregion End robot policy
|
||||
|
||||
/***************************************************************************/
|
||||
// region AJAX, Action API and REST API
|
||||
/** @name AJAX, Action API and REST API
|
||||
*
|
||||
* Note: The AJAX entry point which this section refers to is gradually being
|
||||
* replaced by the Action API entry point, api.php. They are essentially
|
||||
* equivalent. Both of them are used for dynamic client-side features, via XHR.
|
||||
// region Action API and REST API
|
||||
/** @name Action API and REST API
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -9354,20 +9350,6 @@ $wgAPIUselessQueryPages = [
|
|||
'LinkSearch', // list=exturlusage
|
||||
];
|
||||
|
||||
/**
|
||||
* Enable AJAX framework
|
||||
*
|
||||
* @deprecated (officially) since MediaWiki 1.31 and ignored since 1.32
|
||||
*/
|
||||
$wgUseAjax = true;
|
||||
|
||||
/**
|
||||
* List of Ajax-callable functions.
|
||||
* Extensions acting as Ajax callbacks must register here
|
||||
* @deprecated (officially) since 1.27; use the API instead
|
||||
*/
|
||||
$wgAjaxExportList = [];
|
||||
|
||||
/**
|
||||
* Enable AJAX check for file overwrite, pre-upload
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -850,21 +850,6 @@ class MediaWiki {
|
|||
$output = $this->context->getOutput();
|
||||
$request = $this->context->getRequest();
|
||||
|
||||
// Send Ajax requests to the Ajax dispatcher.
|
||||
if ( $request->getRawVal( 'action' ) === 'ajax' ) {
|
||||
// Set a dummy title, because $wgTitle == null might break things
|
||||
$title = Title::makeTitle( NS_SPECIAL, 'Badtitle/performing an AJAX call in '
|
||||
. __METHOD__
|
||||
);
|
||||
$this->context->setTitle( $title );
|
||||
$wgTitle = $title;
|
||||
|
||||
$dispatcher = new AjaxDispatcher( $this->config );
|
||||
$dispatcher->performAction( $this->context->getUser() );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get title from request parameters,
|
||||
// is set on the fly by parseTitle the first time.
|
||||
$title = $this->getTitle();
|
||||
|
|
|
|||
|
|
@ -2231,7 +2231,7 @@ class OutputPage extends ContextSource {
|
|||
public function couldBePublicCached() {
|
||||
if ( !$this->cacheIsFinal ) {
|
||||
// - The entry point handles its own caching and/or doesn't use OutputPage.
|
||||
// (such as load.php, AjaxDispatcher, or MediaWiki\Rest\EntryPoint).
|
||||
// (such as load.php, or MediaWiki\Rest\EntryPoint).
|
||||
//
|
||||
// - Or, we haven't finished processing the main part of the request yet
|
||||
// (e.g. Action::show, SpecialPage::execute), and the state may still
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ class BlockManager {
|
|||
} elseif ( count( $blocks ) === 1 ) {
|
||||
return $blocks[ 0 ];
|
||||
} else {
|
||||
// @phan-suppress-next-line SecurityCheck-DoubleEscaped
|
||||
return new CompositeBlock( [
|
||||
'address' => $ip,
|
||||
'reason' => new Message( 'blockedtext-composite-reason' ),
|
||||
|
|
@ -253,12 +254,14 @@ class BlockManager {
|
|||
if ( !in_array( $ip, $this->options->get( 'ProxyWhitelist' ) ) ) {
|
||||
// Local list
|
||||
if ( $this->isLocallyBlockedProxy( $ip ) ) {
|
||||
// @phan-suppress-next-line SecurityCheck-DoubleEscaped
|
||||
$blocks[] = new SystemBlock( [
|
||||
'reason' => new Message( 'proxyblockreason' ),
|
||||
'address' => $ip,
|
||||
'systemBlock' => 'proxy',
|
||||
] );
|
||||
} elseif ( $isAnon && $this->isDnsBlacklisted( $ip ) ) {
|
||||
// @phan-suppress-next-line SecurityCheck-DoubleEscaped
|
||||
$blocks[] = new SystemBlock( [
|
||||
'reason' => new Message( 'sorbsreason' ),
|
||||
'address' => $ip,
|
||||
|
|
@ -270,6 +273,7 @@ class BlockManager {
|
|||
|
||||
// Soft blocking
|
||||
if ( $isAnon && IPUtils::isInRanges( $ip, $this->options->get( 'SoftBlockRanges' ) ) ) {
|
||||
// @phan-suppress-next-line SecurityCheck-DoubleEscaped
|
||||
$blocks[] = new SystemBlock( [
|
||||
'address' => $ip,
|
||||
'reason' => new Message( 'softblockrangesreason', [ $ip ] ),
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ class DatabaseBlock extends AbstractBlock {
|
|||
$conds['ipb_address'][] = (string)$target;
|
||||
$conds['ipb_address'] = array_unique( $conds['ipb_address'] );
|
||||
$conds[] = self::getRangeCond( IPUtils::toHex( $target ) );
|
||||
// @phan-suppress-next-line SecurityCheck-SQLInjection
|
||||
$conds = $db->makeList( $conds, LIST_OR );
|
||||
break;
|
||||
|
||||
|
|
@ -276,6 +277,7 @@ class DatabaseBlock extends AbstractBlock {
|
|||
list( $start, $end ) = IPUtils::parseRange( $target );
|
||||
$conds['ipb_address'][] = (string)$target;
|
||||
$conds[] = self::getRangeCond( $start, $end );
|
||||
// @phan-suppress-next-line SecurityCheck-SQLInjection
|
||||
$conds = $db->makeList( $conds, LIST_OR );
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -678,6 +678,7 @@ class ChangesList extends ContextSource {
|
|||
$s .= ' <span class="' . $deletedClass . '">' .
|
||||
$this->msg( 'rev-deleted-user' )->escaped() . '</span>';
|
||||
} else {
|
||||
// @phan-suppress-next-line SecurityCheck-DoubleEscaped
|
||||
$s .= $this->getLanguage()->getDirMark() . Linker::userLink( $rc->mAttribs['rc_user'],
|
||||
$rc->mAttribs['rc_user_text'] );
|
||||
$s .= Linker::userToolLinks(
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ class WebInstallerOptions extends WebInstallerPage {
|
|||
}
|
||||
$skinHtml .=
|
||||
'<div class="config-skins-item">' .
|
||||
// @phan-suppress-next-line SecurityCheck-DoubleEscaped
|
||||
$this->parent->getCheckBox( [
|
||||
'var' => "skin-$skin",
|
||||
'rawtext' => $screenshotText,
|
||||
|
|
@ -222,6 +223,7 @@ class WebInstallerOptions extends WebInstallerPage {
|
|||
} else {
|
||||
$text = $ext;
|
||||
}
|
||||
// @phan-suppress-next-line SecurityCheck-DoubleEscaped
|
||||
$extHtml .= $this->parent->getCheckBox( [
|
||||
'var' => "ext-$ext",
|
||||
'rawtext' => $text,
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ class LogPage {
|
|||
if ( $this->updateRecentChanges ) {
|
||||
$titleObj = SpecialPage::getTitleFor( 'Log', $this->type );
|
||||
|
||||
// @phan-suppress-next-line SecurityCheck-DoubleEscaped
|
||||
RecentChange::notifyLog(
|
||||
$now, $titleObj, $this->performer, $this->getRcComment(), '',
|
||||
$this->type, $this->action, $this->target, $this->comment,
|
||||
|
|
@ -136,9 +137,10 @@ class LogPage {
|
|||
return $newId;
|
||||
}
|
||||
|
||||
# Notify external application via UDP.
|
||||
# We send this to IRC but do not want to add it the RC table.
|
||||
// Notify external application via UDP.
|
||||
// We send this to IRC but do not want to add it the RC table.
|
||||
$titleObj = SpecialPage::getTitleFor( 'Log', $this->type );
|
||||
// @phan-suppress-next-line SecurityCheck-DoubleEscaped
|
||||
$rc = RecentChange::newLogEntry(
|
||||
$now, $titleObj, $this->performer, $this->getRcComment(), '',
|
||||
$this->type, $this->action, $this->target, $this->comment,
|
||||
|
|
@ -255,6 +257,7 @@ class LogPage {
|
|||
$titleLink = self::getTitleLink( $title, $langObjOrNull );
|
||||
|
||||
if ( count( $params ) == 0 ) {
|
||||
// @phan-suppress-next-line SecurityCheck-XSS
|
||||
$rv = wfMessage( $wgLogActions[$key] )->rawParams( $titleLink )
|
||||
->inLanguage( $langObj )->escaped();
|
||||
} else {
|
||||
|
|
@ -360,6 +363,7 @@ class LogPage {
|
|||
|
||||
$this->performer = $performer;
|
||||
|
||||
// @phan-suppress-next-line SecurityCheck-DoubleEscaped
|
||||
$logEntry = new ManualLogEntry( $this->type, $action );
|
||||
$logEntry->setTarget( $target );
|
||||
$logEntry->setPerformer( $performer );
|
||||
|
|
|
|||
Loading…
Reference in a new issue