? uc_extra_fields_pane.admin.inc
Index: uc_extra_fields_pane.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_extra_fields_pane/uc_extra_fields_pane.install,v
retrieving revision 1.1.4.1
diff -u -p -r1.1.4.1 uc_extra_fields_pane.install
--- uc_extra_fields_pane.install	19 Jul 2010 08:03:46 -0000	1.1.4.1
+++ uc_extra_fields_pane.install	27 Jul 2010 14:31:13 -0000
@@ -1,22 +1,26 @@
 <?php
 // $Id$
-/* 
+/**
+ * @file
  * Module: uc_extra_fields_pane.module
  *
  * This module extends Ubercart panes by allowing you to set values
- * by a variety of methods to variables that will show up in the order. 
+ * by a variety of methods to variables that will show up in the order.
  * 
  * co-authored by:
  * blackice78 - Maurizio Ganovelli - drupal@ganovelli.it
  * and
  * panthar - Bobby Kramer - panthar1@gmail.com
  *
- * Sponsored by CHG Digital Solutions - http://chgnet.com 
+ * Sponsored by CHG Digital Solutions - http://chgnet.com
  *
- */      
+ */
 
+/**
+ * Implementation of hook_schema().
+ * @return array
+ */
 function uc_extra_fields_pane_schema() {
-   
   $schema['uc_extra_fields_values'] = array(
     'fields' => array(
       'order_id' => array(
@@ -38,52 +42,49 @@ function uc_extra_fields_pane_schema() {
       ),
       'field_name' => array(
         'type' => 'varchar',
-        'length' => 100, 
+        'length' => 100,
         'not null' => TRUE,
-      ), 
+      ),
       'field_description' => array(
         'type' => 'text',
       ),
       'field_db_name' => array(
         'type' => 'varchar',
-        'length' => 20, 
+        'length' => 20,
         'not null' => TRUE,
       ),
       'field_pane_type' => array(
         'type' => 'varchar',
-        'length' => 20, 
-      	'description' => 'The defined pane type for this variable to appear in. If you want more panes, one of the things you will have to do is add another pane type inside uc_extra_fields_pane.module.',
-      
+        'length' => 20,
+        'description' => 'The defined pane type for this variable to appear in. If you want more panes, one of the things you will have to do is add another pane type inside uc_extra_fields_pane.module.',
       ),
       'field_delta' => array(
         'type' => 'int',
-        'length' => 10, 
-      	'description' => 'The delta position of this field on the pane selected for this field.',
-      
-      ), 
+        'length' => 10,
+        'description' => 'The delta position of this field on the pane selected for this field.',
+      ),
       'field_value_type' => array(
         'type' => 'int',
-        'length' => 10, 
-     	'description' => 'The type of input to the field_value database field.',
-      
-      ), 
+        'length' => 10,
+        'description' => 'The type of input to the field_value database field.',
+      ),
        'field_value' => array(
         'type' => 'blob',
         'description' => 'A blob that can be used to store anything from php code, to constant values, to select values',
       ),
-     'field_display' => array(
+      'field_display' => array(
         'type' => 'int',
         'size' => 'tiny',
         'not null' => TRUE,
         'default' => 0,
-      ),     
+      ),
       'field_required' => array(
         'type' => 'int',
         'size' => 'tiny',
-      	'description' => 'Only applies if you select a textbox',
+        'description' => 'Only applies if you select a textbox',
         'not null' => TRUE,
         'default' => 0,
-      ),       
+      ),
     ),
     'primary key' => array('field_id'),
     'unique keys' => array(
@@ -94,10 +95,18 @@ function uc_extra_fields_pane_schema() {
   return $schema;
 }
 
+/**
+ * Implementation of hook_install().
+ * @return void
+ */
 function uc_extra_fields_pane_install() {
   drupal_install_schema('uc_extra_fields_pane');
 }
 
+/**
+ * Implementation of hook_uninstall().
+ * @return void
+ */
 function uc_extra_fields_pane_uninstall() {
   drupal_uninstall_schema('uc_extra_fields_pane');
 }
Index: uc_extra_fields_pane.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_extra_fields_pane/uc_extra_fields_pane.module,v
retrieving revision 1.1.4.1
diff -u -p -r1.1.4.1 uc_extra_fields_pane.module
--- uc_extra_fields_pane.module	19 Jul 2010 08:03:46 -0000	1.1.4.1
+++ uc_extra_fields_pane.module	27 Jul 2010 14:31:14 -0000
@@ -1,10 +1,11 @@
 <?php
 // $Id$
-/*
+/**
+ * @file
  * Module: uc_extra_fields_pane.module
  *
  * This module extends Ubercart panes by allowing you to set values
- * by a variety of methods to variables that will show up in the order. 
+ * by a variety of methods to variables that will show up in the order.
  * 
  * co-authored by:
  * blackice78 - Maurizio Ganovelli - drupal@ganovelli.it
@@ -12,11 +13,64 @@
  * panthar - Bobby Kramer - panthar1@gmail.com
  *
  */
-/*
- * implementation of hook_menu()
+
+/**
+ * MegaChriz:
+ * Overview made changes:
+ * - added 'order addresses'-functionallity
+ * - address fields now appear in original checkout panes (but not in original order panes)
+ * - module now relies upon Ubercart 2.3, because hooks are used that were introduced in that version
+ * - added function comments (added param, return, see)
+ * - reordered functions
+ * - moved admin functions to uc_extra_fields_pane.admin.inc
+ * - improved part of code following Drupal coding standards (this is not finished, warnings about t() are not fixed yet)
+ * - little fixes
+ */
+ 
+ /**
+ * @todo
+ * - token integration -> panthar
+ * - views integration
+ * - adding an address field must result by an extra field in both delivery and billing pane by default
+ * - fix 'saved addresses' drop down and 'my billing information is the same as my delivery information'
+ * - multiple panes support -> panthar
+ * - uc_addresses integration -> MegaChriz
+ * - move 'add address fields' to 'Address fields' (/admin/store/settings/checkout/edit/fields),
+ *   this is currently at 'Custom order fields'
+ * - get the extra address information also in original order panes
+ *
+ * KNOWN BUGS
+ * - adding an address field results in a white page at /cart/checkout when uc_addresses is enabled
+ */
+
+// -------------------------------------------------------------------
+// DRUPAL HOOKS
+// -------------------------------------------------------------------
+
+// MegaChriz: function added
+/**
+ * Implementation of hook_enable().
+ * Makes sure code of this module is executed after 'uc_addresses' (if that module is available)
+ */
+function uc_extra_fields_pane_enable() {
+  // Get weight of uc_addresses module
+  $sQuery = "SELECT weight
+  FROM {system}
+  WHERE name = 'uc_addresses'
+  AND type = 'module'
+  ";
+  $iWeight = db_result(db_query($sQuery)) + 10;
+
+  // Increase the weight of this module, making it 10 heavier then uc_addresses.
+  db_query("UPDATE {system} SET weight = %d WHERE name = 'uc_extra_fields_pane' AND type = 'module'", $iWeight);
+}
+
+/**
+ * Implementation of hook_menu().
+ * @return array
  */
 function uc_extra_fields_pane_menu() {
-	$items['admin/store/settings/checkout/edit/extrafields'] = array(
+  $items['admin/store/settings/checkout/edit/extrafields'] = array(
     'title' => 'Custom order fields',
     'description' => 'Add more custom order fields.',
     'page callback' => 'drupal_get_form',
@@ -24,484 +78,587 @@ function uc_extra_fields_pane_menu() {
     'access arguments' => array('administer store'),
     'type' => MENU_LOCAL_TASK,
     'weight' => 5,
-	);
-	$items['admin/store/settings/extrafields/%/delete'] = array(
+    'file' => 'uc_extra_fields_pane.admin.inc',
+  );
+  $items['admin/store/settings/extrafields/%/delete'] = array(
     'title' => 'Delete custom field',
     'description' => 'Delete a custom field.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('uc_extra_fields_pane_field_delete', 4),
     'access arguments' => array('administer store'),
     'type' => MENU_CALLBACK,
-	);
-	$items['admin/store/settings/extrafields/%/edit'] = array(
+    'file' => 'uc_extra_fields_pane.admin.inc',
+  );
+  $items['admin/store/settings/extrafields/%/edit'] = array(
     'title' => 'Modify field',
     'description' => 'Edit custom field.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('uc_extra_fields_pane_field_edit', 4),
     'access arguments' => array('administer store'),
     'type' => MENU_CALLBACK,
-	);
+    'file' => 'uc_extra_fields_pane.admin.inc',
+  );
 
-	return $items;
+  return $items;
 }
 
+// MegaChriz: function added
 /**
- * implementation of hook_checkout_pane();
+ * Implementation of hook_form_alter().
+ * @param array $form
+ * @param array $form_state
+ * @param string $form_id
+ * @return void
+ */
+function uc_extra_fields_pane_form_alter(&$form, &$form_state, $form_id) {
+  switch ($form_id) {
+    // Address fields configuration form
+    case 'uc_store_address_fields_form':
+      // Add extra address fields currently defined on /admin/store/settings/checkout/edit/extrafields
+      _uc_extra_fields_pane_address_fields_uc_store_address_fields_alter($form, $form_state);
+      
+      // add the possibility to order the address fields.
+      _uc_extra_fields_pane_weight_uc_store_address_fields_alter($form, $form_state);
+      break;
+
+    // The checkout form is altered by an implementation of hook_form_FORM_ID_alter().
+
+    // Ubercart Addresses integration: add/edit address form
+    case 'uc_addresses_get_address_form':
+      // add weight to the address fields
+      _uc_extra_fields_pane_applyWeights($form['panes']['address']);
+      break;
+
+    // Ubercart Addresses integration: address fields on user registration page
+    case 'user_register':
+      // add weight to the address fields
+      _uc_extra_fields_pane_applyWeights($form[0]);
+      break;
+  }
+}
+
+// -------------------------------------------------------------------
+// UBERCART HOOKS
+// -------------------------------------------------------------------
+
+/**
+ * Implementation of hook_checkout_pane().
  *
  * Add panes as you feel fit. Must add a new pane definition for both checkout and order... and a new callback function like below.
  *
  * Once you have that, just add a new pane_type to the create/edit admin forms, and that pane should be operational right away.
+ *
+ * @return array
  */
 function uc_extra_fields_pane_checkout_pane() {
-	$panes[] = array(
+  $panes[] = array(
     'id' => 'extra_information',
     'callback' => 'uc_extra_fields_pane_information',
     'title' => t('Extra order information'),
     'desc' => t('Extra order information'),
     'weight' => 0,
-	);
-	$panes[] = array(
+  );
+  // MegaChriz: removed because the extra fields will now get into the original panes!
+  /*
+  $panes[] = array(
     'id' => 'extra_delivery',
     'callback' => 'uc_extra_fields_pane_delivery',
     'title' => t('Extra delivery information'),
     'desc' => t('Extra delivery information'),
     'weight' => 1,
-	);
-	$panes[] = array(
+  );
+  $panes[] = array(
     'id' => 'extra_billing',
     'callback' => 'uc_extra_fields_pane_billing',
     'title' => t('Extra Billing Information'),
     'desc' => t('Extra Billing Information'),
     'weight' => 2,
-	);
+  );
+  */
 
-	return $panes;
+  return $panes;
 }
+
 /**
+ * Implementation of hook_order_pane().
  * Current order-pane definitions
+ * @return array
  */
 function uc_extra_fields_pane_order_pane() {
-	$panes[] = array(
+  $panes[] = array(
     'id' => 'extra_information',
     'callback' => 'uc_extra_fields_pane_order_information',
     'title' => t('Extra information'),
     'desc' => t('Extra information'),
     'class' => 'pos-left',
     'weight' => 0,
-    'show' => array('view', 'edit', 'customer'), // invoice --> from itpl.php template 
-	);
-	$panes[] = array(
+    'show' => array('view', 'edit', 'customer'), // invoice --> from itpl.php template
+  );
+  // MegaChriz: not sure if the following needs to be removed either
+  // MegaChriz: changed the weights
+  $panes[] = array(
     'id' => 'extra_delivery',
     'callback' => 'uc_extra_fields_pane_order_handler_delivery',
     'title' => t('Extra delivery'),
     'desc' => t('Extra delivery'),
     'class' => 'pos-left',
-    'weight' => 1,
-    'show' => array('view', 'edit', 'customer'), // invoice --> from itpl.php template 
-	);
-	$panes[] = array(
+    'weight' => 1.5,
+    'show' => array('view', 'edit', 'customer'), // invoice --> from itpl.php template
+  );
+  $panes[] = array(
     'id' => 'extra_billing',
     'callback' => 'uc_extra_fields_pane_order_handler_billing',
     'title' => t('Extra billing'),
     'desc' => t('Extra billing'),
     'class' => 'pos-left',
-    'weight' => 2,
-    'show' => array('view', 'edit', 'customer'), // invoice --> from itpl.php template 
-	);
+    'weight' => 2.5,
+    'show' => array('view', 'edit', 'customer'), // invoice --> from itpl.php template
+  );
 
-	return $panes;
+  return $panes;
 }
+
+/**
+ * Implementation of hook_order().
+ * @param string $op
+ * @param mixed $arg1
+ * @param mixed $arg2
+ * @return void
+ */
+function uc_extra_fields_pane_order($op, &$arg1, $arg2) {
+  switch ($op) {
+    case 'new':
+      // do nothing, extra field cannot be handled here
+      break;
+
+    case 'save':
+      if (is_array($arg1->extra_fields) && count($arg1->extra_fields)) {
+        $fields = uc_extra_fields_pane_load_fields_from_db();
+        $sql_field_names = array();
+        $sql_field_values = array();
+        foreach ($arg1->extra_fields as $key => $value) {
+          $sql_field_names[] = $key ;
+          $sql_field_values[] = $value;
+        }
+        if (count($sql_field_values)) {
+          $sql_field_values[] = $arg1->order_id;
+          db_query("UPDATE {uc_extra_fields_values} SET " . implode("='%s',", $sql_field_names) . "='%s' WHERE order_id=%d", $sql_field_values);
+          if (!db_affected_rows()) {
+            $placeholders = '';
+            for ($i = 0; $i<count($sql_field_names);$i++) $placeholders .="'%s',";
+            db_query("INSERT into {uc_extra_fields_values}(" . implode(',', $sql_field_names) . ",order_id) VALUES (" . $placeholders . "%d)", $sql_field_values);
+          }
+        }
+      }
+      break;
+    
+    case 'load':
+      $arg1->extra_fields = array();
+      $values = db_fetch_array(db_query("SELECT * FROM {uc_extra_fields_values} WHERE order_id=%d", $arg1->order_id));
+      if ($values && count($values)) {
+        foreach ($values as $key => $value) {
+          if ($value && $key != 'order_id' ) $arg1->extra_fields[$key] = $value;
+        }
+      }
+      break;
+  }
+}
+
+// MegaChriz: function added
+/**
+ * Implementation of hook_checkout_pane_alter().
+ * Alters delivery and billing pane
+ * @param array $panes
+ * @return void
+ */
+function uc_extra_fields_pane_checkout_pane_alter(&$panes) {
+  foreach ($panes as $key => $pane) {
+    switch ($pane['id']) {
+      case 'delivery':
+        $panes[$key]['callback'] = 'uc_extra_fields_pane_uc_checkout_pane_delivery';
+        break;
+      case 'billing':
+        $panes[$key]['callback'] = 'uc_extra_fields_pane_uc_checkout_pane_billing';
+        break;
+    }
+  }
+}
+
+// -------------------------------------------------------------------
+// TOKEN HOOKS
+// -------------------------------------------------------------------
+
+// MegaChriz: These hook implementations will be added by panthar
+
+// -------------------------------------------------------------------
+// FORM ALTERS (address fields weight)
+// The following functions together makes it possible to change the 
+// order of the address fields
+// -------------------------------------------------------------------
+
+// --------------------------
+// uc_store_address_fields
+// --------------------------
+
+// MegaChriz: function added
+/**
+ * _uc_extra_fields_pane_weight_uc_store_address_fields_alter()
+ * Adds option to order address fields by adding a weight field
+ * @param array $form
+ * @param array $form_state
+ * @access private
+ * @see
+ *  theme_uc_extra_fields_pane_weight_uc_store_address_fields()
+ *  uc_extra_fields_pane_weight_uc_store_address_fields_submit()
+ */
+function _uc_extra_fields_pane_weight_uc_store_address_fields_alter(&$form, $form_state) {
+  // Get weight settings
+  $weights = variable_get('uc_address_fields_weight', _uc_extra_fields_pane_getDefaultAddressFieldsWeights($form['fields']));
+  
+  // Merge weight settings with default weight settings in case extra fields were added
+  $weights = array_merge(_uc_extra_fields_pane_getDefaultAddressFieldsWeights($form['fields']), $weights);
+  
+  foreach ($weights as $fieldname => $weight) {
+    if (isset($form['fields'][$fieldname])) {
+      // Add weight fields
+      $form['fields'][$fieldname]['weight'] = array(
+        '#type' => 'weight',
+        '#delta' => 30,
+        '#default_value' => $weight,
+        '#attributes' => array('class' => 'uc-address-fields-table-ordering'),
+      );
+      
+      // Apply weight settings on fields
+      $form['fields'][$fieldname]['#weight'] = $weight;
+    }
+  }
+  
+  // Add our theme function to the form, so that function can add draggable rows functionallity
+  $form['#theme'][] = 'uc_extra_fields_pane_weight_uc_store_address_fields';
+  
+  // Add submit function in order to save the weight settings
+  $form['#submit'][] = 'uc_extra_fields_pane_weight_uc_store_address_fields_submit';
+}
+
+// MegaChriz: function added
+/**
+ * uc_extra_fields_pane_weight_uc_store_address_fields_submit()
+ * Saves the weight settings for the address fields
+ * @param array $form
+ * @param array $form_state
+ * @see
+ *  _uc_extra_fields_pane_weight_uc_store_address_fields_alter()
+ */
+function uc_extra_fields_pane_weight_uc_store_address_fields_submit($form, $form_state) {
+  $weights = array();
+  foreach ($form_state['values']['fields'] as $fieldname => $fieldsettings) {
+    $weights[$fieldname] = $fieldsettings['weight'];
+  }
+  variable_set('uc_address_fields_weight', $weights);
+}
+
+// -------------------------------------------------------------------
+// FORM ALTERS (extra address fields)
+// The following functions together makes it possible to get extra 
+// address fields inside existing panes
+// -------------------------------------------------------------------
+
+// --------------------------
+// uc_store_address_fields
+// --------------------------
+
+// MegaChriz: function added
+/**
+ * _uc_extra_fields_pane_address_fields_uc_store_address_fields_alter()
+ * Adds extra address fields to form
+ * (which are currently defined at /admin/store/settings/checkout/edit/extrafields)
+ * @param array $form
+ * @param array $form_state
+ * @access private
+ */
+function _uc_extra_fields_pane_address_fields_uc_store_address_fields_alter(&$form, $form_state) {
+  $fields_delivery = uc_extra_fields_pane_load_fields_from_db('extra_delivery');
+  $fields_billing = uc_extra_fields_pane_load_fields_from_db('extra_billing');
+  $fields = array_merge($fields_delivery, $fields_billing);
+  
+  // Similar to uc_store_address_fields_form() from uc_store.module
+  foreach ($fields as $field => $data) {
+    if ($data['display']) {
+      $form['fields'][$field]['#summary callback'] = 'summarize_form';
+      $form['fields'][$field]['enabled'] = array(
+        '#type' => 'checkbox',
+        '#summary callback' => 'summarize_checkbox',
+        '#summary arguments' => array(
+          t('@field is enabled.', array('@field' => $data['title'])),
+          t('@field is disabled.', array('@field' => $data['title'])),
+        ),
+        '#default_value' => ($data['display']) ? TRUE : FALSE,
+        '#disabled' => TRUE,
+      );
+      $form['fields'][$field]['required'] = array(
+        '#type' => 'checkbox',
+        '#default_value' => ($data['required']) ? TRUE : FALSE,
+        '#disabled' => TRUE,
+      );
+    }
+    else {
+      $form['fields'][$field]['enabled'] = array(
+        '#value' => '-',
+      );
+    }
+    $form['fields'][$field]['default'] = array(
+      '#value' => $data['field'],
+    );
+    $form['fields'][$field]['title'] = array(
+      '#value' => $data['title'],
+    );
+  }
+}
+
+// --------------------------
+// uc_cart_checkout_form_alter
+// --------------------------
+
+// MegaChriz: function added
+/**
+ * Implementation of hook_form_FORM_ID_alter().
+ * Applies ordering to address fields following the 'uc_address_fields_weight'-settings.
+ * @param array $form
+ * @param array $form_state
+ * @access private
+ */
+function uc_extra_fields_pane_form_uc_cart_checkout_form_alter(&$form, $form_state) {
+  // Apply weight for delivery fields (fieldnames are prefixed with 'delivery_')
+  _uc_extra_fields_pane_applyWeights($form['panes']['delivery'], 'delivery_');
+  
+  // Apply weight for billing fields (fieldnames are prefixed with 'billing_')
+  _uc_extra_fields_pane_applyWeights($form['panes']['billing'], 'billing_');
+}
+
+// MegaChriz: function added
+/**
+ * uc_extra_fields_pane_uc_checkout_pane_delivery()
+ * Overrides uc_checkout_pane_delivery() function in uc_cart_checkout_pane.inc
+ * @param string $op
+ * @param mixed $arg1
+ * @param mixed $arg2
+ * @return mixed
+ */
+function uc_extra_fields_pane_uc_checkout_pane_delivery($op, $arg1, $arg2) {
+  return uc_extra_fields_pane_uc_checkout_pane_address('delivery', $op, $arg1, $arg2);
+}
+
+// MegaChriz: function added
+/**
+ * uc_extra_fields_pane_uc_checkout_pane_billing()
+ * Overrides uc_checkout_pane_billing() function in uc_cart_checkout_pane.inc
+ * @param string $op
+ * @param mixed $arg1
+ * @param mixed $arg2
+ * @return mixed
+ */
+function uc_extra_fields_pane_uc_checkout_pane_billing($op, $arg1, $arg2) {
+  return uc_extra_fields_pane_uc_checkout_pane_address('billing', $op, $arg1, $arg2);
+}
+
+// MegaChriz: function added
+/**
+ * uc_extra_fields_pane_uc_checkout_pane_address()
+ * @param string $type
+ *  type is 'delivery' or 'billing'
+ * @param string $op
+ * @param mixed $arg1
+ * @param mixed $arg2
+ * @return mixed
+ */
+function uc_extra_fields_pane_uc_checkout_pane_address($type, $op, $arg1, $arg2) {
+  // Throw error if $type is not what we expected
+  if ($type != 'delivery' && $type != 'billing') {
+    trigger_error("Provided type in uc_extra_fields_pane_uc_checkout_pane_address() should be either 'delivery' or 'billing'.", E_USER_WARNING);
+    return;
+  }
+  
+  // Include uc_cart_checkout_pane.inc
+  module_load_include('inc', 'uc_cart', 'uc_cart_checkout_pane');
+  
+  switch ($op) {
+    case 'view':
+      if ($type == 'delivery') {
+        $pane = uc_checkout_pane_delivery($op, $arg1, $arg2);
+      }
+      else {
+        $pane = uc_checkout_pane_billing($op, $arg1, $arg2);
+      }
+      // MegaChriz: This may change later. I didn't want to mess too much with the original load_pane_type-function yet.
+      $pane_extra_fields = uc_extra_fields_pane_load_pane_type($op, $arg1, $arg2, 'extra_' . $type);
+            
+      // Get contents of extra fields and merge it with default content
+      if (isset($pane_extra_fields['contents']['extra_fields'])) {
+        // Prefix fieldnames with 'delivery_' or 'billing_'
+        $extra_fields = array();
+        foreach ($pane_extra_fields['contents']['extra_fields'] as $fieldname => $field) {
+          $extra_fields[$type . '_' . $fieldname] = $field;
+        }
+        
+        // Merge extra fields array with original fields array
+        $pane['contents'] = array_merge($pane['contents'], $extra_fields);die();
+      }
+      
+      return $pane;
+      break;
+    
+    case 'process':
+      if ($type == 'delivery') {
+        $bResult1 = uc_checkout_pane_delivery($op, $arg1, $arg2);
+      }
+      else {
+        $bResult1 = uc_checkout_pane_billing($op, $arg1, $arg2);
+      }
+      
+      // Put extra address fields in 'extra_fields'-array, so uc_extra_fields_pane_load_pane_type() can handle it
+      foreach ($arg2 as $fieldname => $value)
+      {
+        $arg2['extra_fields'] = array();
+        if (strpos($fieldname, $type.'_ucxf') === 0)
+        {
+          // This is an extra field, substract type from fieldname
+          $fixedfieldname = substr($fieldname, strlen($type . '_'));
+          $arg2['extra_fields'][$fixedfieldname] = $value;
+        }
+      }
+      // MegaChriz: again, this may change later
+      $bResult2 = uc_extra_fields_pane_load_pane_type($op, $arg1, $arg2, 'extra_' . $type);
+      return ($bResult1 && $bResult2);
+      break;
+      
+    case 'review':
+      if ($type == 'delivery') {
+        $review1 = uc_checkout_pane_delivery($op, $arg1, $arg2);
+      }
+      else {
+        $review1 = uc_checkout_pane_billing($op, $arg1, $arg2);
+      }
+      // MegaChriz: and again, this may change later
+      $review2 = uc_extra_fields_pane_load_pane_type($op, $arg1, $arg2, 'extra_' . $type);
+      $review = array_merge($review1, $review2);
+      return $review;
+      break;
+  }
+}
+
+// -------------------------------------------------------------------
+// EXTRA FIELDS PANE API
+// -------------------------------------------------------------------
+
 /**
  * We wrap these pane functions for the checkout/order panes, so that we know which pane is calling,
  * and therefore everything appears inside its own pane.
  *
  * The only way I could get this to work was with wrapping these functions.
- * Giveing each pane an arguement did not work. 
- * 
- * If you can figure out another way, please do it. This does however allow for   a lot of flexibility with modules connecting to it
- * because you can call each pane directly in any order processing module. 
- * 
+ * Giving each pane an argument did not work.
  * 
+ * If you can figure out another way, please do it. This does however allow for a lot of flexibility with modules connecting to it
+ * because you can call each pane directly in any order processing module.
  */
+// MegaChriz: removed 'delivery' and 'billing', because those fields now come in original panes.
+/*
 function uc_extra_fields_pane_delivery($op, &$arg1 = NULL, $arg2 = NULL) {
-	return uc_extra_fields_pane_load_pane_type($op, $arg1, $arg2, "extra_delivery");
+  return uc_extra_fields_pane_load_pane_type($op, $arg1, $arg2, "extra_delivery");
 }
 function uc_extra_fields_pane_billing($op, &$arg1 = NULL, $arg2 = NULL) {
-	return uc_extra_fields_pane_load_pane_type($op, $arg1, $arg2, "extra_billing");
-
+  return uc_extra_fields_pane_load_pane_type($op, $arg1, $arg2, "extra_billing");
 }
+*/
+
 function uc_extra_fields_pane_information($op, &$arg1 = NULL, $arg2 = NULL) {
-	return uc_extra_fields_pane_load_pane_type($op, $arg1, $arg2, "extra_information");
+  return uc_extra_fields_pane_load_pane_type($op, $arg1, $arg2, "extra_information");
 }
 
 
 function uc_extra_fields_pane_order_handler_delivery($op, $arg1 = NULL, $arg2 = NULL) {
-	return uc_extra_fields_pane_order_handler($op, $arg1, $arg2, "extra_delivery");
+  return uc_extra_fields_pane_order_handler($op, $arg1, $arg2, "extra_delivery");
 }
 function uc_extra_fields_pane_order_handler_billing($op, $arg1 = NULL, $arg2 = NULL) {
-	return uc_extra_fields_pane_order_handler($op, $arg1, $arg2, "extra_billing");
+  return uc_extra_fields_pane_order_handler($op, $arg1, $arg2, "extra_billing");
 
 }
 function uc_extra_fields_pane_order_information($op, $arg1 = NULL, $arg2 = NULL) {
-	return uc_extra_fields_pane_order_handler($op, $arg1, $arg2, "extra_information");
-}
-/**
- * 
- * uc_extra_fields_pane_form form validation (called after new field insert)
- *
- */
-//check_markup
-//filter_form
-function uc_extra_fields_pane_form_validate($form, &$form_state) {
-
-	$field=$form_state['values']['add_one_more_field'];
-	// No label.
-	if (!$field['label']) {
-		form_set_error('add_one_more_field][label', t('Add new field: you need to provide a label.'));
-	}
-	// No field name.
-	if (!$field['field_name']) {
-		form_set_error('add_one_more_field][field_name', t('Add new field: you need to provide a field name.'));
-	}
-	if(!$field['delta']){
-		form_set_error('add_one_more_field][field_name', t('Add new field: you need to provide a delta value for this extra field.'));
-	}
-	if(!$field['pane_type']){
-		form_set_error('add_one_more_field][field_name', t('Add new field: you need to provide a pane-type for this extra field.'));
-	}
-	if(!$field['value_type']){
-		form_set_error('add_one_more_field][field_name', t('Add new field: you need to provide a way of processing the value for this field as either textbox, select, constant, or php.'));
-	}
-	if($field['value_type'] > 1 && !$field['value_input'] ){
-		form_set_error('add_one_more_field][field_name', t('Add new field: you need to provide a value for this way of calculating the field value.'));
-	}
-	// Field name validation.
-	else {
-		$field_name = $field['field_name'];
-		// Add the 'uc_extra_' prefix.
-		if (substr($field_name, 0, 8) != 'uc_extra_') {
-			$field_name = 'ucxf_'. $field_name;
-			form_set_value($form['add_one_more_field']['field_name'], $field_name, $form_state);
-		}
-		// Invalid field name.
-		if (!preg_match('!^ucxf_[a-z0-9_]+$!', $field_name)) {
-			form_set_error('add_one_more_field][field_name', t('Add new field: the field name %field_name is invalid. The name must include only lowercase unaccentuated letters, numbers, and underscores.', array('%field_name' => $field_name)));
-		}
-		// considering prefix uc_extra_  no more than 23 characters (32 max for a db field)
-		if (strlen($field_name) > 23) {
-			form_set_error('add_one_more_field][field_name', t('Add new field: the field name %field_name is too long. The name is limited to 23 characters, including the \'ucxf_\' prefix.', array('%field_name' => $field_name)));
-		}
-		// Field name already exists.
-		$count = db_result(db_query("select count(*) from {uc_extra_fields} where field_db_name='%s'", $field_name));
-		if ((int)$count>0) {
-			form_set_error('add_one_more_field][field_name', t('Add new field: the field name %field_name already exists.', array('%field_name' => $field_name)));
-		}
-	}
-}
-
-/**
- * uc_extra_fields_pane_form submit function: insert new row and fields into db
- *
- */
-function uc_extra_fields_pane_form_submit($form, &$form_state) {
-	$field=$form_state['values']['add_one_more_field'];
-	db_query("insert into {uc_extra_fields} (field_name,field_description,field_db_name,field_required, field_value, field_value_type, field_delta, field_display, field_pane_type)
-              values ('%s','%s','%s',%d, '%s', %d, %d, %d, '%s')",
-	$field['label'],
-	$field['description'],
-	$field['field_name'],
-	$field['required'],
-	$field['value_input'],
-	$field['value_type'],
-	$field['delta'],
-	$field['display'],
-	$field['pane_type']
-	);
-	$delivery_field_value_name=$field['field_name'];
-	db_query("alter table {uc_extra_fields_values} add column `%s` VARCHAR(255)", $delivery_field_value_name);
-	drupal_set_message(t('Field saved'));
-}
-
-
-/**
- * return a confirm delete form for the passed field id *
- */
-
-function uc_extra_fields_pane_field_delete($form_state, $fid) {
-	$fields=uc_extra_fields_pane_load_fields_from_db();
-	$field_name="";
-	if (count($fields)) {
-		foreach ($fields as $field) {
-			if ($field['id']==$fid) {
-				$field_name=$field['title'];
-				break;
-			}
-		}
-	}
-	return confirm_form(
-	array(
-      'field' => array(
-        '#type' => 'value',
-        '#value' => $fid,
-	),
-	),
-	t('Are you sure you want to remove the field "%field"?', array('%field' => $field_name)),
-    'admin/store/settings/checkout/edit/extrafields',
-	t('This action cannot be undone.'),
-	t('Remove'),
-	t('Cancel')
-	);
-}
-
-function uc_extra_fields_pane_field_delete_submit($form, &$form_state) {
-	$fields=uc_extra_fields_pane_load_fields_from_db();
-	$field_name="";
-	if (count($fields)) {
-		foreach ($fields as $field) {
-			if ($field['id']==$form_state['values']['field']) {
-				$field_db_name=$field['field'];
-				break;
-			}
-		}
-	}
-	db_query("delete from {uc_extra_fields} where field_id=%d", $form_state['values']['field']);
-	db_query("alter table {uc_extra_fields_values} drop column `%s`", $field_db_name );
-	$form_state['redirect']='admin/store/settings/checkout/edit/extrafields';
-	drupal_set_message(t('Field deleted'));
+  return uc_extra_fields_pane_order_handler($op, $arg1, $arg2, "extra_information");
 }
 
-/**
- *  return existent fields list and the "add new" field form
- *
- */
-function uc_extra_fields_pane_form($form_state) {
-	$fields=uc_extra_fields_pane_load_fields_from_db();
-	$page_content .="";
-	$form = array('#tree' => TRUE);
-	if (count($fields)) {
-		$headers=array();
-		$headers[]=array('data' => t('Label'));
-		$headers[]=array('data' => t('Field name'));
-		$headers[]=array('data' => t('Pane type'));
-		$headers[]=array('data' => t('Required'));
-		$headers[]=array('data' => t('List position'));
-		$headers[]=array('data' => t('Description'));
-		$headers[]=array('data' => t('Action'));
-		$rows=array();
-		foreach ($fields as $field) {
-			$content=array();
-			$content[]=array('data' => $field['title']);
-			$content[]=array('data' => $field['field']);
-			$content[]=array('data' => $field['pane_type'] );
-			$content[]=array('data' => $field['required'] );
-			$content[]=array('data' =>  $field['delta'] -10);
-			$content[]=array('data' => $field['description']);
-			$content[]=array('data' => l(t('delete'), 'admin/store/settings/extrafields/' . $field['id'] . '/delete') . ' | ' .
-			l(t('edit'), 'admin/store/settings/extrafields/' . $field['id'] . '/edit')
-			);
-			$rows[]=$content;
-		}
-		$page_content=theme_table($headers, $rows);
-		$form['table']=array('#value' => $page_content);
-	}
-	$form['add_one_more_field']['label'] = array(
-        '#title' => t('Label'),
-        '#type' => 'textfield',
-        '#size' => 15,
-        '#description' => t('Label shown to customers in checkout pages.'),
-	);
-	$form['add_one_more_field']['field_name'] = array(
-        '#title' => t('Field name'),
-        '#type' => 'textfield',
-        '#size' => 15,
-        '#description' => t('Database field name. It must contain only lower chars a-z, digits 0-9 and _. Max allowed lenght is 23 characters.'),
-	);
-	$form['add_one_more_field']['description'] = array(
-        '#title' => t('Description'),
-        '#type' => 'textarea',
-        '#rows' => 3,
-        '#description' => t('Insert a description to tell customers how to fill this field.'),
-	);
-	$form['add_one_more_field']['delta'] = array(
-        '#title' => t('The listing position to display the order data on checkout/order panes'),
-        '#type' => 'select',
-     	'#options' => array(-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3 , 4, 5, 6, 7, 8, 9, 10),
-     	'#default_value' => 10,
-     	'#description' => t('The listing position '),
-	);
-	$form['add_one_more_field']['pane_type'] = array(
-        '#title' => t('Select which pane you would like the form value to be hooked into.'),
-        '#type' => 'select',
-     	'#options' => array('extra_information' => t('Extra Information pane'), 'extra_delivery' => t('Delivery pane') , 'extra_billing' => t('Billing pane')),
-
-	);
-	$options = array( t('Let the user input the data in a textbox. If you want a default value, put it in "value" field below.'), t('Let the user select from a list of options (enter one name|value per line).'), t('Show a admin defined constant value, insert the value int he "value" section.'));
-	$options[] = t('Set the value to the php code that returns a <code>STRING</code> (PHP-mode, experts only).');
-	$description = ' '. t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can break your Drupal site.', array('%php' => '<?php ?>'));
-
-	$form['add_one_more_field']['value_type'] = array(
-      '#type' => 'radios',
-      '#title' => t('Define where the  value comes from'),
-      '#options' => $options,
-	  '#default_value' => 0, 
-	);
-	$form['add_one_more_field']['value_input'] = array(
-      '#type' => 'textarea',
-      '#title' => t('Value'),
-      '#description' => $description,
-	);
-	$form['add_one_more_field']['display'] = array(
-		'#title' => t('Uncheck to hide field on the checkout page. The field will still be added to the order, and will appear in the order confirmation as well.'),
-        '#type' => 'checkbox',
-      	'#default_value' => 1,  
-	);
-	$form['add_one_more_field']['required'] = array(
-        '#title' => t('Field required'),
-        '#type' => 'checkbox',
-        '#description' => t('Check this item is field is mandatory.'),
-	);
-	$form['add_one_more_field']['submit'] = array(
-        '#type' => 'submit', 
-        '#value' => t('Save')
-	);
-	return $form;
-}
-
-function uc_extra_fields_pane_field_edit_submit($form, &$form_state) {
-	$field=$form_state['values'];
-	db_query("update {uc_extra_fields} set field_name='%s',field_description='%s',field_required=%d, field_value='%s', field_value_type=%d, field_delta=%d, field_display=%d, field_pane_type='%s' where field_id=%d", $field['label'], $field['description'], $field['required'], $field['value_input'] , $field['value_type'], $field['delta'], $field['display'], $field['pane_type'],(int)arg(4));
-	drupal_set_message(t('Field updated'));
-	$form_state['redirect']='admin/store/settings/checkout/edit/extrafields';
-}
-/**
- * Edit admin form for the extra fields
- */
-function uc_extra_fields_pane_field_edit($form_state, $fid) {
-	$fields=uc_extra_fields_pane_load_fields_from_db();
-	$field=array();
-	if (count($fields)) {
-		foreach ($fields as $field) {
-			if ($field['id']==$fid) {
-				break;
-			}
-		}
-	}
-	$form = array();
-	 
-	$form['label'] = array(
-        '#title' => t('Label'),
-        '#type' => 'textfield',
-        '#size' => 15,
-        '#description' => t('Label shown to customers in checkout pages.'),
-        '#required' => TRUE,
-        '#default_value' => $field['title'],
-	);
-	$form['delta'] = array(
-        '#title' => t('The listing position to display the order data on checkout/order panes'),
-        '#type' => 'select',
-     	'#options' => array(-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3 , 4, 5, 6, 7, 8, 9, 10),
-     	'#default_value' => $field['delta'],
-     	'#description' => t('The listing position '),
-	);
-	$form['pane_type'] = array(
-        '#title' => t('Select which pane you would like the form value to be hooked into.'),
-        '#type' => 'select',
-     	'#options' => array('extra_information' => t('Extra Information pane'), 'extra_delivery' => t('Delivery pane') , 'extra_billing' => t('Billing pane')),
-
-	);
-	$options = array( t('Let the user input the data in a textbox (leave value below blank).'), t('Let select from a list of options (enter ONE name|value per line'), t('Show a user defined value'));
-	$options[] = t('Set the value to the php code that returns a <code>STRING</code> (PHP-mode, experts only).');
-	$description .= ' '. t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can break your Drupal site.', array('%php' => '<?php ?>'));
-	$form['value_type'] = array(
-      '#type' => 'radios',
-      '#title' => t('Define Value'),
-      '#options' => $options,
-      '#default_value' => $field['value_type'],
-	);
-	$form['value_input'] = array(
-      '#type' => 'textarea',
-      '#title' => t('Value'),
-      '#description' => $description,
-      '#default_value' => $field['value_input'],
-	);
-	$form['display'] = array(
-        '#title' => t('Uncheck to hide field on the checkout page. The field will still be added to the order, and will appear in the order confirmation as well.'),
-        '#type' => 'checkbox',
-       	'#default_value' => $field['display'], 
-	);
-	$form['required'] = array(
-        '#title' => t('Field required'),
-        '#type' => 'checkbox',
-        '#description' => t('Check this item is field is mandatory.'),
-        '#default_value' => $field['required'],
-	);
-	$form['description'] = array(
-        '#title' => t('Description'),
-        '#type' => 'textarea',
-        '#rows' => 3,
-        '#description' => t('Insert a description to tell customers how to fill this field. ONLY applies for select/textbox options'),
-        '#default_value' => $field['description'],
-	);
-	$form['submit'] = array(
-        '#type' => 'submit', 
-        '#value' => t('Save')
-	);
-	return $form;
-}
+// MegaChriz: modified function: improved caching results, caching now happens per pane type.
 /**
  * Load all extra fields from the database.
  * 
  * Optionally, give it a $pane_type to specify which pane we want fields from.
+ * @param string $pane_type
+ * @return array
  */
 function uc_extra_fields_pane_load_fields_from_db($pane_type=NULL) {
-	$uc_extra_fields_pane_fields;
-	// caching results
-	if ($uc_extra_fields_pane_fields==NULL) $uc_extra_fields_pane_fields=array();
-	else return $uc_extra_fields_pane_fields;
-
-	//little if statement that changes our "get all" sql to be more specific if a pane_type arguement is provided
-	if($pane_type){
-		$db_results=db_query("select * from {uc_extra_fields} WHERE field_pane_type='%s' ORDER BY field_delta ASC", $pane_type);
-	}else{
-		$db_results=db_query("select * from {uc_extra_fields} ORDER BY field_delta ASC");
-		 
-	}
-	while ($db_result=db_fetch_array($db_results)) {
-		$uc_extra_fields_pane_fields[$db_result['field_db_name']]=array(
-            'id' => $db_result['field_id'],
-            'field' => $db_result['field_db_name'],
-            'title' => $db_result['field_name'],
-            'description' => $db_result['field_description'],
-            'required' => $db_result['field_required'],
-        	'value_input' => $db_result['field_value'],
-        	'value_type' => $db_result['field_value_type'],
-            'delta' => $db_result['field_delta'],
-        	'pane_type' => $db_result['field_pane_type'],
-        	'display' => $db_result['field_display']
-		);
-	}
-	return $uc_extra_fields_pane_fields;
+  // MegaChriz: added static keyword.
+  static $uc_extra_fields_pane_fields;
+  
+  // If no pane type provided, all fields must be loaded
+  if (!$pane_type) {
+    $pane_type = 'all';
+  }
+  
+  // caching results
+  if (!isset($uc_extra_fields_pane_fields[$pane_type])) {
+    $uc_extra_fields_pane_fields[$pane_type] = array();
+  }
+  else {
+    return $uc_extra_fields_pane_fields[$pane_type];
+  }
+
+  // little if statement that changes our "get all" sql to be more specific if a pane_type argument is provided
+  if ($pane_type != 'all') {
+    $db_results = db_query("SELECT * from {uc_extra_fields} WHERE field_pane_type='%s' ORDER BY field_delta ASC", $pane_type);
+  }
+  else {
+    $db_results = db_query("SELECT * FROM {uc_extra_fields} ORDER BY field_delta ASC");
+  }
+  while ($db_result = db_fetch_array($db_results)) {
+    $uc_extra_fields_pane_fields[$pane_type][$db_result['field_db_name']] = array(
+      'id' => $db_result['field_id'],
+      'field' => $db_result['field_db_name'],
+      'title' => $db_result['field_name'],
+      'description' => $db_result['field_description'],
+      'required' => $db_result['field_required'],
+      'value_input' => $db_result['field_value'],
+      'value_type' => $db_result['field_value_type'],
+      'delta' => $db_result['field_delta'],
+      'pane_type' => $db_result['field_pane_type'],
+      'display' => $db_result['field_display']
+    );
+  }
+  return $uc_extra_fields_pane_fields[$pane_type];
 }
 
-
 //note, this must be patched inside uc_cart.pages.inc
 /**
  * Pane handler
+ * @param string $op
+ * @param mixed $arg1
+ * @param mixed $arg2
+ * @param string $pane_type
+ * @return mixed
  */
 function uc_extra_fields_pane_load_pane_type($op, &$arg1 = NULL, $arg2 = NULL, $pane_type) {
-	switch ($op) {
-		case 'settings':
-			return;
-		case 'view':
-			$fields=uc_extra_fields_pane_load_fields_from_db($pane_type);
-			$contents=array();
-			// dynamically generate form elements
-	  $description='';
-	  if (count($fields)) {
-	  	foreach ($fields as $field) {
-	  		 //value_type 0 == textfield
-	  		 if($field['value_type'] == 0){
-	  			$contents['extra_fields'][$field['field'] ] = array(
+  switch ($op) {
+    case 'settings':
+      return;
+      
+    case 'view':
+      $fields = uc_extra_fields_pane_load_fields_from_db($pane_type);
+      $contents = array();
+      // dynamically generate form elements
+      $description = '';
+      if (count($fields)) {
+        foreach ($fields as $field) {
+          //value_type 0 == textfield
+          if ($field['value_type'] == 0) {
+            $contents['extra_fields'][$field['field'] ] = array(
               '#type' => 'textfield',
               '#title' => $field['title'],
               '#description' => $field['description'],
@@ -509,169 +666,137 @@ function uc_extra_fields_pane_load_pane_
               '#maxlength' => 255,
               '#required' => $field['required'],
               '#default_value' => isset($arg1->extra_fields[$field['field'] ]) ? $arg1->extra_fields[$field['field'] ] : NULL,
-	  			);
-	  		}
-	  		//value_type 1 == select statement, so parse the name|value pairs
-	  		//and display the select
-	  		else if($field['value_type'] == 1){
-	  			$input_token = strtok($field['value_input'], "\n");
-	  			while ($input_token !== false) {
-	  				if(strpos($input_token, "|")){
-	  					$arr = explode("|",$input_token);
-	  					$options[ trim($arr[1])]  = t( trim($arr[0]));
-	  				}else{
-	  					$options[ trim($input_token)]  = t( trim($input_token));
-	  				}
-	  				$input_token = strtok("\n");
-	  			}
-	  			$contents['extra_fields'][$field['field'] ] = array(
-			    '#type' => 'select',
-			              '#title' => $field['title'],
-			              '#description' => $field['description'],
-			              '#required' => $field['required'],
-					  	  '#options' => $options,
-	  			//'#default_value' => NULL,
-	  			);
-	  		}
-	  		//value_type == 3 is php evaluation returning a string
-	  		else if($field['value_type'] == 3){
-	  			$output = drupal_eval($field['value_input']);
-	  		}
-	  		//value_type == 2 is a constant
-	  		else if($field['value_type'] == 2){
-	  			$output = $field['value_input'];
-	  		}
-
-	  		//if its ONLY a constant or php defined value_type
-	  		if($field['value_type'] > 1 ){
-	  			//only display if the user asks, applies to value_type of php and constant ONLY
-	  			if($field['display'] == 1){
-	  				$contents['extra_fields'][$field['field'] . '_i'] = array(
-              		'#type' => 'item',
-        		    '#title' => t($field['title']),
-              		'#value' => $output,
-	  				);
-	  			}
-	  			$contents['extra_fields'][$field['field'] ] = array(
-              		'#type' => 'hidden',
-              		'#value' => $output,
-	  			);
-
-	  		}
-
-	  	}
-	  }
-	  return array('description' => $description, 'contents' => $contents, 'theme' => 'uc_extra_fields_pane');
-		case 'process':
-			// initialize and fill array
-			if ($arg1->extra_fields==NULL) $arg1->extra_fields=array();
-			$arg1->extra_fields=array_merge($arg1->extra_fields, $arg2['extra_fields']);
-			return TRUE;
-		case 'review':
-			$fields=uc_extra_fields_pane_load_fields_from_db($pane_type);
-			if (count($fields)) {
-				foreach ($fields as $field){
-					//make sure if its a textbox, to show it no matter what.
-					if($field['display'] == 1 || $fields['value_type'] == 0){
-						$review[] = array('title' => $field['title'],
+            );
+          }
+          //value_type 1 == select statement, so parse the name|value pairs
+          //and display the select
+          elseif ($field['value_type'] == 1) {
+            $input_token = strtok($field['value_input'], "\n");
+            while ($input_token !== FALSE) {
+              if (strpos($input_token, "|")) {
+                $arr = explode("|", $input_token);
+                $options[ trim($arr[1])] = t(trim($arr[0]));
+              }
+              else {
+                $options[ trim($input_token)] = t( trim($input_token));
+              }
+              $input_token = strtok("\n");
+            }
+            $contents['extra_fields'][$field['field'] ] = array(
+              '#type' => 'select',
+              '#title' => $field['title'],
+              '#description' => $field['description'],
+              '#required' => $field['required'],
+              '#options' => $options,
+              //'#default_value' => NULL,
+            );
+          }
+          //value_type == 3 is php evaluation returning a string
+          elseif ($field['value_type'] == 3) {
+            $output = drupal_eval($field['value_input']);
+          }
+          //value_type == 2 is a constant
+          elseif ($field['value_type'] == 2) {
+            $output = $field['value_input'];
+          }
+  
+          //if its ONLY a constant or php defined value_type
+          if ($field['value_type'] > 1 ) {
+            //only display if the user asks, applies to value_type of php and constant ONLY
+            if ($field['display'] == 1) {
+              $contents['extra_fields'][$field['field'] . '_i'] = array(
+                '#type' => 'item',
+                '#title' => t($field['title']),
+                '#value' => $output,
+              );
+            }
+            $contents['extra_fields'][$field['field'] ] = array(
+                    '#type' => 'hidden',
+                    '#value' => $output,
+            );
+
+          }
+
+        }
+      }
+      return array('description' => $description, 'contents' => $contents, 'theme' => 'uc_extra_fields_pane');
+      
+    case 'process':
+      // initialize and fill array
+      if ($arg1->extra_fields == NULL) $arg1->extra_fields=array();
+      $arg1->extra_fields = array_merge($arg1->extra_fields, $arg2['extra_fields']);
+      return TRUE;
+      
+    case 'review':
+      $fields = uc_extra_fields_pane_load_fields_from_db($pane_type);
+      if (count($fields)) {
+        foreach ($fields as $field) {
+          //make sure if its a textbox, to show it no matter what.
+          if ($field['display'] == 1 || $fields['value_type'] == 0) {
+            $review[] = array('title' => $field['title'],
                               'data' => $arg1->extra_fields[$field['field']]  );
-					}
-				}
-			}
-			return $review;
-	}
-}
-/**
- * hook_order()
- */
-function uc_extra_fields_pane_order($op, &$arg1, $arg2) {
-	switch ($op) {
-		case 'new':
-			// do nothing, extra field cannot be handled here
-			break;
-
-		case 'save':
-			if (is_array($arg1->extra_fields) && count($arg1->extra_fields)) {
-				 
-				$fields=uc_extra_fields_pane_load_fields_from_db();
-				$sql_field_names=array();
-				$sql_field_values=array();
-				foreach ($arg1->extra_fields as $key => $value) {
-					$sql_field_names[]=$key ;
-					$sql_field_values[]=$value;
-				}
-				if (count($sql_field_values)) {
-					$sql_field_values[]=$arg1->order_id;
-					db_query("update {uc_extra_fields_values} set " . implode("='%s',", $sql_field_names) . "='%s' where order_id=%d", $sql_field_values);
-					if (!db_affected_rows()) {
-						$placeholders="";
-						for ($i=0;$i<count($sql_field_names);$i++) $placeholders .="'%s',";
-						db_query("insert into {uc_extra_fields_values}(" . implode(',', $sql_field_names) . ",order_id) values (" . $placeholders . "%d)", $sql_field_values);
-					}
-				}
-			}
-			break;
-		case 'load':
-			$arg1->extra_fields=array();
-			$values=db_fetch_array(db_query("select * from {uc_extra_fields_values} where order_id=%d", $arg1->order_id));
-			if ($values && count($values)) {
-				foreach ($values as $key => $value) {
-					if ($value && $key!='order_id' ) $arg1->extra_fields[$key]=$value;
-				}
-			}
-			break;
-	}
+          }
+        }
+      }
+      return $review;
+  }
 }
+
 /**
  * Wrapped function to load any order pane of $pane_type
+ * @param string $op
+ * @param mixed $arg1
+ * @param mixed $arg2
+ * @param string $pane_type
+ * @return mixed
  */
 function uc_extra_fields_pane_order_handler($op, $arg1, $arg2=NULL, $pane_type=NULL) {
 
-	switch ($op) {
-		case 'edit-theme':
-			$pane_fields=uc_extra_fields_pane_load_fields_from_db($pane_type);
-			$output ='';
-			if(count($pane_fields) > 0) {
-				$output = '<table class="order-edit-table">
-	                  <tr><th>' . $arg1['extra_fields']['#title'] . '</th></tr>';
-				foreach (element_children($arg1['extra_fields']) as $key=>$field) {
-					if(array_key_exists($field, $pane_fields)){
-						$title=$arg1['extra_fields'][$field]['#title'];
-						unset($arg1['extra_fields'][$field]['#title']);
-						unset($arg1['extra_fields'][$field]['#description']);
-						$output .= '<tr><td><strong>' . $title . '</strong>: ' . drupal_render($arg1['extra_fields'][$field]) . '</td></tr>';
-					}
-				}
-				$output .= '</table>';
-			}
-			return $output;
-
-		case 'edit-process':
-			$fields=uc_extra_fields_pane_load_fields_from_db();
-			$changes=array();
-			$changes['extra_fields']=array();
-
-			// dynamically generate form elements
-			if (count($fields)) {
-				foreach ($fields as $field) {
-					if (isset($arg1[$field['field'] ]))
-					$changes['extra_fields'][$field['field'] ]=$arg1[$field['field']];
-				}
-			}
-			return $changes;
+  switch ($op) {
+    case 'edit-theme':
+      $pane_fields = uc_extra_fields_pane_load_fields_from_db($pane_type);
+      $output = '';
+      if (count($pane_fields) > 0) {
+        $output = '<table class="order-edit-table">
+                    <tr><th>' . $arg1['extra_fields']['#title'] . '</th></tr>';
+        foreach (element_children($arg1['extra_fields']) as $key => $field) {
+          if (array_key_exists($field, $pane_fields)) {
+            $title = $arg1['extra_fields'][$field]['#title'];
+            unset($arg1['extra_fields'][$field]['#title']);
+            unset($arg1['extra_fields'][$field]['#description']);
+            $output .= '<tr><td><strong>' . $title . '</strong>: ' . drupal_render($arg1['extra_fields'][$field]) . '</td></tr>';
+          }
+        }
+        $output .= '</table>';
+      }
+      return $output;
+
+    case 'edit-process':
+      $fields = uc_extra_fields_pane_load_fields_from_db();
+      $changes = array();
+      $changes['extra_fields']=array();
+
+      // dynamically generate form elements
+      if (count($fields)) {
+        foreach ($fields as $field) {
+          if (isset($arg1[$field['field'] ]))
+          $changes['extra_fields'][$field['field'] ] = $arg1[$field['field']];
+        }
+      }
+      return $changes;
 
-		case 'edit-form':
-			$form['extra_fields'] = array(
+    case 'edit-form':
+      $form['extra_fields'] = array(
         '#type' => 'fieldset',
         '#title' => t('Additional order information'),
         '#collapsible' => FALSE,
         '#collapsed' => FALSE,
-			);
-			$fields=uc_extra_fields_pane_load_fields_from_db($pane_type);
-			// dynamically generate form elements
-			if (count($fields)) {
-				foreach ($fields as $field) {
-					$form['extra_fields'][$field['field'] ] = array(
+      );
+      $fields = uc_extra_fields_pane_load_fields_from_db($pane_type);
+      // dynamically generate form elements
+      if (count($fields)) {
+        foreach ($fields as $field) {
+          $form['extra_fields'][$field['field'] ] = array(
               '#type' => 'textfield',
               '#title' => $field['title'] ,
               '#description' => $field['description'],
@@ -679,78 +804,205 @@ function uc_extra_fields_pane_order_hand
               '#maxlength' => 255,
               '#required' => $field['required'],
               '#default_value' => isset($arg1->extra_fields[$field['field']]) ? $arg1->extra_fields[$field['field'] ] : NULL,
-					);
+          );
 
-				}
-			}
+        }
+      }
 
-			return $form;
-			// customer or administrator order detail page.
-		case 'customer':
-			 
-		case 'view':
-			$fields=uc_extra_fields_pane_load_fields_from_db($pane_type);
-			$output="";
-			$values=db_fetch_array(db_query("select * from {uc_extra_fields_values} where order_id=%d", $arg1->order_id));
-			$delivery_fields=array();
-
-			if (count($fields)) {
-				foreach ($fields as $field) {
-					// warning: user input --> check_plain
-					if (isset($values[$field['field']  ])){
-						//if its a customer, always show the block with all the info contained
-						if( $field['display'] == "1" || $op =='customer')
-						$delivery_fields[]=t('<strong>' .$field['title']) . '</strong>: ' . check_plain($values[$field['field'] ]) . '<br />';
-						 
-					}
-				}
-			}
-
-			if (count($delivery_fields))
-			$output .='<br />' . implode('<br />', $delivery_fields);
-			return $output;
+      return $form;
+      // customer or administrator order detail page.
+    case 'customer':
+      
+    case 'view':
+      $fields = uc_extra_fields_pane_load_fields_from_db($pane_type);
+      $output = '';
+      $values = db_fetch_array(db_query("SELECT * FROM {uc_extra_fields_values} WHERE order_id=%d", $arg1->order_id));
+      $delivery_fields=array();
+
+      if (count($fields)) {
+        foreach ($fields as $field) {
+          // warning: user input --> check_plain
+          if (isset($values[$field['field']  ])) {
+            //if its a customer, always show the block with all the info contained
+            if ($field['display'] == "1" || $op =='customer')
+            $delivery_fields[] = t('<strong>' .$field['title']) . '</strong>: ' . check_plain($values[$field['field']]) . '<br />';
+          }
+        }
+      }
+
+      if (count($delivery_fields)) {
+        $output .= '<br />' . implode('<br />', $delivery_fields);
+      }
+      return $output;
+  }
+}
+
+// -------------------------------------------------------------------
+// HELPER FUNCTIONS
+// Address fields weight
+// -------------------------------------------------------------------
 
-	}
-}
-/*
- * THEMING
- */
+// MegaChriz: function added
+/**
+ * _getDefaultAddressFieldsWeights()
+ * Get the default weight settings for the address fields.
+ *
+ * These settings will be used as a default value for variable_get('uc_address_fields_weight').
+ * Because the contents of this setting will be called on several places, a general function
+ * is used to get the default settings.
+ *
+ * If the fields don't have the #weight-attribute then the default $iWeight
+ * will be considered the weight of the field, this value will be
+ * increased for each field.
+ *
+ * @param array $fields
+ * @param string $prefix
+ * 	On some forms the field names are prefixed, for example on the checkout forms
+ *	where the fields names are prefixed with 'delivery_' and 'billing_'
+ *	The settings are saved for the fields without the prefix, so we need to load
+ *  the settings without the prefix.
+ * @access private
+ * @return array $aWeightFields
+ */
+function _uc_extra_fields_pane_getDefaultAddressFieldsWeights($fields, $prefix='') {
+  // Get all available fields for the weight
+  $aWeightFields = array();
+  $iWeight = -31;
+  foreach (element_children($fields) as $fieldname) {
+    $iWeight++;
+    
+    // Substract prefix from fieldname, we don't want the prefix
+    // saved into the default weight settings
+    $fixedfieldname = $fieldname;
+    if (strlen($prefix)) {
+      if (strpos($fieldname, $prefix) === 0) {
+        $fixedfieldname = substr($fieldname, strlen($fieldname));
+      }
+    }
+    
+    if (isset($fields[$fieldname]['#weight'])) {
+      $aWeightFields[$fixedfieldname] = $fields[$fieldname]['#weight'];
+      $iWeight = $fields[$fieldname]['#weight'];
+    }
+    else {
+      $aWeightFields[$fixedfieldname] = $iWeight;
+    }
+  }
+  return $aWeightFields;
+}
+
+// MegaChriz: function added
+/**
+ * _applyWeights()
+ * Applies ordering to address fields following the 'uc_address_fields_weight'-settings.
+ * This function is used by some form-alter functions of this module that alters address forms.
+ * @param array $form_part
+ * @param string $prefix
+ *	On the checkout-form the address fields got prefixes: 'delivery_' & 'billing_'.
+ * @access private
+ * @return void
+ */
+function _uc_extra_fields_pane_applyWeights(&$form_part, $prefix='') {
+  // Get weight settings
+  $weights = variable_get('uc_address_fields_weight', _uc_extra_fields_pane_getDefaultAddressFieldsWeights($form_part, $prefix));
+  
+  // Ubercart Addresses integration:
+  // If a field 'address_select' exists, give this field the lowest weight, so that this field appears at first
+  if (isset($form_part[$prefix . 'address_select'])) {
+    $iLowestWeight = min($weights);
+    $weights['address_select'] = $iLowestWeight -1;
+  }
+  
+  // Apply weight to fields
+  foreach ($weights as $fieldname => $weight) {
+    if (isset($form_part[$prefix . $fieldname])) {
+      $form_part[$prefix . $fieldname]['#weight'] = $weight;
+    }
+  }
+}
+
+// -------------------------------------------------------------------
+// THEMING
+// -------------------------------------------------------------------
 
 /**
  * Implementation of hook_theme().
+ * @return array
  */
 function uc_extra_fields_pane_theme() {
-	return array(
+  return array(
     'uc_extra_fields_pane' => array(
       'arguments' => array('form' => NULL),
-	),
-	);
+    ),
+    // MegaChriz: added theme function
+    'uc_extra_fields_pane_weight_uc_store_address_fields' => array(
+      'arguments' => array('form' => NULL),
+    ),
+  );
 }
 
 /**
  * Theme the extra fields forms in tables.
- *
+ * @param array $form
+ * @return string
  * @ingroup themeable
  */
 function theme_uc_extra_fields_pane($form) {
 
-	$req = '<span class="form-required">*</span>';
-	$output = '<div class="address-pane-table"><table>';
-	foreach (element_children($form['extra_fields']) as $field) {
-		$title = $form['extra_fields'][$field]['#title']  ;
-		unset($form['extra_fields'][$field]['#title']);
-		$output .= '<tr><td align="left" class="field-label">';
-		if ($form['extra_fields'][$field]['#required']) {
-			$output .= $req;
-		}
-		$output .= '<tr><td width="100"></td><td width="150"><strong>' .  $title .'</strong></td><td>'. drupal_render($form['extra_fields'][$field]) .'</td></tr>';
-	}
-	$output .= '</table></div>';
-
-	foreach (element_children($form) as $element) {
-		 
-		$output .= drupal_render($form[$element]);
-	}
+  $req = '<span class="form-required">*</span>';
+  $output = '<div class="address-pane-table"><table>';
+  foreach (element_children($form['extra_fields']) as $field) {
+    $title = $form['extra_fields'][$field]['#title']  ;
+    unset($form['extra_fields'][$field]['#title']);
+    $output .= '<tr><td align="left" class="field-label">';
+    if ($form['extra_fields'][$field]['#required']) {
+      $output .= $req;
+    }
+    $output .= '<tr><td width="100"></td><td width="150"><strong>' .  $title .'</strong></td><td>'. drupal_render($form['extra_fields'][$field]) .'</td></tr>';
+  }
+  $output .= '</table></div>';
+
+  foreach (element_children($form) as $element) {
+    $output .= drupal_render($form[$element]);
+  }
+
+  return $output;
+}
+
+// MegaChriz: function added
+/**
+ * theme_uc_extra_fields_pane_weight_address_fields()
+ * This function overrides the theme function theme_uc_store_address_fields_form() in uc_store.module
+ * Adds tabledrag and the column 'weight'
+ * @param array $form
+ * @return string
+ * @see
+ *  _uc_extra_fields_pane_weight_uc_store_address_fields_alter()
+ */
+function theme_uc_extra_fields_pane_weight_uc_store_address_fields($form) {
+  $header = array(t('Enabled'), t('Field'), t('Title'), t('Required'), array('data' => t('List position'), 'sort' => 'asc'));
+
+  foreach (element_children($form['fields']) as $field) {
+    $row = array(
+      array('data' => drupal_render($form['fields'][$field]['enabled']), 'align' => 'center'),
+      drupal_render($form['fields'][$field]['default']),
+      drupal_render($form['fields'][$field]['title']),
+      drupal_render($form['fields'][$field]['required']),
+      drupal_render($form['fields'][$field]['weight']),
+    );
+    
+    $rows[$form['fields'][$field]['#weight']] = array(
+      'data' => $row,
+      'class' => 'draggable',
+    );
+  }
+  
+  // Make sure the rows are ordered by key
+  ksort($rows);
+  
+  drupal_add_tabledrag('uc-address-fields-table', 'order', 'sibling', 'uc-address-fields-table-ordering');
 
-	return $output;
-}
+  $output = theme('table', $header, $rows, array('id' => 'uc-address-fields-table')) .'<br />'. drupal_render($form);
+
+  return $output;
+}
\ No newline at end of file
