--- a/include/common-transit.inc.php +++ b/include/common-transit.inc.php @@ -1,143 +1,304 @@ <?php + +/* + * Copyright 2010,2011 Alexander Sadleir + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ $service_periods = Array( - 'sunday', - 'saturday', - 'weekday' + 'sunday', + 'saturday', + 'weekday' ); -function service_period($date = "") -{ - - if (isset($_SESSION['service_period'])) return $_SESSION['service_period']; - $override = getServiceOverride($date); - if ($override['service_id']){ - return $override['service_id']; - } - - switch (date('w',($date != "" ? $date : time()))) { - case 0: - return 'sunday'; - case 6: - return 'saturday'; - default: - return 'weekday'; - } -} -function midnight_seconds($time = "") -{ - // from http://www.perturb.org/display/Perlfunc__Seconds_Since_Midnight.html - if ($time != "") { - return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); - } - if (isset($_SESSION['time'])) { - $time = strtotime($_SESSION['time']); - return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); - } - return (date("G") * 3600) + (date("i") * 60) + date("s"); -} -function midnight_seconds_to_time($seconds) -{ - if ($seconds > 0) { - $midnight = mktime(0, 0, 0, date("n") , date("j") , date("Y")); - return date("h:ia", $midnight + $seconds); - } - else { - return ""; - } -} - -$serviceAlertCause = Array( -"UNKNOWN_CAUSE" => "Unknown cause", -"OTHER_CAUSE" => "Other cause", -"TECHNICAL_PROBLEM" => "Technical problem", -"STRIKE" => "Strike", -"DEMONSTRATION" => "Demonstration", -"ACCIDENT" => "Accident", -"HOLIDAY" => "Holiday", -"WEATHER" => "Weather", -"MAINTENANCE" => "Maintenance", -"CONSTRUCTION" => "Construction", -"POLICE_ACTIVITY" => "Police activity", -"MEDICAL_EMERGENCY" => "Medical emergency" -); -$serviceAlertEffect = Array( -"NO_SERVICE" => "No service", -"REDUCED_SERVICE" => "Reduced service", -"SIGNIFICANT_DELAYS" => "Significant delays", -"DETOUR" => "Detour", -"ADDITIONAL_SERVICE" => "Additional service", -"MODIFIED_SERVICE" => "Modified service", -"OTHER_EFFECT" => "Other effect", -"UNKNOWN_EFFECT" => "Unknown effect", -"STOP_MOVED" => "Stop moved"); - -function getServiceAlerts($filter_class, $filter_id) { -/* - - also need last modified epoch of client gtfs - - - add,remove,patch,inform (null) - - stop - - trip - - network +function service_period($date = "") { + + if (isset($_REQUEST['service_period'])) { + return $_REQUEST['service_period']; + } + + $override = getServiceOverride($date); + if (isset($override['service_id'])) { + return strtolower($override['service_id']); + } + $date = ($date != "" ? $date : time()); + $dow = date('w', $date); + + switch ($dow) { + case 0: + return 'sunday'; + case 6: + return 'saturday'; + default: + return 'weekday'; + } +} + +function service_ids($service_period, $date = "") { + switch ($service_period) { + case 'sunday': + return Array("Sunday", "Sunday"); + case 'saturday': + return Array("Saturday", "Saturday"); + default: + $date = ($date != "" ? $date : time()); +// school holidays + $ymd = date('Ymd', $date); + $dow = date('w', $date); + if (intval($ymd) < "20120203" && $dow != 0 && $dow != 6) { + return Array("Weekday-SchoolVacation", "Weekday-SchoolVacation"); + } else { + return Array("Weekday", "Weekday"); + } + } +} + +function valid_service_ids() { + return array_merge(service_ids(""), service_ids('saturday'), service_ids('sunday')); +} + +function midnight_seconds($time = "") { + // from http://www.perturb.org/display/Perlfunc__Seconds_Since_Midnight.html + if ($time != "") { + return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); + } + if (isset($_SESSION['time'])) { + $time = strtotime($_SESSION['time']); + return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); + } + return (date("G") * 3600) + (date("i") * 60) + date("s"); +} + +function midnight_seconds_to_time($seconds) { + if ($seconds > 0) { + $midnight = mktime(0, 0, 0, date("n"), date("j"), date("Y")); + return date("h:ia", $midnight + $seconds); + } else { + return ""; + } +} + +if ($GTFSREnabled) { + $serviceAlertCause = Array( + "UNKNOWN_CAUSE" => "Unknown cause", + "OTHER_CAUSE" => "Other cause", + "TECHNICAL_PROBLEM" => "Technical problem", + "STRIKE" => "Strike", + "DEMONSTRATION" => "Demonstration", + "ACCIDENT" => "Accident", + "HOLIDAY" => "Holiday", + "WEATHER" => "Weather", + "MAINTENANCE" => "Maintenance", + "CONSTRUCTION" => "Construction", + "POLICE_ACTIVITY" => "Police activity", + "MEDICAL_EMERGENCY" => "Medical emergency" + ); + $serviceAlertEffect = Array( + "NO_SERVICE" => "No service", + "REDUCED_SERVICE" => "Reduced service", + "SIGNIFICANT_DELAYS" => "Significant delays", + "DETOUR" => "Detour", + "ADDITIONAL_SERVICE" => "Additional service", + "MODIFIED_SERVICE" => "Modified service", + "OTHER_EFFECT" => "Other effect", + "UNKNOWN_EFFECT" => "Unknown effect", + "STOP_MOVED" => "Stop moved"); + + set_include_path(get_include_path() . PATH_SEPARATOR . ($basePath . "lib/Protobuf-PHP/library/DrSlump/")); + + include_once("Protobuf.php"); + include_once("Protobuf/Message.php"); + include_once("Protobuf/Registry.php"); + include_once("Protobuf/Descriptor.php"); + include_once("Protobuf/Field.php"); + + include_once($basePath . "lib/Protobuf-PHP/gtfs-realtime.php"); + include_once("Protobuf/CodecInterface.php"); + include_once("Protobuf/Codec/PhpArray.php"); + include_once("Protobuf/Codec/Binary.php"); + include_once("Protobuf/Codec/Binary/Writer.php"); + include_once("Protobuf/Codec/Json.php"); + + function getServiceAlerts($filter_class = "", $filter_id = "") { + /* + + also need last modified epoch of client gtfs + + - add,remove,patch,inform (null) + - stop + - trip + - network - classes (WHERE=) - - route (short_name or route_id) - - street - - stop - - trip - Currently support: - network inform - trip patch: stop remove - street inform: route inform, trip inform, stop inform - route patch: trip remove - */ -$return = Array(); -$return['header']['gtfs_realtime_version'] = "1"; -$return['header']['timestamp'] = time(); -$return['header']['incrementality'] = "FULL_DATASET"; -$return['entities'] = Array(); -foreach(getCurrentAlerts() as $alert) { - $informedEntities = getInformedAlerts($alert['id'],$_REQUEST['filter_class'],$_REQUEST['filter_id']); - if (sizeof($informedEntities) >0) { - $entity = Array(); - $entity['id'] = $alert['id']; - $entity['alert']['active_period']['start'] = $alert['start']; - $entity['alert']['active_period']['end'] = $alert['end']; - $entity['alert']['url']['translation']['text'] = $alert['url']; - $entity['alert']['url']['translation']['language'] = 'en'; - $entity['alert']['header_text']['translation']['text'] = $alert['header']; - $entity['alert']['header_text']['translation']['language'] = 'en'; - $entity['alert']['description_text']['translation']['text'] = $alert['description']; - $entity['alert']['description_text']['translation']['language'] = 'en'; - - foreach ($informedEntities as $informedEntity) { - $informed = Array(); - $informed[$informedEntity['informed_class']."_id"] = $informedEntity['informed_id']; - if ($informedEntity['informed_action'] != "") $informed["x-action"] = $informedEntity['informed_action']; - $informed[$informedEntity['class']."_type"] = $informedEntity['type']; - $entity['informed'][] = $informed; - } - $return['entities'][] = $entity; - } -} -return $return; -} -function getServiceAlertsByClass() { - $return = Array(); - $alerts = getServiceAlerts("",""); - foreach ($alerts['entities'] as $entity) { - foreach ($entity['informed'] as $informed) { - foreach($informed as $key => $value){ - if (strpos("_id",$key) > 0) { - $parts = explode($key); - $class = $parts[0]; - $id = $value; - } - } - $return[$class][$id][]['entity'] = $entity; - $return[$class][$id][]['action'] = $informed["x-action"]; - } - } -} -?> - + - route (short_name or route_id) + - street + - stop + - trip + Currently support: + network inform + trip patch: stop remove + 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); + } + 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 = "") { + $codec = new DrSlump\Protobuf\Codec\Binary(); + return $codec->encode(getServiceAlerts($filter_class, $filter_id)); + } + + function getServiceAlertsAsJSON($filter_class = "", $filter_id = "") { + $codec = new DrSlump\Protobuf\Codec\Json(); + return $codec->encode(getServiceAlerts($filter_class, $filter_id)); + } + + function getServiceAlertsByClass() { + $return = Array(); + $alerts = getServiceAlertsAsArray("", ""); + foreach ($alerts['entities'] as $entity) { + foreach ($entity['informed'] as $informed) { + foreach ($informed as $key => $value) { + if (strpos("_id", $key) > 0) { + $parts = explode($key); + $class = $parts[0]; + $id = $value; + } + } + $return[$class][$id][] = $entity; + } + } + } + + function getTripUpdates($filter_class = "", $filter_id = "") { + $fm = new transit_realtime\FeedMessage(); + $fh = new transit_realtime\FeedHeader(); + $fh->setGtfsRealtimeVersion(1); + $fh->setTimestamp(time()); + $fm->setHeader($fh); + foreach (getCurrentAlerts() as $alert) { + $informedEntities = getInformedAlerts($alert['id'], $_REQUEST['filter_class'], $_REQUEST['filter_id']); + $stops = Array(); + $routestrips = Array(); + if (sizeof($informedEntities) > 0) { + if ($informedEntity['informed_class'] == "stop" && $informed["x-action"] == "remove") { + $stops[] = $informedEntity['informed_id']; + } + if (($informedEntity['informed_class'] == "route" || $informedEntity['informed_class'] == "trip") && $informed["x-action"] == "patch") { + $routestrips[] = Array("id" => $informedEntity['informed_id'], + "type" => $informedEntity['informed_class']); + } + } + foreach ($routestrips as $routetrip) { + $fe = new transit_realtime\FeedEntity(); + $fe->setId($alert['id'] . $routetrip['id']); + $fe->setIsDeleted(false); + $tu = new transit_realtime\TripUpdate(); + $td = new transit_realtime\TripDescriptor(); + if ($routetrip['type'] == "route") { + $td->setRouteId($routetrip['id']); + } else if ($routetrip['type'] == "trip") { + $td->setTripId($routetrip['id']); + } + $tu->setTrip($td); + foreach ($stops as $stop) { + $stu = new transit_realtime\TripUpdate\StopTimeUpdate(); + $stu->setStopId($stop); + $stu->setScheduleRelationship(transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship::SKIPPED); + $tu->addStopTimeUpdate($stu); + } + $fe->setTripUpdate($tu); + $fm->addEntity($fe); + } + } + return $fm; + } + + function getTripUpdatesAsArray($filter_class = "", $filter_id = "") { + $codec = new DrSlump\Protobuf\Codec\PhpArray(); + return $codec->encode(getTripUpdates($filter_class, $filter_id)); + } + + function getTripUpdatesAsBinary($filter_class = "", $filter_id = "") { + $codec = new DrSlump\Protobuf\Codec\Binary(); + return $codec->encode(getTripUpdates($filter_class, $filter_id)); + } + + function getTripUpdatesAsJSON($filter_class = "", $filter_id = "") { + $codec = new DrSlump\Protobuf\Codec\Json(); + return $codec->encode(getTripUpdates($filter_class, $filter_id)); + } + +} +