mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-11-28 01:30:15 +00:00
Factor out cross-wiki API request code
Change-Id: Id926a607b99103d4489d1b734e00d104b7e80233
This commit is contained in:
parent
c83af257d2
commit
05e531c7b6
|
@ -57,6 +57,7 @@ $wgAutoloadClasses += [
|
|||
'EchoFlyoutFormatter' => __DIR__ . '/includes/formatters/EchoFlyoutFormatter.php',
|
||||
'EchoForeignNotifications' => __DIR__ . '/includes/ForeignNotifications.php',
|
||||
'EchoForeignPresentationModel' => __DIR__ . '/includes/formatters/EchoForeignPresentationModel.php',
|
||||
'EchoForeignWikiRequest' => __DIR__ . '/includes/ForeignWikiRequest.php',
|
||||
'EchoHTMLEmailDecorator' => __DIR__ . '/includes/EmailFormatter.php',
|
||||
'EchoHooks' => __DIR__ . '/Hooks.php',
|
||||
'EchoHtmlDigestEmailFormatter' => __DIR__ . '/includes/formatters/EchoHtmlDigestEmailFormatter.php',
|
||||
|
|
123
includes/ForeignWikiRequest.php
Normal file
123
includes/ForeignWikiRequest.php
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
|
||||
use MediaWiki\Logger\LoggerFactory;
|
||||
|
||||
class EchoForeignWikiRequest {
|
||||
|
||||
/**
|
||||
* @param User $user User object
|
||||
* @param array $params Request parameters
|
||||
* @param array $wikis Wikis to send the request to
|
||||
* @param string $wikiParam Parameter name to set to the name of the wiki
|
||||
*/
|
||||
public function __construct( User $user, array $params, array $wikis, $wikiParam = null ) {
|
||||
$this->user = $user;
|
||||
$this->params = $params;
|
||||
$this->wikis = $wikis;
|
||||
$this->wikiParam = $wikiParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the request
|
||||
* @return array [ wiki => result ]
|
||||
*/
|
||||
public function execute() {
|
||||
$reqs = $this->getRequestParams();
|
||||
return $this->doRequests( $reqs );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return string
|
||||
*/
|
||||
protected function getCentralAuthToken( User $user ) {
|
||||
$context = new RequestContext;
|
||||
$context->setRequest( new FauxRequest( array( 'action' => 'centralauthtoken' ) ) );
|
||||
$context->setUser( $user );
|
||||
|
||||
$api = new ApiMain( $context );
|
||||
$api->execute();
|
||||
|
||||
return $api->getResult()->getResultData( array( 'centralauthtoken', 'centralauthtoken' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getRequestParams() {
|
||||
$apis = EchoForeignNotifications::getApiEndpoints( $this->wikis );
|
||||
if ( !$apis ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$reqs = array();
|
||||
foreach ( $apis as $wiki => $api ) {
|
||||
$reqs[$wiki] = array(
|
||||
'method' => 'GET',
|
||||
'url' => $api['url'],
|
||||
'query' => $this->getQueryParams( $wiki ),
|
||||
);
|
||||
}
|
||||
|
||||
return $reqs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $wiki Wiki name
|
||||
* @return array
|
||||
*/
|
||||
protected function getQueryParams( $wiki ) {
|
||||
$extraParams = array();
|
||||
if ( $this->wikiParam ) {
|
||||
// Only request data from that specific wiki, or they'd all spawn
|
||||
// cross-wiki api requests...
|
||||
$extraParams[$this->wikiParam] = $wiki;
|
||||
}
|
||||
|
||||
return array(
|
||||
'centralauthtoken' => $this->getCentralAuthToken( $this->user ),
|
||||
// once all the results are gathered & merged, they'll be output in the
|
||||
// user requested format
|
||||
// but this is going to be an internal request & we don't want those
|
||||
// results in the format the user requested but in a fixed format that
|
||||
// we can interpret here
|
||||
'format' => 'json',
|
||||
) + $extraParams + $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $reqs API request params
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function doRequests( array $reqs ) {
|
||||
$http = new MultiHttpClient( array() );
|
||||
$responses = $http->runMulti( $reqs );
|
||||
|
||||
$results = array();
|
||||
foreach ( $responses as $wiki => $response ) {
|
||||
$statusCode = $response['response']['code'];
|
||||
|
||||
if ( $statusCode >= 200 && $statusCode <= 299 ) {
|
||||
$parsed = json_decode( $response['response']['body'], true );
|
||||
if ( $parsed ) {
|
||||
$results[$wiki] = $parsed;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isset( $results[$wiki] ) ) {
|
||||
LoggerFactory::getInstance( 'Echo' )->warning(
|
||||
'Failed to fetch API response from {wiki}. Error code {code}',
|
||||
array(
|
||||
'wiki' => $wiki,
|
||||
'code' => $response['response']['code'],
|
||||
'response' => $response['response']['body'],
|
||||
'request' => $reqs[$wiki],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
|
@ -27,9 +27,13 @@ abstract class ApiCrossWikiBase extends ApiQueryBase {
|
|||
* @throws Exception
|
||||
*/
|
||||
protected function getFromForeign() {
|
||||
$reqs = $this->getForeignRequestParams( $this->getRequestedForeignWikis() );
|
||||
|
||||
return $this->foreignRequests( $reqs );
|
||||
$foreignReq = new EchoForeignWikiRequest(
|
||||
$this->getUser(),
|
||||
$this->getRequest()->getValues(),
|
||||
$this->getRequestedForeignWikis(),
|
||||
$this->getModulePrefix() . 'wikis'
|
||||
);
|
||||
return $foreignReq->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,101 +88,6 @@ abstract class ApiCrossWikiBase extends ApiQueryBase {
|
|||
return $this->foreignNotifications->getWikis();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return string
|
||||
*/
|
||||
protected function getCentralAuthToken( User $user ) {
|
||||
$context = new RequestContext;
|
||||
$context->setRequest( new FauxRequest( array( 'action' => 'centralauthtoken' ) ) );
|
||||
$context->setUser( $user );
|
||||
|
||||
$api = new ApiMain( $context );
|
||||
$api->execute();
|
||||
|
||||
return $api->getResult()->getResultData( array( 'centralauthtoken', 'centralauthtoken' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $wikis Wiki names
|
||||
* @return array
|
||||
*/
|
||||
protected function getForeignRequestParams( array $wikis ) {
|
||||
$apis = $this->foreignNotifications->getApiEndpoints( $wikis );
|
||||
if ( !$apis ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$reqs = array();
|
||||
foreach ( $apis as $wiki => $api ) {
|
||||
$reqs[$wiki] = array(
|
||||
'method' => 'GET',
|
||||
'url' => $api['url'],
|
||||
'query' => $this->getForeignQueryParams( $wiki ),
|
||||
);
|
||||
}
|
||||
|
||||
return $reqs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $wiki Wiki name
|
||||
* @return array
|
||||
*/
|
||||
protected function getForeignQueryParams( $wiki ) {
|
||||
// use original request params, to forward them to individual wikis
|
||||
$params = $this->getRequest()->getValues();
|
||||
|
||||
return array(
|
||||
'centralauthtoken' => $this->getCentralAuthToken( $this->getUser() ),
|
||||
// once all the results are gathered & merged, they'll be output in the
|
||||
// user requested format
|
||||
// but this is going to be an internal request & we don't want those
|
||||
// results in the format the user requested but in a fixed format that
|
||||
// we can interpret here
|
||||
'format' => 'json',
|
||||
// Only request data from that specific wiki, or they'd all spawn
|
||||
// cross-wiki api requests...
|
||||
$this->getModulePrefix() . 'wikis' => $wiki,
|
||||
) + $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $reqs API request params
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function foreignRequests( array $reqs ) {
|
||||
$http = new MultiHttpClient( array() );
|
||||
$responses = $http->runMulti( $reqs );
|
||||
|
||||
$results = array();
|
||||
foreach ( $responses as $wiki => $response ) {
|
||||
$statusCode = $response['response']['code'];
|
||||
|
||||
if ( $statusCode >= 200 && $statusCode <= 299 ) {
|
||||
$parsed = json_decode( $response['response']['body'], true );
|
||||
if ( $parsed ) {
|
||||
$results[$wiki] = $parsed;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isset( $results[$wiki] ) ) {
|
||||
LoggerFactory::getInstance( 'Echo' )->warning(
|
||||
'Failed to fetch {module} from {wiki}. Response: {code} {response}',
|
||||
array(
|
||||
'module' => $this->getModuleName(),
|
||||
'wiki' => $wiki,
|
||||
'code' => $response['response']['code'],
|
||||
'response' => $response['response']['body'],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue