 block_class.features.inc |  74 ---------------------------------
 block_class.info         |   4 +-
 block_class.install      |  96 +++++++++++++++++++++++++++++-------------
 block_class.module       | 106 ++++++++++++++++-------------------------------
 4 files changed, 104 insertions(+), 176 deletions(-)

diff --git a/block_class.features.inc b/block_class.features.inc
deleted file mode 100644
index 142493b..0000000
--- a/block_class.features.inc
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-
-/**
- * Implements hook_features_export_options().
- */
-function block_class_features_export_options() {
-  $query = db_select('block_class', 'bc');
-  $query->addExpression("CONCAT(bc.module, ':', bc.delta)");
-  $blocks = $query->execute()->fetchAllKeyed(0, 0);
-
-  natcasesort($blocks);
-  return $blocks;
-}
-
-/**
- * Implements hook_features_export().
- */
-function block_class_features_export($data, &$export, $module_name = '') {
-  $pipe = array();
-
-  $export['dependencies']['features'] = 'features';
-  $export['dependencies']['block_class'] = 'block_class';
-
-  foreach ($data as $component) {
-    $export['features']['block_class'][$component] = $component;
-  }
-
-  return $pipe;
-}
-
-/**
- * Implements hook_features_export_render().
- */
-function block_class_features_export_render($module, $data) {
-  $query = db_select('block_class', 'bc');
-  $query->addExpression("CONCAT(bc.module, ':', bc.delta)", 'id');
-  $query->addField('bc', 'css_class');
-  $classes = $query->execute()->fetchAllKeyed(1, 0);
-
-  $code = array();
-  foreach ($data as $id) {
-    if (isset($classes[$id])) {
-      list($module, $delta) = explode(':', $id);
-      $css_classes = $classes[$id];
-      $code[$id] = compact('module', 'delta', 'css_classes');
-    }
-  }
-
-  $code = "  return ". features_var_export($code, '  ') .";";
-
-  return array('block_class_features_default_class' => $code);
-}
-
-/**
- * Implements hook_features_revert().
- */
-function block_class_features_revert($module) {
-  block_class_features_rebuild($module);
-}
-
-/**
- * Implements hook_features_rebuild().
- */
-function block_class_features_rebuild($module) {
-  $blocks = module_invoke($module, 'block_class_features_default_class');
-  if ($blocks) {
-    foreach($blocks as $block) {
-      db_delete('block_class')->condition('module', $block['module'])->condition('delta', $block['delta'])->execute();
-      if (!empty($block['css_classes'])) {
-        $id = db_insert('block_class')->fields(array('module' => $block['module'], 'delta' => $block['delta'], 'css_class' => $block['css_classes']))->execute();
-      }
-    }
-  }
-}
diff --git a/block_class.info b/block_class.info
index 38d5a4d..2f71998 100644
--- a/block_class.info
+++ b/block_class.info
@@ -2,5 +2,5 @@ name = Block Class
 description = Allows assigning CSS classes to blocks.
 core = 7.x
 
-files[] = block_class.install
-files[] = block_class.module
+dependencies[] = block
+
diff --git a/block_class.install b/block_class.install
index 0582d45..43a3987 100644
--- a/block_class.install
+++ b/block_class.install
@@ -6,37 +6,47 @@
  */
 
 /**
- * Implementation of hook_schema().
+ * Implementation of hook_install().
  */
-function block_class_schema() {
-  $schema['block_class'] = array(
-    'fields' => array(
-      'module' => array(
-        'type' => 'varchar',
-        'length' => 64,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'The module to which the block belongs.',
-      ),
-      'delta' => array(
-        'type' => 'varchar',
-        'length' => 32,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => "The ID of the module's block.",
-      ),
-      'css_class' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'String containing the classes for the block.',
-      ),
-    ),
-    'primary key' => array('module', 'delta'),
-  );
+function block_class_install(){
+  $schema['block']=array();
+  block_class_schema_alter($schema);
+  foreach($schema['block']['fields'] as $field => $spec) {
+    if (db_field_exists('block', $field)) {
+      watchdog('system', t('Module install: Attempt to recreate field: "@field", when it already exists.', array('@field' => $field)), NULL, WATCHDOG_WARNING);
+    }
+    else{
+      db_add_field('block', $field, $spec);
+    }
+  }
+}
 
