Skip to content
Snippets Groups Projects
gmap_location.module 16.4 KiB
Newer Older
<?php
/* $id$ */

/**
 * @file
 * GMap Location module is a module to add some gmap funcationality based on location.modules information.
 *
 * The main functions are to provide a map showing all of the nodes or users that have location information on a map.
 *
 */

/**
 * Implementation of hook_help.
 *
 */

function gmap_location_help($section) {
  switch ($section) {
    case 'admin/modules#description':
      return t('Display location.module information on Google Maps (needs gmap.module)');
  }
}

/**
 * Implementation of hook_perm.
 *
 */

function gmap_location_perm() {
  return array('show user map', 'user locations', 'show node map');
}

/**
 * Implementation of hook_menu.
 *
 */

function gmap_location_menu($may_cache) {
  $items=array();

  if ($may_cache) {
      $items[] = array('path' => 'map/users',
        'type' => MENU_NORMAL_ITEM,
        'title' => t('User locations'),
        'access' => user_access('show user map'),
        'callback' => 'gmap_location_users_page');
      $items[] = array('path' => 'map/node',
        'type' => MENU_NORMAL_ITEM,
        'title' => t('Node locations'),
        'access' => user_access('show node map'),
        'callback' => 'gmap_location_node_page');
  }

  return $items;
}

/**
 * Draws a page with a google map that has all of the site users.
 *
 */

function gmap_location_users_page() {
  global $user, $base_url;
  $output ='<p>'.variable_get('gmap_user_map_header', t('This map illustrates the extent of users of this website. Each marker indicates a user that has entered their locations.'))."</p>\n";

  $result=db_query("SELECT * FROM {location} WHERE (longitude !=0 OR latitude !=0) AND type='user'");
  $thismap = gmap_parse_macro(variable_get('gmap_user_map', '[gmap|id=usermap|center=30,0|zoom=2|width=100%|height=400px]'));

  // Find default marker
  $default_marker = variable_get('gmap_user_map_marker', 'drupal');

  // Determine if any roles override default setting
  $roles = user_roles(TRUE);
  $roles_override = array();
  foreach ($roles as $rid => $role) {
    if (variable_get("gmap_role_map_marker_$rid", $default_marker) != $default_marker) {
      $roles_override[$rid] = $role;
    }
  }


  if (empty($thismap['markers'])) {
    $thismap['markers']=array();
  }
  while ($u=db_fetch_object($result)) {

    $account = user_load(array('uid' => $u->oid));
    $dupes = array_intersect($account->roles, $roles_override);
    if (empty($dupes)) {
      $marker = $default_marker;
    }
    else {
      $key = key($dupes);
      $marker = variable_get("gmap_role_map_marker_$key", $default_marker);
    }

    if (user_access('user locations')) {
      $newmarker['label'] = theme('gmap_location_user_html',$account);
      $newmarker['point']= $u->latitude.','.$u->longitude;
      $newmarker['tooltip']=check_plain($account->name);
    }
    else {
      $newmarker['point']= $u->latitude.', '.$u->longitude;
    }
    $thismap['markers'][]=$newmarker;
  }
  $output .= '<p>'.gmap_draw_map($thismap);
  if ($user->uid>0) {
    $output .= '<p>'.t('To add/change your location to the user map, ').l(t('edit your location'),'user/'.$user->uid.'/edit/gmap_user');
  }
  return $output;
}

/**
 * Draws a page with a google map with the node on it, or if no node is set all of the nodes on it.
 *
 * @param $nn
 * The node number to draw on the map.  If this is not set, or is null then all of the nodes will be drawn.
 */


