Buat EntityFieldQuery yang memilih entitas yang direferensikan


10

Saya mencari ID entitas tipe A dan saya tahu ID entitas B yang mereferensikan A.

Saya menemukan beberapa sumber bagus tentang EntityFieldQuery. Saya kagum bahwa saya mendapatkan hasil dari .NET di google :) (apakah itu tanda kedewasaan Drupal? :). Tetapi tidak berhasil menemukan ini. Tolong bantu ...

Beberapa sumber:

Ini adalah apa yang tampak dengan beban entitas - Anda akan mengerti saya perlu permintaan itu :) Pembungkus ada untuk latihan terutama. Perhatikan bahwa ia memuat entitas target - cukup banyak permintaan.

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

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

1
Sebuah EntityFieldQueryhanya dapat referensi satu set entitas, tidak dapat menciptakan hubungan dengan entitas lain sayangnya. Itu juga hanya dapat mengembalikan satu jenis entitas sekaligus sehingga bahkan jika Anda dapat membuat hubungan ini hasilnya tidak dapat diandalkan.
Clive

@Clive maukah kamu menambahkan itu sebagai jawaban, jadi aku bisa mengonfirmasinya? terima kasih :)
mojzis

Jawaban:


15

Anda dapat menggunakan target_idalih-alih valueuntuk mengambil entitas berdasarkan ID entitas yang dirujuk:

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

terima kasih, tetapi saya tidak berpikir itu yang saya cari ... saya sedang mencoba untuk mendapatkan arah lain, dengan cara ini Anda akan tahu A dan mencari B :)
mojzis

2

err, apakah Modul Relasi apa yang Anda cari? Kedengarannya seperti mendefinisikan hubungan antara entitas X dan Y adalah apa yang ingin Anda lakukan. ia memiliki RelationQuery (pembungkus di sekitar EFQ) sendiri dan RelationQueryEndpoints untuk dengan mudah mendapatkan informasi seperti ini.


Terima kasih. sayangnya saya sudah menetapkan beberapa hubungan dengan entitasreference, jadi beralih ke hubungan akan bermasalah ... akan coba lain kali :).
mojzis

2

Saya tahu ini adalah pertanyaan yang lebih lama, tetapi untuk orang-orang yang mendapatkan ini dari Google saya pikir saya akan melakukan pendekatan lain di sini.

Dari uraian di atas pengaturan memiliki 2 jenis entitas, A dan B. B referensi A dengan referensi entitas yang saya asumsikan. Jadi, jika Anda memiliki id B Anda harus memiliki bidang dengan ID A yang disimpan dalam database.

Catatan Kode:

  • NID Asli - $original_node->nidIni akan menjadi ID B
  • Jenis bundel - $typeini harus menjadi tipe A
  • Kondisi lapangan hanya mencari bidang yang menyimpan referensi
  • Untuk info lebih lanjut tentang cara menggunakan EFQ lihat ini

Kode

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

Anda juga dapat mengatur referensi entitas dua arah dan melakukan permintaan yang sama di atas mundur. Anda dapat menggunakan modul seperti CER untuk memastikan bahwa referensi tersebut selalu diperbarui. Atau mengatur aturan agar referensi tetap terbaru, saya telah menggunakan keduanya.


Jika field_NAME_OF_FIELD bernilai multi, apakah itu fieldCondition('field_NAME_OF_FIELD', 'target_id', $original_node->nid, '=')berfungsi? harus diubah menjadi fieldCondition('field_NAME_OF_FIELD', 'target_id', array($original_node->nid), 'IN'). Tidak dapat menemukan apa pun tentang cara menerapkan kondisi pada bidang referensi entitas multinilai. ada saran?
kiranking

1
Saya tahu ini komentar lama tetapi jika Anda membiarkan '=' dari default EntityFieldQuery ke IN sehingga fieldCondition ('field_NAME_OF_FIELD', 'target_id', $ original_node-> nid) akan benar-benar berfungsi dalam situasi itu. Anda mungkin sudah tahu bahwa sekarang tetapi memetikan orang lain tersandung di kemudian itu :)
burnsjeremy

1

solusi yang cukup dinamis (agak kotor juga tetapi saya membutuhkannya dengan cepat) sehingga Anda tidak perlu membuat kode nama untuk bidang rujukan dan secara otomatis ditangani dengan bidang rujukan baru yang akan Anda tambahkan di masa mendatang:

dalam modul khusus Anda:

/**
 * 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;
}

di mana Anda perlu mendapatkan node induk diberikan simpul anak:

$nodes = _MY_CUSTOM_MODULE_get_referencing_nodes($node);
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.