Passed
Push — bump-dependencies ( b4f034...4ebfc0 )
by Mattia
12:55 queued 09:49
created

PatchManager::handleSubject()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.3332

Importance

Changes 0
Metric Value
cc 3
eloc 5
c 0
b 0
f 0
nc 3
nop 2
dl 0
loc 10
ccs 4
cts 6
cp 0.6667
crap 3.3332
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cypress\PatchManager;
6
7
use Cypress\PatchManager\Event\PatchManagerEvent;
8
use Cypress\PatchManager\Event\PatchManagerEvents;
9
use Cypress\PatchManager\Exception\HandlerNotFoundException;
10
use PhpCollection\Sequence;
11
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
12
13
/**
14
 * The main entry point for the PatchManager bundle
15
 */
16
class PatchManager
17
{
18
    private OperationMatcher $operationMatcher;
0 ignored issues
show
Coding Style introduced by
Private member variable "operationMatcher" must contain a leading underscore
Loading history...
19
20
    private EventDispatcherInterface $eventDispatcherInterface;
0 ignored issues
show
Coding Style introduced by
Private member variable "eventDispatcherInterface" must contain a leading underscore
Loading history...
21
22
    private bool $strictMode;
0 ignored issues
show
Coding Style introduced by
Private member variable "strictMode" must contain a leading underscore
Loading history...
23
24
    /**
25
     * @param OperationMatcher $operationMatcher
26
     * @param bool $strictMode if true throws an error if no handler is found
27
     */
28 4
    public function __construct(OperationMatcher $operationMatcher, bool $strictMode = false)
29
    {
30 4
        $this->operationMatcher = $operationMatcher;
31 4
        $this->strictMode = $strictMode;
32
    }
33
34 4
    public function setEventDispatcherInterface(EventDispatcherInterface $eventDispatcherInterface): void
35
    {
36 4
        $this->eventDispatcherInterface = $eventDispatcherInterface;
37
    }
38
39
    /**
40
     * @param array<Patchable>|Patchable|\Traversable $subject a Patchable instance or a collection of instances
41
     * @throws Exception\InvalidJsonRequestContent
42
     * @throws Exception\MissingOperationNameRequest
43
     * @throws Exception\MissingOperationRequest
44
     * @throws HandlerNotFoundException
45
     */
46 4
    public function handle($subject): void
47
    {
48 4
        $matchedOperations = $this->getMatchedOperations($subject);
49 2
        $this->handleSubject($subject, $matchedOperations);
50
    }
51
52 2
    protected function doHandle(MatchedPatchOperation $matchedPatchOperation, Patchable $subject): void
53
    {
54 2
        $event = new PatchManagerEvent($matchedPatchOperation, $subject);
55 2
        $this->dispatchEvents($event, $matchedPatchOperation->getOpName(), PatchManagerEvents::PATCH_MANAGER_PRE);
56
57 2
        $matchedPatchOperation->process($subject);
58 2
        $this->dispatchEvents($event, $matchedPatchOperation->getOpName(), PatchManagerEvents::PATCH_MANAGER_POST);
59
    }
60
61
    /**
62
     * dispatch events if the eventDispatcher is present
63
     */
64 2
    protected function dispatchEvents(PatchManagerEvent $event, string $opName, string $type): void
65
    {
66 2
        if (!isset($this->eventDispatcherInterface)) {
67
            return;
68
        }
69 2
        $this->eventDispatcherInterface->dispatch($event, $type);
70 2
        $this->eventDispatcherInterface->dispatch(
71 2
            $event,
72 2
            sprintf('%s.%s', $type, $opName)
73 2
        );
74
    }
75
76
    /**
77
     * @param array|Patchable|\Traversable $subject a Patchable instance or a collection of instances
78
     * @throws Exception\InvalidJsonRequestContent
79
     * @throws Exception\MissingOperationNameRequest
80
     * @throws Exception\MissingOperationRequest
81
     * @throws HandlerNotFoundException
82
     * @return Sequence
83
     */
84 4
    private function getMatchedOperations($subject): Sequence
85
    {
86 4
        $matchedOperations = $this->operationMatcher->getMatchedOperations($subject);
87 4
        if ($this->strictMode && $matchedOperations->isEmpty()) {
88 2
            throw new HandlerNotFoundException($this->operationMatcher->getUnmatchedOperations($subject));
89
        }
90
91 2
        return $matchedOperations;
92
    }
93
94
    /**
95
     * @param array<Patchable>|Patchable|\Traversable<Patchable> $subject a Patchable instance or a collection of instances
96
     * @throws Exception\MissingOperationNameRequest
97
     * @throws Exception\MissingOperationRequest
98
     * @throws Exception\InvalidJsonRequestContent
99
     */
100 2
    private function handleSubject($subject, Sequence $matchedOperations): void
101
    {
102 2
        if (is_iterable($subject)) {
103 2
            $this->handleMany($subject);
0 ignored issues
show
Bug introduced by
It seems like $subject can also be of type Cypress\PatchManager\Patchable; however, parameter $subjects of Cypress\PatchManager\PatchManager::handleMany() does only seem to accept Cypress\PatchManager\Patchable[]&Traversable, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

103
            $this->handleMany(/** @scrutinizer ignore-type */ $subject);
Loading history...
104
105 2
            return;
106
        }
107
108
        foreach ($matchedOperations as $matchedPatchOperation) {
109
            $this->doHandle($matchedPatchOperation, $subject);
110
        }
111
    }
112
113
    /**
114
     * @param array<Patchable>|\Traversable<Patchable> $subjects
115
     * @throws Exception\InvalidJsonRequestContent
116
     * @throws Exception\MissingOperationNameRequest
117
     * @throws Exception\MissingOperationRequest
118
     */
119 2
    private function handleMany($subjects): void
120
    {
121 2
        foreach ($subjects as $subject) {
122 2
            foreach ($this->operationMatcher->getMatchedOperations($subject) as $matchedPatchOperation) {
123 2
                $this->doHandle($matchedPatchOperation, $subject);
124
            }
125
        }
126
    }
127
}
128