function gmap_location_node_page($nn=null) {
  if ($nn && $n=node_load($nn)){
    if (node_access('view',$n)) {
      $output .='<p>'.variable_get('gmap_node_map_header', t('This map illustrates the extent of nodes of this website. '))."</p>\n";
      $thismap = gmap_parse_macro(variable_get('gmap_node_map', '[gmap|id=nodemap|center=30,0|zoom=2|width=100%|height=400px]'));
      $thismap = gmap_location_node_map($n,$thismap);
      $output .= '<p>'.gmap_draw_map($thismap);
      return $output;
    }
    else {   //access denied
      return drupal_access_denied();
    }
  }

  $output .='<p>'.variable_get('gmap_node_map_header', t('This map illustrates the extent of nodes of this website.'))."</p>\n";

  $result=db_query("SELECT * FROM {location} WHERE (longitude!=0 OR latitude !=0) AND type='node'");
  $thismap = gmap_parse_macro(variable_get('gmap_node_map', '[gmap|id=usermap|center=30,0|zoom=2|width=100%|height=400px]'));
  if (empty($thismap['markers'])) {
    $thismap['markers']=array();
  }
  while ($locn=db_fetch_object($result)) {
    $n=node_load(array('vid'=>$locn->oid));
    if ($n && node_access('view',$n)) {
      $thismap=gmap_location_node_map($n,$thismap,false);
    }
  }
  $output .= '<p>'.gmap_draw_map($thismap);
  return $output;
}


/**
 * Adds the location information from a node for a gmap.
 *
 * @param $n
 * The node number to add to the map.
 *
 * @param $thismap
 * A gmap var with the map that will be used as the basemap
 *
 * @param $single
 * true if this is the only node being looked at (will center the map and possible add
 * additional information.
 *
 * @return
 * A gmap centred on the
 */

function gmap_location_node_map($n,$thismap,$single=false){

  if (isset($n->location['latitude']) && isset($n->location['longitude'])){
    $newmarker=array();
    $width=0;

    if (!($newmarker['text'] = theme(strtr($n->type,'-','_').'_gmapnodelabel',$n))) {
      $newmarker['text'] = theme('gmapnodelabel',$n);
    }
    $newmarker['point']= $n->location['latitude'].','.$n->location['longitude'];
    $newmarker['markername']=variable_get('gmap_node_map_marker_'.$n->type, '');
    $newmarker['tooltip']=$n->title;
    $newmarker['link']=url('node/'.$n->nid);
    switch ($n->type) {
      case 'acidfree':
        $newmarker['winwidth'] = (variable_get('acidfree_thumb_dim', IMAGE_THUMB_SIZE)+40).'px';
        break;
    }
    $thismap['markers'][]=$newmarker;
    if ($single){
      $thismap['center']=$n->location['latitude'].','.$n->location['longitude'];
    }

  }
  if ($single) {
    //do special things for certain nodes when it is the only node shown
    switch ($n->type) {
      case 'og':
        $result=db_query(og_list_users_sql(), $n->nid);
        while ($user = db_fetch_object($result)) {
          if (isset($user->location['latitude']) && isset($user->location['longitude'])) {
            if (user_access('user locations')) {
              $newmarker=array();
              $newmarker['label'] = theme('user_picture', $user);
              $newmarker['label'] .= theme('username', $user);
              $newmarker['point']= $n->location['latitude'].','.$n->location['longitude'];
              $newmarker['markername']=variable_get('gmap_user_map_marker', 'drupal');
              $thismap['markers'][]=$newmarker;
            }
          }
          else {
            $newmarker['point']= $u->latitude.', '.$u->longitude;
            $thismap['markers'][]=$newmarker;
          }
        }
        break;
    }
  }
  return $thismap;
}



/**
 * Implementation of hook_settings.
 *
 */

