Index: uc_extra_fields_pane.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_extra_fields_pane/Attic/uc_extra_fields_pane.admin.inc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 uc_extra_fields_pane.admin.inc
--- uc_extra_fields_pane.admin.inc	30 Jul 2010 22:04:39 -0000	1.1.2.2
+++ uc_extra_fields_pane.admin.inc	5 Aug 2010 01:56:38 -0000
@@ -1,375 +1,545 @@
 <?php
-// $Id: uc_extra_fields_pane.admin.inc,v 1.1.2.2 2010/07/30 22:04:39 panthar Exp $
+// $Id$
 /**
  * @file
- * Admin functions for adding, editing and deleting custom order fields at
+ * Admin function for adding, editing and deleting fields
+ *
+ * Form extra address fields at
+ * /admin/store/settings/checkout/edit/fields
+ * /admin/store/settings/addresfields/add
+ * /admin/store/settings/addresfields/#/edit
+ *
+ * Form custom order fields at
  * /admin/store/settings/checkout/edit/extrafields
+ * /admin/store/settings/extrafields/add
+ * /admin/store/settings/extrafields/#/edit
  */
 
-// --------------------------
-// uc_extra_fields_pane_form
-// Form for adding fields
-// Form at /admin/store/settings/checkout/edit/extrafields
-// --------------------------
+// -------------------------------------------------------------------
+// EXTRA ADDRESS FIELDS FORM
+// - uc_extra_fields_pane_addressfield_form
+// - uc_extra_fields_pane_addressfield_delete_form
+// -------------------------------------------------------------------
 
+// MegaChriz: p003: function is now getting fields from common Extra Fields API
+// MegaChriz: p003: also changed function name
 /**
- * return existent fields list and the "add new" field form
+ * Form to add/edit extra address fields
+ * Form at /admin/store/settings/addressfields/add
  * @param array $form_state
+ * @param object $field
  * @return array
- * @see
- *  uc_extra_fields_pane_form_validate()
- *  uc_extra_fields_pane_form_submit()
+ * @see uc_extra_fields_pane_addressfield_form_submit()
+ */
+function uc_extra_fields_pane_addressfield_form(&$form_state, $field=NULL) {
+  // Get default form for adding fields
+  $form = _uc_extra_fields_pane_addFieldForm($form_state, $field);
+
+  // Unset pane type field, the pane types asking is handled differently
+  unset($form['ucxf']['pane_type']);
+
+  // Unset also weight field, because the weight for address field is implemented differently
+  unset($form['ucxf']['weight']);
+
+  // Add form element to ask in which panes they need to appear
+  $form['ucxf']['panes'] = array(
+    '#title' => t('Select the panes the field must get into'),
+    '#type' => 'checkboxes',
+    '#options' => array(
+      'delivery' => t('Delivery pane'),
+      'billing' => t('Billing pane'),
+    ),
+    '#weight' => 5,
+    '#default_value' => array('delivery', 'billing'),
+  );
+  // Overwrite default value for 'panes' if the field is edited
+  if (isset($field->delivery_pane)) {
+    $aDefault = array();
+    if ($field->delivery_pane) {
+      $aDefault[] = 'delivery';
+    };
+    if ($field->billing_pane) {
+      $aDefault[] = 'billing';
+    }
+
+    $form['ucxf']['panes']['#default_value'] = $aDefault;
+  }
+
+  // Add 'cancel'-link
+  $form['ucxf']['submit']['#suffix'] = l(t('Cancel'), 'admin/store/settings/checkout/edit/fields');
+
+  // Add submit function, but remove original one because address fields are saved in an other database-table
+  $form['#submit'][] = 'uc_extra_fields_pane_addressfield_form_submit';
+  unset($form['#submit']['ucxf']);
+
+  return $form;
+}
+
+/**
+ * uc_extra_fields_pane_addressfield_form_submit()
+ * Saves address field
+ * @param array $form
+ * @param array $form_state
+ * @return void
+ * @see uc_extra_fields_pane_addressfield_form()
+ */
+function uc_extra_fields_pane_addressfield_form_submit($form, &$form_state) {
+  $field = $form_state['values']['ucxf'];
+
+  // Check if user wants field in both delivery and billing pane
+  if ($field['panes']['delivery']) {
+    $field['panes']['delivery'] = 1;
+  }
+  if ($field['panes']['billing']) {
+    $field['panes']['billing'] = 1;
+  }
+
+  if (!empty($field['fid'])) {
+    // Field already exists, send UPDATE query
+    db_query("UPDATE {uc_extra_fields_address} SET
+      label='%s',
+      description='%s',
+      required=%d,
+      value='%s',
+      value_type=%d,
+      display=%d,
+      delivery_pane=%d,
+      billing_pane=%d
+    WHERE field_id=%d", $field['label'], $field['description'], $field['required'], $field['value_input'], $field['value_type'], $field['display'], $field['panes']['delivery'], $field['panes']['billing'], $field['fid']);
+    drupal_set_message(t('Field updated'));
+  }
+  else {
+    // Field is new, send INSERT query and alter table
+    db_query("INSERT INTO {uc_extra_fields_address} (label, description, db_name, required, value, value_type, display, delivery_pane, billing_pane)
+                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['display'],
+      $field['panes']['delivery'],
+      $field['panes']['billing']
+    );
+
+    // Always add both delivery and billing columns, whether they were selected or not.
+    // In this case there is no check needed when field is edited, preventing extra complexity.
+    @db_query("ALTER TABLE {uc_extra_fields_values} ADD COLUMN `%s` VARCHAR(255)", $field['field_name'] . '_delivery');
+    @db_query("ALTER TABLE {uc_extra_fields_values} ADD COLUMN `%s` VARCHAR(255)", $field['field_name'] . '_billing');
+    drupal_set_message(t('Field saved'));
+  }
+
+  $form_state['redirect'] = 'admin/store/settings/checkout/edit/fields';
+}
+
+/**
+ * return a confirm delete form for the passed field id *
+ * Form for deleting extra address field
+ * @param array $form_state
+ * @param object $field
+ * @return array
+ * @see uc_extra_fields_pane_addressfield_delete_form_submit()
  */
-function uc_extra_fields_pane_form($form_state) {
+function uc_extra_fields_pane_addressfield_delete_form($form_state, $field) {
+  return uc_extra_fields_pane_addFieldForm_delete($form_state, $field, 'admin/store/settings/checkout/edit/fields');
+}
+
+/**
+ * uc_extra_fields_pane_field_delete_submit()
+ * Deletes field if confirmed
+ * @param array $form
+ * @param array $form_state
+ * @return void
+ * @see uc_extra_fields_pane_addressfield_delete_form()
+ */
+function uc_extra_fields_pane_addressfield_delete_form_submit($form, &$form_state) {
+  // Delete the address field
+  uc_extra_fields_pane_addressfield_delete($form_state['values']['field']);
+
+  $form_state['redirect'] = 'admin/store/settings/checkout/edit/fields';
+  drupal_set_message(t('Field deleted'));
+}
+
+// -------------------------------------------------------------------
+// CUSTOM ORDER FIELDS FORM
+// - uc_extra_fields_pane_admin
+// - uc_extra_fields_pane_customfield_form
+// - uc_extra_fields_pane_customfield_delete_form
+// -------------------------------------------------------------------
+
+// MegaChriz: p003: function added
+/**
+ * uc_extra_fields_pane_admin()
+ * Lists all custom fields
+ * @return string
+ */
+function uc_extra_fields_pane_admin() {
   $fields = uc_extra_fields_pane_load_fields_from_db();
-  $page_content .= "";
-  $form = array('#tree' => TRUE);
+  $output .= "";
+
+  $header = array();
+  $header[] = array('data' => t('Label'));
+  $header[] = array('data' => t('Field name'));
+  $header[] = array('data' => t('Pane type'));
+  $header[] = array('data' => t('Required'));
+  $header[] = array('data' => t('List position'));
+  $header[] = array('data' => t('Description'));
+  $header[] = array('data' => t('Action'));
+  $rows = array();
+
   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['label']);
+      $content[] = array('data' => $field['db_name']);
       $content[] = array('data' => $field['pane_type'] );
       $content[] = array('data' => $field['required'] );
-      $content[] = array('data' => $field['delta'] -10);
+      $content[] = array('data' => $field['weight']);
       $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')
+      $content[] = array('data' => l(t('delete'), 'admin/store/settings/extrafields/' . $field['field_id'] . '/delete') . ' | ' .
+      l(t('edit'), 'admin/store/settings/extrafields/' . $field['field_id'] . '/edit')
       );
       $rows[] = $content;
     }
-    $page_content = theme_table($headers, $rows);
-    $form['table'] = array('#value' => $page_content);
   }
