Posted by GloolsGuan on October 11, 2011 at 5:42am
问题:
当通过表单HOOK向表单#submit项中添加新的处理函数时,该函数无法获得$node的完整数据(包含$node_id)?
而事实上,由于在全局中$form_state都是引用的,每个表单默认的#submit项为第一个处理函数,也就是说该函
数处理完成后,根据处理流程,接下来#submit项添加的处理函数应该可以获得上一个函数执行后的结果。
而实际情况并非如此,排在#submit项第一个后面的函数会先开始执行,而且不是由form.inc来控制的,而是在
node.page.inc中,由node_form_submit();函数来执行,导致顺序颠倒,后面的函数失去意义。且该执行流程逻
辑错误。所有#submit指定项都应该由form_execute_handlers();来操作执行,而不是node_form_submit();
form_execute_handlers();判断需要执行的$handlers部分时,逻辑错误.
if (isset($form_state[$type . '_handlers'])) {
$handlers = $form_state[$type . '_handlers'];
}
// Otherwise, check for a form-level handler.
elseif (isset($form['#' . $type])) {
$handlers = $form['#' . $type];
}
else {
$handlers = array();
}错误说明:如果表单在之前的处理中已经完全解析$form中的各项参数,并把#submit值赋值给$form_state那么此时
应该只获取$form_state中的$type.'_handlers',如果没有做到如此规范,那么$form_state[$type.'_handlers']和
$form['#'.$type]应该同时被执行,而该段代码片段说明,如果执行$form_state[$type.'_handlers'],那么后面的
就不会执行,所以逻辑错误。
而$form_state[$type.'_handlers']中,只有一个函数的原因是
//code snipe from form_builder(); executed by drupal_process_form();
if (!$form_state['programmed'] && !isset($form_state['triggering_element']) && !empty($form_state['buttons'])) {
$form_state['triggering_element'] = $form_state['buttons'][0];
}这里$form['#submit']被忽略了,由于此接下来的代码片段如下
foreach (array('validate', 'submit') as $type) {
if (isset($form_state['triggering_element']['#' . $type])) {
$form_state[$type . '_handlers'] = $form_state['triggering_element']['#' . $type];
}
}那么$form['#submit']的定义彻底的没有了意义。
在接下来的整个表单处理流程中,在form.inc文件中,在没有处理#submit的地方,这个处理操作被放置到了node.page.inc中???
解决该问题的临时办法:
不使用#submit项,对node节点表单添加后的处理操作改由 HOOK_node_insert,HOOK_node_update,HOOK_node_delete操作,其次还有
HOOK_node_presave,HOOK_entity_presave可用,这里需要说明,HOOK_node_delete是在$node被删除前执行,insert,update是在操作
后执行。
