mediawiki-extensions-Echo/includes/api/ApiEchoMute.php
Petr Pchelko a10b0b07c8 Use CentralIdLookupFactory and pass UserIdentity
Change-Id: I44144df7cf244eb867c1b261c10cc29b020f8409
2021-07-21 19:23:42 -07:00

150 lines
3.6 KiB
PHP

<?php
use MediaWiki\MediaWikiServices;
use MediaWiki\User\UserOptionsManager;
class ApiEchoMute extends ApiBase {
/** @var CentralIdLookup */
private $centralIdLookup;
/** @var UserOptionsManager */
private $userOptionsManager;
/** @var string[][] */
private static $muteLists = [
'user' => [
'pref' => 'echo-notifications-blacklist',
'type' => 'user',
],
'page-linked-title' => [
'pref' => 'echo-notifications-page-linked-title-muted-list',
'type' => 'title'
],
];
/**
* @param ApiMain $main
* @param string $action
* @param CentralIdLookup $centralIdLookup
* @param UserOptionsManager $userOptionsManager
*/
public function __construct(
ApiMain $main,
$action,
CentralIdLookup $centralIdLookup,
UserOptionsManager $userOptionsManager
) {
parent::__construct( $main, $action );
$this->centralIdLookup = $centralIdLookup;
$this->userOptionsManager = $userOptionsManager;
}
public function execute() {
$user = $this->getUser()->getInstanceForUpdate();
if ( !$user || !$user->isRegistered() ) {
$this->dieWithError(
[ 'apierror-mustbeloggedin', $this->msg( 'action-editmyoptions' ) ],
'notloggedin'
);
}
$this->checkUserRightsAny( 'editmyoptions' );
$params = $this->extractRequestParams();
$mutelistInfo = self::$muteLists[ $params['type'] ];
$prefValue = $user->getOption( $mutelistInfo['pref'] );
$ids = $this->parsePref( $prefValue, $mutelistInfo['type'] );
$targetsToMute = $params['mute'] ?? [];
$targetsToUnmute = $params['unmute'] ?? [];
$changed = false;
$addIds = $this->lookupIds( $targetsToMute, $mutelistInfo['type'] );
foreach ( $addIds as $id ) {
if ( !in_array( $id, $ids ) ) {
$ids[] = $id;
$changed = true;
}
}
$removeIds = $this->lookupIds( $targetsToUnmute, $mutelistInfo['type'] );
foreach ( $removeIds as $id ) {
$index = array_search( $id, $ids );
if ( $index !== false ) {
array_splice( $ids, $index, 1 );
$changed = true;
}
}
if ( $changed ) {
$this->userOptionsManager->setOption(
// Phan does not understand dieWithError() - T240141
// @phan-suppress-next-line PhanTypeMismatchArgumentNullable
$user,
$mutelistInfo['pref'],
$this->serializePref( $ids, $mutelistInfo['type'] )
);
$user->saveSettings();
}
$this->getResult()->addValue( null, $this->getModuleName(), 'success' );
}
private function lookupIds( $names, $type ) {
if ( $type === 'title' ) {
$linkBatch = MediaWikiServices::getInstance()->getLinkBatchFactory()->newLinkBatch();
foreach ( $names as $name ) {
$linkBatch->addObj( Title::newFromText( $name ) );
}
$linkBatch->execute();
$ids = [];
foreach ( $names as $name ) {
$title = Title::newFromText( $name );
if ( $title instanceof Title && $title->getArticleID() > 0 ) {
$ids[] = $title->getArticleID();
}
}
return $ids;
} elseif ( $type === 'user' ) {
return $this->centralIdLookup->centralIdsFromNames( $names, CentralIdLookup::AUDIENCE_PUBLIC );
}
}
private function parsePref( $prefValue, $type ) {
return preg_split( '/\n/', $prefValue, -1, PREG_SPLIT_NO_EMPTY );
}
private function serializePref( $ids, $type ) {
return implode( "\n", $ids );
}
public function getAllowedParams( $flags = 0 ) {
return [
'type' => [
ApiBase::PARAM_REQUIRED => true,
ApiBase::PARAM_TYPE => array_keys( self::$muteLists ),
],
'mute' => [
ApiBase::PARAM_ISMULTI => true,
],
'unmute' => [
ApiBase::PARAM_ISMULTI => true,
]
];
}
public function needsToken() {
return 'csrf';
}
public function mustBePosted() {
return true;
}
public function isWriteMode() {
return true;
}
}