-  $form['add_one_more_field']['label'] = array(
+
+  if (count($rows) == 0) {
+    $rows[] = array(
+      array('data' => t('No custom order fields have been added yet.'), 'colspan' => '7')
+    );
+  }
+
+  $output = theme('table', $header, $rows) . theme('pager', NULL, 30)
+          . l(t('Add a custom order field'), 'admin/store/settings/extrafields/add');
+
+  return $output;
+}
+
+// MegaChriz: p003: function is now getting fields from common Extra Fields API
+// MegaChriz: p003: also changed function name
+/**
+ * Form to add/edit custom order fields
+ * Form at /admin/store/settings/checkout/edit/extrafields/add
+ * @param array $form_state
+ * @param int $fid
+ * @return array
+ * @see uc_extra_fields_pane_customfield_form_submit()
+ */
+function uc_extra_fields_pane_customfield_form(&$form_state, $field=NULL) {
+  // Get default form for adding fields
+  $form = _uc_extra_fields_pane_addFieldForm($form_state, $field);
+
+  // Add 'cancel'-link
+  $form['ucxf']['submit']['#suffix'] = l(t('Cancel'), 'admin/store/settings/checkout/edit/extrafields');
+
+  // Add submit function
+  $form['#submit'][] = 'uc_extra_fields_pane_customfield_form_submit';
+
+  return $form;
+}
+
+/**
+ * uc_extra_fields_pane_customfield_form_submit()
+ * @param array $form
+ * @param array $form_state
+ * @return void
+ * @see uc_extra_fields_pane_customfield_form()
+ */
+function uc_extra_fields_pane_customfield_form_submit($form, &$form_state) {
+  $form_state['redirect'] = 'admin/store/settings/checkout/edit/extrafields';
+}
+
+/**
+ * return a confirm delete form for the passed field id *
+ * Form for deleting custom order field
+ * @param array $form_state
+ * @param object $field
+ * @return array
+ * @see uc_extra_fields_pane_customfield_delete_form_submit()
+ */
+function uc_extra_fields_pane_customfield_delete_form($form_state, $field) {
+  return uc_extra_fields_pane_addFieldForm_delete($form_state, $field, 'admin/store/settings/checkout/edit/extrafields');
+}
+
+/**
+ * uc_extra_fields_pane_field_delete_submit()
+ * Deletes field if confirmed
+ * @param array $form
+ * @param array $form_state
+ * @return void
+ * @see uc_extra_fields_pane_customfield_delete_form()
+ */
+function uc_extra_fields_pane_customfield_delete_form_submit($form, &$form_state) {
+  // Delete the custom field
+  uc_extra_fields_pane_customfield_delete($form_state['values']['field']);
+
+  $form_state['redirect'] = 'admin/store/settings/checkout/edit/extrafields';
+  drupal_set_message(t('Field deleted'));
+}
+
+// -------------------------------------------------------------------
+// EXTRA FIELDS API (adding fields)
+// API functions for adding fields
+// Note: This may be replaced by webform integration in the future
+// -------------------------------------------------------------------
+
+// MegaChriz: p003: function added
+// MegaChriz: p003: changed array name 'add_one_more_field' into 'ucxf'
+/**
+ * _addFieldForm()
+ * @param array $form_state
+ * @param int $fid
+ * @access private
+ * @return array $form
+ * @see
+ *   uc_extra_fields_pane_addFieldForm_validate()
+ *   uc_extra_fields_pane_addFieldForm_submit()
+ */
+function _uc_extra_fields_pane_addFieldForm($form_state, $field=NULL) {
+  $form = array('#tree' => TRUE);
+
+  if (empty($field)) {
+    $field = new stdClass();
+  }
+  else {
+    $form['ucxf']['fid'] = array('#type' => 'hidden', '#value' => $field->field_id);
+    drupal_set_title(t('Modify field: %name', array('%name' => $field->db_name)));
+  }
+
+  $form['ucxf']['label'] = array(
     '#title' => t('Label'),
     '#type' => 'textfield',
     '#size' => 15,
     '#description' => t('Label shown to customers in checkout pages.'),
+    '#required' => TRUE,
+    '#default_value' => $field->label,
+    '#weight' => 0,
   );
-  $form['add_one_more_field']['field_name'] = array(
+  // MegaChriz: p003: marked this field as required
+  $form['ucxf']['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.'),
+    '#description' => t('Database field name. It must contain only lower chars a-z, digits 0-9 and _. Max allowed length is 23 characters.'),
+    '#required' => TRUE,
+    '#default_value' => $field->db_name,
+    '#weight' => 1,
   );
-  $form['add_one_more_field']['description'] = array(
+  if (isset($field->field_id)) {
+    // if field already exists, don't allow to alter the name
+    $form['ucxf']['field_name']['#disabled'] = 'disabled';
+    $form['ucxf']['field_name']['#value'] = $field->db_name;
+  }
+  $form['ucxf']['description'] = array(
     '#title' => t('Description'),
     '#type' => 'textarea',
     '#rows' => 3,
-    '#description' => t('Insert a description to tell customers how to fill this field.'),
+    '#description' => t('Insert a description to tell customers how to fill this field. ONLY applies for select/textbox options'),
+    '#default_value' => $field->description,
+    '#weight' => 3,
   );
-  $form['add_one_more_field']['delta'] = array(
+
+  // MegaChriz: p003: changed type from select to weight, also changed fieldname from delta to weight.
+  $form['ucxf']['weight'] = 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,
+    '#type' => 'weight',
+    '#delta' => 30,
+    '#default_value' => isset($field->weight)? $field->weight:0,
     '#description' => t('The listing position '),
+    '#weight' => 5,
   );
-  $form['add_one_more_field']['pane_type'] = array(
+  $form['ucxf']['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('extra_information' => t('Extra Information pane')),
+    '#default_value' => $field->pane_type,
+    '#weight' => 7,
   );
 
-  $options = array(
+  $value_type_options = array(
     UCXF_WIDGET_TYPE_TEXTFIELD => t('Let the user input the data in a textbox. If you want a default value, put it in "value" field below.'),
     UCXF_WIDGET_TYPE_SELECT => t('Let the user select from a list of options (enter one name|value per line).'),
     UCXF_WIDGET_TYPE_CHECKBOXES => t('Let the user select from checkboxes (enter one name|value per line).'),
     UCXF_WIDGET_TYPE_CONSTANT => t('Show a admin defined constant value, insert the value int he "value" section.'),
     UCXF_WIDGET_TYPE_PHP => t('Set the value to the php code that returns a <code>STRING</code> (PHP-mode, experts only).'),
-	UCXF_WIDGET_TYPE_PHP_SELECT => t('Let the user select from a list of options from php code returning a <code>ARRAY</code> of key => value pairs. ie- <code>return array(\'element1\' => \'somevalue1\',\'element2\' => \'somevalue2\')</code> (PHP-mode, experts only).'),
-    UCXF_WIDGET_TYPE_PHP_CHECKBOX => t('Let the user select checkboxes from a list of options from php code returning a <code>ARRAY</code> of key => value pairs. ie- <code>return array(\'element1\' => \'somevalue1\',\'element2\' => \'somevalue2\')</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 ?>'));
+    UCXF_WIDGET_TYPE_PHP_SELECT => t('Let the user select from a list of options from php code returning a <code>ARRAY</code> of key => value pairs. ie- <code>return array(\'element1\' => \'somevalue1\',\'element2\' => \'somevalue2\')</code> (PHP-mode, experts only).'),
+    UCXF_WIDGET_TYPE_PHP_CHECKBOXES => t('Let the user select checkboxes from a list of options from php code returning a <code>ARRAY</code> of key => value pairs. ie- <code>return array(\'element1\' => \'somevalue1\',\'element2\' => \'somevalue2\')</code> (PHP-mode, experts only).'),
+  );
 
-  $form['add_one_more_field']['value_type'] = array(
+  $form['ucxf']['value_type'] = array(
     '#type' => 'radios',
-    '#title' => t('Define where the  value comes from'),
-    '#options' => $options,
-    '#default_value' => 0,
+    '#title' => t('Define Value'),
+    '#options' => $value_type_options,
+    '#default_value' => isset($field->value_type)? $field->value_type:UCXF_WIDGET_TYPE_TEXTFIELD,
+    '#weight' => 9,
   );
-  $form['add_one_more_field']['value_input'] = array(
+  $form['ucxf']['value_input'] = array(
     '#type' => 'textarea',
     '#title' => t('Value'),
-    '#description' => $description,
+    '#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 ?>')),
+    '#default_value' => $field->value,
+    '#weight' => 10,
   );
-  $form['add_one_more_field']['display'] = array(
+  $form['ucxf']['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,
+    '#default_value' => isset($field->display)? $field->display:1,
+    '#weight' => 12,
   );
-  $form['add_one_more_field']['required'] = array(
+  $form['ucxf']['required'] = array(
     '#title' => t('Field required'),
     '#type' => 'checkbox',
-    '#description' => t('Check this item is field is mandatory.'),
+    '#description' => t('Check this item if the field is mandatory.'),
+    '#default_value' => $field->required,
+    '#weight' => 14,
   );
-  $form['add_one_more_field']['submit'] = array(
+  $form['ucxf']['submit'] = array(
     '#type' => 'submit',
-    '#value' => t('Save')
+    '#value' => t('Save'),
+    '#weight' => 50,
   );
+
+  $form['#validate']['ucxf'] = 'uc_extra_fields_pane_addFieldForm_validate';
+  $form['#submit']['ucxf'] = 'uc_extra_fields_pane_addFieldForm_submit';
+
+  // MegaChriz: p003: there could be a hook introduced here so extra field types can added easier,
+  // but this won't be needed if the module is going to make use of webforms-functionality
+
   return $form;
 }
 
-// MegaChriz: changed form_set_error() lines. They were sometimes pointing to the wrong field.
+// MegaChriz: p003: function added
+// MegaChriz: p003: changed array name 'add_one_more_field' into 'extra_fields'
 /**
  * uc_extra_fields_pane_form form validation (called after new field insert)
  * @param array $form
  * @param array $form_state
  * @return void
  * @see
- *  uc_extra_fields_pane_form()
- *  uc_extra_fields_pane_form_submit()
+ *  uc_extra_fields_pane_addFieldForm()
+ *  uc_extra_fields_pane_addFieldForm_submit()
  */
-function uc_extra_fields_pane_form_validate($form, &$form_state) {
-  $field=$form_state['values']['add_one_more_field'];
+function uc_extra_fields_pane_addFieldForm_validate($form, &$form_state) {
+  $field = $form_state['values']['ucxf'];
+
   // No label.
   if (!$field['label']) {
-    form_set_error('add_one_more_field][label', t('Add new field: you need to provide a label.'));
+    form_set_error('label', t('Custom order 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.'));
+    form_set_error('field_name', t('Custom order field: you need to provide a field name.'));
   }
-  if (!$field['delta']) {
-    form_set_error('add_one_more_field][delta', t('Add new field: you need to provide a delta value for this extra field.'));
+  if (isset($form['ucxf']['weight']) && !$field['weight'] && $field['weight'] !==0 && $field['weight'] !=='0') {
+    form_set_error('ucxf][weight', t('Custom order field: you need to provide a weight value for this extra field.'));
   }
-  if (!$field['pane_type']) {
-    form_set_error('add_one_more_field][pane_type', t('Add new field: you need to provide a pane-type for this extra field.'));
+  if (isset($form['ucxf']['pane_type']) && empty($field['pane_type'])) {
+    form_set_error('ucxf][pane_type', t('Custom order field: you need to provide a pane-type for this extra field.'));
   }
-  if (!$field['value_type'] && $field['value_type'] !== UCXF_WIDGET_TYPE_TEXTFIELD) {
-    form_set_error('add_one_more_field][value_type', t('Add new field: you need to provide a way of processing the value for this field as either textbox, select, constant, or php.'));
+  // MegaChriz: p003: changed error string, added 'checkboxes'.
+  if (!$field['value_type']) {
+    form_set_error('ucxf][value_type', t('Custom order field: you need to provide a way of processing the value for this field as either textbox, select, checkboxes, constant, or php.'));
   }
   if (($field['value_type'] == UCXF_WIDGET_TYPE_CONSTANT || $field['value_type'] == UCXF_WIDGET_TYPE_PHP) && !$field['value_input'] ) {
-    form_set_error('add_one_more_field][value_input', t('Add new field: you need to provide a value for this way of calculating the field value.'));
+    form_set_error('ucxf][value_input', t('Custom order field: you need to provide a value for this way of calculating the field value.'));
   }
 
   // Field name validation.
-  else {
+  if (empty($field['fid'])) {
     $field_name = $field['field_name'];
-    // Add the 'uc_extra_' prefix.
-    if (substr($field_name, 0, 8) != 'uc_extra_') {
+    // MegaChriz: p003: changed validation rule
+    // Add the 'ucxf_' prefix.
+    if (strpos($field_name, 'ucxf_') !== 0) {
       $field_name = 'ucxf_'. $field_name;
-      form_set_value($form['add_one_more_field']['field_name'], $field_name, $form_state);
+      form_set_value($form['ucxf']['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)));
+      form_set_error('ucxf][field_name', t('Custom order 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)
+    // considering prefix ucxf_ 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)));
+      form_set_error('ucxf][field_name', t('Custom order 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));
+    // Check if field name already exists in both address and information tables
+    $count = db_result(db_query("SELECT count(*) FROM {uc_extra_fields} WHERE db_name='%s'", $field_name));
+    $count += db_result(db_query("SELECT count(*) FROM {uc_extra_fields_address} WHERE 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)));
+      form_set_error('ucxf][field_name', t('Custom order 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
+ * uc_extra_fields_pane_addFieldForm_submit()
+ * If the field is new, a new row will inserted and the table 'uc_extra_fields_values' will get a new row
+ * If the field already exists, only the field information gets updated
  * @param array $form
  * @param array $form_state
  * @return void
+ * @see uc_extra_fields_pane_addFieldForm()
  */
-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'));
-}
-
-// --------------------------
-// uc_extra_fields_pane_field_delete
-// Form for deleting fields
-// --------------------------
+function uc_extra_fields_pane_addFieldForm_submit($form, &$form_state) {
+  $field = $form_state['values']['ucxf'];
+
+  if (!empty($field['fid'])) {
+    // Field already exists, send UPDATE query
+    db_query("UPDATE {uc_extra_fields} SET
+      label='%s',
+      description='%s',
+      required=%d,
+      value='%s',
+      value_type=%d,
+      weight=%d,
+      display=%d,
+      pane_type='%s'
+    WHERE field_id=%d", $field['label'], $field['description'], $field['required'], $field['value_input'], $field['value_type'], $field['weight'], $field['display'], $field['pane_type'], $field['fid']);
+    drupal_set_message(t('Field updated'));
+  }
+  else {
+    // Field is new, send INSERT query and alter table
+    db_query("INSERT INTO {uc_extra_fields} (label, description, db_name, required, value, value_type, weight, display, 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['weight'],
+      $field['display'],
+      $field['pane_type']
+    );
+    db_query("ALTER TABLE {uc_extra_fields_values} ADD COLUMN `%s` VARCHAR(255)", $field['field_name']);
+    drupal_set_message(t('Field saved'));
+  }
+}
 
 /**
  * return a confirm delete form for the passed field id *
  * @param array $form_state
- * @param string $fid
+ * @param object $field
+ * @param string $returnpath
+ *   The path to return to when deleting is canceled.
  * @return array
- * @see
- *	uc_extra_fields_pane_field_delete_submit()
  */
-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;
-      }
-    }
+function uc_extra_fields_pane_addFieldForm_delete($form_state, $field, $returnpath) {
+  if (!$field->field_id) {
+    return;
   }
+
   return confirm_form(
   array(
       'field' => array(
         '#type' => 'value',
-        '#value' => $fid,
+        '#value' => $field->field_id,
   ),
   ),
-  t('Are you sure you want to remove the field "%field"?', array('%field' => $field_name)),
-    'admin/store/settings/checkout/edit/extrafields',
+  t('Are you sure you want to remove the field "%field"?', array('%field' => $field->db_name)),
+    $returnpath,
   t('This action cannot be undone.'),
   t('Remove'),
   t('Cancel')
   );
-}
-
-/**
- * uc_extra_fields_pane_field_delete_submit()
- * Deletes field if confirmed
- * @param array $form
- * @param array $form_state
- * @return void
- */
-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'));
-}
-
-// --------------------------
-// uc_extra_fields_pane_field_edit
-// Form for editing fields
-// --------------------------
-
-/**
- * Edit admin form for the extra fields
- * @param array $form_state
- * @param string $fid
- * @return array
- * @see
- *   uc_extra_fields_pane_field_edit_submit()
- */
-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 '),
-  );
-  // MegaChriz: added default value
-  $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')),
-    '#default_value' => $field['pane_type'],
-  );
- $options = array(
-    UCXF_WIDGET_TYPE_TEXTFIELD => t('Let the user input the data in a textbox. If you want a default value, put it in "value" field below.'),
-    UCXF_WIDGET_TYPE_SELECT => t('Let the user select from a list of options (enter one name|value per line).'),
-    UCXF_WIDGET_TYPE_CHECKBOXES => t('Let the user select from checkboxes (enter one name|value per line).'),
-    UCXF_WIDGET_TYPE_CONSTANT => t('Show a admin defined constant value, insert the value int he "value" section.'),
-    UCXF_WIDGET_TYPE_PHP => t('Set the value to the php code that returns a <code>STRING</code> (PHP-mode, experts only).'),
-	UCXF_WIDGET_TYPE_PHP_SELECT => t('Let the user select from a list of options from php code returning a <code>ARRAY</code> of key => value pairs. ie- <code>return array(\'element1\' => \'somevalue1\',\'element2\' => \'somevalue2\')</code> (PHP-mode, experts only).'),
-    UCXF_WIDGET_TYPE_PHP_CHECKBOX => t('Let the user select checkboxes from a list of options from php code returning a <code>ARRAY</code> of key => value pairs. ie- <code>return array(\'element1\' => \'somevalue1\',\'element2\' => \'somevalue2\')</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;
-}
-
-/**
- * uc_extra_fields_pane_field_edit_submit()
- * @param array $form
- * @param array $form_state
- * @return void
- * @see
- *   uc_extra_fields_pane_field_edit()
- */
-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';
 }
\ No newline at end of file
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.2
diff -u -r1.1.4.2 uc_extra_fields_pane.install
--- uc_extra_fields_pane.install	30 Jul 2010 16:00:51 -0000	1.1.4.2
+++ uc_extra_fields_pane.install	5 Aug 2010 01:56:39 -0000
@@ -34,61 +34,136 @@
   );
 
   $schema['uc_extra_fields'] = array(
+    'description' => t('Custom order fields are stored in this table.'),
     'fields' => array(
       'field_id' => array(
         'type' => 'serial',
         'unsigned' => TRUE,
         'not null' => TRUE,
       ),
-      'field_name' => array(
+      // MegaChriz: p003: changed.
+      'label' => array(
         'type' => 'varchar',
-        'length' => 100,
+        'length' => '100',
         'not null' => TRUE,
       ),
-      'field_description' => array(
+      'description' => array(
         'type' => 'text',
       ),
-      'field_db_name' => array(
+      'db_name' => array(
         'type' => 'varchar',
-        'length' => 20,
+        'length' => '20',
         'not null' => TRUE,
       ),
-      'field_pane_type' => array(
+      'pane_type' => array(
+        'description' => t('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.'),
         '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',
+        'not null' => FALSE,
       ),
-      'field_delta' => array(
+      // MegaChriz: p003: changed. 'weight' is a better name then 'delta'
+      'weight' => array(
+        'description' => t('The list position of this field on the pane selected for this field.'),
         'type' => 'int',
-        'length' => 10,
-        'description' => 'The delta position of this field on the pane selected for this field.',
+        'not null' => FALSE,
       ),
-      'field_value_type' => array(
+      'value_type' => array(
+        'description' => t('The type of input to the field_value database field.'),
         'type' => 'int',
-        'length' => 10,
-        'description' => 'The type of input to the field_value database field.',
+        'size' => 'small',
+        'not null' => FALSE,
       ),
-       'field_value' => array(
+      'value' => array(
+        'description' => t('A blob that can be used to store anything from php code, to constant values, to select values'),
         'type' => 'blob',
-        'description' => 'A blob that can be used to store anything from php code, to constant values, to select values',
+        'not null' => FALSE,
       ),
-      'field_display' => array(
+      'display' => array(
         'type' => 'int',
         'size' => 'tiny',
         'not null' => TRUE,
         'default' => 0,
       ),
-      'field_required' => array(
+      'required' => array(
+        'description' => t('Only applies if you select a textbox'),
         'type' => 'int',
         'size' => 'tiny',
-        'description' => 'Only applies if you select a textbox',
         'not null' => TRUE,
         'default' => 0,
       ),
     ),
     'primary key' => array('field_id'),
     'unique keys' => array(
-      'field_db_name' => array('field_db_name'),
+      'db_name' => array('db_name')
+    ),
+  );
+
+  $schema['uc_extra_fields_address'] = array(
+    'description' => t('Address fields are stored in this table.'),
+    'fields' => array(
+      'field_id' => array(
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'label' => array(
+        'type' => 'varchar',
+        'length' => '100',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'type' => 'text',
+      ),
+      'db_name' => array(
+        'type' => 'varchar',
+        'length' => '20',
+        'not null' => TRUE,
+      ),
+      'value_type' => array(
+        'description' => t('The type of input to the field_value database field.'),
+        'type' => 'int',
+        'size' => 'small',
+        'not null' => FALSE,
+      ),
+      'value' => array(
+        'description' => t('A blob that can be used to store anything from php code, to constant values, to select values'),
+        'type' => 'blob',
+        'not null' => FALSE,
+      ),
+      'enabled' => array(
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 1,
+      ),
+      'display' => array(
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+      ),
+      'required' => array(
+        'description' => t('Only applies if you select a textbox'),
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'delivery_pane' => array(
+        'description' => t('Whether the field should appear in the delivery pane'),
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+      ),
+      'billing_pane' => array(
+        'description' => t('Whether the field should appear in the billing pane'),
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+      ),
+    ),
+    'primary key' => array('field_id'),
+    'unique keys' => array(
+      'db_name' => array('db_name')
     ),
   );
 
@@ -109,6 +184,7 @@
  */
 function uc_extra_fields_pane_uninstall() {
   drupal_uninstall_schema('uc_extra_fields_pane');
+  variable_del('uc_address_fields_weight');
 }
 
 /**
@@ -128,4 +204,200 @@
   $ret = array();
   $ret[] = update_sql("UPDATE {uc_extra_fields} SET field_value_type = 5 WHERE field_value_type = 0");
   return $ret;
+}
+
+// MegaChriz: p003: function added !need to implement!
+/**
+ * Changed field 'delta' to 'weight', also changes length of field_value_type and field_weight
+ */
+function uc_extra_fields_pane_update_6202() {
+  $ret = array();
+
+  // ------------------------------------------------
+  // Rename fields
+  // ------------------------------------------------
+  db_change_field($ret, 'uc_extra_fields', 'field_name', 'label', array(
+      'type' => 'varchar',
+      'length' => '100',
+      'not null' => TRUE,
+    )
+  );
+
+  db_change_field($ret, 'uc_extra_fields', 'field_description', 'description', array(
+      'type' => 'text',
+    )
+  );
+  db_change_field($ret, 'uc_extra_fields', 'field_db_name', 'db_name', array(
+      'type' => 'varchar',
+      'length' => '20',
+      'not null' => TRUE,
+    )
+  );
+  db_change_field($ret, 'uc_extra_fields', 'field_pane_type', 'pane_type', array(
+      'description' => t('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.'),
+      'type' => 'varchar',
+      'length' => '20',
+      'not null' => FALSE,
+    )
+  );
+  db_change_field($ret, 'uc_extra_fields', 'field_delta', 'weight', array(
+      'description' => t('The list position of this field on the pane selected for this field.'),
+      'type' => 'int',
+      'not null' => FALSE,
+    )
+  );
+  db_change_field($ret, 'uc_extra_fields', 'field_value_type', 'value_type', array(
+      'description' => t('The type of input to the field_value database field.'),
+      'type' => 'int',
+      'size' => 'small',
+      'not null' => FALSE,
+    )
+  );
+  db_change_field($ret, 'uc_extra_fields', 'field_value', 'value', array(
+      'description' => t('A blob that can be used to store anything from php code, to constant values, to select values'),
+      'type' => 'blob',
+      'not null' => FALSE,
+    )
+  );
+  db_change_field($ret, 'uc_extra_fields', 'field_display', 'display', array(
+      'type' => 'int',
+      'size' => 'tiny',
+      'not null' => TRUE,
+      'default' => 0,
+    )
+  );
+  db_change_field($ret, 'uc_extra_fields', 'field_required', 'required', array(
+      'description' => t('Only applies if you select a textbox'),
+      'type' => 'int',
+      'size' => 'tiny',
+      'not null' => TRUE,
+      'default' => 0,
+    )
+  );
+
+  // ------------------------------------------------
+  // Add table 'uc_extra_fields_address'
+  // ------------------------------------------------
+  $schema['uc_extra_fields_address'] = array(
+    'description' => t('Address fields are stored in this table.'),
+    'fields' => array(
+      'field_id' => array(
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'label' => array(
+        'type' => 'varchar',
+        'length' => '100',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'type' => 'text',
+      ),
+      'db_name' => array(
+        'type' => 'varchar',
+        'length' => '20',
+        'not null' => TRUE,
+      ),
+      'value_type' => array(
+        'description' => t('The type of input to the field_value database field.'),
+        'type' => 'int',
+        'size' => 'small',
+        'not null' => FALSE,
+      ),
+      'value' => array(
+        'description' => t('A blob that can be used to store anything from php code, to constant values, to select values'),
+        'type' => 'blob',
+        'not null' => FALSE,
+      ),
+      'enabled' => array(
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 1,
+      ),
+      'display' => array(
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+      ),
+      'required' => array(
+        'description' => t('Only applies if you select a textbox'),
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'delivery_pane' => array(
+        'description' => t('Whether the field should appear in the delivery pane'),
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+      ),
+      'billing_pane' => array(
+        'description' => t('Whether the field should appear in the billing pane'),
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+      ),
+    ),
+    'primary key' => array('field_id'),
+    'unique keys' => array(
+      'db_name' => array('db_name')
+    ),
+  );
+  db_create_table($ret, 'uc_extra_fields_address', $schema['uc_extra_fields_address']);
+
+  // ------------------------------------------------
+  // Move address fields to uc_extra_fields_address table and alter uc_extra_fields_values table
+  // ------------------------------------------------
+  $to_move = array('delivery', 'billing');
+
+  foreach ($to_move as $addresstype) {
+    // Get all fields from delivery or billing
+    $result = db_query("SELECT * FROM {uc_extra_fields} WHERE pane_type='%s'", 'extra_' . $addresstype);
+
+    while ($row = db_fetch_array($result)) {
+      // Insert in address table
+      $row['delivery'] = ($addresstype == 'delivery')? 1:0;
+      $row['billing'] = ($addresstype == 'billing')? 1:0;
+
+      $ret[] = update_sql(
+        "INSERT INTO {uc_extra_fields_address} (label, description, db_name, required, value, value_type, display, delivery_pane, billing_pane)
+        VALUES (
+          '" . $row['label'] . "',
+          '" . $row['description'] . "',
+          '" . $row['db_name'] . "',
+          " . $row['required'] . ",
+          '" . $row['value'] . "',
+          " . $row['value_type'] . ",
+          " . $row['display'] . ",
+          " . $row['delivery'] . ",
+          " . $row['billing'] . "
+        )"
+      );
+
+      // Alter columns in uc_extra_fields_values
+      db_change_field($ret, 'uc_extra_fields_values', $row['db_name'], $row['db_name'] . '_' . $addresstype, array(
+          'type' => 'varchar',
+          'length' => '255',
+          'not null' => FALSE,
+        )
+      );
+
+      // Add 'missing' column
+      $other_addresstype = ($addresstype == 'delivery')? 'billing':'delivery';
+      db_add_field($ret, 'uc_extra_fields_values', $row['db_name'] . '_' . $other_addresstype, array(
+          'type' => 'varchar',
+          'length' => '255',
+          'not null' => FALSE,
+        )
+      );
+    }
+
+    // Remove from original table
+    $ret[] = update_sql("DELETE FROM {uc_extra_fields} WHERE pane_type='extra_" . $addresstype . "'");
+  }
+
+  return $ret;
 }
\ No newline at end of file
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.3
diff -u -r1.1.4.3 uc_extra_fields_pane.module
--- uc_extra_fields_pane.module	30 Jul 2010 22:04:39 -0000	1.1.4.3
+++ uc_extra_fields_pane.module	5 Aug 2010 03:46:08 -0000
@@ -15,9 +15,46 @@
  */
 
 /**
+ **********************************************
+ * TABLE OF CONTENTS
+ **********************************************
+ * - DRUPAL HOOKS
+ *   implementations of hook_enable(), hook_menu() and hook_form_alter()
+ *
+ * - UBERCART HOOKS
+ *   implementations of hook_checkout_pane(), hook_order() and hook_checkout_pane_alter()
+ *
+ * - TOKEN HOOKS
+ *   uc_extra_fields_pane_token_values(), uc_extra_fields_pane_token_list().
+ *
+ * - DATABASE REQUREST
+ *   functions to load and delete address fields and custom order fields
+ *   function to load fields from a particular pane type
+ *
+ * - FORM ALTERS (address fields weight)
+ *   functions for the 'order address fields'-feature
+ *
+ * - FORM ALTERS (extra address fields)
+ *   functions for the 'extra address fields'-feature
+ *
+ * - EXTRA FIELDS PANE API (pane types loading)
+ *   functions for loading pane types for custom order fields
+ *
+ * - CREATE FIELD API
+ *   functions for generating fields
+ *
+ * - HELPER FUNCTIONS
+ *   currently this contains only functions for the 'order address fields'-feature
+ *
+ * - THEMING
+ *   functions using the Drupal theme layer
+ **********************************************
+ */
+
+/**
  * MegaChriz:
  * Overview made changes:
- * - added 'order addresses'-functionallity
+ * - added 'order addresses'-functionality
  * - 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)
@@ -35,21 +72,32 @@
  * - Code standards review (coder).
  */
 
- /**
+/**
+ * MegaChriz: p003:
+ * Overview made changes:
+ * - moved address fields adding to 'Address fields'-page
+ * - changed admin interface
+ * - introduced common API function for field forms (add/edit/delete)
+ * - introduced API function to generate fields (this will be needed later when uc_addresses integration is being implemented)
+ * - completely changed database tables. Address fields are now handled differently than custom order fields.
+ * - an address field now comes in both panes by default
+ * - fixed 'my billing information is the same as my delivery information' (actually, this was automatically fixed when address fields came in both panes)
+ */
+
+/**
  * @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'
+ * - views integration ->panthar
+ * - fix 'saved addresses' drop down
  * - 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
+ * - get the extra address information also in original order panes -> MegaChriz
  * - checkboxes do not display properly on the order-review or order-view pages
+ * - write an upgrade script for 1.x to 2.x
+ * - improve order pane handling
  *
  * KNOWN BUGS
- * - adding an address field results in a white page at /cart/checkout when uc_addresses is enabled
+ * - checkboxes is not functioning yet
+ * - edit order form (/admin/store/orders/#/edit) not working properly
  */
 
 define('UCXF_WIDGET_TYPE_SELECT', 1);
@@ -64,7 +112,6 @@
 // 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)
@@ -82,35 +129,74 @@
   db_query("UPDATE {system} SET weight = %d WHERE name = 'uc_extra_fields_pane' AND type = 'module'", $iWeight);
 }
 
+// MegaChriz: p003: changed function. Extra address fields now will be added on 'Address field'-page.
 /**
  * Implementation of hook_menu().
  * @return array
  */
 function uc_extra_fields_pane_menu() {
+  // Extra address fields
+  $items['admin/store/settings/addressfields/add'] = array(
+    'title' => 'Add an address field',
+    'description' => 'Add extra address fields.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('uc_extra_fields_pane_addressfield_form'),
+    'access arguments' => array('administer store'),
+    'type' => MENU_CALLBACK,
+    'file' => 'uc_extra_fields_pane.admin.inc',
+  );
+  $items['admin/store/settings/addressfields/%uc_extra_fields_pane_addressfield/delete'] = array(
+    'title' => 'Delete address field',
+    'description' => 'Delete an address field.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('uc_extra_fields_pane_addressfield_delete_form', 4),
+    'access arguments' => array('administer store'),
+    'type' => MENU_CALLBACK,
+    'file' => 'uc_extra_fields_pane.admin.inc',
+  );
+  $items['admin/store/settings/addressfields/%uc_extra_fields_pane_addressfield/edit'] = array(
+    'title' => 'Modify address field',
+    'description' => 'Edit an address field.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('uc_extra_fields_pane_addressfield_form', 4),
+    'access arguments' => array('administer store'),
+    'type' => MENU_CALLBACK,
+    'file' => 'uc_extra_fields_pane.admin.inc',
+  );
+
+  // Custom order fields
   $items['admin/store/settings/checkout/edit/extrafields'] = array(
     'title' => 'Custom order fields',
-    'description' => 'Add more custom order fields.',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('uc_extra_fields_pane_form'),
+    'description' => 'Create and edit custom order fields.',
+    'page callback' => 'uc_extra_fields_pane_admin',
     'access arguments' => array('administer store'),
     'type' => MENU_LOCAL_TASK,
     'weight' => 5,
     'file' => 'uc_extra_fields_pane.admin.inc',
   );
-  $items['admin/store/settings/extrafields/%/delete'] = array(
-    'title' => 'Delete custom field',
+  $items['admin/store/settings/extrafields/add'] = array(
+    'title' => 'Add custom order field',
+    'description' => 'Add custom order fields.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('uc_extra_fields_pane_customfield_form'),
+    'access arguments' => array('administer store'),
+    'type' => MENU_CALLBACK,
+    'file' => 'uc_extra_fields_pane.admin.inc',
+  );
+  $items['admin/store/settings/extrafields/%uc_extra_fields_pane_customfield/delete'] = array(
+    'title' => 'Delete custom order field',
     'description' => 'Delete a custom field.',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('uc_extra_fields_pane_field_delete', 4),
+    'page arguments' => array('uc_extra_fields_pane_customfield_delete_form', 4),
     'access arguments' => array('administer store'),
     'type' => MENU_CALLBACK,
     'file' => 'uc_extra_fields_pane.admin.inc',
   );
-  $items['admin/store/settings/extrafields/%/edit'] = array(
+  $items['admin/store/settings/extrafields/%uc_extra_fields_pane_customfield/edit'] = array(
     'title' => 'Modify field',
-    'description' => 'Edit custom field.',
+    'description' => 'Edit custom order field.',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('uc_extra_fields_pane_field_edit', 4),
+    'page arguments' => array('uc_extra_fields_pane_customfield_form', 4),
     'access arguments' => array('administer store'),
     'type' => MENU_CALLBACK,
     'file' => 'uc_extra_fields_pane.admin.inc',
@@ -119,7 +205,6 @@
   return $items;
 }
 
-// MegaChriz: function added
 /**
  * Implementation of hook_form_alter().
  * @param array $form
@@ -136,6 +221,10 @@
 
       // add the possibility to order the address fields.
       _uc_extra_fields_pane_weight_uc_store_address_fields_alter($form, $form_state);
+
+      // Add our theme function to the form, so that function can add draggable rows functionality
+      // and also the delete/edit-actions
+      $form['#theme'][] = 'uc_extra_fields_pane_uc_store_address_fields';
       break;
 
     // The checkout form is altered by an implementation of hook_form_FORM_ID_alter().
@@ -175,24 +264,6 @@
     'desc' => t('Extra order information'),
     'weight' => 0,
   );
-  // 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(
-    'id' => 'extra_billing',
-    'callback' => 'uc_extra_fields_pane_billing',
-    'title' => t('Extra Billing Information'),
-    'desc' => t('Extra Billing Information'),
-    'weight' => 2,
-  );
-  */
-
   return $panes;
 }
 
@@ -212,7 +283,6 @@
     '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',
@@ -250,7 +320,6 @@
 
     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) {
@@ -280,8 +349,39 @@
       break;
   }
 }
-
-// MegaChriz: function added
+/**
+ * Implementation of hook_token_list().   
+ */
+function uc_extra_fields_pane_token_list($type = 'all') {
+  $tokens = array();
+  if ($type == 'order' || $type == 'ubercart' || $type == 'all') {
+      
+      $results=db_query("select pane_type, db_name from {uc_extra_fields}");
+      while ($result=db_fetch_array($results)) {
+        $tokens['order']['extra-'. $result['pane_type'] . '-' . str_replace('ucxf_', '', $result['db_name'])]=
+        t(variable_get('uc_extra_fields_pane_'. $result['pane_type'] . '_title', 'Additional ' . ucwords($result['pane_type']) . ' information for field')) . ': ' . t(str_replace('ucxf_', '', $result['db_name']));
+        }
+  }
+  return $tokens;
+}
+/**
+ * Implementation of hook_token_values().   
+ */
+function uc_extra_fields_pane_token_values($type, $object = NULL) {
+  $values = array();
+  switch ($type) {
+    case 'order':
+      $order = $object;     
+      $results=db_query("select db_name, pane_type from {uc_extra_fields}");
+      while ($result=db_fetch_array($results)) {
+        $values['extra-' . $result['pane_type'] . '-' . str_replace('ucxf_', '', $result['db_name'])]=
+        (isset($order->extra_fields[$result['db_name'] . '_' . $result['pane_type']])?$order->extra_fields[$result['db_name'] . $result['pane_type']]:'');
+            }
+      
+      break;
+  }
+  return $values;
+}
 /**
  * Implementation of hook_checkout_pane_alter().
  * Alters delivery and billing pane
@@ -308,6 +408,124 @@
 // MegaChriz: These hook implementations will be added by panthar
 
 // -------------------------------------------------------------------
+// DATABASE REQUESTS
+// - load/delete address field
+// - load/delete custom order field
+// - load fields from particular pane type
+// -------------------------------------------------------------------
+
+// MegaChriz: p003: function added
+/**
+ * Implementation of hook_load().
+ * @param int $fid
+ * @return object
+ */
+function uc_extra_fields_pane_addressfield_load($fid) {
+  return db_fetch_object(db_query("SELECT * FROM {uc_extra_fields_address} WHERE field_id = %d", $fid));
+}
+
+// MegaChriz: p003: function added
+/**
+ * addressfield_delete()
+ * Deletes field
+ * @param int $fid
+ * @return boolean
+ */
+function uc_extra_fields_pane_addressfield_delete($fid) {
+  $field = uc_extra_fields_pane_addressfield_load($fid);
+
+  if (!empty($field)) {
+    db_query("DELETE FROM {uc_extra_fields_address} WHERE field_id=%d", $field->field_id);
+    @db_query("ALTER TABLE {uc_extra_fields_values} DROP COLUMN `%s`", $field->db_name . '_delivery');
+    @db_query("ALTER TABLE {uc_extra_fields_values} DROP COLUMN `%s`", $field->db_name . '_billing');
+    return TRUE;
+  }
+  return FALSE;
+}
+
+// MegaChriz: p003: function added
+/**
+ * Implementation of hook_load().
+ * @param int $fid
+ * @return object
+ */
+function uc_extra_fields_pane_customfield_load($fid) {
+  return db_fetch_object(db_query("SELECT * FROM {uc_extra_fields} WHERE field_id = %d", $fid));
+}
+
+// MegaChriz: p003: function added
+/**
+ * customfield_delete()
+ * Deletes field
+ * @param int $fid
+ * @return boolean
+ */
+function uc_extra_fields_pane_customfield_delete($fid) {
+  $field = uc_extra_fields_pane_customfield_load($fid);
+
+  if (!empty($field)) {
+    db_query("DELETE FROM {uc_extra_fields} WHERE field_id=%d", $field->field_id);
+    db_query("ALTER TABLE {uc_extra_fields_values} DROP COLUMN `%s`", $field->db_name);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+// MegaChriz: p003: replaced 'delta' with 'weight'
+// MegaChriz: p003: added additional code for loading extra delivery/billing fields
+/**
+ * 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) {
+  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];
+  }
+
+  switch ($pane_type) {
+    case 'all':
+      // Load all fields from all panes (except delivery and billing panes)
+      $db_results = db_query("SELECT * FROM {uc_extra_fields} ORDER BY weight ASC");
+      break;
+
+    case 'extra_delivery':
+      // Load all extra delivery fields
+      $db_results = db_query("SELECT * FROM {uc_extra_fields_address} WHERE delivery_pane=1}");
+      break;
+    case 'extra_billing':
+      // Load all extra billing fields
+      $db_results = db_query("SELECT * FROM {uc_extra_fields_address} WHERE billing_pane=1}");
+      break;
+
+    default:
+      // Load fields from specific pane (not delivery or billing pane)
+      $db_results = db_query("SELECT * from {uc_extra_fields} WHERE pane_type='%s' ORDER BY weight ASC", $pane_type);
+      break;
+  }
+
+  // Get results
+  while ($row = db_fetch_array($db_results)) {
+    $uc_extra_fields_pane_fields[$pane_type][$row['db_name']] = $row;
+  }
+
+  return $uc_extra_fields_pane_fields[$pane_type];
+}
+
+// -------------------------------------------------------------------
 // FORM ALTERS (address fields weight)
 // The following functions together makes it possible to change the
 // order of the address fields
@@ -317,7 +535,6 @@
 // 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
@@ -325,8 +542,8 @@
  * @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()
+ *  theme_uc_extra_fields_pane_weight_uc_store_address_fields()
  */
 function _uc_extra_fields_pane_weight_uc_store_address_fields_alter(&$form, $form_state) {
   // Get weight settings
@@ -350,21 +567,16 @@
     }
   }
 
-  // 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()
+ * @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();
@@ -374,6 +586,25 @@
   variable_set('uc_address_fields_weight', $weights);
 }
 
+// --------------------------
+// uc_cart_checkout_form_alter
+// --------------------------
+
+/**
+ * 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_');
+}
+
 // -------------------------------------------------------------------
 // FORM ALTERS (extra address fields)
 // The following functions together makes it possible to get extra
@@ -384,14 +615,14 @@
 // 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)
+ * which can be defined at /admin/store/settings/addresfields/add
  * @param array $form
  * @param array $form_state
  * @access private
+ * @see _uc_extra_fields_pane_address_fields_uc_store_address_fields_submit()
  */
 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');
@@ -400,59 +631,72 @@
 
   // Similar to uc_store_address_fields_form() from uc_store.module
   foreach ($fields as $field => $data) {
-    if ($data['display']) {
+    if (1) {
       $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'])),
+          t('@field is enabled.', array('@field' => $data['label'])),
+          t('@field is disabled.', array('@field' => $data['label'])),
         ),
-        '#default_value' => ($data['display']) ? TRUE : FALSE,
-        '#disabled' => TRUE,
+        '#default_value' => ($data['enabled']) ? TRUE : FALSE,
       );
       $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'],
+      '#value' => $data['db_name'],
     );
     $form['fields'][$field]['title'] = array(
-      '#value' => $data['title'],
+      '#value' => $data['label'],
+    );
+    // Add id of field
+    $form['fields'][$field]['field_id'] = array(
+      '#type' => 'value',
+      '#value' => $data['field_id'],
     );
   }
-}
 
-// --------------------------
-// uc_cart_checkout_form_alter
-// --------------------------
+  // MegaChriz: p003: added link
+  // Add link to add address field
+  $form['add_field'] = array(
+    '#type' => 'markup',
+    '#value' => l(t('Add an address field'), 'admin/store/settings/addressfields/add') . '<br /><br />',
+    '#weight' => 2,
+  );
+  $form['save']['#weight'] = 3;
+  $form['reset']['#weight'] = 4;
+
+  // Add submit function so 'enabled' and 'required' can be saved
+  $form['#submit'][] = 'uc_extra_fields_pane_address_fields_uc_store_address_fields_submit';
+}
 
-// MegaChriz: function added
 /**
- * Implementation of hook_form_FORM_ID_alter().
- * Applies ordering to address fields following the 'uc_address_fields_weight'-settings.
+ * uc_extra_fields_pane_address_fields_uc_store_address_fields_submit()
+ * Saves 'enabled' and 'required' for address fields
  * @param array $form
  * @param array $form_state
- * @access private
+ * @see _uc_extra_fields_pane_address_fields_uc_store_address_fields_alter()
  */
-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_');
+function uc_extra_fields_pane_address_fields_uc_store_address_fields_submit($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');
+  $address_fields = array_merge($fields_delivery, $fields_billing);
 
-  // Apply weight for billing fields (fieldnames are prefixed with 'billing_')
-  _uc_extra_fields_pane_applyWeights($form['panes']['billing'], 'billing_');
+  $fields = $form_state['values']['fields'];
+
+  foreach ($address_fields as $fieldname => $field) {
+    db_query("UPDATE {uc_extra_fields_address} SET enabled=%d, required=%d WHERE field_id=%d", $fields[$fieldname]['enabled'], $fields[$fieldname]['required'], $fields[$fieldname]['field_id']);
+  }
 }
 
-// MegaChriz: function added
+// --------------------------
+// uc_cart_checkout_form_alter
+// --------------------------
+
 /**
  * uc_extra_fields_pane_uc_checkout_pane_delivery()
  * Overrides uc_checkout_pane_delivery() function in uc_cart_checkout_pane.inc
@@ -465,7 +709,6 @@
   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
@@ -478,7 +721,7 @@
   return uc_extra_fields_pane_uc_checkout_pane_address('billing', $op, $arg1, $arg2);
 }
 
-// MegaChriz: function added
+// MegaChriz: p003: changed function, now points to uc_extra_fields_pane_generateField() for generating extra address fields
 /**
  * uc_extra_fields_pane_uc_checkout_pane_address()
  * @param string $type
@@ -491,10 +734,13 @@
 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);
+    // MegaChriz: p003: made next string translatable
+    trigger_error(t("Provided type in uc_extra_fields_pane_uc_checkout_pane_address() should be either 'delivery' or 'billing'."), E_USER_WARNING);
     return;
   }
 
+  $pane_type = 'extra_' . $type;
+
   // Include uc_cart_checkout_pane.inc
   module_load_include('inc', 'uc_cart', 'uc_cart_checkout_pane');
 
@@ -506,21 +752,43 @@
       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;
-        }
+      // Load extra fields for this pane
+      $extra_address_fields = array();
+      $extra_fields_db = uc_extra_fields_pane_load_fields_from_db($pane_type);
+      foreach ($extra_fields_db as $fieldname => $field) {
+        // Only view address fields that are enabled
+        if ($field['enabled'] == 1) {
+          $order_field_name = $fieldname . '_' . $type;
+          $generated_field = uc_extra_fields_pane_generateField($field['value_type'], $field);
 
-        // Merge extra fields array with original fields array
-        $pane['contents'] = array_merge($pane['contents'], $extra_fields);
+          switch ($field['value_type']) {
+            case UCXF_WIDGET_TYPE_PHP:
+            case UCXF_WIDGET_TYPE_CONSTANT:
+              break;
+            default:
+              // Adding default value for every field except for php and constant
+              $generated_field['#default_value'] = isset($arg1->extra_fields[$order_field_name]) ? $arg1->extra_fields[$order_field_name] : NULL;
+              break;
+          }
+
+          // Prefix fieldname with 'delivery_' or 'billing_'
+          $extra_address_fields[$type . '_' . $fieldname] = $generated_field;
+
+          // If the field happens to be a hidden field, display value if the user asks
+          // This currently applies to value_type of php and constant ONLY
+          if ($generated_field['#type'] == 'hidden' && $field['display'] == 1) {
+            $extra_address_fields[$type . '_' . $fieldname . '_i'] = array(
+              '#type' => 'item',
+              '#title' => t($field['label']),
+              '#value' => $generated_field['#value'],
+            );
+          }
+        }
       }
 
+      // Merge extra fields array with original fields array
+      $pane['contents'] = array_merge($pane['contents'], $extra_address_fields);
       return $pane;
       break;
 
@@ -532,37 +800,59 @@
         $bResult1 = uc_checkout_pane_billing($op, $arg1, $arg2);
       }
 
+      // MegaChriz: this may change later
       // Put extra address fields in 'extra_fields'-array, so uc_extra_fields_pane_load_pane_type() can handle it
+      $arg2['extra_fields'] = array();
       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 . '_'));
+          $fixedfieldname = substr($fieldname, strlen($type . '_')) . '_' . $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);
+      $bResult2 = uc_extra_fields_pane_load_pane_type($op, $arg1, $arg2, $pane_type);
       return ($bResult1 && $bResult2);
       break;
 
     case 'review':
       if ($type == 'delivery') {
-        $review1 = uc_checkout_pane_delivery($op, $arg1, $arg2);
+        $review = uc_checkout_pane_delivery($op, $arg1, $arg2);
       }
       else {
-        $review1 = uc_checkout_pane_billing($op, $arg1, $arg2);
+        $review = uc_checkout_pane_billing($op, $arg1, $arg2);
+      }
+
+      // Extra address fields
+      $review2 = array();
+      $fields = uc_extra_fields_pane_load_fields_from_db($pane_type);
+      if (count($fields)) {
+        foreach ($fields as $field) {
+          // Only display if the field is enabled
+          if ($field['enabled'] == 1) {
+            //Display it as data, unless its a checkbox
+            if ($field['value_type'] == UCXF_WIDGET_TYPE_PHP_CHECKBOXES ||
+              $field['value_type'] == UCXF_WIDGET_TYPE_CHECKBOXES ) {
+              //TODO: need a way of displaying this checkbox info
+            }
+            else {
+              $order_field_name = $field['db_name'] . '_' . $type;
+              $review2[] = array(
+                'title' => $field['label'],
+                'data' => $arg1->extra_fields[$order_field_name] ? ' ' . $arg1->extra_fields[$order_field_name] : "n/a"
+              );
+            }
+          }
+        }
       }
-      // 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);
+
+      $review = array_merge($review, $review2);
       return $review;
       break;
   }
 }
 
 // -------------------------------------------------------------------
-// EXTRA FIELDS PANE API
+// EXTRA FIELDS PANE API (Pane types loading)
 // -------------------------------------------------------------------
 
 /**
@@ -575,16 +865,6 @@
  * 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");
-}
-function uc_extra_fields_pane_billing($op, &$arg1 = NULL, $arg2 = NULL) {
-  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");
 }
@@ -601,56 +881,7 @@
   return uc_extra_fields_pane_order_handler($op, $arg1, $arg2, "extra_information");
 }
 
-// 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) {
-  // 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
+// MegaChriz: p003: changed function, fields generation now happens in a separate function
 /**
  * Pane handler
  * @param string $op
@@ -671,81 +902,29 @@
       $description = '';
       if (count($fields)) {
         foreach ($fields as $field) {
-           switch ($field['value_type']) {
-            case UCXF_WIDGET_TYPE_TEXTFIELD:
-              $contents['extra_fields'][$field['field'] ] = array(
-                '#type' => 'textfield',
-                '#title' => $field['title'],
-                '#description' => $field['description'],
-                '#size' => 32,
-                '#maxlength' => 255,
-                '#required' => $field['required'],
-                '#default_value' => isset($arg1->extra_fields[$field['field'] ]) ? $arg1->extra_fields[$field['field'] ] : NULL,
-              );
-              break;
-
-            case UCXF_WIDGET_TYPE_SELECT:
-            case UCXF_WIDGET_TYPE_CHECKBOXES:
-              $options = array();
-              $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");
-              }
-
-              $type = $field['value_type'] == UCXF_WIDGET_TYPE_SELECT? 'select' : 'checkboxes';
-
-              $contents['extra_fields'][$field['field'] ] = array(
-                '#type' => $type,
-                '#title' => $field['title'],
-                '#description' => $field['description'],
-                '#required' => $field['required'],
-                '#options' => $options,
-                //'#default_value' => NULL,
-              );
-              break;
+          $generated_field = uc_extra_fields_pane_generateField($field['value_type'], $field);
 
+          switch ($field['value_type']) {
             case UCXF_WIDGET_TYPE_PHP:
             case UCXF_WIDGET_TYPE_CONSTANT:
-                $output = $field['value_type'] == UCXF_WIDGET_TYPE_PHP? drupal_eval($field['value_input']) : $field['value_input'];
-
-              //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,
-              );
               break;
-            case UCXF_WIDGET_TYPE_PHP_SELECT:
-            case UCXF_WIDGET_TYPE_PHP_CHECKBOXES:	
-              //displays php-defined select/checkboxes
-              //This option creates elements from eval returning an array
-              //with array('name' => 'value', 'name2' => 'value2')
-			  //unfortionately drupal_eval is not equipped for the task, so we need to use the standard php-eval
-              $options = eval($field['value_input']) ;
-              $type = $field['value_type'] == UCXF_WIDGET_TYPE_PHP_SELECT ? 'select' : 'checkboxes';
-
-              $contents['extra_fields'][$field['field'] ] = array(
-                '#type' => $type,
-                '#title' => $field['title'],
-                '#description' => $field['description'],
-                '#required' => $field['required'],
-                '#options' => $options,
-                //'#default_value' => NULL,
-              );
-            	break;
+            default:
+              // Adding default value for every field except for php and constant
+              $generated_field['#default_value'] = isset($arg1->extra_fields[$field['db_name']]) ? $arg1->extra_fields[$field['db_name']] : NULL;
+              break;
+          }
+
+          // Add field
+          $contents['extra_fields'][$field['db_name']] = $generated_field;
+
+          // If the field happens to be a hidden field, display value if the user asks
+          // This currently applies to value_type of php and constant ONLY
+          if ($generated_field['#type'] == 'hidden' && $field['display'] == 1) {
+            $contents['extra_fields'][$field['db_name'] . '_i'] = array(
+              '#type' => 'item',
+              '#title' => t($field['label']),
+              '#value' => $generated_field['#value'],
+            );
           }
         }
       }
@@ -753,7 +932,7 @@
 
     case 'process':
       // initialize and fill array
-      if ($arg1->extra_fields == NULL) $arg1->extra_fields=array();
+      if ($arg1->extra_fields == NULL) $arg1->extra_fields = array();
       $arg1->extra_fields = array_merge($arg1->extra_fields, $arg2['extra_fields']);
       return TRUE;
 
@@ -761,13 +940,16 @@
       $fields = uc_extra_fields_pane_load_fields_from_db($pane_type);
       if (count($fields)) {
         foreach ($fields as $field) {
-   			//Display it as data, unless its a checkbox
-        	if($field['value_type'] == UCXF_WIDGET_TYPE_PHP_CHECKBOXES ||
-            	$field['value_type'] == UCXF_WIDGET_TYPE_CHECKBOXES ){
-            		//TODO: need a way of displaying this checkbox info
-            }else{
-        	$review[] = array('title' => $field['title'],
-                              'data' => $arg1->extra_fields[$field['field']] ? ' ' . $arg1->extra_fields[$field['field']] : "n/a"  );
+          //Display it as data, unless its a checkbox
+          if ($field['value_type'] == UCXF_WIDGET_TYPE_PHP_CHECKBOXES ||
+                $field['value_type'] == UCXF_WIDGET_TYPE_CHECKBOXES ) {
+                //TODO: need a way of displaying this checkbox info
+          }
+          else {
+              $review[] = array(
+                'title' => $field['label'],
+                'data' => ($arg1->extra_fields[$field['db_name']]) ? ' ' . $arg1->extra_fields[$field['db_name']] : "n/a"
+              );
           }
         }
       }
@@ -775,6 +957,9 @@
   }
 }
 
+// MegaChriz: p003: changed variable names because of changes elsewhere.
+// MegaChriz: p003: added code specific for addresses, but maybe that should be in a separate function.
+// This function needs work, the edit forms are not working properly
 /**
  * Wrapped function to load any order pane of $pane_type
  * @param string $op
@@ -784,6 +969,13 @@
  * @return mixed
  */
 function uc_extra_fields_pane_order_handler($op, $arg1, $arg2=NULL, $pane_type=NULL) {
+  $addresstype = '';
+  if ($pane_type == 'extra_delivery') {
+    $addresstype = 'delivery';
+  }
+  elseif ($pane_type == 'extra_billing') {
+    $addresstype = 'billing';
+  }
 
   switch ($op) {
     case 'edit-theme':
@@ -812,8 +1004,8 @@
       // dynamically generate form elements
       if (count($fields)) {
         foreach ($fields as $field) {
-          if (isset($arg1[$field['field'] ]))
-          $changes['extra_fields'][$field['field'] ] = $arg1[$field['field']];
+          if (isset($arg1[$field['db_name']]))
+          $changes['extra_fields'][$field['db_name']] = $arg1[$field['db_name']];
         }
       }
       return $changes;
@@ -829,16 +1021,19 @@
       // 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'],
-              '#size' => 32,
-              '#maxlength' => 255,
-              '#required' => $field['required'],
-              '#default_value' => isset($arg1->extra_fields[$field['field']]) ? $arg1->extra_fields[$field['field'] ] : NULL,
-          );
+          $generated_field = uc_extra_fields_pane_generateField($field['value_type'], $field);
+          switch ($pane_type) {
+            case 'extra_delivery':
+            case 'extra_billing':
+              $order_field_name = $field['db_name'] . '_' . $addresstype;
+              $generated_field['#default_value'] = isset($arg1->extra_fields[$order_field_name]) ? $arg1->extra_fields[$order_field_name] : NULL;
+              break;
 
+            default:
+              $generated_field['#default_value'] = isset($arg1->extra_fields[$field['db_name']]) ? $arg1->extra_fields[$field['db_name']] : NULL;
+              break;
+          }
+          $form['extra_fields'][$field['db_name']] = $generated_field;
         }
       }
 
@@ -850,32 +1045,122 @@
       $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();
+      $custom_order_fields=array();
 
       if (count($fields)) {
         foreach ($fields as $field) {
           // warning: user input --> check_plain
-          if (isset($values[$field['field']  ])) {
+          if (isset($values[$field['db_name']])) {
             //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 />';
+            $custom_order_fields[] = t('<strong>'. $field['label']) .'</strong>: '. check_plain($values[$field['db_name']]) .'<br />';
+          }
+          // MegaChriz: p003: may be moved later
+          // Address panes
+          elseif (isset($values[$field['db_name'] . '_' . $addresstype])) {
+            //if its a customer, always show the block with all the info contained
+            if ($field['display'] == "1" || $op =='customer')
+            $custom_order_fields[] = t('<strong>'. $field['label']) .'</strong>: '. check_plain($values[$field['db_name'] . '_' . $addresstype]) .'<br />';
           }
         }
       }
 
-      if (count($delivery_fields)) {
-        $output .= '<br />' . implode('<br />', $delivery_fields);
+      if (count($custom_order_fields)) {
+        $output .= '<br />' . implode('<br />', $custom_order_fields);
       }
       return $output;
   }
 }
 
 // -------------------------------------------------------------------
+// CREATE FIELD API
+// Functions to generate form elements
+// -------------------------------------------------------------------
+
+/**
+ * generateField()
+ * Generates a field array used in forms generated by uc_extra_fields_pane
+ * @param string $p_sFieldtype
+ * @param array $p_aFieldsettings
+ * @return array $return_field
+ */
+function uc_extra_fields_pane_generateField($p_sFieldtype, $p_aFieldsettings) {
+  $return_field = array();
+  switch ($p_sFieldtype) {
+    case UCXF_WIDGET_TYPE_TEXTFIELD:
+      $return_field = array(
+        '#type' => 'textfield',
+        '#title' => $p_aFieldsettings['label'],
+        '#description' => $p_aFieldsettings['description'],
+        '#size' => 32,
+        '#maxlength' => 255,
+        '#required' => $p_aFieldsettings['required'],
+      );
+      break;
+
+    case UCXF_WIDGET_TYPE_SELECT:
+    case UCXF_WIDGET_TYPE_CHECKBOXES:
+      $options = array();
+      $input_token = strtok($p_aFieldsettings['value'], "\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");
+      }
+
+      $type = ($p_sFieldtype == UCXF_WIDGET_TYPE_SELECT)? 'select' : 'checkboxes';
+
+      $return_field = array(
+        '#type' => $type,
+        '#title' => $p_aFieldsettings['label'],
+        '#description' => $p_aFieldsettings['description'],
+        '#required' => $p_aFieldsettings['required'],
+        '#options' => $options,
+        //'#default_value' => NULL,
+      );
+      break;
+
+    case UCXF_WIDGET_TYPE_PHP:
+    case UCXF_WIDGET_TYPE_CONSTANT:
+      $output = ($p_sFieldtype == UCXF_WIDGET_TYPE_PHP)? drupal_eval($p_aFieldsettings['value']) : $p_aFieldsettings['value'];
+
+      $return_field = array(
+        '#type' => 'hidden',
+        '#value' => $output,
+      );
+      break;
+    case UCXF_WIDGET_TYPE_PHP_SELECT:
+    case UCXF_WIDGET_TYPE_PHP_CHECKBOXES:
+      //displays php-defined select/checkboxes
+      //This option creates elements from eval returning an array
+      //with array('name' => 'value', 'name2' => 'value2')
+      //unfortionately drupal_eval is not equipped for the task, so we need to use the standard php-eval
+      $options = eval($p_aFieldsettings['value']) ;
+      $type = ($p_sFieldtype == UCXF_WIDGET_TYPE_PHP_SELECT) ? 'select' : 'checkboxes';
+
+      $return_field = array(
+        '#type' => $type,
+        '#title' => $p_aFieldsettings['label'],
+        '#description' => $p_aFieldsettings['description'],
+        '#required' => $p_aFieldsettings['required'],
+        '#options' => $options,
+        //'#default_value' => NULL,
+      );
+      break;
+    }
+    return $return_field;
+}
+
+// -------------------------------------------------------------------
 // HELPER FUNCTIONS
-// Address fields weight
+// Helper functions to apply weights to address fields
 // -------------------------------------------------------------------
 
-// MegaChriz: function added
 /**
  * _getDefaultAddressFieldsWeights()
  * Get the default weight settings for the address fields.
@@ -924,7 +1209,6 @@
   return $aWeightFields;
 }
 
-// MegaChriz: function added
 /**
  * _applyWeights()
  * Applies ordering to address fields following the 'uc_address_fields_weight'-settings.
@@ -967,8 +1251,7 @@
     'uc_extra_fields_pane' => array(
       'arguments' => array('form' => NULL),
     ),
-    // MegaChriz: added theme function
-    'uc_extra_fields_pane_weight_uc_store_address_fields' => array(
+    'uc_extra_fields_pane_uc_store_address_fields' => array(
       'arguments' => array('form' => NULL),
     ),
   );
@@ -1002,18 +1285,15 @@
   return $output;
 }
 
-// MegaChriz: function added
 /**
- * theme_uc_extra_fields_pane_weight_address_fields()
+ * theme_uc_extra_fields_pane_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'));
+function theme_uc_extra_fields_pane_uc_store_address_fields($form) {
+  $header = array(t('Enabled'), t('Field'), t('Title'), t('Required'), array('data' => t('List position'), 'sort' => 'asc'), t('Action'));
 
   foreach (element_children($form['fields']) as $field) {
     $row = array(
@@ -1024,6 +1304,17 @@
       drupal_render($form['fields'][$field]['weight']),
     );
 
+    // Add Edit/Delete link to fields that are editable.
+    if (isset($form['fields'][$field]['field_id'])) {
+      $field_id = $form['fields'][$field]['field_id']['#value'];
+      $row[] = array('data' => l(t('delete'), 'admin/store/settings/addressfields/' . $field_id . '/delete') . ' | ' .
+      l(t('edit'), 'admin/store/settings/addressfields/' . $field_id . '/edit')
+      );
+    }
+    else {
+      $row[] = '';
+    }
+
     $rows[$form['fields'][$field]['#weight']] = array(
       'data' => $row,
       'class' => 'draggable',
@@ -1035,7 +1326,8 @@
 
   drupal_add_tabledrag('uc-address-fields-table', 'order', 'sibling', 'uc-address-fields-table-ordering');
 
-  $output = theme('table', $header, $rows, array('id' => 'uc-address-fields-table')) .'<br />'. drupal_render($form);
+  // MegaChriz: p003: changed
+  $output = theme('table', $header, $rows, array('id' => 'uc-address-fields-table')) . drupal_render($form);
 
   return $output;
 }
\ No newline at end of file