-  return $schema;
+/**
+ * Implementation of hook_uninstall().
+ */
+function block_class_uninstall(){
+  $schema['block']=array();
+  block_class_schema_alter($schema);
+  foreach($schema['block']['fields'] as $field => $specs) {
+    db_drop_field('block', $field);
+  }
+}
+
+/**
+ * Implementation of hook_schema_alter().
+ * Other modules, such as i18n_block also modify the block schema and
+ * database table structure.
+ */
+function block_class_schema_alter(&$schema) {
+  if (isset($schema['block'])) {
+    $schema['block']['fields']['css_class'] = array(
+      'type' => 'varchar',
+      'length' => 255,
+      'not null' => TRUE,
+      'default' => '',
+      'description' => 'String containing the classes for the block.',
+    );
+  }
 }
 
 /**
@@ -105,3 +115,31 @@ function block_class_update_7101() {
   // Create new primary key.
   db_add_primary_key('block_class', array('module', 'delta'));
 }
+
+/**
+ * Migration from previous database structure (block_class table) to new
+ * structure based on altering the core block table.
+ */
+function block_class_update_7103() {
+  if(!db_field_exists('block', 'block_class')) {
+    $schema['block']=array();
+    block_class_schema_alter($schema);
+    foreach($schema['block']['fields'] as $field => $specs) {
+      db_add_field('block', $field, $specs);
+    }
+  }
+
+  if(db_table_exists('block_class')) {
+    // Migrate all existing records from block_class table to block table.
+    $result = db_query('SELECT css_class, module, delta FROM {block_class}');
+    while ($record = $result->fetchObject()) {
+        db_update('block')
+          ->fields(array('css_class' => $record->css_class))
+          ->condition('module', $record->module)
+          ->condition('delta', $record->delta)
+          ->execute();
+    }
+    // Remove the block_class table.
+    db_drop_table('block_class');
+  }
+}
diff --git a/block_class.module b/block_class.module
index 9dc7386..2c2ee4d 100644
--- a/block_class.module
+++ b/block_class.module
@@ -1,5 +1,15 @@
 <?php
 
+ /**
+ * @file
+ * Enhanced control over the CSS Classes of any Block.
+ *
+ * Block Class allows users to add classes to any block through the block's
+ * configuration interface. This implementation is based on an alteration of
+ * the Core block database table to leverage the Core Block API functions,
+ * objects and structure.
+ */
+
 /**
  * Implements hook_permission().
  */
@@ -12,37 +22,20 @@ function block_class_permission() {
   );
 }
 
