Drupal 开发函数参考

字段
1. 获取一个Entity类型里面的所有字段信息.
$instances = field_info_instances($entity_type, $bundle);

2.获取所有可用的字段类型, 此函数将遍历所有的hook_field_info().
$field_types = field_info_field_types();

3.获取指定的字段名信息
$fieldinfo = field_info_field(‘myfield_name’);

4. 获取所有的字段widget, 此函数将遍历所有的hook_field_widget_info().
$widget_types = field_info_widget_types();

Drupal 的错误和异常处理

在includes/bootstrap.inc文件的_drupal_bootstrap_configuration函数中可以看到Drupal 自定义了错误和异常的处理函数

function _drupal_bootstrap_configuration() {
 // Set the Drupal custom error handler.
 set_error_handler('_drupal_error_handler');
 set_exception_handler('_drupal_exception_handler');
......

Drupal 使用了_drupal_error_handler和_drupal_exception_handler函数来分别处理错误和异常.

Drupal 7 translation

程序执行顺序. 以下解释
Module: i18n_node

Node FORM 表单

1. node_add() 添加node跑的第一个函数
2. 接着获取node_form() 获取node表单. 里面会有一个node_object_prepare是整合node对象. 当你翻译一个已存在的node时, 你会发现跑了这个函数里面会多一个对象translation_source. 此对象由系统模块locale提供translation_node_prepare(). 此处的translation_source对象是由你在点击添加翻译以后根据传过来$_GET对象translation来获取. 传过的$_GET数据中还有target这个是lancode

在I18n模块中: i18n_node_form_node_form_alter() 这里覆盖了node默认的submit函数node_form_submit. 其实没有太大用处. 可以无视.

Node Save Process

主要的作用在于node_save中. 会调用Hook_node_insert. 这里会调用系统模块locale: translation_node_insert()
node_add();

Drupal hook_forms

http://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_forms/7

定义form id 对应 调用的函数名

function hook_forms($form_id, $args) {
  // Simply reroute the (non-existing) $form_id 'mymodule_first_form' to
  // 'mymodule_main_form'.
  $forms['mymodule_first_form'] = array(
    'callback' => 'mymodule_main_form',
  );

  // Reroute the $form_id and prepend an additional argument that gets passed to
  // the 'mymodule_main_form' form builder function.
  $forms['mymodule_second_form'] = array(
    'callback' => 'mymodule_main_form',
    'callback arguments' => array('some parameter'),
  );

  // Reroute the $form_id, but invoke the form builder function
  // 'mymodule_main_form_wrapper' first, so we can prepopulate the $form array
  // that is passed to the actual form builder 'mymodule_main_form'.
  $forms['mymodule_wrapped_form'] = array(
    'callback' => 'mymodule_main_form',
    'wrapper_callback' => 'mymodule_main_form_wrapper',
  );

  return $forms;
}

在commerce product 模块中, 我看到有 menu 的callback是 drupal_get_form(), 并且参数是commerce_product_ui_product_form. 但是我并没有找到这个function. 最后通过搜索过终于找到它是如何定义commerce_product_ui_product_form这个form

/**
 * Implements hook_forms().
 */
function commerce_product_ui_forms($form_id, $args) {
  $forms = array();

  // Define a wrapper ID for the product add / edit form.
  $forms['commerce_product_ui_product_form'] = array(
    'callback' => 'commerce_product_product_form',
  );

  // Define a wrapper ID for the product delete confirmation form.
  $forms['commerce_product_ui_product_delete_form'] = array(
    'callback' => 'commerce_product_product_delete_form',
  );

  return $forms;
}

Drupal 执行任意menu url

    这段代码也纺强悍了,只需要一个menu地址就会车出这个url 的content. index.php 也刚好运行了这个函数:

    http://api.drupal.org/api/drupal/includes%21menu.inc/function/menu_execute_active_handler/7

    menu_execute_active_handler 这个是drupal 路径处理函数,当你把menu node/2设置成 Active以后就运行处理node/2 这个path

    
    

    其实这样也是可以的

    return menu_execute_active_handler('node/2', FALSE);
    

Drupal menu_set_active_item 使用Link出错

这个函数使我的链接错乱了
当node view 的时候将menu Active设置为event. 这样写当然没错,是正确的。
当我进行文章搜索的时候, 搜索到了content type 为 event的内容, 也就会运行menu_set_active_item. 结果导致我的搜索结果分页链接也就坏了.
http://api.drupal.org/api/drupal/includes%21menu.inc/function/menu_set_active_item/7

官方有提示如果使用不当会有意想不到的结果。果然出现错误了

/**
 * Impelments hook_node_view()
 */
function MYMODULE_node_view($node) {
  if ($node->type == 'event') {
    menu_set_active_item('event');
  }
}

随之我修改了我的代码:

/**
 * Impelments Hook_node_view()
 */
function sigvaris_global_node_view($node) {
  if (arg(0)=='node' && $node->type == 'event') {
    menu_set_active_item('event');
  }
}

Drupal 去掉 Menu Link

/**
 * Overide theme_menu_link
 */
function sigvaris_menu_link(array $variables) {
  $element = $variables['element'];
  // 如果是footer_menu, 并且链接为, 那么就去掉链接
  if($element['#original_link']['menu_name'] == 'menu-footer-menu' && $element['#original_link']['link_path']=='') {
    $sub_menu = '';
    if ($element['#below']) {
      $sub_menu = drupal_render($element['#below']);
    }
    //$output = l($element['#title'], $element['#href'], $element['#localized_options']);
    return '' . $element['#title'] . $sub_menu . "\n";
  } else {
    //否则就使用默认的链接
    return theme_menu_link($variables);
  }
}

Drupal 钩子/Hook

Drupal 的大部分功能都是靠 钩子来改变和增加的

一般格式是: 模块名_钩子名

下面是几个比较常用的函数:

module_invoke($module, $hook)           //在指定的模块中执行指定的钩子
module_invoke_all($hook)                //执行所有模块中指定的钩子
module_implements($hook)                //查看有哪些模块加载了指定的钩子
drupal_alter($type, &$data)             //过滤所有hook_$type_alter($data) 

如何调用自定义钩子

module_invoke_all('my_custom_hook', &$name);

来创建这个钩子,我的模块名叫 mymodule

function mymodule_my_custom_hook(&$name) {
  $name = '123';
}

调用hook_$type_alter($data);来过滤你的数据

//比如你在写一个模块的时候,你有一个$name值. 如果这个name值是可以通过其它的钩子来进行过滤和覆盖
$name = get_name('cc');
drupal_alter('my_custom_hook', &$name);
return $name;

这样这个$name值就得到了过滤/修改