Файловый менеджер - Редактировать - /var/www/html/Api.zip
Ðазад
PK ! �I�NY Y ApiCrossWiki.phpnu �Iw�� <?php namespace MediaWiki\Extension\Notifications\Api; // @phan-file-suppress PhanUndeclaredMethod This is a trait, and phan is confused by $this use Exception; use MediaWiki\Extension\Notifications\ForeignNotifications; use MediaWiki\Extension\Notifications\ForeignWikiRequest; use MediaWiki\WikiMap\WikiMap; use Wikimedia\ParamValidator\ParamValidator; /** * Trait that adds cross-wiki functionality to an API module. For mixing into ApiBase subclasses. * * In addition to mixing in this trait, you have to do the following in your API module: * - In your getAllowedParams() method, merge in the return value of getCrossWikiParams() * - In your execute() method, call getFromForeign() somewhere and do something with the result * - Optionally, override getForeignQueryParams() to customize what is sent to the foreign wikis */ trait ApiCrossWiki { protected ?ForeignNotifications $foreignNotifications = null; /** * This will take the current API call (with all of its params) and execute * it on all foreign wikis, returning an array of results per wiki. * * @param array|null $wikis List of wikis to query. Defaults to the result of getRequestedForeignWikis(). * @param array $paramOverrides Request parameter overrides * @return array[] * @throws Exception */ protected function getFromForeign( ?array $wikis = null, array $paramOverrides = [] ) { $wikis ??= $this->getRequestedForeignWikis(); if ( $wikis === [] ) { return []; } $tokenType = $this->needsToken(); $foreignReq = new ForeignWikiRequest( $this->getUser(), $paramOverrides + $this->getForeignQueryParams(), $wikis, $this->getModulePrefix() . 'wikis', $tokenType !== false ? $tokenType : null ); return $foreignReq->execute( $this->getRequest() ); } /** * Get the query parameters to use for the foreign API requests. * Implementing classes should override this if they need to customize * the parameters. * @return array Query parameters */ protected function getForeignQueryParams() { return $this->getRequest()->getValues(); } /** * @return bool */ protected function allowCrossWikiNotifications() { global $wgEchoCrossWikiNotifications; return $wgEchoCrossWikiNotifications; } /** * This is basically equivalent to $params['wikis'], but some added checks: * - `*` will expand to "all wikis with unread notifications" * - if `$wgEchoCrossWikiNotifications` is off, foreign wikis will be excluded * * @return string[] */ protected function getRequestedWikis(): array { $params = $this->extractRequestParams(); // if wiki is omitted from params, that's because crosswiki is/was not // available, and it'll default to current wiki $wikis = $params['wikis'] ?? [ WikiMap::getCurrentWikiId() ]; if ( in_array( '*', $wikis ) ) { // expand `*` to all foreign wikis with unread notifications + local $wikis = array_merge( [ WikiMap::getCurrentWikiId() ], $this->getForeignWikisWithUnreadNotifications() ); } if ( !$this->allowCrossWikiNotifications() ) { // exclude foreign wikis if x-wiki is not enabled $wikis = array_intersect_key( [ WikiMap::getCurrentWikiId() ], $wikis ); } return $wikis; } /** * @return string[] Wiki names */ protected function getRequestedForeignWikis(): array { return array_diff( $this->getRequestedWikis(), [ WikiMap::getCurrentWikiId() ] ); } protected function getForeignNotifications(): ForeignNotifications { $this->foreignNotifications ??= new ForeignNotifications( $this->getUser() ); return $this->foreignNotifications; } /** * @return string[] Wiki names */ protected function getForeignWikisWithUnreadNotifications(): array { return $this->getForeignNotifications()->getWikis(); } /** * @return array[] */ public function getCrossWikiParams(): array { global $wgConf; $params = []; if ( $this->allowCrossWikiNotifications() ) { $params += [ // fetch notifications from multiple wikis 'wikis' => [ ParamValidator::PARAM_ISMULTI => true, ParamValidator::PARAM_DEFAULT => WikiMap::getCurrentWikiId(), // `*` will let you immediately fetch from all wikis that have // unread notifications, without having to look them up first ParamValidator::PARAM_TYPE => array_unique( array_merge( $wgConf->wikis, [ WikiMap::getCurrentWikiId(), '*' ] ) ), ], ]; } return $params; } } PK ! �W��� � ApiEchoMute.phpnu �Iw�� <?php namespace MediaWiki\Extension\Notifications\Api; use MediaWiki\Api\ApiBase; use MediaWiki\Api\ApiMain; use MediaWiki\Cache\LinkBatchFactory; use MediaWiki\Title\Title; use MediaWiki\User\CentralId\CentralIdLookup; use MediaWiki\User\Options\UserOptionsManager; use Wikimedia\ParamValidator\ParamValidator; class ApiEchoMute extends ApiBase { /** @var CentralIdLookup */ private $centralIdLookup; /** @var LinkBatchFactory */ private $linkBatchFactory; /** @var UserOptionsManager */ private $userOptionsManager; /** @var string[][] */ private const MUTE_LISTS = [ '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 LinkBatchFactory $linkBatchFactory * @param UserOptionsManager $userOptionsManager */ public function __construct( ApiMain $main, $action, CentralIdLookup $centralIdLookup, LinkBatchFactory $linkBatchFactory, UserOptionsManager $userOptionsManager ) { parent::__construct( $main, $action ); $this->centralIdLookup = $centralIdLookup; $this->linkBatchFactory = $linkBatchFactory; $this->userOptionsManager = $userOptionsManager; } public function execute() { $user = $this->getUser(); if ( !$user || !$user->isRegistered() ) { $this->dieWithError( [ 'apierror-mustbeloggedin', $this->msg( 'action-editmyoptions' ) ], 'notloggedin' ); } $this->checkUserRightsAny( 'editmyoptions' ); $params = $this->extractRequestParams(); $mutelistInfo = self::MUTE_LISTS[ $params['type'] ]; $prefValue = $this->userOptionsManager->getOption( $user, $mutelistInfo['pref'] ); $ids = $this->parsePref( $prefValue ); $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( $user, $mutelistInfo['pref'], $this->serializePref( $ids ) ); $this->userOptionsManager->saveOptions( $user ); } $this->getResult()->addValue( null, $this->getModuleName(), 'success' ); } private function lookupIds( $names, $type ) { if ( $type === 'title' ) { $linkBatch = $this->linkBatchFactory->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 ) { return preg_split( '/\n/', $prefValue, -1, PREG_SPLIT_NO_EMPTY ); } private function serializePref( $ids ) { return implode( "\n", $ids ); } public function getAllowedParams( $flags = 0 ) { return [ 'type' => [ ParamValidator::PARAM_REQUIRED => true, ParamValidator::PARAM_TYPE => array_keys( self::MUTE_LISTS ), ], 'mute' => [ ParamValidator::PARAM_ISMULTI => true, ], 'unmute' => [ ParamValidator::PARAM_ISMULTI => true, ] ]; } public function needsToken() { return 'csrf'; } public function mustBePosted() { return true; } public function isWriteMode() { return true; } } PK ! ٷVg� � ApiEchoCreateEvent.phpnu �Iw�� <?php namespace MediaWiki\Extension\Notifications\Api; use MediaWiki\Api\ApiBase; use MediaWiki\Api\ApiMain; use MediaWiki\Extension\Notifications\Model\Event; use MediaWiki\ParamValidator\TypeDef\TitleDef; use MediaWiki\ParamValidator\TypeDef\UserDef; use MediaWiki\Title\Title; use MediaWiki\User\UserIdentity; use MediaWiki\User\UserNameUtils; use Wikimedia\ParamValidator\ParamValidator; use Wikimedia\ParamValidator\TypeDef\StringDef; class ApiEchoCreateEvent extends ApiBase { private UserNameUtils $userNameUtils; public function __construct( ApiMain $mainModule, $moduleName, UserNameUtils $userNameUtils ) { parent::__construct( $mainModule, $moduleName ); $this->userNameUtils = $userNameUtils; } /** * @see ApiBase::execute() * @return void */ public function execute() { if ( !$this->getConfig()->get( 'EchoEnableApiEvents' ) ) { $this->dieWithError( [ 'apierror-moduledisabled', $this->getModuleName() ] ); } // Only for logged in users $user = $this->getUser(); if ( !$user->isNamed() ) { $this->dieWithError( 'apierror-mustbeloggedin-generic', 'login-required' ); } $params = $this->extractRequestParams(); // Default to self if unspecified /** @var UserIdentity $userToNotify */ $userToNotify = $params['user'] ?? $user; if ( $userToNotify->getName() !== $user->getName() ) { $this->checkUserRightsAny( 'echo-create' ); } if ( !$userToNotify->isRegistered() || $this->userNameUtils->isTemp( $userToNotify->getName() ) ) { $this->dieWithError( [ 'nosuchusershort', $userToNotify->getName() ] ); } $event = Event::create( [ // type is one of api-notice, api-alert 'type' => 'api-' . $params['section'], 'agent' => $user, 'title' => $params['page'] ? Title::newFromLinkTarget( $params['page'] ) : null, 'extra' => [ 'recipients' => [ $userToNotify->getId() ], 'header' => $params['header'], 'content' => $params['content'], // Send email only if specified 'noemail' => !$params['email'], ] ] ); // Return a success message $this->getResult()->addValue( null, $this->getModuleName(), [ 'result' => 'success' ] ); } /** * @see ApiBase::needsToken() * @return bool */ public function mustBePosted() { return true; } public function isWriteMode() { return true; } public function needsToken() { return 'csrf'; } /** * @see ApiBase::getAllowedParams() * @return array */ public function getAllowedParams() { return [ 'user' => [ ParamValidator::PARAM_TYPE => 'user', UserDef::PARAM_ALLOWED_USER_TYPES => [ 'name', 'id' ], UserDef::PARAM_RETURN_OBJECT => true, ], 'header' => [ ParamValidator::PARAM_REQUIRED => true, ParamValidator::PARAM_TYPE => 'string', StringDef::PARAM_MAX_BYTES => 160, ], 'content' => [ ParamValidator::PARAM_REQUIRED => true, ParamValidator::PARAM_TYPE => 'string', StringDef::PARAM_MAX_BYTES => 5000, ], 'page' => [ ParamValidator::PARAM_TYPE => 'title', TitleDef::PARAM_RETURN_OBJECT => true, ], 'section' => [ ParamValidator::PARAM_REQUIRED => true, ParamValidator::PARAM_TYPE => [ 'alert', 'notice' ], ParamValidator::PARAM_DEFAULT => 'notice', ], 'email' => [ ParamValidator::PARAM_TYPE => 'boolean', ParamValidator::PARAM_DEFAULT => false, ], ]; } /** * @see ApiBase::getExamplesMessages() * @return string[] */ protected function getExamplesMessages() { return [ 'action=echocreateevent&header=Hi&content=From_API' => 'apihelp-echocreateevent-example', ]; } /** * @see ApiBase::getHelpUrls() * @return string */ public function getHelpUrls() { return 'https://www.mediawiki.org/wiki/Special:MyLanguage/Echo_(Notifications)/API'; } } PK ! UBu�� � ApiEchoMarkSeen.phpnu �Iw�� <?php namespace MediaWiki\Extension\Notifications\Api; // This is a GET module, not a POST module, for multi-DC support. See T222851. // Note that this module doesn't write to the database, only to the seentime cache. use MediaWiki\Api\ApiBase; use MediaWiki\Extension\Notifications\SeenTime; use Wikimedia\ParamValidator\ParamValidator; class ApiEchoMarkSeen extends ApiBase { public function execute() { // To avoid API warning, register the parameter used to bust browser cache $this->getMain()->getVal( '_' ); $user = $this->getUser(); if ( !$user->isRegistered() ) { $this->dieWithError( 'apierror-mustbeloggedin-generic', 'login-required' ); } $params = $this->extractRequestParams(); $timestamp = wfTimestamp( TS_MW ); $seenTime = SeenTime::newFromUser( $user ); $seenTime->setTime( $timestamp, $params['type'] ); if ( $params['timestampFormat'] === 'ISO_8601' ) { $outputTimestamp = wfTimestamp( TS_ISO_8601, $timestamp ); } else { // MW $this->addDeprecation( 'apiwarn-echo-deprecation-timestampformat', 'action=echomarkseen×tampFormat=MW' ); $outputTimestamp = $timestamp; } $this->getResult()->addValue( 'query', $this->getModuleName(), [ 'result' => 'success', 'timestamp' => $outputTimestamp, ] ); } public function getAllowedParams() { return [ 'type' => [ ParamValidator::PARAM_REQUIRED => true, ParamValidator::PARAM_TYPE => [ 'alert', 'message', 'all' ], ], 'timestampFormat' => [ // Not using the TS constants, since clients can't. ParamValidator::PARAM_DEFAULT => 'MW', ParamValidator::PARAM_TYPE => [ 'ISO_8601', 'MW' ], ], ]; } /** * @see ApiBase::getExamplesMessages() * @return string[] */ protected function getExamplesMessages() { return [ 'action=echomarkseen&type=all' => 'apihelp-echomarkseen-example-1', ]; } public function getHelpUrls() { return 'https://www.mediawiki.org/wiki/Special:MyLanguage/Echo_(Notifications)/API'; } } PK ! ����� � ApiEchoMarkRead.phpnu �Iw�� <?php namespace MediaWiki\Extension\Notifications\Api; use MediaWiki\Api\ApiBase; use MediaWiki\Extension\Notifications\AttributeManager; use MediaWiki\Extension\Notifications\Controller\NotificationController; use MediaWiki\Extension\Notifications\DbFactory; use MediaWiki\Extension\Notifications\NotifUser; use MediaWiki\WikiMap\WikiMap; use Wikimedia\ParamValidator\ParamValidator; class ApiEchoMarkRead extends ApiBase { use ApiCrossWiki; public function execute() { // To avoid API warning, register the parameter used to bust browser cache $this->getMain()->getVal( '_' ); $user = $this->getUser(); if ( !$user->isRegistered() ) { $this->dieWithError( 'apierror-mustbeloggedin-generic', 'login-required' ); } elseif ( DbFactory::newFromDefault()->isReadOnly() ) { $this->dieReadOnly(); } $notifUser = NotifUser::newFromUser( $user ); $params = $this->extractRequestParams(); // Mark as read/unread locally, if requested if ( in_array( WikiMap::getCurrentWikiId(), $this->getRequestedWikis() ) ) { // There is no need to trigger markRead if all notifications are read if ( $notifUser->getLocalNotificationCount() > 0 ) { if ( $params['list'] ) { // Make sure there is a limit to the update $notifUser->markRead( array_slice( $params['list'], 0, ApiBase::LIMIT_SML2 ) ); // Mark all as read } elseif ( $params['all'] ) { $notifUser->markAllRead(); // Mark all as read for sections } elseif ( $params['sections'] ) { $notifUser->markAllRead( $params['sections'] ); } } // Mark as unread if ( $params['unreadlist'] !== null && $params['unreadlist'] !== [] ) { // Make sure there is a limit to the update $notifUser->markUnRead( array_slice( $params['unreadlist'], 0, ApiBase::LIMIT_SML2 ) ); } } $foreignResults = $this->getFromForeign(); $result = [ 'result' => 'success' ]; foreach ( $foreignResults as $wiki => $foreignResult ) { if ( isset( $foreignResult['error'] ) ) { $result['errors'][$wiki] = $foreignResult['error']; } } $rawCount = 0; foreach ( AttributeManager::$sections as $section ) { $rawSectionCount = $notifUser->getNotificationCount( $section ); $result[$section]['rawcount'] = $rawSectionCount; $result[$section]['count'] = NotificationController::formatNotificationCount( $rawSectionCount ); $rawCount += $rawSectionCount; } $result += [ 'rawcount' => $rawCount, 'count' => NotificationController::formatNotificationCount( $rawCount ), ]; $this->getResult()->addValue( 'query', $this->getModuleName(), $result ); } public function getAllowedParams() { return $this->getCrossWikiParams() + [ 'list' => [ ParamValidator::PARAM_ISMULTI => true, ], 'unreadlist' => [ ParamValidator::PARAM_ISMULTI => true, ], 'all' => [ ParamValidator::PARAM_REQUIRED => false, ParamValidator::PARAM_TYPE => 'boolean' ], 'sections' => [ ParamValidator::PARAM_TYPE => AttributeManager::$sections, ParamValidator::PARAM_ISMULTI => true, ], 'token' => [ ParamValidator::PARAM_REQUIRED => true, ] ]; } public function needsToken() { return 'csrf'; } public function mustBePosted() { return true; } public function isWriteMode() { return true; } /** * @see ApiBase::getExamplesMessages() * @return string[] */ protected function getExamplesMessages() { return [ 'action=echomarkread&list=8' => 'apihelp-echomarkread-example-1', 'action=echomarkread&all=true' => 'apihelp-echomarkread-example-2', 'action=echomarkread&unreadlist=1' => 'apihelp-echomarkread-example-3', ]; } public function getHelpUrls() { return 'https://www.mediawiki.org/wiki/Special:MyLanguage/Echo_(Notifications)/API'; } } PK ! �cz� � ApiEchoArticleReminder.phpnu �Iw�� <?php namespace MediaWiki\Extension\Notifications\Api; use DateInterval; use DateTime; use MediaWiki\Api\ApiBase; use MediaWiki\Extension\Notifications\Model\Event; use MediaWiki\Utils\MWTimestamp; use Wikimedia\ParamValidator\ParamValidator; class ApiEchoArticleReminder extends ApiBase { public function execute() { $this->getMain()->setCacheMode( 'private' ); $user = $this->getUser(); if ( !$user->isRegistered() ) { $this->dieWithError( 'apierror-mustbeloggedin-generic', 'login-required' ); } $params = $this->extractRequestParams(); $result = []; $userTimestamp = new MWTimestamp( $params['timestamp'] ); $nowTimestamp = new MWTimestamp(); // We need $params['timestamp'] to be a future timestamp: // $userTimestamp < $nowTimestamp = invert 0 // $userTimestamp > $nowTimestamp = invert 1 if ( $userTimestamp->diff( $nowTimestamp )->invert === 0 ) { $this->dieWithError( [ 'apierror-badparameter', 'timestamp' ], 'timestamp-not-in-future', null, 400 ); } $eventCreation = Event::create( [ 'type' => 'article-reminder', 'agent' => $user, 'title' => $this->getTitleFromTitleOrPageId( $params ), 'extra' => [ 'comment' => $params['comment'], ], ] ); if ( !$eventCreation ) { $this->dieWithError( 'apierror-echo-event-creation-failed', null, null, 500 ); } /* Temp - removing the delay just for now: $job = new JobSpecification( 'articleReminder', [ 'userId' => $user->getId(), 'timestamp' => $params['timestamp'], 'comment' => $params['comment'], ], [ 'removeDuplicates' => true ], Title::newFromID( $params['pageid'] ) ); MediaWikiServices::getInstance()->getJobQueueGroup()->push( $job );*/ $result += [ 'result' => 'success' ]; $this->getResult()->addValue( 'query', $this->getModuleName(), $result ); } public function getAllowedParams() { return [ 'pageid' => [ ParamValidator::PARAM_TYPE => 'integer', ], 'title' => [ ParamValidator::PARAM_TYPE => 'string', ], 'comment' => [ ParamValidator::PARAM_TYPE => 'string', ], 'timestamp' => [ ParamValidator::PARAM_REQUIRED => true, ParamValidator::PARAM_TYPE => 'timestamp', ], 'token' => [ ParamValidator::PARAM_REQUIRED => true, ], ]; } public function needsToken() { return 'csrf'; } public function mustBePosted() { return true; } public function isWriteMode() { return true; } /** * @see ApiBase::getExamplesMessages() * @return string[] */ protected function getExamplesMessages() { $todayDate = new DateTime(); $oneDay = new DateInterval( 'P1D' ); $tomorrowDate = $todayDate->add( $oneDay ); $tomorrowDateTimestamp = new MWTimestamp( $tomorrowDate ); $tomorrowTimestampStr = $tomorrowDateTimestamp->getTimestamp( TS_ISO_8601 ); return [ "action=echoarticlereminder&pageid=1×tamp=$tomorrowTimestampStr&comment=example" => 'apihelp-echoarticlereminder-example-1', "action=echoarticlereminder&title=Main_Page×tamp=$tomorrowTimestampStr" => 'apihelp-echoarticlereminder-example-2', ]; } public function getHelpUrls() { return 'https://www.mediawiki.org/wiki/Special:MyLanguage/Echo_(Notifications)/API'; } } PK ! Sj�s s "