mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-11-23 15:36:58 +00:00
More specific type hints and type declarations
Most notably: * Use the much more narrow UserIdentity interface where possible. * Make array type hints in PHPDocs as specific as possible. Change-Id: Id189da4028b7874909277881dcf6539169dd13b6
This commit is contained in:
parent
40d6588415
commit
7e3d73c11b
|
@ -18,10 +18,8 @@ use Wikimedia\ParamValidator\ParamValidator;
|
|||
* - Optionally, override getForeignQueryParams() to customize what is sent to the foreign wikis
|
||||
*/
|
||||
trait ApiCrossWiki {
|
||||
/**
|
||||
* @var ForeignNotifications
|
||||
*/
|
||||
protected $foreignNotifications;
|
||||
|
||||
protected ?ForeignNotifications $foreignNotifications = null;
|
||||
|
||||
/**
|
||||
* This will take the current API call (with all of its params) and execute
|
||||
|
@ -73,7 +71,7 @@ trait ApiCrossWiki {
|
|||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getRequestedWikis() {
|
||||
protected function getRequestedWikis(): array {
|
||||
$params = $this->extractRequestParams();
|
||||
|
||||
// if wiki is omitted from params, that's because crosswiki is/was not
|
||||
|
@ -99,31 +97,26 @@ trait ApiCrossWiki {
|
|||
/**
|
||||
* @return string[] Wiki names
|
||||
*/
|
||||
protected function getRequestedForeignWikis() {
|
||||
protected function getRequestedForeignWikis(): array {
|
||||
return array_diff( $this->getRequestedWikis(), [ WikiMap::getCurrentWikiId() ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ForeignNotifications
|
||||
*/
|
||||
protected function getForeignNotifications() {
|
||||
if ( $this->foreignNotifications === null ) {
|
||||
$this->foreignNotifications = new ForeignNotifications( $this->getUser() );
|
||||
}
|
||||
protected function getForeignNotifications(): ForeignNotifications {
|
||||
$this->foreignNotifications ??= new ForeignNotifications( $this->getUser() );
|
||||
return $this->foreignNotifications;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Wiki names
|
||||
*/
|
||||
protected function getForeignWikisWithUnreadNotifications() {
|
||||
protected function getForeignWikisWithUnreadNotifications(): array {
|
||||
return $this->getForeignNotifications()->getWikis();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
*/
|
||||
public function getCrossWikiParams() {
|
||||
public function getCrossWikiParams(): array {
|
||||
global $wgConf;
|
||||
|
||||
$params = [];
|
||||
|
|
|
@ -18,6 +18,7 @@ use MediaWiki\Extension\Notifications\SeenTime;
|
|||
use MediaWiki\Extension\Notifications\Services;
|
||||
use MediaWiki\Title\Title;
|
||||
use MediaWiki\User\User;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
use MediaWiki\WikiMap\WikiMap;
|
||||
use Wikimedia\ParamValidator\ParamValidator;
|
||||
use Wikimedia\ParamValidator\TypeDef\IntegerDef;
|
||||
|
@ -343,12 +344,12 @@ class ApiEchoNotifications extends ApiQueryBase {
|
|||
|
||||
/**
|
||||
* Internal helper method for getting property 'count' data
|
||||
* @param User $user
|
||||
* @param UserIdentity $user
|
||||
* @param string[] $sections
|
||||
* @param bool $groupBySection
|
||||
* @return array
|
||||
*/
|
||||
protected function getPropCount( User $user, array $sections, $groupBySection ) {
|
||||
protected function getPropCount( UserIdentity $user, array $sections, $groupBySection ) {
|
||||
$result = [];
|
||||
$notifUser = NotifUser::newFromUser( $user );
|
||||
$global = $this->crossWikiSummary ? 'preference' : false;
|
||||
|
@ -370,12 +371,12 @@ class ApiEchoNotifications extends ApiQueryBase {
|
|||
|
||||
/**
|
||||
* Internal helper method for getting property 'seenTime' data
|
||||
* @param User $user
|
||||
* @param UserIdentity $user
|
||||
* @param string[] $sections
|
||||
* @param bool $groupBySection
|
||||
* @return array
|
||||
*/
|
||||
protected function getPropSeenTime( User $user, array $sections, $groupBySection ) {
|
||||
protected function getPropSeenTime( UserIdentity $user, array $sections, $groupBySection ) {
|
||||
$result = [];
|
||||
$seenTimeHelper = SeenTime::newFromUser( $user );
|
||||
|
||||
|
@ -649,10 +650,7 @@ class ApiEchoNotifications extends ApiQueryBase {
|
|||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ApiBase::getExamplesMessages()
|
||||
* @return array
|
||||
*/
|
||||
/** @inheritDoc */
|
||||
protected function getExamplesMessages() {
|
||||
return [
|
||||
'action=query&meta=notifications'
|
||||
|
|
|
@ -282,9 +282,9 @@ class AttributeManager {
|
|||
* Gets an associative array mapping categories to the notification types in
|
||||
* the category
|
||||
*
|
||||
* @return array[] Associative array with category as key
|
||||
* @return array<string,string[]> Associative array with category as key
|
||||
*/
|
||||
public function getEventsByCategory() {
|
||||
public function getEventsByCategory(): array {
|
||||
$eventsByCategory = [];
|
||||
|
||||
foreach ( $this->categories as $category => $categoryDetails ) {
|
||||
|
|
|
@ -481,7 +481,7 @@ class NotificationController {
|
|||
* Retrieves an array of User objects to be notified for an Event.
|
||||
*
|
||||
* @param Event $event
|
||||
* @return Iterator values are User objects
|
||||
* @return Iterator<User>
|
||||
*/
|
||||
public static function getUsersToNotifyForEvent( Event $event ) {
|
||||
$notify = new FilteredSequentialIterator;
|
||||
|
|
|
@ -11,6 +11,7 @@ use MediaWiki\Extension\Notifications\Model\Event;
|
|||
use MediaWiki\Extension\Notifications\Model\Notification;
|
||||
use MediaWiki\Revision\RevisionRecord;
|
||||
use MediaWiki\User\User;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
use MediaWiki\Utils\MWTimestamp;
|
||||
use MediaWiki\WikiMap\WikiMap;
|
||||
use RequestContext;
|
||||
|
@ -22,7 +23,7 @@ use RequestContext;
|
|||
class DataOutputFormatter {
|
||||
|
||||
/**
|
||||
* @var string[] type => class
|
||||
* @var array<string,class-string<EchoEventFormatter>> type => class
|
||||
*/
|
||||
protected static $formatters = [
|
||||
'flyout' => EchoFlyoutFormatter::class,
|
||||
|
@ -223,13 +224,13 @@ class DataOutputFormatter {
|
|||
/**
|
||||
* Helper function for converting UTC timezone to a user's timezone
|
||||
*
|
||||
* @param User $user
|
||||
* @param UserIdentity $user
|
||||
* @param string|int $ts
|
||||
* @param int $format output format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getUserLocalTime( User $user, $ts, $format = TS_MW ) {
|
||||
public static function getUserLocalTime( UserIdentity $user, $ts, $format = TS_MW ) {
|
||||
$timestamp = new MWTimestamp( $ts );
|
||||
$timestamp->offsetForUser( $user );
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ class ForeignNotifications {
|
|||
* @param string $section Name of section
|
||||
* @return string[]
|
||||
*/
|
||||
public function getWikis( $section = AttributeManager::ALL ) {
|
||||
public function getWikis( $section = AttributeManager::ALL ): array {
|
||||
$this->populate();
|
||||
|
||||
if ( $section === AttributeManager::ALL ) {
|
||||
|
@ -202,7 +202,7 @@ class ForeignNotifications {
|
|||
* @param string[] $wikis
|
||||
* @return array[] [(string) wiki => (array) data]
|
||||
*/
|
||||
public static function getApiEndpoints( array $wikis ) {
|
||||
public static function getApiEndpoints( array $wikis ): array {
|
||||
global $wgConf;
|
||||
$wgConf->loadFullData();
|
||||
|
||||
|
|
|
@ -22,11 +22,10 @@ class ForeignWikiRequest {
|
|||
/** @var User */
|
||||
protected $user;
|
||||
|
||||
/** @var array */
|
||||
protected $params;
|
||||
protected array $params;
|
||||
|
||||
/** @var array */
|
||||
protected $wikis;
|
||||
/** @var string[] */
|
||||
protected array $wikis;
|
||||
|
||||
/** @var string|null */
|
||||
protected $wikiParam;
|
||||
|
@ -43,7 +42,7 @@ class ForeignWikiRequest {
|
|||
/**
|
||||
* @param User $user
|
||||
* @param array $params Request parameters
|
||||
* @param array $wikis Wikis to send the request to
|
||||
* @param string[] $wikis Wikis to send the request to
|
||||
* @param string|null $wikiParam Parameter name to set to the name of the wiki
|
||||
* @param string|null $postToken If set, use POST requests and inject a token of this type;
|
||||
* if null, use GET requests.
|
||||
|
|
|
@ -12,6 +12,7 @@ use MediaWiki\Revision\RevisionRecord;
|
|||
use MediaWiki\SpecialPage\SpecialPage;
|
||||
use MediaWiki\Title\Title;
|
||||
use MediaWiki\User\User;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
use MediaWiki\WikiMap\WikiMap;
|
||||
use Message;
|
||||
use MessageLocalizer;
|
||||
|
@ -127,6 +128,7 @@ abstract class EchoEventPresentationModel implements JsonSerializable, MessageLo
|
|||
global $wgEchoNotifications;
|
||||
// @todo don't depend upon globals
|
||||
|
||||
/** @var class-string<EchoEventPresentationModel> $class */
|
||||
$class = $wgEchoNotifications[$event->getType()]['presentation-model'];
|
||||
return new $class( $event, $language, $user, $distributionType );
|
||||
}
|
||||
|
@ -562,10 +564,10 @@ abstract class EchoEventPresentationModel implements JsonSerializable, MessageLo
|
|||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param UserIdentity $user
|
||||
* @return string
|
||||
*/
|
||||
protected function getTruncatedUsername( User $user ) {
|
||||
protected function getTruncatedUsername( UserIdentity $user ) {
|
||||
return $this->language->embedBidi( $this->language->truncateForVisual(
|
||||
$user->getName(), self::USERNAME_RECOMMENDED_LENGTH, '...', false ) );
|
||||
}
|
||||
|
|
|
@ -43,7 +43,11 @@ class EchoForeignPresentationModel extends EchoEventPresentationModel {
|
|||
return $msg;
|
||||
}
|
||||
|
||||
protected function getWikiNames( array $wikis ) {
|
||||
/**
|
||||
* @param string[] $wikis
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getWikiNames( array $wikis ): array {
|
||||
$data = ForeignNotifications::getApiEndpoints( $wikis );
|
||||
$names = [];
|
||||
foreach ( $wikis as $wiki ) {
|
||||
|
|
|
@ -152,9 +152,9 @@ EOF;
|
|||
|
||||
/**
|
||||
* @param EchoEventPresentationModel[] $models
|
||||
* @return array [ 'category name' => EchoEventPresentationModel[] ]
|
||||
* @return array<string,EchoEventPresentationModel[]> [ 'category name' => EchoEventPresentationModel[] ]
|
||||
*/
|
||||
private function groupByCategory( array $models ) {
|
||||
private function groupByCategory( array $models ): array {
|
||||
$eventsByCategory = [];
|
||||
foreach ( $models as $model ) {
|
||||
$eventsByCategory[$model->getCategory()][] = $model;
|
||||
|
|
|
@ -11,7 +11,7 @@ class EchoModelFormatter extends EchoEventFormatter {
|
|||
* @param EchoEventPresentationModel $model
|
||||
* @return array
|
||||
*/
|
||||
protected function formatModel( EchoEventPresentationModel $model ) {
|
||||
protected function formatModel( EchoEventPresentationModel $model ): array {
|
||||
$data = $model->jsonSerialize();
|
||||
$data['iconUrl'] = EchoIcon::getUrl( $model->getIconType(), $this->language->getDir() );
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace MediaWiki\Extension\Notifications\Mapper;
|
|||
|
||||
use InvalidArgumentException;
|
||||
use MediaWiki\Extension\Notifications\Model\Event;
|
||||
use MediaWiki\User\User;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
|
||||
/**
|
||||
* Database mapper for Event model, which is an immutable class, there should
|
||||
|
@ -154,11 +154,11 @@ class EventMapper extends AbstractMapper {
|
|||
/**
|
||||
* Fetch events unread by a user and associated with a page
|
||||
*
|
||||
* @param User $user
|
||||
* @param UserIdentity $user
|
||||
* @param int $pageId
|
||||
* @return Event[]
|
||||
*/
|
||||
public function fetchUnreadByUserAndPage( User $user, $pageId ) {
|
||||
public function fetchUnreadByUserAndPage( UserIdentity $user, $pageId ) {
|
||||
$dbr = $this->dbFactory->getEchoDb( DB_REPLICA );
|
||||
$fields = array_merge( Event::selectFields(), [ 'notification_timestamp' ] );
|
||||
|
||||
|
|
|
@ -5,17 +5,17 @@ namespace MediaWiki\Extension\Notifications\Push;
|
|||
use MediaWiki\Extension\Notifications\Model\Event;
|
||||
use MediaWiki\Extension\Notifications\Services;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\User\User;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
|
||||
class PushNotifier {
|
||||
|
||||
/**
|
||||
* Submits a notification derived from an Echo event to each push notifications service
|
||||
* subscription found for a user, via a configured service handler implementation
|
||||
* @param User $user
|
||||
* @param UserIdentity $user
|
||||
* @param Event $event
|
||||
*/
|
||||
public static function notifyWithPush( User $user, Event $event ): void {
|
||||
public static function notifyWithPush( UserIdentity $user, Event $event ): void {
|
||||
$attributeManager = Services::getInstance()->getAttributeManager();
|
||||
$userEnabledEvents = $attributeManager->getUserEnabledEvents( $user, 'push' );
|
||||
if ( in_array( $event->getType(), $userEnabledEvents ) ) {
|
||||
|
@ -24,11 +24,11 @@ class PushNotifier {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param UserIdentity $user
|
||||
* @param Event|null $event
|
||||
* @return NotificationRequestJob
|
||||
*/
|
||||
private static function createJob( User $user, Event $event = null ): NotificationRequestJob {
|
||||
private static function createJob( UserIdentity $user, Event $event = null ): NotificationRequestJob {
|
||||
$centralId = Utils::getPushUserId( $user );
|
||||
$params = [ 'centralId' => $centralId ];
|
||||
// below params are only needed for debug logging (T255068)
|
||||
|
|
|
@ -89,9 +89,9 @@ class SubscriptionManager extends AbstractMapper {
|
|||
/**
|
||||
* Get full data for all registered subscriptions for a user (by central ID).
|
||||
* @param int $centralId
|
||||
* @return array array of Subscription objects
|
||||
* @return Subscription[]
|
||||
*/
|
||||
public function getSubscriptionsForUser( int $centralId ) {
|
||||
public function getSubscriptionsForUser( int $centralId ): array {
|
||||
$res = $this->dbr->newSelectQueryBuilder()
|
||||
->select( '*' )
|
||||
->from( 'echo_push_subscription' )
|
||||
|
|
|
@ -7,7 +7,7 @@ use CachedBagOStuff;
|
|||
use MediaWiki\Deferred\DeferredUpdates;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\User\CentralId\CentralIdLookup;
|
||||
use MediaWiki\User\User;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
use UnexpectedValueException;
|
||||
|
||||
/**
|
||||
|
@ -22,23 +22,16 @@ class SeenTime {
|
|||
*/
|
||||
private static $allowedTypes = [ 'alert', 'message' ];
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
private UserIdentity $user;
|
||||
|
||||
/**
|
||||
* @param User $user A logged in user
|
||||
* @param UserIdentity $user A logged in user
|
||||
*/
|
||||
private function __construct( User $user ) {
|
||||
private function __construct( UserIdentity $user ) {
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @return SeenTime
|
||||
*/
|
||||
public static function newFromUser( User $user ) {
|
||||
public static function newFromUser( UserIdentity $user ): self {
|
||||
return new self( $user );
|
||||
}
|
||||
|
||||
|
|
|
@ -4,23 +4,19 @@ namespace MediaWiki\Extension\Notifications;
|
|||
|
||||
use MediaWiki\Title\Title;
|
||||
use MediaWiki\User\User;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
|
||||
class SummaryParser {
|
||||
/** @var callable */
|
||||
private $userLookup;
|
||||
|
||||
/**
|
||||
* @param callable|null $userLookup Function that receives User object and returns its id
|
||||
* or 0 if the user doesn't exist. Passing null to this parameter will result in default
|
||||
* implementation being used.
|
||||
* @param callable|null $userLookup An alternative filter function that receives a User object
|
||||
* (see the caller in {@see parse}) and returns the user id or 0 if the user doesn't exist.
|
||||
* Only tests should modify this.
|
||||
*/
|
||||
public function __construct( callable $userLookup = null ) {
|
||||
$this->userLookup = $userLookup;
|
||||
if ( !$this->userLookup ) {
|
||||
$this->userLookup = static function ( User $user ) {
|
||||
return $user->getId();
|
||||
};
|
||||
}
|
||||
$this->userLookup = $userLookup ?? static fn ( UserIdentity $user ) => $user->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,8 +44,7 @@ class SummaryParser {
|
|||
&& $title->getNamespace() === NS_USER
|
||||
) {
|
||||
$user = User::newFromName( $title->getText() );
|
||||
$lookup = $this->userLookup;
|
||||
if ( $user && $lookup( $user ) > 0 ) {
|
||||
if ( $user && ( $this->userLookup )( $user ) > 0 ) {
|
||||
$users[$user->getName()] = $user;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ class SuppressionRowUpdateGenerator implements RowUpdateGenerator {
|
|||
* @param stdClass $row A row from the database
|
||||
* @return array All updates required for this row
|
||||
*/
|
||||
protected function updatePageIdFromTitle( $row ) {
|
||||
protected function updatePageIdFromTitle( $row ): array {
|
||||
$update = [];
|
||||
$title = $this->newTitleFromNsAndText( $row->event_page_namespace, $row->event_page_title );
|
||||
if ( $title !== null ) {
|
||||
|
@ -88,7 +88,7 @@ class SuppressionRowUpdateGenerator implements RowUpdateGenerator {
|
|||
*
|
||||
* @return array All updates required for this row
|
||||
*/
|
||||
protected function updatePageLinkedExtraData( $row, array $update ) {
|
||||
protected function updatePageLinkedExtraData( $row, array $update ): array {
|
||||
$extra = $this->extra( $row, $update );
|
||||
|
||||
if ( isset( $extra['link-from-title'] ) && isset( $extra['link-from-namespace'] ) ) {
|
||||
|
@ -115,7 +115,7 @@ class SuppressionRowUpdateGenerator implements RowUpdateGenerator {
|
|||
* @param array $update Updates that need to be applied to the database row
|
||||
* @return array The event extra data
|
||||
*/
|
||||
protected function extra( $row, array $update = [] ) {
|
||||
protected function extra( $row, array $update = [] ): array {
|
||||
if ( isset( $update['event_extra'] ) ) {
|
||||
return unserialize( $update['event_extra'] );
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ class UserLocator {
|
|||
*
|
||||
* @param Event $event
|
||||
* @param string[] $keys one or more keys to check for user ids
|
||||
* @return User[]
|
||||
* @return array<int,User>
|
||||
*/
|
||||
public static function locateFromEventExtra( Event $event, array $keys ) {
|
||||
$users = [];
|
||||
|
|
|
@ -66,9 +66,8 @@ class NotificationTest extends MediaWikiIntegrationTestCase {
|
|||
|
||||
/**
|
||||
* Mock a notification row from database
|
||||
* @return array
|
||||
*/
|
||||
protected function mockNotificationRow() {
|
||||
protected function mockNotificationRow(): array {
|
||||
return [
|
||||
'notification_user' => 1,
|
||||
'notification_event' => 1,
|
||||
|
@ -80,9 +79,8 @@ class NotificationTest extends MediaWikiIntegrationTestCase {
|
|||
|
||||
/**
|
||||
* Mock an event row from database
|
||||
* @return array
|
||||
*/
|
||||
protected function mockEventRow() {
|
||||
protected function mockEventRow(): array {
|
||||
return [
|
||||
'event_id' => 1,
|
||||
'event_type' => 'test_event',
|
||||
|
@ -97,9 +95,8 @@ class NotificationTest extends MediaWikiIntegrationTestCase {
|
|||
|
||||
/**
|
||||
* Mock a target page row
|
||||
* @return array
|
||||
*/
|
||||
protected function mockTargetPageRow() {
|
||||
protected function mockTargetPageRow(): array {
|
||||
return [
|
||||
'etp_page' => 2,
|
||||
'etp_event' => 1
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use MediaWiki\Extension\Notifications\Mapper\NotificationMapper;
|
||||
use MediaWiki\Extension\Notifications\Model\Event;
|
||||
use MediaWiki\User\User;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
|
||||
/**
|
||||
* Tests for the built in notification types
|
||||
|
@ -21,7 +22,7 @@ class NotificationsTest extends MediaWikiIntegrationTestCase {
|
|||
|
||||
/**
|
||||
* Helper function to get a user's latest notification
|
||||
* @param User $user
|
||||
* @param UserIdentity $user
|
||||
* @return Event
|
||||
*/
|
||||
public static function getLatestNotification( $user ) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use MediaWiki\Extension\Notifications\SummaryParser;
|
||||
use MediaWiki\User\User;
|
||||
use MediaWiki\User\UserIdentity;
|
||||
|
||||
/**
|
||||
* @group Echo
|
||||
|
@ -22,7 +23,7 @@ class SummaryParserTest extends MediaWikiIntegrationTestCase {
|
|||
* @param string[] $expectedUsers
|
||||
*/
|
||||
public function testParse( $summary, array $expectedUsers ) {
|
||||
$parser = new SummaryParser( function ( User $user ) {
|
||||
$parser = new SummaryParser( function ( UserIdentity $user ) {
|
||||
if ( in_array( $user->getName(), $this->existingUsers ) ) {
|
||||
return crc32( $user->getName() );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue