Example #1
0
 /**
  * Search for routes going from from to to
  * @return array
  * @param string $from
  * @param string $to
  * @param mixed $time
  */
 public function search($from, $to, $time = false, $weekday = false, $limit = 5, $offset = 0, $timer = false)
 {
     if ($timer) {
         $timer->tick("search", "Entering RouteSearch::search");
     }
     if (!$weekday) {
         $weekday = (int) date("w");
     }
     if ($weekday == 0) {
         // sunday, fix it
         $weekday = 7;
     }
     $cacheKey = $from . $to . $time . $weekday;
     $memcache = new Memcache();
     $memcache->connect('localhost', 11211);
     $hits = $memcache->get($cacheKey);
     if ($timer) {
         $timer->tick("search", "Fetched from memcache");
     }
     if ($hits) {
         $hits = unserialize($hits);
     }
     if (!is_array($hits) || count($hits) == 0) {
         $hits = array();
         /**
          * First find all buses having both stops in their path, kinda nice
          */
         if ($timer) {
             $timer->tick("search", "No cache");
         }
         $db = Config::getDb();
         $start = toLower($from);
         $end = toLower($to);
         if ($timer) {
             $timer->tick("search", "Lowercased input");
         }
         $buses = $db->routes->find(array('search' => array('$all' => array($start, $end))));
         if ($timer) {
             $timer->tick("search", "Search routes");
         }
         // Find some necessary data
         if (!$time) {
             $time = date("Hi");
         }
         //"0700";
         $minutes = (int) substr($time, -2);
         $hours = (int) substr($time, 0, -2);
         $searchFilters = array();
         $hitCount = 0;
         $timeSort = array();
         while ($route = $buses->getNext()) {
             // Iterate over stops and find the
             $startStop = null;
             $endStop = null;
             foreach ($route['stops'] as $stop) {
                 if (!$startStop && toLower($stop['name']) == $start) {
                     $startStop = $stop;
                 } elseif ($startStop && !$endStop && toLower($stop['name']) == $end) {
                     $endStop = $stop;
                 }
             }
             if ($startStop && $endStop) {
                 /**
                  * By now we have tested that we have both stops
                  * and in the correct order for this route
                  * Its time to generate the query to find departures
                  */
                 $minuteMark = $minutes - (int) $startStop['timeOffset'];
                 $latestStartTime = date("Hi", mktime($hours, $minuteMark));
                 $startOffset = (int) $startStop['timeOffset'];
                 $endOffset = (int) $endStop['timeOffset'];
                 $runningTime = $endOffset - $startOffset;
                 $filters = array('route' => $route['_id'], 'time' => array('$gte' => (int) $latestStartTime), 'days' => $weekday);
                 $departuresForRoute = $db->departures->find($filters)->sort(array('time' => 1))->limit(15);
                 /**
                  * Loop over each departure and calculate some times
                  */
                 while ($dep = $departuresForRoute->getNext()) {
                     $arrivalTime = (int) $dep['time'];
                     $startTime = Config::timeAdd($arrivalTime, $startOffset);
                     $startM = substr($startTime, -2);
                     $startH = substr($startTime, 0, -2);
                     $waitTime = ($startH - $hours) * 60 + ($startM - $minutes);
                     $arrivalTime = Config::timeAdd(str_replace(":", "", $startTime), $runningTime, "H:i");
                     while ($waitTime < 0) {
                         $waitTime += 1440;
                     }
                     $timeSort[] = $waitTime;
                     // Wait time should be arrival time minus specified search time
                     $hits[] = array('id' => $route['num'], 'name' => $route['dest'], 'runningTime' => $runningTime, 'startTime' => $startTime, 'wait' => $waitTime, 'arrivalTime' => $arrivalTime, 'arrivalSpan' => $runningTime + $waitTime);
                 }
             }
         }
         if ($timer) {
             $timer->tick("search", "Searched departures");
         }
         array_multisort($timeSort, SORT_ASC, $hits);
         $memcache->set($cacheKey, serialize($hits), false, 120);
     }
     $this->count = count($hits);
     return array_slice($hits, $offset, $limit);
 }