Passed
Push — master ( a9efcd...937cf8 )
by Chema
02:37
created

TransactionMessage::segmentByTagAndSubId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
ccs 2
cts 2
cp 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EdifactParser;
6
7
use EdifactParser\Segments\SegmentInterface;
8
use EdifactParser\Segments\UNHMessageHeader;
9
use EdifactParser\Segments\UNTMessageFooter;
10
11
/** @psalm-immutable */
12
final class TransactionMessage
13
{
14
    /** @var array<string, array<string,SegmentInterface>> */
15
    private array $groupedSegments;
16
17
    /**
18
     * A transaction message starts with the "UNHMessageHeader" segment and finalizes with
19
     * the "UNTMessageFooter" segment, this process is repeated for each pair of segments.
20
     *
21
     * @psalm-pure
22
     * @psalm-return list<TransactionMessage>
23
     */
24 11
    public static function groupSegmentsByMessage(SegmentInterface...$segments): array
25
    {
26 11
        $messages = [];
27 11
        $groupedSegments = [];
28
29 11
        foreach ($segments as $segment) {
30 11
            if ($segment instanceof UNHMessageHeader) {
31 11
                $groupedSegments = [];
32
            }
33
34 11
            $groupedSegments[] = $segment;
35
36 11
            if ($segment instanceof UNTMessageFooter
37 11
                && self::isGroupedSegmentsNotEmpty($groupedSegments)
38
            ) {
39 10
                $messages[] = self::groupSegmentsByName(...$groupedSegments);
40
            }
41
        }
42
43 11
        return array_values(
44
            array_filter($messages, static function (self $m) {
45 10
                return !empty($m->segmentsByTag(UNHMessageHeader::class));
46 11
            })
47
        );
48
    }
49
50
    /** @param array<string, array<string,SegmentInterface>> $groupedSegments */
51 10
    public function __construct(array $groupedSegments)
52
    {
53 10
        $this->groupedSegments = $groupedSegments;
54 10
    }
55
56
    /** @return array<string, SegmentInterface>|array */
57 10
    public function segmentsByTag(string $tag): array
58
    {
59 10
        return $this->groupedSegments[$tag] ?? [];
60
    }
61
62
    /** @return ?SegmentInterface */
63 3
    public function segmentByTagAndSubId(string $tag, string $subId): ?SegmentInterface
64
    {
65 3
        return $this->groupedSegments[$tag][$subId] ?? null;
66
    }
67
68
    /**
69
     * We add automatically all items to the $groupedSegments array in the loop,
70
     * one message is made of "UNHMessageHeader" and "UNTMessageFooter" segments.
71
     * So the minimum messages are two, only one segment is not possible.
72
     *
73
     * @psalm-pure
74
     */
75 11
    private static function isGroupedSegmentsNotEmpty(array $groupedSegments): bool
76
    {
77 11
        return count($groupedSegments) > 1;
78
    }
79
80
    /** @psalm-pure */
81 10
    private static function groupSegmentsByName(SegmentInterface...$segments): self
82
    {
83 10
        $return = [];
84
85 10
        foreach ($segments as $s) {
86 10
            $return[$s->tag()] ??= [];
87 10
            $return[$s->tag()][$s->subId()] = $s;
88
        }
89
90 10
        return new self($return);
91
    }
92
}
93