diff --git a/GeolocationPlugin.php b/GeolocationPlugin.php index dfb839a..5e29805 100644 --- a/GeolocationPlugin.php +++ b/GeolocationPlugin.php @@ -135,19 +135,47 @@ public function hookDefineAcl($args) public function hookDefineRoutes($args) { $router = $args['router']; - $mapRoute = new Zend_Controller_Router_Route('items/map', - array('controller' => 'map', - 'action' => 'browse', - 'module' => 'geolocation')); - $router->addRoute('items_map', $mapRoute); + + // Map based on an item to get all other items around. + $mapRoute = new Zend_Controller_Router_Route( + 'items/map/:item_id/:page', + array( + 'module' => 'geolocation', + 'controller' => 'map', + 'action' => 'browse', + 'page' => 1, + ), + array( + 'item_id' => '\d+', + 'page' => '\d+', + )); + $router->addRoute('items_map_item', $mapRoute); + + $mapRoute = new Zend_Controller_Router_Route( + 'items/map/:pager/:page', + array( + 'module' => 'geolocation', + 'controller' => 'map', + 'action' => 'browse', + 'pager' => 'page', + 'page' => 1, + ), + array( + 'pager' => 'page', + 'page' => '\d+', + )); + $router->addRoute('items_map_page', $mapRoute); // Trying to make the route look like a KML file so google will eat it. // @todo Include page parameter if this works. - $kmlRoute = new Zend_Controller_Router_Route_Regex('geolocation/map\.kml', - array('controller' => 'map', - 'action' => 'browse', - 'module' => 'geolocation', - 'output' => 'kml')); + $kmlRoute = new Zend_Controller_Router_Route_Regex( + 'geolocation/map\.kml', + array( + 'module' => 'geolocation', + 'controller' => 'map', + 'action' => 'browse', + 'output' => 'kml', + )); $router->addRoute('map_kml', $kmlRoute); } @@ -251,9 +279,12 @@ public function hookItemsBrowseSql($args) { $db = $this->_db; $select = $args['select']; + $params = $args['params']; + $alias = $this->_db->getTable('Location')->getTableAlias(); - if (!empty($args['params']['only_map_items']) - || !empty($args['params']['geolocation-address']) + if (!empty($params['only_map_items']) + || !empty($params['item_id']) + || !empty($params['geolocation-address']) ) { $select->joinInner( array($alias => $db->Location), @@ -261,32 +292,60 @@ public function hookItemsBrowseSql($args) array() ); } - if (!empty($args['params']['geolocation-address'])) { + + // Select all items around the selected one. + if (!empty($params['item_id'])) { + // TODO Use a sub-query? + $location = $db->getTable('Location')->findLocationByItem($params['item_id'], true); + if ($location) { + $params['geolocation-address'] = $location->address; + $params['geolocation-latitude'] = $location->latitude; + $params['geolocation-longitude'] = $location->longitude; + $params['geolocation-radius'] = isset($params['geolocation-radius']) + ? $params['geolocation-radius'] + : get_option('geolocation_default_radius'); + $this->_selectItemsBrowseSql($select, $params); + } + } + + elseif (!empty($params['geolocation-address'])) { // Get the address, latitude, longitude, and the radius from parameters - $address = trim($args['params']['geolocation-address']); - $lat = trim($args['params']['geolocation-latitude']); - $lng = trim($args['params']['geolocation-longitude']); - $radius = trim($args['params']['geolocation-radius']); + $params['geolocation-address'] = trim($params['geolocation-address']); + $params['geolocation-latitude'] = trim($params['geolocation-latitude']); + $params['geolocation-longitude'] = trim($params['geolocation-longitude']); + $params['geolocation-radius'] = trim($params['geolocation-radius']); // Limit items to those that exist within a geographic radius if an address and radius are provided - if ($address != '' - && is_numeric($lat) - && is_numeric($lng) - && is_numeric($radius) + if ($params['geolocation-address'] != '' + && is_numeric($params['geolocation-latitude']) + && is_numeric($params['geolocation-longitude']) + && is_numeric($params['geolocation-radius']) ) { - // SELECT distance based upon haversine forumula - if (get_option('geolocation_use_metric_distances')) { - $denominator = 111; - $earthRadius = 6371; - } else { - $denominator = 69; - $earthRadius = 3959; - } + $this->_selectItemsBrowseSql($select, $params); + } + } + } - $radius = $db->quote($radius, Zend_Db::FLOAT_TYPE); - $lat = $db->quote($lat, Zend_Db::FLOAT_TYPE); - $lng = $db->quote($lng, Zend_Db::FLOAT_TYPE); + /** + * Helper for hookItemsBrowseSql(). + */ + private function _selectItemsBrowseSql($select, $params) + { + $db = $this->_db; + + // Select distance based upon haversine forumula. + if (get_option('geolocation_use_metric_distances')) { + $denominator = 111; + $earthRadius = 6371; + } else { + $denominator = 69; + $earthRadius = 3959; + } + + $lat = $db->quote($params['geolocation-latitude'], Zend_Db::FLOAT_TYPE); + $lng = $db->quote($params['geolocation-longitude'], Zend_Db::FLOAT_TYPE); + $radius = $db->quote($params['geolocation-radius'], Zend_Db::FLOAT_TYPE); - $select->columns(<<columns(<<where(<<where(<<having('distance < radius'); + // Actually use distance calculation. + //$select->having('distance < radius'); - //ORDER by the closest distances - $select->order('distance'); - } - } + //ORDER by the closest distances + $select->order('distance'); } /** @@ -456,7 +513,7 @@ public function filterExhibitLayouts($layouts) ); return $layouts; } - + public function filterApiImportOmekaAdapters($adapters, $args) { $geolocationAdapter = new ApiImport_ResponseAdapter_Omeka_GenericAdapter(null, $args['endpointUri'], 'Location'); @@ -510,7 +567,7 @@ public function geolocationShortcode($args) if (isset($args['tags'])) { $options['params']['tags'] = $args['tags']; - } + } $pattern = '#^[0-9]*(px|%)$#'; @@ -550,7 +607,7 @@ protected function _mapForm($item, $label = 'Find a Location by Address:', $conf $post = $_POST; } - $usePost = !empty($post) + $usePost = !empty($post) && !empty($post['geolocation']) && $post['geolocation']['longitude'] != '' && $post['geolocation']['latitude'] != ''; diff --git a/controllers/MapController.php b/controllers/MapController.php index 9a29512..8a6e039 100644 --- a/controllers/MapController.php +++ b/controllers/MapController.php @@ -6,30 +6,36 @@ public function init() { $this->_helper->db->setDefaultModelName('Item'); } - + public function browseAction() { $table = $this->_helper->db->getTable(); $locationTable = $this->_helper->db->getTable('Location'); - + $params = $this->getAllParams(); $params['only_map_items'] = true; $limit = (int) get_option('geolocation_per_page'); $currentPage = $this->getParam('page', 1); - // Only get pagination data for the "normal" page, only get - // item/location data for the KML output. + // Only get item/location data for the KML output. if ($this->_helper->contextSwitch->getCurrentContext() == 'kml') { $items = $table->findBy($params, $limit, $currentPage); $this->view->items = $items; $this->view->locations = $locationTable->findLocationByItem($items); - } else { + } + // Only get pagination data for the "normal" page. + else { + $item_id = $this->getParam('item_id'); + if (!empty($item_id)) { + $this->view->item = get_record_by_id('Item', $item_id); + $this->view->location = $locationTable->findLocationByItem($item_id, true); + } $this->view->totalItems = $table->count($params); $this->view->params = $params; - + $pagination = array( - 'page' => $currentPage, - 'per_page' => $limit, + 'page' => $currentPage, + 'per_page' => $limit, 'total_results' => $this->view->totalItems ); Zend_Registry::set('pagination', $pagination); diff --git a/views/public/map/browse.php b/views/public/map/browse.php index e851034..389ddd2 100644 --- a/views/public/map/browse.php +++ b/views/public/map/browse.php @@ -1,7 +1,19 @@ -latitude; + $center['longitude'] = (double) $location->longitude; + $center['zoomLevel'] = (double) get_option('geolocation_default_zoom_level'); +} +else { + $title = __('Browse Items on the Map (%s total)', $totalItems); +} + echo head(array('title' => $title, 'bodyclass' => 'map browse')); ?> @@ -17,7 +29,7 @@ ?>
- googleMap('map_browse', array('list' => 'map-links', 'params' => $params)); ?> + googleMap('map_browse', array('list' => 'map-links', 'params' => $params), array(), $center); ?>