Skip to content

Commit

Permalink
IBX-7057: Provided Channel Subscriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
webhdx committed Nov 15, 2023
1 parent fbe0a3f commit 57560b6
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Bundle\Notifications\DependencyInjection\Configuration\Parser;

use Ibexa\Bundle\Core\DependencyInjection\Configuration\AbstractParser;
use Ibexa\Bundle\Core\DependencyInjection\Configuration\SiteAccessAware\ContextualizerInterface;
use Symfony\Component\Config\Definition\Builder\NodeBuilder;

final class NotificationsConfigParser extends AbstractParser
{
public const MAPPED_SETTINGS = ['subscriptions'];

public function addSemanticConfig(NodeBuilder $nodeBuilder): void
{
$nodeBuilder
->arrayNode('notifications')
->children()
->arrayNode('subscriptions')
->info('Mandatory system notifications. Users cannot opt-out from below subscriptions.')
->useAttributeAsKey('notification_type')
->arrayPrototype()
->children()
->arrayNode('channels')
->cannotBeEmpty()
->scalarPrototype()->end()
->end()
->end()
->end()
->end()
->end()
->end();
}

/**
* @param array<string, array<string, mixed>> $scopeSettings
*/
public function mapConfig(array &$scopeSettings, $currentScope, ContextualizerInterface $contextualizer): void
{
if (empty($scopeSettings['notifications'])) {
return;
}

$settings = $scopeSettings['notifications'];

foreach (self::MAPPED_SETTINGS as $key) {
if (empty($settings[$key])) {
continue;
}

$contextualizer->setContextualParameter(
sprintf('notifications.%s', $key),
$currentScope,
$settings[$key]
);
}
}

/**
* @param array<string, mixed> $config
*/
public function postMap(array $config, ContextualizerInterface $contextualizer)
{
foreach (self::MAPPED_SETTINGS as $setting) {
$contextualizer->mapConfigArray(sprintf('notifications.%s', $setting), $config);
}
}
}
15 changes: 15 additions & 0 deletions src/bundle/Resources/config/services/subscription_resolver.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: false

Ibexa\Notifications\SubscriptionResolver\ConfigBasedSubscriptionResolver:
tags:
- ibexa.notifications.subscription_resolver

Ibexa\Notifications\SubscriptionResolver\ChainSubscriptionResolver:
arguments:
$resolvers: !tagged_iterator ibexa.notifications.subscription_resolver

Ibexa\Notifications\SubscriptionResolver\SubscriptionResolverInterface: '@Ibexa\Notifications\SubscriptionResolver\ChainSubscriptionResolver'
Empty file removed src/lib/.gitkeep
Empty file.
39 changes: 39 additions & 0 deletions src/lib/SubscriptionResolver/ChainSubscriptionResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Notifications\SubscriptionResolver;

use Ibexa\Contracts\Notifications\Value\NotificationInterface;

final class ChainSubscriptionResolver implements SubscriptionResolverInterface
{
/** @var iterable<\Ibexa\Notifications\SubscriptionResolver\SubscriptionResolverInterface> */
private iterable $resolvers;

/**
* @param iterable<\Ibexa\Notifications\SubscriptionResolver\SubscriptionResolverInterface> $resolvers
*/
public function __construct(iterable $resolvers)
{
$this->resolvers = $resolvers;
}

public function resolve(NotificationInterface $notification, array $context = []): iterable
{
foreach ($this->resolvers as $resolver) {
$channelSubscriptions = $resolver->resolve($notification, $context);
foreach ($channelSubscriptions as $channelSubscription) {
if (null === $channelSubscription) {
continue;
}

yield $channelSubscription;
}
}
}
}
37 changes: 37 additions & 0 deletions src/lib/SubscriptionResolver/ConfigBasedSubscriptionResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Notifications\SubscriptionResolver;

use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
use Ibexa\Contracts\Notifications\Value\NotificationInterface;
use Ibexa\Notifications\Value\ChannelSubscription;

final class ConfigBasedSubscriptionResolver implements SubscriptionResolverInterface
{
private ConfigResolverInterface $configResolver;

public function __construct(ConfigResolverInterface $configResolver)
{
$this->configResolver = $configResolver;
}

public function resolve(NotificationInterface $notification, array $context = []): iterable
{
$config = $this->configResolver->getParameter('notifications.subscriptions');
$notificationType = $notification->getType();

if (!array_key_exists($notificationType, $config)) {
yield;
}

foreach ($config[$notificationType]['channels'] as $channel) {
yield new ChannelSubscription($notificationType, $channel);
}
}
}
21 changes: 21 additions & 0 deletions src/lib/SubscriptionResolver/SubscriptionResolverInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Notifications\SubscriptionResolver;

use Ibexa\Contracts\Notifications\Value\NotificationInterface;

interface SubscriptionResolverInterface
{
/**
* @param array<string, mixed> $context
*
* @return \Iterator<\Ibexa\Notifications\Value\ChannelSubscription|null>
*/
public function resolve(NotificationInterface $notification, array $context = []): iterable;
}
32 changes: 32 additions & 0 deletions src/lib/Value/ChannelSubscription.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Notifications\Value;

final class ChannelSubscription
{
private string $notificationType;

private string $channel;

public function __construct(string $notificationType, string $channel)
{
$this->notificationType = $notificationType;
$this->channel = $channel;
}

public function getNotificationType(): string
{
return $this->notificationType;
}

public function getChannel(): string
{
return $this->channel;
}
}

0 comments on commit 57560b6

Please sign in to comment.