entity_metadata_wrapperを使用する場合の不明なフィールドタイプの値へのアクセス


12

エンティティメタデータラッパークラス(Drupal 7のエンティティモジュールで定義されている)を使用してフィールド値にアクセスすることを検討してきました。

しかし、これを少し厄介なものにするいくつかのことがあります。そのfield_somethingような名前のフィールドを定義するコンテンツタイプのラッパーがあるとします。

$wrapper = entity_metadata_wrapper('node', node_load($nid));
$value = $wrapper->field_something->value();

私が持っている最初の問題は、実際の値(文字列、エンティティなど)、別のメタデータ構造ラッパー(フィールドに複数の値がある場合)、または配列(いつフィールドには複数のプロパティがあります)。

info()メソッドを使用してこれらの質問に答える方法を見つけました。

$info = $wrapper->field_something->info();
$is_multi_value = (strpos($info['type'], 'list<') === 0);
$has_multiple_properties = isset($info['property info']]);

しかし、それはほとんど実用的ではありません。事前に定義を知らずにフィールドを使用する場合は、いくつかのケースを考慮する必要があります。これにより、コードが非常に重くなります。

これに対処するために、次のコードを作成しました。

  1. 単一の値フィールドであっても、常に配列が返されるようにします。
  2. 複数のプロパティがある場合、最初の列の値を返します。

ポイント1.呼び出し側がこれが単一値フィールドであるかどうかを知りたくない限り、ここで常に機能します。ポイント2は、すべてではなく一部のケースで機能しますが、適用する場合に便利です。

コードは次のとおりです。

function entity_metadata_simple_values($field) {
  $fields = array();
  $values = array();
  $info = $field->info();
  if (strpos($info['type'], 'list<') === 0) {
    foreach ($field->getIterator() as $field_iteration) {
      $fields[] = $field_iteration;
    }
  } else {
    $fields[] = $field;
  }
  foreach ($fields as $final_field) {
    $ff_info = $final_field->info();
    if (isset($ff_info['property info'])) {
      $column = reset(array_keys($ff_info['property info']));
      $values[] = $final_field->{$column}->value();
    } else {
      $values[] = $final_field->value();
    }
  }

  return $values;
}

したがって、私の質問は次のとおりです。フィールドタイプが不明な場合にメタデータラッパーから値を取得するというこの問題に対処するための、より簡単でより良い方法はありますか。

回答:


4

このプロセスを少し簡単にするためのいくつかの提案があります。

$wrapper->field_something->type();

すなわち、フィールドの型を返しますnodetaxonomy_termintegertextあなたはその後から返された値扱うことができるなど$wrapper->field_something->value()、正しくを。

また

$wrapper->field_something->raw()

フィールドの生の値を返します。これはarray、値のみの複数値フィールドの場合のいずれかです。たとえば、entity_referencenid、参照されるエンティティ(またはエンティティID)の(またはエンティティID)ですarray


おっと、私はそれをあまりにも早く入力しました!追加したいのは、$ wrapper-> field_something-> type()が、$ wrapper-> field_something-> info()によって返される配列の「type」要素と同じ情報を返すことです。重要なのは、多値型の文字列 "list <type>"を返すため、strpos(または同等のもの)が複数値を取得するために必要です(取得する前に解決したい場合)。
アリスヒートン

2番目の点については、-> raw()または-> value()の戻り値をテストすることで複数値の場合は実際に解決できますが、値を取得する前に、多値の場合のように知りたい-> getIterator()を使用してforeachループを実行し、各アイテムのラッパーを再作成する必要がある配列を手動で実行するのではありません。
アリスヒートン

3

だから誰も別の解決策を思いついていないので、私は自分の質問に答えます:

そこではありませんエンティティのメタデータラッパーを使用して、未知のフィールド型のアクセス値への簡単な方法は。

最初に説明したものに代わる方法があります(たとえば、@ thepearsonが指摘した方法)。特に、この方法は便利です。

 entity_property_list_extract_type($type)

タイプがリストの場合、リストされたタイプを返します(たとえば、タイプが「list <integer>」の場合は「integer」)、タイプがリストでない場合はfalseを返します。内部的には、私が最初に投稿したコードと同じようにstrposを実行しますが、より将来性があると思います。

結論は次のとおりです。

  • エンティティメタデータラッパーは、フィールドタイプがわからない場合や、考えられる各ケースに慎重に対処したい場合にうまく機能します。

  • エンティティメタデータラッパーは、フィールドの種類を正確に把握しており、それらを使用する場合に適切に機能します。

  • フィールドタイプがどのようなものかについていくつかのアイデアしか持っていない場合(たとえば、すべてのテキストがフォーマットされているかどうかがわからず、単一値か複数値かがわからない場合)、エンティティメタデータラッパーショートカットを提供しないでください。最初の質問で行ったように、独自のショートカットを作成する必要があります。


1

単一/複数フィールドのチェックでは、ラッパーオブジェクトのタイプをテストすることが有用であることがわかりました。これはEntityListWrapper、複数値フィールドおよびEntityValueWrapper単一値フィールド用です。

<?php
...
$wrapper = entity_metadata_wrapper('user', $account);
// Get address, or first address if a multi-value field instance.
if (get_class($wrapper->field_address) == 'EntityListWrapper') {
  $value = $wrapper->field_address[0]->value();
}
else {
  $value = $wrapper->field_address->value();
}

またはif($wrapper->field_name instanceof EntityListWrapper) {...}
rudolfbyker
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.