Index: inline.install
===================================================================
RCS file: inline.install
diff -N inline.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ inline.install	11 Aug 2009 22:35:03 -0000
@@ -0,0 +1,75 @@
+<?php
+// $Id: inline.module,v 1.39 2009/08/11 20:29:35 sun Exp $
+
+/**
+ * @file
+ * Inline installation functions.
+ */
+
+/**
+ * Implementation of hook_schema().
+ */
+function inline_schema() {
+  $schema['inline'] = array(
+    'description' => t('Stores inline tags.'),
+    'fields' => array(
+      'iid' => array('type' => 'serial'),
+      'parameters' => array('type' => 'text', 'size' => 'normal'),
+      'status' => array('type' => 'int', 'not null' => TRUE, 'default' => 0,
+        'description' => 'A flag indicating whether the tag is temporary (1) or permanent (0).',
+      ),
+      'timestamp' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0,
+        'description' => 'UNIX timestamp for when the tag was added.',
+      ),
+    ),
+    'primary key' => array('iid'),
+    'indexes' => array(
+      'status' => array('status'),
+    ),
+  );
+  return $schema;
+}
+
+/**
+ * Implementation of hook_install().
+ */
+function inline_install() {
+  drupal_install_schema('inline');
+}
+
+/**
+ * Implementation of hook_uninstall()
+ */
+function inline_uninstall() {
+  drupal_uninstall_schema('inline');
+}
+
+/**
+ * Create new {inline} table.
+ */
+function inline_update_6001() {
+  $ret = array();
+  if (db_table_exists('inline')) {
+    return $ret;
+  }
+  // Install new schema.
+  db_create_table($ret, 'inline', array(
+    'description' => t('Stores inline tags.'),
+    'fields' => array(
+      'iid' => array('type' => 'serial'),
+      'parameters' => array('type' => 'text', 'size' => 'normal'),
+      'status' => array('type' => 'int', 'not null' => TRUE, 'default' => 0,
+        'description' => 'A flag indicating whether the tag is temporary (1) or permanent (0).',
+      ),
+      'timestamp' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0,
+        'description' => 'UNIX timestamp for when the tag was added.',
+      ),
+    ),
+    'primary key' => array('iid'),
+    'indexes' => array(
+      'status' => array('status'),
+    ),
+  ));
+  return $ret;
+}
+
Index: inline.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/inline/inline.module,v
retrieving revision 1.37
diff -u -p -r1.37 inline.module
--- inline.module	11 Aug 2009 19:06:42 -0000	1.37
+++ inline.module	12 Aug 2009 01:00:40 -0000
@@ -14,6 +14,64 @@ function inline_perm() {
 }
 
 /**
+ * Implementation of hook_elements().
+ */
+function inline_elements() {
+  $type['textarea'] = array('#process' => 'inline_process_textarea');
+  return $type;
+}
+
+function inline_process_textarea(&$form, $edit, &$form_state, $complete_form) {
+  /*
+  $parents = $form['#array_parents'];
+  array_pop($parents);
+  foreach ($parents as $key) {
+    $complete_form = $complete_form[$key];
+  }
+  if (isset($complete_form['format'])) {
+    $element = $complete_form['format'];
+    // Make sure we either match a input format selector or input format
+    // guidelines (displayed if user has access to one input format only).
+    if ((isset($element['#type']) && $element['#type'] == 'fieldset') || isset($element['format']['guidelines'])) {
+    }
+  }
+  */
+
+  // Store a reference to this textarea for our submit handler.
+  $form_state['inline_elements'][] = $form['#parents'];
+
+  // @todo
+  preg_match_all('/\[inline\|iid=(\d+)\]/', $form['#value'], $matches);
+  foreach ($matches[1] as $key => $iid) {
+    if ($params = inline_tag_load($iid)) {
+      $value = str_replace($matches[0][$key], inline_build_macro($params), $form['#value']);
+      $form['#value'] = $value;
+    }
+  }
+
+  return $form;
+}
+
+function inline_form_alter(&$form, &$form_state) {
+  $form['#submit'][] = 'inline_form_submit';
+}
+
+function inline_form_submit($form, &$form_state) {
+  if (!isset($form_state['inline_elements'])) {
+    return;
+  }
+  foreach ($form_state['inline_elements'] as $parents) {
+    eval('$content = &$form_state[\'values\'][\'' . implode("']['", $parents) . "'];");
+
+    foreach (inline_get_macros($content) as $macro => $params) {
+      $object = inline_tag_save($params);
+      $GLOBALS['inline'][$object->iid] = $object;
+      $content = str_replace($macro, '[inline|iid=' . $object->iid . ']', $content);
+    }
+  }
+}
+
+/**
  * Implementation of hook_inline_info().
  *
  * @see hook_inline_info()
@@ -56,6 +114,13 @@ function inline_filter($op, $delta = 0, 
 
     case 'process':
       $processed = FALSE;
+      // @todo
+      preg_match_all('/\[inline\|iid=(\d+)\]/', $text, $matches);
+      foreach ($matches[1] as $key => $iid) {
+        if ($params = inline_tag_load($iid)) {
+          $text = str_replace($matches[0][$key], inline_build_macro($params), $text);
+        }
+      }
       foreach (inline_get_macros($text) as $macro => $params) {
         $validation = inline_validate_params($params);
         if (is_bool($validation) && $validation) {
@@ -92,6 +157,9 @@ function inline_invoke($params, $op) {
 
 /**
  * Return all inline macros as an array.
+ *
+ * @todo Use placeholders for #default_value and/or additional properties.
+ *   Or introduce a new $op 'alter' for hook_inline?
  */
 function inline_get_macros($text) {
   $macros = array();
@@ -157,6 +225,9 @@ function inline_get_macros($text) {
         $params['params'][$key] = $value;
       }
     }
