From ed25f56051714db50d7564a912c6952ca7dfd3bf Mon Sep 17 00:00:00 2001
From: Taran2l <Taran2L@473438.no-reply.drupal.org>
Date: Tue, 14 Feb 2012 02:51:35 +0200
Subject: [PATCH] Issue #805734 by wjaspers: Fixed illegal offset issues
 caused by incorrect form element processing function.

diff --git a/addresses.module b/addresses.module
index e24628e..9df85d5 100644
--- a/addresses.module
+++ b/addresses.module
@@ -174,6 +174,7 @@ function addresses_elements() {
     'addresses_elements' => array(
       '#columns' => $fields,
       '#delta' => 0,
+      '#ignore_required' => FALSE,
       '#input' => TRUE,
       '#process' => array('addresses_elements_process'),
     )
@@ -188,22 +189,21 @@ function addresses_elements() {
  */
 function addresses_elements_process($element, $edit, $form_state, $form) {
   global $language;
-
+  
   // Add the language definition in the settings so we can properly select words in a given language.
   drupal_add_js(array('addresses' => array('language' => $language->language)), 'setting');
-
+  
   // The $form['#field_info'] entry comes from CCK
-  $settings = empty($form['#field_info'][$element['#field_name']])
+  $settings = empty($form['#field_info'][$element['#field_name']]['addresses'])
     ? variable_get('addresses_user_settings', array())
-    : $form['#field_info'][$element['#field_name']];
+    : $form['#field_info'][$element['#field_name']]['addresses'];
   $fields = $element['#fields'];
   $values = $element['#default_value'];
-
+  
   // Reset the required fields based on the general required value
-  if (empty($element['#required'])) {
-    foreach ($fields as $field => $required) {
-      if ($required == ADDRESSES_FIELD_REQUIRED
-          && $form['#id'] == 'content-field-edit-form') {
+  if ($element['#ignore_required']) {
+    foreach ($fields as $field => $ftype) {
+      if ($ftype == ADDRESSES_FIELD_REQUIRED) {
         $fields[$field] = ADDRESSES_FIELD_SHOW;
       }
     }
@@ -225,39 +225,36 @@ function addresses_elements_process($element, $edit, $form_state, $form) {
   // Include the main module file
   module_load_include('inc', 'addresses');
 
-  // Update the $fields array to reflect element visibility settings per the
-  // new global settings options.  It would be cleaner to simply update the
-  // form generation function, but this method will be compatible with extra
-  // contrib fields.
+  // Invoke addressfieldapi to allow modules to add their own addresses fields.
+  $extra = module_invoke_all('addressesfieldapi', 'form', $fields, $values);
+  // Set proper field visibility
   foreach (array_keys($fields) as $ftype) {
-    if (!empty($settings[$ftype . '_select'])) {
-      if ($form['form_id']['#value'] == 'content_field_edit_form') {
-        // force optional on content_field_edit_form
-        $fields[$ftype] = ADDRESSES_FIELD_SHOW;
-      }
-      else {
-        $fields[$ftype] = $settings[$ftype . '_select'];
+    if (!empty($extra[$ftype])) {
+      switch ($fields[$ftype]) {
+        case ADDRESSES_FIELD_REQUIRED:
+          $extra[$ftype]['#required'] = TRUE;
+          break;
+        case ADDRESSES_FIELD_HIDDEN:
+          $extra[$ftype]['#type'] = 'hidden';
+          break;
       }
     }
   }
-
-  // Invoke addressfieldapi to allow modules to add their own addresses fields.
   // Then update these fields with the global settings for each field instance.
-  $extra = module_invoke_all('addressesfieldapi', 'form', $fields, $values);
-  foreach (element_children($extra) as $ename) {
-    if (isset($settings[$ename . '_label'])) {
-      $extra[$ename]['#title'] = t($settings[$ename . '_label']);
+  foreach (element_children($extra) as $ftype) {
+    if (isset($settings[$ftype]['label'])) {
+      $extra[$ftype]['#title'] = $settings[$ftype]['label'];
     }
-    if (isset($settings[$ename . '_desc'])) {
-      $extra[$ename]['#description'] = t($settings[$ename . '_desc']);
+    if (isset($settings[$ftype]['desc'])) {
+      $extra[$ftype]['#description'] = $settings[$ftype]['desc'];
     }
-    if ('textfield' == $extra[$ename]['#type'] && isset($settings[$ename . '_size'])) {
-      $extra[$ename]['#size'] = $settings[$ename . '_size'];
-      if (!isset($extra[$ename]['#attributes']['class'])) {
-        $extra[$ename]['#attributes']['class'] = 'text';
+    if ('textfield' == $extra[$ftype]['#type'] && isset($settings[$ftype]['size'])) {
+      $extra[$ftype]['#size'] = $settings[$ftype]['size'];
+      if (!isset($extra[$ftype]['#attributes']['class'])) {
+        $extra[$ftype]['#attributes']['class'] = 'text';
       }
       else {
-        $extra[$ename]['#attributes']['class'] .= ' text';
+        $extra[$ftype]['#attributes']['class'] .= ' text';
       }
     }
   }
diff --git a/addresses.settings.inc b/addresses.settings.inc
index ce44e2f..0305e11 100644
--- a/addresses.settings.inc
+++ b/addresses.settings.inc
@@ -35,7 +35,6 @@ function _addresses_addressesfieldapi_form($fields = array(), $values = array())
       '#maxlength' => 75,
       '#description' => t('e.g. a place of business, venue, meeting point'),
       '#attributes' => NULL,
-      '#required' => ($fields['aname'] == ADDRESSES_FIELD_REQUIRED),
       '#weight' => empty($field_weights['aname']['weight']) ? 0 : $field_weights['aname']['weight'],
     );
   }
@@ -62,7 +61,6 @@ function _addresses_addressesfieldapi_form($fields = array(), $values = array())
       '#extra' => 0,
       '#multiple' => FALSE,
       '#element_validate' => array('_addresses_validate_top_countries'),
-      '#required' => ($fields['country'] == ADDRESSES_FIELD_REQUIRED),
       '#weight' => empty($field_weights['country']['weight']) ? 0 : $field_weights['country']['weight'],
     );
   }
@@ -72,7 +70,6 @@ function _addresses_addressesfieldapi_form($fields = array(), $values = array())
     $form['province'] = array(
       '#default_value' => isset($values['province']) ? $values['province'] : '',
       '#maxlength' => 16,
-      '#required' => ($fields['province'] == ADDRESSES_FIELD_REQUIRED),
       '#size' => 16,
       '#title' => t('State / Province'),
       '#type' => 'textfield',
@@ -98,7 +95,6 @@ function _addresses_addressesfieldapi_form($fields = array(), $values = array())
       '#default_value' => isset($values['city']) ? $values['city'] : '',
       '#size' => 50,
       '#maxlength' => 255,
-      '#required' => ($fields['city'] == ADDRESSES_FIELD_REQUIRED),
       '#weight' => empty($field_weights['city']['weight']) ? 0 : $field_weights['city']['weight'],
     );
   }
@@ -111,7 +107,6 @@ function _addresses_addressesfieldapi_form($fields = array(), $values = array())
       '#default_value' => isset($values['street']) ? $values['street'] : '',
       '#size' => 50,
       '#maxlength' => 255,
-      '#required' => ($fields['street'] == ADDRESSES_FIELD_REQUIRED),
       '#weight' => empty($field_weights['street']['weight']) ? 0 : $field_weights['street']['weight'],
     );
     if (!empty($fields['additional'])) {
@@ -134,20 +129,10 @@ function _addresses_addressesfieldapi_form($fields = array(), $values = array())
       '#default_value' => isset($values['postal_code']) ? $values['postal_code'] : '',
       '#size' => 16,
       '#maxlength' => 16,
-      '#required' => ($fields['postal_code'] == ADDRESSES_FIELD_REQUIRED),
       '#weight' => empty($field_weights['postal_code']['weight']) ? 0 : $field_weights['postal_code']['weight'],
     );
   }
 
-  foreach (array_keys($fields) as $ftype) {
-    if ($fields[$ftype] == ADDRESSES_FIELD_HIDDEN) {
-      $form[$ftype] = array(
-        '#type' => 'hidden',
-        '#value' => isset($values[$ftype]) ? $values[$ftype] : '',
-      );
-    }
-  }
-
   return $form;
 }
 
@@ -578,12 +563,12 @@ function _addresses_settings(&$form_state) {
  */
 function _addresses_settings_fields($field_values = array()) {
   $ftypes = module_invoke_all('addressesfieldapi', 'fields');
-
+  
   // List of address fields
   // We let the user choose the current status, sizes, labels and descriptions
   foreach ($ftypes as $ftype => $field) {
     // Mode
-    $form['addresses'][$ftype][$ftype . '_select'] = array(
+    $form['addresses'][$ftype]['select'] = array(
       '#type' => 'select',
       '#options' => array(
         ADDRESSES_FIELD_NONE      => 'None',
@@ -591,12 +576,12 @@ function _addresses_settings_fields($field_values = array()) {
         ADDRESSES_FIELD_REQUIRED  => 'Required',
         ADDRESSES_FIELD_HIDDEN    => 'Hidden',
       ),
-      '#default_value'  => !isset($field_values[$ftype . '_select']) ? $field['display'] : $field_values[$ftype . '_select'],
+      '#default_value'  => !isset($field_values[$ftype]['select']) ? $field['display'] : $field_values[$ftype]['select'],
     );
 
     // Size
     if ($field['type'] == 'int') {
-      $form['addresses'][$ftype][$ftype . '_size'] = array(
+      $form['addresses'][$ftype]['size'] = array(
         '#type' => 'textfield',
         '#size' => 3,
         '#maxlength' => 3,
@@ -605,8 +590,8 @@ function _addresses_settings_fields($field_values = array()) {
       );
     }
     else {
-      if (isset($field_values[$ftype . '_size'])) {
-        $size = $field_values[$ftype . '_size'];
+      if (isset($field_values[$ftype]['size'])) {
+        $size = $field_values[$ftype]['size'];
       }
       elseif (empty($field['length'])) {
         if ($field['type'] == 'text') {
@@ -624,7 +609,7 @@ function _addresses_settings_fields($field_values = array()) {
           $size = 60;
         }
       }
-      $form['addresses'][$ftype][$ftype . '_size'] = array(
+      $form['addresses'][$ftype]['size'] = array(
         '#type' => 'textfield',
         '#size' => 3,
         '#maxlength' => 3,
@@ -633,22 +618,23 @@ function _addresses_settings_fields($field_values = array()) {
     }
 
     // Label
-    $form['addresses'][$ftype][$ftype . '_label'] = array(
+    $form['addresses'][$ftype]['label'] = array(
       '#type' => 'textfield',
       '#size' => 20,
       '#maxlength' => 255,
-      '#default_value' => !isset($field_values[$ftype . '_label']) ? $field['title'] : $field_values[$ftype . '_label'],
+      '#default_value' => !isset($field_values[$ftype]['label']) ? $field['title'] : $field_values[$ftype]['label'],
     );
 
     // Description
-    $form['addresses'][$ftype][$ftype . '_desc'] = array(
+    $form['addresses'][$ftype]['desc'] = array(
       '#type' => 'textfield',
       '#size' => 60,
-      '#default_value' => !isset($field_values[$ftype . '_desc']) ? $field['description'] : $field_values[$ftype . '_desc'],
+      '#default_value' => !isset($field_values[$ftype]['desc']) ? $field['description'] : $field_values[$ftype]['desc'],
     );
     $form['addresses'][$ftype]['#title'] = $field['title'];
   }
 
+  $form['addresses']['#tree'] = TRUE;
   $form['addresses']['#theme'] = 'addresses_settings_fields';
 
   return $form;
@@ -746,10 +732,10 @@ function theme_addresses_settings_fields($form) {
     $field = $form[$ftype];
     $rows[] = array(
       $field['#title'],
-      drupal_render($field[$ftype . '_select']),
-      drupal_render($field[$ftype . '_size']),
-      drupal_render($field[$ftype . '_label']),
-      drupal_render($field[$ftype . '_desc']),
+      drupal_render($field['select']),
+      drupal_render($field['size']),
+      drupal_render($field['label']),
+      drupal_render($field['desc']),
     );
     unset($form[$ftype]);
   }
diff --git a/addresses_cck/addresses_cck.module b/addresses_cck/addresses_cck.module
index 1b78f77..d88d966 100644
--- a/addresses_cck/addresses_cck.module
+++ b/addresses_cck/addresses_cck.module
@@ -125,29 +125,12 @@ function addresses_cck_field_settings($op, $field) {
     case 'form':
       // Get the form fields from the API addressesfieldapi
       module_load_include('settings.inc', 'addresses');
-      $form = _addresses_settings_fields($field);
-      $form['required'] = array(
-        '#type'   => 'hidden',
-        '#value'  => $field['required'],
-        '#tree'   => TRUE,
-      );
-      $form['#validate'][] = '_addresses_cck_field_validate';
+      $form = _addresses_settings_fields($field['addresses']);
+      $form['required']['#access'] = FALSE;
       return $form;
 
     case 'save':
-      // First, get the form fields from the API addressesfieldapi
-      module_load_include('settings.inc', 'addresses');
-      $form = _addresses_settings_fields($field);
-
-      // With the fields and their values correctly assigned,
-      // its time to recover only the field name and its value
-      // and save that
-      foreach (array_keys($form['addresses']) as $ftype) {
-        foreach (element_children($form['addresses'][$ftype]) as $field) {
-          $fields[] = $field;
-        }
-      }
-      return $fields;
+      return array('addresses');
 
     case 'callbacks':
       // The simple callback map for such field
@@ -190,26 +173,6 @@ function addresses_cck_field_settings($op, $field) {
 }
 
 /**
- * Reset the general 'required' value based on each address field.
- *
- * @ingroup form
- */
-function _addresses_cck_field_validate(&$form, &$form_state) {
-  if (substr($form_state['values']['country'], 0, 4) == 'top_') {
-    $form_state['values']['country'] = substr($form_state['values']['country'], 4);
-  }
-  if (isset($form_state['values']['columns']) && is_array($form_state['values']['columns'])) {
-    foreach (array_keys($form_state['values']['columns']) as $ftype) {
-      if ($form_state['values'][$ftype . '_select'] == ADDRESSES_FIELD_REQUIRED) {
-        form_set_value($form['field']['required'], TRUE, $form_state);
-        return;
-      }
-    }
-  }
-  form_set_value($form['field']['required'], FALSE, $form_state);
-}
-
-/**
  * Implementation of hook_geocode_handlers_alter().
  *
  * Allows the address field to be used by the geocode module.
@@ -258,20 +221,24 @@ function addresses_cck_theme() {
 function addresses_cck_widget(&$form, &$form_state, $field, $items, $delta = 0) {
   // Include the main module file
   module_load_include('inc', 'addresses');
-
   // Get all form fields for building addresses
   $ftypes = module_invoke_all('addressesfieldapi', 'fields');
+  $field_values = $field['addresses'];
   $fields = array();
-  foreach (array_keys($ftypes) as $ftype) {
-    $fields[$ftype] = $field[$ftype];
+  foreach ($ftypes as $ftype => $field_defaults) {
+    $fields[$ftype] = !isset($field_values[$ftype]['select']) ? $field_defaults['display'] : $field_values[$ftype]['select'];
   }
-
+  
   // The Addresses field
   $element = array(
     '#type'           => 'addresses_elements',
     '#fields'         => $fields,
     '#default_value'  => $items[$delta],
   );
+  // Check if we are on content edit field page
+  if(empty($form['form_id'])) {
+    $element['#ignore_required'] = TRUE;
+  }
 
   return $element;
 }
diff --git a/addresses_phone/addresses_phone.module b/addresses_phone/addresses_phone.module
index 2bd47c0..e5dfba3 100644
--- a/addresses_phone/addresses_phone.module
+++ b/addresses_phone/addresses_phone.module
@@ -57,7 +57,6 @@ function addresses_phone_addressesfieldapi($op, $fields = array(), $values = arr
         '#size'           => 30,
         '#maxlength'      => 24,
         '#attributes'     => NULL,
-        '#required'       => ($fields['phone'] == ADDRESSES_FIELD_REQUIRED),
         '#weight'         => empty($field_weights['phone']['weight']) ? 0 :
           $field_weights['phone']['weight'],
       );
@@ -72,21 +71,11 @@ function addresses_phone_addressesfieldapi($op, $fields = array(), $values = arr
         '#size'           => 30,
         '#maxlength'      => 24,
         '#attributes'     => NULL,
-        '#required'       => ($fields['fax'] == ADDRESSES_FIELD_REQUIRED),
         '#weight'         => empty($field_weights['fax']['weight']) ? 0 :
           $field_weights['fax']['weight'],
       );
     }
 
-    foreach (array_keys($fields) as $ftype) {
-      if ($fields[$ftype] == ADDRESSES_FIELD_HIDDEN) {
-        $form[$ftype] = array(
-          '#type'         => 'hidden',
-          '#value'        => isset($values[$ftype]) ? $values[$ftype] : '',
-        );
-      }
-    }
-
     return $form;
   }
 }
diff --git a/addresses_user/addresses_user.module b/addresses_user/addresses_user.module
index 2f98adf..e0c50ef 100644
--- a/addresses_user/addresses_user.module
+++ b/addresses_user/addresses_user.module
@@ -138,66 +138,6 @@ function addresses_user_form__addresses_settings_alter(&$form, &$form_state) {
 }
 
 /**
- * Implementation of hook_form_alter().
- *
- * Put the address form into the registration form.
- */
-function addresses_user_form_user_register_alter(&$form, &$form_state) {
-  addresses_user_form_user_profile_form_alter($form, $form_state, TRUE);
-}
-
-/**
- * Implementation of hook_form_alter().
- *
- * Put the address form into the user form.
- */
-function addresses_user_form_user_profile_form_alter(&$form, &$form_state, $register = FALSE) {
-  if ((variable_get('addresses_user_register', FALSE) && $register)
-   || (variable_get('addresses_user_form',     FALSE) && $form['_category']['#value'] == 'account')) {
-
-    // get existing user address if defined
-    $address = array();
-    if (!$register) {
-      module_load_include('inc', 'addresses_user');
-      $addresses = _addresses_user_address_get($form['#uid']);
-      if (!empty($addresses)) {
-        // get the first element (may not be $addresses[0])
-        $address = array_shift($addresses);
-        // (should we check that it is a primary address?)
-      }
-    }
-
-    // Get the fields used on this address
-    $fields = variable_get('addresses_user', array());
-
-    // If it's the very first time it's loaded, use all fields
-    if (empty($fields)) {
-      $ftypes = module_invoke_all('addressesfieldapi', 'fields');
-      foreach ($ftypes as $ftype => $field) {
-        // List of address fields
-        $fields[$ftype] = empty($field_values[$ftype]) ? $field['display'] : $field_values[$ftype];
-      }
-    }
-
-    // Get the address form builder
-    $form['address_information'] =  array(
-      '#collapsible'        => TRUE,
-      '#collapsed'          => variable_get($register ? 'addresses_user_register_collapsed' : 'addresses_user_form_collapsed', FALSE),
-      '#title'              => t('Address'),
-      '#type'               => 'fieldset',
-      '#weight'             => variable_get($register ? 'addresses_user_register_weight' : 'addresses_user_form_weight', 0),
-    );
-    $form['address_information']['addresses'] = array(
-      '#default_value'  => $address,
-      '#fields'         => $fields,
-      '#required'       => TRUE,
-      '#type'           => 'addresses_elements',
-      '#tree'           => TRUE,
-    );
-  }
-}
-
-/**
  * Submit the address
  *
  * @ingroup form
@@ -226,10 +166,8 @@ function _addresses_user_settings_submit($form, &$form_state) {
   $settings = array();
 
   foreach ($ftypes as $ftype => $elements) {
-    $fields[$ftype] = $elements[$ftype . '_select'];
-    foreach ($elements as $name => $value) {
-      $settings[$name] = $value;
-    }
+    $fields[$ftype] = $elements['select'];
+    $settings[$ftype] = $elements;
   }
 
   variable_set('addresses_user', $fields);
@@ -279,6 +217,53 @@ function addresses_user_theme() {
  */
 function addresses_user_user($op, &$edit, &$account, $category = NULL) {
   switch ($op) {
+    case 'form':
+    case 'register':
+      if ((variable_get('addresses_user_register', FALSE) && $op == 'register')
+       || (variable_get('addresses_user_form',     FALSE) && $op == 'form' && $category == 'account')) {
+
+      // get existing user address if defined
+      $address = array();
+      if ($op != 'register') {
+        module_load_include('inc', 'addresses_user');
+        $addresses = _addresses_user_address_get($account->uid);
+        if (!empty($addresses)) {
+          // get the first element (may not be $addresses[0])
+          $address = array_shift($addresses);
+          // (should we check that it is a primary address?)
+        }
+      }
+
+      // Get the fields used on this address
+      $fields = variable_get('addresses_user', array());
+
+      // If it's the very first time it's loaded, use all fields
+      if (empty($fields)) {
+        $ftypes = module_invoke_all('addressesfieldapi', 'fields');
+        foreach ($ftypes as $ftype => $field) {
+          // List of address fields
+          $fields[$ftype] = empty($field_values[$ftype]) ? $field['display'] : $field_values[$ftype];
+        }
+      }
+
+      // Get the address form builder
+      $form['address_information'] =  array(
+        '#collapsible'        => TRUE,
+        '#collapsed'          => variable_get($register ? 'addresses_user_register_collapsed' : 'addresses_user_form_collapsed', FALSE),
+        '#title'              => t('Address'),
+        '#type'               => 'fieldset',
+        '#weight'             => variable_get($register ? 'addresses_user_register_weight' : 'addresses_user_form_weight', 0),
+      );
+      $form['address_information']['addresses'] = array(
+        '#default_value'  => $address,
+        '#fields'         => $fields,
+        '#required'       => TRUE,
+        '#type'           => 'addresses_elements',
+        '#tree'           => TRUE,
+      );
+      
+      return $form;
+    }
     case 'delete':
       // Delete all addresses that the user has set under their account
       db_query('DELETE FROM {addresses_user} WHERE eid = %d', $account->uid);
@@ -311,7 +296,7 @@ function addresses_user_user($op, &$edit, &$account, $category = NULL) {
         elseif (isset($account->addresses)) {
           $address =& $account->addresses;
         }
-
+        
         if (isset($address)) {
           module_load_include('inc', 'addresses_user');
           _addresses_user_address_save($address, $account->uid);
-- 