Is it possible to use node_load() to check for a value in a cck field?

Something like:


$node_query['type'] = 'myccktype';
$node_query['field_mycckfield'] = array ( 0 => array ('value' => $mycckvaluetocheck ));

$node = node_load($node_query);

if (!$node)
{
     // Node doesn't exist..
}

The above doesn't work for me, so essentially if it's possible to query CCK fields using node_load() what is the proper format for my $node_query above?

Comments

nevets’s picture

node_load() only directly works with core tables so what you wish to do will not work using node_load.

roysteves’s picture

Oh?

$node = node_load($nid);
var_dump($node);

produces output which includes:
["field_myfield"]=> array(1) { [0]=> array(1) { ["value"]=> string(1) "X" }
In conclusion, it's in there somewhere, but it looks like cck fields are abstracted into arrays that yet perplex me. But they're in there.
Roy Steves

eoneillPPH’s picture

Yes, but if you look in the documentation (api.drupal.org) and read the node_load function, you'll see it only looks in the core tables (node and node_revisions), not in the tables created by CCK. Sad but true.

Here's what I do in a module that needs to load a CCK node (I think I adapted most of this from the Taxonomy Import module):

function [your module name]_get_[desired content type]_nid($value) {
   static $cache = array();

   $key = "$value";      // I needed to make sure "00023864" values stayed as strings -- 
                                 // quotes unnecessary? I wasn't sure
   if (isset($cache[$key])) {
      $nid = $cache[$key];
   }
   else {
      $query = "SELECT nid FROM {table where your field lives} WHERE field_[your field name] = '%s' LIMIT 1 ";
      // if the field is an integer type, change '%s' above to %d
      $nid = db_result(db_query($query, $key));
      if ($nid) {
         $cache[$key] = $nid;
      }
         else $nid = '';
   }
   return $nid;
}

Someday, I'll make it more generic so I don't keep writing a new one for each odd content type I need to search (requires dynamically naming the static $cache variable, among other things).

Then, your code could just do ...

$node = node_load([your module name]_get_[desired content type]_nid($value));

Place the function in a module and activate it, and you'd be able to use it in a page or view or block's php code block too, I presume. Haven't tried it yet.

What I usually use it for is during custom node imports from flat files and other odd data we need. If the node exists, I pass the nid in the node array to node_save and it decides to do an update; if not, it's empty and node_save does an insert. Remember that if you re-use a CCK field in another content type, that field will be moved to another table, where the multiple content types share it. There's probably some cool way to deal with that problem, but I haven't bothered yet. We have a policy of NOT re-using CCK fields for other content types.

If you're not doing repeated hits on this function (as I do), the caching is probably unnecessary and could be deleted.

Hope that helps someone
--eon--

Dracolyte’s picture

when you customize your node.tpl.php.
Since this is an old post you may have already thought of this long ago, but just in case...
I'm using it for a nodereference field that I do not want to link to its node -- instead I want it to display an image and a hyperlink to an external url.
So in node.tpl.php I capture the nodereference field, get the node id it references, load that node, then output the value of a CCK field "field_myfield" (which contains my hyperlink and image) like this:

$noderefnode = node_load($nid);
print $noderefnode->field_myfield[0]['value']; 

and voila, it prints the contents of my custom field.
Hope this is helpful.

junro’s picture

Hello,

It looks like exactly what I'm looking for:

I'm using Content template module and I'm looking for to use a node reference:

node-type A: field_title_france

node-type B: node reference A, the node referrence cck fielk name is: field_lien_fiche

Content template node-type B:

print $node->field_title_france[0]['view'] 

but how to use the node reference in it?? (field_title_france is a cck from node A)

I try:

$noderefnode = node_load($nid);
print $noderefnode->field_titre_france[0]['value'];

Any idea?

Thanks :)

Chris Einkauf’s picture

Put this in the template for node-type B:

$noderefnode = node_load($field_lien_fiche[0][nid]);
print $noderefnode->field_title_france[0]['value'];
junro’s picture

Thanks a lot!! It works! :)

Chris Einkauf’s picture

Basically, your original content type B code was just looking at the node ID of itself, which is of no interest when you want information about the type A node being referenced. What my code did was look at the node ID of the type A node that was being referenced, and then extract information from there.