function gmap_location_settings() {
   $markerdir=variable_get('gmap_markerfiles','modules/gmap/markers');
  // Retrieve and sort a list of available markers
  $marker_images = file_scan_directory($markerdir, '.*\.png$',array('shadow.png','.','..'),0,true, 'filename');
//  $marker_images=array();
  foreach ($marker_images as $marker) {
    $thisfile=substr($marker->filename,strlen($markerdir)+1,-4);
    $markers[$thisfile] = $thisfile;
  }
  asort($markers);

  $form['user']=array('#type' => 'fieldset', '#title' => t('Location settings for users'));
  $form['user']['gmap_user_map']=array('#type'=>'textfield',
                                       '#title'=>t('Default user map'),
                                       '#default_value'=>variable_get('gmap_user_map', '[gmap |id=usermap|center=40,0|zoom=3|width=100%|height=400px]'),
                                       '#size'=>50,
                                       '#maxlength'=>500,
                                       '#description'=>t('The gmap macro where the user information will be diplayed on.'));
  $form['user']['gmap_user_map_header']=array('#type'=>'textarea',
                                              '#title'=>t('Text at the top of the map/users page'),
                                              '#default_value'=>variable_get('gmap_user_map_header', t('This map illustrates the extent of users of this website. Each marker indicates a user that has entered their locations.')),
                                              '#cols'=>50,
                                              '#rows'=>6 );
  $form['user']['gmap_user_map_marker']=array('#type'=>'select',
                                              '#title'=>t('Marker for users'),
                                              '#default_value'=>variable_get('gmap_user_map_marker', 'drupal'),
                                              '#options'=>$markers);
  // Option to use a different marker for each role
  $form['user']['roles']=array('#type'=>'fieldset',
                               '#title'=>t('Markers per role'),
                               '#description'=>t('Use a different marker to denote users in the following roles.'));

  // Retrieve and sort list of roles, sans anonymous user
  $roles = user_roles(TRUE);
  asort($roles);

  // Create a selection box per role
  foreach ($roles as $rid => $role) {
    $form['user']['roles']["gmap_role_map_marker_$rid"]=array('#type'=>'select',
                                                              '#title'=>$role,
                                                              '#default_value'=>variable_get("gmap_role_map_marker_$rid", variable_get('gmap_user_map_marker', 'drupal')),
                                                              '#options'=>$markers);
  }


  $form['node']=array('#type' => 'fieldset', '#title' => t('Location settings for nodes'));
  $form['node']['gmap_node_map']=array('#type'=>'textfield',
                                       '#title'=>t('Default node map'),
                                       '#default_value'=>variable_get('gmap_node_map',
                                       '[gmap |id=nodemap|center=40,0|zoom=3|width=100%|height=400px]'),
                                       '#size'=>50,
                                       '#maxlength'=>500,
                                       '#description'=>t('The gmap macro where the user information will be diplayed on.'));
  $form['node']['gmap_node_map_header']=array('#type'=>'textarea',
                                              '#title'=>t('Text at the top of the map/nodes page'),
                                              '#default_value'=>variable_get('gmap_node_map_header', t('This map illustrates the locations of the nodes on this website. Each marker indicates a node associated with a specific location.')),
                                              '#cols'=>50,
                                              '#rows'=>6 );
  $ntypes=node_get_types();
  foreach ($ntypes as $key => $value) {
    if (variable_get('location_'. $key, 0)) {
      $form['node']['gmap_node_map_marker_'.$key]=array('#type'=>'select',
                                                        '#title'=>t('Marker for '.$value),
                                                        '#default_value'=>variable_get('gmap_node_map_marker_'.$key, ''),
    }
  }
  return $form;
}

function gmap_location_block($op = 'list', $delta = 0, $edit = array()) {

  // The $op parameter determines what piece of information is being requested.
  switch ($op) {
    case 'list':
      $blocks[0]['info'] = t('Location map');

      return $blocks;
    case 'configure':
      $form = array();
      if ($delta == 0) {
         $form['gmap_location_block_macro'] = array(
          '#type' => 'textfield',
          '#title' => t('Map Macro'),
          '#size' => 60,
          '#maxlength'=>500,
          '#description' => t('A macro to be used as a base map for the location block.  This map will be recentered on the location, so the center is not that important. <p>Alternate base map macros can be entered for a specific node type below.'),
          '#default_value' =>
            variable_get('gmap_location_block_macro', '[gmap |id=block0|zoom=10 |width=100% |height=200px |control=Small |type=Map] '),
        );
        
        $ntypes=node_get_types();
        foreach ($ntypes as $key => $value) {
          if (variable_get('location_'. $key, 0)) {
            $form['gmap_location_block_macro_'.$key]=array(
                                                          '#type' => 'textfield',
                                                          '#title' => t('Map Macro for '.$value),
                                                          '#size' => 60,
                                                          '#maxlength'=>500,
                                                          '#default_value' => variable_get('gmap_location_block_macro_'.$key, ''),        );
          }
        }
      }
      return $form;
    case 'save':
      if ($delta == 0) {
        // Have Drupal save the string to the database.
        variable_set('gmap_location_block_macro', $edit['gmap_location_block_macro']);
        $ntypes=node_get_types();
        foreach ($ntypes as $key => $value) {
          if (variable_get('location_'. $key, 0)) {
            variable_set('gmap_location_block_macro_'.$key,$edit['gmap_location_block_macro_'.$key]);
          }
        }
    case 'view': default:

      // If $op is "view", then we need to generate the block for display
      // purposes. The $delta parameter tells us which block is being requested.
      switch ($delta) {
        case 0:
          // The subject is displayed at the top of the block. Note that it
          // should be passed through t() for translation.
          $path = drupal_get_normal_path($_GET['q']);
          list($node, $nid) = array_values(explode('/', $path));
          if ($node == 'node') {
            $block=gmap_location_block_view($nid);
function gmap_location_block_view($nid) {
  $block=array();
  $node = node_load(array('nid' => $nid));
  if (isset( $node->location['latitude']) &&  isset($node->location['longitude'])) {
    $block['subject'] = t('Location');
    if (strlen(variable_get('gmap_location_block_macro_'.$node->type, '')) > 0) {
      $macro=variable_get('gmap_location_block_macro_'.$node->type, '');
    }
    else {
      $macro=variable_get('gmap_location_block_macro', '[gmap |id=block0|zoom=10 |width=100% |height=200px |control=Small |type=Map] ');
    }
    $block['content'] = gmap_draw_map(gmap_location_map_add_node( gmap_parse_macro($macro),$node));
  }
  return $block;
}


function gmap_location_map_add_node($basemap, $node, $label='') {
  if (empty($basemap['markers'])) {
    $thismap['markers']=array();
  }
  $newmarker['point']= $node->location['latitude'].','.$node->location['longitude'];
  $newmarker['markername']=variable_get('gmap_node_map_marker_'.$node->type, '');
  $newmarker['label']=$label;
  $basemap['markers'][]=$newmarker;
  $basemap['center']= $node->location['latitude'].','.$node->location['longitude'];
  return $basemap;
}


//Any module can create a default theme for the display of nodes of the node type by
//creating a function theme_hook_gmapnodelabel a theme could then further specify it
//by creating a mytheme_nodetype_gmapnodelabel or could simply create a default
//node type by creating a mytheme_gmapnodelabel

function theme_acidfree_gmapnodelabel($n) {
  $out = strtr(theme_acidfree_print_thumb_photo($n),"'\n",'" ');                   //<table><tr><td> </td></tr></table>
  $width=120;
  return $out;
}
function theme_image_gmapnodelabel($n) {
  $out = '<a href="'.url('node/'.$n->nid).'">'.check_plain($n->title).'</a> <br>';
  $out .= image_display($n,'thumbnail');
}
function theme_gmapnodelabel($n) {
          // Allow a module (where the module name matches the node type name)
          // to define a custom display for the google map label.
          // For this to work with flexinode defined data types,
          // a module called 'flexinode_#.module' in your site's module
          // directory and add theme_hook_gmapnodelabel($node, $location) to it.
          // Be sure to enable your 'flexinode_#.module'.
  return strtr(theme('node',$n,true),"'\n\r",'"  ');    //make sure it all goes on one line.
}

function theme_gmap_location_user_html($account) {
  $returntxt = theme('user_picture', $account);
  $returntxt .= theme('username', $account);
  return $returntxt;
}