You are here

7.11 添加实体

admin 的头像
Submitted by admin on 星期二, 2015-09-01 09:51

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

我们首先定义菜单项:

  $items['breadcrumb/add'] = array(

    'title' => 'Add breadcrumb',

    'page callback' => 'breadcrumb2_add',

    'access arguments' => array('administer breadcrumbs'),

    'file' => 'breadcrumb2.admin.inc',

  );

接着,向breadcrumb2.admin.inc添加回调函数breadcrumb2_add

/**

 * Returns a breadcrumb submission form.

 */

function breadcrumb2_add(){

  $breadcrumb = entity_get_controller('breadcrumb2')->create();

  drupal_set_title(t('Create breadcrumb'));

  $output = drupal_get_form('breadcrumb2_form', $breadcrumb);

 

  return $output;

}

在这个函数里面,我们首先使用entity_get_controller创建了一个初始化的面包屑,然后设置了标题,最后调用drupal_get_form,调用的表单IDbreadcrumb2_form,同时我们把$breadcrumb传递给了它。我们这样做的目的,是希望breadcrumb2_form同时能够适应于编辑表单。我们来看看breadcrumb2_form的定义:

/**

 * The breadcrumb edit form.

 */

function breadcrumb2_form($form, &$form_state, $breadcrumb) {

  // Save the breadcrumb for later, in case we need it.

  $form['#breadcrumb'] = $breadcrumb;

  $form_state['breadcrumb'] = $breadcrumb;

  

  $form['bid'] = array(

    '#type' => 'value',

    '#value' => isset($breadcrumb->bid) ? $breadcrumb->bid : NULL,

  );

  

  // Add the field related form elements.

  field_attach_form('breadcrumb2', $breadcrumb, $form, $form_state);

 

  $form['actions'] = array('#type' => 'actions');

  $form['actions']['submit'] = array(

    '#type' => 'submit',

    '#value' => t('Save'),

    '#weight' => 40,

  );

  if (!empty($breadcrumb->bid)) {

    $form['actions']['delete'] = array(

      '#type' => 'submit',

      '#value' => t('Delete breadcrumb'),

      '#weight' => 45,

      '#limit_validation_errors' => array(),

      '#submit' => array('breadcrumb2_form_submit_delete')

    );

  }

  $form['#validate'][] = 'breadcrumb2_form_validate';

  $form['#submit'][] = 'breadcrumb2_form_submit';

  return $form;

}

首先,我们将$breadcrumb保存到了$form$form_state里面,这里保存原始的面包屑对象。接着,我们添加了'bid'元素,它的类型为value,为什么这样做呢?因为有些模块会使用entity_extract_ids来提取实体的ID,在Drupal7里面,如果我们不预先保存一个实体ID的话,entity_extract_ids就会提取不出来,Drupal8已经改进了这个问题,我遇到过这个问题,所以在这里加了了'bid'。接着是使用field_attach_form,把实体上面的字段也添加进来,由于字段的添加,是动态的,我们也不知道具体有几个字段,通过field_attach_form,我们就可以把这个工作委托给Field模块了,它能够帮我们做这件事情。再往下是提交、删除按钮,我们把这两者放到了actions里面了,actionsDrupal7里面的一个新的表单元素类型;对于删除按钮,我们为它指定了一个单独的提交函数breadcrumb2_form_submit_delete,同时为它设置了'#limit_validation_errors',通过这个设置,在删除面包屑的时候,即便是存在验证错误的话,也可以正常提交。最后是为表单设置$form['#validate']$form['#submit'],我们在第一集里面学过,即便不设置这两行代码,表单系统也会自动使用这两个函数,为什么明确的设置呢?因为我看到其它实体的添加表单都是这样明确设置的,包括节点的添加表单,或许这样做的好处的,代码的可读性更强。

接下来是表单验证函数:

function breadcrumb2_form_validate($form, &$form_state) {

  $breadcrumb = $form_state['breadcrumb'];

  

  // Notify field widgets to validate their data.

  field_attach_form_validate('breadcrumb2', $breadcrumb, $form, $form_state);

}

代码比较简单,我们模块本身没有多少验证工作,所以这里直接将验证工作委托给了Field模块,这里使用的是field_attach_form_validate

再往下,是提交函数,逻辑也比较简单:

/**

 * Breadcrumb form submit handler.

 */

function breadcrumb2_form_submit($form, &$form_state) {

 

  $breadcrumb = &$form_state['breadcrumb'];

  // Notify field widgets.

  field_attach_submit('breadcrumb2', $breadcrumb, $form, $form_state);

  

  // Save the breadcrumb

  breadcrumb2_save($breadcrumb);

 

  drupal_set_message(t('Breadcrumb saved.'));

  $form_state['redirect'] = 'breadcrumb/' . $breadcrumb->bid;

 

}

我们首先使用field_attach_submit,将提交委托给了Field模块,接着我们调用我们的API函数breadcrumb2_save,保存实体。最后设置一个消息,并重定向。

在这部分,需要注意的是field_attach_formfield_attach_form_validatefield_attach_submit的使用。这里我有个疑问,不知道为什么不把field_attach_submit叫做field_attach_form_submit

编写完这些代码以后,可以测试一下了,如果你按照这里所列的代码,跟着做的,现在访问breadcrumb/add页面,我们可以看到一个表单页面,这里面包含前面我们添加的两个字段。一切正常。输入一些测试数据,提交,我们遇到了第一个问题:

图片4.png 

这是一个PHP错误。我在网上搜索了这个问题,很多人也遇到了同样的问题,但是没有找到答案。我们在开发的过程中,是存在一些问题,这些问题起初我也没有注意到,我也希望一次能够搞定所有的问题,但是错误总是不经意的出现。如果你能够,在现有的代码基础上,把所有的问题都解决掉,那么证明你完全掌握了如何定义一个实体类型。我也是在解决这些问题的过程中,才明白了里面的很多细微的地方。


Drupal版本: