views:

294

answers:

1

Edit:

So, I've been working on this for hours now... I think it's because the action is the same or something... I tried to modify the action using this:

function mytheme_user_profile_form($form) {
        global $user;
        $uid = $user->uid;
        //print '<pre>'; print_r($form); print '</pre>';
    $category = $form['_category']['#value'];

    switch($category) {
            case 'account':
      $form['#action'] = '/user/'.$uid.'/edit?destination=user/'.$uid;
                        break;
     case 'education':
                        $form['#action'] = '/user/'.$uid.'/edit/education?destination=user/'.$uid;
                        break;
     case 'experience':
                        $form['#action'] = '/user/'.$uid.'/edit/experience?destination=user/'.$uid;
                        break;
            case 'publications':
                        $form['#action'] = '/user/'.$uid.'/edit/publications?destination=user/'.$uid;
                        break;
     case 'conflicts':
                        $form['#action'] = '/user/'.$uid.'/edit/conflicts?destination=user/'.$uid;
                        break;
    }

        //print '<pre>'; print_r($form); print '</pre>';
        //print $form['#action'];
        $output .= drupal_render($form);
        return $output;
}

But, the form action, when the form is actually rendered is unchanged. They're all /user/%uid ...

Can I modify the form action?


I'm including several different "categories" of the user profile form on one page, and the code will correctly output the forms I'm specifying. Each form is in a separate collapsible div. My problem is twofold...

(1) The existing values for the fields aren't pre-populated and (2) Clicking on "Save" for one section will result in a warning: Email field is required, regardless of which form you're actually saving

I'm pretty sure that for problem #2, it's because the name of the button is the same in all cases, as is the form id...

print '<h3>&ndash; Account Settings</h3>';
print '<div class="expand">';
print(drupal_get_form('user_profile_form', $user, 'account'));
print '</div>';

print '<h3>&ndash; My Info</h3>';
print '<div class="expand">';
print(drupal_get_form('user_profile_form', $user, 'Personal'));
print '</div>';

print '<h3>&ndash; Experience</h3>';
print '<div class="expand">';
print(drupal_get_form('user_profile_form', $user, 'experience'));
print '</div>';

print '<h3>&ndash; Education</h3>';
print '<div class="expand">';
print(drupal_get_form('user_profile_form', $user, 'education'));
print '</div>';
+1  A: 

Problem #1: ? Could you post the html source? For problem #2: OK, I'll step through the code here: The validation handler for the user profile form (user_profile_form_validate()) calls

user_module_invoke('validate', $form_state['values'], $form_state['values']['_account'], $form_state['values']['_category']);

Which looks like

<?php
/**
* Invokes hook_user() in every module.
*
* We cannot use module_invoke() for this, because the arguments need to
* be passed by reference.
*/
function user_module_invoke($type, &$array, &$user, $category = NULL) {
  foreach (module_list() as $module) {
    $function = $module .'_user'; 
    if (function_exists($function)) {
      $function($type, $array, $user, $category);
    }
  }
}
?>

So, the validation handler for this form is going through every module looking for user hook functions and calling them with $type = 'validate'. (Note that 'category' param is optional here - contrib modules are not required to use it)

Let's look at user.module's user hook as an example to see what happens:

function user_user($type, &$edit, &$account, $category = NULL) {
  if ($type == 'view') {
    $account->content['user_picture'] = array(
      '#value' => theme('user_picture', $account),
      '#weight' => -10,
    );
    if (!isset($account->content['summary'])) {
      $account->content['summary'] = array();
    }
    $account->content['summary'] += array(
      '#type' => 'user_profile_category',
      '#attributes' => array('class' => 'user-member'),
      '#weight' => 5,
      '#title' => t('History'),
    );
    $account->content['summary']['member_for'] = array(
      '#type' => 'user_profile_item',
      '#title' => t('Member for'),
      '#value' => format_interval(time() - $account->created),
    );
  }
  if ($type == 'form' && $category == 'account') {
    $form_state = array();
    return user_edit_form($form_state, (isset($account->uid) ? $account->uid : FALSE), $edit);
  }
//<-- LOOK HERE -->
  if ($type == 'validate' && $category == 'account') {
    return _user_edit_validate((isset($account->uid) ? $account->uid : FALSE), $edit);
  }

  if ($type == 'submit' && $category == 'account') {
    return _user_edit_submit((isset($account->uid) ? $account->uid : FALSE), $edit);
  }

  if ($type == 'categories') {
    return array(array('name' => 'account', 'title' => t('Account settings'), 'weight' => 1));
  }
}

So, it is only supposed to validate if the category == 'account'

In the function _use_edit_validate, we find:

  // Validate the e-mail address:
  if ($error = user_validate_mail($edit['mail'])) {
    form_set_error('mail', $error);
  }

There's your error message.

Since that form is only supposed to validate when the category == 'account', and your problem (#2) seems to be that it always validates regardless of the category, maybe your forms are not being rendered as unique form instances? Drupal might be rendering a complete form each time, and just setting a hidden form value to whatever the category is (like in this form's definition function in user_pages.inc $form['_category'] = array('#type' => 'value', '#value' => $category);)

It would be helpful to see the actual html source output.

==EDIT 10-15-09 in response to updated question===

OK, it looks like your method (editing $form['#action'] manually in the theme layer) may not be possible (see this post for reference). If you want to alter the form action you need to write a custom module that implements hook_form_alter() (it won't work in a theme template file). This function allows you to modify how a form is rendered, in your case the user modification form. There are more details on form modification here.

I am not 100% sure that's what you want to do though; (since it looks like you already must create a module) perhaps you want to hook into hook_user() instead; this function "... allows modules to react when operations are performed on user accounts.". You may be able to react to the category in this function and block/allow whichever user changes you like.

However, if it's just email address validation that is the problem, and if you are dealing with existing users, why don't you just make sure the email address is set before you save?

threecheeseopera
Yes, that is the problem... I'm editing my original post to elaborate a bit on this...
n00b0101