Passed
Push — master ( 893b4c...065242 )
by Tom
01:46
created

IndexParser::generateIdKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 22
ccs 5
cts 5
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace NoaaCapAlerts\Parser;
4
5
use NoaaCapAlerts\Exceptions\XmlParseException;
6
7
/**
8
 * Class IndexParser
9
 * @package IndexParser
10
 */
11
class IndexParser
12
{
13
    protected $xmlParser;
14
15 2
    function __construct(XmlParser $xmlParser = null)
16
    {
17 2
        $this->xmlParser = $xmlParser;
18
19 2
        if($xmlParser === null) {
20 2
            $this->xmlParser = new XmlParser();
21
        }
22 2
    }
23
24 2
    public function parse(string $xml) : array
25
    {
26
        // parse XML into an array of alerts
27 2
        $rawDataArray = $this->xmlParser->getArrayFromXml($xml);
0 ignored issues
show
Bug introduced by
The method getArrayFromXml() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

27
        /** @scrutinizer ignore-call */ 
28
        $rawDataArray = $this->xmlParser->getArrayFromXml($xml);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
28 1
        $alertDataArray = $rawDataArray[0]['children'];
29
30
        // Process each alert ("ENTRY")
31 1
        $resultArray = array();
32
33 1
        foreach($alertDataArray as $alert) {
34 1
            if (!$this->isAlert($alert)) {
35 1
                continue;
36
            }
37
38 1
            $parsedAlert = $this->parseAlert($alert);
39
40 1
            $resultArray[] = $parsedAlert;
41
        }
42
43 1
        return $resultArray;
44
    }
45
46 1
    protected function isAlert(array $alert) : bool
47
    {
48 1
        return isset($alert['name']) && $alert['name'] == 'ENTRY';
49
    }
50
51 1
    protected function parseAlert(array $alert) : array
52
    {
53
        $parsedAlert = array(
54 1
            'idString' => '',
55
            'idKey' => '',
56
            'updatedDateTime' => null,
57
            'publishedDateTime' => null,
58
            'updatedTime' => '',
59
            'publishedTime' => '',
60
            'authorName' => '',
61
            'title' => '',
62
            'link' => '',
63
            'summary' => '',
64
            'capEvent' => '',
65
            'capEffectiveTime' => '',
66
            'capExpiresTime' => '',
67
            'capEffectiveDateTime' => null,
68
            'capExpiresDateTime' => null,
69
            'capStatus' => '',
70
            'capMsgType' => '',
71
            'capCategory' => '',
72
            'capUrgencyExpected' => '',
73
            'capSeverity' => '',
74
            'capCertainty' => '',
75
            'capAreaDesc' => '',
76
            'capPolygon' => '',
77
            'capGeo' => array(),
78
            'capGeoString' => '',
79
            'capParameters' => '',
80
        );
81
82
        // Loop through attributes and set values
83 1
        foreach($alert['children'] as $element){
84 1
            $elementName = $element['name'];
85 1
            $elementAttrs = $element['attrs'];
86 1
            if(isset($element['tagData'])){
87 1
                $elementData = $element['tagData'];
88
            } else {
89 1
                $elementData = '';
90
            }
91
92
93
            switch($elementName){
94 1
                case 'ID':
95 1
                    $parsedAlert['idString'] = $elementData;
96 1
                    break;
97 1
                case 'UPDATED':
98 1
                    $parsedAlert['updatedDateTime'] = new \DateTime($elementData);
99 1
                    $parsedAlert['updatedTime'] = $parsedAlert['updatedDateTime']->format('Y-m-d H:i:s');
100 1
                    break;
101 1
                case 'PUBLISHED':
102 1
                    $parsedAlert['publishedDateTime'] = new \DateTime($elementData);
103 1
                    $parsedAlert['publishedTime'] = $parsedAlert['publishedDateTime']->format('Y-m-d H:i:s');
104 1
                    break;
105 1
                case 'AUTHOR':
106 1
                    $parsedAlert['authorName'] = $element['children'][0]['tagData'];
107 1
                    break;
108 1
                case 'TITLE':
109 1
                    $parsedAlert['title'] = $elementData;
110 1
                    break;
111 1
                case 'LINK':
112 1
                    $parsedAlert['link'] = $elementAttrs['HREF'];
113 1
                    break;
114 1
                case 'SUMMARY':
115 1
                    $parsedAlert['summary'] = $elementData;
116 1
                    break;
117 1
                case 'CAP:EVENT':
118 1
                    $parsedAlert['capEvent'] = $elementData;
119 1
                    break;
120 1
                case 'CAP:EFFECTIVE':
121 1
                    $effectiveDateTime = new \DateTime($elementData);
122 1
                    $parsedAlert['capEffectiveTime'] = $effectiveDateTime->format('Y-m-d H:i:s');
123 1
                    $parsedAlert['capEffectiveDateTime'] = $effectiveDateTime;
124 1
                    break;
125 1
                case 'CAP:EXPIRES':
126 1
                    $expiresDateTime = new \DateTime($elementData);
127 1
                    $parsedAlert['capExpiresTime'] = $expiresDateTime->format('Y-m-d H:i:s');
128 1
                    $parsedAlert['capExpiresDateTime'] = $expiresDateTime;
129 1
                    break;
130 1
                case 'CAP:STATUS':
131 1
                    $parsedAlert['capStatus'] = $elementData;
132 1
                    break;
133 1
                case 'CAP:MSGTYPE':
134 1
                    $parsedAlert['capMsgType'] = $elementData;
135 1
                    break;
136 1
                case 'CAP:CATEGORY':
137 1
                    $parsedAlert['capCategory'] = $elementData;
138 1
                    break;
139 1
                case 'CAP:URGENCY':
140 1
                    $parsedAlert['capUrgencyExpected'] = $elementData;
141 1
                    break;
142 1
                case 'CAP:SEVERITY':
143 1
                    $parsedAlert['capSeverity'] = $elementData;
144 1
                    break;
145 1
                case 'CAP:CERTAINTY':
146 1
                    $parsedAlert['capCertainty'] = $elementData;
147 1
                    break;
148 1
                case 'CAP:AREADESC':
149 1
                    $parsedAlert['capAreaDesc'] = $elementData;
150 1
                    break;
151 1
                case 'CAP:POLYGON':
152 1
                    $capPolygonString = $elementData;
153 1
                    $parsedAlert['capPolygon'] = explode(' ', $capPolygonString);
154 1
                    break;
155 1
                case 'CAP:GEOCODE':
156 1
                    $geoArray = array();
157
158
                    // parse into simple array
159 1
                    foreach($element['children'] as $geo) {
160 1
                        if(isset($geo['tagData'])) {
161 1
                            $geoArray[] = $geo['tagData'];
162
                        }
163
                    }
164
165 1
                    $geoLocArray = $this->parseGeoArray($geoArray);
166 1
                    $parsedAlert['capGeoString'] = implode(', ', $geoArray);
167 1
                    $parsedAlert['capGeo'] = $geoLocArray;
168 1
                    break;
169 1
                case 'CAP:PARAMETERS':
170
                    $paramArray = array();
171
                    foreach($element['children'] as $param){
172
                        $paramArray[] = $param['tagData'];
173
                    }
174
                    $parsedAlert['capParameters'] = implode(', ', $paramArray);
175
                    break;
176
            }
177
178 1
            $parsedAlert['idKey'] = $this->generateIdKey($parsedAlert['idString']);
179
180
        }
181
182 1
        return $parsedAlert;
183
    }
184
185
    /**
186
     * @param array $geoArray
187
     * @return array
188
     */
189 1
    protected function parseGeoArray(array $geoArray) : array
190
    {
191
        // organize array by format type
192
        $locationFormatTypes = array(
193 1
            'FIPS6',
194
            'UGC',
195
        );
196
197 1
        $currentLocationKey = 'null';
198 1
        $geoLocArray = array();
199
200 1
        foreach($geoArray as $geoLoc) {
201 1
            if(in_array($geoLoc, $locationFormatTypes)) {
202 1
                $currentLocationKey = $geoLoc;
203 1
                $geoLocArray[$geoLoc] = array();
204
            } else {
205 1
                $geoLocArray[$currentLocationKey] = explode(' ', $geoLoc);
206
            }
207
        }
208
209 1
        return $geoLocArray;
210
    }
211
212 1
    protected function generateIdKey(string $idString) : string
213
    {
214
        // idString contains important data in it as well.
215
        // Use it to generate a unique key for the alert.
216
        //
217
        // Example:
218
        //    alerts.weather.gov/cap/wwacapget.php?x=AK12539092A414.WinterWeatherAdvisory.125390A09AB0AK.AFGWSWNSB.a59f94b5da45867f6f45272a36df61cc
219
        //
220
        // The pieces of idString appears to be
221
        // 0. State abrev + some strange timestamp format
222
        // 1. Type
223
        // 2. Another timestamp with state abrev.
224
        // 3. ??
225
        // 4. Hash of some data (32 bit)
226
        //
227
        // 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.
228
229 1
        $idParts = explode('=', $idString);
230 1
        $idSplit = explode('.', $idParts[1]);
231 1
        $idKey = $idSplit[0] . '.' . $idSplit[4];
232
233 1
        return $idKey;
234
    }
235
236
}
237