junro’s picture

Thanks for the explanation! This code is perfect I think :)

junro’s picture

Strange, I'm using Roles with these fields and all of them appear

$noderefnode = node_load($field_lien_fiche[0][nid]);
print $noderefnode->field_title_vo[0]['value'].$noderefnode->field_title_france[0]['value']. $noderefnode->field_title_anglais[0]['value']. $noderefnode->field_title_espagne[0]['value']. $noderefnode->field_title_allemagne[0]['value'];

Users have to choose one role, and will only see the title in their role.

Any idea why roles don't have effect here?

Chris Einkauf’s picture

I guess the roles rules aren't being applied because you're only extracting the value of a field, and not all of the extra little fields that are normally rendered along with it.

You could try a code like this...

<?php
  global $user;

  $noderefnode = node_load($field_lien_fiche[0][nid]);

  if (in_array('espagne', array_values($user->roles))) {
    print $noderefnode->field_title_espagne[0]['value'];
  }
  if (in_array('france', array_values($user->roles))) {
    print $noderefnode->field_title_france[0]['value'];
  }
  //etc.

?>

I know it's not the optimal solution to hand-code each role into your code, but it's all I can think of. There's probably an easier and less-manual way, though.

junro’s picture

I try this but doesn't work.

I try change something in this code, and it was a big mystake.

I can't go back to the contemplate edit page... I can't go to the node page. I've got:

Fatal error: Call to undefined function array_value() in /home/pariscin/www/sites/all/modules/contemplate/contemplate.module(834) : eval()'d code on line 22

How to rechange the code? lol

Without deleting the template?

Chris Einkauf’s picture

So you typed that code into contemplate and now you can't get back to the contemplate edit page for that specific template, or you can't get back to the contemplate page that lists all of the contemplate templates? (In other words, is your contemplate installation completely broken now, or does it just have to do with this one content type?)

junro’s picture

can't get back to the contemplate edit page for that specific template,

but don't worry, I deleted it and rebuilt it in 5 min. :)

I tried this code too:

  global $user;

  $noderefnode = node_load($field_lien_fiche[0][nid]);

  if (in_array('france', array_values($user->roles[5]))) {
    print $noderefnode->field_title_france[0]['value'];
  }

The php code shouldn't be good.

Maybe something like:

if $user->roles[5] print...

I'm not an expert in php, I began a few month ago with php :)

Chris Einkauf’s picture

Try this code instead:

<?php
  global $user;

  $noderefnode = node_load($field_lien_fiche[0][nid]);

  if (in_array('espagne', $user->roles)) {
    print $noderefnode->field_title_espagne[0]['value'];
  }
  if (in_array('france', $user->roles)) {
    print $noderefnode->field_title_france[0]['value'];
  }
  //etc.

?>
junro’s picture

nothing appears at all

junro’s picture

  global $user;

  $noderefnode = node_load($field_lien_fiche[0][nid]);

  if (array('espagne', $user->roles)) {
    print $noderefnode->field_title_espagne[0]['value'];
  }
  if (array('france', $user->roles)) {
    print $noderefnode->field_title_france[0]['value'];
  }
  //etc.

This works, but all roles appear.

in_array to array

junro’s picture

Using (array('espagne', array_values($user->roles))) or (array('espagne', $user->roles)) is the same.

Chris Einkauf’s picture

<?php

  global $user;

  $noderefnode = node_load($field_lien_fiche[0][nid]);

  foreach($user->roles as $rid => $role){
     if($role == "espagne"){
       print $noderefnode->field_title_espagne[0]['value'];
     }
     if($role == "france"){
       print $noderefnode->field_title_france[0]['value'];
     }
     //etc.
  }


?>
junro’s picture

nothing appears :)

junro’s picture

but why if($role == "france") ?

It shouldn't be if($user->roles[5]) ?

junro’s picture

Funny, I try this:


  global $user;

  $noderefnode = node_load($field_lien_fiche[0][nid]);

  foreach($user->roles as $rid => $role){
     if($user->roles[8]){
       print $noderefnode->field_title_espagne[0]['value'];
     }
     if($user->roles[5]){
       print $noderefnode->field_title_france[0]['value'];
     }

  }

