From 74ef87f9b62af8635e3d4d8386d86a48268be040 Mon Sep 17 00:00:00 2001
From: flow <f.weber@digi-info.de>
Date: Fri, 1 Apr 2011 14:36:18 +0200
Subject: [PATCH] refactor multiselect and provide API for other modules.

---
 multiselect.api.php |   27 +++++++++++++++++
 multiselect.module  |   82 ++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 92 insertions(+), 17 deletions(-)
 create mode 100644 multiselect.api.php

diff --git a/multiselect.api.php b/multiselect.api.php
new file mode 100644
index 0000000..56f1b3b
--- /dev/null
+++ b/multiselect.api.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * Enhance your field type with multiselect support.
+ */
+ 
+/**
+ * Implements hook_field_widget_info_alter()
+ */
+function hook_field_widget_info_alter(&$info) {
+  if (isset($info['multiselect'])) {
+    $info['multiselect']['field types'][] = 'your_field_type';    
+  }
+}
+
+/** 
+ * Implements hook_multiselect_default_values()
+ */
+function hook_multiselect_default_values($items, $field) {
+  $default_value = array();
+  
+  foreach ($items as $item) {
+    $default_value[$item['field_value']] = $item['field_value'];
+  }
+  
+  return $default_value;
+}
\ No newline at end of file
diff --git a/multiselect.module b/multiselect.module
index 0c1c83a..ff4ede8 100644
--- a/multiselect.module
+++ b/multiselect.module
@@ -90,7 +90,7 @@ function multiselect_field_widget_form(&$form, &$form_state, $field, $instance,
   $default_value = _options_storage_to_form($items, $options, $value_key, $properties);
   /* END copy from options.module */
 
-  $widget = _multiselect_build_widget_code($options, $items, $element, $required);
+  $widget = _multiselect_build_widget_code($options, $items, $element, $required, $field);
 
   // Build the basic select box using Form API.
   $element += array(
@@ -155,7 +155,7 @@ function _multiselect_html_for_box_options($options) {
  * @param $element = the form element being created
  * return $widget = an array of html items and values for use in the final presentation of widget.
  */
-function _multiselect_build_widget_code($options, $items, $element, $required = FALSE) {
+function _multiselect_build_widget_code($options, $items, $element, $required = FALSE, $field = array()) {
   // Insert Javascript and CSS for this widget.
   $path = drupal_get_path('module', 'multiselect');
   drupal_add_js($path . '/multiselect.js');
@@ -170,23 +170,13 @@ function _multiselect_build_widget_code($options, $items, $element, $required =
   $unselected_options = array();
   // Add selected items to the array first
   if (is_array($items)) {
-    foreach ($items as $key => $value) {
-      if (is_array($value) && array_key_exists('value', $value)) { // With CCK, it's an array.
-        $selected_options[$value['value']] = $value['value'];
-      }
-      elseif (is_array($value) && array_key_exists('tid', $value)) { // With CCK, it's an array. Taxonomy
-        $selected_options[$value['tid']] = $value['tid'];
-      }
-      elseif (is_array($value) && array_key_exists('nid', $value)) { // With CCK, it's an array. Node ref
-        $selected_options[$value['nid']] = $value['nid'];
-      }
-      elseif (is_array($value) && array_key_exists('uid', $value)) { // With CCK, it's an array. User ref
-        $selected_options[$value['uid']] = $value['uid'];
-      }
-      elseif (array_key_exists($value, $options)) { // With FAPI, it's not.
-        $selected_options[$value] = $options[$value];
+    $function = '_multiselect_default_values';
+    if (!empty($field['module']) && $module = $field['module']) {
+      if ($func = module_hook($module, 'multiselect_default_values')) {
+        $function = $module . '_multiselect_default_values';
       }
     }
+    $selected_options = call_user_func_array($function, array($items, $field));
   }
   else { // There's only one selected option.
     if (array_key_exists($items, $options)) {
@@ -311,4 +301,62 @@ function form_type_multiselect_value($element, $edit = FALSE) {
   if (func_num_args() == 1) {
     return $element['#default_value'];
   }
+}
+
+/**
+ * Implements hook_multiselect_default_values().
+ */
+function _multiselect_default_values($items, $field) {
+  $selected_options = array();
+
+  foreach ($items as $key => $value) {
+    $selected_options[$value] = $options[$value];
+  }
+
+  return $selected_options;
+}
+
+/**
+ * Implements hook_multiselect_default_values().
+ * Field-Type: list
+ */
+function list_multiselect_default_values($items, $field) {
+  return _multiselect_default_values_key('value', $items, $field);
+}
+
+/**
+ * Implements hook_multiselect_default_values().
+ * Field-Type: taxonomy_term_reference
+ */
+function taxonomy_multiselect_default_values($items, $field) {
+  return _multiselect_default_values_key('tid', $items, $field);
+}
+
+/**
+ * Implements hook_multiselect_default_values().
+ * Field-Type: user_reference
+ */
+function user_reference_multiselect_default_values($items, $field) {
+  return _multiselect_default_values_key('uid', $items, $field);
+}
+
+/**
+ * Implements hook_multiselect_default_values().
+ * Field-Type: node_reference
+ */
+function node_reference_multiselect_default_values($items, $field) {
+  return _multiselect_default_values_key('uid', $items, $field);
+}
+
+/**
+ * Helper function for hook_multiselect_default_values()
+ */
+function _multiselect_default_values_key($key, $items, $field) {
+  $selected_options = array();
+
+  foreach ($items as $value) {
+    $selected_options[$value[$key]] = $value[$key];
+  }
+
+  return $selected_options;
 }
\ No newline at end of file
-- 
1.7.3.4

