BillingRegistryService::getBehaviors()   B
last analyzed

Complexity

Conditions 7
Paths 16

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 8
c 1
b 0
f 0
nc 16
nop 1
dl 0
loc 14
rs 8.8333
1
<?php declare(strict_types=1);
2
3
namespace hiqdev\php\billing\product\Application;
4
5
use Generator;
6
use hiqdev\php\billing\product\AggregateInterface;
7
use hiqdev\php\billing\product\behavior\BehaviorInterface;
8
use hiqdev\php\billing\product\behavior\BehaviorNotFoundException;
9
use hiqdev\php\billing\product\behavior\InvalidBehaviorException;
10
use hiqdev\php\billing\product\BillingRegistryInterface;
11
use hiqdev\php\billing\product\Exception\PriceTypeDefinitionNotFoundException;
12
use hiqdev\php\billing\product\Exception\TariffTypeDefinitionNotFoundException;
13
use hiqdev\php\billing\product\invoice\InvalidRepresentationException;
14
use hiqdev\php\billing\product\invoice\RepresentationInterface;
15
use hiqdev\php\billing\product\price\PriceTypeDefinitionInterface;
16
use hiqdev\php\billing\product\TariffTypeDefinitionInterface;
17
use hiqdev\php\billing\type\Type;
18
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...
19
20
final class BillingRegistryService implements BillingRegistryServiceInterface
21
{
22
    public function __construct(private readonly BillingRegistryInterface $registry)
23
    {
24
    }
25
26
    public function getRepresentationsByType(string $representationClass): array
27
    {
28
        if (!class_exists($representationClass) && !interface_exists($representationClass)) {
29
            throw InvalidRepresentationException::make("Representation does not exist", [
30
                'representationClass' => $representationClass,
31
            ]);
32
        }
33
34
        if (class_exists($representationClass)
35
            && !is_subclass_of($representationClass, RepresentationInterface::class)
36
        ) {
37
            throw InvalidBehaviorException::make('Representation class does not implement RepresentationInterface', [
38
                    'representationClass' => $representationClass,
39
                ]
40
            );
41
        }
42
43
        $representations = [];
44
        foreach ($this->registry->priceTypes() as $priceTypeDefinition) {
45
            foreach ($priceTypeDefinition->documentRepresentation() as $representation) {
46
                if ($representation instanceof $representationClass) {
47
                    $representations[] = $representation;
48
                }
49
            }
50
        }
51
52
        return $representations;
53
    }
54
55
    public function getTariffTypeDefinitionByTariffName(string $tariffName): TariffTypeDefinitionInterface
56
    {
57
        foreach ($this->registry->getTariffTypeDefinitions() as $tariffTypeDefinition) {
58
            if ($tariffTypeDefinition->tariffType()->equalsName($tariffName)) {
59
                return $tariffTypeDefinition;
60
            }
61
        }
62
63
        throw TariffTypeDefinitionNotFoundException::make('TariffTypeDefinition was not found', [
64
            'tariffName' => $tariffName,
65
        ]);
66
    }
67
68
    public function getBehavior(string $type, string $behaviorClassWrapper): BehaviorInterface
69
    {
70
        if (!class_exists($behaviorClassWrapper)) {
71
            throw InvalidBehaviorException::make( 'Behavior class does not exist', [
72
                    'behavior' => $behaviorClassWrapper,
73
                ]
74
            );
75
        }
76
77
        if (!is_subclass_of($behaviorClassWrapper, BehaviorInterface::class)) {
78
            throw InvalidBehaviorException::make(
79
                'Behavior class does not implement BehaviorInterface', [
80
                    'behavior' => $behaviorClassWrapper,
81
                ]
82
            );
83
        }
84
85
        $billingType = $this->convertStringTypeToType($type);
86
87
        foreach ($this->registry->priceTypes() as $priceTypeDefinition) {
88
            if ($priceTypeDefinition->hasType($billingType)) {
89
                $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...
90
91
                if ($behavior) {
92
                    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...
93
                }
94
            }
95
        }
96
97
        throw BehaviorNotFoundException::make('Behavior was not found', [
98
                'behavior' => $behaviorClassWrapper,
99
                'type' => $type,
100
            ],
101
        );
102
    }
103
104
    private function convertStringTypeToType(string $type): TypeInterface
105
    {
106
        return Type::anyId($type);
107
    }
108
109
    private function findBehaviorInPriceType(
110
        PriceTypeDefinitionInterface $priceTypeDefinition,
111
        string $behaviorClassWrapper
112
    ): ?BehaviorInterface {
113
        foreach ($priceTypeDefinition->withBehaviors() as $behavior) {
114
            if ($behavior instanceof $behaviorClassWrapper) {
115
                return $behavior;
116
            }
117
        }
118
119
        return null;
120
    }
121
122
    public function getBehaviors(string $behaviorClassWrapper): Generator
123
    {
124
        foreach ($this->registry->getTariffTypeDefinitions() as $tariffTypeDefinition) {
125
            foreach ($tariffTypeDefinition->withBehaviors() as $behavior) {
126
                if ($behavior instanceof $behaviorClassWrapper) {
127
                    yield $behavior;
128
                }
129
            }
130
        }
131
132
        foreach ($this->registry->priceTypes() as $priceTypeDefinition) {
133
            foreach ($priceTypeDefinition->withBehaviors() as $behavior) {
134
                if ($behavior instanceof $behaviorClassWrapper) {
135
                    yield $behavior;
136
                }
137
            }
138
        }
139
    }
140
141
    public function getAggregate(string $type): AggregateInterface
142
    {
143
        return $this->getPriceTypeDefinitionByPriceTypeName($type)->getAggregate();
144
    }
145
146
    public function getPriceTypeDefinitionByPriceTypeName(string $typeName): PriceTypeDefinitionInterface
147
    {
148
        $type = $this->convertStringTypeToType($typeName);
149
150
        foreach ($this->registry->priceTypes() as $priceTypeDefinition) {
151
            if ($priceTypeDefinition->hasType($type)) {
152
                return $priceTypeDefinition;
153
            }
154
        }
155
156
        throw PriceTypeDefinitionNotFoundException::make('PriceTypeDefinition was not found', [
157
            'type' => $typeName,
158
        ]);
159
    }
160
161
    public function findPriceTypeDefinitionsByBehavior(string $behaviorClassWrapper): Generator
162
    {
163
        foreach ($this->registry->priceTypes() as $priceTypeDefinition) {
164
            if ($priceTypeDefinition->hasBehavior($behaviorClassWrapper)) {
165
                yield $priceTypeDefinition;
166
            }
167
        }
168
    }
169
}
170