Passed
Push — master ( b0b60e...277995 )
by Dmitry
14:12 queued 07:36
created

BillingRegistryService::hasBehaviour()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace hiqdev\php\billing\product\Application;
4
5
use hiqdev\php\billing\product\AggregateInterface;
6
use hiqdev\php\billing\product\behavior\BehaviorInterface;
7
use hiqdev\php\billing\product\behavior\BehaviorNotFoundException;
8
use hiqdev\php\billing\product\behavior\InvalidBehaviorException;
9
use hiqdev\php\billing\product\BillingRegistryInterface;
10
use hiqdev\php\billing\product\Exception\AggregateNotFoundException;
11
use hiqdev\php\billing\product\Exception\TariffTypeDefinitionNotFoundException;
12
use hiqdev\php\billing\product\invoice\InvalidRepresentationException;
13
use hiqdev\php\billing\product\invoice\RepresentationInterface;
14
use hiqdev\php\billing\product\price\PriceTypeDefinitionInterface;
15
use hiqdev\php\billing\product\quantity\FractionQuantityData;
16
use hiqdev\php\billing\product\quantity\QuantityFormatterInterface;
17
use hiqdev\php\billing\product\quantity\QuantityFormatterNotFoundException;
18
use hiqdev\php\billing\product\TariffTypeDefinitionInterface;
19
use hiqdev\php\billing\type\Type;
20
use hiqdev\php\billing\type\TypeInterface;
0 ignored issues
show
Bug introduced by
The type hiqdev\php\billing\type\TypeInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
22
final class BillingRegistryService implements BillingRegistryServiceInterface
23
{
24
    public function __construct(private readonly BillingRegistryInterface $registry)
25
    {
26
    }
27
28
    public function getRepresentationsByType(string $representationClass): array
29
    {
30
        if (!class_exists($representationClass) && !interface_exists($representationClass)) {
31
            throw new InvalidRepresentationException("Class '$representationClass' does not exist");
32
        }
33
34
        if (class_exists($representationClass) && !is_subclass_of($representationClass, RepresentationInterface::class)) {
35
            throw new InvalidBehaviorException(
36
                sprintf('Representation class "%s" does not implement RepresentationInterface', $representationClass)
37
            );
38
        }
39
40
        $representations = [];
41
        foreach ($this->registry->priceTypes() as $priceTypeDefinition) {
42
            foreach ($priceTypeDefinition->documentRepresentation() as $representation) {
43
                if ($representation instanceof $representationClass) {
44
                    $representations[] = $representation;
45
                }
46
            }
47
        }
48
49
        return $representations;
50
    }
51
52
    public function getTariffDefinitionByName(string $tariffName): ?TariffTypeDefinitionInterface
53
    {
54
        foreach ($this->registry->getTariffTypeDefinitions() as $tariffTypeDefinition) {
55
            if ($tariffName === $tariffTypeDefinition->tariffType()->name) {
0 ignored issues
show
Bug introduced by
Accessing name on the interface hiqdev\php\billing\produ...del\TariffTypeInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
56
                return $tariffTypeDefinition;
57
            }
58
        }
59
        return null;
60
    }
61
62
    public function hasBehaviour(TariffTypeDefinitionInterface $tariffTypeDefinition, string $behaviorClassWrapper): bool
63
    {
64
        return $tariffTypeDefinition->hasBehavior($behaviorClassWrapper);
65
    }
66
67
    public function createQuantityFormatter(string $type, FractionQuantityData $data): QuantityFormatterInterface {
68
        $type = $this->convertStringTypeToType($type);
69
70
        foreach ($this->registry->priceTypes() as $priceTypeDefinition) {
71
            if ($priceTypeDefinition->hasType($type)) {
72
                return $priceTypeDefinition->createQuantityFormatter($data);
73
            }
74
        }
75
76
        throw new QuantityFormatterNotFoundException('Quantity formatter not found');
77
    }
78
79
    private function convertStringTypeToType(string $type): TypeInterface
80
    {
81
        return Type::anyId($type);
82
    }
83
84
    public function getBehavior(string $type, string $behaviorClassWrapper): BehaviorInterface
85
    {
86
        if (!class_exists($behaviorClassWrapper)) {
87
            throw new InvalidBehaviorException(
88
                sprintf('Behavior class "%s" does not exist', $behaviorClassWrapper)
89
            );
90
        }
91
92
        if (!is_subclass_of($behaviorClassWrapper, BehaviorInterface::class)) {
93
            throw new InvalidBehaviorException(
94
                sprintf('Behavior class "%s" does not implement BehaviorInterface', $behaviorClassWrapper)
95
            );
96
        }
97
98
        $billingType = $this->convertStringTypeToType($type);
99
100
        foreach ($this->registry->priceTypes() as $priceTypeDefinition) {
101
            if ($priceTypeDefinition->hasType($billingType)) {
102
                $behavior = $this->findBehaviorInPriceType($priceTypeDefinition, $behaviorClassWrapper);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $behavior is correct as $this->findBehaviorInPri... $behaviorClassWrapper) targeting hiqdev\php\billing\produ...ndBehaviorInPriceType() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
103
104
                if ($behavior) {
105
                    return $behavior;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $behavior returns the type void which is incompatible with the type-hinted return hiqdev\php\billing\produ...avior\BehaviorInterface.
Loading history...
106
                }
107
            }
108
        }
109
110
        throw new BehaviorNotFoundException(
111
            sprintf('Behavior of class "%s" not found for type "%s"', $behaviorClassWrapper, $type),
112
        );
113
    }
