Coming from #2708419: Wrong parameter type hint in docblock

profile2_regpath uses a custom page callback to build the user registration form. In this page callback it already has all the $profile2_regpath objects. But later in hook_form_alter(), it tries to load the objects again, by examining $form['#action']. This is unnecessarily complex, and it is currently not supporting the "tabs" paths, as can be seen in #2505973: Profile2 fields only show up when Show on all user account forms is checked

Solution:

function _profile2_regpath_user_register($regpath) {
  module_load_include('pages.inc', 'user', 'user');

  /* @see drupal_get_form() */
  $form_state = array();
  $form_state['build_info']['args'] = array();
  // Add information to $form_state, that will later be picked up in
  /* @see profile2_regpath_form_alter() */
  $form_state['build_info']['_profile2_regpath'] = $regpath;
  $output = drupal_build_form('user_register_form', $form_state);

  _profile2_regpath_set_title($regpath, 'register_title');
  return $output;
}

The $form_state['build_info']['_profile2_regpath'] can later be picked up in hook_form_alter(), thus avoiding the fragile path acrobatics.

Before:

function profile2_regpath_form_alter(&$form, &$form_state, $form_id) {
  [..]
      // Get profile2 profile types from current path.
      $url = drupal_parse_url($form['#action']);
      $path = ltrim($url['path'], '/');

      // Check to see if this is an alias. If so, use source path.
      if ($source = drupal_lookup_path('source', $path)) {
        $path = $source;
      }

      // Grab first part of URL.
      $path_parts = explode('/', $path);
      $path_key = reset($path_parts);

      // Load profiles for this path key.
      $profile_types = profile2_regpath_regpath_load_multiple(array('path' => $path_key, 'status' => 1));

After:

function profile2_regpath_form_alter(&$form, &$form_state, $form_id) {
  [..]
      $profile_types = $form_state['build_info']['_profile2_regpath'];

I am not posting this as a patch, because for a satisfactory solution more work is needed:
- $profile_types is a wrong variable name, because the objects are not from profile2 but from the profile2_regpath table.
- $regpath is a wrong variable name, because it contains an array of objects, not just one.

This will likely fix #2505973: Profile2 fields only show up when Show on all user account forms is checked

Comments

donquixote created an issue.

donquixote’s picture

It can be done even simpler.
With something like this:

function _profile2_regpath_user_register($regpath) {
  module_load_include('pages.inc', 'user', 'user');

  /* @see drupal_get_form() */
  $form_state = array();
  $form_state['build_info']['args'] = array();
  // Add information to $form_state, that will later be picked up in
  /* @see profile2_form_user_register_form_alter() */
  foreach ($regpath as $regpath_object) {
    $type_name = $regpath_object->profile_type;
    $form_state['profiles'][$type_name] = profile2_create(array('type' => $type_name));
  }
  $output = drupal_build_form('user_register_form', $form_state);

  _profile2_regpath_set_title($regpath, 'register_title');
  return $output;
}

Now profile2_regpath no longer needs to do much in hook_form_alter(). Because profile2 itself already does the job.

As mentioned above, I am not posting this as a patch, because there are too many other things I would not be able to resist to fix them too. So I rather not touch it at all.