Index: image_attach.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/image/contrib/image_attach/image_attach.install,v
retrieving revision 1.16
diff -u -p -r1.16 image_attach.install
--- image_attach.install	22 Aug 2009 11:30:43 -0000	1.16
+++ image_attach.install	26 Aug 2009 11:34:10 -0000
@@ -22,8 +22,14 @@ function image_attach_schema() {
         'not null' => TRUE,
         'default' => 0,
       ),
+      'weight' => array(
+        'description' => 'The display order of attached images.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
     ),
-    'primary key' => array('nid'),
+    'primary key' => array('nid', 'iid'),
     'indexes' => array(
       'iid' => array('iid'),
     ),
@@ -119,4 +125,18 @@ function image_attach_update_6101() {
   return $ret;  
 }
 
+/**
+ * Adjust primary key on {image_attach} to allow multiple attachments.
+ */
+function image_attach_update_6102() {
+  $ret = array();
+  db_drop_primary_key($ret, 'image_attach');
+  db_add_primary_key($ret, 'image_attach', array('nid', 'iid'));
+  db_add_field($ret, 'image_attach', 'weight', array(
+    'type' => 'int',
+    'not null' => TRUE,
+    'default' => 0,
+  ));
+  return $ret;
+}
 
Index: image_attach.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/image/contrib/image_attach/image_attach.module,v
retrieving revision 1.52
diff -u -p -r1.52 image_attach.module
--- image_attach.module	26 Aug 2009 07:52:05 -0000	1.52
+++ image_attach.module	26 Aug 2009 11:56:01 -0000
@@ -76,15 +76,17 @@ function image_attach_block($op = 'list'
       if ($delta == 0) {
         if (arg(0) == 'node' && is_numeric(arg(1))) {
           $node = node_load(arg(1));
-          if (isset($node->iid) && $node->iid) {
-            $image = node_load($node->iid);
-            if (node_access('view', $image)) {
-              $img = image_display($image, variable_get('image_attach_block_0_size', IMAGE_THUMBNAIL));
-              return array(
-                'subject' => t('Attached images'),
-                'content' => l($img, "node/$node->iid", array('html' => TRUE)),
-              );
+          if (isset($node->iids)) {
+            $output['subject'] = t('Attached images');
+            foreach ($node->iids as $iid) {
+              $image = node_load($iid);
+              if (node_access('view', $image)) {
+                $img = image_display($image, variable_get('image_attach_block_0_size', IMAGE_THUMBNAIL));
+                $content .= '<div class="attached-image">' .l($img, "node/$iid", array('html' => TRUE)). '</div>';
+              }
             }
+            $output['content'] = '<div class="all-attached-images">' .$content. '</div>';
+            return $output;
           }
         }
       }
@@ -115,8 +117,6 @@ function image_attach_block($op = 'list'
   }
 }
 
-
-
 /**
  * implementation of hook_form_alter()
  */
@@ -184,26 +184,30 @@ function image_attach_form_alter(&$form,
         '#type' => 'fieldset',
         '#title' => t('Attached images'),
         '#collapsible' => TRUE,
-        '#collapsed' => empty($node->iid),
+        '#collapsed' => empty($node->iids),
       );
       // Add a custom submit handler so we can handle image creation on-the-fly
       $form['#validate'][] = 'image_attach_validate'; 
 
-      if (!empty($node->iid)) {
-        $image = node_load($node->iid);
-        $form['image_attach']['image_thumbnail'] = array(
-          '#type' => 'item',
-          '#title' => t('Thumbnail'),
-          '#value' => image_display($image, 'thumbnail')
-        );
+      if (!empty($node->iids)) {
+        foreach ($node->iids as $iid) {
+          $image = node_load($iid);
+          $form['image_attach']['image_thumbnail'][$iid] = array(
+            '#type' => 'item',
+            '#title' => t('Thumbnail'),
+            '#value' => image_display($image, 'thumbnail')
+          );
+        }
       }
       if (variable_get('image_attach_existing', 1) && user_access('access content')) {
-        $form['image_attach']['iid'] = array(
+        $form['image_attach']['iids'] = array(
           '#type' => 'select',
           '#title' => t('Existing image'),
           '#options' => _image_attach_get_image_nodes(),
-          $value => empty($node->iid) ? NULL : $node->iid,
-          '#description' => t('Choose an image already existing on the server if you do not upload a new one.')
+          $value => empty($node->iids) ? NULL : $node->iids,
+          '#description' => t('Choose an image already existing on the server if you do not upload a new one.'),
+          '#multiple' => TRUE,
+          '#size' => 6,
         );
         $form['image_attach'][] = array(
           '#type' => 'item',
@@ -212,10 +216,12 @@ function image_attach_form_alter(&$form,
         );
       }
       else {
-        $form['image_attach']['iid'] = array(
-          '#type' => 'hidden',
-          $value => empty($node->iid) ? NULL : $node->iid,
-        );
+        foreach ($node->iids as $iid) {
+          $form['image_attach']['iids'][$iid] = array(
+            '#type' => 'value',
+            '#value' => $iid,
+          );
+        }
       }
       $form['image_attach']['image'] = array(
         '#type' => 'file',
@@ -227,27 +233,72 @@ function image_attach_form_alter(&$form,
         $value => '',
         '#description' => t('The title the image will be shown with.')
       );
+      // Provide an additional submit button, which adds an image and redirects
+      // the user to the node edit form.
+      $form['image_attach']['image_attach_multiple'] = array(
+        '#type' => 'submit',
+        '#value' => t('Attach'),
+        '#validate' => array('image_attach_validate'),
+        '#submit' => array('image_attach_image_add_submit'),
+      );
     }
   }
 }
 
 /**
+ * Save attached image nids and rebuild form.
+ *
+ * This submit function adds the new images and returns to the
+ * node edit form directly afterwards, without creating the new node yet.
+ */
+function image_attach_image_add_submit(&$form, &$form_state) {
+  // Rebuild the attached image data.
+  if (isset($form_state['values']['iids'])) {
+    db_query("DELETE FROM {image_attach} WHERE nid = %d", $form['nid']['#value']);
+    if (count($form_state['values']['iids'])) {
+      $weight = 0;
+      foreach ($form_state['values']['iids'] as $iid) {
+        db_query("INSERT INTO {image_attach} (nid, iid, weight) VALUES (%d, %d, %d)", $form['nid']['#value'], $iid, $weight++);
+      }
+    }
+  }
+
+  // Convert taxonomy format from Preview to Object.
+  if (module_exists('taxonomy') && !empty($form_state['values']['taxonomy'])) {
+    $temp_node = new stdClass();
+    $temp_node->taxonomy = $form_state['values']['taxonomy'];
+    $form_state['values']['taxonomy'] = taxonomy_preview_terms($temp_node);
+    unset($temp_node);
+  }
+
+  // Rebuild the node edit form.
+  node_form_submit_build_node($form, $form_state);
+}
+
+/**
  * Capture node form submission and immediately create an image if one has been
  * uploaded.
  * Note that the new image nodes are created even on preview. Taking several
  * attempts may create trash.
  */
-function image_attach_validate($form, &$form_state) {
+function image_attach_validate(&$form, &$form_state) {
   $validators = array(
     'file_validate_is_image' => array(),
   );
   if ($file = file_save_upload('image', $validators)) {
     $image_title = $_POST['image_title'] ? $_POST['image_title'] : basename($file->filepath);
-    // This func now does all the things to initialize an image properly
+    // Initialize an image properly.
     $image = image_create_node_from($file->filepath, $image_title, '');
     if ($image && !form_get_errors()) {
       drupal_set_message(t("Created new image to attach to this node. !image_link", array('!image_link' => l($image_title, 'node/'. $image->nid) )));
-      form_set_value($form['image_attach']['iid'], $image->nid, $form_state);
+      // Append image nid to array of images.
+      $form_state['values']['iids'][$image->nid] = $image->nid;
+    }
+  }
+  else {
+    // Only raise error if user clicked specific Attach button.
+    if ($form_state['clicked_button']['#value'] == 'Attach') {
+      form_set_error('image_attach', t('Invalid or missing image file for upload and attach.'));
     }
   }
 }
@@ -260,7 +311,7 @@ function image_attach_nodeapi(&$node, $o
   if ($node->type == 'image') {
     switch ($op) {
       case 'delete':
-        db_query("DELETE FROM {image_attach} WHERE iid=%d", $node->nid);
+        db_query("DELETE FROM {image_attach} WHERE iid = %d", $node->nid);
     }
     return;
   }
@@ -270,41 +321,54 @@ function image_attach_nodeapi(&$node, $o
   switch ($op) {
     case 'insert':
     case 'update':
-      if (isset($node->iid)) {
-        db_query("DELETE FROM {image_attach} WHERE nid=%d", $node->nid);
-        if ($node->iid > 0) {
-          db_query("INSERT INTO {image_attach} (nid, iid) VALUES (%d, %d)", $node->nid, $node->iid);
+      if (!empty($node->iids)) {
+        db_query("DELETE FROM {image_attach} WHERE nid = %d", $node->nid);
+        // Populate weight column with placeholder values.
+        $weight = 0;
+        foreach ($node->iids as $iid) {
+          db_query("INSERT INTO {image_attach} (nid, iid, weight) VALUES (%d, %d, %d)", $node->nid, $iid, $weight++);
         }
       }
       break;
 
     case 'delete':
-      db_query("DELETE FROM {image_attach} WHERE nid=%d", $node->nid);
+      db_query("DELETE FROM {image_attach} WHERE nid = %d", $node->nid);
       break;
 
     case 'load':
-      $iid = db_result(db_query("SELECT iid FROM {image_attach} WHERE nid=%d", $node->nid));
-      return array('iid' => $iid);
+      $res = db_query("SELECT iid FROM {image_attach} WHERE nid = %d ORDER BY weight", $node->nid);
+      $iids = array();
+      while ($iid = db_fetch_array($res)) {
+        $iids[] = $iid['iid'];
+      }
+      return array('iids' => $iids);
 
-    // Pass the body and teaser objects to the theme again to add the images
+    // Pass the body and teaser objects to the theme again to add the images.
     case 'view':
-      if ($node->iid) {
+      if (!empty($node->iids)) {
         $teaser_or_body = $teaser ? 'teaser' : 'body';
-        $node->content['image_attach'] = array(
-          '#value' => theme("image_attach_{$teaser_or_body}", $node),
-          '#weight' => variable_get("image_attach_weight_{$teaser_or_body}_{$node->type}", 0),
-        );
+        $node->content['image_attach'] = array('#weight' => variable_get("image_attach_weight_{$teaser_or_body}_{$node->type}", 0));
+        if ($teaser_or_body == 'teaser') {
+          $node->content['image_attach'][$node->iids[0]]['#value'] = theme("image_attach_{$teaser_or_body}", $node, $node->iids[0]);
+        }
+        else {
+          $content = '';
+          foreach ($node->iids as $iid) {
+            $content .= theme("image_attach_{$teaser_or_body}", $node, $iid);
+          }
+          $node->content['image_attach']['#value'] = '<div class="all-attached-images">' .$content. '</div>';
+        }
       }
       break;
 
     case 'rss item':
       $ret = array();
-      if ($node->iid && $image = node_load($node->iid)) {
+      if (!empty($node->iids) && $image = node_load($node->iids[0])) {
         $info = image_get_info(file_create_path($image->images[IMAGE_PREVIEW]));
         $ret[] = array(
           'key' => 'enclosure',
           'attributes' => array(
-            'url' => url("image/view/{$node->iid}/". IMAGE_PREVIEW, array('absolute' => TRUE)),
+            'url' => url("image/view/{$node->iids[0]}/". IMAGE_PREVIEW, array('absolute' => TRUE)),
             'length' => $info['file_size'],
             'type' => $info['mime_type'],
           )
@@ -353,7 +417,6 @@ function image_attach_views_handlers() {
   );
 }
 
-
 /**
  * Implementation of hook_theme() registry.
  **/
@@ -369,18 +432,23 @@ function image_attach_theme() {
 }
 
 /**
- * Theme the teaser.
+ * Theme an image shown in teaser.
+ *
+ * @param $node
+ *   The node object to theme.
+ * @param $iid
+ *   Node id of image to display.
  *
  * Override this in template.php to include a case statement if you want different node types to appear differently.
  * If you have additional image sizes you defined in image.module, you can use them by theming this function as well.
  */
-function theme_image_attach_teaser($node) {
+function theme_image_attach_teaser($node, $iid) {
   $img_size = variable_get('image_attach_size_teaser_'. $node->type, 'thumbnail');
 
   if ($img_size != IMAGE_ATTACH_HIDDEN) {
     drupal_add_css(drupal_get_path('module', 'image_attach') .'/image_attach.css');
 
-    $image = node_load($node->iid);
+    $image = node_load($iid);
     if (!node_access('view', $image)) {
       // If the image is restricted, don't show it as an attachment.
       return NULL;
@@ -393,7 +461,7 @@ function theme_image_attach_teaser($node
     $info = image_get_info(file_create_path($image->images[$img_size]));
 
     $output = '<div style="width: ' . $info['width'] . 'px" class="' . $class . '">';
-    $output .= l(image_display($image, $img_size), "node/$node->nid", array('html' => TRUE));
+    $output .= l(image_display($image, $img_size), "node/$iid", array('html' => TRUE));
     $output .= '</div>'."\n";
 
     return $output;
@@ -401,15 +469,20 @@ function theme_image_attach_teaser($node
 }
 
 /**
- * Theme the body
+ * Theme an image shown in body
+ *
+ * @param $node
+ *   The node object to theme.
+ * @param $iid
+ *   Nid of image to display.
  */
-function theme_image_attach_body($node) {
+function theme_image_attach_body($node, $iid) {
   $img_size = variable_get('image_attach_size_body_'. $node->type, IMAGE_THUMBNAIL);
 
   if ($img_size != IMAGE_ATTACH_HIDDEN) {
     drupal_add_css(drupal_get_path('module', 'image_attach') .'/image_attach.css');
 
-    $image = node_load($node->iid);
+    $image = node_load($iid);
     if (!node_access('view', $image)) {
       // If the image is restricted, don't show it as an attachment.
       return NULL;
@@ -422,7 +495,7 @@ function theme_image_attach_body($node) 
     $info = image_get_info(file_create_path($image->images[$img_size]));
 
     $output = '<div style="width: ' . $info['width'] . 'px" class="' . $class . '">';
-    $output .= l(image_display($image, $img_size), "node/$node->iid", array('html' => TRUE));
+    $output .= l(image_display($image, $img_size), "node/$iid", array('html' => TRUE));
     $output .= '</div>'."\n";
 
     return $output;
