PatchManager   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 128
Duplicated Lines 0 %

Test Coverage

Coverage 91.67%

Importance

Changes 0
Metric Value
eloc 31
c 0
b 0
f 0
dl 0
loc 128
ccs 33
cts 36
cp 0.9167
rs 10
wmc 16

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setEventDispatcherInterface() 0 3 1
A handleMany() 0 5 3
A handle() 0 4 1
A getMatchedOperations() 0 8 3
A dispatchEvents() 0 9 2
A doHandle() 0 7 1
A handleSubject() 0 10 4
1
<?php
2
3
namespace Cypress\PatchManager;
4
5
use Cypress\PatchManager\Event\PatchManagerEvent;
6
use Cypress\PatchManager\Event\PatchManagerEvents;
7
use Cypress\PatchManager\Exception\HandlerNotFoundException;
8
use PhpCollection\Sequence;
9
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
10
11
/**
12
 * The main entry point for the PatchManager bundle
13
 */
14
class PatchManager
15
{
16
    /**
17
     * @var OperationMatcher
18
     */
19
    private OperationMatcher $operationMatcher;
0 ignored issues
show
Coding Style introduced by
Private member variable "operationMatcher" must contain a leading underscore
Loading history...
20
21
    /**
22
     * @var EventDispatcherInterface
23
     */
24
    private EventDispatcherInterface $eventDispatcherInterface;
0 ignored issues
show
Coding Style introduced by
Private member variable "eventDispatcherInterface" must contain a leading underscore
Loading history...
25
26
    /**
27
     * @var bool
28
     */
29
    private bool $strictMode;
0 ignored issues
show
Coding Style introduced by
Private member variable "strictMode" must contain a leading underscore
Loading history...
30
31
    /**
32
     * @param OperationMatcher $operationMatcher
33
     * @param bool $strictMode if true throws an error if no handler is found
34
     */
35 4
    public function __construct(OperationMatcher $operationMatcher, bool $strictMode = false)
36
    {
37 4
        $this->operationMatcher = $operationMatcher;
38 4
        $this->strictMode = $strictMode;
39
    }
40
41
    /**
42
     * @param EventDispatcherInterface $eventDispatcherInterface
43
     */
44 4
    public function setEventDispatcherInterface(EventDispatcherInterface $eventDispatcherInterface): void
45
    {
46 4
        $this->eventDispatcherInterface = $eventDispatcherInterface;
47
    }
48
49
    /**
50
     * @param array<Patchable>|Patchable|\Traversable $subject a Patchable instance or a collection of instances
51
     * @throws Exception\InvalidJsonRequestContent
52
     * @throws Exception\MissingOperationNameRequest
53
     * @throws Exception\MissingOperationRequest
54
     * @throws HandlerNotFoundException
55
     */
56 4
    public function handle($subject): void
57
    {
58 4
        $matchedOperations = $this->getMatchedOperations($subject);
59 2
        $this->handleSubject($subject, $matchedOperations);
60
    }
61
62
    /**
63
     * @param MatchedPatchOperation $matchedPatchOperation
64
     * @param Patchable $subject
65
     */
66 2
    protected function doHandle(MatchedPatchOperation $matchedPatchOperation, Patchable $subject): void
67
    {
68 2
        $event = new PatchManagerEvent($matchedPatchOperation, $subject);
69 2
        $this->dispatchEvents($event, $matchedPatchOperation->getOpName(), PatchManagerEvents::PATCH_MANAGER_PRE);
70
71 2
        $matchedPatchOperation->process($subject);
72 2
        $this->dispatchEvents($event, $matchedPatchOperation->getOpName(), PatchManagerEvents::PATCH_MANAGER_POST);
73
    }
74
75
    /**
76
     * dispatch events if the eventDispatcher is present
77
     *
78
     * @param PatchManagerEvent $event
79
     * @param string $opName
80
     * @param string $type
81
     */
82 2
    protected function dispatchEvents(PatchManagerEvent $event, string $opName, string $type): void
83
    {
84 2
        if (!isset($this->eventDispatcherInterface)) {
85
            return;
86
        }
87 2
        $this->eventDispatcherInterface->dispatch($event, $type);
88 2
        $this->eventDispatcherInterface->dispatch(
89 2
            $event,
90 2
            sprintf('%s.%s', $type, $opName)
91 2
        );
92
    }
93
94
    /**
95
     * @param array|Patchable|\Traversable $subject a Patchable instance or a collection of instances
96
     * @throws Exception\InvalidJsonRequestContent
97
     * @throws Exception\MissingOperationNameRequest
98
     * @throws Exception\MissingOperationRequest
99
     * @throws HandlerNotFoundException
100
     * @return Sequence
101
     */
102 4
    private function getMatchedOperations($subject): Sequence
103
    {
104 4
        $matchedOperations = $this->operationMatcher->getMatchedOperations($subject);
105 4
        if ($this->strictMode && $matchedOperations->isEmpty()) {
106 2
            throw new HandlerNotFoundException($this->operationMatcher->getUnmatchedOperations($subject));
107
        }
108
109 2
        return $matchedOperations;
110
    }
111
112
    /**
113
     * @param array|Patchable|\Traversable $subject a Patchable instance or a collection of instances
114
     * @param Sequence $matchedOperations
115
     * @throws Exception\MissingOperationNameRequest
116
     * @throws Exception\MissingOperationRequest
117
     */
118 2
    private function handleSubject($subject, Sequence $matchedOperations): void
119
    {
120 2
        if (is_array($subject) || $subject instanceof \Traversable) {
121 2
            $this->handleMany($subject);
122
123 2
            return;
124
        }
125
126
        foreach ($matchedOperations as $matchedPatchOperation) {
127
            $this->doHandle($matchedPatchOperation, $subject);
128
        }
129
    }
130
131
    /**
132
     * @param array|\Traversable $subjects
133
     * @throws Exception\InvalidJsonRequestContent
134
     * @throws Exception\MissingOperationNameRequest
135
     * @throws Exception\MissingOperationRequest
136
     */
137 2
    private function handleMany($subjects): void
138
    {
139 2
        foreach ($subjects as $subject) {
140 2
            foreach ($this->operationMatcher->getMatchedOperations($subject) as $matchedPatchOperation) {
141 2
                $this->doHandle($matchedPatchOperation, $subject);
142
            }
143
        }
144
    }
145
}
146