Mengakses nilai tipe bidang yang tidak dikenal saat menggunakan entitas_metadata_wrapper


12

Saya telah mencari cara menggunakan kelas Entity Metadata Wrapper (didefinisikan oleh modul entitas di Drupal 7) untuk mengakses nilai-nilai bidang, karena ini tampaknya merupakan cara yang bersih untuk melakukannya.

Ada beberapa hal yang membuat ini agak canggung. Asumsikan saya memiliki pembungkus untuk tipe konten yang mendefinisikan bidang bernama field_somethingseperti:

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

Masalah pertama yang saya miliki adalah bahwa saya tidak memiliki cara untuk mengetahui sebelumnya apakah apa yang saya dapatkan adalah nilai aktual (string, entitas, dll.), Pembungkus struktur metadata lain (ketika bidang memiliki beberapa nilai) atau array (ketika bidang memiliki beberapa properti).

Saya telah menemukan cara untuk menjawab pertanyaan-pertanyaan itu menggunakan info()metode:

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

Namun itu hampir tidak praktis. Setiap kali saya ingin menggunakan bidang tanpa mengetahui definisi itu sebelumnya, saya harus mempertimbangkan beberapa kasus. Ini membuat kode saya cukup berat.

Untuk mengatasi ini saya telah menulis beberapa kode yang:

  1. Memastikan kami selalu mendapatkan kembali array, bahkan jika itu adalah bidang nilai tunggal;
  2. Ketika ada beberapa properti, kembalikan nilai kolom pertama.

Poin 1. di sini akan selalu berfungsi, kecuali jika penelepon ingin tahu apakah ini adalah bidang nilai tunggal atau tidak. Poin 2 berfungsi dalam beberapa kasus, tidak semua, tetapi nyaman saat diterapkan.

Ini kodenya:

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

Jadi pertanyaan saya adalah: apakah ada cara yang lebih sederhana / lebih baik untuk mengatasi masalah ini mendapatkan nilai dari pembungkus metadata ketika jenis bidang tidak diketahui?

Jawaban:


4

Berikut adalah beberapa saran untuk membuat proses ini sedikit lebih mudah.

$wrapper->field_something->type();

akan kembali jenis bidang, yaitu node, taxonomy_term, integer, textdll Anda kemudian bisa menangani nilai kembali dari $wrapper->field_something->value()benar.

Juga

$wrapper->field_something->raw()

akan mengembalikan nilai mentah lapangan. Yang baik akan menjadi arraydalam kasus bidang bernilai multi hanya nilai. Sebagai contoh suatu entity_referenceakan menjadi nid(atau entitas id) dari entitas yang direferensikan, atau suatu arrayid entitas yang direferensikan.


Ups, saya memasukkannya terlalu cepat! Saya ingin menambahkan: $ wrapper-> field_something-> type () mengembalikan informasi yang sama dengan elemen 'type' dari array yang dikembalikan oleh $ wrapper-> field_something-> info (). Yang terpenting, masih mengembalikan string "list <type>" untuk tipe multi-nilai, jadi saya masih membutuhkan strpos (atau yang setara) untuk menyelesaikannya secara multivalued (jika saya ingin menyelesaikannya sebelum mengambilnya).
Alice Heaton

Adapun poin kedua: Saya memang bisa bekerja jika itu bernilai multi dengan menguji kembalinya -> raw () atau of -> value (), namun saya lebih suka tahu sebelum mengambil nilai, seolah-olah itu bernilai multi lalu Saya ingin menjalankannya melalui loop foreach dengan -> getIterator () daripada secara manual melalui array yang mengharuskan saya untuk membuat kembali pembungkus untuk setiap item.
Alice Heaton

3

Jadi karena tidak ada yang datang dengan solusi lain, saya akan menjawab pertanyaan saya sendiri:

Tidak ada cara yang lebih sederhana untuk mengakses nilai tipe bidang yang tidak dikenal saat menggunakan pembungkus metadata entitas.

Ada metode alternatif yang saya jelaskan sebelumnya (misalnya yang ditunjukkan oleh @thepearson). Secara khusus metode ini bermanfaat:

 entity_property_list_extract_type($type)

Ini akan mengembalikan tipe yang terdaftar jika tipe Anda adalah daftar (mis. 'Integer' jika tipe Anda adalah 'list <integer>'), atau false jika tipe Anda bukan daftar. Secara internal ia melakukan strpos persis seperti kode yang awalnya saya posting, tapi saya rasa itu lebih banyak bukti di masa depan.

Kesimpulannya adalah:

  • Pembungkus metadata entitas berfungsi dengan baik jika Anda tidak tahu jenis bidang Anda, dan ingin menangani setiap kasus dengan hati-hati;

  • Pembungkus metadata entitas berfungsi dengan baik jika Anda tahu persis apa jenis bidang Anda, dan Anda ingin menggunakannya;

  • Jika Anda hanya memiliki beberapa gagasan tentang seperti apa jenis bidang Anda (misalnya semua teks, tetapi Anda tidak tahu apakah mereka diformat atau tidak, dan Anda tidak tahu apakah itu nilai tunggal atau multi nilai) maka pembungkus metadata entitas tidak memberikan jalan pintas dan Anda harus menulis sendiri seperti yang saya lakukan di pertanyaan awal.


1

Untuk pemeriksaan bidang tunggal / ganda, saya merasa berguna untuk menguji jenis objek pembungkus, yang akan EntityListWrapperuntuk bidang multi-nilai dan EntityValueWrapperuntuk bidang bernilai tunggal:

<?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();
}

Atau bahkanif($wrapper->field_name instanceof EntityListWrapper) {...}
rudolfbyker
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.