SituationParser::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

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