PaymentReference::loadValidatorMetadata()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 36
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 24
nc 1
nop 1
dl 0
loc 36
rs 9.536
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Sprain\SwissQrBill\DataGroup\Element;
4
5
use Sprain\SwissQrBill\Constraint\ValidCreditorReference;
6
use Sprain\SwissQrBill\DataGroup\QrCodeableInterface;
7
use Sprain\SwissQrBill\String\StringModifier;
8
use Sprain\SwissQrBill\Validator\SelfValidatableInterface;
9
use Sprain\SwissQrBill\Validator\SelfValidatableTrait;
10
use Symfony\Component\Validator\Constraints as Assert;
11
use Symfony\Component\Validator\Constraints\GroupSequence;
12
use Symfony\Component\Validator\GroupSequenceProviderInterface;
13
use Symfony\Component\Validator\Mapping\ClassMetadata;
14
15
final class PaymentReference implements GroupSequenceProviderInterface, QrCodeableInterface, SelfValidatableInterface
16
{
17
    use SelfValidatableTrait;
18
19
    public const TYPE_QR = 'QRR';
20
    public const TYPE_SCOR = 'SCOR';
21
    public const TYPE_NON = 'NON';
22
23
    /**
24
     * Reference type
25
     */
26
    private string $type;
27
28
    /**
29
     * Structured reference number
30
     * Either a QR reference or a Creditor Reference (ISO 11649)
31
     */
32
    private ?string $reference;
33
34
    private function __construct(string $type, ?string $reference)
35
    {
36
        $this->type = $type;
37
        $this->reference = $reference;
38
39
        $this->handleWhiteSpaceInReference();
40
    }
41
42
    public static function create(string $type, ?string $reference = null): self
43
    {
44
        return new self($type, $reference);
45
    }
46
47
    public function getType(): string
48
    {
49
        return $this->type;
50
    }
51
52
    public function getReference(): ?string
53
    {
54
        return $this->reference;
55
    }
56
57
    public function getFormattedReference(): ?string
58
    {
59
        switch ($this->type) {
60
            case self::TYPE_QR:
61
                return trim(strrev(chunk_split(strrev($this->reference), 5, ' ')));
0 ignored issues
show
Bug introduced by
It seems like $this->reference can also be of type null; however, parameter $string of strrev() does only seem to accept string, 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

61
                return trim(strrev(chunk_split(strrev(/** @scrutinizer ignore-type */ $this->reference), 5, ' ')));
Loading history...
62
            case self::TYPE_SCOR:
63
                return trim(chunk_split($this->reference, 4, ' '));
0 ignored issues
show
Bug introduced by
It seems like $this->reference can also be of type null; however, parameter $string of chunk_split() does only seem to accept string, 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

63
                return trim(chunk_split(/** @scrutinizer ignore-type */ $this->reference, 4, ' '));
Loading history...
64
            default:
65
                return null;
66
        }
67
    }
68
69
    public function getQrCodeData(): array
70
    {
71
        return [
72
            $this->getType(),
73
            $this->getReference()
74
        ];
75
    }
76
77
    public static function loadValidatorMetadata(ClassMetadata $metadata): void
78
    {
79
        $metadata->setGroupSequenceProvider(true);
80
81
        $metadata->addPropertyConstraints('type', [
82
            new Assert\NotBlank([
83
                'groups' => ['default']
84
            ]),
85
            new Assert\Choice([
86
                'groups' => ['default'],
87
                'choices' => [
88
                    self::TYPE_QR,
89
                    self::TYPE_SCOR,
90
                    self::TYPE_NON
91
                ]
92
            ])
93
        ]);
94
95
        $metadata->addPropertyConstraints('reference', [
96
            new Assert\Type([
97
                'type' => 'alnum',
98
                'groups' => [self::TYPE_QR]
99
            ]),
100
            new Assert\NotBlank([
101
                'groups' => [self::TYPE_QR, self::TYPE_SCOR]
102
            ]),
103
            new Assert\Length([
104
                'min' => 27,
105
                'max' => 27,
106
                'groups' => [self::TYPE_QR]
107
            ]),
108
            new Assert\Blank([
109
                'groups' => [self::TYPE_NON]
110
            ]),
111
            new ValidCreditorReference([
112
                'groups' => [self::TYPE_SCOR]
113
            ])
114
        ]);
115
    }
116
117
    public function getGroupSequence(): array|GroupSequence
118
    {
119
        return [
120
            'default',
121
            $this->getType()
122
        ];
123
    }
124
125
    private function handleWhiteSpaceInReference(): void
126
    {
127
        if (null === $this->reference) {
128
            return;
129
        }
130
131
        $this->reference = StringModifier::stripWhitespace($this->reference);
132
133
        if ('' === $this->reference) {
134
            $this->reference = null;
135
        }
136
    }
137
}
138