#after_build is not added in content_profile_registration_add_profile_form(). This can produce unexpected missing functionality provided by other modules defining form wide #after_build operations, as conditional_fields. Related issue: #795324: Latest 2.x-dev not compatible with content profile?.

Comments

StatusFileSize
new1.21 KB

Here's another patch with a working solution.

Note this patch is part of a solution to another issue that is stalled - #621346-3: Validate Multigroup (CCK3) Fields on User Registration Form

Patch in #1 did not work for me (using conditional fields on Content Profile in the registration form). I got it working with this: https://drupal.org/node/795324#comment-2981146

Status:Needs review» Closed (works as designed)

That's impossible to do it right in general. CP only cares about the CCK field forms, any additions won't be in.

Patch in #1 did work for me to get conditional fields to work on the main registration page.

I spent forever chasing down a problem with a geocode field.
Finally, I discovered that this user registration module doesn't honour the #after_build callbacks.

The normal sequence to build a form includes:
drupal_prepare_form
drupal_process_form
process_form calls formbuilder,
formbuilder runs the #after_build callbacks.

It's not uncommon for a contributed module to implement a field's functionality using an #after_build callback.

This user registration module works as follows;
- It uses a hook_form_alter to alter user_register form.
- Inside that hook, it partially creates a bunch of node-form types, copies parts of them back to the user_register form, and then throws the form_nodes away.
Because drupal_process_form doesn't get called on each node_form, the #after_build callbacks don't get called either.

Depending on how the contributed module works, you may be grabbing the field, but not grabbing all it's functionality.

So what's the solution
- should this module know how to play nice with the fields that it's grabbing?
- should other fields know about this module, and know that they need to stick a callback not only on user_node forms, but also user_register forms?
- should this module say "I only support this set {} of field types" (if so, then the fields shouldn't show up on admin/content/node-type/profile-personal/profile)

In my humble opinion, if you're going to interfere with the form building process in this manner, then it's your reponsability to make sure that the #after_build functions are called. Perhaps you shoud also have a peek at the form_builder() function itself, and see if there's any other important work that you need to replicate.

regarding the patches:

content_profile_registration_after_build.patch
- This patch fails, because of the way += works when the two arrays have matching keys. Consider the following:

before:
"$form['#after_build']" Array [1]
0 wysiwyg_process_form
"$node_form['#after_build']" Array [4]
0 climbing_partner_after_build
1 _flexifield_theme_node_form
2 geocode_widget_set_form_value
3 wysiwyg_process_form

after:
"$form['#after_build']" Array [1]
0 wysiwyg_process_form
1 _flexifield_theme_node_form
2 geocode_widget_set_form_value
3 wysiwyg_process_form

patch from comment 1
This patch looks like it will get the correct set of values into the callback array, but the order will be a little strange. Not sure if the order is important or not.

my patch
+ // add the callbacks
+ foreach (array('#after_build') as $type) {
+ $form[$type] = array_merge($form[$type], array_diff($node_form[$type], $form[$type]));
+ }
+
// Add in further callbacks needed, if not yet done.

Status:Closed (works as designed)» Needs work

I confirmed that this issue can also prevent flexifield from working correctly.

My intial symptom only involved geo, so I initially patched the code with something like this:

sites/all/modules/content_profile/modules/content_profile_registration.module:

  // Add in the new form elements into $form.
  $form += array('#field_info' => array());
  $form['#field_info'] += $node_form['#field_info'];
  $form += $form_add;
+ // add the geo callback, if needed
+ $form_add += array('#after_build' => array());
+ $form     += array('#after_build' => array());
+ if (   ( in_array('geocode_widget_set_form_value', $form_add['#after_build']))
+     && (!in_array('geocode_widget_set_form_value', $form['#after_build']))) {
+   $form['#after_build'][] = 'geocode_widget_set_form_value';
+ }

Later, after we fixed a non-related configuration issue with flexifield, we started getting SQL errors on user reg form submission. The SQL query in question involved flexifield. I remembered that flexifield also wanted an after_build callback, (see post #5) so I altered my patchwork, and that solved the flexifield SQL problem.

  // Add in the new form elements into $form.
  $form += array('#field_info' => array());
  $form['#field_info'] += $node_form['#field_info'];
  $form += $form_add;
+ // patch to add in all afterbuild functions
+ foreach (array('#after_build') as $type) {
+   $form += array($type => array());
+   $form_add += array($type => array());
+   $form[$type] = array_merge($form[$type], array_diff($node_form[$type], $form[$type]));
+ }

In case your wondering, the rational for using the foreach loop, is just in case someone else identifies another array inside $form_add that needs to get merged into $form. You can re-patch as follows:

foreach (array('#after_build', '#whatever') as $type) {

I'm seeing a similar problem with the Location module. With Content Profile Registration enabled a user cannot enter their location on registration. It won't save to the database. The patches aren't working for me.

The patch in #1 worked for me, getting conditional fields to work on registration pages. Thanks!

Status:Needs work» Needs review
StatusFileSize
new750 bytes

I agree with the comments in #5. Here is a patch. seems to work for me.

Status:Needs review» Reviewed & tested by the community

Patch looks good (maybe the comment should start with an uppercase A to match the other comments in this function, but that's minor and I won't reroll for that, otherwise I couldn't RTBC the pach ;-)).

The array approach seems reasonable too, as maybe #pre_render could be moved there in another issue, which would allow the use of cck's ordering without needing to reimplement it in content profile)

I have the same Problem, but in my case cck private fields don't work after a failed validation of the Registration form. Also none of the patches work for me...

@#12 : Do you mean functionnality provided by http://drupal.org/project/cck_private_fields ? If you do, then, it's quite unlikely to be the same problem, as this module doesn't use #after_build at all. Which would also explains why no patches in this issue fixes your problem: it's a different one...

Ok, then thats another Problem. I will start a new issue for that.

I have got a Problem with the Avatar Selection Module too, only when Content Profiles Registration Page ist active.

Status:Reviewed & tested by the community» Closed (works as designed)

I don't think adding in #after_build callbacks is a good thing when we are just taking over some fields of the form. The callbacks expect a node form, what is not here so they could fail.

In case, the module is configured to take over the whole form, I think the callbacks should have been already taken over.

Thanks to adamus_maximus & mrfelton. The patch in #10 worked for me, allowing me to add and execute an #after_build.