Index: taxonomy_image.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/taxonomy_image/taxonomy_image.module,v
retrieving revision 1.12.4.9
diff -u -r1.12.4.9 taxonomy_image.module
--- taxonomy_image.module	8 Feb 2008 01:14:17 -0000	1.12.4.9
+++ taxonomy_image.module	8 Feb 2008 16:57:54 -0000
@@ -8,104 +8,89 @@
  */
 
 /**
- * Call this function from your theme or other php code to display the
- * image associated with the given term id.  An html <img> tag will be returned
- * if an image is found.  The format of the link can be modified with the
- * tags parameter.
+ * Function to display the image associated with the given term id.
+ * An html <img> tag will be returned if an image is found.  The link
+ * format can be modified with the tags parameter.
+ * @see taxonomy_image_get_object().
+ * @see taxonomy_image_get_url().
  *
- * @param  int     $tid   the term id.
- * @param  string  $tags optional tags to add into the <img src=''> link
+ * @param
+ *   $tid - the term id.
+ * @param
+ *   $tags - optional HTML attributes to include in the link.
  * 
- * @return string  An html <img src> link.
+ * @return
+ *   An html img link.
  */
 function taxonomy_image_display($tid, $tags = NULL) {
   global $user;
-  static $image = array();
 
   if (user_access('access taxonomy images') &&
       !$user->taxonomy_image_disable_images) {
     // do lookup, return full display path
-    if (!$image[$tid]->url) {
-      if ($image[$tid] = db_fetch_object(db_query('SELECT i.path, d.name FROM {term_image} i INNER JOIN {term_data} d USING(tid) WHERE i.tid=%d', $tid))) {
-        $image[$tid]->url = file_create_url($image[$tid]->path);
-      }
-      else if (variable_get('taxonomy_image_recursive', 0)) {
-        // walk up the taxonomy hierarchy and look for an image
-        $orig = $tid;
-        while ($parent = db_fetch_object(db_query('SELECT t.tid FROM {term_hierarchy} h, {term_data} t WHERE h.parent=t.tid AND h.tid=%d ORDER BY weight, name', $tid))) {
-          $tid = $parent->tid;
-          if ($image[$tid]->url) {
-            // we have already loaded this image from the database
-            $image[$orig] = $image[$tid];
-            break;
-          } 
-          else if ($image[$tid] = db_fetch_object(db_query('SELECT i.path, d.name FROM {term_image} i INNER JOIN {term_data} d USING(tid) WHERE i.tid=%d', $tid))) {
-            // we found a parent with a configured image, use it
-            $image[$tid]->url = file_create_url($image[$tid]->path);
-            $image[$orig] = $image[$tid];
-            break;
+    $image = taxonomy_image_get_object($tid);
+    // Do we have an image?
+    if ($image->path) {
+      // Handle image resizing.
+      switch (variable_get('taxonomy_image_resize', 0)) {
+        case 3: // Exact.
+          if ($width = variable_get('taxonomy_image_width', 0)) {
+            $image->width = $width;
           }
-        }
-      }
-    }
-    if ($image[$tid]->url) {
-      if (!$image[$tid]->width || !$image[$tid]->height) {
-        list($image[$tid]->width, $image[$tid]->height) = getimagesize($image[$tid]->path);
-        // handle image resizing
-        switch (variable_get('taxonomy_image_resize', 0)) {
-          case 3: // exact
-            if ($width = variable_get('taxonomy_image_width', 0))
-              $image[$tid]->width = $width;
-            if ($height = variable_get('taxonomy_image_height', 0))
-              $image[$tid]->height = $height;
-            break;
-          case 2: // not less than
-            if (($width = variable_get('taxonomy_image_width', 0)) &&
-                ($width > $image[$tid]->width)) {
-              $width_scale = $image[$tid]->width / $width;
-            }
-            if (($height = variable_get('taxonomy_image_height', 0)) &&
-                ($height > $image[$tid]->height)) {
-              $height_scale = $image[$tid]->height / $height;
-            }
-            if ($height_scale || $width_scale) {
-              if ($width_scale && $height_scale)
-                $scale = min($width_scale, $height_scale);
-              else
-                $scale = $width_scale ? $width_scale : $height_scale;
-              $image[$tid]->height = round($image[$tid]->height / $scale);
-              $image[$tid]->width = round($image[$tid]->width / $scale);
-            }
-            break;
-          case 1: // not greater than
-            if (($width = variable_get('taxonomy_image_width', 0)) &&
-                ($width < $image[$tid]->width)) {
-              $width_scale = $image[$tid]->width / $width;
-            }
-            if (($height = variable_get('taxonomy_image_height', 0)) &&
-                ($height < $image[$tid]->height)) {
-              $height_scale = $image[$tid]->height / $height;
-            }
-            if ($height_scale || $width_scale) {
-              $scale = max($width_scale, $height_scale);
-              $image[$tid]->height = round($image[$tid]->height / $scale);
-              $image[$tid]->width = round($image[$tid]->width / $scale);
-            }
-            break;
-        }
+          if ($height = variable_get('taxonomy_image_height', 0)) {
+            $image->height = $height;
+          }
+          break;
+        case 2: // Not less than.
+          if (($width = variable_get('taxonomy_image_width', 0)) &&
+              ($width > $image->width)) {
+            $width_scale = $image->width / $width;
+          }
+          if (($height = variable_get('taxonomy_image_height', 0)) &&
+              ($height > $image->height)) {
+            $height_scale = $image->height / $height;
+          }
+          if ($height_scale || $width_scale) {
+            if ($width_scale && $height_scale)
+              $scale = min($width_scale, $height_scale);
+            else
+              $scale = $width_scale ? $width_scale : $height_scale;
+            $image->height = round($image->height / $scale);
+            $image->width = round($image->width / $scale);
+          }
+          break;
+        case 1: // Not greater than.
+          if (($width = variable_get('taxonomy_image_width', 0)) &&
+              ($width < $image->width)) {
+            $width_scale = $image->width / $width;
+          }
+          if (($height = variable_get('taxonomy_image_height', 0)) &&
+              ($height < $image->height)) {
+            $height_scale = $image->height / $height;
+          }
+          if ($height_scale || $width_scale) {
+            $scale = max($width_scale, $height_scale);
+            $image->height = round($image->height / $scale);
+            $image->width = round($image->width / $scale);
+          }
+          break;
       }
-      $current = $image[$tid];
+//      }
+      $current = $image;
       $my_attrs = array(
         'width' => $current->width,
         'height' => $current->height,
         'alt' => $current->name,
         'title' => $current->name,
         );
+      // $tage was originally an HTML attribute string. It should
+      // now be a standard attributes array.
       // If the caller provided the same key, this will force me to use those.
       if (is_array($tags)) {
         $attributes = array_merge($my_attrs, $tags);
       }
       else {
+        // Handle the old string format.
         $attributes = array_merge($my_attrs, taxonomy_image_parse_tags($tags));
       }
       $return_url = '<img src="'. $current->url .'"'. drupal_attributes($attributes) .'/>';
@@ -132,16 +117,72 @@
   }
   return $attrs;
 }
+/**
+ * Function to get a url for an image, for use in css, html or other client-side code.
+ * @param
+ *   $tid - the term id
+ * @return
+ *   The url string.
+ */
+function taxonomy_image_get_url($tid) {
+  $image = taxonomy_image_get_object($tid);
+  return $image->url;
+}
+
+/**
+ * Function to get an image object with more useful data for custom formatting.
+ * @param
+ *   $tid - the term tid.
+ * @return
+ *   image object.
+ */
+function taxonomy_image_get_object($tid) {
+  static $image = array();
 
-// standard Drupal functions
+  if (user_access('access taxonomy images') && !$user->taxonomy_image_disable_images) {
+    if (!$image[$tid]->url) {
+      if ($image[$tid] = db_fetch_object(db_query('SELECT i.path, d.name FROM {term_image} i INNER JOIN {term_data} d USING(tid) WHERE i.tid=%d', $tid))) {
+        $image[$tid]->url = file_create_url($image[$tid]->path);
+      }
+      elseif (variable_get('taxonomy_image_recursive', 0)) {
+        // walk up the taxonomy hierarchy and look for an image
+        $orig = $tid;
+        while ($parent = db_fetch_object(db_query('SELECT t.tid FROM {term_hierarchy} h, {term_data} t WHERE h.parent=t.tid AND h.tid=%d ORDER BY weight, name', $tid))) {
+          $tid = $parent->tid;
+          if ($image[$tid]->url) {
+            // we have already loaded this image from the database
+            $image[$orig] = $image[$tid];
+            break;
+          } 
+          elseif ($image[$tid] = db_fetch_object(db_query('SELECT i.path, d.name FROM {term_image} i INNER JOIN {term_data} d USING(tid) WHERE i.tid=%d', $tid))) {
+            // we found a parent with a configured image, use it
+            $image[$tid]->url = file_create_url($image[$tid]->path);
+            $image[$orig] = $image[$tid];
+            break;
+          }
+        }
+      }
+    }
+    list($image[$tid]->width, $image[$tid]->height) = getimagesize($image[$tid]->path);
+    return $image[$tid];
+  }
+  return null;
+}
+// Standard Drupal functions.
+/**
+ * Implementation of hook_perm.
+ */
 function taxonomy_image_perm() {
   return array('access taxonomy images', 'administer taxonomy images', 'can disable taxonomy images');
 }
 
-function taxonomy_image_help($section = '') {
+/**
+ * Implementation of hook_help.
+ */
+function taxonomy_image_help($section) {
   switch ($section) {
     case 'admin/content/taxonomy/image':
-      return t('The taxonomy_image module allows site administrators to associate images with category terms.  Once defined, this association allows Drupal themes to display images with site content.  For example, this module might be used to display a penguin with content about Linux, and a cheeseburger with content about junk food.  To upload a new image for a specific term, click "upload image" next to the term.  To modify or delete and existing image, click "edit image".  To learn more about how to create vocabularies and terms, review the <a href="%taxonomy-help">taxonomy help page</a>.', array('%taxonomy-help' => url('admin/help/taxonomy')));
+      return t('The taxonomy_image module allows site administrators to associate images with category terms.  Once defined, this association allows Drupal themes to display images with site content.  For example, this module might be used to display a penguin with content about Linux, and a cheeseburger with content about junk food.  To upload a new image for a specific term, click "upload image" next to the term.  To modify or delete and existing image, click "edit image".  To learn more about how to create vocabularies and terms, review the <a href="!taxonomy-help">taxonomy help page</a>.', array('!taxonomy-help' => url('admin/help/taxonomy')));
     case 'admin/help#taxonomy_image':
       return t('
       <h3>Introduction</h3>
@@ -169,6 +210,9 @@
   }
 }
 
+/**
+ * Implementation of hook_menu.
+ */
 function taxonomy_image_menu($may_cache) {
   $items = array();
 
@@ -458,27 +502,26 @@
 
 function taxonomy_image_save($tid) {
   $edit['tid'] = $tid;
-  $fields = array('tid', 'path');
   $directory = file_create_path(variable_get('taxonomy_image_path', 'category_pictures'));
   file_check_directory($directory, FILE_CREATE_DIRECTORY);
-  if ($file = file_save_upload('path', file_create_path(variable_get('taxonomy_image_path', 'category_pictures')))) {
-    $edit['path'] = $file->filepath;
 
-    if ($old_image = db_fetch_object(db_query('SELECT tid FROM {term_image} WHERE tid = %d', $edit['tid']))) {
-      // delete old image before saving the new one
-      taxonomy_image_delete($old_image->tid);
-    }
+  // There is a slight risk that we will delete an image even if the new one can't be saved.
+  if ($old_image = db_fetch_object(db_query('SELECT tid FROM {term_image} WHERE tid = %d', $edit['tid']))) {
+    // delete old image before saving the new one
+    taxonomy_image_delete($old_image->tid);
+  }
 
-    foreach ($fields as $field) {
-      $values[] = (string)db_escape_string($edit[$field]);
-    }
+  if ($file = file_save_upload('path', $directory)) {
+    $edit['path'] = $file->filepath;
 
-    db_query('INSERT INTO {term_image} ('. implode(', ', $fields) .') VALUES (\''. implode('\', \'', $values) .'\')');
-    cache_clear_all();
+    db_query("INSERT INTO {term_image} (tid, path) VALUES ('%d', '%s')", $tid, $file->filepath);
+    // @todo do we need to clear the whole cache?  Can't we just clear taxonomy_image bits of the cache?
+    // @todo do we need even to clear the cache?  Taxonomy caches with "static."
+//    cache_clear_all();
 
-    $message = t('Image uploaded.');
+    $message = t('Image uploaded as @name.', array('@name' => $file->filepath));
   }
-  else if (!file_check_directory(file_create_path(variable_get('taxonomy_image_path', 'category_pictures')))) {
+  else if (!file_check_directory($directory)) {
     // we know what's wrong, so generate a more useful error message
     $message = theme('error', t('The category picture directory "%dir" does not exist, or is not writable.', array('%dir' => variable_get('file_directory_path', 'files') .'/'. variable_get('taxonomy_image_path', 'category_pictures'))));
   }
@@ -489,14 +532,23 @@
 }
 
 function taxonomy_image_delete($tid) {
-  file_delete(db_result(db_query('SELECT path FROM {term_image} WHERE tid = %d', $tid)));
-  db_query('DELETE FROM {term_image} WHERE tid = %d', $tid);
-  cache_clear_all();
-  return drupal_set_message(t('Image deleted.'));
+  $old_path = db_result(db_query('SELECT path FROM {term_image} WHERE tid=%d', $tid));
+  $file_del_ok = file_delete($old_path);
+  $db_del_ok = db_query('DELETE FROM {term_image} WHERE tid=%d', $tid);
+// @todo: why clear the cache?
+//  cache_clear_all();
+  if ($file_del_ok && $db_del_ok) {
+    drupal_set_message(t('@name image deleted.', array('@name' => $old_path)));
+  }
+  else {
+    drupal_set_message(t('Image delete failed. File: !file, Db: !db.',
+      array('!file' => ($file_del_ok ? 'yes' : 'no'), '!db' => ($db_del_ok ? 'yes' : 'no'))));
+  }
+  return;
 }
 
 function _taxonomy_image_exists($tid) {
-  if (db_fetch_object(db_query('SELECT path FROM {term_image} WHERE tid = %d', $tid))) {
+  if (db_fetch_object(db_query('SELECT path FROM {term_image} WHERE tid=%d', $tid))) {
     return 1;
   }
   return 0;
