Passed
Pull Request — master (#121)
by Manuel
09:56 queued 01:17
created

PaymentReference::getQrCodeData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 5
rs 10
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\GroupSequenceProviderInterface;
12
use Symfony\Component\Validator\Mapping\ClassMetadata;
13
14
final class PaymentReference implements GroupSequenceProviderInterface, QrCodeableInterface, SelfValidatableInterface
15
{
16
    use SelfValidatableTrait;
17
18
    public const TYPE_QR = 'QRR';
19
    public const TYPE_SCOR = 'SCOR';
20
    public const TYPE_NON = 'NON';
21
22
    /**
23
     * Reference type
24
     */
25
    private string $type;
26
27
    /**
28
     * Structured reference number
29
     * Either a QR reference or a Creditor Reference (ISO 11649)
30
     */
31
    private ?string $reference;
32
33
    private function __construct(string $type, ?string $reference)
34
    {
35
        $this->type = $type;
36
        $this->reference = $reference;
37
38
        $this->handleWhiteSpaceInReference();
39
    }
40
41
    public static function create(string $type, ?string $reference = null): self
42
    {
43
        return new self($type, $reference);
44
    }
45
46
    public function getType(): string
47
    {
48
        return $this->type;
49
    }
50
51
    public function getReference(): ?string
52
    {
53
        return $this->reference;
54
    }
55
56
    public function getFormattedReference(): ?string
57
    {
58
        switch ($this->type) {
59
            case self::TYPE_QR:
60
                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

60
                return trim(strrev(chunk_split(strrev(/** @scrutinizer ignore-type */ $this->reference), 5, ' ')));
Loading history...
61
            case self::TYPE_SCOR:
62
                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

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