-2

I have an entityreference field that references a redhen_contact entity. I want to set the node's author to be the user associated with the contact referenced in this field.

This is part of a (I think, rather basic) custom rendition of the node form via hook_menu() and drupal_get_form.

I can get the user from the entityreference field and I can print its name, uid, email etc. with drupal_set_message. And when I print $node->uid with drupal_set_message it shows up as if I was successful, but it gets overridden apparently and I have no idea where. The saved nodes always show that I'm the author (as I'm the one submitting the form).

I first tried using hook_form_alter(), then I tried using hook_node_presave(), then hook_node_insert(). I don't know of any hooks that fire later. But maybe one of these hooks would work if I did it right?

Here's most of what I've tried:

<?php
function mymodule_register_existing_adult_submit($form, &$form_state) {
  $registrant_id = $form['#node']->field_registrant['und'][0]['target_id'];
//  $contact_wrapper = entity_metadata_wrapper('redhen_contact', $registrant_id);
//  $registrant_name = $contact_wrapper->label();
//  $registrant_email = $contact_wrapper->email->value();
//  $registrant_user = $contact_wrapper->user->value();
//  $registrant_url = $contact_wrapper->user->value();
//  drupal_set_message(t("Hey this works! " . "ID=" . $registrant_id . " " . $registrant_name . " " . $registrant_email . "<br>" . $registrant_user->uid));
//  sdpm($form);
  //$form['additional_settings']['group']['#groups']['additional_settings'][0]['name']['#value'] = $registrant_user->uid;
  //$form['additional_settings']['group']['#groups']['additional_settings'][0]['name']['#default_value'] = $registrant_user->uid;
  //$form['author']['name']['#default_value'] = $registrant_user->uid;
  //$form['author']['name']['#value'] = $registrant_user->uid;
  //$form_state['complete form']['uid']['#value'] = $registrant_user->uid;
  //$form_state['complete form']['uid']['#value'] = $registrant_email;
  //$form_state['values']['uid'] = $registrant_user->uid;
  //$form_state['build_info']['args'][0]->uid = $registrant_user->uid;
  //$form['uid'] = $registrant_user->uid;
//  $form['#node']->uid = $registrant_user->uid;
  //dpm($contact_wrapper->getPropertyInfo());
  $form_state['redirect'] = 'redhen/contact/' . $registrant_id . '/view/edit';
}
function mymodule_node_presave($node) {
  if ( $node->type == 'program_registration' ) {
    $registrant_id = $node->field_registrant['und'][0]['target_id'];
    $contact_wrapper = entity_metadata_wrapper('redhen_contact', $registrant_id);
    $registrant_user = $contact_wrapper->user->value();
    $node->author = $registrant_user->name;
    drupal_set_message('Hook implemented successfully.<br>User ID: ' . $registrant_user->uid);
    drupal_set_message($node->author);
    sdpm($registrant_user);
  }
}
function mymodule_node_insert($node) {
  $path = current_path();
  if ( $path == 'admin/register-existing-adult' ) {
    drupal_set_message('hook_node_insert author: ' . $node->author . '<br>Path: ' . $path);
    $registrant_id = $node->field_registrant['und'][0]['target_id'];
    $contact_wrapper = entity_metadata_wrapper('redhen_contact', $registrant_id);
    $registrant_user = $contact_wrapper->user->value();
    $node->author = $registrant_user->uid;
    $node->uid = $registrant_user->uid;
  }
}

Edit:

Where I'm at now is I've cleaned up the code to see more precisely what's going one:

<?php
function mymodule_node_presave($node) {
  if ( $node->type == 'program_registration' ) {
    $registrant_id = $node->field_registrant['und'][0]['target_id'];
    $contact_wrapper = entity_metadata_wrapper('redhen_contact', $registrant_id);
    $registrant_user = $contact_wrapper->user->value();
    $node->author = $registrant_user->name;
  }
}
function mymodule_node_insert($node) {
  $path = current_path();
  if ( $path == 'admin/register-existing-adult' ) {
    drupal_set_message('author: ' . $node->author);
  }

Here hook_node_insert() is successfully printing the email address for the user associated with the contact entity. So it seems that the code in hook_node_presave() works, except that it must then be overwritten by Drupal afterwards? Or maybe the email address is not a valid value for the node author?

1

The hook depends on what you want to do and when. I don't think that you need to implement the code in hook_form_alter as will be executed every time you access that form. Try in your hook_node_insert to use field_attach_update('node', $node); in order to update your node. Also check https://www.drupal.org/node/2453099. In similar situation (I had to change the author after submit) I created a callback for the specific form where I was changing the author. Finally, keep in mind that when you altering a node you need to save/update it.

  • Thanks but no success yet. I simply added field_attach_update('node', $node); to the end of the hook_node_insert() function but that had no effect, not sure if there's more I should have done for that. I looked around that post from d.o but calling node_save() yielded "duplicate entry" PDOException errors. The callback you created when changing author after submit... that was a submit callback function that you added to the form via hook_form_alter? I just added more information to the question. – alec Sep 22 '17 at 13:21
  • 1
    Yes @alec, I'm working on D8 but it's the same more or less. I think submit callback is the best option. Have a look at this link drupal.stackexchange.com/questions/219752/… I think is exactly what you need – Ismini Sep 22 '17 at 14:06
0

Thanks to the link in the accepted answer by Ismini, I figured out how to do this in a form submit callback function.

<?php
/**
 * Implements hook_form_FORM_ID_alter().
 * Use this to call your submit function below.
 */
function roots_reg_form_program_registration_node_form_alter(&$form, $form_id, $form_state) {
  $path = current_path();
  if ($path == 'admin/register-new-adult/program') {
    $form['actions']['submit']['#submit'][] = 'mymodule_register_existing_adult_submit';
  }
}

function mymodule_register_existing_adult_submit($form, &$form_state) {
  $registrant_id = $form['#node']->field_registrant['und'][0]['target_id'];
  $contact_wrapper = entity_metadata_wrapper('redhen_contact', $registrant_id);
  $registrant_user = $contact_wrapper->user->value();
  // the following lines made the critical difference
  $nid = $form_state['values']['nid'];
  $node = node_load($nid);
  $node->uid = $registrant_user->uid;
  // calling node_save() is necessary but not at all obvious.
  node_save($node);
}
0

Another solution, alternate to doing it in the form submit callback, is to add $node->uid = $registrant_user->uid; to hook_node_presave(). In this case I had simply missed the needle in the haystack. So the function could look like:

function mymodule_node_presave($node) {
  $path = current_path();
  if ( $path == 'admin/register-existing-adult' ) {
    $registrant_id = $node->field_registrant['und'][0]['target_id'];
    $contact_wrapper = entity_metadata_wrapper('redhen_contact', $registrant_id);
    $registrant_user = $contact_wrapper->user->value();
    // $node->author = $registrant_user->name;
    // doesn't seem to work
    // but...
    $node->uid = $registrant_user->uid;
    // does :)
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.