I've got: field_title_france[0]['value'] 3 times

Chris Einkauf’s picture

I was just assuming that one of the role names was "france". Let's assume you have a role named "france" with a role id of 8. Either of these 2 methods should work I believe:

<?php

  global $user;

  $noderefnode = node_load($field_lien_fiche[0][nid]);

  foreach($user->roles as $rid => $role){
     if($role == "france"){
       print $noderefnode->field_title_france[0]['value'];
     }
     //etc.
  }


?>
<?php

  global $user;

  $noderefnode = node_load($field_lien_fiche[0][nid]);

  foreach($user->roles as $rid => $role){
     if($rid == 8){
       print $noderefnode->field_title_france[0]['value'];
     }
     //etc.
  }


?>
junro’s picture


  global $user;

  $noderefnode = node_load($field_lien_fiche[0][nid]);

  foreach($user->roles as $rid => $role){
     if($rid == 8){
       print $noderefnode->field_title_france[0]['value'];
     }
     //etc.
  }


works great!!

I had really appreciate your help, thanks a lot :)

nevets’s picture

Note there is no need for the loop, you could just write

global $user;

if (  !empty($user->roles[8]) ) {
   print $noderefnode->field_title_france[0]['value'];
}
junro’s picture

oh ok! Thanks :)

hum Nothing appears

Chris Einkauf’s picture

Don't forget the line that reads $noderefnode = node_load($field_lien_fiche[0][nid]);

So, the code would be:

<?php
  global $user;

  $noderefnode = node_load($field_lien_fiche[0][nid]);

   if (!empty($user->roles[8]) ) {
       print $noderefnode->field_title_france[0]['value'];
   }
     //etc.
  }
?>
junro’s picture

Oh sure forgot it! Thanks.

junro’s picture

Just a last question as you look like to know very well nodereferrence stuff :)

Is it possible to use a nodereference with C from A?

A contains field_title_france

B reference to A, display field_title_france

C reference to B, display field_title_france possible??

Without using a new nodereferrence field with C and A.

Chris Einkauf’s picture

This is in response to your "Just a last question as you", but I'm bringing it over to the left so there's more room...

Yes, that's possible. The code would look like this:

<?php 
//this code would go in your content type C template...
$nodebdata = node_load($field_noderef_inc_tob[0][nid]);
$nodeadata = node_load($nodebdata[field_noderef_inb_toa][0][nid]);
print $nodeadata->field_a_field[0]['value'];
?>

Notes:
-field_noderef_inc_tob is the node reference field in content type C that references a type B node
-field_noderef_inb_toa is the node reference field in content type B that references a type A node
-field_a_field is the field in content type A that you want to display in content type C
-I created the variable $nodebdata to temporarily store the data about the referenced type B node
-I created the variable $nodeadata to temporarily store the data about the referenced type A node
-You'll also have to add in the permissions code like we discussed above. Same method as above. (Not including it here so as not to confuse people reading this in the future).

junro’s picture

Hello,

It doesn't work, crash the template page again (can't get back to the contemplate edit page for that specific template).

Fatal error: Cannot use object of type stdClass as array in /home/pariscin/www/sites/all/modules/contemplate/contemplate.module(834) : eval()'d code on line 32

$nodebdata = node_load($field_lien_fiche[0][nid]);
$nodeadata = node_load($nodebdata[field_lien_fiche][0][nid]);
print $nodeadata->field_title_france[0]['value'];

My node referrence cck field is "field_lien_fiche".

I'm using the same node referrence field in node type B and node type C. Could be a problem with this code? (I don't think so, but i'm not an expert.)

Chris Einkauf’s picture

I think I accidentally thought node_load would load that data as an array. Kind of stupid of me to think, seeing as how with my original node_load I treated the loaded data as an object and not as an array. This code should work I think...

<?php

$nodebdata = node_load($field_lien_fiche[0][nid]);
$nodeadata = node_load($nodebdata->field_lien_fiche[0][nid]);
print $nodeadata->field_title_france[0]['value'];
?>
junro’s picture

Damm, you're good!! lol

It works perfectly!

Thanks! :)

Chris Einkauf’s picture

:)