web-dev-qa-db-fra.com

Existe-t-il un moyen de charger l'objet entité actuel?

Existe-t-il un moyen, depuis n'importe où dans Drupal, d'obtenir l'objet entité actuel? J'utilise le hook hook_filter_FILTER_process () et j'aimerais remplacer les choses dans le texte $ par des données de l'entité, mais il ne semble pas qu'il existe un moyen d'accéder à l'entité sans faire quelque chose comme

if (!empty(arg(0)) && is_numeric(arg(1)) {
    $entity = entity_load(arg(0), array(arg(1)));
}

Cela fonctionne la plupart du temps, mais parfois (comme les termes de taxonomie), cela ne fonctionne pas. En plus de cela, c'est vraiment compliqué car cela fait un autre appel à la base de données.

Y a-t-il une meilleure manière de faire cela?

5
David Barratt

Je pense que menu_get_object() pourrait être utile:

menu_get_object () permet d'accéder aux objets chargés par l'élément de routeur actuel. Par exemple, sur la page node /% node, le routeur charge l'objet% node, et l'appel de menu_get_object () le renverra. Normalement, il est nécessaire de spécifier le type d'objet référencé, cependant le noeud est la valeur par défaut. L'exemple suivant teste pour voir si le nœud affiché est du type de contenu "histoire":

<?php
$node = menu_get_object();
$story = $node->type == 'story';
?>

Vous pouvez l'utiliser avec n'importe quel objet chargé par un routeur, il est donc logique que sur les pages d'entité (y compris les pages de termes de taxonomie), cela vous obtienne l'objet correct:

$entity = menu_get_object($entity_type);

[~ # ~] mise à jour [~ # ~]

Après une inspection plus approfondie, vous devez toujours transmettre la position de l'ID dans l'URL en tant que paramètre à menu_get_object (), donc c'est à peu près la même chose que l'utilisation de arg(), mais c'est sans doute un peu plus propre. Pour les termes de taxonomie, le chemin est taxonomy/term/% Donc vous appelleriez:

$term = menu_get_object('taxonomy_term', 2);

Il convient de garder à l'esprit que entity_load N'encourra un appel à la base de données que si l'entité n'a pas été précédemment chargée dans la demande de page en cours. S'il est déjà chargé, il sera servi à partir du cache statique.

MISE À JOUR 2

Juste pour ajouter un exemple de modèle statique pour éviter de recharger l'entité encore et encore si vous obtenez des erreurs de mémoire:

$loaded_entity = &drupal_static(__FUNCTION__, NULL);
if (!$loaded_entity) {
  $loaded_entity = menu_get_object();
}
return $loaded_entity;
8
Clive

Créé cette fonction de chargeur d'entité actuelle agnostique ...

<?php
function my_module_menu_get_any_object() {
  // Figure out how this entity is loaded.
  $type = FALSE;
  $item = menu_get_item();
  $vals = array_values($item['load_functions']);
  $load_function = $vals[0];
  $arg_position = array_search($load_function, $item['load_functions']);

  // Compare to entity types.
  $entity_info = entity_get_info();
  foreach($entity_info as $i => $e) {
    if ($e['load hook'] == $load_function) {
      $type = $i;
    }
  }

  // Many happy returns.
  if($type && $obj = menu_get_object($type, $arg_position)) {
    if(is_object($obj)) {
      return $obj;
    }
    else {
      return FALSE;
    }
  }
  else {
    return FALSE;
  }
}
2
doublejosh

La bonne façon est d'utiliser menu_get_object().

2
gilzero

Les filtres d'entrée n'ont aucun moyen d'obtenir l'entité pour laquelle ils sont appelés à effectuer le rendu.

En fait, un filtre d'entrée pourrait également être appelé dans des situations où une entité n'est pas du tout impliquée. Par exemple, le module Vues vous permet de définir l'en-tête d'une vue et vous propose les options suivantes.

screenshot

screenshot

Lorsque vous sélectionnez Global: zone de texte, les options suivantes sont les suivantes.

screenshot

Lorsqu'un filtre d'entrée est appelé dans ce cas, aucune entité n'est associée à l'en-tête de la vue; si vous utilisiez menu_get_object() vous obtiendriez probablement la mauvaise entité, ou vous n'en obtiendriez pas du tout. Pour obtenir l'entité correcte avec menu_get_object(), vous devez savoir quelle entité est associée à la page affichée et où l'ID d'entité est stocké dans l'URL.

En règle générale, les filtres d'entrée ne doivent pas prendre d'hypothèses sur la façon dont ils sont utilisés, car ils pourraient être utilisés pour rendre tout texte obtenu en entrée de l'utilisateur; l'en-tête de la vue utilisé à partir du module Vues n'est qu'un exemple, mais rien n'empêcherait un autre module d'utiliser la même méthode.

0
kiamlaluno