Skip to content

Instantly share code, notes, and snippets.

@mheadd
Created November 2, 2010 15:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mheadd/659768 to your computer and use it in GitHub Desktop.
Save mheadd/659768 to your computer and use it in GitHub Desktop.
A Tropo SMS/IM app that provides transit route and stop locations.
<?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