web-dev-qa-db-fra.com

Mise à jour d'un champ par programme, hook_node_update

Vous essayez actuellement de mettre à jour un champ chaque fois qu'un nœud est créé ou mis à jour. Cependant, la valeur n'est pas remplie dans le nœud, ai-je accès à l'objet nœud avec ce crochet particulier? Que pourrais-je manquer?

  function vbtoken_node_update($node) {


      entity_get_controller('node')->resetCache(array($node->nid));


      $types = node_type_get_types(); //What are the current Node Content Types?
      $yes = ($types['volunteer_project']->type);

      if($node->type === $yes){


        $hash = md5($node->title . $node->nid . $node->nid);
        $hashed = substr($hash, 0, 6);
        $node = node_load($node->nid);
        $node->tcode[$node->language][0]['value'] = $hashed;
        node_save($node);

        watchdog('vbtoken', 'Added a new Token code to %nid', array('%nid' => $node->nid));

        }
        else 
        {
          dpm('not working dude');
        }

    }
13
generalconsensus

Encapsuleurs de métadonnées d'entité

L'API d'entité fournit certaines classes d'encapsuleur que vous pouvez utiliser pour traiter facilement les entités et tirer parti des modules d'informations sur les propriétés d'entité fournis. Avec l'aide des wrappers, vous pouvez accéder aux informations de propriété, parcourir les propriétés connues, ou simplement obtenir/définir les valeurs de données décrites, etc.

Voici quelques exemples d'utilisation simples que l'on trouve dans le fichier README:

Pour utiliser ces informations (métadonnées), le module fournit des classes wrapper qui facilitent l'obtention et la définition de valeurs. L'encapsuleur prend en charge l'utilisation enchaînée pour récupérer les encapsuleurs des propriétés d'entité, par ex. pour obtenir l'adresse e-mail d'un auteur de nœud, on pourrait utiliser:

$wrapper = entity_metadata_wrapper('node', $node);
$wrapper->author->mail->value();

Pour mettre à jour l'adresse e-mail de l'utilisateur, on pourrait utiliser

$wrapper->author->mail->set('[email protected]');

ou

$wrapper->author->mail = '[email protected]';

Les wrappers retournent toujours les données comme décrit dans les informations de propriété, qui peuvent être récupérées directement via entity_get_property_info () ou à partir du wrapper:

$mail_info = $wrapper->author->mail->info();

Afin de forcer l'obtention d'une valeur textuelle purifiée pour la sortie, on peut utiliser, par ex.

$wrapper->title->value(array('sanitize' => TRUE));

pour obtenir le titre du nœud aseptisé. Lorsqu'une propriété est déjà retournée nettoyée par défaut, comme le corps du nœud, on peut éventuellement obtenir les données non filtrées telles qu'elles apparaîtront dans un navigateur pour d'autres cas d'utilisation. Pour ce faire, on peut activer l'option "décoder", qui garantit que pour toutes les données filtrées, les balises sont supprimées et les entités HTML sont décodées avant le retour de la propriété:

$wrapper->body->value->value(array('decode' => TRUE));

De cette façon, on obtient toujours les données comme indiqué à l'utilisateur. Cependant, si vous voulez vraiment obtenir la valeur brute et non traitée, même pour les données textuelles filtrées, vous pouvez le faire via:

$wrapper->body->value->raw();

Plus d'exemples:

$wrapper->body->set(array('value' => "content"));
$wrapper->field_text[0] = 'the text';
$wrapper->field_text[0]->set(array('value' => "content"));
$wrapper->field_text2->summary = 'the summary';
$wrapper->field_text2->value = 'the text';

$wrapper->save();
$wrapper->delete();

Plus de documents : http://drupal.org/node/1021556

16
retif

L'appel de field_attach_update('node', $node) à la fin de hook_node_update A fonctionné pour moi. Je suppose que field_attach_insert('node', $node) à la fin de hook_node_insert Fonctionnerait aussi. Ainsi, un exemple de fonction ressemblerait à ceci:

function mymodule_node_update($node) {
  $new_value = // ...do some stuff to compute a new value for the field.
  $node->field_my_field[LANGUAGE_NONE][0]['value'] = $new_value;
  field_attach_update('node', $node);
}

Il n'est pas nécessaire d'appeler node_loadnode_save Ou de retourner quoi que ce soit.

Je pense que la raison en est que node_save, À partir duquel hook_node_update Et hook_node_insert Sont appelés, encapsule toutes les requêtes de base de données dans une transaction. (Notez la première ligne de node_save: $transaction = db_transaction().) Ces requêtes ne sont pas appelées avant la fin de node_save. La dernière requête que node_save Ajoute à la transaction est appelée depuis field_attach_update, Qui utilise l'objet nœud $ tel qu'il est avanthook_node_update Est appelé. Vous devez donc mettre en file d'attente une autre requête en appelant à nouveau field_attach_update. C'est du moins ce que je comprends de ce qui se passe.

Si vous ne parvenez pas à modifier les attributs hors champ du nœud (par exemple, $node->log), Essayez également d'appeler _node_save_revision($node, $user->uid, 'vid');. Cela ne créera pas de nouvelle révision.

14
grobemo

Voici comment vous modifiez les valeurs sur un nœud:

$node = node_load($nodeID);
$node->field_fieldname['und'][0]['value'] = $val;
node_save($node);
2
Lance

Une amélioration de la solution de Lance ci-dessus, évitant la sauvegarde d'un nœud entier lorsque seules quelques valeurs de champ sont modifiées:

$node = node_load($nodeID);
// for each field whose value remains unchanged
unset($node->field_<field-name>); 
// for each field whose value changes
$node->field_<field-name>[LANGUAGE_NONE][0]['value'] = <new-value>;
field_attach_update('node', $node);
entity_get_controller('node')->resetCache(array($node->nid));

Cela pourrait également être utile pour éviter les effets secondaires de node_save().

Source: Enregistrement des champs du nœud sans enregistrer le nœud lui-même

https://www.urbaninsight.com/2011/10/24/saving-nodes-fields-without-saving-node-itself

1
amuli