114
115
    private function findBehaviorInPriceType(
116
        PriceTypeDefinitionInterface $priceTypeDefinition,
117
        string $behaviorClassWrapper
118
    ): ?BehaviorInterface {
119
        foreach ($priceTypeDefinition->withBehaviors() as $behavior) {
120
            if ($behavior instanceof $behaviorClassWrapper) {
121
                return $behavior;
122
            }
123
        }
124
125
        return null;
126
    }
127
128
    public function getBehaviors(string $behaviorClassWrapper): \Generator
129
    {
130
        foreach ($this->registry->getTariffTypeDefinitions() as $tariffTypeDefinition) {
131
            foreach ($tariffTypeDefinition->withBehaviors() as $behavior) {
132
                if ($behavior instanceof $behaviorClassWrapper) {
133
                    yield $behavior;
134
                }
135
            }
136
        }
137
138
        foreach ($this->registry->priceTypes() as $priceTypeDefinition) {
139
            foreach ($priceTypeDefinition->withBehaviors() as $behavior) {
140
                if ($behavior instanceof $behaviorClassWrapper) {
141
                    yield $behavior;
142
                }
143
            }
144
        }
145
    }
146
147
    public function getAggregate(string $type): AggregateInterface
148
    {
149
        $type = $this->convertStringTypeToType($type);
150
151
        foreach ($this->registry->priceTypes() as $priceTypeDefinition) {
152
            if ($priceTypeDefinition->hasType($type)) {
153
                return $priceTypeDefinition->getAggregate();
154
            }
155
        }
156
157
        throw new AggregateNotFoundException('Aggregate was not found');
158
    }
159
160
    public function findTariffTypeDefinitionByBehavior(BehaviorInterface $behavior): TariffTypeDefinitionInterface
161
    {
162
        $tariffType = $behavior->getTariffType();
163
164
        foreach ($this->registry->getTariffTypeDefinitions() as $tariffTypeDefinition) {
165
            if ($tariffTypeDefinition->belongToTariffType($tariffType)) {
166
                return $tariffTypeDefinition;
167
            }
168
        }
169
170
        throw new TariffTypeDefinitionNotFoundException('Tariff type definition was not found');
171
    }
172
173
    public function findPriceTypeDefinitionsByBehavior(string $behaviorClassWrapper): \Generator
174
    {
175
        foreach ($this->registry->priceTypes() as $priceTypeDefinition) {
176
            if ($priceTypeDefinition->hasBehavior($behaviorClassWrapper)) {
177
                yield $priceTypeDefinition;
178
            }
179
        }
180
    }
181
}
182