Texan78 Posted May 3, 2017 Share Posted May 3, 2017 (edited) Hello, I have been struggling with this for months and please be gentle as I am not a coder. Just a hobbyist trying to build a site for my brand. I know just enough to try to do what I need to do so I certainly do not know the best logic. I have been search for months and months for how to do this. I have three events I need to show in a certain order when they display. 1.) Tornado Warning 2.) Severe Thunderstorm Warning 3.) Flash Flood Warning I have them filtered but I am probably not using the best logic for this approach. Is there anyone who could offer some assistance and help me out with ordering these by severity as I have posted above so I can mark this little section as completed. -Thanks hugely!!! ini_set('display_errors','1'); ## Start Configurable data ## //Set message to display if there were not report $noStormMessage = 'There are currently no active severe weather alerts'; //Set path to data file #$data = "http://alerts.weather.gov/cap/".$zone.".php?x=0"; $data = "../xml/nat_warnings.xml"; ## End Configurable data ## // get path info & protect for cross-site scripting vulnerability $sri = ($_SERVER['REQUEST_URI']) ? str_replace('#SA', '', htmlspecialchars(strip_tags($_SERVER['REQUEST_URI']))) : ''; $error = false; //Set initial output to false $AlertData = false; $entries = simplexml_load_file($data); if(count($entries)): //Registering NameSpace $entries->registerXPathNamespace('prefix', 'http://www.w3.org/2005/Atom'); $result = $entries->xpath("//prefix:entry"); if(!$result){ $error = true; } foreach ($result as $entry): $updated = $entry->updated; if($updated == ''){ $error = true; } $Updated = date("D, M d, g:i a", strtotime($updated)); $summary = $entry->summary; if($summary == ''){ $error = true; } // Replaces all triple periods with single periods $summary = trim(str_replace('...', '.', $summary), '.') . '.'; //now capitalize every letter after a . ? and ! followed by space $Summary = preg_replace_callback('/([.!?*])\s*(\w)/', function ($matches) { return strtoupper($matches[1] . ' ' . $matches[2]); }, ucfirst(strtolower($summary))); $event = $entry->children("cap", true)->event; if ($event == ''){ $error = true; } $url = $entry->id; $updated = $entry->updated; $link = $entry->link; $effective = $entry->children("cap", true)->effective; $expires = $entry->children("cap", true)->expires; $updated = date("l M jS, g:i A", strtotime($updated)); $effectiveDate = date("l M jS, g:i A", strtotime($effective)); $expiresDate = date("D M jS, g:i A", strtotime($expires)); $status = $entry->children("cap", true)->status; $severity = $entry->children("cap", true)->severity; $urgency = $entry->children("cap", true)->urgency; $area = $entry->children("cap", true)->areaDesc; include ('alertColors.php'); // Let's assign the table some styles $divNoStorms = "padding:5px; width:45%; margin:auto; margin-top:5px; margin-bottom:5px"; // If no storms were in the source, set no storm message if($error) { $AlertData .= "<div style='{$divNoStorms}' class='alert alert-info' role='alert' data-toggle='tooltip' data-placement='top' title='There are currently no active severe weather alerts.'>\n"; $AlertData .= "{$noStormMessage}\n"; $AlertData .= "</div>\n"; } elseif ($event == 'Tornado Warning' || $event == 'Severe Thunderstorm Warning' || $event == 'Flash Flood Warning') { $AlertData .= "<div>\n"; $AlertData .= "<div id='{$alertID}' class='individualAlert'>\n"; $AlertData .= "<div class='text_alert'>\n"; $AlertData .= "<span class='title {$alertClass}'><i class='fa fa-exclamation-triangle severe-icon__tornado'></i>{$event}</span>\n"; $AlertData .= "<span class='state'>{$stateShort}</span>\n"; $AlertData .= "<span class='counties'>{$area}</span>\n"; $AlertData .= "<span class='expires'>Expires: {$expiresDate}</span>\n"; $AlertData .= "</div>\n"; $AlertData .= "<div class='alert__view'>\n"; $AlertData .= "<a href='{$url}'><span class='fa fa-eye'></span></a>\n"; $AlertData .= "</div>\n"; $AlertData .= "</div>\n"; } $AlertData .= "</div>\n"; endforeach; endif; echo $AlertData; Edited May 3, 2017 by Texan78 Quote Link to comment Share on other sites More sharing options...
dalecosp Posted May 5, 2017 Share Posted May 5, 2017 (edited) If I can offer some unsolicited advice first:1. While PHP can parse conditionals in both the "Shell Script Style" and the "Curly Brace" style, mixing them is "Not Good Style". 2. A better way to concatenate strings: // instead of this $foo = "Text"; $foo .= " and more text"; $foo .= " and still more text"; // try this $foo = "Text" . " and more text" . " and still more text"; As for the main question, I wonder if the sections for displaying an error and displaying a warning could be placed in custom functions, say, "show_error()" and "show_warning($warning_data)".You could then loop through the XML, placing the data in arrays and sorting them by "warning type" prior to output. That might even allow you to separate the logic of the program from the display of the information more fully, a concept that falls under the grand title "Separation of Concerns", and is fairly common practice among well-engineered software projects. By the same token, anyone who says they've never had logic and output mixed in the same area before is either lying, has a bad memory, or was privileged to be both a freakin' genius and working on a large team of similarly-brained individuals.Not that this idea/design might not scale if you're doing a large geographical area or a large time window, but for one local region and current or fairly recent data, that shouldn't be a big problem. Hope that this helps you a little. Edited May 5, 2017 by dalecosp Quote Link to comment Share on other sites More sharing options...
Texan78 Posted May 5, 2017 Author Share Posted May 5, 2017 Thanks, I am not worried about the other right now. Each their own. Main focus is getting these sorted by priority and I have no idea how to do this and cannot find any examples. I have even been willing to PAY someone to do this since last November for what is probably less than 5 mins of work but can't find anyone. Is what I am asking that difficult? I didn't think it was that difficult, I see sites doing it all the time everyday. I have already tried the array approach and got shot down on here with it and could never get it working. Quote Link to comment Share on other sites More sharing options...
Texan78 Posted May 10, 2017 Author Share Posted May 10, 2017 Anyone? Quote Link to comment Share on other sites More sharing options...
fatkatie Posted May 11, 2017 Share Posted May 11, 2017 These are just some ideas. I'm a low hours PHP pilot so I'm sure I'll get nuked. It's been sitting here awhile so no one can call me presumptuous. These are the 'weather events' you are looking to report, correct?Tornado WarningSevere Thunderstorm WarningFlash Flood WarningThese are contained in an XML structure and each 'weather event' has a lot information; things like: location,links,status...blah blah. You want to order this data in a report ($AlertData) based on different things.You could create weather event objects as you parse the XML and then sort the objects based on any parameter(s) you wish.Take that object sort, iterate and build your $AlertData string. If you've never done object stuff, this may be an adventure.If you don't want to use objects, dump it in a database and use sql to fetch it. You could even write a db procedure to doit for you. In my old language I'd build a couple structures but I don't think I'd do that in PHP.PHP may have some container objects ready for you to use. Like I said, don't know PHP that well so you'll have to look around. Good luck. 1 Quote Link to comment Share on other sites More sharing options...
requinix Posted May 11, 2017 Share Posted May 11, 2017 fatkatie has the right idea: process the XML into temporary structures first, be those objects or arrays (I think arrays would be sufficient), sort those how you want, and then display them in order. 1. Start with $warnings = empty 2. Go through all the warnings in the XML 3. Process each one into an array, with the data you want from it, then add it to $warnings 4. Sort the final array with usort 5. Loop over the array and display the results Code looks something like $warnings = []; // list of prioritized event types $priorities = [ "Tornado Warning" => 9, "Severe Thunderstorm Warning" => 8, "Flash Flood Warning" => 7 ]; // for each $entry { $warning = [ "entry" => $entry, // <id> is $warning["entry"]->id "cap" => $entry->children("cap", true) // <cap:effective> is $warning["cap"]->effective // other things? ]; // add priority $p = (string)$warning["cap"]->event; // php 5: if (isset($priorities[$p])) { $warning["priority"] = $p; } else { $warning["priority"] = 0; // lower than anything in $priorities } // php 7 (you should have this by now): //$warning["priority"] = ($priorities[$p] ?? 0); // maybe more data...? // finally add to list $warnings[] = $warning; // } // sort by comparing pairs of elements from the array usort($warnings, function($a, $b) { // return <0 if $a before $b, 0 if $a same rank as $b (try to avoid this), >0 if $a after $b // usort trick: get numeric values then use subtraction to "compare" them and end up with something that follows the above rule // first sort by priority if ($a["priority"] != $b["priority"]) { return $b["priority"] - $a["priority"]; // try the math in your head to see how this works } // sort by something else. effective date, earliest first? return strtotime($a["cap"]->effective) - strtotime($b["cap"]->effective); }); // now display foreach ($warnings as $warning) { // ... } Quote Link to comment Share on other sites More sharing options...
requinix Posted May 11, 2017 Share Posted May 11, 2017 For everyone's reference, each looks like <entry> <id>https://alerts.weather.gov/cap/wwacapget.php?x=AR12585024B610.SpecialWeatherStatement.125850256ED4AR.SHVSPSSHV.c94c6bdfd6f158c4839211f689a70233</id> <updated>2017-05-10T19:52:00-05:00</updated> <published>2017-05-10T19:52:00-05:00</published> <author> <name>w-nws.webmaster@noaa.gov</name> </author> <title>Special Weather Statement issued May 10 at 7:52PM CDT until further notice by NWS</title> <link href='https://alerts.weather.gov/cap/wwacapget.php?x=AR12585024B610.SpecialWeatherStatement.125850256ED4AR.SHVSPSSHV.c94c6bdfd6f158c4839211f689a70233'/> <summary>...SIGNIFICANT WEATHER ADVISORY FOR SOUTH CENTRAL LITTLE RIVER... SOUTHERN MILLER...CENTRAL CASS AND SOUTHEASTERN BOWIE COUNTIES UNTIL 815 PM CDT... At 752 PM CDT, Doppler radar was tracking a strong thunderstorm 7 miles north of Linden, or 12 miles west of Atlanta, moving northeast at 55 mph.</summary> <cap:event>Special Weather Statement</cap:event> <cap:effective>2017-05-10T19:52:00-05:00</cap:effective> <cap:expires>2017-05-11T00:25:00-05:00</cap:expires> <cap:status>Actual</cap:status> <cap:msgType>Alert</cap:msgType> <cap:category>Met</cap:category> <cap:urgency>Expected</cap:urgency> <cap:severity>Minor</cap:severity> <cap:certainty>Observed</cap:certainty> <cap:areaDesc>Little River; Miller</cap:areaDesc> <cap:polygon>33.25,-93.7 33.24,-93.73 33.23,-93.73 33.23,-93.7 33.22,-93.71 33.21,-93.74 32.97,-94.38 33.11,-94.53 33.63,-94.27 33.25,-93.7</cap:polygon> <cap:geocode> <valueName>FIPS6</valueName> <value>005081 005091</value> <valueName>UGC</valueName> <value>ARZ059 ARZ070</value> </cap:geocode> <cap:parameter> <valueName>VTEC</valueName> <value></value> </cap:parameter> </entry> Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.