-/*
+/**
+ * Implements theme_preprocess_block().
  * Extend block's classes with any user defined classes.
  */
 function block_class_preprocess_block(&$vars) {
   $block = $vars['block'];
-
-  /* The original code: */
-  //$classes = block_class($block);
-  //$vars['classes_array'] = array_merge($vars['classes_array'], explode(' ', $classes));
-
-  /* Replaced with the following so it doesn't fire that many queries if you have a lot of blocks */
-  static $_block_class_blocks_classes;
-
-  if (! isset ($_block_class_blocks_classes)) {
-    $_block_class_blocks_classes = array();
-    $result = db_query('SELECT css_class, module, delta FROM {block_class}');
-    while ($record = $result->fetchObject()) {
-      $_block_class_blocks_classes[$record->module][$record->delta] = $record->css_class;
-    }
-  }
-
-  if (isset($_block_class_blocks_classes[$block->module][$block->delta])) {
-    $classes = $_block_class_blocks_classes[$block->module][$block->delta];
-    $vars['classes_array'] = array_merge($vars['classes_array'], explode(' ', $classes));
+  if (isset($block->css_class) && $block->css_class != '') {
+    $vars['classes_array'] = array_merge($vars['classes_array'], explode(' ', $block->css_class));
   }
 }
 
-
-/*
+/**
+ * Implements hook_preprocess_panels_pane().
  * Extend panel block's classes with any user defined classes.
- * Implements hook_preprocess_hook()
  */
 function block_class_preprocess_panels_pane(&$vars) {
   if ($vars['pane']->type != 'block') {
@@ -52,42 +45,28 @@ function block_class_preprocess_panels_pane(&$vars) {
   $block_parts = explode('-', $vars['pane']->subtype);
   // Load the block based on the block parts.
   $block = block_load($block_parts[0], $block_parts[1]);
-  // Return block_class classes as string.
-  $css_class = block_class($block);
   // Add a generic 'module type' pane class.
   $vars['classes_array'][] = drupal_html_class('pane-' . $block->module);
   // Add $css_class to the $classes_array.
-  $vars['classes_array'][] = $css_class;
-}
-
-
-/**
- * Return classes as string
- */
-function block_class($block) {
-  $ret = db_query('SELECT css_class FROM {block_class} WHERE module = :module AND delta = :delta', array(':module' => $block->module, ':delta' => $block->delta))->fetchField();
-  return $ret ? check_plain ($ret) : '';
+  if (isset($block->css_class) && $block->css_class != '') {
+    $vars['classes_array'] = array_merge($vars['classes_array'], explode(' ', $block->css_class));
+  }
 }
 
-
 /**
- * Alter block edit form
+ * Implements hook_form_alter().
+ * Alter block edit form to add configuration field.
  */
 function block_class_form_alter(&$form, &$form_state, $form_id) {
-  if (user_access('administer block classes') && $form_id == 'block_admin_configure' || $form_id == 'block_add_block_form') {
-    $block = new stdClass;
-    $block->module = $form['module']['#value'];
-    $block->delta = $form['delta']['#value'];
-    $css_class = block_class($block);
-
-    // Create a more technical description for users with administer blocks permission.
-    $description = t('Customize the styling of this block by adding CSS classes. Separate multiple classes by spaces.');
+  if (user_access('administer block classes') && ($form_id == 'block_admin_configure' || $form_id == 'block_add_block_form')) {
+    // Load statically cached block object used to display block_admin_configure form.
+    $block = block_load($form['module']['#value'], $form['delta']['#value']);
 
     $form['settings']['css_class'] = array(
       '#type' => 'textfield',
       '#title' => t('CSS class(es)'),
-      '#default_value' => $css_class,
-      '#description' => t('Separate classes with a space.'),
+      '#default_value' => isset($block->css_class) ? $block->css_class : '',
+      '#description' => t('Customize the styling of this block by adding CSS classes. Separate multiple classes by spaces.'),
       '#maxlength' => 255,
     );
 
@@ -95,34 +74,19 @@ function block_class_form_alter(&$form, &$form_state, $form_id) {
   }
 }
 
-
 /**
- * Save supplied class.
+ * Helper function: additional submit callback for block configuration pages.
+ * Save supplied CSS classes.
  */
 function block_class_form_submit($form, &$form_state) {
   if ($form_state['values']['form_id'] == 'block_admin_configure' || $form_state['values']['form_id'] == 'block_add_block_form') {
-    if (isset($form_state['values']['css_class']) && user_access('administer blocks')) {
-      $module = $form_state['values']['module'];
-      $delta = $form_state['values']['delta'];
-      $class = $form_state['values']['css_class'];
-      db_delete('block_class')->condition('module', $module)->condition('delta', $delta)->execute();
-      if (!empty($class)) {
-        $id = db_insert('block_class')->fields(array('module' => $module, 'delta' => $delta, 'css_class' => $class))->execute();
-      }
+    // Only save if value has changed.
+    if (isset($form_state['values']['css_class']) && $form['settings']['css_class']['#default_value'] != $form_state['values']['css_class'] && user_access('administer blocks')) {
+        db_update('block')
+          ->fields(array('css_class' => $form_state['values']['css_class']))
+          ->condition('module', $form_state['values']['module'])
+          ->condition('delta', $form_state['values']['delta'])
+          ->execute();
     }
   }
 }
-
-/**
- * Implements hook_features_api().
- */
-function block_class_features_api() {
-  return array(
-    'block_class' => array(
-      'name' => t('Block class'),
-      'feature_source' => TRUE,
-      'default_hook' => 'block_class_features_default_class',
-      'file' => drupal_get_path('module', 'block_class') . '/block_class.features.inc',
-    ),
-  );
-}
