Completed
Push — master ( 522c84...893b4c )
by Tom
02:22
created

IndexParser::parseAlert()   F

Complexity

Conditions 28
Paths 44

Size

Total Lines 179
Code Lines 140

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 133
CRAP Score 28.0371

Importance

Changes 0
Metric Value
cc 28
eloc 140
nc 44
nop 1
dl 0
loc 179
ccs 133
cts 138
cp 0.9638
crap 28.0371
rs 3.3333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace NoaaCapAlerts\Parser;
4
5
/**
6
 * Class IndexParser
7
 * @package IndexParser
8
 */
9
class IndexParser
10
{
11
    protected $xmlParser;
12
13
    /**
14
     * IndexParser constructor.
15
     * @param XmlParser|null $xmlParser
16
     */
17 2
    function __construct(XmlParser $xmlParser = null)
18
    {
19 2
        $this->xmlParser = $xmlParser;
20
21 2
        if($xmlParser === null) {
22 2
            $this->xmlParser = new XmlParser();
23
        }
24 2
    }
25
26
    /**
27
     * @param string $xml
28
     * @return array
29
     */
30 2
    public function parse(string $xml) : array
31
    {
32
        // parse XML into an array of alerts
33 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

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