? .DS_Store
? kml_5_0.patch
Index: README.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/kml/README.txt,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 README.txt
--- README.txt	4 Sep 2006 22:05:02 -0000	1.1.1.1
+++ README.txt	24 Jan 2007 18:09:47 -0000
@@ -20,13 +20,19 @@ Requirements
 Installation
 ==================
 1. Copy the kml directory into the modules directory
-2. Enable the 'kml module' under administer > modules
+2. Enable the 'KML module' under Administer > Site building > Modules
+3. Configure the module under Administer > Site configuration > KML
+4. (see the section below about network links and access problems)
 
 Using the module
 ==================
-Once you have enabled the module, you should check the settings page under administer > settings > kml and change them as neccesary. Here you can choose a number of things, including adding a KML link to all location-enabled nodes. A block and a menu item will also be made available to you and should be enabled if desired. The block is designed to be visible in certain parts of the site to give a quick link to a KML feed of the current grouping of nodes (eg those tagged with a term, those within an organic group, or those returned by a search).
+Once you have enabled the module, you should check the settings page under Administer > Site configuration > KML and change them as neccesary. Here you can choose a number of things, including adding a KML link to all location-enabled nodes. A block and a menu item will also be made available to you and should be enabled if desired. The block is designed to be visible in certain parts of the site to give a quick link to a KML feed of the current grouping of nodes (eg those tagged with a term, those within an organic group, or those returned by a search).
+
+Network links and access problems
+==================
+To use KML network links (automatically updating KML feeds from your site that will pick up the latest content as people explore in Google Earth) it is recommended that you enable the 'access kml' permission under Administer > User management > Access control. This will prevent 'Access denied' messages appearing in Google Earth. Alternatively, a module such as Securesite could be installed to protect the kml/* directory behind a standard HTTP Auth barrier that Google Earth can prompt the user to log in through.
 
 Credit
 ==================
-Written by Dan Karran (geodan)
-http://geodan.org
\ No newline at end of file
+Written by Dan Karran (geodaniel) <dan at karran dot net>
+http://geodaniel.org
\ No newline at end of file
Index: kml.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/kml/kml.info,v
retrieving revision 1.1
diff -u -p -r1.1 kml.info
--- kml.info	25 Sep 2006 13:23:41 -0000	1.1
+++ kml.info	24 Jan 2007 18:09:47 -0000
@@ -1,3 +1,5 @@
 ; $Id: kml.info,v 1.1 2006/09/25 13:23:41 geodan Exp $
 name = KML
-description = Creates KML feeds from location-enabled nodes in Drupal
+description = Creates Google Earth KML feeds from location-enabled nodes in Drupal.
+dependencies = location
+package = Location
Index: kml.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/kml/kml.module,v
retrieving revision 1.4
diff -u -p -r1.4 kml.module
--- kml.module	30 Oct 2006 09:57:03 -0000	1.4
+++ kml.module	24 Jan 2007 18:09:48 -0000
@@ -2,9 +2,11 @@
 // $Id: kml.module,v 1.4 2006/10/30 09:57:03 geodan Exp $
 
 /**
+ * KML Module
+ *
  * @file
- * Author: Dan Karran (geodan) <dan at karran dot net>
- * Creates KML feeds from location-enabled nodes in Drupal. For more information, visit http://geodan.org/kml-module
+ * Creates Google Earth KML feeds from location-enabled nodes in Drupal.
+ * @author Dan Karran (geodaniel) <dan at karran dot net>
  */
 
 /**
@@ -17,8 +19,8 @@ function kml_help($section = 'admin/help
       $output = t('<p>The KML module allows you to create KML feeds from Drupal for use in Google Earth. It requires the use of the location module to assign geographic locations to nodes.</p>');
       $output .= t('<p>You can</p>
 <ul>
-<li>administer KML feed options at <a href="%admin-settings-kml">administer &gt;&gt; settings &gt;&gt; kml</a>.</li>
-</ul>', array('%admin-settings-kml' => url('admin/settings/kml')));
+<li>administer KML feed options at !admin_link.</li>
+</ul>', array('!admin_link' => l('admin &raquo; settings &raquo; kml', 'admin/settings/kml', NULL, NULL, NULL, FALSE, TRUE)));
       return $output;
     case 'admin/modules#description':
       return t('Module to feed KML from Drupal to Google Earth');
@@ -38,16 +40,22 @@ function kml_perm() {
 function kml_menu($may_cache) {
   $items = array();
   if ($may_cache) {
-    $items[] = array('path' => 'kml', 'title' => t('kml'),
+    $items[] = array('path' => 'kml', 
+      'title' => t('KML feeds'),
       'callback' => 'kml_interface',
       'access' => user_access('access kml'),
-      'type' => MENU_SUGGESTED_ITEM);
+      'type' => MENU_SUGGESTED_ITEM,
+    );
   }
   else {
-    $items[] = array('path' => 'admin/settings/kml', 'title' => t('kml'),
-      'callback' => 'kml_admin_settings',
+    $items[] = array('path' => 'admin/settings/kml', 
+      'title' => t('KML'),
+      'description' => t('Settings for the KML module'),
+      'callback' => 'drupal_get_form',
+      'callback arguments' => array('kml_admin_settings'),
       'access' => user_access('administer kml'),
-      'type' => MENU_NORMAL_ITEM);
+      'type' => MENU_NORMAL_ITEM,
+    );
   }
 
   return $items;
@@ -61,33 +69,38 @@ function kml_interface($a = NULL, $b = N
   $sortorder = variable_get('kml_sortorder', 'asc');
   if ($a == 'node') {
     if (is_numeric($b)) {
-      $nodes = db_query("SELECT n.nid, n.created FROM {node} n INNER JOIN {location} l ON n.vid = l.oid WHERE n.status = 1 AND l.source != 0 AND l.type = 'node' AND n.nid = %d", $b);
-      kml_feed($nodes,$attributes);
+      /* Single node */
+      $nodes = db_query("SELECT n.nid, n.created FROM {node} n WHERE n.status = 1 AND n.vid IN (SELECT l.eid FROM {location} l WHERE l.source != 0 AND l.type = 'node' AND l.eid = n.vid) AND n.nid = %d", $b);
+      kml_feed($nodes, $attributes);
     }
     else if ($b == 'networklink') {
+      /* Network link for all location-enabled nodes */
       $attributes['kml_feed'] = url('kml/node/', NULL, NULL, TRUE);
       kml_networklink($attributes);
     }
     else {
-      $nodes = db_query("SELECT n.nid, n.created FROM {node} n INNER JOIN {location} l ON n.vid = l.oid INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND l.source != 0 AND l.type = 'node' ORDER BY %s %s", $sortmode, $sortorder);
-      kml_feed($nodes,$attributes);
+      /* All location-enabled nodes */
+      $nodes = db_query("SELECT n.nid, n.created FROM {node} n WHERE n.status = 1 AND n.vid IN (SELECT l.eid FROM {location} l WHERE l.source != 0 AND l.type = 'node' AND l.eid = n.vid) ORDER BY %s %s", $sortmode, $sortorder);
+      kml_feed($nodes, $attributes);
     }
   }
   else if ($a == 'term' && is_numeric($b)) {
-    if (module_exist('taxonomy')) {   // TODO: module_exist is called module_exists in HEAD
+    if (module_exists('taxonomy')) {
       if ($term = taxonomy_get_term($b)) {
         $tag = $term->name;
         if ($c == 'networklink') {
-          $attributes['kml_feed'] = url("kml/term/$b/", NULL, NULL, TRUE);
-          $attributes['title'] = 'Tag: '.$tag;
-          $attributes['description'] = 'Nodes tagged with '.$tag;
+          /* Network link for all location-enabled nodes tagged with a certain term */
+          $attributes['kml_feed'] = url('kml/term/'. $b .'/', NULL, NULL, TRUE);
+          $attributes['title'] = 'Tag: '. $tag;
+          $attributes['description'] = 'Nodes tagged with '. $tag;
           kml_networklink($attributes);
         }
         else {
-          $nodes = db_query("SELECT n.nid, n.created FROM {node} n INNER JOIN {location} l ON n.vid = l.oid INNER JOIN {term_node} tn ON n.nid = tn.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND l.source != 0 AND l.type = 'node' AND tn.tid = %d ORDER BY %s %s", $b, $sortmode, $sortorder);
-          $attributes['title'] = 'Tag: '.$tag;
-          $attributes['description'] = 'Nodes tagged with '.$tag;
-          kml_feed($nodes,$attributes);
+          /* All location-enabled nodes tagged with a certain term */
+          $nodes = db_query("SELECT n.nid, n.created FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE n.status = 1 AND n.vid IN (SELECT l.eid FROM {location} l WHERE l.source != 0 AND l.type = 'node' AND l.eid = n.vid) AND tn.tid = %d ORDER BY %s %s", $b, $sortmode, $sortorder);
+          $attributes['title'] = 'Tag: '. $tag;
+          $attributes['description'] = 'Nodes tagged with '. $tag;
+          kml_feed($nodes, $attributes);
         }
       }
       else {
@@ -96,21 +109,23 @@ function kml_interface($a = NULL, $b = N
     }
   }
   else if ($a == 'group' && is_numeric($b)) {
-    if (module_exist('og')) {   // TODO: module_exist is called module_exists in HEAD
+    if (module_exists('og')) {
       $groupnode = node_load($b);
       if (og_is_group_type($groupnode->type)) {  // TODO: check also to see if user is part of group
         $group_name = $groupnode->title;
         if ($c == 'networklink') {
-          $attributes['kml_feed'] = url("kml/group/$b/", NULL, NULL, TRUE);
-          $attributes['title'] = 'Group: '.$group_name;
-          $attributes['description'] = 'Nodes in '.$group_name;
+          /* Network link for all location-enabled nodes in a certain group */
+          $attributes['kml_feed'] = url('kml/group/' . $b .'/', NULL, NULL, TRUE);
+          $attributes['title'] = 'Group: '. $group_name;
+          $attributes['description'] = 'Nodes in '. $group_name;
           kml_networklink($attributes);
         }
         else {
-          $nodes = db_query("SELECT n.nid, n.created FROM {node} n INNER JOIN {location} l ON n.vid = l.oid INNER JOIN {node_access} na ON n.nid = na.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND l.source != 0 AND l.type = 'node' AND na.gid = %d ORDER BY %s %s", $b, $sortmode, $sortorder);
+          /* All location-enabled nodes in a certain group */
+          $nodes = db_query("SELECT n.nid, n.created FROM {node} n INNER JOIN {node_access} na ON n.nid = na.nid WHERE n.status = 1 AND n.vid IN (SELECT l.eid FROM {location} l WHERE l.source != 0 AND l.type = 'node' AND l.eid = n.vid) AND na.gid = %d ORDER BY %s %s", $b, $sortmode, $sortorder);
           $attributes['title'] = 'Group: '.$group_name;
-          $attributes['description'] = 'Nodes in '.$group_name;
-          kml_feed($nodes,$attributes);
+          $attributes['description'] = 'Nodes in '. $group_name;
+          kml_feed($nodes, $attributes);
         }
       }
       else {
@@ -119,20 +134,22 @@ function kml_interface($a = NULL, $b = N
     }
   }
   else if ($a == 'search' && $b == 'node' && $c) {
-    if (module_exist('search')) {   // TODO: module_exist is called module_exists in HEAD
-      $type = $b;
-      $keys = $c;
+    if (module_exists('search')) {
+      $type = check_plain($b);
+      $keys = check_plain($c);
       if ($d == 'networklink') {
-        $attributes['kml_feed'] = url("kml/search/$type/$keys/", NULL, NULL, TRUE);
-        $attributes['title'] = 'Search: '.$keys;
-        $attributes['description'] = 'Nodes matching '.$keys;
+        /* Network link for all nodes returned by a certain search */
+        $attributes['kml_feed'] = url('kml/search/'. $type .'/'. $keys .'/', NULL, NULL, TRUE);
+        $attributes['title'] = 'Search: '. $keys;
+        $attributes['description'] = 'Nodes matching '. $keys;
         kml_networklink($attributes);
       }
       else {
+        /* All nodes returned by a certain search */
         $nodes = module_invoke($type, 'search', 'search', $keys);
-        $attributes['title'] = 'Search: '.$keys;
-        $attributes['description'] = 'Nodes matching '.$keys;
-        kml_feed($nodes,$attributes);
+        $attributes['title'] = 'Search: '. $keys;
+        $attributes['description'] = 'Nodes matching '. $keys;
+        kml_feed($nodes, $attributes);
       }
     }
     else {
@@ -148,18 +165,9 @@ function kml_interface($a = NULL, $b = N
 }
 
 /**
- * Admin settings callback
- */
-function kml_admin_settings() {
-  return system_settings_form('kml_admin_settings', kml_admin_form());
-}
-
-/**
  * Form for settings page
  */
-function kml_admin_form() {
-  // TODO: 
-  //  [feed types] - dealt with by (location.module) permissions instead?
+function kml_admin_settings() {
   $form['individual_nodes'] = array(
     '#type' => 'fieldset',
     '#title' => t('Node display'),
@@ -241,72 +249,26 @@ function kml_admin_form() {
     '#description' => t("The number of seconds to wait before refreshing the Network Link after the view in Google Earth has stopped moving. Requires 'onStop' to be selected above."), 
     '#maxlength' => '2', 
     '#size' => '2');
-  return $form;
-}
-
-/**
- * Implementation of hook_form_alter()
- */
-function kml_form_alter($form_id, &$form) {
-  /* this is a check for module dependencies.  the only way we
-  can ensure this check happening when the module is initially
-  enabled is to insert the check for when the form is initially
-  built, which will also be caught when the admin/module page is
-  reloaded upon submission.  this means we never want to call this
-  function when the form has been submitted, so make sure there's
-  no $_POST. */
-  if ($form_id == 'system_modules' && !$_POST) {
-    kml_system_module_validate($form);
-  }
-}
-
-/**
- * Validates module dependencies for the module.
- *
- * @param $form The form array passed from hook_form_alter.
- * 
- * Set the $module variable to a string which is the name of the module, minus
- * the .module extension.  Set $dependencies to an array of module names which
- * the module is dependent on--each element is a string which is the module name
- * minus the .module extension.  Note that this will not check for any dependencies
- * for the modules this module depends on--only those that are explicitly listed in
- * the $dependencies array.
- */
-function kml_system_module_validate(&$form) {
-  $module = 'kml';
-  $dependencies = array('location');
-
-  foreach ($dependencies as $dependency) {
-      if (!in_array($dependency, $form['status']['#default_value'])) {
-        $missing_dependency = TRUE;
-        $missing_dependency_list[] = $dependency;
-      }
-  }
-
-  if (in_array($module, $form['status']['#default_value']) && isset($missing_dependency)) {
-    db_query("UPDATE {system} SET status = 0 WHERE type = 'module' AND name = '%s'", $module);
-    $key = array_search($module, $form['status']['#default_value']);
-    unset($form['status']['#default_value'][$key]);
-    drupal_set_message(t('The module <b>%module</b> was deactivated. It requires the following disabled/non-existant modules to function properly: <b>%dependencies</b>.', array('%module' => $module, '%dependencies' => implode(', ', $missing_dependency_list))), 'error');
-  }
+  return system_settings_form($form);
 }
 
 /**
  * Displays directory of KML feeds available
  */
 function kml_page() {
-  $content = '<p>KML feeds available from this site include:</p>' . "\n";
-  $feeds[] = theme('kml_link','kml/node/networklink') .' '. t('All content from this site');
-  if (module_exist('taxonomy')) {
+  // TODO: actually list all terms, groups, etc with links to their feeds
+  $content = t('<p>KML feeds available from this site include:</p>') . "\n";
+  $feeds[] = theme('kml_link', 'kml/node/networklink') .' '. t('All content from this site');
+  if (module_exists('taxonomy')) {
     $feeds[] = t('Content tagged with a particular term');
   }
-  if (module_exist('og')) {
-    $feeds[] = t('Content within a particular %group', array('%group' => l('group','og')));
+  if (module_exists('og')) {
+    $feeds[] = t('Content within a particular !group', array('!group' => l('group','og')));
   }
-  if (module_exist('search')) {
-    $feeds[] = t('Content of %search', array('%search' => l('search results','search')));
+  if (module_exists('search')) {
+    $feeds[] = t('Content of !search', array('!search' => l('search results','search')));
   }
-  $content .= theme('item_list',$feeds);
+  $content .= theme('item_list', $feeds);
   print theme('page', $content);
 }
 
@@ -321,25 +283,18 @@ function kml_block($op = 'list', $delta 
     case 'configure':
       $form = array(); 
       if ($delta == 0) { 
-        $form['kml_block_taxonomy_title'] = array( 
-          '#type' => 'textfield', 
-          '#title' => t('Block title'), 
-          '#size' => 60, 
-          '#description' => t('This will be used as the heading for the KML block.'), 
-          '#default_value' => 
-            variable_get('kml_block_title',  t('View nodes in Google Earth')) 
-        ); 
+
       } 
       return $form; 
     case 'save':
       if ($delta == 0) { 
-        variable_set('kml_block_title', $edit['kml_block_title']); 
+
       } 
       return; 
     case 'view': default: 
       switch ($delta) { 
         case 0: 
-          $block['subject'] = variable_get('kml_block_title',  t('View nodes in Google Earth'));
+          $block['subject'] = t('View this content in Google Earth');
           $block['content'] = kml_block_content($delta); 
           $block['weight'] = -6; 
           $block['enabled'] = 1; 
@@ -355,11 +310,12 @@ function kml_block($op = 'list', $delta 
  */
 function kml_block_content($block) {
   if ($block == 0) {
+    // TODO: allow admin to choose if network links are used, or normal links
     if (arg(0) == 'taxonomy' && arg(1) == 'term') {
       return theme('kml_link', 'kml/term/'. arg(2) . '/networklink');
     }
-    else if (module_exist('og') && $groupnode = og_get_group_context()) {
-      if ($groupnode->nid == arg(1)) {  // show block only on group homepage. TODO: allow admin to choose where to show block
+    else if (module_exists('og') && $groupnode = og_get_group_context()) {
+      if ($groupnode->nid == arg(1)) {  // show block only on group homepage
         return theme('kml_link', 'kml/group/'. $groupnode->nid .'/networklink');
       }
     }
@@ -372,12 +328,15 @@ function kml_block_content($block) {
 /**
  * Implementation of hook_link(). Adds KML links to individual nodes
  */
-function kml_link($type, $node = 0, $teaser = 0) {
+function kml_link($type, $node = 0, $main = 0) {
   $links = array();
   // if node type is location enabled and has lat long info
-  if ((variable_get('location_'. $node->type, 0)) && ($node->location['source'] != 0)) {
-    if ((variable_get('kml_nodelink', 1) && ($teaser == 0)) || ((variable_get('kml_nodelink_teaser', 0) && ($teaser == 1)))) {
-      $links[] = theme('kml_link',"kml/node/$node->nid");
+  if ((variable_get('location_maxnum_'. $node->type, 0)) && ($node->location['source'] != 0)) {
+    if ((variable_get('kml_nodelink', 1) && ($main == 0)) || ((variable_get('kml_nodelink_teaser', 0) && ($main == 1)))) {
+      $links['kml_link_node'] = array('title' => t('KML'),
+                                      'href' => 'kml/node/'. $node->nid,
+                                      'attributes' => array('title' => t('View location in Google Earth'))
+                                     );
     }
   }
   return $links;
@@ -387,7 +346,7 @@ function kml_link($type, $node = 0, $tea
  * Standardised KML link
  */
 function theme_kml_link($link) {
-  return l(t('kml'), $link, array('title' => t('View location in Google Earth'), 'class' => 'kml'));
+  return l(t('KML'), $link, array('title' => t('View location in Google Earth'), 'class' => 'kml_link'));
 }
 
 /**
@@ -419,8 +378,9 @@ function kml_feed($nodes, $attributes = 
  *   An associative array containing title, link, description and other keys.
  *   The link should be an absolute URL.
  */
-function kml_format_feed($nodes = 0, $channel = array()) {
+function kml_format_feed($nodes = array(), $channel = array()) {
   $items = '';
+  // TODO: check if $nodes contains items, otherwise error is thrown on foreach (eg viewing a tag with no location-enabled nodes)
   if (is_array($nodes)) {
     foreach ($nodes as $node) {
       $nodes_array[] = $node['node'];
@@ -435,7 +395,7 @@ function kml_format_feed($nodes = 0, $ch
     // Load the specified node:
     if ($item = node_load(array('nid' => $node->nid))) {
       // TODO: check to make sure the node has geo properties
-      $link = url("node/$node->nid", NULL, NULL, 1);
+      $link = url('node/'. $item->nid, NULL, NULL, 1);
 
       // Filter and prepare node teaser
       if (node_hook($item, 'view')) {
