Completed
Branch master (7ef222)
by Tom
01:41
created

IndexParser::parseGeoArray()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 12
nc 3
nop 1
dl 0
loc 21
ccs 10
cts 10
cp 1
crap 3
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
namespace NoaaCapAlerts\Parser;
4
5
class IndexParser
6
{
7
    protected $xmlParser;
8
9 2
    function __construct(XmlParser $xmlParser = null)
10
    {
11 2
        if ($xmlParser === null) {
12 2
            $this->xmlParser = new XmlParser();
13
        } else {
14
            $this->xmlParser = $xmlParser;
15
        }
16 2
    }
17
18 2
    public function parse(string $xml): array
19
    {
20
        // parse XML into an array of alerts
21 2
        $rawDataArray = $this->xmlParser->getArrayFromXml($xml);
22 1
        $alertDataArray = $rawDataArray[0]['children'];
23
24
        // Process each alert ("ENTRY")
25 1
        $resultArray = array();
26
27 1
        foreach ($alertDataArray as $alert) {
28 1
            if (!$this->isAlert($alert)) {
29 1
                continue;
30
            }
31
32 1
            $parsedAlert = $this->parseAlert($alert);
33
34 1
            $resultArray[] = $parsedAlert;
35
        }
36
37 1
        return $resultArray;
38
    }
39
40 1
    protected function isAlert(array $alert): bool
41
    {
42 1
        return isset($alert['name']) && $alert['name'] == 'ENTRY';
43
    }
44
45 1
    protected function parseAlert(array $alert): array
46
    {
47
        $parsedAlert = array(
48 1
            'idString' => '',
49
            'idKey' => '',
50
            'updatedDateTime' => null,
51
            'publishedDateTime' => null,
52
            'updatedTime' => '',
53
            'publishedTime' => '',
54
            'authorName' => '',
55
            'title' => '',
56
            'link' => '',
57
            'summary' => '',
58
            'capEvent' => '',
59
            'capEffectiveTime' => '',
60
            'capExpiresTime' => '',
61
            'capEffectiveDateTime' => null,
62
            'capExpiresDateTime' => null,
63
            'capStatus' => '',
64
            'capMsgType' => '',
65
            'capCategory' => '',
66
            'capUrgencyExpected' => '',
67
            'capSeverity' => '',
68
            'capCertainty' => '',
69
            'capAreaDesc' => '',
70
            'capPolygon' => '',
71
            'capGeo' => array(),
72
            'capGeoString' => '',
73
            'vtec' => '',
74
        );
75
76
        // Loop through attributes and set values
77 1
        foreach ($alert['children'] as $element) {
78 1
            $elementName = $element['name'];
79 1
            $elementAttrs = $element['attrs'];
80 1
            if (isset($element['tagData'])) {
81 1
                $elementData = $element['tagData'];
82
            } else {
83 1
                $elementData = '';
84
            }
85
86
            switch ($elementName) {
87 1
                case 'ID':
88 1
                    $parsedAlert['idString'] = $elementData;
89 1
                    break;
90 1
                case 'UPDATED':
91 1
                    $parsedAlert['updatedDateTime'] = new \DateTime($elementData);
92 1
                    $parsedAlert['updatedTime'] = $parsedAlert['updatedDateTime']->format('Y-m-d H:i:s');
93 1
                    break;
94 1
                case 'PUBLISHED':
95 1
                    $parsedAlert['publishedDateTime'] = new \DateTime($elementData);
96 1
                    $parsedAlert['publishedTime'] = $parsedAlert['publishedDateTime']->format('Y-m-d H:i:s');
97 1
                    break;
98 1
                case 'AUTHOR':
99 1
                    $parsedAlert['authorName'] = $element['children'][0]['tagData'];
100 1
                    break;
101 1
                case 'TITLE':
102 1
                    $parsedAlert['title'] = $elementData;
103 1
                    break;
104 1
                case 'LINK':
105 1
                    $parsedAlert['link'] = $elementAttrs['HREF'];
106 1
                    break;
107 1
                case 'SUMMARY':
108 1
                    $parsedAlert['summary'] = $elementData;
109 1
                    break;
110 1
                case 'CAP:EVENT':
111 1
                    $parsedAlert['capEvent'] = $elementData;
112 1
                    break;
113 1
                case 'CAP:EFFECTIVE':
114 1
                    $effectiveDateTime = new \DateTime($elementData);
115 1
                    $parsedAlert['capEffectiveTime'] = $effectiveDateTime->format('Y-m-d H:i:s');
116 1
                    $parsedAlert['capEffectiveDateTime'] = $effectiveDateTime;
117 1
                    break;
118 1
                case 'CAP:EXPIRES':
119 1
                    $expiresDateTime = new \DateTime($elementData);
120 1
                    $parsedAlert['capExpiresTime'] = $expiresDateTime->format('Y-m-d H:i:s');
121 1
                    $parsedAlert['capExpiresDateTime'] = $expiresDateTime;
122 1
                    break;
123 1
                case 'CAP:STATUS':
124 1
                    $parsedAlert['capStatus'] = $elementData;
125 1
                    break;
126 1
                case 'CAP:MSGTYPE':
127 1
                    $parsedAlert['capMsgType'] = $elementData;
128 1
                    break;
129 1
                case 'CAP:CATEGORY':
130 1
                    $parsedAlert['capCategory'] = $elementData;
131 1
                    break;
132 1
                case 'CAP:URGENCY':
133 1
                    $parsedAlert['capUrgencyExpected'] = $elementData;
134 1
                    break;
135 1
                case 'CAP:SEVERITY':
136 1
                    $parsedAlert['capSeverity'] = $elementData;
137 1
                    break;
138 1
                case 'CAP:CERTAINTY':
139 1
                    $parsedAlert['capCertainty'] = $elementData;
140 1
                    break;
141 1
                case 'CAP:AREADESC':
142 1
                    $parsedAlert['capAreaDesc'] = $elementData;
143 1
                    break;
144 1
                case 'CAP:POLYGON':
145 1
                    $capPolygonString = $elementData;
146 1
                    $parsedAlert['capPolygon'] = explode(' ', $capPolygonString);
147 1
                    break;
148 1
                case 'CAP:GEOCODE':
149 1
                    $geoArray = array();
150
151
                    // parse into simple array
152 1
                    foreach ($element['children'] as $geo) {
153 1
                        if (isset($geo['tagData'])) {
154 1
                            $geoArray[] = $geo['tagData'];
155
                        }
156
                    }
157
158 1
                    $geoLocArray = $this->parseGeoArray($geoArray);
159 1
                    $parsedAlert['capGeoString'] = implode(', ', $geoArray);
160 1
                    $parsedAlert['capGeo'] = $geoLocArray;
161 1
                    break;
162 1
                case 'CAP:PARAMETER':
163
                    // It appears only vtec is currently stored here
164 1
                    if (isset($element['children'][1]['tagData'])) {
165 1
                        $parsedAlert['vtec'] = $element['children'][1]['tagData'];
166
                    }
167 1
                    break;
168
            }
169
170 1
            $parsedAlert['idKey'] = $this->generateIdKey($parsedAlert['idString']);
171
172
        }
173
174 1
        return $parsedAlert;
175
    }
176
177 1
    protected function parseGeoArray(array $geoArray): array
178
    {
179
        // organize array by format type
180
        $locationFormatTypes = array(
181 1
            'FIPS6',
182
            'UGC',
183
        );
184
185 1
        $currentLocationKey = 'null';
186 1
        $geoLocArray = array();
187
188 1
        foreach ($geoArray as $geoLoc) {
189 1
            if (in_array($geoLoc, $locationFormatTypes)) {
190 1
                $currentLocationKey = $geoLoc;
191 1
                $geoLocArray[$geoLoc] = array();
192
            } else {
193 1
                $geoLocArray[$currentLocationKey] = explode(' ', $geoLoc);
194
            }
195
        }
196
197 1
        return $geoLocArray;
198
    }
199
200 1
    protected function generateIdKey(string $idString): string
201
    {
202
        // idString contains important data in it as well.
203
        // Use it to generate a unique key for the alert.
204
        //
205
        // Example:
206
        //    alerts.weather.gov/cap/wwacapget.php?x=AK12539092A414.WinterWeatherAdvisory.125390A09AB0AK.AFGWSWNSB.a59f94b5da45867f6f45272a36df61cc
207
        //
208
        // The pieces of idString appears to be
209
        // 0. State abrev + some strange timestamp format
210
        // 1. Type
211
        // 2. Another timestamp with state abrev.
212
        // 3. ??
213
        // 4. Hash of some data (32 bit)
214
        //
215
        // Since 0,1,2, and 3 aren't unique on their own, but it looks like 4 is, I'll plan on using 0 and 4 just to be sure.
216
217 1
        $idParts = explode('=', $idString);
218 1
        $idSplit = explode('.', $idParts[1]);
219 1
        $idKey = $idSplit[0] . '.' . $idSplit[4];
220
221 1
        return $idKey;
222
    }
223
224
}
225