it-swarm-ja.com

プログラムによるフィールドの更新、hook_node_update

現在、ノードが作成または更新されるたびにフィールドを更新しようとしています。ただし、値がノード内に入力されていない場合、この特定のフックでノードオブジェクトにアクセスできますか?何が欠けているのでしょうか?

  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

エンティティメタデータラッパー

エンティティAPIは、エンティティを簡単に処理し、提供されるエンティティプロパティ情報モジュールを活用するために使用できるいくつかのラッパークラスを提供します。ラッパーを使用して、プロパティ情報にアクセスしたり、既知のプロパティをループしたり、説明されたデータ値を取得/設定したりできます。

以下は、READMEにある簡単な使用例です。

この情報(メタデータ)を利用するために、モジュールは、値の取得と設定を容易にするいくつかのラッパークラスを提供します。ラッパーは、エンティティプロパティのラッパーを取得するためのチェーン使用をサポートします。ノード作成者のメールアドレスを取得するには、次のように使用できます。

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

ユーザーのメールアドレスを更新するには、次のように使用できます

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

または

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

ラッパーは常に、entity_get_property_info()を介して、またはラッパーから直接取得できるプロパティ情報で説明されているデータを返します。

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

出力用にサニタイズされたテキスト値を強制的に取得するために、使用できます。

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

サニタイズされたノードのタイトルを取得します。プロパティがノード本体のようにデフォルトですでにサニタイズされて返されている場合、他のユースケースでブラウザに表示されるように、サニタイズされていないデータを取得したい場合があります。これを行うには、「デコード」オプションを有効にします。これにより、サニタイズされたデータについて、タグが削除され、プロパティが返される前にHTMLエンティティがデコードされます。

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

そうすれば、ユーザーに表示されるデータを常に取得できます。ただし、サニタイズされたテキストデータであっても、未加工の未処理の値を取得したい場合は、次の方法で取得できます。

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

その他の例:

$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();

その他のドキュメントhttp://drupal.org/node/1021556

16
retif

_hook_node_update_の最後にfield_attach_update('node', $node)を呼び出すとうまくいきました。 _hook_node_insert_の最後のfield_attach_insert('node', $node)も機能すると思います。したがって、サンプル関数は次のようになります。

_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);
}
_

_node_load_ _node_save_を呼び出したり、何かを返す必要はありません。

その理由は、_node_save_および_hook_node_update_の呼び出し元である_hook_node_insert_がすべてのデータベースクエリをトランザクションでラップするためだと思います。 (_node_save_の最初の行に注意してください:$transaction = db_transaction()。)これらのクエリは、_node_save_が完了するまで呼び出されません。 _node_save_がトランザクションに追加する最後のクエリは_field_attach_update_から呼び出され、$ nodeオブジェクトをそのまま使用しますbefore _hook_node_update_が呼び出されます。したがって、もう一度_field_attach_update_を呼び出して、別のクエリをキューに入れる必要があります。少なくとも、それは何が起こっているかについての私の理解です。

ノードのフィールド以外の属性(_$node->log_など)を変更できない場合は、_node_save_revision($node, $user->uid, 'vid');を呼び出してみてください。これは新しいリビジョンを作成しません。

14
grobemo

これは、ノードの値を変更する方法です。

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

上記のランスのソリューションの改善により、いくつかのフィールド値のみが変更されたときにノード全体の保存を回避します。

_$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));
_

これは、node_save()の副作用を回避するのにも役立ちます。

ソース:ノード自体を保存せずにノードのフィールドを保存

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

1
amuli