#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

jonhattan’s picture

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

JThan’s picture

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

fago’s picture

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.

murias’s picture

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

adamus_maximus’s picture

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.

adamus_maximus’s picture

Status:Closed (works as designed)» Needs work
adamus_maximus’s picture

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) {

scalp’s picture

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.

loze’s picture

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

mrfelton’s picture

Status:Needs work» Needs review
StatusFileSize
new750 bytes

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

DeFr’s picture

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)

Donngal’s picture

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...

DeFr’s picture

@#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...

Donngal’s picture

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.

fago’s picture

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.

joekrukosky’s picture

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