Fix street closure service alerts
Fix street closure service alerts

--- a/include/common-request.inc.php
+++ b/include/common-request.inc.php
@@ -57,6 +57,12 @@
 if (isset($_REQUEST['stopids'])) {
     $stopids = explode(",", filter_var($_REQUEST['stopids'], FILTER_SANITIZE_STRING));
 }
+if (isset($_REQUEST['filterIncludeRoutes'])) {
+    $filterIncludeRoutes = explode(",", filter_var($_REQUEST['filterIncludeRoutes'], FILTER_SANITIZE_STRING));
+}
+if (isset($_REQUEST['filterHasStop'])) {
+    $filterHasStop = filter_var($_REQUEST['filterHasStop'], FILTER_SANITIZE_STRING);
+}
 if (isset($_REQUEST['tripid'])) {
     $tripid = filter_var($_REQUEST['tripid'], FILTER_SANITIZE_STRING);
 }

--- a/include/common-template.inc.php
+++ b/include/common-template.inc.php
@@ -42,7 +42,7 @@
 }
 
 function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false, $datepicker = false) {
-    global $basePath, $GTFSREnabled;
+    global $basePath, $GTFSREnabled, $stopid, $routeid;
     echo '
 <!DOCTYPE html> 
 <html lang="en">
@@ -59,14 +59,13 @@
         $jqmcss = $basePath . "css/jquery.mobile-$jqmVersion.css";
         $jqjs = $basePath . "js/jquery-1.6.4.min.js";
         $jqmjs = $basePath . "js/jquery.mobile-$jqmVersion.js";
-        
+
         $jqmcss = $basePath . "css/jquery.mobile-b90eab4935.css";
         $jqmjs = $basePath . "js/jquery.mobile-b90eab4935.js";
     } else {
         $jqmcss = "//code.jquery.com/mobile/$jqmVersion/jquery.mobile-$jqmVersion.min.css";
         $jqjs = "//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js";
         $jqmjs = "//code.jquery.com/mobile/$jqmVersion/jquery.mobile-$jqmVersion.min.js";
-
     }
     echo '<link rel="stylesheet"  href="' . $jqmcss . '" />
 	<script src="' . $jqjs . '"></script>
@@ -108,7 +107,7 @@
 }';
     echo '</style>';
     echo '<link rel="stylesheet"  href="' . $basePath . 'css/local.css.php" />';
