Başvurulan varlıkları seçen bir EntityFieldQuery oluşturun


10

A tipi varlığın kimliğini arıyorum ve A'ya başvuran B varlığının kimliğini biliyorum.

EntityFieldQuery hakkında birkaç güzel kaynak buldum. Ben google :) (Drupal'ın olgunluğunun bir işareti mi? :) :) .NET sonuçları almak olduğunu şaşırdım. Ama bunu bulmayı başaramadı. Lütfen yardım et ...

Kaynaklardan bazıları:

Bu varlık yükleri ile neye benzediğini anlayacaksınız - bu sorguya ihtiyacım olduğunu anlayacaksınız :) Sarıcı esas olarak uygulama için var. Hedef varlığı yüklediğini unutmayın - oldukça fazla sorgu.

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

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

1
Bir EntityFieldQuery, yalnızca bir varlık kümesine başvurabilir, maalesef diğer varlıklarla ilişki oluşturamaz. Ayrıca, aynı anda yalnızca bir tür varlık döndürebilir , bu nedenle bu ilişkileri oluşturabilseniz bile sonuçlar güvenilir olmaz.
Clive

@Clive bunu bir cevap olarak eklemeyi düşünür müsünüz, böylece onaylayabilir miyim? teşekkürler :)
mojzis

Yanıtlar:


15

Başvurulan varlıkların kimliğine dayalı varlıkları almak target_idyerine kullanabilirsiniz value:

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

teşekkürler, ama ben aradığım şey olduğunu sanmıyorum ... ben diğer yönü almaya çalışıyordum, bu yolla A'yı bilir ve
B'yi ararsınız

2

err, aradığınız İlişki Modülü nedir? Yapmak istediğiniz şey X ve Y varlıkları arasındaki ilişkileri tanımlamak gibi görünüyor. bu tür bilgileri kolayca almak için kendi RelationQuery (EFQ etrafında bir sarıcı) ve RelationQueryEndpoints özellikleri vardır.


Teşekkürler. ne yazık ki ben zaten enterprisereference ile birkaç ilişki tanımladım, bu yüzden ilişkiye geçmek sorunlu olurdu ... bir dahaki sefere deneyeceğim :).
mojzis

2

Bunun daha eski bir soru olduğunu biliyorum, ancak Google'dan bunu alan insanlar için buraya başka bir yaklaşım atacağımı düşündüm.

Yukarıdaki açıklamadan, kurulumun A ve B olmak üzere 2 varlık türü vardır. B varsaydığım varlık referansı olan A referansları. Eğer B kimliğine sahipseniz, veritabanında A'nın kimliğine sahip bir alanınız olmalıdır.

Kod Notları:

  • Orijinal NID - $original_node->nidBu, B'nin kimliği olacaktır
  • Paket türü - $typebu A türü olmalıdır
  • Alan koşulu yalnızca referansı tutan alanı arar
  • Nasıl kullanılacağı hakkında daha fazla bilgi için EFQ bkz bu

kod

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

Ayrıca, iki yönlü varlık başvuruları ayarlayabilir ve aynı sorguyu geriye doğru yapabilirsiniz. Bu referansların güncel kalmasını sağlamak için CER gibi bir modül kullanabilirsiniz . Ya da referansı güncel tutmak için bir kural belirleyin, ikisini de kullandım.


Field_NAME_OF_FIELD ise çoklu değer fieldCondition('field_NAME_OF_FIELD', 'target_id', $original_node->nid, '=')çalışır mı? olarak değiştirilmelidir fieldCondition('field_NAME_OF_FIELD', 'target_id', array($original_node->nid), 'IN'). Çok değerli varlık başvurusu alanında koşulun nasıl uygulanacağı hakkında hiçbir şey bulunamadı. herhangi bir öneri?
kiranking

1
Bu eski bir yorum biliyorum, ancak '=' kapalı EntityFieldQuery varsayılan olarak IN alan fielddown ('field_NAME_OF_FIELD', 'target_id', $ original_node-> nid) aslında bu durumda çalışır. Muhtemelen artık biliyoruz ama bu sonradan :) karşısında sadece örtmek başkasının Tökezlemeler
burnsjeremy

1

oldukça dinamik bir çözüm (biraz da kirli ama ben hızlı bir şekilde gerekli) böylece referans alanı için adını sabit kod gerekmez ve otomatik olarak gelecekte ekleyecek yeni referans alanı ile ele:

özel modülünüzde:

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

alt düğüm verildiğinde üst düğümleri almanız gerekir:

$nodes = _MY_CUSTOM_MODULE_get_referencing_nodes($node);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.