? test.patch
? contrib/image_attach/test.patch
? contrib/image_import/image_import.module_____fixes
Index: image.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/image/image.module,v
retrieving revision 1.243
diff -u -r1.243 image.module
--- image.module	1 Jul 2007 21:59:16 -0000	1.243
+++ image.module	5 Jul 2007 19:35:18 -0000
@@ -115,15 +115,15 @@
     IMAGE_LINK_SHOWN => t('Same window'),
     IMAGE_LINK_NEW => t('New window'),
   );
-  
+
   $sizes = _image_get_sizes();
   // Add some empty rows for user defined sizes.
   for ($i = count($sizes); $i < 6; $i++) {
     $sizes['new'. $i] = array(
       'label' => '',
-      'width' => '', 
-      'height' => '', 
-      'link' => IMAGE_LINK_SHOWN, 
+      'width' => '',
+      'height' => '',
+      'link' => IMAGE_LINK_SHOWN,
       'new' => TRUE,
     );
   }
@@ -133,8 +133,9 @@
       '#type' => 'textfield',
       '#default_value' => $size['label'],
       '#size' => 25,
+      '#maxlength' => 32,
     );
-    if (in_array($key, _image_required_sizes())) {
+    if (_image_is_required_size($key)) {
       $form['image_sizes'][$key]['label']['#attributes'] = array('disabled' => 'disabled');
       $form['image_sizes'][$key]['label']['#required'] = TRUE;
     }
@@ -169,6 +170,7 @@
  */
 function image_settings_sizes_validate(&$form) {
   foreach (element_children($form) as $key) {
+    // If there's a label they must provide at either a height or width.
     if ($key != IMAGE_ORIGINAL && !empty($form[$key]['label']['#value'])) {
       if (empty($form[$key]['width']['#value']) && empty($form[$key]['height']['#value'])) {
         form_set_error("image_sizes][$key][width", t('Must specify a width or height.'));
@@ -184,9 +186,11 @@
  */
 function image_settings_sizes_submit($form_id, &$form_values) {
   foreach ($form_values['image_sizes'] as $key => $value) {
+    // Remove rows with no label.
     if (empty($value['label'])) {
       unset($form_values['image_sizes'][$key]);
     }
+    // Set a key for new rows.
     else if ($value['new']) {
       unset($form_values['image_sizes'][$key]);
       $form_values['image_sizes'][$value['label']] = $value;
@@ -297,13 +301,16 @@
       form_set_error($field_name, t('Uploaded file is not a valid image. Only JPG, PNG and GIF files are allowed.'));
       return;
     }
+
     // Save the file to the temp directory.
     $file = file_save_upload($field_name, _image_filename($file->filename, IMAGE_ORIGINAL, TRUE));
     if (!$file) {
       return;
     }
+
     // Resize the original.
-    $original_size = _image_get_sizes(IMAGE_ORIGINAL);
+    $aspect_ratio = $image_info['height'] / $image_info['width'];
+    $original_size = _image_get_sizes(IMAGE_ORIGINAL, $aspect_ratio);
     if (!empty($original_size['width']) && !empty($original_size['height'])) {
       $result = image_scale($file->filepath, $file->filepath, $original_size['width'], $original_size['height']);
       if ($result) {
@@ -312,12 +319,14 @@
         drupal_set_message(t('The original image was resized to fit within the maximum allowed resolution of %width x %height pixels.', array('%width' => $original_size['width'], '%height' => $original_size['height'])));
       }
     }
+
     // Check the file size limit.
     if ($file->filesize > variable_get('image_max_upload_size', 800) * 1024) {
       form_set_error($field_name, t('The image you uploaded was too big. You are only allowed upload files less than %max_size but your file was %file_size.', array('%max_size' => format_size(variable_get('image_max_upload_size', 800) * 1024), '%file_size' => format_size($file->filesize))));
       file_delete($file->filepath);
       return;
     }
+
     // We're good to go.
     $node->images[IMAGE_ORIGINAL] = $file->filepath;
     $node->new_file = TRUE;
@@ -360,10 +369,10 @@
               'attributes' => array('target' => '_blank'),
             );
           }
-          else {            
+          else {
             $links['image_size_'. $key] = array(
               'title' => $size['label'],
-              'href' => 'node/'. $node->nid, 
+              'href' => 'node/'. $node->nid,
               'query' => 'size='. urlencode($key)
             );
           }
@@ -598,7 +607,7 @@
   // regenerate images?
   if ($node->images[$label] != $node->images[IMAGE_ORIGINAL] &&
       (!file_exists(file_create_path($node->images[$label])) ||
-       filemtime(file_create_path($node->images[$label])) < variable_get('image_updated', 0))) 
+       filemtime(file_create_path($node->images[$label])) < variable_get('image_updated', 0)))
   {
     _image_remove_derivatives($node);
     _image_build_derivatives($node);
@@ -610,10 +619,10 @@
     return;
   }
 
-  $info = image_get_info(file_create_path($node->images[$label]));
+  $image_info = image_get_info(file_create_path($node->images[$label]));
   $attributes['class'] = "image image-$label ". (isset($attributes['class']) ? $attributes['class'] : "");
-  $attributes['width'] = $info['width'];
-  $attributes['height'] = $info['height'];
+  $attributes['width'] = $image_info['width'];
+  $attributes['height'] = $image_info['height'];
 
   return theme('image_display', $node, $label, file_create_url($node->images[$label]), $attributes);
 }
@@ -759,28 +768,25 @@
     return FALSE;
   }
   $original_path = file_create_path($node->images[IMAGE_ORIGINAL]);
-  $info = image_get_info($original_path);
+
   // If we can't find our original image, we can not proceed.
-  if (!$info) {
+  if (!$image_info = image_get_info($original_path)) {
     return FALSE;
   }
+  $aspect_ratio = $image_info['height'] / $image_info['width'];
 
-  foreach (_image_get_sizes() as $key => $size) {
-    if (empty($size['width']) || empty($size['height'])) {
-      $aspect = $info['height'] / $info['width'];
-      if (empty($size['height']) && !empty($size['width'])) {
-        $size['height'] = (int)round($size['width'] * $aspect);
-      }
-      elseif (empty($size['width']) && !empty($size['height'])) {
-        $size['width'] = (int)round($size['height'] / $aspect);
-      }
+  foreach (_image_get_sizes(NULL, $aspect_ratio) as $key => $size) {
+    // Skip over the original.
+    if ($key == IMAGE_ORIGINAL) {
+      continue;
     }
+
     if (!empty($size['width']) && !empty($size['height'])) {
       $destination = _image_filename($original_path, $key, $temp);
 
-      // Don't bother making a derivative image if the original is smaller than
-      // the requested size.
-      if ($info['width'] > $size['width'] || $info['height'] > $size['height']) {
+      // If the original isn't bigger than the requested size then there's no
+      // need to resize it.
+      if ($image_info['width'] > $size['width'] || $image_info['height'] > $size['height']) {
         if (!image_scale($original_path, $destination, $size['width'], $size['height'])) {
           drupal_set_message(t('Unable to create scaled %label image', array('%label' => $size['label'])), 'error');
           return FALSE;
@@ -789,23 +795,23 @@
         module_invoke_all('image_alter', $node, $destination, $key);
       }
       else {
-        unset($node->images[$key]);
+        $node->images[$key] = NULL;
       }
     }
   }
 }
 
 function _image_remove_derivatives($node) {
-  $result = db_query("SELECT * FROM {files} WHERE nid=%d AND filename <> '%s'", $node->nid, IMAGE_ORIGINAL);
+  $original_file = db_fetch_object(db_query("SELECT * FROM {files} WHERE nid=%d AND filename = '%s'", $node->nid, IMAGE_ORIGINAL));
+  $result = db_query("SELECT * FROM {files} WHERE nid=%d AND fid <> %d", $node->nid, $original_file->fid);
   while ($file = db_fetch_object($result)) {
     // Never delete the original!
-    if ($file->filepath != $node->images[IMAGE_ORIGINAL]) {
+    if ($file->filepath != $original_file->filepath) {
       file_delete(file_create_path($file->filepath));
     }
   }
-  $original_fid = db_result(db_query("SELECT fid FROM {files} WHERE nid=%d AND filename = '%s'", $node->nid, IMAGE_ORIGINAL));
-  db_query("DELETE FROM {files} WHERE nid = %d AND filename <> '%s'", $node->nid, IMAGE_ORIGINAL);
-  db_query("DELETE FROM {file_revisions} WHERE vid = %d AND fid <> %d", $node->vid, $original_fid);
+  db_query("DELETE FROM {files} WHERE nid = %d AND fid <> %d", $node->nid, $original_file->fid);
+  db_query("DELETE FROM {file_revisions} WHERE vid = %d AND fid <> %d", $node->vid, $original_file->fid);
 }
 
 /**
@@ -825,8 +831,8 @@
     if ($pos === false) {
       // The file had no extension - which happens in really old image.module
       // versions, so figure out the extension.
-      $info = image_get_info(file_create_path($path . $filename));
-      $filename = $filename .'.'. $label .'.'. $info['extension'];
+      $image_info = image_get_info(file_create_path($path . $filename));
+      $filename = $filename .'.'. $label .'.'. $image_info['extension'];
     }
     else {
       $filename = substr($filename, 0, $pos) .'.'. $label . substr($filename, $pos);
@@ -840,11 +846,16 @@
  * Helper function to return the defined sizes (or proper defaults).
  *
  * @param $size
- *   An optional string to return only the specific image size.
+ *   An optional string to return only the image size with the specified key.
+  * @param $aspect_ratio
+ *   Float value with the ratio of image height / width. If a size has only one
+ *   dimension provided this will be used to compute the other.
  * @return
  *   An associative array with width, height, and label fields for the size.
+ *   If a $size parameter was specified and it cannot be found FALSE will be 
+ *   returned.
  */
-function _image_get_sizes($size = NULL) {
+function _image_get_sizes($size = NULL, $aspect_ratio = NULL) {
   $defaults = array(
     IMAGE_ORIGINAL => array('width' => '', 'height' => '', 'label' => t('Original'), 'link' => IMAGE_LINK_SHOWN),
     IMAGE_THUMBNAIL => array('width' => 100, 'height' => 100, 'label' => t('Thumbnail'), 'link' => IMAGE_LINK_SHOWN),
@@ -853,7 +864,18 @@
 
   $sizes = array();
   foreach (variable_get('image_sizes', $defaults) as $key => $val) {
+    // Only return sizes with a label.
     if (!empty($val['label'])) {
+      // For a size with only one dimension specified, compute the other 
+      // dimension based on an aspect ratio.
+      if ($aspect_ratio && (empty($val['width']) || empty($val['height']))) {
+        if (empty($val['height']) && !empty($val['width'])) {
+          $val['height'] = (int)round($val['width'] * $aspect_ratio);
+        }
+        elseif (empty($val['width']) && !empty($val['height'])) {
+          $val['width'] = (int)round($val['height'] / $aspect_ratio);
+        }
+      }
       $sizes[$key] = $val;
     }
   }
@@ -867,8 +889,14 @@
   return $sizes;
 }
 
-function _image_required_sizes() {
-  return array(IMAGE_THUMBNAIL, IMAGE_PREVIEW, IMAGE_ORIGINAL);
+/**
+ * Is a given size a built-in, required size?
+ * @param $size
+ *   On of the keys in the array returned by _image_get_sizes().
+ * @return boolean
+ */
+function _image_is_required_size($size) {
+  return in_array($size, array(IMAGE_THUMBNAIL, IMAGE_PREVIEW, IMAGE_ORIGINAL));
 }
 
 /**
@@ -893,12 +921,83 @@
     // if a file of the same name already existed.
     $node->images[$size] = $image_path;
 
-    $info = image_get_info($image_path);
+    $image_info = image_get_info($image_path);
     $fid = db_next_id('{files}_fid');
     db_query("INSERT INTO {files} (fid, nid, filename, filepath, filemime, filesize) VALUES (%d, %d, '%s', '%s', '%s', '%s')",
-             $fid, $node->nid, $size, $image_path, $info['mime_type'], $info['file_size']);
+             $fid, $node->nid, $size, $image_path, $image_info['mime_type'], $image_info['file_size']);
     db_query("INSERT INTO {file_revisions} (fid, vid, description, list) VALUES (%d, %d, '%s', %d)",
              $fid, $node->vid, '', 0);
   }
 }
 
+/**
+ * Function to other modules to use to create image nodes.
+ *
+ * @param $filepath
+ *   String filepath of an image file. Note that this file will be moved into 
+ *   the image module's images directory.
+ * @param $title
+ *   String to be used as the node's title. If this is ommitted the filename 
+ *   will be used.
+ * @param $body 
+ *   String to be used as the node's body.
+ * @param $taxonomy
+ *   Taxonomy terms to assign to the node if the taxonomy.module is installed.
+ * @return 
+ *   A node object if the node is created successfully or FALSE on error.
+ */
+function image_create_node_from($filepath, $title = NULL, $body = '', $taxonomy = NULL) {
+  global $user;
+
+  if (!user_access('create images')) {
+    drupal_access_denied();
+  }
+  
+  // Ensure it's a valid image.
+  if (!$image_info = image_get_info($filepath)) {
+    return FALSE;
+  }
+
+  $file = new stdClass();
+  $file->filepath = realpath($filepath);
+  $file->filename = basename($file->filepath);
+
+  $node = new stdClass();
+  $node->type = 'image';
+  $node->uid = $user->uid;
+  $node->name = $user->name;
+
+  // Set the node's defaults... (copied this from node and comment.module)
+  $node_options = variable_get('node_options_'. $node->type, array('status', 'promote'));
+  $node->status = in_array('status', $node_options);
+  $node->promote = in_array('promote', $node_options);
+  if (module_exists('comment')) {
+    $node->comment = variable_get("comment_$node->type", COMMENT_NODE_READ_WRITE);
+  }
+  if (module_exists('taxonomy')) {
+    $node->taxonomy = $taxonomy;
+  }
+  
+  $node->title = isset($title) ? $title : $file->filename;
+  $node->body = $body;
+
+  // Resize the original.
+  $aspect_ratio = $image_info['height'] / $image_info['width'];
+  $original_size = _image_get_sizes(IMAGE_ORIGINAL, $aspect_ratio);
+  if (!empty($original_size['width']) && !empty($original_size['height'])) {
+    if (image_scale($file->filepath, $file->filepath, $original_size['width'], $original_size['height'])) {
+      clearstatcache();
+      $file->filesize = filesize($file->filepath);
+    }
+  }
+
+  $node->images[IMAGE_ORIGINAL] = $file->filepath;
+  _image_build_derivatives($node, TRUE);
+  $node->new_file = TRUE;
+
+  $node = node_submit($node);
+  node_save($node);
+
+  return $node;
+}
+
Index: contrib/image_import/image_import.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/image/contrib/image_import/image_import.module,v
retrieving revision 1.7
diff -u -r1.7 image_import.module
--- contrib/image_import/image_import.module	22 May 2007 00:39:24 -0000	1.7
+++ contrib/image_import/image_import.module	5 Jul 2007 18:51:38 -0000
@@ -175,11 +175,11 @@
         $origname = $form_values['file_list'][$index];
         $filename = file_check_location($dirpath .'/'. $origname, $dirpath);
         if ($filename) {
-          $node = _image_import_file(
+          $node = image_create_node_from(
             $filename,
-            $form_values['taxonomy'],
             $form_values['title'][$index],
-            $form_values['body'][$index]
+            $form_values['body'][$index],
+            $form_values['taxonomy']
           );
 
           if ($node) {
@@ -221,61 +221,6 @@
   return system_settings_form($form);
 }
 
-function _image_import_file($filepath, $taxonomy, $title = '', $body = '') {
-  global $user;
-
-  //check for user permission...
-  if (!user_access('create images')) {
-    drupal_access_denied();
-  }
-
-  // build a file object
-  $file = new stdClass();
-  $file->filepath = realpath($filepath);
-  $file->filename = basename($file->filepath);
-
-  // start building a node
-  $node = new stdClass();
-  $node->type = 'image';
-  $node->uid = $user->uid;
-  $node->name = $user->name;
-
-  // set the node's defaults... (copied this from node and comment.module)
-  $node_options = variable_get('node_options_'. $node->type, array('status', 'promote'));
-  $node->status = in_array('status', $node_options);
-  $node->promote = in_array('promote', $node_options);
-  if (module_exists('comment')) {
-    $node->comment = variable_get("comment_$node->type", COMMENT_NODE_READ_WRITE);
-  }
-  if (module_exists('taxonomy')) {
-    $node->taxonomy = $taxonomy;
-  }
-
-  // Fill in the node content
-  $node->title = $title ? $title : $file->filename;
-  $node->body = $body;
-
-  // copy the file so if there's a problem it can be re-imported.
-  if (file_copy($file, _image_filename($file->filename, NULL, TRUE), FILE_EXISTS_RENAME)) {
-    if ($image = image_get_info($file->filepath)) {
-      $node->images[IMAGE_ORIGINAL] = $file->filepath;
-      _image_build_derivatives($node, TRUE);
-      $node->new_file = TRUE;
-
-      $node = node_submit($node);
-      node_save($node);
-
-      // remove the original file
-      file_delete($filepath);
-
-      return $node;
-    }
-    // the copied file wasn't a proper image, trash it
-    file_delete($file->filepath);
-  }
-  return FALSE;
-}
-
 /**
  * Checks the existence of the directory specified in $form_element.
  *
