Drupal的第三方貢獻模塊Entiry API提供了一個包裝類wrapper,使得在處理實體類型的字段和屬性的值的時候更加容易和得心應手。
Drupal7如何使用Entity metadata wrappers (Entity API)
注:本文翻譯自:https://www.drupal.org/documentation/entity-metadata-wrappers 由于英文水平有限,某些句子可能理解不是很到位,如有疑慮請自行查閱源文檔。
使用wrapper包裝類可以更容易的以一致的編程的方式獲取和設置字段的值以及內容。
舉例來說,當我們需要從一個node節點中獲取某個字段的值,以下這種方法是我們經常在drupal的實體中獲取值的方式:
$node->field_number[LANGUAGE_NONE][0]['value']
盡管這種方式在大多數情況下可以正常工作,但是這并不理想。比如:用戶要求頁面需要顯示不同的語言或者上面的字段中的'value'并不存在亦或是一個image或file類型的字段呢?
使用Entity模塊提供的metadata wrapper我們可以輕松的獲取某個字段的值而不用顧慮這些,就像這樣:
$node_wrapper->field_number->value();
Drupal中所有的Entities實體類型都有某種類型的label,實體類型的label通常是一個對用戶友好的字符名稱,例如:所有的節點類型都有title的屬性、所有用戶都有用戶名稱,如果是一個標準的實體類型我們將很難知道如何正確的處理這些label。Metadata wrapper提供了一個統一的方法去獲取不同實體類型的信息,例如:
- // Unified way of getting $node->title, $user->name, ...
- $wrapper->label();
- // Unified way of getting $node->nid, $user->uid, ...
- $wrapper->getIdentifier(); //Vevb.com
- // Unified way of getting $node->type, ...
- $wrapper->getBundle();
Examples(例子)
利用一些wrapper的包裝類可以很輕松的獲取和設置值。
包裝一個實體對象,你可以使用程序化的函數,如下:
$wrapper = entity_metadata_wrapper('node', $node);
或者從Entity API 7.x-1.6之后,你也可以使用Entity::wrapper()。
$wrapper = $entity->wrapper();
但這僅限于如果$entity 對象使用了Entity API模塊提供的Entity類的情況下。
wrapper支持使用鏈式操作來獲取實體的屬性,例如:獲取一個node節點的作者的mail address信息:
$wrapper->author->mail->value();
更新用戶的mail address:
$wrapper->author->mail->set('sepp@example.com');
或者也可以這樣寫:
$wrapper->author->mail = 'sepp@example.com';
wrappers總是返回一個描述性的數據對象,可以通過entity_get_property_info()來從一個wrapper中獲?。?/p>
$mail_info = $wrapper->author->mail->info();
獲取文本的值并進行對應的清理工作可以這樣:
$wrapper->title->value(array('sanitize' => TRUE));
一般node的title是純文本類型的,但是body字段卻可能是帶有標簽等有害內容的,如何獲取body字段并進行相應的過濾處理呢?
$wrapper->body->value->value(array('decode' => TRUE));
這樣總會獲取清理或者過濾后的數據呈現給用戶,但是如果你確實需要獲取未加工處理的原始數據,你可以這樣:
$wrapper->body->raw();
更多的例子請參考Entity模塊中的tests文件。
Working with lists(使用列表)
一個包含wrappers的多值的列表數據,例如多值引用的字段,可以這樣進行迭代:
- $wrapper = entity_metadata_wrapper('node', $node);
- <a href="/tags.php/foreach/" target="_blank">foreach</a> ($wrapper->field_taxonomy_terms->getIterator() as $delta => $term_wrapper) {
- // $term_wrapper may now be accessed as a taxonomy term wrapper.
- $label = $term_wrapper->label->value();
- }
給一個多值列表設置值有多種實現方式,可以將整個值作為一個數組進行設置:
- $containing_node = node_load($nid);
- $w_containing_node = entity_metadata_wrapper('node', $containing_node); //Vevb.com
- $nids_to_set = array(42, 23);
- $w_containing_node->field_entity_reference_field->set($nids_to_set);
也可以使用標準數組的方括號語法來為字段設置值:
- // Setting or adding to a list using square bracket syntax
- $containing_node = node_load($nid);
- $w_containing_node = entity_metadata_wrapper('node', $containing_node);
- // This appends to what is already there, just like a normal array.
- $w_containing_node->field_entity_reference_field[] = 42;
- $w_containing_node->field_entity_reference_field[] = 23;
最后你也可以從獲取字段的數組數據,處理并返回:
- // Add to a list using the whole array.
- $containing_node = node_load($nid);
- $w_containing_node = entity_metadata_wrapper('node', $containing_node);
- $curr_list = $w_containing_node->field_entity_reference_field->value();
- if (!$curr_list)
- $curr_list = array();
- $curr_list[] = $new_nid;
- $w_containing_node->field_entity_reference_field->set($curr_list);
- $w_containing_node->save();
Deleting values(刪除值)
wrapper并沒有提供->delete()方法來刪除一個字段的值,如果想正確的刪除一個字段的值可以這樣做:
- // Using an empty ->set(NULL) removes the value - without NULL you'll get a PHP notice that set($value) requires 1 parameter.
- $wrapper->field_data->set(NULL);
- // And handles correctly the deltas when using multiple values fields
- $wrapper->field_data[$delta]->set(NULL);
Example of using value(),set() and save() (使用value()、set()、和save()方法)
我們先獲取一個字段的值,然后使用set()為它設置值并保存:
- $node_wrapper = entity_metadata_wrapper('node', $node);
- $var = $node_wrapper->field_number->value() + 1;
- $node_wrapper->field_number->set($var);
- $node_wrapper->save();
如果需要保存一個文件或圖片的字段的值,你需要傳遞鍵名為'fid'給set()函數,例如:
- $containing_node = node_load($nid);
- $w_containing_node = entity_metadata_wrapper('node', $containing_node); //Vevb.com
- // Load the file object in any way
- $file_obj = file_load($fid);
- $w_containing_node->field_attachment_content->file->set( $file_obj );
- // ..or pass an array with the fid
- $w_containing_node->field_attachment_content->set( array('fid' => $fid) );
- $w_containing_node->save();
Example of creating a node:(創建一個節點)
你需要為新的節點設置節點的內容類型和用戶ID,然后你就可以用entity_metadata_wrapper()的對象來處理它了:
- // Create an Entity.
- $node = entity_create('node', array('type' => 'image'));
- // Specify the author.
- $node->uid = $user->uid;
- // Create a Entity Wrapper of that new Entity.
- $emw_node = entity_metadata_wrapper('node', $node);
- // Set a title and some text field value.
- $emw_node->title = 'Test node';
- $emw_node->field_text_field = 'Field value text';
- // And save it.
- $emw_node->save();
Get first value of multifield (multiple-value field)(獲取多值字段的第一個值)
只需要在字段名稱后面加上索引(數組下標)即可,例如獲取第一個的值:
$first_name = $wrapper->field_tags[0]->name->value();
Example using field collections(使用field collections的例子)
- // Populate the fields.
- $ewrapper = entity_metadata_wrapper('node', $node);
- $ewrapper->field_lead_contact_name->set($contact_name);
- $ewrapper->field_lead_contact_phone->set($contact_phone);
- $ewrapper->field_lead_contact_email->set($contact_email);
- // Create the collection entity and set it's "host".
- $collection = entity_create('field_collection_item', array('field_name' => 'field_facilities_<a href="/tags.php/request/" target="_blank">request</a>ed'));
- $collection->setHostEntity('node', $node);
- // Now define the collection parameters.
- $cwrapper = entity_metadata_wrapper('field_collection_item', $collection); //Vevb.com
- $cwrapper->field_facility->set(intval($offset));
- $cwrapper->save();
- // Save.
- $ewrapper->save();
Exceptions(異常處理)
當你使用entity_metadata_wrapper()時將代碼放入到try..catch代碼塊中是一個很值得推薦的做法。這樣你可以避免在程序異常的時候不至于中斷允許,而且可以在catch代碼塊中使用watchdog來在后臺記錄錯誤日志方便調試,例如:
- try {
- $node_wrapper = entity_metadata_wrapper('node', $node);
- $price = $node_wrapper->field_product->field_price->value();
- }
- catch (EntityMetadataWrapperException $exc) {
- watchdog(
- 'MODULE_NAME',
- 'See ' . __FUNCTION__ . '() <pre>' . $exc->getTraceAsString() . '</pre>',
- NULL, WATCHDOG_ERROR
- );
- }
Get Start-date and End-date values from Date fields(獲取日期字段的開始和結束日期).
如果你有一個日期字段(由Date模塊提供),你可以像這樣來獲取開始/結束的日期:
- $wrap_node = entity_metadata_wrapper('node', $node);
- $start_date = $wrap_node->field_my_data->value()['value'];
- $end_date = $wrap_node->field_my_data->value()['value2'];
或者也可以這樣:
- $wrap_node = entity_metadata_wrapper('node', $node);
- $start_date = $wrap_node->field_my_data->value->value();
- $end_date = $wrap_node->field_my_data->value2->value();
Getting information about properties and fields(獲取關于屬性和字段的信息)
getPropertyInfo()方法可以返回有關屬性和字段的變量信息,但是需要給entity_metadata_wrapper()方法傳遞對應的字段.
- // Wrapper for entity type 'node', but not specific bundle.
- $wrapper = entity_metadata_wrapper('node');
- // Info will contain information only about properties and not about fields.
- $info = $this->getPropertyInfo();
現在加上綁定類型:
- // Wrapper for entity type 'node' with specific bundle 'page' specified.
- $wrapper = entity_metadata_wrapper('node', NULL, array('bundle' => 'page'));
- // Info will contain information about both properties and fields.
- $info = $this->getPropertyInfo();
Debugging or introspecting wrappers(調試)
獲取一個Entity wrapper的所有可用變量的列表,可以使用dpm()來輸出(需要安裝devel模塊并開啟):
dpm($wrapper->getPropertyInfo());
但這并不會給你任何的屬性值,你可以自己寫一段代碼來進行調試信息的輸出:
- function _wrapper_debug($w) {
- $values = array();
- foreach ($w->getPropertyInfo() as $key => $val) {
- $values[$key] = $w->$key->value();
- }
- return $values;
- }
然后在你的代碼中使用它:
dpm(_wrapper_debug($some_wrapped_object));
新聞熱點
疑難解答