Index: skinr.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr.info,v
retrieving revision 1.1.4.2
diff -u -p -r1.1.4.2 skinr.info
--- skinr.info	26 Jan 2010 08:20:33 -0000	1.1.4.2
+++ skinr.info	17 Mar 2010 08:45:10 -0000
@@ -4,3 +4,4 @@ name = Skinr
 description = Provides a way to define and/or skin bits of Drupal output from the UI.
 package = Skinr
 core = 6.x
+dependencies[] = ctools
Index: skinr.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr.install,v
retrieving revision 1.3.2.2.2.3
diff -u -p -r1.3.2.2.2.3 skinr.install
--- skinr.install	17 Feb 2010 18:21:05 -0000	1.3.2.2.2.3
+++ skinr.install	17 Mar 2010 08:45:10 -0000
@@ -12,7 +12,25 @@
 function skinr_schema() {
   $schema['skinr'] = array(
     'description' => 'Stores skinr data.',
+    'export' => array(
+      'key' => 'name',
+      'identifier' => 'skinr',
+      'default hook' => 'skinr_default_skins',
+      'api' => array(
+        'owner' => 'skinr',
+        'api' => 'skinr_skins',
+        'minimum_version' => 1,
+        'current_version' => 1,
+      ),
+    ),
     'fields' => array(
+      'name' => array(
+        'description' => 'Unique identifier string',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
       'theme' => array(
         'description' => 'The system name of the theme.',
         'type' => 'varchar',
@@ -50,7 +68,7 @@ function skinr_schema() {
         'default' => '',
       ),
     ),
-    'primary key' => array('theme', 'module', 'sid'),
+    'primary key' => array('name'),
     'indexes' => array(
       'theme' => array('theme'),
       'module' => array('module'),
Index: skinr.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr.module,v
retrieving revision 1.13.2.6.2.18
diff -u -p -r1.13.2.6.2.18 skinr.module
--- skinr.module	8 Mar 2010 16:55:52 -0000	1.13.2.6.2.18
+++ skinr.module	17 Mar 2010 08:45:10 -0000
@@ -399,15 +399,17 @@ function skinr_set($skinr) {
     return FALSE;
   }
 
+  $skinr->name = $skinr->theme . ':' . $skinr->module . ':' . $skinr->sid;
   if (empty($skinr->skins) && empty($skinr->settings)) {
     // Delete the db entry if it exists.
-    db_query("DELETE FROM {skinr} WHERE theme = '%s' AND module = '%s' AND sid = '%s'", $skinr->theme, $skinr->module, $skinr->sid);
+    db_query("DELETE FROM {skinr} WHERE name = '%s'", $skinr->name);
   }
   else {
     // Let's save the data.
-    if (skinr_get($skinr->theme, $skinr->module, $skinr->sid) !== FALSE) {
+    $existing = skinr_get($skinr->theme, $skinr->module, $skinr->sid);
+    if (!empty($existing) && $existing->export_type & EXPORT_IN_DATABASE) {
       // Record exists, so let's update.
-      drupal_write_record('skinr', $skinr, array('theme', 'module', 'sid'));
+      drupal_write_record('skinr', $skinr, $name);
     }
     else {
       // Insert a new record.
@@ -427,60 +429,37 @@ function skinr_set($skinr) {
  *   theme if neither $module nor $sid is specified. FALSE on failure.
  */
 function skinr_get($theme = NULL, $module = NULL, $sid = NULL, $reset = FALSE) {
-  static $cache = array();
-
-  if (is_null($theme)) {
-    $theme = skinr_current_theme();
-  }
-
-  if ($reset) {
-    $cache = array();
-  }
-
-  if (!isset($cache[$theme][$module][$sid])) {
-    if (!isset($cache[$theme])) {
-      $cache[$theme] = array();
-    }
-    if (!is_null($module) && !isset($cache[$theme][$module])) {
-      $cache[$theme][$module] = array();
-    }
-
-    if (!is_null($module) && !is_null($sid)) {
-      // Fetch just this sid.
-      $result = db_query("SELECT theme, module, sid, settings, skins FROM {skinr} WHERE theme = '%s' AND module = '%s' AND sid = '%s'", $theme, $module, $sid);
-    }
-    elseif (!is_null($module)) {
-      // Fetch all settings for this theme and module.
-      $result = db_query("SELECT theme, module, sid, settings, skins FROM {skinr} WHERE theme = '%s' AND module = '%s'", $theme, $module);
+  ctools_include('export');
+  // Handle first case when all variables are specified.
+  if (isset($theme) && isset($module) && isset($sid)) {
+    $name = "$theme:$module:$sid";
+    $result = ctools_export_load_object('skinr', 'names', array($name));
+    if (isset($result[$name])) {
+      return $result[$name];
     }
     else {
-      // Fetch all settings for this theme.
-      $result = db_query("SELECT theme, module, sid, settings, skins FROM {skinr} WHERE theme = '%s'", $theme);
-    }
-
-    while ($skinr = db_fetch_object($result)) {
-      $skinr->settings = unserialize($skinr->settings);
-      $skinr->skins = unserialize($skinr->skins);
-      $cache[$skinr->theme][$skinr->module][$skinr->sid] = $skinr;
+      return FALSE;
     }
   }
 
-  if (is_null($sid) && is_null($module)) {
-    // Return all the skinrs for the theme.
-    if (isset($cache[$theme])) {
-      return $cache[$theme];
-    }
+  // Second case where a subset of the variables are given.
+  $conditions = array();
+  if (isset($theme)) {
+    $conditions['theme'] = $theme;
   }
-  elseif(is_null($sid)) {
-    // Return all the skinrs for the module.
-    if (isset($cache[$theme][$module])) {
-      return $cache[$theme][$module];
-    }
+  if (isset($module)) {
+    $conditions['module'] = $module;
   }
-  elseif (isset($cache[$theme][$module][$sid])) {
-    return $cache[$theme][$module][$sid];
+  if (isset($sid)) {
+    $conditions['sid'] = $sid;
   }
-  return FALSE;
+
+  if (!empty($conditions)) {
+    return ctools_export_load_object('skinr', 'conditions', $conditions);
+  }
+
+  // In this final case, return all skinr objects.
+  return ctools_export_load_object('skinr');
 }
 
 /**
Index: skinr_ui.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr_ui.admin.inc,v
retrieving revision 1.1.2.7
diff -u -p -r1.1.2.7 skinr_ui.admin.inc
--- skinr_ui.admin.inc	1 Mar 2010 19:20:40 -0000	1.1.2.7
+++ skinr_ui.admin.inc	17 Mar 2010 08:45:10 -0000
@@ -16,7 +16,7 @@ function skinr_ui_list() {
     array('data' => t('Theme'), 'field' => 'theme'),
     array('data' => t('Type'), 'field' => 'type'),
     array('data' => t('Skinr ID'), 'field' => 'sid'),
-    array('data' => t('Operations'), 'colspan' => 2),
+    array('data' => t('Operations'), 'colspan' => 3),
   );
 
   $ts = tablesort_init($headers);
@@ -49,19 +49,27 @@ function skinr_ui_list() {
       continue;
     }
     $skinrs = skinr_get($theme->name);
-    
-    foreach ($skinrs as $module => $elements) {
-      foreach ($elements as $sid => $skin) {
-        $row = array(
-          $theme->info['name'],
-          $module,
-          $sid,
-          l(t('edit'), 'admin/settings/skinr/edit/nojs/'. $module .'/'. $sid, array('query' => 'destination=admin/settings/skinr')),
-          l(t('delete'), 'admin/settings/skinr/delete/'. $theme->name .'/'. $module .'/'. $sid, array('query' => 'destination=admin/settings/skinr')),
-        );
-        $sorts[] = strip_tags($row[$sortby]);
-        $rows[] = $row;
+    foreach ($skinrs as $name => $skin) {
+      $row = array(
+        $theme->info['name'],
+        $skin->module,
+        $skin->sid,
+        l(t('edit'), 'admin/settings/skinr/edit/nojs/'. $skin->module .'/'. $skin->sid, array('query' => 'destination=admin/settings/skinr')),
+        l(t('export'), 'admin/settings/skinr/export/' . $theme->name .'/'. $skin->module .'/'. $skin->sid, array('query' => 'destination=admin/settings/skinr')),
+      );
+
+      // Is this the database.
+      if ($skin->export_type & EXPORT_IN_DATABASE) {
+        $delete_text = 'delete';
+        // Is this overridden.
+        if ($skin->export_type & EXPORT_IN_CODE) {
+          $delete_text = 'revert';
+        }
+        $row[] = l(t($delete_text), 'admin/settings/skinr/delete/' . $theme->name . '/' . $skin->module . '/' . $skin->sid, array('query' => drupal_get_destination()));
       }
+
+      $sorts[] = strip_tags($row[$sortby]);
+      $rows[] = $row;
     }
   }
   
@@ -117,19 +125,18 @@ function skinr_ui_admin_form_validate(&$
  * Skinr settings export form.
  */
 function skinr_ui_export_form(&$form_state, $theme = NULL) {
+  // @TODO: this doesn't work use CTools bulk export.
   $form = array();
   $themes = list_themes();
 
   if ($theme) {
     // Export an individual theme.
     $theme = str_replace('-', '_', $theme);
-    $skinrs = skinr_get($theme);
+    $skinrs = array();
 
     // Convert classes to arrays.
-    foreach ($skinrs as $module => $data) {
-      foreach ($data as $sid => $skinr) {
-        $skinrs[$module][$sid] = (array) $skinrs[$module][$sid];
-      }
+    foreach (skinr_get($theme) as $name => $skinr) {
+      $skinrs[$skinr->module][$skinr->sid] = (array) $skinr;
     }
 
     $code = '$skinrs = '. var_export($skinrs, TRUE) .';';
@@ -235,11 +242,12 @@ function skinr_ui_import_form(&$form_sta
     '#options' => $options,
     '#required' => TRUE,
   );
-  $form['skinr_settings'] = array(
+  $form['skinr'] = array(
     '#type' => 'textarea',
     '#title' => t('Skinr settings'),
     '#description' => t('Paste skinr settings here.'),
     '#rows' => 16,
+    '#required' => TRUE,
   );
   $form['submit'] = array(
     '#type' => 'submit',
@@ -253,84 +261,71 @@ function skinr_ui_import_form(&$form_sta
  * Validation handler for Skinr settings import form.
  */
 function skinr_ui_import_form_validate(&$form, &$form_state) {
-  if (empty($form_state['values']['skinr_settings'])) {
-    // Error.
-    form_error($form['skinr_settings'], t('These are not valid Skinr settings.'));
-    return;
-  }
-
-  $skinrs = '';
   ob_start();
-  eval($form_state['values']['skinr_settings']);
+  eval($form_state['values']['skinr']);
   ob_end_clean();
-
-  foreach ($skinrs as $module => $ignored) {
-    if (!is_array($skinrs[$module])) {
-      // Error.
-      form_error($form['skinr_settings'], t('These are not valid Skinr settings.'));
+  // The object should appear as $skinr. This was the "identifier" set in the export section of the schema.
+  if (empty($skinr)) {
+    $errors = ob_get_contents();
+    if (empty($errors)) {
+      $errors = t('No skinr found.');
     }
-    foreach ($skinrs[$module] as $sid => $ignored) {
-      if (!is_array($skinrs[$module][$sid])) {
-        // Error.
-        form_error($form['skinr_settings'], t('These are not valid Skinr settings.'));
-      }
 
-      // Cast skinr array to object so we can actually use it.
-      $skinrs[$module][$sid] = (object) $skinrs[$module][$sid];
-      if (!skinr_validate($skinrs[$module][$sid])) {
-        // Error.
-        form_error($form['skinr_settings'], t('These are not valid Skinr settings.'));
-      }
-    }
+    form_error($form['skinr'], t('Unable to get a Skinr from the import. Errors reported: @errors', array('@errors' => $errors)));
   }
 
+
   if (!empty($form_state['values']['theme']) && preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['theme'])) {
     form_error($form['theme'], t('The theme name must be alphanumeric and can contain underscores only.'));
   }
 
-  $form_state['skinrs'] = &$skinrs;
+  $form_state['skinr'] = $skinr;
 }
 
 /**
  * Submit handler for skinr settings import form.
  */
 function skinr_ui_import_form_submit(&$form, &$form_state) {
-  foreach ($form_state['skinrs'] as $module => $skinrs) {
-    foreach ($skinrs as $sid => $skinr) {
-      if (!skinr_set($skinr)) {
-        drupal_set_message(t('Skinr settings for the theme %theme could not be saved!', array('%theme' => $form_state['values']['theme'])), 'error');
-      }
-    }
-  }
+  $skinr = $form_state['skinr'];
+  $skinr->theme = $form_state['values']['theme'];
 
+  skinr_set($skinr);
   drupal_set_message(t('Skinr settings for the theme %theme have been saved.', array('%theme' => $form_state['values']['theme'])));
-  drupal_goto('admin/settings/skinr');
+  $form_state['redirect'] = 'admin/settings/skinr';
 }
 
 /**
  * Menu callback; displays the delete confirmation for a skinr page rule.
  */
 function skinr_ui_delete_confirm(&$form_state, $theme, $module, $sid) {
+  $theme = isset($form_state['theme']) ? $form_state['theme'] : $theme;
+  $module = isset($form_state['module']) ? $form_state['module'] : $module;
+  $sid = isset($form_state['sid']) ? $form_state['sid'] : $sid;
   $form['theme'] = array(
     '#type' => 'value',
-    '#value' => isset($form_state['theme']) ? $form_state['theme'] : $theme,
+    '#value' => $theme,
   );
   $form['module'] = array(
     '#type' => 'value',
-    '#value' => isset($form_state['module']) ? $form_state['module'] : $module,
+    '#value' => $module,
   );
   $form['sid'] = array(
     '#type' => 'value',
-    '#value' => isset($form_state['sid']) ? $form_state['sid'] : $sid,
+    '#value' => $sid,
   );
 
   $themes = list_themes();
 
+  $skin = skinr_get($theme, $module, $sid);
+  $delete_text = 'Delete';
+  if ($skin->export_type & EXPORT_IN_CODE) {
+    $delete_text = 'Revert';
+  }
   return confirm_form($form,
     t('Are you sure you want to delete these Skinr settings?'),
     isset($_GET['destination']) ? $_GET['destination'] : 'admin/settings/skinr',
     t('This action cannot be undone.<br /> Theme: !theme<br />Module: !module<br />Skinr ID: !sid', array('!theme' => $themes[$theme]->info['name'], '!module' => $module, '!sid' => $sid)),
-    t('Delete'),
+    t($delete_text),
     t('Cancel')
   );
 }
@@ -349,3 +344,29 @@ function skinr_ui_delete_confirm_submit(
 
   $form_state['redirect'] = 'admin/settings/skinr';
 }
+
+/**
+ * Menu callback to export an individual skin.
+ *
+ * @param $theme
+ *   Theme id for the skin.
+ * @param $module
+ *   Module that the skin is for.
+ * @param $sid
+ *   Skin id.
+ */
+function skinr_ui_skin_export($theme, $module, $sid) {
+  $skin = skinr_get($theme, $module, $sid);
+  $code = skinr_ui_skin_export_code($skin);
+  return drupal_get_form('ctools_export_form', $code, '');
+}
+
+/**
+* Export a skin.
+*/
+function skinr_ui_skin_export_code($skin, $indent = '') {
+  ctools_include('export');
+  $output = ctools_export_object('skinr', $skin, $indent);
+  return $output;
+}
+
Index: skinr_ui.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/skinr/skinr_ui.module,v
retrieving revision 1.1.2.22
diff -u -p -r1.1.2.22 skinr_ui.module
--- skinr_ui.module	8 Mar 2010 21:11:57 -0000	1.1.2.22
+++ skinr_ui.module	17 Mar 2010 08:45:10 -0000
@@ -60,7 +60,6 @@ function skinr_ui_menu() {
     'file' => 'skinr_ui.rules.inc',
   );
 
-  // Import & Export.
   $items['admin/settings/skinr/import'] = array(
     'title' => 'Import',
     'page callback' => 'drupal_get_form',
@@ -71,16 +70,6 @@ function skinr_ui_menu() {
     'weight' => 2,
     'file' => 'skinr_ui.admin.inc',
   );
-  $items['admin/settings/skinr/export'] = array(
-    'title' => 'Export',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('skinr_ui_export_form'),
-    'type' => MENU_LOCAL_TASK,
-    'access arguments' => array('administer skinr'),
-    'parent' => 'admin/settings/skinr',
-    'weight' => 3,
-    'file' => 'skinr_ui.admin.inc',
-  );
 
   // Settings.
   $items['admin/settings/skinr/settings'] = array(
@@ -115,6 +104,15 @@ function skinr_ui_menu() {
     'file' => 'skinr_ui.admin.inc',
   );
 
+  $items['admin/settings/skinr/export/%/%/%'] = array(
+    'title' => 'Export skin',
+    'page callback' => 'skinr_ui_skin_export',
+    'page arguments' => array(4, 5, 6),
+    'access arguments' => array('administer skinr'),
+    'file' => 'skinr_ui.admin.inc',
+    'type' => MENU_CALLBACK,
+  );
+
   // Fetch skin file info through AJAX.
   $items['admin/settings/skinr/info/%'] = array(
     'title' => 'Skinr file information',
