web-dev-qa-db-ja.com

現在のエンティティオブジェクトをロードする方法はありますか?

Drupalのどこからでも、現在のエンティティオブジェクトを取得する方法はありますか?フック hook_filter_FILTER_process() を使用していて、$ textの内容をエンティティのデータで置き換えたいのですが、エンティティなしでエンティティにアクセスする方法がないようですのようなことをしています

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

これはほとんどの場合機能しますが、(分類用語のように)機能しない場合もあります。その上、データベースへの別の呼び出しを行うため、これは本当に厄介です。

これを行うより良い方法はありますか?

5
David Barratt

menu_get_object() が役立つと思います:

menu_get_object()は、現在のルーター項目によってロードされたオブジェクトへのアクセスを提供します。たとえば、node /%nodeページで、ルーターは%nodeオブジェクトをロードし、menu_get_object()を呼び出すとそれが返されます。通常、参照されるオブジェクトのタイプを指定する必要がありますが、ノードがデフォルトです。次の例では、表示されているノードが「ストーリー」コンテンツタイプであるかどうかをテストします。

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

ルーターに読み込まれたオブジェクトでこれを使用できるため、エンティティページ(分類用語のページを含む)では、これにより正しいオブジェクトが得られると考えられます。

_$entity = menu_get_object($entity_type);
_

[〜#〜]更新[〜#〜]

詳細な検査では、URL内のIDの位置をパラメーターとしてmenu_get_object()に渡す必要があるため、arg()を使用する場合とほぼ同じですが、おそらく少しクリーンです。分類用語の場合、パスは_taxonomy/term/%_なので、次のように呼び出します。

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

_entity_load_は、エンティティが現在のページリクエストで以前にロードされていない場合にのみデータベースコールが発生することに注意してください。既に読み込まれている場合は、静的キャッシュから提供されます。

更新2

メモリエラーが発生した場合にエンティティを何度もリロードしないように、静的パターンの例を追加するだけです。

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

この不可知論的な現在のエンティティローダー関数を作成しました...

<?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

適切な方法は、menu_get_object()を使用することです。

2
gilzero

入力フィルターには、レンダリングのために呼び出されるエンティティを取得する方法がありません。

実際には、エンティティがまったく関与していない状況でも、入力フィルターを呼び出すことができます。たとえば、Viewsモジュールではビューのヘッダーを設定でき、次のオプションを提供します。

screenshot

screenshot

Global:Text areaを選択した場合、次のオプションは次のオプションです。

screenshot

この場合に入力フィルターが呼び出されると、ビューのヘッダーに関連付けられたエンティティはありません。 menu_get_object()を使用すると、おそらく間違ったエンティティが取得されるか、エンティティがまったく取得されません。 menu_get_object()で正しいエンティティを取得するには、表示されたページに関連付けられているエンティティと、エンティティIDがURLに格納されている場所を知る必要があります。

一般的なガイドラインとして、入力フィルターは、ユーザーからの入力として取得したテキストをレンダリングするために使用される可能性があるため、それらの使用方法について想定するべきではありません。 Viewsモジュールから使用されるビューのヘッダーは単なる例ですが、別のモジュールが同じメソッドを使用するのを妨げるものはありません。

0
kiamlaluno