+    if (isset($params['params']['iid'])) {
+      $params['iid'] = $params['params']['iid'];
+    }
     // The full unaltered tag is the key for the filter attributes array.
     $macros[$matches[0][$n]] = $params;
   }
@@ -264,16 +335,17 @@ function inline_render($params) {
  * @see inline_nodeapi()
  */
 function inline_alter_macros(&$node, $fields) {
-  if ($node->inline_altered) {
+  if (isset($node->inline_altered)) {
     return;
   }
 
-  // Backup some node properties to undo them later, since we don't know whether
-  // other modules are invoked after hook_nodeapi of Inline.
+  // Backup some node properties to revert them later, since we do not know
+  // whether other modules are invoked after inline_nodeapi().
   $properties = array(
     'is_new' => $node->is_new,
     'revision' => $node->revision,
     'old_vid' => isset($node->old_vid) ? $node->old_vid : NULL,
+    'files' => $node->files,
   );
 
   // @todo When a new node is saved, some modules (like menu) do not update
@@ -283,6 +355,17 @@ function inline_alter_macros(&$node, $fi
   //   ensure this.
   $node = node_load($node->nid);
 
+  // Revert some file properties from the originally passed node.
+  foreach ($node->files as $fid => $file) {
+    // $op insert/update expects an array.
+    settype($node->files[$fid], 'array');
+    // Do not perform any file updates.
+    if (isset($properties['files'][$fid])) {
+      $node->files[$fid]['remove'] = 0;
+      $node->files[$fid]['new'] = FALSE;
+    }
+  }
+
   // Mark this node as processed to prevent recursive loops.
   $node->inline_altered = TRUE;
 
@@ -299,7 +382,7 @@ function inline_alter_macros(&$node, $fi
   // Save the altered node (again).
   node_save($node);
 
-  // Undo our changes.
+  // Revert our changes.
   foreach ($properties as $property => $value) {
     $node->$property = $value;
   }
@@ -329,7 +412,7 @@ function _inline_alter_macros(&$node, $f
     // @todo Assign the currently processed field name to $params['#field'] to
     //   allow certain hook_inline implementations to add/ensure this
     //   information in their macros.
-    if (isset($params['params']['nid']) && $params['params']['nid'] == 0) {
+    if (!isset($params['params']['nid']) || $params['params']['nid'] == 0) {
       $params['params']['nid'] = $node->nid;
       $content = str_replace($macro, inline_build_macro($params), $content);
       // @todo Update of reference table perhaps needed.
@@ -350,6 +433,9 @@ function inline_build_macro($params) {
   $macro_params = array();
 
   $macro_params[] = $params['tag'];
+  if (isset($params['iid'])) {
+    $params['params'] = array_merge(array('iid' => $params['iid']), $params['params']);
+  }
   // @todo Support for #multiple values.
   // @todo Escape |, [, ] chars in values.
   foreach ($params['params'] as $key => $value) {
@@ -363,6 +449,43 @@ function inline_build_macro($params) {
  */
 
 /**
+ * @defgroup inline_crud Inline CRUD functions.
+ * @{
+ */
+
+function inline_tag_load($iid) {
+  if ($params = db_result(db_query("SELECT parameters FROM {inline} WHERE iid = %d", $iid))) {
+    $params = unserialize($params);
+    $params['iid'] = $iid;
+  }
+  return $params;
+}
+
+function inline_tag_save($params) {
+  $params['params'] = inline_invoke($params, 'presave', $params['params']);
+  $object = new stdClass;
+  $update = array();
+  if (isset($params['iid'])) {
+    $update[] = 'iid';
+    $object->iid = $params['iid'];
+    unset($params['iid']);
+    $object->status = 0;
+  }
+  else {
+    $object->status = 1; // temporary
+  }
+  unset($params['status']);
+  $object->timestamp = time();
+  $object->parameters = serialize($params);
+  drupal_write_record('inline', $object, $update);
+  return $object;
+}
+
+/**
+ * @} End of "defgroup inline_crud".
+ */
+
+/**
  * Implementation of hook_nodeapi().
  *
  * Inline needs to
@@ -391,13 +514,29 @@ function inline_nodeapi(&$node, $op, $a3
       //   filter cache for all contents referencing it.  As long as there is
       //   no generic solution, we completely clear the filter cache.
       cache_clear_all(NULL, 'cache_filter');
-      return;
 
-      // Break intentionally left out.
     case 'insert':
       // Update references to 'current' system objects, e.g. the nid after
       // inserting a new node.
-      inline_alter_macros($node, $fields);
+      #inline_alter_macros($node, $fields);
+
+      // @todo Assign the currently processed field name to $params['#field'] to
+      //   allow certain hook_inline implementations to add/ensure this
+      //   information in their macros.
+      // @todo Update of reference table perhaps needed.
+      if (empty($GLOBALS['inline'])) {
+        return;
+      }
+      foreach ($GLOBALS['inline'] as $iid => $object) {
+        $params = unserialize($object->parameters);
+        $params['iid'] = $iid;
+        $params['status'] = 0;
+        if (!isset($params['params']['nid'])) {
+          $params['params']['nid'] = $node->nid; // vid here?
+        }
+        inline_tag_save($params);
+        #drupal_write_record('inline', $object, array('iid'));
+      }
       return;
 
     case 'prepare':
Index: inline_upload.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/inline/inline_upload.module,v
retrieving revision 1.7
diff -u -p -r1.7 inline_upload.module
--- inline_upload.module	11 Aug 2009 19:06:42 -0000	1.7
+++ inline_upload.module	12 Aug 2009 00:57:26 -0000
@@ -50,25 +50,7 @@ function inline_upload_inline($op, $para
       );
       return $args;
 
-    case 'validate':
-      // Custom validation of user supplied values.
-      return TRUE;
-
-    case 'prepare':
-      // Prepare user supplied values for rendering.
-      if ($params['nid'] == 0) {
-        // Insert some tricky code to insert current node id here. 02/02/2008 sun
-        if (arg(0) == 'node' && is_numeric(arg(1))) {
-          $params['nid'] = (int)arg(1);
-        }
-      }
-      // Load a node object if valid nid is given.
-      if ($params['nid'] > 0) {
-        $node = node_load($params['nid']);
-        if (node_access('view', $node)) {
-          $params['#node'] = $node;
-        }
-      }
+    case 'presave':
       // Add new uploaded files to $node->files in node preview.
       // @see upload_js()
       // @todo This basically works how it should. However, altered weights are
@@ -76,7 +58,7 @@ function inline_upload_inline($op, $para
       //   additionally derive the attachment weights from the form in $_POST.
       $cached_form_state = array();
       if (isset($_POST['form_build_id']) && ($cached_form = form_get_cache($_POST['form_build_id'], $cached_form_state)) && isset($cached_form['#node']) && isset($cached_form['attachments']['wrapper']['files'])) {
-        $params['#node']->files = array();
+        $files = array();
         foreach (element_children($cached_form['attachments']['wrapper']['files']) as $fid) {
           $element = $cached_form['attachments']['wrapper']['files'][$fid];
           if (empty($element['remove']['#default_value'])) {
@@ -84,16 +66,37 @@ function inline_upload_inline($op, $para
             foreach ($element as $key => $item) {
               $file->{$key} = (isset($item['#value']) ? $item['#value'] : $item['#default_value']);
             }
-            $params['#node']->files[$fid] = $file;
+            $files[$fid] = $file;
           }
         }
       }
       // Convert a numeric file reference to a named one.
-      if (is_int($params['file']) && isset($params['#node']->files)) {
-        $files = array_keys($params['#node']->files);
+      if (is_int($params['file']) && isset($files)) {
+        $filekeys = array_keys($files);
         // Humans count from 1.
-        if (isset($files[$params['file'] - 1])) {
-          $params['file'] = $params['#node']->files[$files[$params['file'] - 1]]->filename;
+        if (isset($filekeys[$params['file'] - 1])) {
+          $params['file'] = $files[$filekeys[$params['file'] - 1]]->filename;
+        }
+      }
+      return $params;
+
+    case 'validate':
+      // Custom validation of user supplied values.
+      return TRUE;
+
+    case 'prepare':
+      // Prepare user supplied values for rendering.
+      if ($params['nid'] == 0) {
+        // Insert some tricky code to insert current node id here. 02/02/2008 sun
+        if (arg(0) == 'node' && is_numeric(arg(1))) {
+          $params['nid'] = (int)arg(1);
+        }
+      }
+      // Load a node object if valid nid is given.
+      if ($params['nid'] > 0) {
+        $node = node_load($params['nid']);
+        if (node_access('view', $node)) {
+          $params['#node'] = $node;
         }
       }
       return $params;
@@ -305,10 +308,10 @@ function _inline_upload_decide_img_tag($
       list($maxwidth, $maxheight) = explode(',', variable_get('inline_upload_img_dim', '150,150'));
 
       if (!empty($file->in_preview)) {
-        list($width, $height) = getimagesize($file->real_path);
+        list($width, $height) = @getimagesize($file->real_path);
       }
       else {
-        list($width, $height) = getimagesize($file->filepath);
+        list($width, $height) = @getimagesize($file->filepath);
       }
       if (($width && $height) && ($width <= $maxwidth && $height <= $maxheight)) {
         return TRUE;
@@ -347,8 +350,10 @@ function theme_inline_upload_img($file, 
   // Prepare link text with inline title, file description or filename.
   $title = (!empty($file->title) ? $file->title : (!empty($file->description) ? $file->description : $file->filename));
   $inline_upload_preset = ($field == 'teaser' ? 'inline_upload_teaser_preset' : 'inline_upload_full_preset');
-  
+  $url = file_create_url($file->filepath);
+
   if (module_exists('imagecache') && variable_get($inline_upload_preset, '') != '') {
+    // ImageCache implements its own private files handling.
     $output = theme('imagecache',
       variable_get($inline_upload_preset, ''),
       $file->filepath,
@@ -358,12 +363,15 @@ function theme_inline_upload_img($file, 
     );
   }
   else {
+    // Private files support: theme_image() requires us to set $getsize to FALSE
+    // and prepare image attributes on our own.
+    $info = image_get_info($file->filepath);
     $output = theme('image',
-      $file->filepath,
+      $url,
       $title,
       $title,
-      array('class' => 'inline'),
-      !isset($file->in_preview)
+      array('class' => 'inline', 'width' => $info['width'], 'height' => $info['height']),
+      FALSE
     );
   }
   
@@ -372,7 +380,7 @@ function theme_inline_upload_img($file, 
       'class' => 'inline-image-link',
       'title' => t('View: @file', array('@file' => $title)),
     );
-    $output = l($output, $file->filepath, array('attributes' => $attributes, 'html' => TRUE));
+    $output = l($output, $url, array('attributes' => $attributes, 'html' => TRUE));
   }
   
   return $output;
