Code from another issue (#368612: Unable to Connect to Distribution):

      // nodereference
      if (module_exists('nodereference')) {
      $fields = content_fields();
       
        if (!empty($fields)) {
          foreach($fields as $content_type_field){
            if ($content_type_field['type_name'] == $node->type && $content_type_field['module'] == 'nodereference') {
          if(!empty($node->$content_type_field['field_name'])){
                watchdog ('noderef', 'field found: ' . $content_type_field['field_name']);
                // $node->$content_type_field['field_name'][0][nid]

                $nr_data = $node->$content_type_field['field_name'];
                if (isset($nr_data[0]['nid']) && $nr_data[0]['nid'] != '') {
                  $nr_newids = array();
                  // Loop all values
                  foreach ($nr_data as $nr_key => $nr_item) {
                    // Try to find the new node id
                    watchdog ('noderef', 'looking for ' . $nr_item['nid']);
                     
                    $result = db_query("select nid, original_nid FROM {content_retriever} as c WHERE c.original_nid = %d", $nr_item['nid']);
                    $nr_new = (int)db_result($result);
                    if ($nr_new && $nr_new != 0) {
                      watchdog ('noderef', 'new id = ' . $nr_new);
                      $nr_newids[] = array (nid => $nr_new);
                    }
                    else {
                      // Remove the reference
                      watchdog ('noderef', 'didnt find id ' . $nr_item['nid']);
                     
                    }
                  }
                  $node->$content_type_field['field_name'] = $nr_newids;
            }
          }
          }
          }
        }
      }

Haven't time to make a patch; posting here for someone else to find :)

Comments

luketsimmons’s picture

Version: 6.x-1.x-dev » 6.x-2.0-beta4

Hi joachim,

Noticed this code is from http://drupal.org/node/368612, the patch on there seemed to pick up a lot of whitespace corrections which I guess are sorted now?

Also plopping this code in _content_retriever_save_node() eventually works (the code above doesn't cater for shared node reference fields, i.e. multiple types referring to one type) but a cleaner way would be to use the content_retriever_node_presave() hook, like you did for filefield?

If so I'll maybe have a look at doing this because it would be a great addition to the module.

Thanks,

Luke

joachim’s picture

Yup -- basically, that issue was a mix of things and the patch had tons of other stuff in it, so this above is just the meat of it which I filed as a fresh issue.

Looking at the code as it is now, this should either go in content_retriever.content_retriever_node_process.inc as a proxy hook implementation, or it should be a submodule and sit alongside content_retriever_process_filefield. Probably the latter, as non-core things should get their own module.

luketsimmons’s picture

Status: Active » Needs review
StatusFileSize
new2.06 KB

Hi joachim,

Cool, I've had a look and it's done :-) I agree with your point about where it would fit best, so please find attached a sub module for content retriever - content_retriever_process_nodereference.

As I said before I've tweaked it so it works for the same nodereference field being used in more than one content type, as the type_name for a field is set to the first content type it is used on, so checking that wouldn't work for other content types.

Have a look and let me know if it's missing anything, I've tested it out and it seems to work as expected!

Thanks,

Luke

joachim’s picture

Status: Needs review » Needs work

Looks good in general.

Just a few things...

- needs a newline at the end of the file
- the 'field_name' key looks wrong:

$node->$content_type_field['field_name'] = $noderef_ids;

- are both checks necessary? I do hate PHP's handling of truthiness...

if ($noderef_new && $noderef_new != 0) {
luketsimmons’s picture

Hi joachim,

- Newline is no problem.
- For the field key bit, the $node->$content_type_field['field_name'] is a variable property, so the property of the node object we are looking at is the value of $content_type_field['field_name']. If that makes sense? So PHP see the value as $node->field_node_ref_id, "field_name" is just the array key of the field name in the content_fields() array.
- Yer I agree on the odd looking check double check, it was from the original code but I guess we could change it if need be. From what I understand -

if ($noderef_new) {

That would check that the return from the DB query is not FALSE, i.e. TRUE or is a MySQL resource.

if ($noderef_new != 0) {

This would check that the NID returned is an integer that we can use.

So it is necessary but alternatively we could make it tidier by doing -

$nr_new = $result != FALSE ? (int)db_result($result) : 0;

if ($noderef_new != 0) {

Dropping the first check after we get the node ID but ensuring we do check the validity of the MySQL query.

How does that sound? I just wanted to check before I changed it and reposted.

Thanks,

Luke

joachim’s picture

$node->$content_type_field['field_name']

See I'm reading that as: Get the property $node->$content_type_field. It's an array. Get its 'field_name' key.

And what it actually means is: get the string in $content_type_field['field_name']. Find the property of $node that has this name.

Does PHP do the right thing here? Do we need {} in there? Can we put them in anyway for readability?
I guess we can always do:

$field_name = $content_type_field['field_name'];
dostuffto($node->$field_name);

luketsimmons’s picture

Morning joachim,

That's cool, yes PHP will do what we want it, I can understand that the readability of what it is doing isn't ideal, so yes there is no harm in clarifying it for maintenance purposes with the method you suggest, I'll make the change.

Putting the variable in curly braces is really only for specifying the variable exactly, i.e. if it's in a string "Show me some {$variable}s"; or if it's a variable variable.

Thanks,

Luke