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_something
seperti:
$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:
- Memastikan kami selalu mendapatkan kembali array, bahkan jika itu adalah bidang nilai tunggal;
- 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?
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:
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.
sumber
Untuk pemeriksaan bidang tunggal / ganda, saya merasa berguna untuk menguji jenis objek pembungkus, yang akan
EntityListWrapper
untuk bidang multi-nilai danEntityValueWrapper
untuk bidang bernilai tunggal:sumber
if($wrapper->field_name instanceof EntityListWrapper) {...}