-    if (isIOSDevice()){
+    if (isIOSDevice()) {
         echo '<meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  <link rel="apple-touch-startup-image" href="startup.png" />
@@ -174,19 +173,38 @@
         <a name="maincontent" id="maincontent"></a>
         <div data-role="content"> ';
         if ($GTFSREnabled) {
-        $overrides = getServiceOverride();
-        if (isset($overrides['service_id'])) {
-            if ($overrides['service_id'] == "noservice") {
-                echo '<div id="servicewarning">Buses are <strong>not running today</strong> due to industrial action/public holiday. See <a 
+            $overrides = getServiceOverride();
+            if (isset($overrides['service_id'])) {
+                if ($overrides['service_id'] == "noservice") {
+                    echo '<div id="servicewarning">Buses are <strong>not running today</strong> due to industrial action/public holiday. See <a 
 href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>';
-            } else {
-                echo '<div id="servicewarning">Buses are running on an altered timetable today due to industrial action/public holiday. See <a href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>';
-            }
-        }
-            $serviceAlerts = getServiceAlertsAsArray("agency", "0");
+                } else {
+                    echo '<div id="servicewarning">Buses are running on an altered timetable today due to industrial action/public holiday. See <a href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>';
+                }
+            }
+            $serviceAlerts = Array();
+            $globalAlerts = getServiceAlertsAsArray("agency", "0");
+            if ($globalAlerts != nullarray) {
+                $serviceAlerts = array_merge($serviceAlerts, $globalAlerts);
+            }
+            if (isset($stopid)) {
+                $stopAlerts = getServiceAlertsAsArray("stop", $stopid);
+                if ($stopAlerts != nullarray) {
+                    $serviceAlerts = array_merge($serviceAlerts, $stopAlerts);
+                }
+            }
+            if (isset($routeid)) {
+                $routeAlerts = getServiceAlertsAsArray("route", $routeid);
+                if ($routeAlerts != nullarray) {
+                    $serviceAlerts = array_merge($serviceAlerts, $routeAlerts);
+                }
+            }
             if (isset($serviceAlerts['entity']) && sizeof($serviceAlerts['entity']) > 0) {
                 foreach ($serviceAlerts['entity'] as $entity) {
-                    echo "<div id='servicewarning'>" . date("F j, g:i a", strtotime($entity['alert']['active_period'][0]['start'])) . " to " . date("F j, g:i a", strtotime($entity['alert']['active_period'][0]['end'])) . "{$entity['alert']['header_text']['translation'][0]['text']}<br>Warning: {$entity['alert']['description_text']['translation'][0]['text']} 
+                    echo "<div id='servicewarning'><b>{$entity['alert']['header_text']['translation'][0]['text']}</b>&nbsp;<small>"
+                    . date("F jS Y, g:i a", $entity['alert']['active_period'][0]['start']) . " to "
+                    . date("F jS Y, g:i a", $entity['alert']['active_period'][0]['end']) . "</small>
+                            <br>Warning: {$entity['alert']['description_text']['translation'][0]['text']} 
                             <br><a href='{$entity['alert']['url']['translation'][0]['text']}'>Source</a>  </div>";
                 }
             }
@@ -212,9 +230,10 @@
     }
     echo "\n</div></div></body></html>";
 }
+
 function timeSettings() {
     global $service_periods;
-echo '<div id="settings" data-role="collapsible" data-collapsed="true">
+    echo '<div id="settings" data-role="collapsible" data-collapsed="true">
 <h3>Change Time (' . (isset($_REQUEST['time']) ? $_REQUEST['time'] : "Current Time,") . ' ' . ucwords(service_period()) . ')...</h3>
         <form action="' . basename($_SERVER['PHP_SELF']) . '" method="GET">
                <input type="hidden" name="suburb" id="suburb" value="' . (isset($_REQUEST['suburb']) ? $_REQUEST['suburb'] : "") . '"/>
@@ -230,10 +249,10 @@
 		<div data-role="fieldcontain">
 		    <label for="service_period"> Service Period:  </label>
 			<select name="service_period" id="service_period">';
-foreach ($service_periods as $service_period) {
-    echo "<option value=\"$service_period\"" . (service_period() === $service_period ? " SELECTED" : "") . '>' . ucwords($service_period) . '</option>';
-}
-echo '</select>
+    foreach ($service_periods as $service_period) {
+        echo "<option value=\"$service_period\"" . (service_period() === $service_period ? " SELECTED" : "") . '>' . ucwords($service_period) . '</option>';
+    }
+    echo '</select>
 			<a href="#" style="display:none" name="currentPeriod" id="currentPeriod">Current Period?</a>
 		</div>
 		
@@ -241,8 +260,9 @@
                 </div></form>
             </div>';
 }
+
 function placeSettings() {
-    
+
     $geoerror = false;
     $geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == "";
 
@@ -275,14 +295,15 @@
 
 //stop list collapsing
 function stopCompare($stopName) {
-    return substr(trim(preg_replace("/\(Platform.*/", "", $stopName)),0,9);
-}
-function stopGroupTitle($stopName,$stopdesc) {
-    if (preg_match("/Dr |Cct |Cir |Av |St |Cr |Parade |Way |Bank /",$stopName)) {
-        $descParts =  explode("<br>",$stopdesc);
-         return trim(str_replace("Street: ","",$descParts[0]));
+    return substr(trim(preg_replace("/\(Platform.*/", "", $stopName)), 0, 9);
+}
+
+function stopGroupTitle($stopName, $stopdesc) {
+    if (preg_match("/Dr |Cct |Cir |Av |St |Cr |Parade |Way |Bank /", $stopName)) {
+        $descParts = explode("<br>", $stopdesc);
+        return trim(str_replace("Street: ", "", $descParts[0]));
     } else {
-        return trim(preg_replace("/\(Platform.*/", "",$stopName));
+        return trim(preg_replace("/\(Platform.*/", "", $stopName));
     }
 }
 

--- a/include/common-transit.inc.php
+++ b/include/common-transit.inc.php
@@ -149,69 +149,96 @@
           street inform: route inform, trip inform, stop inform
           route patch: trip remove
          */
-        $fm = new transit_realtime\FeedMessage();
-        $fh = new transit_realtime\FeedHeader();
-        $fh->setGtfsRealtimeVersion(1);
-        $fh->setTimestamp(time());
-        $fm->setHeader($fh);
-        foreach (getCurrentAlerts() as $alert) {
-            $fe = new transit_realtime\FeedEntity();
-            $fe->setId($alert['id']);
-            $fe->setIsDeleted(false);
-            $alert = new transit_realtime\Alert();
-            $tr = new transit_realtime\TimeRange();
-            $tr->setStart($alert['start']);
-            $tr->setEnd($alert['end']);
-            $alert->addActivePeriod($tr);
-            $informedEntities = getInformedAlerts($alert['id'], $_REQUEST['filter_class'], $_REQUEST['filter_id']);
-            if (sizeof($informedEntities) > 0) {
-                $informed = Array();
-                $es = new transit_realtime\EntitySelector();
-                if ($informedEntity['informed_class'] == "agency") {
-                    $es->setAgencyId($informedEntity['informed_id']);
-                }
-                if ($informedEntity['informed_class'] == "stop") {
-                    $es->setStopId($informedEntity['informed_id']);
-                }
-                if ($informedEntity['informed_class'] == "route") {
-                    $es->setRouteId($informedEntity['informed_id']);
-                }
-                if ($informedEntity['informed_class'] == "trip") {
-                    $td = new transit_realtime\TripDescriptor();
-                    $td->setTripId($informedEntity['informed_id']);
-                    $es->setTrip($td);
-                }
-                $alert->addInformedEntity($es);
-            }
-            $alert->setCause(constant("transit_realtime\Alert\Cause::" . $alert['cause']));
-            $alert->setEffect(constant("transit_realtime\Alert\Effect::" . $alert['effect']));
-            $tsUrl = new transit_realtime\TranslatedString();
-            $tUrl = new transit_realtime\TranslatedString\Translation();
-            $tUrl->setText($alert['url']);
-            $tUrl->setLanguage("en");
-            $tsUrl->addTranslation($tUrl);
-            $alert->setUrl($tsUrl);
-            $tsHeaderText = new transit_realtime\TranslatedString();
-            $tHeaderText = new transit_realtime\TranslatedString\Translation();
-            $tHeaderText->setText($alert['header']);
-            $tHeaderText->setLanguage("en");
-            $tsHeaderText->addTranslation($tHeaderText);
-            $alert->setHeaderText($tsHeaderText);
-            $tsDescriptionText = new transit_realtime\TranslatedString();
-            $tDescriptionText = new transit_realtime\TranslatedString\Translation();
-            $tDescriptionText->setText($alert['description']);
-            $tDescriptionText->setLanguage("en");
-            $tsDescriptionText->addTranslation($tDescriptionText);
-            $alert->setDescriptionText($tsDescriptionText);
-            $fe->setAlert($alert);
-            $fm->addEntity($fe);
+        $current_alerts = getCurrentAlerts();
+        $informed_count = 0;
+        if (sizeof($current_alerts) > 0) {
+            $fm = new transit_realtime\FeedMessage();
+            $fh = new transit_realtime\FeedHeader();
+            $fh->setGtfsRealtimeVersion(1);
+            $fh->setTimestamp(time());
+            $fm->setHeader($fh);
+            foreach ($current_alerts as $current_alert) {
+                $fe = new transit_realtime\FeedEntity();
+                $fe->setId($current_alert['id']);
+                $fe->setIsDeleted(false);
+                $alert = new transit_realtime\Alert();
+                $tr = new transit_realtime\TimeRange();
+                $tr->setStart($current_alert['start']);
+                $tr->setEnd($current_alert['end']);
+                $alert->addActivePeriod($tr);
+                $informedEntities = getInformedAlerts($current_alert['id'], $filter_class, $filter_id);
+                if (sizeof($informedEntities) > 0) {
+                    $informed_count++;
+                    $informed = Array();
+                    $es = new transit_realtime\EntitySelector();
+                    if ($informedEntity['informed_class'] == "agency") {
+                        $es->setAgencyId($informedEntity['informed_id']);
+                    }
+                    if ($informedEntity['informed_class'] == "stop") {
+                        $es->setStopId($informedEntity['informed_id']);
+                    }
+                    if ($informedEntity['informed_class'] == "route") {
+                        $es->setRouteId($informedEntity['informed_id']);
+                    }
+                    if ($informedEntity['informed_class'] == "trip") {
+                        $td = new transit_realtime\TripDescriptor();
+                        $td->setTripId($informedEntity['informed_id']);
+                        $es->setTrip($td);
+                    }
+                    $alert->addInformedEntity($es);
+                }
+                if ($current_alert['cause'] != "") {
+                    $alert->setCause(constant("transit_realtime\Alert\Cause::" . $current_alert['cause']));
+                }
+                if ($current_alert['effect'] != "") {
+                    $alert->setEffect(constant("transit_realtime\Alert\Effect::" . $current_alert['effect']));
+                }
+                if ($current_alert['url'] != "") {
+                    $tsUrl = new transit_realtime\TranslatedString();
+                    $tUrl = new transit_realtime\TranslatedString\Translation();
+                    $tUrl->setText($current_alert['url']);
+                    $tUrl->setLanguage("en");
+                    $tsUrl->addTranslation($tUrl);
+                    $alert->setUrl($tsUrl);
+                }
+                if ($current_alert['header'] != "") {
+                    $tsHeaderText = new transit_realtime\TranslatedString();
+                    $tHeaderText = new transit_realtime\TranslatedString\Translation();
+                    $tHeaderText->setText($current_alert['header']);
+                    $tHeaderText->setLanguage("en");
+                    $tsHeaderText->addTranslation($tHeaderText);
+                    $alert->setHeaderText($tsHeaderText);
+                }
+                if ($current_alert['description'] != "") {
+                    $tsDescriptionText = new transit_realtime\TranslatedString();
+                    $tDescriptionText = new transit_realtime\TranslatedString\Translation();
+                    $tDescriptionText->setText($current_alert['description']);
+                    $tDescriptionText->setLanguage("en");
+                    $tsDescriptionText->addTranslation($tDescriptionText);
+                    $alert->setDescriptionText($tsDescriptionText);
+                }
+                $fe->setAlert($alert);
+                $fm->addEntity($fe);
+            }
+            if ($informed_count > 0) {
+                return $fm;
+            } else {
+                return null;
+            }
+        } else
+            return null;
+    }
+
+    function getServiceAlertsAsArray($filter_class = "", $filter_id = "") {
+        
+        $alerts = getServiceAlerts($filter_class, $filter_id);
+        if ($alerts != null) {
+            $codec = new DrSlump\Protobuf\Codec\PhpArray();
+
+            return $codec->encode($alerts);
+        } else {
+            return nullarray;
         }
-        return $fm;
-    }
-
-    function getServiceAlertsAsArray($filter_class = "", $filter_id = "") {
-        $codec = new DrSlump\Protobuf\Codec\PhpArray();
-        return $codec->encode(getServiceAlerts($filter_class, $filter_id));
     }
 
     function getServiceAlertsAsBinary($filter_class = "", $filter_id = "") {

--- a/include/db/route-dao.inc.php
+++ b/include/db/route-dao.inc.php
@@ -97,7 +97,7 @@
 function getRoutesByNumberSeries($routeNumberSeries = "") {
     global $conn;
     if (strlen($routeNumberSeries) == 1) {
-        return getRoutesByNumber($routeNumberSeries);
+        return getRoute($routeNumberSeries);
     }
     $seriesMin = substr($routeNumberSeries, 0, -1) . "0";
     $seriesMax = substr($routeNumberSeries, 0, -1) . "9";

--- a/include/db/servicealert-dao.inc.php
+++ b/include/db/servicealert-dao.inc.php
@@ -44,17 +44,19 @@
     return $query->fetch(PDO :: FETCH_ASSOC);
 }
 
-function updateServiceAlert($alertID, $start, $end, $header, $description, $url) {
+function updateServiceAlert($alertID, $alert) {
     global $conn;
-    $query = 'update servicealerts_alerts set start=:start, "end"=:end, header=:header, description=:description, url=:url where id = :servicealert_id';
+    $query = 'update servicealerts_alerts set start=:start, "end"=:end, header=:header, description=:description, url=:url, cause=:cause, effect=:effect where id = :servicealert_id';
     debug($query, "database");
     $query = $conn->prepare($query);
-    $query->bindParam(":servicealert_id", $alertID);
-    $query->bindParam(":start", $start);
-    $query->bindParam(":end", $end);
-    $query->bindParam(":header", $header);
-    $query->bindParam(":description", $description);
-    $query->bindParam(":url", $url);
+    $query->bindValue(":servicealert_id", $alertID);
+    $query->bindValue(":start", $alert['startdate']);
+    $query->bindValue(":end", $alert['enddate']);
+    $query->bindValue(":header", $alert['header']);
+    $query->bindValue(":description", $alert['description']);
+    $query->bindValue(":url", $alert['url']);
+    $query->bindValue(":cause", $alert['cause']);
+    $query->bindValue(":effect", $alert['effect']);
     $query->execute();
 
     print_r($conn->errorInfo());
@@ -65,16 +67,19 @@
     return $query->fetch(PDO :: FETCH_ASSOC);
 }
 
-function addServiceAlert($start, $end, $header, $description, $url) {
+function addServiceAlert($alert) {
     global $conn;
-    $query = 'INSERT INTO servicealerts_alerts (start, "end", header, description, url) VALUES (:start, :end, :header, :description, :url) ';
+    $query = 'INSERT INTO servicealerts_alerts (start, "end", header, description, url,cause,effect) VALUES (:start, :end, :header, :description, :url,:cause,:effect) ';
     debug($query, "database");
     $query = $conn->prepare($query);
-    $query->bindParam(":start", $start);
-    $query->bindParam(":end", $end);
-    $query->bindParam(":header", $header);
-    $query->bindParam(":description", $description);
-    $query->bindParam(":url", $url);
+    //print_r($alert);
+    $query->bindValue(":start", $alert['startdate']);
+    $query->bindValue(":end", $alert['enddate']);
+    $query->bindValue(":header", $alert['header']);
+    $query->bindValue(":description", $alert['description']);
+    $query->bindValue(":url", $alert['url']);
+    $query->bindValue(":cause", $alert['cause']);
+    $query->bindValue(":effect", $alert['effect']);
     $query->execute();
 
     print_r($conn->errorInfo());
@@ -158,12 +163,14 @@
 
 function addInformedAlert($serviceAlertID, $class, $id, $action) {
     global $conn;
-    $query = 'INSERT INTO servicealerts_informed (servicealert_id , informed_class , informed_id) VALUES(:servicealert_id ,:informed_class, :informed_id)';
+    $query = 'INSERT INTO servicealerts_informed (servicealert_id , informed_class , informed_id, informed_action) 
+        VALUES(:servicealert_id ,:informed_class, :informed_id, :informed_action)';
     debug($query, "database");
     $query = $conn->prepare($query);
     $query->bindParam(":servicealert_id", $serviceAlertID);
     $query->bindParam(":informed_class", $class);
     $query->bindParam(":informed_id", $id);
+    $query->bindParam(":informed_action", $action);
     $query->execute();
 
     print_r($conn->errorInfo());

--- a/include/db/stop-dao.inc.php
+++ b/include/db/stop-dao.inc.php
@@ -89,7 +89,7 @@
     $query = "Select * from stops where stop_name LIKE :name;";
     debug($query, "database");
     $query = $conn->prepare($query);
-    $name = "%" . $name . ";%";
+    $name = $name . "%";
     $query->bindParam(":name", $name);
     $query->execute();
     if (!$query) {

--- a/include/db/trip-dao.inc.php
+++ b/include/db/trip-dao.inc.php
@@ -51,6 +51,25 @@
     }
     return $query->fetchAll();
 }
+
+function getTripHasStop($tripID, $stopID) {
+        global $conn;
+    $query = "SELECT stop_id
+FROM stop_times
+join trips on trips.trip_id = stop_times.trip_id
+WHERE trips.trip_id = :tripID and stop_times.stop_id = :stopID";
+    debug($query, "database");
+    $query = $conn->prepare($query);
+    $query->bindParam(":tripID", $tripID);
+    $query->bindParam(":stopID", $stopID);
+    $query->execute();
+    if (!$query) {
+        databaseError($conn->errorInfo());
+        return Array();
+    }
+    return ($query->fetchColumn() > 0);
+}
+
 function getTripShape($tripID) {
     // todo, use shapes table if shape_id specified
     global $conn;

--- a/servicealerts/servicealert_editor.php
+++ b/servicealerts/servicealert_editor.php
@@ -27,10 +27,11 @@
  */
 if (isset($_REQUEST['saveedit'])) {
 
-    if ($_REQUEST['saveedit'] != "")
-        updateServiceAlert($_REQUEST['saveedit'], $_REQUEST['startdate'], $_REQUEST['enddate'], $_REQUEST['header'], $_REQUEST['description'], $_REQUEST['url']);
-    else
-        addServiceAlert($_REQUEST['startdate'], $_REQUEST['enddate'], $_REQUEST['description'], $_REQUEST['url']);
+    if ($_REQUEST['saveedit'] != "") {
+        updateServiceAlert($_REQUEST['saveedit'], $_REQUEST);
+    } else {
+        addServiceAlert($_REQUEST);
+    }
     echo "Saved " . $_REQUEST['saveedit'];
     die();
 }
@@ -61,26 +62,27 @@
 if ($_REQUEST['streetsearch']) {
 
     echo "Informing stops of street<br>\n";
-    foreach (getStopByName() as $stop) {
-        addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "inform");
-        echo "Added stop inform for" . $_REQUEST['stopsearch'] . ", stop" . $_REQUEST['stopid'] . "<br>\n";
+    foreach (getStopsByName($_REQUEST['street']) as $stop) {
+        addInformedAlert($_REQUEST['streetsearch'], "stop", $stop['stop_id'], "inform");
+        echo "Added stop inform for" . $_REQUEST['streetsearch'] . ", stop" . $stop['stop_id'] . " ". $stop['stop_name']."<br>\n";
 
         foreach ($service_periods as $sp) {
             echo "Informing $sp routes<br>\n";
-            foreach (getStopRoutes($_REQUEST['stopid'], $sp) as $route) {
-                addInformedAlert($_REQUEST['stopsearch'], "route", $route['route_id'], "inform");
-                echo "Added route inform for stop" . $_REQUEST['stopsearch'] . ", route" . $route['route_id'] . "<br>\n";
+            foreach (getStopRoutes($stop['stop_id'], $sp) as $route) {
+                addInformedAlert($_REQUEST['streetsearch'], "route", $route['route_id'], "inform");
+                echo "Added route inform for stop" . $_REQUEST['streetsearch'] . ", route" . $route['route_id'] . "<br>\n";
             }
         }
+    }
+    
         die();
-    }
 }
 ?>
 Active and Future Alerts:
 <table>
     <?php
     foreach (getFutureAlerts() as $alert) {
-        echo "<tr><td>{$alert['start']}</td><td>{$alert['end']}</td><td>" . substr($alert['description'], 0, 999) . '</td><td><a href="?edit=' . $alert['id'] . '">edit</a></td></tr>';
+        echo "<tr><td>" . date("c", $alert['start']) . "</td><td>" . date("c", $alert['end']) . "</td><td>" . substr($alert['description'], 0, 999) . '</td><td><a href="?edit=' . $alert['id'] . '">edit</a></td></tr>';
     }
     ?>
 </table>
@@ -94,7 +96,7 @@
         <label for="startdate"> Start Date</label>
         <input type="text" name="startdate" id="startdate" value="<?php
       if ($alert['start'])
-          echo $alert['start'];
+          echo date("c", $alert['start']);
       else
           echo date("c", strtotime("0:00"));
 ?>"  />
@@ -102,10 +104,10 @@
     <div data-role="fieldcontain">
         <label for="enddate"> End Date </label>
         <input type="text" name="enddate" id="enddate" value="<?php
-      if ($alert['end'])
-          echo $alert['end'];
-      else
-          echo date("c", strtotime("23:59"));
+               if ($alert['end'])
+                   echo date("c", $alert['end']);
+               else
+                   echo date("c", strtotime("23:59"));
 ?>"  />
     </div>
     <div data-role="fieldcontain">
@@ -115,12 +117,31 @@
     <div data-role="fieldcontain">
         <label for="description">Description</label>
         <textarea name="description">
-<?php echo $alert['description']; ?></textarea>
+            <?php echo $alert['description']; ?></textarea>
     </div>
     <div data-role="fieldcontain">
         <label for="url">URL</label>
         <input type="text" name="url" id="url" value="<?php echo $alert['url']; ?>"  />
     </div>
+    <div data-role="fieldcontain">
+        <label for="cause"> Cause:  </label>
+        <select name="cause" id="cause">
+            
+            <?php
+            foreach ($serviceAlertCause as $key => $value) {
+                echo "<option value=\"$key\"" . ($key === $alert['cause'] ? " SELECTED" : "") . '>' . $value . '</option>';
+            }
+            ?>
+        </select></div>
+    <div data-role="fieldcontain">
+        <label for="effect"> Effect:  </label>
+        <select name="effect" id="effect">
+            <?php
+            foreach ($serviceAlertEffect as $key => $value) {
+                echo "<option value=\"$key\"" . ($key === $alert['effect'] ? " SELECTED" : "") . '>' . $value . '</option>';
+            }
+            ?>
+        </select></div>
     <input type="hidden" name="saveedit" value="<?php echo $_REQUEST['edit']; ?>"/>
     <input type="submit" value="Save"/>
 </div></form>

file:a/stop.php -> file:b/stop.php
--- a/stop.php
+++ b/stop.php
@@ -74,10 +74,10 @@
     }
 }
 if (sizeof($stops) > 0) {
-$stopDescParts = explode("<br>",$stop['stop_desc']);
-include_header(trim(str_replace("Street: ","",$stopDescParts[0])), "stop");
+    $stopDescParts = explode("<br>", $stop['stop_desc']);
+    include_header(trim(str_replace("Street: ", "", $stopDescParts[0])), "stop");
 } else {
-    include_header($stop['stop_name']);
+    include_header($stop['stop_name'], "stop");
 }
 /* $serviceAlerts = json_decode(getPage(curPageURL() . "/servicealerts_api.php?filter_class=stop&filter_id=".$stopid) , true);
 
@@ -108,15 +108,15 @@
     sktimesort($allStopsTrips, "arrival_time", true);
     $trips = $allStopsTrips;
 } else {
-    $trips = getStopTripsWithTimes($stopid);
+    $trips = getStopTripsWithTimes($stopid, "", "", "", (isset($filterIncludeRoutes) || isset($filterHasStop) ? "75" : ""));
 }
 
 echo "<div class='ui-header' style='overflow: visible; height: 2.5em'>";
 // if we have too many trips, cut down to size.
-if (sizeof($trips) > 10) {
-    $trips = array_splice($trips, 0,10);
+if (!isset($filterIncludeRoutes) && !isset($filterHasStop) && sizeof($trips) > 10) {
+    $trips = array_splice($trips, 0, 10);
 }
-    
+
 // later/earlier button setup
 if (sizeof($trips) == 0) {
     $time = isset($_REQUEST['time']) ? strtotime($_REQUEST['time']) : time();
@@ -141,29 +141,35 @@
     echo "<li style='text-align: center;'>No trips in the near future.</li>";
 } else {
     foreach ($trips as $trip) {
-        echo '<li>';
+        if (
+                isset($filterHasStop) && (getTripHasStop($trip['trip_id'], $filterHasStop) == 1)
+                || (isset($filterIncludeRoutes) && in_array($trip["route_short_name"], $filterIncludeRoutes))
+                || (!isset($filterIncludeRoutes) && !isset($filterHasStop))
+        ) {
+            echo '<li>';
 
-        $destination = getTripDestination($trip['trip_id']);
-        echo '<a href="trip.php?stopid=' . $stopid . '&amp;tripid=' . $trip['trip_id'] . '"><h3>'. $trip['route_short_name'] . " towards " . $destination['stop_name'] . "</h3><p>";
-        $viaPoints = viaPointNames($trip['trip_id'], $trip['stop_sequence']);
-        if ($viaPoints != "")
-            echo '<br><span class="viaPoints">Via: ' . $viaPoints . '</span>';
-        if (sizeof($tripStopNumbers) > 0) {
-            echo '<br><small>Boarding At: ';
-            if (sizeof($tripStopNumbers[$trip['trip_id']]) == sizeof($stopids)) {
-                echo "All Stops";
-            } else {
-                foreach ($tripStopNumbers[$trip['trip_id']] as $key) {
-                    echo $stopNames[$key] . ', ';
+            $destination = getTripDestination($trip['trip_id']);
+            echo '<a href="trip.php?stopid=' . $stopid . '&amp;tripid=' . $trip['trip_id'] . '"><h3>' . $trip['route_short_name'] . " towards " . $destination['stop_name'] . "</h3><p>";
+            $viaPoints = viaPointNames($trip['trip_id'], $trip['stop_sequence']);
+            if ($viaPoints != "")
+                echo '<br><span class="viaPoints">Via: ' . $viaPoints . '</span>';
+            if (sizeof($tripStopNumbers) > 0) {
+                echo '<br><small>Boarding At: ';
+                if (sizeof($tripStopNumbers[$trip['trip_id']]) == sizeof($stopids)) {
+                    echo "All Stops";
+                } else {
+                    foreach ($tripStopNumbers[$trip['trip_id']] as $key) {
+                        echo $stopNames[$key] . ', ';
+                    }
                 }
+                echo '</small>';
             }
-            echo '</small>';
+            echo '</p>';
+            echo '<p class="ui-li-aside"><strong>' . $trip['arrival_time'] . '</strong></p>';
+            echo '</a></li>';
+            flush();
+            @ob_flush();
         }
-        echo '</p>';
-        echo '<p class="ui-li-aside"><strong>' . $trip['arrival_time'] . '</strong></p>';
-        echo '</a></li>';
-        flush();
-        @ob_flush();
     }
 }
 echo '</ul>';