Index: imagecache.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/imagecache/imagecache.info,v
retrieving revision 1.3
diff -u -p -r1.3 imagecache.info
--- imagecache.info	14 Dec 2007 13:28:57 -0000	1.3
+++ imagecache.info	13 Apr 2008 22:33:03 -0000
@@ -2,5 +2,5 @@
 name = ImageCache
 description = Dynamic image manipulator and cache.
 package = ImageCache
-dependencies = imageapi
-version = VERSION
+dependencies[] = imageapi
+core = 6.x
Index: imagecache.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/imagecache/imagecache.install,v
retrieving revision 1.7
diff -u -p -r1.7 imagecache.install
--- imagecache.install	2 Apr 2008 07:21:01 -0000	1.7
+++ imagecache.install	13 Apr 2008 22:33:03 -0000
@@ -1,53 +1,74 @@
 <?php
 // $Id: imagecache.install,v 1.7 2008/04/02 07:21:01 dopry Exp $
 
-function imagecache_install() {
-  switch ($GLOBALS['db_type']) {
-    case 'mysql':
-    case 'mysqli':
-      $ret1 = db_query("CREATE TABLE {imagecache_preset} (
-            presetid INT UNSIGNED NOT NULL PRIMARY KEY,
-            presetname VARCHAR(255) NOT NULL DEFAULT '' )
-            /*!40100 DEFAULT CHARACTER SET utf8 */
-      ");
-
-      $ret2 = db_query("CREATE TABLE {imagecache_action} (
-            actionid INT UNSIGNED NOT NULL PRIMARY KEY,
-            presetid INT UNSIGNED NOT NULL DEFAULT 0,
-            weight INT NOT NULL DEFAULT 0,
-            module varchar(255) not null default '',
-            action varchar(255) not null default '',
-            data TEXT NOT NULL)
-            /*!40100 DEFAULT CHARACTER SET utf8 */
-      ");
-      break;
 
-    case 'pgsql':
-      $ret1 = db_query("CREATE TABLE {imagecache_preset} (
-            presetid INTEGER NOT NULL CHECK (presetid > 0),
-            presetname VARCHAR(255) NOT NULL DEFAULT '',
-            PRIMARY KEY (presetid));
-      ");
-      $ret2 = db_query("CREATE TABLE {imagecache_action} (
-            actionid INTEGER NOT NULL CHECK (actionid > 0),
-            presetid INTEGER NOT NULL DEFAULT 0,
-            weight INTEGER NOT NULL DEFAULT 0,
-            module varchar(255) not null default '',
-            action varchar(255) not null default '',
-            data TEXT NOT NULL DEFAULT '',
-            PRIMARY KEY (actionid));
-      ");
-      db_query("CREATE SEQUENCE imagecache_preset_presetid_seq INCREMENT 1 START 1;");
-      db_query("CREATE SEQUENCE imagecache_action_actionid_seq INCREMENT 1 START 1;");
-      break;
-  }
+function imagecache_schema() {
+    $schema['imagecache_preset'] = array(
+    'fields' => array(
+      'presetid' => array(
+        'description' => t('The primary identifier for an imagecache_preset.'),
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE),
+      'presetname' => array(
+        'description' => t('The primary identifier for a node.'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE),
+    ),
+    'primary key' => array('presetid'),
+  );
+
+  $schema['imagecache_action'] = array(
+    'fields' => array(
+      'actionid' => array(
+        'description' => t('The primary identifier for an imagecache_action.'),
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE),
+      'presetid' => array(
+        'description' => t('The primary identifier for an imagecache_preset.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0),
+      'weight' => array(
+        'description' => t('The weight of the action in the preset.'),
+        'type' => 'int',
+        'unsigned' => FALSE,
+        'not null' => TRUE,
+        'default' => 0),
+      'module' => array(
+        'description' => t('The module that defined the action.'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE),
+      'action' => array(
+        'description' => t('The unique ID of the action to be executed.'),
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE),
+      'data' => array(
+        'description' => t('The configuration data for the action.'),
+        'type' => 'text',
+        'not null' => TRUE,
+        'size' => 'big',
+        'serialize' => TRUE),
+    ),
+    'primary key' => array('actionid'),
+    'indexes' => array(
+      'presetid' => array('presetid'),
+    ),
+  );
 
-  if ($ret1 && $ret2) {
-    drupal_set_message(t('Imagecache module installed succesfully.'));
-  } else {
-    drupal_set_message(t('Imagecache module installation was unsuccessfull. Necessary database tables should be created by hand.', 'error'));
-  }
-  return $ret;
+
+
+  return $schema;
+}
+
+
+function imagecache_install() {
+  drupal_install_schema('imagecache');
 }
 
 // Add action id to actions table.
@@ -69,7 +90,7 @@ function imagecache_update_2() {
       $ret[] = update_sql('ALTER TABLE {imagecache_preset} CHANGE rulesetname presetname VARCHAR(255) NOT NULL DEFAULT \'\'');
       $ret[] = update_sql('ALTER TABLE {imagecache_action} CHANGE rulesetid presetid  INTEGER NOT NULL DEFAULT 0');
       break;
-    
+
     case 'pgsql':
       $ret[] = update_sql('ALTER TABLE {imagecache_preset} RENAME COLUMN rulesetid TO presetid');
       $ret[] = update_sql('ALTER TABLE {imagecache_preset} RENAME COLUMN rulesetname TO presetname');
@@ -80,15 +101,15 @@ function imagecache_update_2() {
 }
 
 
-/** 
+/**
  * Remove auto-increment from tables, instead depending on the sequences table and db_next_id()
- */  
+ */
 function imagecache_update_3() {
   $ret = array();
-  
+
   $count_action = db_result(db_query('SELECT max(actionid) FROM {imagecache_action}')) + 1;
   $count_preset = db_result(db_query('SELECT max(presetid) FROM {imagecache_preset}')) + 1;
-  
+
   switch ($GLOBALS['db_type']) {
     case 'mysql':
     case 'mysqli':
@@ -128,7 +149,7 @@ function imagecache_update_4() {
   $result = db_query("SELECT * FROM {imagecache_action}");
   while($row = db_fetch_array($result)) {
     $data = unserialize($row['data']);
-    // Keep scale and crop and the old scale function seperate... I don't really want to break BC with 
+    // Keep scale and crop and the old scale function seperate... I don't really want to break BC with
     // the 2.x update. We'll deprecate this version.
     $function = $data['function'];
     unset($data['function']);
@@ -138,7 +159,7 @@ function imagecache_update_4() {
     if ($function == 'scale and crop') {
       $function = 'scale_and_crop';
     }
-    // Keep scale and crop and the old scale function seperate... I don't really want to break BC with 
+    // Keep scale and crop and the old scale function seperate... I don't really want to break BC with
     // the 2.x update. We'll deprecate this version.
     if ($function == 'scale') {
       $function = 'deprecated_scale';
@@ -160,18 +181,5 @@ function imagecache_update_4() {
  * Implementation of hook_uninstall().
  */
 function imagecache_uninstall() {
-  db_query('DROP TABLE {imagecache_preset}');
-  db_query('DROP TABLE {imagecache_action}');
-
-  switch ($GLOBALS['db_type']) {
-    case 'mysql':
-    case 'mysqli':
-      db_query("DELETE FROM {sequences} WHERE name = '{imagecache_action}_actionid'");
-      db_query("DELETE FROM {sequences} WHERE name = '{imagecache_action}_presetid'");
-      break;
-    case 'pgsql':
-      db_query('DROP SEQUENCE {imagecache_action}_actionid_seq');
-      db_query('DROP SEQUENCE {imagecache_preset}_presetid_seq');
-      break;
-  }
+  drupal_uninstall_schema('imagecache');
 }
Index: imagecache.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/imagecache/imagecache.module,v
retrieving revision 1.54
diff -u -p -r1.54 imagecache.module
--- imagecache.module	21 Feb 2008 12:44:54 -0000	1.54
+++ imagecache.module	13 Apr 2008 22:33:04 -0000
@@ -8,24 +8,24 @@
  * Imagecache allows you to setup specialized identifiers for dynamic image
  * processing and caching. It abuses the rewrite rules used for drupal's clean
  * URLs to provide dynamic image generation.
- * 
+ *
  * Earlier security flaws were overcome by using 'presets' similar to
  * image.module. We don't fuss with the database, and creating data that we have
  * to keep up within Drupal. We do it on the fly and flush it when we want to,
  * or when a preset changes.
- * 
+ *
  * URLs are of the form: files/imagecache/<preset>/path
- * 
+ *
  * @todo: improve image resizing, reduce distortion.
  * @todo: add watermarking capabilities.
  * @todo: split action/handlers into their own little .inc files.
  * @todo: enforce permissions.
- * 
+ *
  * Notes:
  *   To add a new handler,
  *     add fields and select option to _imagecache_actions_form;
  *     add handling code to imagecache_cache
- * 
+ *
  */
 
 
@@ -47,26 +47,23 @@ function imagecache_perm() {
 /**
  * Implementation of hook_menu().
  */
-function imagecache_menu($may_cache) {
+function imagecache_menu() {
   $items = array();
-  if ($may_cache) {
 
-    // standard imagecache callback.
-    $items[] = array(
-      'path' => file_directory_path() .'/imagecache', 
-      'callback' => 'imagecache_cache',
-      'access' => TRUE,
-      'type' => MENU_CALLBACK
-    );
+  // standard imagecache callback.
+  $items[file_directory_path() .'/imagecache'] = array(
+    'page callback' => 'imagecache_cache',
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK
+  );
+
+  // private downloads imagecache callback
+  $items['system/files/imagecache'] = array(
+    'page callback' => 'imagecache_cache_private',
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK
+  );
 
-    // private downloads imagecache callback 
-    $items[] = array( 
-      'path' => 'system/files/imagecache',
-      'callback' => 'imagecache_cache_private',
-      'access' => TRUE,
-      'type' => MENU_CALLBACK
-    );     
-  }
   return $items;
 }
 
@@ -97,26 +94,83 @@ function imagecache_requirements($phase)
             'title' => $t('GD !format Support', array('!format' => drupal_ucfirst($format))),
             'value' => $t('Not installed'),
             'severity' => REQUIREMENT_INFO,
-            'description' => $t('PHP was not compiled with %format support. Imagecache will not be able to process %format images.', array('%format' => $format)), 
+            'description' => $t('PHP was not compiled with %format support. Imagecache will not be able to process %format images.', array('%format' => $format)),
           );
         }
-      } 
+      }
     }
   }
   return $requirements;
 }
 
 /**
+ * Implementation of hook_theme().
+ */
+function imagecache_theme() {
+  return array(
+    'imagecache' => array(
+      'arguments' => array(
+        'namespace' => NULL,
+        'path' => NULL,
+        'alt' => NULL,
+        'title' => NULL,
+    )),
+    'imagecache_imagelink' => array(
+      'arguments' => array(
+        'namespace' => NULL,
+        'path' => NULL,
+        'alt' => NULL,
+        'title' => NULL,
+        'attributes' => array(),
+    )),
+    'imagecache_formatter' => array(
+      'arguments' => array(
+        'field' => NULL,
+        'item' => NULL,
+        'formatter' => NULL,
+    )),
+    'imagecache_resize' => array(
+      'arguments' => array('element' => NULL),
+    ),
+    'imagecache_scale' => array(
+      'file' => 'imagecache_actions.inc',
+      'arguments' => array('element' => NULL),
+    ),
+    'imagecache_scale_and_crop' => array(
+      'file' => 'imagecache_actions.inc',
+      'arguments' => array('element' => NULL),
+    ),
+    'imagecache_deprecated_scale' => array(
+      'file' => 'imagecache_actions.inc',
+      'arguments' => array('element' => NULL),
+    ),
+    'imagecache_crop' => array(
+      'file' => 'imagecache_actions.inc',
+      'arguments' => array('element' => NULL),
+    ),
+    'imagecache_desaturate' => array(
+      'file' => 'imagecache_actions.inc',
+      'arguments' => array('element' => NULL),
+    ),
+    'imagecache_rotate' => array(
+      'file' => 'imagecache_actions.inc',
+      'arguments' => array('element' => NULL),
+    ),
+    
+  );
+}
+
+/**
  * Implementation of hook_imagecache_actions.
  *
  * @return array
- *   An array of information on the actions implemented by a module. The array contains a 
- *   sub-array for each action node type, with the machine-readable action name as the key. 
+ *   An array of information on the actions implemented by a module. The array contains a
+ *   sub-array for each action node type, with the machine-readable action name as the key.
  *   Each sub-array has up to 3 attributes. Possible attributes:
- * 
+ *
  *     "name": the human-readable name of the action. Required.
  *     "description": a brief description of the action. Required.
- *     "file": the name of the include file the action can be found 
+ *     "file": the name of the include file the action can be found
  *             in relative to the implementing module's path.
  */
 function imagecache_imagecache_actions() {
@@ -150,6 +204,11 @@ function imagecache_imagecache_actions()
       'description' => 'Convert an image to grey scale.',
       'file' => 'imagecache_actions.inc',
     ),
+    'imagecache_rotate' => array(
+      'name' => 'Rotate',
+      'description' => 'Rotate an image.',
+      'file' => 'imagecache_actions.inc',
+    ),
   );
 
   return $actions;
@@ -169,20 +228,20 @@ function imagecache_action_definitions($
   static $actions;
   if (!isset($actions) || $reset) {
     if (!$reset && ($cache = cache_get('imagecache_actions')) && !empty($cache->data)) {
-      $actions = unserialize($cache->data);
+      $actions = $cache->data;
     }
     else {
       foreach(module_implements('imagecache_actions') as $module) {
         foreach (module_invoke($module, 'imagecache_actions') as $key => $action) {
           $action['module'] = $module;
-          if ($action['file']) {
+          if (!empty($action['file'])) {
             $action['file'] = drupal_get_path('module', $action['module']) .'/'. $action['file'];
           }
           $actions[$key] = $action;
         };
       }
       uasort($actions, '_imagecache_definitions_sort');
-      cache_set('imagecache_actions', 'cache', serialize($actions));
+      cache_set('imagecache_actions', $actions);
     }
   }
   return $actions;
@@ -202,14 +261,14 @@ function imagecache_action_definition($a
   if (!isset($definition_cache[$action])) {
     $definitions = imagecache_action_definitions();
     $definition = (isset($definitions[$action])) ? $definitions[$action] : array();
-    
+
     if ($definition && $definition['file']) {
       require_once($definition['file']);
     }
     $definition_cache[$action] = $definition;
   }
   return $definition_cache[$action];
-} 
+}
 
 /**
  * Return a URL that points to the location of a derivative of the
@@ -243,7 +302,7 @@ function _imagecache_strip_file_director
 }
 
 
-/** 
+/**
  * callback for handling public files imagecache requests.
  */
 function imagecache_cache() {
@@ -263,7 +322,7 @@ function imagecache_cache_private() {
 
   if (user_access('view imagecache '. $preset)) {
     _imagecache_cache($preset, $source);
-  } 
+  }
   else {
     // if there is a 403 image, display it.
     $accesspath = file_create_path('imagecache/'. $preset .'.403.png');
@@ -277,32 +336,32 @@ function imagecache_cache_private() {
 }
 
 /**
- * handle request validation and responses to imagecache requests. 
+ * handle request validation and responses to imagecache requests.
  */
 function _imagecache_cache($presetname, $path) {
   if (!$preset = imagecache_preset_by_name($presetname)) {
-    // send a 404 if we dont' know of a preset. 
+    // send a 404 if we dont' know of a preset.
     header("HTTP/1.0 404 Not Found");
     exit;
   }
 
   // umm yeah deliver it early if it is there. especially useful
-  // to prevent lock files from being created when delivering private files. 
+  // to prevent lock files from being created when delivering private files.
   $dst = imagecache_create_path($preset['presetname'], $path);
   if (file_exists($dst)) {
     imagecache_transfer($dst);
-  }  
+  }
 
   $src = file_create_path($path);
-  if (!is_file($src)) {
+  if (!is_file($src) && isset($_SESSION['imagefield'])) {
     // scan the session
-    foreach ($_SESSION['imagefield'] as $fieldname => $files) {
+    foreach ((array) $_SESSION['imagefield'] as $fieldname => $files) {
       foreach ($files as $delta => $file) {
         if ($file['preview'] == $src) {
           $dst = tempnam(file_directory_temp(), 'imagecache.preview');
           if (!imagecache_build_derivative($preset['actions'], $file['filepath'], $dst)) {
             // Generate an error if image could not generate.
-            watchdog('imagecache', t('Failed generating a preview image from %image using imagecache preset %preset.', array('%image' => $path, '%preset' => $presetname)), WATCHDOG_ERROR);
+            watchdog('imagecache', 'Failed generating a preview image from %image using imagecache preset %preset.', array('%image' => $path, '%preset' => $presetname), WATCHDOG_ERROR);
             header("HTTP/1.0 500 Internal Server Error");
             exit;
           }
@@ -311,7 +370,7 @@ function _imagecache_cache($presetname, 
         }
       }
     }
-  
+
     // if there is a 404 image uploaded for the preset display it.
     $notfoundpath = file_create_path('imagecache/'. $preset['presetname'] .'.404.png');
     if (file_exists($notfoundpath)) {
@@ -325,8 +384,8 @@ function _imagecache_cache($presetname, 
 
   $lockfile = file_directory_temp() .'/'. $preset['presetname'] . basename($src) ;
   if (file_exists($lockfile)) {
-    watchdog('imagecache', t('Imagecache already generating: %dst, Lock file: %tmp.', array('%dst' => $dst, '%tmp' => $lockfile)), WATCHDOG_NOTICE);
-    // send a response code that will make the browser wait and reload in a 1/2 sec. 
+    watchdog('imagecache', 'Imagecache already generating: %dst, Lock file: %tmp.', array('%dst' => $dst, '%tmp' => $lockfile), WATCHDOG_NOTICE);
+    // send a response code that will make the browser wait and reload in a 1/2 sec.
     // header()
     exit;
   }
@@ -335,24 +394,24 @@ function _imagecache_cache($presetname, 
   register_shutdown_function('file_delete', $lockfile);
 
   // check if deriv exists... (file was created between apaches request handler and reaching this code)
-  // otherwise try to create the derivative. 
+  // otherwise try to create the derivative.
   if (!file_exists($dst) && !imagecache_build_derivative($preset['actions'], $src, $dst)) {
     // Generate an error if image could not generate.
-    watchdog('imagecache', t('Failed generating an image from %image using imagecache preset %preset.', array('%image' => $path, '%preset' => $preset)), WATCHDOG_ERROR);
+    watchdog('imagecache', 'Failed generating an image from %image using imagecache preset %preset.', array('%image' => $path, '%preset' => $preset), WATCHDOG_ERROR);
     header("HTTP/1.0 500 Internal Server Error");
     exit;
-  } 
+  }
   imagecache_transfer($dst);
 }
 
 function _imagecache_apply_action($action, &$image) {
   $actions = imagecache_action_definitions();
- 
+
   if ($definition = imagecache_action_definition($action['action'])) {
     return call_user_func($action['action'] .'_image', $image, $action['data']);
   }
   // skip undefined actions.. module probably got uninstalled or disabled.
-  watchdog('imagecache', t('non-existant action %action', array('%action' => $action['action'])), WATCHDOG_NOTICE);
+  watchdog('imagecache', 'non-existant action %action', array('%action' => $action['action']), WATCHDOG_NOTICE);
   return TRUE;
 }
 
@@ -428,24 +487,24 @@ function _imagecache_mkdir($dir) {
       continue;
     }
     if (is_file($path)) {
-      watchdog('imagecache', t('file exists where we would like a directory: %path', array('%path' => $path)), WATCHDOG_ERROR);
+      watchdog('imagecache', 'file exists where we would like a directory: %path', array('%path' => $path), WATCHDOG_ERROR);
       return FALSE;
-    } 
+    }
     if (!@mkdir($path)) {
-      watchdog('imagecache', t('Could not create destination: %dir halted at: %path', array('%dir' => $dir, '%path' => $path)), WATCHDOG_ERROR);
+      watchdog('imagecache', 'Could not create destination: %dir halted at: %path', array('%dir' => $dir, '%path' => $path), WATCHDOG_ERROR);
       return FALSE;
     }
     if (!@chmod($path, 0775)) {
-      watchdog('imagecache', t('Could not set permissons on created directory: %dir halted at: %path', array('%dir' => $dir, '%path' => $path)), WATCHDOG_ERROR);
+      watchdog('imagecache', 'Could not set permissons on created directory: %dir halted at: %path', array('%dir' => $dir, '%path' => $path), WATCHDOG_ERROR);
       return FALSE;
-    } 
+    }
   }
   return TRUE;
 }
- 
+
 /**
  * build an image cache derivative
- * 
+ *
  * @param $actions  Array of imagecache actions.
  * @param $src      Path of the source file.
  * @param $dst      Path of the destination file.
@@ -458,12 +517,12 @@ function imagecache_build_derivative($ac
 
   // Build the destination folder tree if it doesn't already exists.
   if (!file_check_directory($dir) && !_imagecache_mkdir($dir)) {
-    watchdog('imagecache', t('Failed to create imagecache directory: %dir', array('%dir' => $dir)), WATCHDOG_ERROR);
+    watchdog('imagecache', 'Failed to create imagecache directory: %dir', array('%dir' => $dir), WATCHDOG_ERROR);
     return FALSE;
   }
 
   if (!$image = imageapi_image_open($src)) {
-    return FALSE; 
+    return FALSE;
   }
 
 
@@ -481,30 +540,30 @@ function imagecache_build_derivative($ac
       }
     }
     if (!_imagecache_apply_action($action, $image)) {
-      watchdog( 'imagecache', t('action(id:%id): %action failed for %src', array('%id' => $action['actionid'], '%action' => $action['action'], '%src' => $src)), WATCHDOG_ERROR);
+      watchdog('imagecache', 'action(id:%id): %action failed for %src', array('%id' => $action['actionid'], '%action' => $action['action'], '%src' => $src), WATCHDOG_ERROR);
       return FALSE;
     }
   }
 
   if (!imageapi_image_close($image, $dst)) {
     if (file_exists($dst)) {
-      watchdog('imagecache', t('Cached image file already exists. There is an issue with your Rewrite configuration.'), WATCHDOG_ERROR);
+      watchdog('imagecache', 'Cached image file already exists. There is an issue with your Rewrite configuration.', WATCHDOG_ERROR);
     }
     return FALSE;
   }
   return TRUE;
 }
 
-  
+
 
 function imagecache_imagefield_file($op, $file) {
   switch($op) {
     // Delete imagecache presets when imagecache images are deleted.
     case 'delete': imagecache_image_flush($file['filepath']); break;
 
-    // Create imagecache derivatives when files are saved. 
-    case 'save': 
-      break; 
+    // Create imagecache derivatives when files are saved.
+    case 'save':
+      break;
   }
 
 }
@@ -513,6 +572,7 @@ function imagecache_imagefield_file($op,
  * Implementation of hook_field_formatter_info().
  */
 function imagecache_field_formatter_info() {
+  $formatters = array();
   foreach (imagecache_presets() as $preset) {
     $formatters[$preset['presetname']] = array(
       'label' => $preset['presetname'],
@@ -535,7 +595,7 @@ function imagecache_field_formatter_info
  */
 function imagecache_field_formatter($field, $item, $formatter) {
   if (empty($item['fid']) && $field['use_default_image']) {
-    $item = $field['default_image']; 
+    $item = $field['default_image'];
   }
   // Views does not load the file for us, while CCK display fields does.
   if (!isset($item['filepath'])) {
@@ -642,7 +702,7 @@ function theme_imagecache_formatter($fie
   if (preg_match('/_linked$/', $formatter)) {
     $formatter = preg_replace('/_linked$/', '', $formatter);
     $image = theme('imagecache', $formatter, $item['filepath'], $item['alt'], $item['title']);
-    $output = l($image, 'node/'. $item['nid'], array(), NULL, NULL, FALSE, TRUE);
+    $output = l($image, 'node/'. $item['nid'], array('absolute' => FALSE, 'html' => TRUE));
   }
   else if (preg_match('/_imagelink$/', $formatter)) {
     $formatter = preg_replace('/_imagelink$/', '', $formatter);
@@ -655,6 +715,10 @@ function theme_imagecache_formatter($fie
 }
 
 function theme_imagecache($namespace, $path, $alt = '', $title = '', $attributes = NULL) {
+  if ($image = image_get_info(imagecache_create_path($namespace, $path))) {
+    $attributes['width'] = $image['width'];
+    $attributes['height'] = $image['height'];
+  }
   $attributes = drupal_attributes($attributes);
   $imagecache_path = imagecache_create_url($namespace, $path);
   return '<img src="'. $imagecache_path .'" alt="'. check_plain($alt) .'" title="'. check_plain($title) .'" '. $attributes .' />';
@@ -663,7 +727,7 @@ function theme_imagecache($namespace, $p
 function theme_imagecache_imagelink($namespace, $path, $alt = '', $title = '', $attributes = NULL) {
   $image = theme('imagecache', $namespace, $path, $alt, $title);
   $original_image_url = file_create_url($path);
-  return l($image, $original_image_url, array(), NULL, NULL, FALSE, TRUE);
+  return l($image, $original_image_url, array('absolute' => FALSE, 'html' => TRUE));
 }
 
 
@@ -672,7 +736,7 @@ function theme_imagecache_imagelink($nam
  */
 function imagecache_resize_image(&$image, $data) {
   if (!imageapi_image_resize($image, $data['width'], $data['height'])) {
-    watchdog('imagecache', t('imagecache_resize_image failed. image: %image, data: %data.', array('%path' => $image, '%data' => print_r($data, TRUE))), WATCHDOG_ERROR);
+    watchdog('imagecache', 'imagecache_resize_image failed. image: %image, data: %data.', array('%path' => $image, '%data' => print_r($data, TRUE)), WATCHDOG_ERROR);
     return FALSE;
   }
   return TRUE;
@@ -682,13 +746,13 @@ function imagecache_resize_form($action)
   $form['width'] = array(
     '#type' => 'textfield',
     '#title' => t('Width'),
-    '#default_value' => $action['width'],
+    '#default_value' => isset($action['width']) ? $action['width'] : '100%',
     '#description' => t('Enter a width in pixels or as a percentage. i.e. 500 or 80%.'),
   );
   $form['height'] = array(
     '#type' => 'textfield',
     '#title' => t('Height'),
-    '#default_value' => $action['height'],
+    '#default_value' => isset($action['height']) ? $action['height'] : '100%',
     '#description' => t('Enter a height in pixels or as a percentage. i.e. 500 or 80%.'),
   );
   return $form;
@@ -704,10 +768,10 @@ function theme_imagecache_resize($elemen
 /**
  *  ImageCache 2.x API
  *
- *  The API for imagecache has changed. There is a compatibility layer for 
+ *  The API for imagecache has changed. There is a compatibility layer for
  *  imagecache 1.x. Please see the imagecache_compat.module
- * 
- *  The 2.x API returns more structured data, has shorter function names, and 
+ *
+ *  The 2.x API returns more structured data, has shorter function names, and
  *  implements more aggressive metadata caching.
  *
  */
@@ -717,7 +781,7 @@ function theme_imagecache_resize($elemen
  *
  * @param reset
  *   if set to true it will clear the preset cache
- * 
+ *
  * @return
  *   array of presets array( $preset_id => array('presetid' => integer, 'presetname' => string))
  */
@@ -741,7 +805,7 @@ function imagecache_presets($reset = FAL
 
   // Grab from cache or build the array.
   if ($cache = cache_get('imagecache:presets', 'cache')) {
-    $presets = unserialize($cache->data);
+    $presets = $cache->data;
   }
   else {
     $result = db_query('SELECT * FROM {imagecache_preset} ORDER BY presetname');
@@ -749,17 +813,21 @@ function imagecache_presets($reset = FAL
       $presets[$preset['presetid']] = $preset;
       $presets[$preset['presetid']]['actions'] = imagecache_preset_actions($preset);
     }
-    cache_set('imagecache:presets', 'cache', serialize($presets));
+    cache_set('imagecache:presets', $presets);
   }
   return $presets;
 }
 
+function imagecache_preset_load($preset_id) {
+  return imagecache_preset($preset_id, TRUE);
+}
+
 /**
  * Load a preset by preset_id.
  *
  * @param preset_id
  *   The numeric id of a preset.
- * 
+ *
  * @return
  *   preset array( 'presetname' => string, 'presetid' => integet)
  *   empty array if preset_id is an invalid preset
@@ -778,7 +846,7 @@ function imagecache_preset($preset_id, $
  *   preset array( 'presetname' => string, 'presetid' => integer)
  *   empty array if preset_name is an invalid preset
  */
- 
+
 function imagecache_preset_by_name($preset_name) {
   static $presets_by_name = array();
   if (!$presets_by_name &&  $presets = imagecache_presets()) {
@@ -786,7 +854,7 @@ function imagecache_preset_by_name($pres
       $presets_by_name[$preset['presetname']] = $preset;
     }
   }
-  return (isset($presets_by_name[$preset_name])) ? $presets_by_name[$preset_name] : array(); 
+  return (isset($presets_by_name[$preset_name])) ? $presets_by_name[$preset_name] : array();
 }
 
 /**
@@ -800,11 +868,10 @@ function imagecache_preset_by_name($pres
 function imagecache_preset_save($preset) {
   // @todo: CRUD level validation?
   if (isset($preset['presetid']) && is_numeric($preset['presetid'])) {
-    db_query('UPDATE {imagecache_preset} SET presetname =\'%s\' WHERE presetid = %d', $preset['presetname'], $preset['presetid']);
+    drupal_write_record('imagecache_preset', $preset, 'presetid');
   }
   else {
-    $preset['presetid'] = db_next_id('{imagecache_preset}_presetid');
-    db_query('INSERT INTO {imagecache_preset} (presetid, presetname) VALUES (%d, \'%s\')', $preset['presetid'], $preset['presetname']);
+    drupal_write_record('imagecache_preset', $preset);
   }
 
   // Reset presets cache.
@@ -829,7 +896,7 @@ function imagecache_preset_actions($pres
     while ($row = db_fetch_array($result)) {
       $row['data'] = unserialize($row['data']);
       $actions_cache[$preset['presetid']][] = $row;
-    } 
+    }
   }
 
   return isset($actions_cache[$preset['presetid']]) ? $actions_cache[$preset['presetid']] : array();
@@ -875,22 +942,25 @@ function imagecache_action($actionid) {
       $action = array_merge($definition, $action);
       $actions[$actionid] = $action;
     }
-  }  
+  }
   return $actions[$actionid];
 }
 
+function imagecache_action_load($actionid) {
+  return imagecache_action($actionid, TRUE);
+}
+
 function imagecache_action_save($action) {
-  if ($action['actionid']) {
-    db_query("UPDATE {imagecache_action} SET weight=%d, data='%s' WHERE actionid=%d", $action['weight'], serialize($action['data']), $action['actionid']);
+  if (!empty($action['actionid'])) {
+    drupal_write_record('imagecache_action', $action, 'actionid');
   }
   else {
-    $action['actionid'] = db_next_id('{imagecache_action}_actionid');
-    db_query("INSERT INTO {imagecache_action} (actionid, presetid, weight, action, data) VALUES (%d, %d, %d,'%s', '%s')", $action['actionid'], $action['presetid'], $action['weight'], $action['action'], serialize($action['data']));
+    drupal_write_record('imagecache_action', $action);
   }
   $preset = imagecache_preset($action['presetid']);
   imagecache_preset_flush($preset);
   imagecache_presets(TRUE);
-  return $action; 
+  return $action;
 }
 
 function imagecache_action_delete($action) {
@@ -899,5 +969,3 @@ function imagecache_action_delete($actio
   imagecache_preset_flush($preset);
   imagecache_presets(TRUE);
 }
-
-
Index: imagecache_actions.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/imagecache/imagecache_actions.inc,v
retrieving revision 1.8
diff -u -p -r1.8 imagecache_actions.inc
--- imagecache_actions.inc	28 Dec 2007 18:26:38 -0000	1.8
+++ imagecache_actions.inc	13 Apr 2008 22:33:04 -0000
@@ -2,7 +2,7 @@
 // $Id: imagecache_actions.inc,v 1.8 2007/12/28 18:26:38 dopry Exp $
 
 /**
- * Imagecache Scale 
+ * Imagecache Scale
  */
 function imagecache_scale_form($data) {
   $form = imagecache_resize_form($data);
@@ -16,7 +16,7 @@ function imagecache_scale_form($data) {
 }
 
 function theme_imagecache_scale($element) {
-  $output = theme_imagecache_resize($element) .  ', upscale: '. 
+  $output = theme_imagecache_resize($element) .  ', upscale: '.
   $output .= ($element['#value']['upscale']) ? t('Yes') : t('No');
   return $output;
 }
@@ -117,9 +117,15 @@ function imagecache_deprecated_scale_ima
 
 
 /**
- * Imagecache Crop 
+ * Imagecache Crop
  */
 function imagecache_crop_form($data) {
+  $data += array(
+    'width' => '',
+    'height' => '',
+    'xoffset' => '',
+    'yoffset' => '',
+  );
   $form['width'] = array(
     '#type' => 'textfield',
     '#title' => t('Width'),
@@ -180,3 +186,58 @@ function imagecache_desaturate_image(&$i
   }
   return TRUE;
 }
+
+
+
+/**
+ * Imagecache Rotate
+ */
+function imagecache_rotate_form($data) {
+  $form['degrees'] = array(
+    '#type' => 'textfield',
+    '#default_value' => (isset($data['degrees'])) ? $data['degrees'] : 0,
+    '#title' => t('Rotation angle'),
+    '#description' => t('The number of degrees the image should be rotated. Positive numbers are clockwise, negative are counter-clockwise.'),
+  );
+  $form['random'] = array(
+    '#type' => 'checkbox',
+    '#default_value' => (isset($data['random'])) ? $data['random'] : 0,
+    '#title' => t('Randomize'),
+    '#description' => t('Randomize the rotation angle for each image. The angle specified above is used as a maximum.'),
+  );
+  $form['bgcolor'] = array(
+    '#type' => 'textfield',
+    '#default_value' => (isset($data['bgcolor'])) ? $data['bgcolor'] : '#FFFFFF',
+    '#title' => t('Background color'),
+    '#description' => t('The background color to use for exposed areas of the image. Use web-style hex colors (#FFFFFF for white, #000000 for black).'),
+  );
+  return $form;
+}
+
+function theme_imagecache_rotate($element) {
+  $output = t('degrees: ') . $element['#value']['degrees'] . ', ';
+  $output .= t('randomize: ') . (($element['#value']['random']) ? t('Yes') : t('No')) . ', ';
+  $output .= t('background: ') . $element['#value']['bgcolor'];
+  return $output;
+}
+
+function imagecache_rotate_image(&$image, $data) {
+  // Set sane default values.
+  $data['degrees'] = $data['degrees'] ? $data['degrees'] : 0;
+  $data['random'] = $data['random'] ? $data['random'] : FALSE;
+  $data['bgcolor'] = $data['bgcolor'] ? $data['bgcolor'] : '#FFFFFF';
+
+  // Manipulate the if we need to randomize, and convert to proper colors.
+  $data['bgcolor'] = '0x'. str_replace('#', '', $data['bgcolor']);
+
+  if (!empty($data['random'])) {
+	$degrees = abs((float)$data['degrees']);
+	$data['degrees'] = rand(-1 * $degrees, $degrees);
+  }
+
+  if (!imageapi_image_rotate($image, $data['degrees'], $data['bgcolor'])) {
+    watchdog('imagecache', t('imagecache_rotate_image failed. image: %image, data: %data.', array('%path' => $image, '%data' => print_r($data, TRUE))), WATCHDOG_ERROR);
+    return FALSE;
+  }
+  return TRUE;
+}
Index: imagecache_ui.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/imagecache/imagecache_ui.info,v
retrieving revision 1.2
diff -u -p -r1.2 imagecache_ui.info
--- imagecache_ui.info	14 Dec 2007 13:28:57 -0000	1.2
+++ imagecache_ui.info	13 Apr 2008 22:33:04 -0000
@@ -1,7 +1,7 @@
 ; $Id: imagecache_ui.info,v 1.2 2007/12/14 13:28:57 dopry Exp $
 name = Imagecache UI
 description = ImageCache User Interface.
-dependencies = imagecache imageapi
+dependencies[] = imagecache
+dependencies[] = imageapi
 package = ImageCache
-version = VERSION
-
+core = 6.x
Index: imagecache_ui.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/imagecache/imagecache_ui.module,v
retrieving revision 1.8
diff -u -p -r1.8 imagecache_ui.module
--- imagecache_ui.module	17 Dec 2007 20:38:42 -0000	1.8
+++ imagecache_ui.module	13 Apr 2008 22:33:04 -0000
@@ -6,111 +6,120 @@
  *
  */
 
-function imagecache_ui_help($section) {
-  switch($section) {
+function imagecache_ui_help($path, $arg) {
+  switch($path) {
     case 'admin/build/imagecache': return t('Manage imagecache preset.');
   }
 }
 
-function imagecache_ui_menu($may_cache) {
+function imagecache_ui_menu() {
   $items = array();
-  if ($may_cache) {
-    $items[] = array( 
-      'path' => 'admin/build/imagecache',
-      'title' => t('Imagecache Presets'),
-      'description' => t('Administer imagecache presets and actions.'),
-      'callback' => 'imagecache_ui_presets',
-      'access' => user_access('administer imagecache'),
-               
-    );
-    $items[] = array( 
-      'path' => 'admin/build/imagecache/list',
-      'title' => t('List'),
-      'type' => MENU_DEFAULT_LOCAL_TASK,
-      'weight' => -10,
-    );
-    $items[] = array( 
-      'path' => 'admin/build/imagecache/add',
-      'title' => t('Add New Preset'),
-      'callback' => 'drupal_get_form',
-      'callback arguments' => array('imagecache_ui_preset_add_form'),
-      'access' => user_access('administer imagecache'),
-      'type' => MENU_LOCAL_TASK,
-    );
-  }
-  // Use Dynamic menu items to get better breadcrumb trails by default.
-  elseif (arg(0) == 'admin' && arg(1) == 'build' && arg(2) == 'imagecache' && arg(3) == 'preset') {
-    $preset = imagecache_preset(arg(4));
-    if (empty($preset)) {
-      return $items;
-    }
-    $t = array('!presetname' => $preset['presetname']);
-    $items[] = array(
-      'path' => 'admin/build/imagecache/preset/'. arg(4) .'/delete',
-      'title' =>  t('Delete Preset: !presetname', $t),
-      'callback' => 'drupal_get_form',
-      'callback arguments' => array('imagecache_ui_preset_delete_form', arg(4)),
-      'type' => MENU_CALLBACK,
-    );
-    $items[] = array(
-      'path' => 'admin/build/imagecache/preset/'. arg(4) .'/flush',
-      'title' =>  t('Flush Preset: !presetname', $t),
-      'callback' => 'drupal_get_form',
-      'callback arguments' => array('imagecache_ui_preset_flush_form', arg(4)),
-      'access' => user_access('flush imagecache'),
-      'type' => MENU_CALLBACK,
-    );
-    $items[] = array(
-      'path' => 'admin/build/imagecache/preset/'. arg(4),
-      'title' =>  t('!presetname', $t),
-      'callback' => 'drupal_get_form',
-      'callback arguments' => array('imagecache_ui_preset_form', arg(4)),
-      'type' => MENU_CALLBACK,
-    );
-/*
-    $items[] = array(
-      'path' => 'admin/build/imagecache/preset/'. arg(4) .'/action/add',
-      'title' =>  t('Add !action to !presetname', $t),
-      'callback' => 'imagecache_ui_action_add_list',
-      'callback arguments' => array(arg(4)),
-      'type' => MENU_CALLBACK,
-    );
-*/
-    $definition = imagecache_action_definition(arg(7));
-    if (!empty($definition)) {
-      $t['!action'] = $definition['name'];
-      $items[] = array(
-        'path' => 'admin/build/imagecache/preset/'. arg(4) .'/action/add/'. arg(7),
-        'title' =>  t('Add !action to !presetname', $t),
-        'callback' => 'drupal_get_form',
-        'callback arguments' => array('imagecache_ui_action_add_form', arg(4), arg(7)),
-        'type' => MENU_CALLBACK,
-      );
-    }
- 
-    $action = imagecache_action(arg(6));
-    if ($action) {
-      $t['!action'] = $action['name'];
-      $items[] = array(
-        'path' => 'admin/build/imagecache/preset/'. arg(4) .'/action/'. arg(6),
-        'title' =>  t('!action for preset !presetname', $t),
-        'callback' => 'drupal_get_form',
-        'callback arguments' => array('imagecache_ui_action_form', arg(6)),
-        'type' => MENU_CALLBACK,
-      );
-    
-      $items[] = array(
-        'path' => 'admin/build/imagecache/preset/'. arg(4) .'/action/'. arg(6) .'/delete',
-        'title' =>  t('Delete !action for preset !presetname', $t),
-        'callback' => 'drupal_get_form',
-        'callback arguments' => array('imagecache_ui_action_delete_form', arg(4), arg(6)),
-        'type' => MENU_CALLBACK,
-      );
-    }
-  }    
+  $items['admin/build/imagecache'] = array(
+    'title' => 'Imagecache presets',
+    'description' => 'Administer imagecache presets and actions.',
+    'page callback' => 'imagecache_ui_presets',
+    'access arguments' => array('administer imagecache'),
+  );
+  $items['admin/build/imagecache/list'] = array(
+    'title' => 'List',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -10,
+  );
+
+  $items['admin/build/imagecache/add'] = array(
+    'title' => 'Add new preset',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('imagecache_ui_preset_add_form'),
+    'access arguments' => array('administer imagecache'),
+    'type' => MENU_LOCAL_TASK,
+  );
+
+  $items['admin/build/imagecache/preset/%imagecache_preset'] = array(
+    'title callback' => 'imagecache_preset_title_callback',
+    'title arguments' => array('Edit preset: !presetname', 4),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('imagecache_ui_preset_form', 4),
+    'access arguments' => array('administer imagecache'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['admin/build/imagecache/preset/%imagecache_preset/delete'] = array(
+    'title callback' => 'imagecache_preset_title_callback',
+    'title arguments' => array('Delete preset: !presetname', 4),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('imagecache_ui_preset_delete_form', 4),
+    'access arguments' => array('administer imagecache'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['admin/build/imagecache/preset/%imagecache_preset/flush'] = array(
+    'title callback' => 'imagecache_preset_title_callback',
+    'title arguments' => array('Flush preset: !presetname', 4),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('imagecache_ui_preset_flush_form', 4),
+    'access arguments' => array('flush imagecache'),
+    'type' => MENU_CALLBACK,
+  );
+
+  $items['admin/build/imagecache/preset/%imagecache_preset/action-add/%'] = array(
+    'title callback' => 'imagecache_preset_title_callback',
+    'title arguments' => array('Add !actionname to !presetname', 4, 6),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('imagecache_ui_action_add_form', 4, 6),
+    'access arguments' => array('administer imagecache'),
+    'type' => MENU_CALLBACK,
+  );
+
+  $items['admin/build/imagecache/preset/%imagecache_preset/action/%imagecache_action'] = array(
+    'title callback' => 'imagecache_preset_title_callback',
+    'title arguments' => array('!action for preset !presetname', 4, 6),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('imagecache_ui_action_form', 4, 6),
+    'access arguments' => array('administer imagecache'),
+    'type' => MENU_CALLBACK,
+  );
+
+  $items['admin/build/imagecache/preset/%imagecache_preset/action-delete/%imagecache_action'] = array(
+    'title callback' => 'imagecache_preset_title_callback',
+    'title arguments' => array('Delete !action for preset !presetname', 4, 6),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('imagecache_ui_action_delete_form', 4, 6),
+    'access arguments' => array('administer imagecache'),
+    'type' => MENU_CALLBACK,
+  );
+
   return $items;
 }
 
+function imagecache_preset_title_callback($title, $preset = array(), $action = array()) {
+  $replacements = array();
+  if (!empty($preset)) {
+    $replacements['!presetname'] = $preset['presetname'];
+    $replacements['!presetid'] = $preset['presetid'];
+  }
+  if (!empty($action) && !is_array($action)) {
+    $replacements['!actionname'] = $action;
+  }
+  elseif (!empty($action)) {
+    $replacements['!action'] = $action['action'];
+  }
+  return t($title, $replacements);
+}
+
+/**
+ * Implementation of hook_theme().
+ */
+function imagecache_ui_theme() {
+  return array(
+    'imagecache_admin_title' => array(
+      'arguments' => array(
+        'element' => NULL,
+    )),
+    'imagecache_ui_preset_actions' => array(
+      'arguments' => array(
+        'form' => NULL,
+    )),
+  );
+}
+
 /**
  * Preset Admin callbacks and required functions.
  */
@@ -119,7 +128,7 @@ function imagecache_ui_presets() {
   $header = array(t('Preset Name'), t('Actions'));
   $rows = array();
   foreach(imagecache_presets() as $preset) {
-    $row = array(); 
+    $row = array();
     $row[] = l($preset['presetname'], 'admin/build/imagecache/preset/'. $preset['presetid']);
     $links = array();
     $links[] = l(t('edit'), 'admin/build/imagecache/preset/'. $preset['presetid']);
@@ -129,10 +138,11 @@ function imagecache_ui_presets() {
     $rows[] = $row;
   }
   $output = theme('table', $header, $rows);
+
   return $output;
 }
 
-function imagecache_ui_preset_add_form($presetid = 0) {
+function imagecache_ui_preset_add_form($form_state) {
   $form = array();
   $form['presetname'] = array(
     '#type' => 'textfield',
@@ -149,11 +159,11 @@ function imagecache_ui_preset_add_form($
   return $form;
 }
 
-function  imagecache_ui_preset_add_form_submit($id, $form_values) {
-  $preset = array('presetname' => $form_values['presetname']);
+function  imagecache_ui_preset_add_form_submit($form, &$form_state) {
+  $preset = array('presetname' => $form_state['values']['presetname']);
   $preset = imagecache_preset_save($preset);
   drupal_set_message(t('Preset "%name" (ID: @id) Created.', array('%name' => $preset['presetname'], '@id' => $preset['presetid'])));
-  return 'admin/build/imagecache/preset/'. $preset['presetid'];
+  $form_state['redirect'] = 'admin/build/imagecache/preset/'. $preset['presetid'];
 }
 
 function imagecache_element_presetname_validate($element) {
@@ -169,10 +179,8 @@ function imagecache_element_presetname_v
   }
 }
 
-function imagecache_ui_preset_delete_form($presetid) {
-  $preset = imagecache_preset($presetid);
-
-  if (!$preset) {
+function imagecache_ui_preset_delete_form($form_state, $preset = array()) {
+  if (empty($preset)) {
     drupal_set_message(t('The specified preset was not found'), 'error');
     drupal_goto('admin/build/imagecache');
   }
@@ -181,58 +189,54 @@ function imagecache_ui_preset_delete_for
   $form['presetid'] = array('#type' => 'value', '#value' => $preset['presetid']);
   return confirm_form(
     $form,
-    t('Are you sure you want to delete the preset %preset?', 
+    t('Are you sure you want to delete the preset %preset?',
       array('%preset' => $preset['presetname'])
     ),
-    'admin/build/imagecache', 
+    'admin/build/imagecache',
     t('This action cannot be undone.'),
-    t('Delete'),  t('Cancel')  
+    t('Delete'),  t('Cancel')
   );
 }
 
-function imagecache_ui_preset_delete_form_submit($form_id, $form_values) {
-  $preset = imagecache_preset($form_values['presetid']);
-  imagecache_preset_delete($preset);  
+function imagecache_ui_preset_delete_form_submit($form, &$form_state) {
+  $preset = imagecache_preset($form_state['values']['presetid']);
+  imagecache_preset_delete($preset);
   drupal_set_message(t('Preset "%name" (ID: @id) deleted.', array('%name' => $preset['presetname'], '@id' => $preset['presetid'])));
-  return 'admin/build/imagecache';
+  $form_state['redirect'] = 'admin/build/imagecache';
 }
 
-function imagecache_ui_preset_flush_form($presetid) {
-  $preset = imagecache_preset($presetid);
-
-  if (!$preset) {
+function imagecache_ui_preset_flush_form(&$form_state, $preset = array()) {
+  if (empty($preset)) {
     drupal_set_message(t('The specified preset was not found'), 'error');
-    drupal_goto('admin/build/imagecache');
+    $form_state['redirect'] = 'admin/build/imagecache';
   }
 
   $form = array();
   $form['presetid'] = array('#type' => 'value', '#value' => $preset['presetid']);
   return confirm_form(
     $form,
-    t('Are you sure you want to flush the preset %preset?', 
+    t('Are you sure you want to flush the preset %preset?',
       array('%preset' => $preset['presetname'])
     ),
-    'admin/build/imagecache', 
+    'admin/build/imagecache',
     t('This action cannot be undone.'),
-    t('Flush'),  t('Cancel')  
+    t('Flush'),  t('Cancel')
   );
 }
 
-function imagecache_ui_preset_flush_form_submit($form_id, $form_values) {
-  $preset = imagecache_preset($form_values['presetid']);
-  imagecache_preset_flush($preset);  
+function imagecache_ui_preset_flush_form_submit($form, &$form_state) {
+  $preset = imagecache_preset($form_state['values']['presetid']);
+  imagecache_preset_flush($preset);
   drupal_set_message(t('Preset "%name" (ID: @id) flushed.', array('%name' => $preset['presetname'], '@id' => $preset['presetid'])));
-  return 'admin/build/imagecache';
+  $form_state['redirect'] = 'admin/build/imagecache';
 }
 
 
 
 
 
-function imagecache_ui_preset_form($presetid) {
-  $preset = imagecache_preset($presetid, TRUE);
-
-  if (!$preset) {
+function imagecache_ui_preset_form($form_state, $preset = array()) {
+  if (empty($preset)) {
     drupal_set_message(t('The specified preset was not found'), 'error');
     drupal_goto('admin/build/imagecache');
   }
@@ -258,7 +262,6 @@ function imagecache_ui_preset_form($pres
     '#theme' => 'imagecache_ui_preset_actions',
   );
 
-
   foreach($preset['actions'] as $i => $action) {
     // skip unknown actions...
     if(!$definition = imagecache_action_definition($action['action'])) {
@@ -298,11 +301,11 @@ function imagecache_ui_preset_form($pres
       '#value' => l(t('Configure'), 'admin/build/imagecache/preset/'. $action['presetid'] .'/action/'. $action['actionid'] ),
     );
     $action_form['remove'] = array(
-      '#value' => l(t('Delete'), 'admin/build/imagecache/preset/'. $action['presetid'] .'/action/'. $action['actionid'] .'/delete'),
+      '#value' => l(t('Delete'), 'admin/build/imagecache/preset/'. $action['presetid'] .'/action-delete/'. $action['actionid']),
     );
-    $form['actions'][$i] = $action_form; 
-  }  
- 
+    $form['actions'][$i] = $action_form;
+  }
+
   $form['actions']['new'] = array(
     '#tree' => FALSE,
     '#type' => 'fieldset',
@@ -310,15 +313,15 @@ function imagecache_ui_preset_form($pres
     '#collapsible' => TRUE,
     '#collapsed' => TRUE,
   );
-  
-   
+
+
   foreach(imagecache_action_definitions() as $action => $definition) {
     $form['actions']['new'][] = array(
       '#type' => 'markup',
       '#prefix' => '<div>',
       '#suffix' => '</div>',
-      '#value' => l(t('Add !action', array('!action' => $definition['name'])), 
-                    'admin/build/imagecache/preset/'.  $preset['presetid'] .'/action/add/'. $action) .
+      '#value' => l(t('Add !action', array('!action' => $definition['name'])),
+                    'admin/build/imagecache/preset/'.  $preset['presetid'] .'/action-add/'. $action) .
                     ' - '. $definition['description'],
     );
   }
@@ -326,7 +329,7 @@ function imagecache_ui_preset_form($pres
 /**
  @todo: 404/403 image per preset.
  @todo: global 404/403 image.
-    
+
   $form['files'] = array(
     '#type' => 'fieldset',
     '#collapsible' => TRUE,
@@ -339,13 +342,13 @@ function imagecache_ui_preset_form($pres
     '#title' => t('403 Image'),
     '#description' => t('Image that will be used when access is denied to the source image.'),
   );
-  
+
   $path403 = imagecache/'. $preset['presetname'] .'/403.png';
   if (file_exists($path403)) {
     $url403 =  imagecache_create_url($preset['presetname'], $path403);
 
     $form['files']['403']['view'] = array(
-      '#value' => '<img src="'. $url403 .'">', 
+      '#value' => '<img src="'. $url403 .'">',
     );
   }
 
@@ -368,46 +371,54 @@ function theme_imagecache_admin_title($e
   return '<h2>'.$element['value'].'</h2>';
 }
 
-function theme_imagecache_ui_preset_actions($element) {
+function theme_imagecache_ui_preset_actions($form) {
   $header = array(t('Action'), t('Settings'), t('Weight'), '','');
   $rows = array();
-  foreach(element_children($element) as $key) {
+  foreach(element_children($form) as $key) {
+    if (!is_numeric($key)) {
+      continue;
+    }
     $row = array();
-    $row[] = drupal_render($element[$key]['name']);
-    $row[] = drupal_render($element[$key]['settings']);
-    $row[] = drupal_render($element[$key]['weight']);
-    $row[] = drupal_render($element[$key]['configure']);
-    $row[] = drupal_render($element[$key]['remove']);
-    $rows[] = $row; 
+    $form[$key]['weight']['#attributes']['class'] = 'imagecache-action-order-weight';
+    $row[] = drupal_render($form[$key]['name']);
+    $row[] = drupal_render($form[$key]['settings']);
+    $row[] = drupal_render($form[$key]['weight']);
+    $row[] = drupal_render($form[$key]['configure']);
+    $row[] = drupal_render($form[$key]['remove']);
+    $rows[] = array(
+      'data' => $row,
+      'class' => 'draggable',
+    );
   }
-  $output .= theme('table', $header, $rows); 
-  $output .= drupal_render($element);
+  $output = theme('table', $header, $rows, array('id' => 'imagecache-preset-actions'));
+  drupal_add_tabledrag('imagecache-preset-actions', 'order', 'sibling', 'imagecache-action-order-weight');
+  $output .= drupal_render($form);
   return $output;
 }
 
-function imagecache_ui_preset_form_submit($form_id, $form_values) {
-  if (isset($form_values['actions'])) {
-    foreach($form_values['actions'] as $action) {
+function imagecache_ui_preset_form_submit($form, &$form_state) {
+  if (isset($form_state['values']['actions'])) {
+    foreach($form_state['values']['actions'] as $action) {
       imagecache_action_save($action);
     }
   }
-  imagecache_preset_save($form_values);
-  return 'admin/build/imagecache/preset/'. $form_values['presetid'];
+  imagecache_preset_save($form_state['values']);
+  $form_state['redirect'] = 'admin/build/imagecache/preset/'. $form_state['values']['presetid'];
 }
 
-function imagecache_ui_action_form($actionid) {
+function imagecache_ui_action_form($form_state, $preset, $action) {
   $definitions = imagecache_action_definitions();
-  
-  if (!$action = imagecache_action($actionid)) {
+
+  if (empty($action)) {
     drupal_set_message('Unknown Action.'. $actionid, 'error');
     drupal_goto('admin/build/imagecache');
-  } 
+  }
 
-  if (!$preset = imagecache_preset($action['presetid'])) {
+  if (empty($preset)) {
     drupal_set_message('Unknown Preset.');
     drupal_goto('admin/build/imagecache');
   }
-  
+
   $form = array(
     '#tree' => TRUE,
   );
@@ -418,7 +429,7 @@ function imagecache_ui_action_form($acti
   );
 
 
-  if ($definitions[$action['action']]['file']) {
+  if (!empty($definitions[$action['action']]['file'])) {
     require_once($definitions[$action['action']]['file']);
   }
   $form['data'] = call_user_func($action['action'] .'_form', $action['data']);
@@ -426,26 +437,28 @@ function imagecache_ui_action_form($acti
     '#type' => 'submit',
     '#value' => t('Update Action'),
   );
-  return $form;  
+  return $form;
 }
 
-function imagecache_ui_action_form_submit($form_id, $form_values) {
-  if ($action = imagecache_action($form_values['actionid'])) {
-    $action = array_merge($action, $form_values);
+function imagecache_ui_action_form_submit($form, &$form_state) {
+  if ($action = imagecache_action($form_state['values']['actionid'])) {
+    $action = array_merge($action, $form_state['values']);
     imagecache_action_save($action);
     drupal_set_message('Action Updated');
-    return 'admin/build/imagecache/preset/'. $action['presetid'];
+    $form_state['redirect'] = 'admin/build/imagecache/preset/'. $action['presetid'];
+  }
+  else {
+    drupal_set_message('Unknown Action: '. $form_state['values']['actionid']);
+    $form_state['redirect'] = 'admin/build/imagecache';
   }
-  drupal_set_message('Unknown Action: '. $form_values['actionid']);
-  return 'admin/build/imagecache';
 }
 
-function imagecache_ui_action_delete_form($presetid, $actionid) {
-  if (!$action = imagecache_action($actionid)) {
+function imagecache_ui_action_delete_form($form_state, $preset = array(), $action = array()) {
+  if (empty($action)) {
     drupal_set_message('Unknown Action.'. $actionid, 'error');
     drupal_goto('admin/build/imagecache');
-  } 
-  if (!$preset = imagecache_preset($action['presetid'])) {
+  }
+  if (empty($preset)) {
     drupal_set_message('Unknown Preset.');
     drupal_goto('admin/build/imagecache');
   }
@@ -454,26 +467,26 @@ function imagecache_ui_action_delete_for
   $form['actionid'] = array('#type' => 'value', '#value' => $action['actionid']);
   return confirm_form(
     $form,
-    t('Are you sure you want to delete the !action action from preset !preset?', 
+    t('Are you sure you want to delete the !action action from preset !preset?',
       array('!preset' => $preset['presetname'], '!action' => $action['name'])
     ),
-    'admin/build/imagecache', 
+    'admin/build/imagecache',
     t('This action cannot be undone.'),
-    t('Delete'),  t('Cancel')  
+    t('Delete'),  t('Cancel')
   );
 }
 
 
-function imagecache_ui_action_delete_form_submit($form_id, $form_values) {
-  $action = imagecache_action($form_values['actionid']);
+function imagecache_ui_action_delete_form_submit($form, &$form_state) {
+  $action = imagecache_action($form_state['values']['actionid']);
   imagecache_action_delete($action);
   drupal_set_message(t('The action has been deleted.'));
-  return 'admin/build/imagecache/preset/'. $action['presetid'];
+  $form_state['redirect'] = 'admin/build/imagecache/preset/'. $action['presetid'];
 }
 
-function imagecache_ui_action_add_form($presetid, $actionname) {
+function imagecache_ui_action_add_form($form_state, $preset, $actionname) {
   $definition = imagecache_action_definition($actionname);
-  
+
   $form = array(
     '#tree' => TRUE,
   );
@@ -483,23 +496,23 @@ function imagecache_ui_action_add_form($
   );
   $form['presetid'] = array(
     '#type' => 'value',
-    '#value' => $presetid,
+    '#value' => $preset['presetid'],
   );
   $form['weight'] = array(
     '#type' => 'weight',
     '#title' => t('Weight'),
-  );  
+  );
 
-  $form['data'] = call_user_func($actionname .'_form', $action['data']);
+  $form['data'] = call_user_func($actionname .'_form', array());
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Add Action'),
   );
-  return $form;  
+  return $form;
 }
 
 
-function imagecache_ui_action_add_form_submit($form_id, $form_values) {
-  imagecache_action_save($form_values);
-  return 'admin/build/imagecache/preset/'. $form_values['presetid'];
+function imagecache_ui_action_add_form_submit($form, &$form_state) {
+  imagecache_action_save($form_state['values']);
+  $form_state['redirect'] = 'admin/build/imagecache/preset/'. $form_state['values']['presetid'];
 }
