Passed
Push — master ( 1c5d16...a9efcd )
by Chema
03:27
created

TransactionMessage::segmentsByName()   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 1
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 9
    public static function groupSegmentsByMessage(SegmentInterface...$segments): array
25
    {
26 9
        $messages = [];
27 9
        $groupedSegments = [];
28
29 9
        foreach ($segments as $segment) {
30 9
            if ($segment instanceof UNHMessageHeader) {
31 9
                $groupedSegments = [];
32
            }
33
34 9
            $groupedSegments[] = $segment;
35
36 9
            if ($segment instanceof UNTMessageFooter
37 9
                && self::isGroupedSegmentsNotEmpty($groupedSegments)
38
            ) {
39 8
                $messages[] = self::groupSegmentsByName(...$groupedSegments);
40
            }
41
        }
42
43 9
        return array_values(
44
            array_filter($messages, static function (self $m) {
45 8
                return !empty($m->segmentsByName(UNHMessageHeader::class));
46 9
            })
47
        );
48
    }
49
50
    /** @param array<string, array<string,SegmentInterface>> $groupedSegments */
51 8
    public function __construct(array $groupedSegments)
52
    {
53 8
        $this->groupedSegments = $groupedSegments;
54 8
    }
55
56
    /** @return array<string,SegmentInterface> */
57 8
    public function segmentsByName(string $name): array
58
    {
59 8
        return $this->groupedSegments[$name] ?? [];
60
    }
61
62
    /**
63
     * We add automatically all items to the $groupedSegments array in the loop,
64
     * one message is made of "UNHMessageHeader" and "UNTMessageFooter" segments.
65
     * So the minimum messages are two, only one segment is not possible.
66
     *
67
     * @psalm-pure
68
     */
69 9
    private static function isGroupedSegmentsNotEmpty(array $groupedSegments): bool
70
    {
71 9
        return count($groupedSegments) > 1;
72
    }
73
74
    /** @psalm-pure */
75 8
    private static function groupSegmentsByName(SegmentInterface...$segments): self
76
    {
77 8
        $return = [];
78
79 8
        foreach ($segments as $s) {
80 8
            $return[$s->tag()] ??= [];
81 8
            $return[$s->tag()][$s->subId()] = $s;
82
        }
83
84 8
        return new self($return);
85
    }
86
}
87