AbstractNotificationStrategy   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 4
dl 0
loc 79
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A addNotificationMessageGenerator() 0 18 2
A canHandleNotification() 0 5 2
A generateNotificationMessage() 0 11 2
A getNotificationName() 0 4 1
A hasGeneratorForNotification() 0 4 1
A isAllowedForNotification() 0 16 3
A getStrategyDefinitionForNotification() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Explicit Architecture POC,
7
 * which is created on top of the Symfony Demo application.
8
 *
9
 * (c) Herberto Graça <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Acme\App\Infrastructure\Notification\Strategy;
16
17
use Acme\App\Core\Port\Notification\NotificationInterface;
18
use Acme\App\Infrastructure\Notification\StrategyDefinition;
19
use Acme\PhpExtension\Helper\TypeHelper;
20
21
/**
22
 * @author Herberto Graca <[email protected]>
23
 * @author Nicolae Nichifor
24
 */
25
abstract class AbstractNotificationStrategy implements NotificationStrategyInterface
26
{
27
    /**
28
     * @var [
29
     *      '$notificationName' => StrategyDefinition,
30
     *      ...
31
     *  ]
32
     */
33
    private $notificationGeneratorList = [];
34
35
    public function addNotificationMessageGenerator(
36
        $generator,
37
        string $notificationName,
38
        string $generatorMethodName,
39
        $voter = null,
40
        ?string $voterMethodName = null
41
    ): void {
42
        if (!method_exists($generator, $generatorMethodName)) {
43
            throw new InvalidGeneratorException(\get_class($generator), $generatorMethodName);
44
        }
45
46
        $this->notificationGeneratorList[$notificationName] = new StrategyDefinition(
47
            $generator,
48
            $generatorMethodName,
49
            $voter,
50
            $voterMethodName
51
        );
52
    }
53
54
    public function canHandleNotification(NotificationInterface $notification): bool
55
    {
56
        return $this->hasGeneratorForNotification($notification)
57
            && $this->isAllowedForNotification($notification);
58
    }
59
60
    protected function generateNotificationMessage(NotificationInterface $notification)
61
    {
62
        if (!$this->canHandleNotification($notification)) {
63
            throw new UnprocessableNotificationException($this->getNotificationName($notification), self::class);
64
        }
65
66
        $generator = $this->getStrategyDefinitionForNotification($notification)->getGenerator();
67
        $generatorMethodName = $this->getStrategyDefinitionForNotification($notification)->getGeneratorMethod();
68
69
        return $generator->$generatorMethodName($notification);
70
    }
71
72
    private function getNotificationName(NotificationInterface $notification): string
73
    {
74
        return \get_class($notification);
75
    }
76
77
    private function hasGeneratorForNotification(NotificationInterface $notification): bool
78
    {
79
        return array_key_exists($this->getNotificationName($notification), $this->notificationGeneratorList);
80
    }
81
82
    private function isAllowedForNotification(NotificationInterface $notification): bool
83
    {
84
        $strategyDefinition = $this->getStrategyDefinitionForNotification($notification);
85
        if (!$strategyDefinition->hasVoter()) {
86
            return true;
87
        }
88
89
        $voter = $strategyDefinition->getVoter();
90
        $voterMethod = $strategyDefinition->getVoterMethod();
91
92
        if (!method_exists($voter, $voterMethod)) {
93
            throw new InvalidVoterException(TypeHelper::getType($voter), $voterMethod);
94
        }
95
96
        return $voter->$voterMethod($notification);
97
    }
98
99
    private function getStrategyDefinitionForNotification(NotificationInterface $notification): StrategyDefinition
100
    {
101
        return $this->notificationGeneratorList[$this->getNotificationName($notification)];
102
    }
103
}
104