A Tropo SMS/IM app that provides transit route and stop locations.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* Copyright 2010 Mark J. Headd | |
* | |
* This application is free software: you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation, either version 3 of the License, or | |
* (at your option) any later version. | |
* | |
* This application is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
*/ | |
require_once 'path/to/tropo.class.php'; | |
// Constants used to geocode an address. | |
define("MAPS_LOOKUP_BASE_URL", "http://maps.google.com/maps/geo"); | |
define("MAPS_LOOKUP_FORMAT", "xml"); | |
define("MAPS_API_KEY", "your-api-key-goes-here"); | |
// Configurable items. | |
define("DEFAULT_ERROR_MESSAGE", "An error occured. Try again later. :-("); | |
define("DEFAULT_NO_INFORMATION_MESSAGE", "No information was available to respond to your request. Try again..."); | |
define("DEFAULT_NUMBER_DEPARTURES", 3); | |
define("DEFAULT_ROUNDING_PRECISION", 2); | |
define("DEFAULT_STOP_DISTANCE", 5); | |
define("DEFAULT_NUMBER_STOPS", 3); | |
// Exception classes. | |
class DatabaseException extends Exception {} | |
class GeoCodeException extends Exception {} | |
/********************************************************************* | |
* Display methods. | |
*********************************************************************/ | |
// Get the latest departure times for a specific stop, identified by stopID. | |
function getDepartureTimes(&$tropo, $stopID) { | |
$sql = "CALL GetDepartureTimesAndRoutesByStopID($stopID, ".DEFAULT_NUMBER_DEPARTURES.", DAYOFWEEK(CURDATE()))"; | |
$result = runQuery($sql); | |
while ($row = $result->fetch_assoc()) { | |
$tropo->say("Route ". $row["route_id"]."/".$row["route_long_name"].", Departs in: ".$row["min_leaving"]); | |
} | |
} | |
// Get the closest transit stop given a specific address. | |
function getClosestStop(&$tropo, $address) { | |
$geoXML = new SimpleXmlElement(geoCodeAddress($address)); | |
$coordinates = $geoXML->Response->Placemark->Point->coordinates; | |
$coordinatesArray = explode(",", $coordinates); | |
$sql = "CALL GetClosestStopsByLocation($coordinatesArray[1], $coordinatesArray[0], ".DEFAULT_ROUNDING_PRECISION.", ".DEFAULT_STOP_DISTANCE.", ".DEFAULT_NUMBER_STOPS.")"; | |
$result = runQuery($sql); | |
while ($row = $result->fetch_assoc()) { | |
$tropo->say($row["stop_id"]."/". $row["stop_name"].", Distance: ".$row["DISTANCE"]." miles"); | |
} | |
} | |
/********************************************************************* | |
* Helper methods. | |
*********************************************************************/ | |
// Geocode an address. | |
function geoCodeAddress($address) { | |
// Format address and URL. | |
$address = str_replace(" ", "+", $address); | |
$url = MAPS_LOOKUP_BASE_URL."?q=".$address."&output=".MAPS_LOOKUP_FORMAT."&sensor=".false."&key=".MAPS_API_KEY; | |
// Set up cURL call. | |
$ch = curl_init($url); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | |
// Execute. | |
$output = curl_exec($ch); | |
$info = curl_getinfo($ch); | |
// Return results. | |
if($info['http_code'] != '200') { | |
throw new GeoCodeException(DEFAULT_ERROR_MESSAGE); | |
} | |
else { | |
return $output; | |
} | |
} | |
// Run an SQL query. | |
function runQuery($query) { | |
try { | |
$mysqli = new mysqli($_SERVER["TRANSIT_DB_HOST"], $_SERVER["TRANSIT_DB_USER"], $_SERVER["TRANSIT_DB_USER"], $_SERVER["TRANSIT_DB_USER"], $_SERVER["TRANSIT_DB_USER"]); | |
if (mysqli_connect_errno()) { | |
throw new Exception(DEFAULT_ERROR_MESSAGE); | |
} | |
$result = $mysqli->query($query); | |
if($result->num_rows > 0) { | |
return $result; | |
} | |
else { | |
throw new Exception(DEFAULT_NO_INFORMATION_MESSAGE); | |
} | |
} | |
catch (Exception $ex) { | |
throw new DatabaseException($ex->getMessage()); | |
} | |
} | |
// Instantiate a new Tropo object. | |
$tropo = new Tropo(); | |
// Get the incoming session information from Tropo | |
$session = new Session(); | |
// Access the initial text sent with the session. | |
$message = $session->getInitialText(); | |
try { | |
// If the user sent a stop number. | |
if(is_numeric($message)) { | |
getDepartureTimes($tropo, $message); | |
} | |
// If the user sent an address. | |
else { | |
getClosestStop($tropo, $message); | |
} | |
$tropo->renderJSON(); | |
} | |
// Handler for various database exceptions. | |
catch (DatabaseException $ex) { | |
$tropo->say($ex->getMessage()); | |
$tropo->renderJSON(); | |
} | |
// Handler for geocoding exceptions. | |
catch (GeoCodeException $ex) { | |
$tropo->say($ex->getMessage()); | |
$tropo->renderJSON(); | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment