How to set form element order with field_attach_form (and why does it do it?) Problem

I'm attaching the user register form to the add node form using hook_form_alter (for a custom content type). (Forcing an anonymous user to register when they create a node.)

My solution to this problem, has been to put a large chunk of the user register code into hook_form_alter (because I'm a "great" developer).

While this works in a custom form, in hook_form_alter the following function

 field_attach_form('user', $form['#user'], $form, $form_state, $langcode);


Causes the register fields to always appear in the middle of the form. (#weight does nothing.)

Reading through the documentation, it appears this function always puts the fields at the top of $form_state['values'] and you can change it by setting the #parents property on the incoming $form parameter.

2 Questions:


Why does the order in $form_state effect the display of my form? I thought the #weight property in the form elements determined this.
I don't really understand how to set the parents property. Do I need to create a parent which encompasses all of the standard node add form, and then set this new form relative to that?


More code in case it's wanted.

mymodule_form_alter (&amp;$form, $form_state, $form_id) {

...

if (user_is_anonymous($user)) {

    $admin = user_access('administer users');

    $form['administer_users'] = array(
       '#type' =&gt; 'value',
       '#value' =&gt; $admin,
    );

    $form['#user'] = drupal_anonymous_user();
    $form['#user_category'] = 'register';

    $form['#attached']['library'][] = array('system', 'jquery.cookie');
    $form['#attributes']['class'][] = 'user-info-from-cookie';

    $account = $form['#user'];
    $register = ($form['#user']-&gt;uid &gt; 0 ? FALSE : TRUE);

    $form['#validate'][] = 'user_account_form_validate';

    $form['account'] = array(
      '#type'   =&gt; 'container',
      '#weight' =&gt; 61,
    );

    .... //form elements for user reg like password, username email etc. go in here...

    $langcode = entity_language('user', $form['#user']);
    field_attach_form('user', $form['#user'], $form, $form_state, $langcode);
    foreach (field_info_instances('user', 'user') as $field_name =&gt; $instance) {
      if (empty($instance['settings']['user_register_form'])) {
        $form[$field_name]['#access'] = FALSE;
      }
    }

}
I can't really offer much explanation here but here's my solution. I suspect it has something to do with having a single form create two entities and how you need to separate that to allow both to be created. 

The above created both, but didn't order the form correctly. The solution below does both.

The solution came from bundling up everything to do with user registration and attaching it inside a form container as opposed to just putting it in the form.

As I mentioned in the question, the documentation says this function always attaches to the top of the form, so you position the form container at the bottom then put it in that.

Here are the updated sections of my code, only two sections changed, the rest stayed the same. So you can just add the following parts to the code above.

   ....

   $form['account'] = array(
     '#type'   =&gt; 'container',
     '#weight' =&gt; 61,
   );

   //The new form container I added is below

   $form['user_reg'] = array(
     '#type'   =&gt; 'container',
     '#weight' =&gt; 62,
   );

   ....
   //added variables for clearer reading
   $account = $form['#user'];

   //The crucial part is the third parameter. This attaches it to a container rather
   //than the standalone form
   field_attach_form('user', $account, $form['user_reg'], $form_state, $langcode);