it-swarm-ja.com

参照されるエンティティを選択するEntityFieldQueryを作成する

タイプAのエンティティのIDを探しています。Aを参照するエンティティBのIDを知っています。

EntityFieldQueryに関するニースのソースをいくつか見つけました。私はグーグルで.NETから結果を得ていたことに驚きました:)(それはDrupalの成熟の兆候ですか?:)しかし、これを見つけることができませんでした。助けてください ...

ソースのいくつか:

これは、エンティティのロードでどのように見えるかです-私はそのクエリが必要であることを理解します:)ラッパーは主に練習用にあります。ターゲットエンティティをロードすることに注意してください-非常に多くのクエリ。

  $b = entity_load('B', array($id));
  $bm = entity_metadata_wrapper('B', $sl[$id]);

  $tsl = $slm->field_sl_tpref->value();
  echo $tsl->id;
10
mojzis

valueの代わりにtarget_idを使用して、参照されたエンティティのIDに基づいてエンティティを取得できます。

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', <type-of-the-entity>);
$query->fieldCondition('<name-of-the-field-referring-the-other-entity>', 'target_id', <id-of-the-referenced-entity>, '=');
$results = $query->execute();
15
pablo

エラー、 Relation Module はあなたが探しているものですか? XエンティティとYエンティティ間の関係を定義することが、やりたいことのように思えます。独自のRelationQuery(EFQのラッパー)とRelationQueryEndpointsを使用して、この種の情報を簡単に取得できます。

2
tenken

これは古い質問であることはわかっていますが、Googleからこれにアクセスする人にとっては、ここで別のアプローチを採用すると思いました。

上記の説明から、セットアップには2つのエンティティタイプ、AとBがあります。Bは、私が想定しているエンティティ参照を持つAを参照しています。したがって、IDがBの場合は、IDがAのフィールドがデータベースに格納されているはずです。

コードノート:

  • 元のNID-$original_node->nidこれはBのIDになります
  • バンドルタイプ-$typeこれはAのタイプである必要があります
  • フィールド条件は、参照を保持するフィールドを探すだけです
  • EFQの使用方法の詳細については、 this を参照してください

コード

// Start a new EFQ
$query = new EntityFieldQuery();

// Define query, the user load is probably not needed but sometimes is.
$query->entityCondition('entity_type', 'node')
      ->entityCondition('bundle', $type)
      ->fieldCondition('field_NAME_OF_FIELD', 'target_id', $original_node->nid, '=')
      ->addMetaData('account', user_load(1));

// Execute query, result with have node key
$result = $query->execute();

// If results it will be in node key
if (isset($result['node'])) {
  $nids = array_keys($result['node']);
  // This example has multiple nodes being referenced by one node
  $nodes = node_load_multiple($nids, array('type' => $type));
  // Devel module needed
  dpm($nodes);
}

また、双方向エンティティ参照を設定して、同じクエリを上記の逆方向に実行することもできます。 [〜#〜] cer [〜#〜] のようなモジュールを使用して、これらの参照を最新の状態に保つことができます。または、参照を最新に保つルールを設定します。私は両方を使用しました。

2
burnsjeremy

非常に動的な解決策(少し汚いですが、すぐに必要になりました)なので、参照フィールドの名前をハードコーディングする必要はなく、将来追加する新しい参照フィールドで自動的に処理されます。

カスタムモジュールで:

/**
 * Implement hook_field_create_instance().
 */
function MY_CUSTOM_MODULE_field_create_instance() {
  _MY_CUSTOM_MODULE_set_variable_node_back_references();
}

/**
 * Implement hook_field_delete_field().
 */
function MY_CUSTOM_MODULE_field_delete_field() {
  _MY_CUSTOM_MODULE_set_variable_node_back_references();
}

/**
 * Set Variable node_back_references.
 */
function _MY_CUSTOM_MODULE_set_variable_node_back_references() {
  $field_list = db_select('field_config', 'fc')
    ->fields('fc', array('field_name', 'data'))
    ->condition('fc.data', '%"foreign keys";a:1:{s:4:"node"%', 'like')
    ->condition('fc.deleted', 0);
  $field_list->innerJoin('field_config_instance', 'fci', 'fci.field_name = fc.field_name');
  $field_list->rightJoin('node_type', 'n', 'n.type = fci.bundle');
  $fields = $field_list->execute()->fetchAll();

  $fields_array = array();
  foreach ($fields as $field) {
    $unserialized = unserialize($field->data);
    if (isset($unserialized['settings']['handler_settings']['target_bundles'])) {
      foreach ($unserialized['settings']['handler_settings']['target_bundles'] as $bundle) {
        $fields_array[$bundle][] = $field->field_name;
      }
    }
  }

  variable_set('node_back_references', $fields_array);
}

function _MY_CUSTOM_MODULE_get_referencing_nodes($node) {
  $nids = array();
  $fields = variable_get('node_back_references', array());
  if (isset($fields[$node->type])) {
    foreach ($fields[$node->type] as $field) {
      $query = new \EntityFieldQuery();
      $query->entityCondition('entity_type', 'node');
      $query->propertyCondition('status', 1);
      $query->fieldCondition($field, 'target_id', $node->nid);
      $result = $query->execute();
      $nids = isset($result['node']) ? array_merge(array_keys($result['node']), $nids) : $nids;
    }
    $nodes = (!empty($nids)) ? node_load_multiple($nids) : array();

    return $nodes;
  }

  return $nids;
}

子ノードを指定して親ノードを取得する必要がある場合:

$nodes = _MY_CUSTOM_MODULE_get_referencing_nodes($node);
1
Gueno