Hướng dẫn code entity reference trong custom entities (no bundles)

Hướng dẫn code entity reference trong custom entities (no bundles)

Entities are a big boon to Drupal, just that the learning curve is a bit longer than CCKs and nodes. I've read a lot about how these entities work but the more I read, the more complex they sound. Here are small snippets of code that I would like to share to allow you to create an entity reference field with your custom entities.

Lets create a scenario we have 2 entities: "employee" and "company". And we want the entity reference field to be used with our "employee" entity to refer the "company". I use Entity APImodule to create my custom entities. As it is clear by the name of the entities, we do not need any bundles for them. We can use hook_entity_info to define our entities and use the controller class from EntityAPI. Here is how we do that:

<?php
function MY_MODULE_entity_info() {
  $return = array(
    'employee' => array(
      'label' => t('Employee'),
      'plural label' => t('Employees'),
      'description' => t('An entity which stores all the employee\'s information.'),
      'controller class' => 'EntityAPIController',
      'base table' => 'employee',
      'fieldable' => TRUE,
      'entity keys' => array(
        'id' => 'employee_id',
        'label' => 'name',
      ),
      'uri callback' => 'employee_uri',
    ),
    'company' => array(
      'label' => t('Company'),
      'plural label' => t('Companies'),
      'description' => t('An entity which stores all the company\'s information.'),
      'controller class' => 'EntityAPIController',
      'base table' => 'company',
      'fieldable' => TRUE,
      'entity keys' => array(
        'id' => 'company_id',
        'label' => 'name',
      ),
      'uri callback' => 'company_uri',
    ),
  );
  
  return $return;
}
?>

A little explanation to the above code: You define your entities using hook_entity_info. Before defining the entities, the base tables must be present in the database which means in your implementation of hook_schema you need to define the database for your entity (employee and company table in our case). You dont necessarily need to have bundles for your entities which would mean if you dont specify a bundle the bundle's default name is same as that of the entity. You use EntityAPIController as your controller class to be able to use the CRUD functionalities like entity_save, entity_create, entity_delete, etc.

Next, using hook_menu, we define all the urls for employee and company entities. Lets also assume we have a url for employee/company add/edit form. We now need a select list or autocomplete form item on the employee add/edit form. To do that we have to follow 2 simple steps:

  1. Create a field --> An entry needs to go into field_config table
  2. Create an instance of the field --> An entry needs to go into field_config_instance table

To do the above 2, we need to use field_create_field & field_create_instance respectively. We need to create an entityreference field and attach it to our employee entity. Here is the code that can help us do that:

<?php
function MY_MODULE_install() {
  // Create a field for company reference to be used by various entities
  $field = array(
    'field_name' => 'company_reference',
    'type' => 'entityreference',
    'settings' => array(
      'target_type' => 'company',
      'handler_settings' => array('target_bundles' => NULL),
    ),
    'cardinality' => 1,
    'translatable' => FALSE,
  );
  field_create_field($field);
 
  // Attach the company reference field to employee instance
  $instance = array(
    'field_name' => 'company_reference',
    'entity_type' => 'employee',
    'bundle' => 'employee',
    'label' => 'Company',
    'required' => false,
    'widget' => array(
      'type' => 'options_select'
    ),
    'settings' => array(
      'target_type' => 'company',
      'handler_settings' => array('target_bundles' => NULL),
    ),
    'display' => array(
      'default' => array('label' => 'inline', 'type' => 'entityreference_label'),
    ),
  );

  field_create_instance($instance);
}
?>

A little explanation to the above code: You need to create the fields and instances only once and therefore you execute your code for the same in the hook_install. Note the use of settings when using field_create_field. "target_type" lets you define the type of the entity to which this field can refer to, "target_bundles" lets you filter the company entities based on the bundle. Unless you have a bundle specified for your entity, it is important to specify NULL over here. In case you do have a bundle use the following settings when creating your field:

'handler_settings' => array('target_bundles' => array('MY_BUNDLE_NAME')),

Note the use of bundle when using field_create_instance. If you look into your field_config_instance table, you'll find that the bundle field is a required field. Remember, if we dont have bundles for an entity, the default bundle name is the same as the entity. Next, note the widget implementation, I'm using a select list instead of autocomplete. To use autocomplete, you just need to specify "entityreference_autocomplete" instead of "options_select". The settings and display portions are self explanatory.

