it-swarm.com.de

Erstellen Sie eine EntityFieldQuery, die referenzierte Entitäten auswählt

Ich suche nach der ID der Entität vom Typ A und kenne die ID der Entität B, die auf A verweist.

Ich habe ein paar nette Quellen über EntityFieldQuery gefunden. Ich war erstaunt, dass ich in Google Ergebnisse von .NET erhalten habe :) (ist das ein Zeichen für Drupals Reife? :). Aber ich habe es nicht geschafft, dies zu finden. Bitte helfen Sie ...

Einige der Quellen:

So sieht es beim Laden von Entitäten aus - Sie werden verstehen, dass ich diese Abfrage brauche :) Der Wrapper dient hauptsächlich zum Üben. Beachten Sie, dass die Zielentität geladen wird - ziemlich viele Abfragen.

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

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

Sie können target_id Anstelle von value verwenden, um Entitäten basierend auf der ID der referenzierten Entitäten abzurufen:

$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

äh, ist das Beziehungsmodul was Sie suchen? Es klingt so, als ob Sie Beziehungen zwischen X- und Y-Entitäten definieren möchten. Es verfügt über eine eigene RelationQuery (ein Wrapper um EFQ) und RelationQueryEndpoints, um diese Art von Informationen einfach abzurufen.

2
tenken

Ich weiß, dass dies eine ältere Frage ist, aber für Leute, die von Google darauf zugreifen, dachte ich, ich würde hier einen anderen Ansatz einbringen.

Aus der obigen Beschreibung geht hervor, dass das Setup zwei Entitätstypen hat, A und B. B-Referenzen A mit Entitätsreferenz, die ich annehme. Wenn Sie also die ID von B haben, sollten Sie ein Feld mit der ID von A in der Datenbank speichern.

Code Hinweise:

  • Ursprüngliche NID - $original_node->nid Dies wäre die ID von B.
  • Bundle-Typ - $type Dies sollte der Typ von A sein
  • Die Feldbedingung sucht nur nach einem Feld, das die Referenz enthält
  • Weitere Informationen zur Verwendung von EFQ finden Sie unter this

Code

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

Sie können auch bidirektionale Entitätsreferenzen einrichten und dieselbe Abfrage oben rückwärts ausführen. Sie können ein Modul wie CER verwenden, um sicherzustellen, dass diese Referenzen auf dem neuesten Stand gehalten werden. Oder richten Sie eine Regel ein, um die Referenz auf dem neuesten Stand zu halten. Ich habe beide verwendet.

2
burnsjeremy

eine ziemlich dynamische Lösung (auch ein bisschen schmutzig, aber ich brauchte sie schnell), sodass Sie den Namen des Referenzierungsfelds nicht fest codieren müssen und sie automatisch mit einem neuen Referenzierungsfeld behandelt wird, das Sie in Zukunft hinzufügen werden:

in Ihrem benutzerdefinierten Modul:

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

wo müssen Sie die übergeordneten Knoten erhalten, wenn der untergeordnete Knoten angegeben ist:

$nodes = _MY_CUSTOM_MODULE_get_referencing_nodes($node);
1
Gueno