Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
40.48% covered (danger)
40.48%
34 / 84
40.00% covered (danger)
40.00%
6 / 15
CRAP
0.00% covered (danger)
0.00%
0 / 1
TransportSection
40.48% covered (danger)
40.48%
34 / 84
40.00% covered (danger)
40.00%
6 / 15
293.35
0.00% covered (danger)
0.00%
0 / 1
 fromTransportApi
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 parseFromTransportApi
82.35% covered (warning)
82.35%
14 / 17
0.00% covered (danger)
0.00%
0 / 1
6.20
 getFieldValue
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 fromFieldValue
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 populateFromFieldValue
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 getDeparture
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setDeparture
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getArrival
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setArrival
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getPassList
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setPassList
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getIsWalk
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setIsWalk
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getHalts
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 getCropped
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
240
1<?php
2
3namespace Olz\Apps\Oev\Utils;
4
5use Olz\Utils\WithUtilsTrait;
6
7class TransportSection {
8    use WithUtilsTrait;
9
10    protected TransportHalt $departure;
11    protected TransportHalt $arrival;
12    /** @var array<TransportHalt> */
13    protected array $passList = [];
14    protected bool $isWalk;
15
16    /** @param array<string, mixed> $api_section */
17    public static function fromTransportApi(array $api_section): self {
18        $section = new self();
19        $section->parseFromTransportApi($api_section);
20        return $section;
21    }
22
23    /** @param array<string, mixed> $api_section */
24    protected function parseFromTransportApi(array $api_section): void {
25        $this->isWalk = (
26            ($api_section['journey'] ?? null) === null
27            && $api_section['walk']
28        );
29        $this->departure = TransportHalt::fromTransportApi($api_section['departure']);
30        $this->arrival = TransportHalt::fromTransportApi($api_section['arrival']);
31        $this->passList = [];
32
33        $pass_list = $api_section['journey']['passList'] ?? [];
34        foreach ($pass_list as $pass_location) {
35            $halt = TransportHalt::fromTransportApi($pass_location);
36            if ($halt->getStationId() === $this->departure->getStationId()) {
37                continue;
38            }
39            if ($halt->getStationId() === $this->arrival->getStationId()) {
40                continue;
41            }
42            if (!$halt->getTimeSeconds()) {
43                continue;
44            }
45            $this->passList[] = $halt;
46        }
47    }
48
49    /** @return array<string, mixed> */
50    public function getFieldValue(): array {
51        return [
52            'departure' => $this->departure->getFieldValue(),
53            'arrival' => $this->arrival->getFieldValue(),
54            'passList' => array_map(function ($halt) {
55                return $halt->getFieldValue();
56            }, $this->passList),
57            'isWalk' => $this->isWalk,
58        ];
59    }
60
61    /** @param array<string, mixed> $value */
62    public static function fromFieldValue(array $value): self {
63        $instance = new self();
64        $instance->populateFromFieldValue($value);
65        return $instance;
66    }
67
68    /** @param array<string, mixed> $value */
69    protected function populateFromFieldValue(array $value): void {
70        $this->departure = TransportHalt::fromFieldValue($value['departure']);
71        $this->arrival = TransportHalt::fromFieldValue($value['arrival']);
72        $this->passList = array_map(function ($halt) {
73            return TransportHalt::fromFieldValue($halt);
74        }, $value['passList']);
75        $this->isWalk = $value['isWalk'];
76    }
77
78    public function getDeparture(): TransportHalt {
79        return $this->departure;
80    }
81
82    public function setDeparture(TransportHalt $new_departure): void {
83        $this->departure = $new_departure;
84    }
85
86    public function getArrival(): TransportHalt {
87        return $this->arrival;
88    }
89
90    public function setArrival(TransportHalt $new_arrival): void {
91        $this->arrival = $new_arrival;
92    }
93
94    /** @return array<TransportHalt> */
95    public function getPassList(): array {
96        return $this->passList;
97    }
98
99    /** @param array<TransportHalt> $new_pass_list */
100    public function setPassList(array $new_pass_list): void {
101        $this->passList = $new_pass_list;
102    }
103
104    public function getIsWalk(): bool {
105        return $this->isWalk;
106    }
107
108    public function setIsWalk(bool $new_is_walk): void {
109        $this->isWalk = $new_is_walk;
110    }
111
112    /** @return array<TransportHalt> */
113    public function getHalts(): array {
114        $halts = [];
115        $halts[] = $this->departure;
116        foreach ($this->passList as $halt) {
117            $halts[] = $halt;
118        }
119        $halts[] = $this->arrival;
120        return $halts;
121    }
122
123    public function getCropped(?TransportHalt $start_halt, ?TransportHalt $end_halt): TransportSection {
124        $cropped_section = new self();
125        $cropped_section->setIsWalk($this->isWalk);
126        if ($start_halt === null && $end_halt === null) {
127            $cropped_section->setDeparture($this->departure);
128            $cropped_section->setArrival($this->arrival);
129            $cropped_section->setPassList(array_slice($this->passList, 0));
130            return $cropped_section;
131        }
132        $stage = 'search_start';
133        if ($start_halt === null) {
134            $cropped_section->setDeparture($this->departure);
135            $stage = 'search_end';
136        }
137        $cropped_pass_list = [];
138        foreach ($this->getHalts() as $halt) {
139            if ($stage === 'search_start') {
140                if ($start_halt && $halt->equals($start_halt)) {
141                    $cropped_section->setDeparture($halt);
142                    $stage = 'search_end';
143                }
144            } elseif ($stage === 'search_end') {
145                if ($end_halt && $halt->equals($end_halt)) {
146                    $cropped_section->setArrival($halt);
147                    $stage = 'end_found';
148                } else {
149                    $cropped_pass_list[] = $halt;
150                }
151            }
152        }
153        if ($end_halt === null && $stage === 'search_end') {
154            $pass_list_length = count($cropped_pass_list);
155            $cropped_section->setArrival($cropped_pass_list[$pass_list_length - 1]);
156            $cropped_pass_list = array_slice($cropped_pass_list, 0, $pass_list_length - 1);
157            $stage = 'end_found';
158        }
159        $cropped_section->setPassList($cropped_pass_list);
160        if ($stage === 'search_start') {
161            throw new \ValueError('TransportSection::getCropped: Start not found.');
162        }
163        if ($stage === 'search_end') {
164            throw new \ValueError('TransportSection::getCropped: End not found.');
165        }
166        return $cropped_section;
167    }
168}