Passed
Push — master ( e45f00...64accf )
by Jasper
14:15
created

SituationParser::getPeriods()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 5
ccs 5
cts 5
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Swis\Melvin\Parsers;
6
7
use Swis\Melvin\Enums\ActivityType;
8
use Swis\Melvin\Enums\Delay;
9
use Swis\Melvin\Enums\EventType;
10
use Swis\Melvin\Enums\Impact;
11
use Swis\Melvin\Enums\ImpactDescription;
12
use Swis\Melvin\Enums\PersonType;
13
use Swis\Melvin\Enums\RoadAuthorityType;
14
use Swis\Melvin\Enums\SituationStatus;
15
use Swis\Melvin\Enums\Source;
16
use Swis\Melvin\Enums\WorkObject;
17
use Swis\Melvin\Enums\WorkType;
18
use Swis\Melvin\Models\Location;
19
use Swis\Melvin\Models\Person;
20
use Swis\Melvin\Models\RoadAuthority;
21
use Swis\Melvin\Models\Situation;
22
23
class SituationParser
24
{
25
    public function __construct(
26
        protected GeometryParser $geometryParser,
27
        protected PeriodParser $periodParser,
28
        protected AttachmentParser $attachmentParser,
29
        protected RestrictionParser $restrictionParser,
30
        protected DetourParser $detourParser
31
    ) {
32
    }
33
34
    public function parse(\stdClass $object, array $restrictions, array $detours = []): Situation
35 6
    {
36
        $situationId = (int) $object->id;
37
38
        if ($roadAuthority = $object->properties->roadAuthority ?? null) {
39
            $roadAuthority = new RoadAuthority(
40
                $roadAuthority->id ?? $situationId,
41
                $roadAuthority->type !== 'EMPTY' ? RoadAuthorityType::from($roadAuthority->type) : null,
42 6
                $roadAuthority->name
43 6
            );
44 6
        }
45 6
46 6
        if ($createdBy = $object->properties->createdBy ?? null) {
47 3
            $createdBy = new Person(
48
                $createdBy->firstName,
49 6
                $createdBy->prefix,
50
                $createdBy->lastName,
51 6
                PersonType::from($createdBy->type)
52
            );
53 6
        }
54 6
        if ($createdAt = $object->properties->createdAt ?? $object->properties->createdBy->createdAt ?? null) {
55 6
            $createdAt = new \DateTime($createdAt, new \DateTimeZone('UTC'));
56 6
        }
57 6
58 3
        if ($lastChangedBy = $object->properties->lastChangedBy ?? null) {
59
            $lastChangedBy = new Person(
60
                $lastChangedBy->firstName,
61 6
                $lastChangedBy->prefix,
62 6
                $lastChangedBy->lastName,
63 6
                PersonType::from($lastChangedBy->type)
64 6
            );
65 6
        }
66 6
        if ($lastChangedAt = $object->properties->lastChangeAt ?? $object->properties->lastChangedBy->lastChangeAt ?? null) {
67 3
            $lastChangedAt = new \DateTime($lastChangedAt, new \DateTimeZone('UTC'));
68
        }
69 6
70 6
        $location = new Location(
71
            $object->properties->location->city,
72
            $object->properties->location->road,
73 6
            $object->properties->location->district,
74 6
            $object->properties->location->comment ?? ''
75 6
        );
76 6
77 6
        if ($impactDescription = $object->properties->impactDescription ?? null) {
78 6
            $impactDescription = ImpactDescription::isValid($impactDescription) ? ImpactDescription::from($impactDescription)->getLabel() : $impactDescription;
79 3
        }
80
81 6
        return new Situation(
82 6
            $object->id,
83
            str_contains($object->properties->type, '_EXTERNAL'),
84
            $this->geometryParser->parse($object->geometry),
85 6
            $this->getName($object),
86 6
            ($object->activityType ?? '') ? ActivityType::from($object->activityType) : ActivityType::WORK(),
87 6
            ($object->properties->workObject ?? '') ? WorkObject::from($object->properties->workObject) : null,
88 6
            isset($object->properties->impact) && $object->properties->impact !== 'EMPTY' ? Impact::from($object->properties->impact) : null,
89 6
            $impactDescription,
90 3
            $object->properties->project,
91
            Source::from($object->properties->source),
92 6
            $object->properties->published,
93 6
            ($object->properties->url ?? '') ?: null,
94
            ($object->properties->urlDescription ?? '') ?: null,
95
            Delay::from($object->properties->delay),
96 6
            ($object->properties->workType ?? '') ? WorkType::from($object->properties->workType) : null,
97 6
            ($object->properties->eventType ?? '') ? EventType::from($object->properties->eventType) : null,
98 6
            ($object->properties->eventName ?? '') ?: null,
99 6
            ($object->properties->addition ?? '') ?: null,
100 6
            SituationStatus::from($object->properties->status),
101 6
            $roadAuthority,
102 6
            $location,
103 6
            $this->getPeriods($object->properties->periods),
104 3
            $createdAt,
105 6
            $createdBy,
106 6
            $lastChangedAt,
107 6
            $lastChangedBy,
108 6
            array_map([$this->attachmentParser, 'parse'], $object->properties->attachments ?? [], array_keys($object->properties->attachments ?? [])),
109 6
            array_map([$this->restrictionParser, 'parse'], $restrictions, array_keys($restrictions)),
110 6
            array_map([$this->detourParser, 'parse'], $detours, array_keys($detours))
111 6
        );
112 6
    }
113 6
114 6
    protected function getName(\stdClass $object): string
115 6
    {
116 3
        if (isset($object->properties->name) && trim($object->properties->name)) {
117 3
            return trim($object->properties->name);
118 6
        }
119 3
120 3
        $eventName = ($object->properties->eventName ?? '') ?: null;
121 3
        $eventType = ($object->properties->eventType ?? '') ? EventType::from($object->properties->eventType) : null;
122 3
        $workType = ($object->properties->workType ?? '') ? WorkType::from($object->properties->workType) : null;
123 6
        $workObject = ($object->properties->workObject ?? '') ? WorkObject::from($object->properties->workObject) : null;
124 6
125 6
        $description = '';
126 3
        if ($eventName) {
127
            $description = $eventName;
128
        } elseif ($eventType) {
129 6
            $description = $eventType->getLabel();
130
        } elseif ($workType) {
131 6
            $description = $workType->getLabel();
132 6
133
            if ($workObject) {
134
                $description = str_replace('...', $workObject->getLabel(), $description);
135 6
            }
136 6
        }
137 6
138 6
        return trim(
139
            preg_replace(
140 6
                '/\s+/',
141 6
                ' ',
142 6
                sprintf(
143 6
                    '%s %s %s %s %s',
144 6
                    $object->properties->location->road,
145 6
                    $object->properties->location->district,
146 6
                    $object->properties->location->city,
147
                    $description,
148 6
                    $object->properties->addition ?? ''
149 6
                )
150
            )
151
        );
152
    }
153 6
154 6
    /**
155 6
     * @param \stdClass[] $objects
156 6
     *
157 6
     * @return array
158 6
     */
159 6
    protected function getPeriods(array $objects): array
160 6
    {
161 6
        $filtered = array_values(array_filter($objects, static fn (\stdClass $object) => $object->id));
162 3
163 6
        return array_map([$this->periodParser, 'parse'], $filtered, array_keys($filtered));
164 3
    }
165
}
166