Entity_metadata_wrapper kullanırken bilinmeyen alan türlerinin değerlerine erişme


12

Bu bunu yapmak için temiz bir yol gibi görünüyor gibi varlık değerlerine erişmek için Entity Metadata Wrapper sınıfları (Drupal 7 varlık modülü tarafından tanımlanan) kullanarak bakıyordum.

Ancak bu biraz garip kılan birkaç şey var. Aşağıdaki field_somethinggibi bir alan tanımlayan bir içerik türü için bir sarıcı var varsayalım :

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

Sahip olduğum ilk sorun, elde ettiğim şeyin gerçek bir değer (dize, varlık, vb.), Başka bir meta veri yapısı sarıcısı (alanlar birden çok değere sahip olduğunda) veya bir dizi (ne zaman alanlar birden fazla özelliğe sahiptir).

Bu soruları info()yöntemi kullanarak cevaplamak için bir yol buldum :

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

Ancak bu pek pratik değildir. Bir alanı önceden tanımını bilmeden kullanmak istediğimde, birkaç durumu dikkate almalıyım. Bu benim kodumu oldukça ağır yapar.

Bununla başa çıkmak için bazı kodlar yazdım:

  1. Tek bir değer alanı olsa bile, her zaman bir dizi döndürmemizi sağlar;
  2. Birden çok özellik olduğunda, ilk sütunun değerini döndürün.

Nokta 1 burada arayan tek bir değer alanı olup olmadığını bilmek istemiyorsa, her zaman işe yarayacaktır. Nokta 2 bazı durumlarda çalışır, hepsi değil, uygulandığında uygundur.

İşte kod:

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

Yani sorum şu: Alan türü bilinmediğinde meta veri sarmalayıcısından değer alma sorununu çözmenin daha basit / daha iyi yolları var mı?

Yanıtlar:


4

İşte bu işlemi biraz daha kolaylaştırmak için birkaç öneri.

$wrapper->field_something->type();

yani alanın türünü döndürür node, taxonomy_term, integer, textDaha sonra ele verebilir vb değeri döndü $wrapper->field_something->value()düzgün.

Ayrıca

$wrapper->field_something->raw()

alanın ham değerini döndürür. Bu ya arraysadece değerin çok değerli alanları için bir olacak . Mesela bir entity_referenceolacaktır nidbaşvurulan varlık (veya varlık kimliği) veya arraybaşvurulan varlık kimliği yılların.


Hata! Çok hızlı girdim! Eklemek istedim: $ wrapper-> field_something-> type (), $ wrapper-> field_something-> info () tarafından döndürülen dizinin 'type' öğesi ile aynı bilgileri döndürür. Çok önemli, hala çok değerli türler için bir dize "listesi <tür>" döndürür, bu yüzden hala çok değerli (bir onu almadan önce çalışmak istiyorsanız) çalışmak için bir strpos (veya eşdeğeri) gerekir.
Alice Heaton

İkinci noktaya gelince: -> ham () veya -> değer () 'in dönüşünü test ederek çok değerli olup olmadığını gerçekten anlayabilirim, ancak değeri getirmeden önce, çok değerli gibi Ben manuel olarak her öğe için bir sarıcı yeniden oluşturmak için gerektiren dizi üzerinden -> getIterator () ile bir foreach döngü üzerinden çalıştırmak istiyorum.
Alice Heaton

3

Kimse başka bir çözüm bulamadığı için kendi sorumu cevaplayacağım:

Orada değil varlık meta wrapperları kullanılarak bilinmeyen alan türlerinden erişim değerlerine basit bir yolu.

Başlangıçta tarif ettiğim yöntem için alternatif yöntemler var (örneğin @thepearson tarafından işaret edilenler). Özellikle bu yöntem yararlıdır:

 entity_property_list_extract_type($type)

Türünüz bir liste ise listelenen türü döndürür (örneğin, türünüz 'list <integer>' ise 'integer') veya türünüz liste değilse false olur. Dahili olarak sadece başlangıçta gönderdiğim kod gibi bir strpos yapar, ama sanırım daha gelecek kanıtı.

Sonuç şudur:

  • Alan türleriniz hakkında hiçbir fikriniz yoksa ve olası her durumu dikkatle ele almak istiyorsanız, varlık meta veri sarmalayıcıları iyi çalışır;

  • Varlık meta veri sarmalayıcıları, alanlarınızın tam olarak ne tür olduğunu biliyorsanız ve bunları kullanmak istiyorsanız iyi çalışır;

  • Alan türlerinizin nasıl olduğuna dair yalnızca bazı fikirleriniz varsa (örneğin, tüm metinler, ancak bunların biçimlendirilip biçimlendirilmediğini bilmiyorsanız ve bunların tek veya çok değerli olup olmadığını bilmiyorsanız), Varlık meta veri sarmalayıcıları herhangi bir kısa yol vermeyin ve ilk soruda yaptığım gibi kendiniz yazmanız gerekir.


1

Tek / çoklu alan kontrolü EntityListWrapperiçin, çok değerli bir alan ve EntityValueWrappertek değerli bir alan için olacak olan sarıcı nesnesinin türünü test etmeyi yararlı buldum :

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

Veya hattaif($wrapper->field_name instanceof EntityListWrapper) {...}
rudolfbyker
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.