Commit fea34b4c authored by Samuel Hilson's avatar Samuel Hilson
Browse files

Delete folders that need renamed

parent 788f0aca
......@@ -26,19 +26,19 @@
},
"callback": "Reverb\\Hooks::registerExtension",
"AutoloadClasses": {
"Reverb\\Api\\ApiNotifications": "includes/api/ApiNotifications.php",
"Reverb\\Api\\ApiNotifications": "includes/Api/ApiNotifications.php",
"Reverb\\Hooks": "includes/Hooks.php",
"Reverb\\Identifier\\Identifier": "includes/identifier/Identifier.php",
"Reverb\\Identifier\\InvalidIdentifierException": "includes/identifier/InvalidIdentifierException.php",
"Reverb\\Identifier\\SiteIdentifier": "includes/identifier/SiteIdentifier.php",
"Reverb\\Identifier\\UserIdentifier": "includes/identifier/UserIdentifier.php",
"Reverb\\Notification\\Notification": "includes/notification/Notification.php",
"Reverb\\Notification\\NotificationBroadcast": "includes/notification/NotificationBroadcast.php",
"Reverb\\Notification\\NotificationBundle": "includes/notification/NotificationBundle.php",
"Reverb\\Notification\\NotificationEmail": "includes/notification/NotificationEmail.php",
"Reverb\\Special\\SpecialNotifications": "includes/special/SpecialNotifications.php",
"Reverb\\Traits\\NotificationListTrait": "includes/traits/NotificationListTrait.php",
"Reverb\\Traits\\UserContextTrait": "includes/traits/UserContextTrait.php",
"Reverb\\Identifier\\Identifier": "includes/Identifier/Identifier.php",
"Reverb\\Identifier\\InvalidIdentifierException": "includes/Identifier/InvalidIdentifierException.php",
"Reverb\\Identifier\\SiteIdentifier": "includes/Identifier/SiteIdentifier.php",
"Reverb\\Identifier\\UserIdentifier": "includes/Identifier/UserIdentifier.php",
"Reverb\\Notification\\Notification": "includes/Notification/Notification.php",
"Reverb\\Notification\\NotificationBroadcast": "includes/Notification/NotificationBroadcast.php",
"Reverb\\Notification\\NotificationBundle": "includes/Notification/NotificationBundle.php",
"Reverb\\Notification\\NotificationEmail": "includes/Notification/NotificationEmail.php",
"Reverb\\Special\\SpecialNotifications": "includes/Special/SpecialNotifications.php",
"Reverb\\Traits\\NotificationListTrait": "includes/Traits/NotificationListTrait.php",
"Reverb\\Traits\\UserContextTrait": "includes/Traits/UserContextTrait.php",
"Reverb\\TwiggyWiring": "includes/TwiggyWiring.php",
"Reverb\\UserIdHelper": "includes/UserIdHelper.php"
},
......
This diff is collapsed.
<?php
/**
* Reverb
* Service Wiring for Reverb
*
* @package Reverb
* @author Alexia E. Smith
* @license GPL-2.0-or-later
*/
declare(strict_types=1);
use Http\Discovery\HttpClientDiscovery;
use Http\Discovery\MessageFactoryDiscovery;
use Hydrawiki\Reverb\Client\V1\ClientFactory;
use MediaWiki\MediaWikiServices;
return [
'ReverbApiClient' => function (MediaWikiServices $services) {
$mainConfig = $services->getMainConfig();
$endPoint = $mainConfig->get('ReverbApiEndPoint');
$apiKey = $mainConfig->get('ReverbApiKey');
return (new ClientFactory)->make(
HttpClientDiscovery::find(),
MessageFactoryDiscovery::find(),
$endPoint,
$apiKey
);
}
];
<?php
/**
* Reverb
* Service Wiring for Twiggy
*
* @package Reverb
* @author Samuel Hilson
* @license GPL-2.0-or-later
*/
namespace Reverb;
use MediaWiki\MediaWikiServices;
use Twiggy\TwiggyService;
class TwiggyWiring {
/**
* Initialize Twiggy
*
* @return TwiggyService
*/
public static function init() {
$twig = MediaWikiServices::getInstance()->getService('TwiggyService');
$twig->setTemplateLocation('Reverb', __DIR__ . '/../resources/templates');
return $twig;
}
}
<?php
/**
* Reverb
* User ID Helper
*
* @package Reverb
* @author Alexia E. Smith
* @license MIT
*/
declare(strict_types=1);
namespace Reverb;
use User;
class UserIdHelper {
/**
* Get the user ID for this user in the Reverb service.
*
* @param User $user
*
* @return integer
*/
public static function getUserIdForService(User $user): int {
return $user->getId();
}
/**
* Get a local User object for this user ID in the Reverb service.
*
* @param integer $serviceUserId
*
* @return User|null
*/
public static function getUserForServiceUserId(int $serviceUserId): ?User {
return User::newFromId($serviceUserId);
}
}
<?php
/**
* Reverb
* Notifications API
*
* @package Reverb
* @author Alexia E. Smith
* @license GPL-2.0-or-later
*/
declare(strict_types=1);
namespace Reverb\Api;
use ApiBase;
use Hydrawiki\Reverb\Client\V1\Resources\NotificationDismissals as NotificationDismissalsResource;
use MediaWiki\MediaWikiServices;
use Reverb\Identifier\Identifier;
use Reverb\Notification\Notification;
use Reverb\Notification\NotificationBroadcast;
use Reverb\Notification\NotificationBundle;
use Reverb\UserIdHelper;
class ApiNotifications extends ApiBase {
/**
* Main API entry point.
*
* @return void
*/
public function execute() {
$this->params = $this->extractRequestParams();
if (!$this->getUser()->isLoggedIn()) {
$this->dieWithError(['apierror-permissiondenied-generic']);
}
switch ($this->params['do']) {
case 'getNotificationsForUser':
$response = $this->getNotificationsForUser();
break;
case 'dismissNotification':
$response = $this->dismissNotification();
break;
case 'dismissAllNotifications':
$response = $this->dismissAllNotifications();
break;
default:
$this->dieWithError(['invaliddo', $this->params['do']]);
break;
}
foreach ($response as $key => $value) {
$this->getResult()->addValue(null, $key, $value);
}
}
/**
* Get notifications for the current user.
*
* @return array
*/
public function getNotificationsForUser(): array {
$return = [
'notifications' => []
];
$filters = [];
if ($this->params['read'] === 1) {
$filters['read'] = 1;
}
if ($this->params['unread'] === 1) {
$filters['unread'] = 1;
}
if (!empty($this->params['type'])) {
$types = explode(',', $this->params['type']);
foreach ($types as $key => $type) {
if (!NotificationBroadcast::isTypeConfigured($type)) {
unset($types[$key]);
}
}
if (!empty($types)) {
$filters['type'] = implode(',', $types);
}
}
$bundle = NotificationBundle::getBundleForUser(
$this->getUser(),
$filters,
$this->params['itemsPerPage'],
$this->params['page']
);
if ($bundle !== null) {
foreach ($bundle as $key => $notification) {
$return['notifications'][] = $notification->toArray();
}
$return['meta'] = [
'unread' => $bundle->getUnreadCount(),
'read' => $bundle->getReadCount(),
'total_this_page' => $bundle->getTotalThisPage(),
'total_all' => $bundle->getTotalAll(),
'page' => $bundle->getPageNumber(),
'items_per_page' => $bundle->getItemsPerPage()
];
}
return $return;
}
/**
* Dismiss a notification based on ID.
*
* @return array
*/
public function dismissNotification(): array {
if (!$this->getRequest()->wasPosted()) {
$this->dieWithError(['apierror-mustbeposted', __FUNCTION__]);
}
$success = false;
$id = $this->params['notificationId'];
$timestamp = $this->params['dismissedAt'];
if ($timestamp === null) {
$timestamp = time();
}
if (!empty($id)) {
$success = Notification::dismissNotification($this->getUser(), (string)$id, $timestamp);
}
return [
'success' => $success
];
}
/**
* Dismiss a notification based on ID.
*
* @return array
*/
public function dismissAllNotifications(): array {
if (!$this->getRequest()->wasPosted()) {
$this->dieWithError(['apierror-mustbeposted', __FUNCTION__]);
}
$success = false;
$serviceUserId = UserIdHelper::getUserIdForService($this->getUser());
$userIdentifier = Identifier::newUser($serviceUserId);
$dismiss = new NotificationDismissalsResource(
[
'target-id' => (string)$userIdentifier
]
);
try {
$client = MediaWikiServices::getInstance()->getService('ReverbApiClient');
$response = $client->notification_dismissals()->create($dismiss);
$success = true;
} catch (ApiRequestUnsuccessful $e) {
wfLogWarning('Invalid API response from the service: ' . $e->getMessage());
} catch (Exception $e) {
wfLogWarning('General exception encountered when communicating with the service: ' . $e->getMessage());
}
return [
'success' => $success
];
}
/**
* Array of allowed parameters on the API request.
*
* @return array
*/
public function getAllowedParams() {
return [
'do' => [
ApiBase::PARAM_TYPE => 'string',
ApiBase::PARAM_REQUIRED => true
],
'page' => [
ApiBase::PARAM_TYPE => 'integer',
ApiBase::PARAM_REQUIRED => true,
ApiBase::PARAM_DFLT => 0
],
'itemsPerPage' => [
ApiBase::PARAM_TYPE => 'integer',
ApiBase::PARAM_REQUIRED => true,
ApiBase::PARAM_DFLT => 50
],
'type' => [
ApiBase::PARAM_TYPE => 'string',
ApiBase::PARAM_REQUIRED => false,
ApiBase::PARAM_DFLT => null
],
'read' => [
ApiBase::PARAM_TYPE => 'integer',
ApiBase::PARAM_REQUIRED => false,
ApiBase::PARAM_DFLT => null
],
'unread' => [
ApiBase::PARAM_TYPE => 'integer',
ApiBase::PARAM_REQUIRED => false,
ApiBase::PARAM_DFLT => null
],
'notificationId' => [
ApiBase::PARAM_TYPE => 'string',
ApiBase::PARAM_REQUIRED => false,
ApiBase::PARAM_DFLT => null
],
'dismissedAt' => [
ApiBase::PARAM_TYPE => 'integer',
ApiBase::PARAM_REQUIRED => false,
ApiBase::PARAM_DFLT => null
]
];
}
/**
* Get example URL parameters and help message key.
*
* @return string
*/
protected function getExamplesMessages() {
return [
'action=notifications&do=getNotificationsForUser&page=0&itemsPerPage=50'
=> 'apihelp-notifications-getNotificationsForUser-example',
'action=notifications&do=dismissNotification&notificationId=1&dismissedAt=1562006555'
=> 'apihelp-notifications-dismissNotification-example',
'action=notifications&do=dismissAllNotifications'
=> 'apihelp-notifications-dismissAllNotifications-example'
];
}
/**
* Destination URL of help information for this API.
*
* @return string
*/
public function getHelpUrls() {
return '';
}
}
<?php
/**
* Reverb
* Identifier
*
* @package Reverb
* @author Alexia E. Smith
* @license GPL-2.0-or-later
*/
declare(strict_types=1);
namespace Reverb\Identifier;
use DynamicSettings\Environment;
use MediaWiki\MediaWikiServices;
abstract class Identifier {
/**
* Namespace
*
* @var string
*/
protected $namespace = '';
/**
* What am I?(Type such as site, user.)
*
* @var string
*/
protected $what = '';
/**
* Unique ID
*
* @var string
*/
protected $who = '';
/**
* What/Type to class mapping.
*
* @var array
*/
private static $whatClassMap = [
'site' => 'Reverb\Identifier\SiteIdentifier',
'user' => 'Reverb\Identifier\UserIdentifier'
];
/**
* Get a new instance based on the identifier given.
*
* @param string|array $identifier String or array based identifier with namespace, what, and who.
*
* @return Identifier One of the Identifier children.
*
* @throws InvalidIdentifierException
*/
public static function factory($identifier): Identifier {
if (!is_array($identifier)) {
$idPieces = self::splitIdentifier($identifier);
} else {
$idPieces = $identifier;
}
if ($idPieces === null || !isset(self::$whatClassMap[$idPieces['what']])) {
throw new InvalidIdentifierException();
}
return new self::$whatClassMap[$idPieces['what']]((string)$idPieces['namespace'], (string)$idPieces['who']);
}
/**
* Return a factory response for an user identifier.
*
* @param mixed $who Unique identifier of the item.
*
* @return UserIdentifier
*/
public static function newUser($who): UserIdentifier {
$who = strval($who);
return self::factory(['namespace' => self::getConfiguredNamespace(), 'what' => 'user', 'who' => $who]);
}
/**
* Return a factory response for a site identifier.
*
* @param mixed $who Unique identifier of the item.
*
* @return SiteIdentifier
*/
public static function newSite($who): SiteIdentifier {
$who = strval($who);
return self::factory(['namespace' => self::getConfiguredNamespace(), 'what' => 'site', 'who' => $who]);
}
/**
* Return a factory response for a local site identifier.
*
* @return SiteIdentifier
*/
public static function newLocalSite(): SiteIdentifier {
$siteKey = Environment::getSiteKey();
if (empty($siteKey)) {
throw new MWException('Site key could not be detected.');
}
return self::factory(['namespace' => self::getConfiguredNamespace(), 'what' => 'site', 'who' => $siteKey]);
}
/**
* Split an identifier with all three parts into an array.
*
* @param string $identifier Raw parameter with unknown validity.
*
* @return array|null Array with ['namespace' => 'hydra', 'what' => 'hydra', 'id' => 'hydra'] or null if invalid.
*/
private static function splitIdentifier(string $identifier): ?array {
$regex = '#^([a-z]{1,64}):([a-z]{1,64}):([\w]{1,64})$#';
$matches = [];
if (preg_match($regex, $identifier, $matches) > 0) {
return [
'namespace' => $matches[1],
'what' => $matches[2],
'who' => $matches[3]
];
}
return null;
}
/**
* Main Constructor
*
* @param string $namespace Namespace
* @param string $who Unique ID
*
* @return void
*/
private function __construct(string $namespace, string $who) {
$this->namespace = $namespace;
$this->who = $who;
}
/**
* Return a concatenated version of the identifier.
*
* @return string
*/
public function __toString(): string {
return $this->whereIsHome() . ":" . $this->whatAmI() . ':' . $this->whoAmI();
}
/**
* Get the namespace for this identifier.
*
* @return string
*/
public function whereIsHome(): string {
return $this->namespace;
}
/**
* Return what kind of identifier this is such as 'user' or 'site'.
*
* @return string What kind of identifier am I?
*/
public function whatAmI(): string {
return $this->what;
}
/**
* Get the unique ID for this identifier.
*
* @return string
*/
public function whoAmI(): string {
return $this->who;
}
/**
* Did this notification originate from this place?
*
* @return boolean
*/
public function isLocal(): bool {
return $this->namespace === self::getConfiguredNamespace();
}
/**
* Get the namespace from $wgReverbNamespace.
*
* @return string
*/
public static function getConfiguredNamespace(): string {
$mainConfig = MediaWikiServices::getInstance()->getMainConfig();
return $mainConfig->get('ReverbNamespace');
}
}
<?php
/**
* Reverb
* InvalidIdentifierException
*
* @package Reverb
* @author Alexia E. Smith
* @license GPL-2.0-or-later
*/
declare(strict_types=1);
namespace Reverb\Identifier;
use Exception;
class InvalidIdentifierException extends Exception {
}
<?php
/**
* Reverb
* SiteIdentifier
*