So, now what - everyone says that if you make fields in your entity, you are done, everything is there by default, but tell you what it is actually not so :-) There are 2 things that you'll still have to do:

  1. Tell your employee form to show the fields as well
  2. Make sure that after filling the form, the values rightly go into the database

To do the first part, let me give a little background of my form, I have a dedicated page to add employee and that renders a form using drupal_get_form. Add to it, I use the same form to edit an employee too, so I pass the employee entity as an object to the form. Now, I need to change my form to incorporate the fields. Here is the snippet of the form:

<?php
function employee_form($form, &$form_state, $employee = NULL) {
  // Create a hidden form element when editing a employee if it is an employee edit form
  if ($employee) {
    $form['employee_id'] = array(
      '#type' => 'hidden',
      '#value' => $employee->employee_id,
    );
  }
 
  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Employee Name'),
    '#size' => 60,
    '#required' => TRUE,
    '#default_value' => ($employee) ? $employee->name : '',
  );
 
  // Provide a delete link after the submit button in case of editing the employee details
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
    '#suffix' => ($employee) ? l('Delete', 'employee/' . arg(1) . '/delete') : '',
  );
 
  field_attach_form('employee', $employee, $form, $form_state);
 
  return $form;
}
?>

Thats it, the forms start showing on my form, YAY :-) Just one thing left, make sure, they get submitted into the database too. In my form submit, I use entity_save to save the entity. All I need to do is that before I pass the entity object to entity_save, I make sure that the values of the fields (in our case, the entity reference) are also a part of the entity. This is how my form submit looks like after doing that:

<?php
function employee_form_submit($form, &$form_state) {
  // Create an entity object from the form submitted values and pass it to entity_save
  $entity = new stdClass();
  if (array_key_exists('employee_id', $form_state['values'])) {
    $entity->employee_id = $form_state['values']['employee_id'];
    $entity->is_new = FALSE;
  }
  $entity->name = $form_state['values']['name'];
  entity_form_submit_build_entity('employee', $entity, $form, $form_state);
  $result = entity_save('employee', $entity);
  // Display add/update messages
  if ($result == SAVED_NEW)
    drupal_set_message(t('You have successfully added a employee.'));
  if ($result == SAVED_UPDATED)
    drupal_set_message(t('You have successfully updated the employee details.'));
}
?>

Note the use of entity_form_submit_build_entity in the above piece of code. Thats pretty much it. (sweat) Hope this is useful, please share your experience (if you do happen to follow all the above :P)

Bạn thấy bài viết này như thế nào?: 
Average: 5 (1 vote)
Ảnh của Khanh Hoang

Khanh Hoang - Kenn

Kenn is a user experience designer and front end developer who enjoys creating beautiful and usable web and mobile experiences.

Quảng cáo việc làm

 

Thích hợp các bạn nữ mảng thợ may làm việc tại nước NGA

Đơn hàng Tuyển dụng 100 Thợ may đi Nga(đợt 1 tháng 3.2021, đợt 2 tháng 5.2021). Lương thực lãnh 800 USD, bao ăn ở, vé máy bay và visa, phí xuất cảnh(1800 USD)trả khi đi làm có lương. Bạn có thể liên hệ CÔNG TY qua Phone/Zalo: (+84) 944 225 212. Công ty sẽ tư vấn cho bạn.

Xem chi tiết: >>> https://bit.ly/3o9NOfR

Tìm kiếm bất động sản

 

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
Mike Tyson với trang trại cần sa rộng 418 héc ta tại California

Mike Tyson với trang trại cần sa rộng 418 héc ta tại California

Không chỉ là một võ sĩ quyền Anh, một ngôi sao điện ảnh hay gần đây nhất là một diễn giả, cuộc đời của Mike Tyson dường như sắp bước sang một chương mới với tư cách là một ‘ông trùm’ cần sa.

 

Export và import Drupal 7 nodes như thế nào ?

There are lots of ways to export configuration from one Drupal site and import into another; however, there are few ways to do the same with content. Here's a quick tip which has worked well for me.

Thủ thuật xóa nhanh các nội dung trong Drupal

Thủ thuật xóa nhanh các nội dung trong Drupal

Trong quá trình xây dựng website với Drupal chúng ta sẽ phải tạo nhiều nội dung test và qua thời gian làm cho những nội dung đó trở nên rác và làm dữ liệu không được "đẹp".