2016-05-26 20:41:25 +00:00
|
|
|
<?php
|
2019-03-11 13:25:18 +00:00
|
|
|
// @phan-file-suppress PhanUndeclaredMethod This is a trait, and phan is confused by $this
|
2022-04-03 23:26:22 +00:00
|
|
|
use Wikimedia\ParamValidator\ParamValidator;
|
|
|
|
|
2018-08-30 01:03:16 +00:00
|
|
|
/**
|
|
|
|
* 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 {
|
2016-05-26 20:41:25 +00:00
|
|
|
/**
|
|
|
|
* @var EchoForeignNotifications
|
|
|
|
*/
|
|
|
|
protected $foreignNotifications;
|
|
|
|
|
|
|
|
/**
|
2018-08-30 01:03:16 +00:00
|
|
|
* This will take the current API call (with all of its params) and execute
|
2016-05-26 20:41:25 +00:00
|
|
|
* it on all foreign wikis, returning an array of results per wiki.
|
|
|
|
*
|
2018-05-26 02:15:41 +00:00
|
|
|
* @param array|null $wikis List of wikis to query. Defaults to the result of getRequestedForeignWikis().
|
2016-05-29 20:54:15 +00:00
|
|
|
* @param array $paramOverrides Request parameter overrides
|
2018-08-13 07:25:22 +00:00
|
|
|
* @return array[]
|
2016-05-26 20:41:25 +00:00
|
|
|
* @throws Exception
|
|
|
|
*/
|
2019-10-23 10:44:35 +00:00
|
|
|
protected function getFromForeign( array $wikis = null, array $paramOverrides = [] ) {
|
2018-08-30 01:03:16 +00:00
|
|
|
$wikis = $wikis ?? $this->getRequestedForeignWikis();
|
|
|
|
if ( $wikis === [] ) {
|
|
|
|
return [];
|
|
|
|
}
|
2018-09-18 21:10:45 +00:00
|
|
|
$tokenType = $this->needsToken();
|
2016-06-08 20:30:51 +00:00
|
|
|
$foreignReq = new EchoForeignWikiRequest(
|
|
|
|
$this->getUser(),
|
2016-05-29 20:54:15 +00:00
|
|
|
$paramOverrides + $this->getForeignQueryParams(),
|
2019-05-19 11:14:05 +00:00
|
|
|
$wikis,
|
2018-08-30 00:30:06 +00:00
|
|
|
$this->getModulePrefix() . 'wikis',
|
2018-09-18 21:10:45 +00:00
|
|
|
$tokenType !== false ? $tokenType : null
|
2016-06-08 20:30:51 +00:00
|
|
|
);
|
|
|
|
return $foreignReq->execute();
|
2016-05-26 20:41:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-06-15 22:39:07 +00:00
|
|
|
* Get the query parameters to use for the foreign API requests.
|
2018-08-30 01:03:16 +00:00
|
|
|
* Implementing classes should override this if they need to customize
|
|
|
|
* the parameters.
|
2016-06-15 22:39:07 +00:00
|
|
|
* @return array Query parameters
|
|
|
|
*/
|
|
|
|
protected function getForeignQueryParams() {
|
|
|
|
return $this->getRequest()->getValues();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-05-26 20:41:25 +00:00
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
protected function allowCrossWikiNotifications() {
|
|
|
|
global $wgEchoCrossWikiNotifications;
|
|
|
|
return $wgEchoCrossWikiNotifications;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-05-27 21:10:04 +00:00
|
|
|
* 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
|
|
|
|
*
|
2018-08-13 07:25:22 +00:00
|
|
|
* @return string[]
|
2016-05-26 20:41:25 +00:00
|
|
|
*/
|
2016-05-27 21:10:04 +00:00
|
|
|
protected function getRequestedWikis() {
|
|
|
|
$params = $this->extractRequestParams();
|
|
|
|
|
|
|
|
// if wiki is omitted from params, that's because crosswiki is/was not
|
|
|
|
// available, and it'll default to current wiki
|
2021-12-21 00:47:31 +00:00
|
|
|
$wikis = $params['wikis'] ?? [ WikiMap::getCurrentWikiId() ];
|
2016-05-27 21:10:04 +00:00
|
|
|
|
|
|
|
if ( array_search( '*', $wikis ) !== false ) {
|
|
|
|
// expand `*` to all foreign wikis with unread notifications + local
|
|
|
|
$wikis = array_merge(
|
2021-12-21 00:47:31 +00:00
|
|
|
[ WikiMap::getCurrentWikiId() ],
|
2016-05-27 21:10:04 +00:00
|
|
|
$this->getForeignWikisWithUnreadNotifications()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-05-26 20:41:25 +00:00
|
|
|
if ( !$this->allowCrossWikiNotifications() ) {
|
2016-05-27 21:10:04 +00:00
|
|
|
// exclude foreign wikis if x-wiki is not enabled
|
2021-12-21 00:47:31 +00:00
|
|
|
$wikis = array_intersect_key( [ WikiMap::getCurrentWikiId() ], $wikis );
|
2016-05-26 20:41:25 +00:00
|
|
|
}
|
|
|
|
|
2016-05-27 21:10:04 +00:00
|
|
|
return $wikis;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-08-13 07:25:22 +00:00
|
|
|
* @return string[] Wiki names
|
2016-05-27 21:10:04 +00:00
|
|
|
*/
|
|
|
|
protected function getRequestedForeignWikis() {
|
2021-12-21 00:47:31 +00:00
|
|
|
return array_diff( $this->getRequestedWikis(), [ WikiMap::getCurrentWikiId() ] );
|
2016-05-27 21:10:04 +00:00
|
|
|
}
|
|
|
|
|
2018-08-30 01:03:16 +00:00
|
|
|
/**
|
|
|
|
* @return EchoForeignNotifications
|
|
|
|
*/
|
|
|
|
protected function getForeignNotifications() {
|
|
|
|
if ( $this->foreignNotifications === null ) {
|
|
|
|
$this->foreignNotifications = new EchoForeignNotifications( $this->getUser() );
|
|
|
|
}
|
|
|
|
return $this->foreignNotifications;
|
|
|
|
}
|
|
|
|
|
2016-05-27 21:10:04 +00:00
|
|
|
/**
|
2018-08-13 07:25:22 +00:00
|
|
|
* @return string[] Wiki names
|
2016-05-27 21:10:04 +00:00
|
|
|
*/
|
|
|
|
protected function getForeignWikisWithUnreadNotifications() {
|
2018-08-30 01:03:16 +00:00
|
|
|
return $this->getForeignNotifications()->getWikis();
|
2016-05-26 20:41:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-08-13 07:25:22 +00:00
|
|
|
* @return array[]
|
2016-05-26 20:41:25 +00:00
|
|
|
*/
|
2018-08-30 01:03:16 +00:00
|
|
|
public function getCrossWikiParams() {
|
2016-05-26 20:41:25 +00:00
|
|
|
global $wgConf;
|
|
|
|
|
2016-12-05 18:51:07 +00:00
|
|
|
$params = [];
|
2016-05-26 20:41:25 +00:00
|
|
|
|
|
|
|
if ( $this->allowCrossWikiNotifications() ) {
|
2016-12-05 18:51:07 +00:00
|
|
|
$params += [
|
2016-05-26 20:41:25 +00:00
|
|
|
// fetch notifications from multiple wikis
|
2016-12-05 18:51:07 +00:00
|
|
|
'wikis' => [
|
2022-04-03 23:26:22 +00:00
|
|
|
ParamValidator::PARAM_ISMULTI => true,
|
|
|
|
ParamValidator::PARAM_DEFAULT => WikiMap::getCurrentWikiId(),
|
2016-05-27 21:10:04 +00:00
|
|
|
// `*` will let you immediately fetch from all wikis that have
|
|
|
|
// unread notifications, without having to look them up first
|
2022-04-03 23:26:22 +00:00
|
|
|
ParamValidator::PARAM_TYPE => array_unique(
|
2021-12-21 00:47:31 +00:00
|
|
|
array_merge(
|
|
|
|
$wgConf->wikis,
|
|
|
|
[ WikiMap::getCurrentWikiId(), '*' ]
|
|
|
|
)
|
|
|
|
),
|
2016-12-05 18:51:07 +00:00
|
|
|
],
|
|
|
|
];
|
2016-05-26 20:41:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $params;
|
|
|
|
}
|
|
|
|
}
|