Drupal 7 中文教程 代码部分

Drupal 7 中文教程 代码部分,

这里面包含了教程中所有的代码部分,包括模块的实例代码,菜单的实例代码,用户的实例代码,各个部分的实例代码。

所有的代码,都是原创的,源自于多年的实践经验。

Drupal版本:

Drupal 7 中文教程 字段验证 ISBN验证

<?php

/**
 * @file
 * isbn validation
 */

Drupal info文件:

name = ISBN Validation
description = "Add ISBN validation to text field"
core = 7.x
dependencies[] = field
dependencies[] = field_ui

module文件:

/**
 * Implements hook_field_attach_validate().
 */
function isbn_validation_field_attach_validate($entity_type, $entity, &$errors) {
 list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
 
 if($entity_type =='node' &&  $bundle == 'book'){
   $field_isbn_length = strlen($entity->field_isbn['und'][0]['value']);
   if(($field_isbn_length != 10) && ($field_isbn_length != 13)){
    $errors['field_isbn']['und'][0][] = array(
     'error' => 'field_isbn',
     'message' => t('无效的ISBN号.'),
    );
   }  
 }
}

Drupal 7 中文教程 省市县三级联动 实例代码

<?php
/**
 * @file
 * 省市县三级联动实例代码,
 */

/**
 * 实现钩子hook_menu().
 */
function shengshixian_menu() {
  $items['ssx'] = array(
  'title' => '省市县',
    'page callback' => 'shengshixian_test_page',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );

  return $items;
}

/**
 * 路径“ssx”页面的回调函数
 */
function shengshixian_test_page(){
 $render_array = array();
 //我们为这个页面设置标题
 drupal_set_title('省市县三级联动');
 //页面的正文为一个表单,注意drupal_get_form返回的不是html,需要使用drupal_render呈现一下。
 $render_array['#markup'] .= drupal_render(drupal_get_form('shengshixian_test_form'));
 //Drupal7的页面回调,返回的应该是一个数组,只有在退化形式下,才返回字符串。
 return $render_array;
}

/**
 * 表单shengshixian_test_form的构建函数
 */
function shengshixian_test_form($form, &$form_state){
  //设置省市县对应元素的默认值
  $default_sheng = !empty($form_state['values']['sheng']) ? $form_state['values']['sheng'] : '';
 $default_shi = !empty($form_state['values']['shi']) ? $form_state['values']['shi'] : '';
 $default_xian = !empty($form_state['values']['xian']) ? $form_state['values']['xian'] : '';
 
 //构建省份的选项数组,首先设置了一个提示语
  $sheng_options = array(
   '' => '请选择省份',
 );
 
 //向数据库中查询省份信息,
 $query_sheng = db_select('taxonomy_term_data','ttd')
 ->fields('ttd', array('tid', 'name'));
 
 //因为省份是第一级术语,分类术语的父亲为0
 $query_sheng->leftJoin('taxonomy_term_hierarchy', 'tth', 'ttd.tid = tth.tid ');
 $query_sheng->condition('tth.parent', 0);
 
 //需要确定术语所在的词汇表,就是我们在前面创建的地区
 $query_sheng->leftJoin('taxonomy_vocabulary', 'tv', 'ttd.vid = tv.vid ');
 $query_sheng->condition('tv.machine_name', 'diqu');
 
 //按照tid排序,并执行
 $result_sheng = $query_sheng->orderBy('tid')->execute();
 
 //将返回的结果,进行迭代,为$sheng_options赋值。
 foreach ($result_sheng as $record) {
   $sheng_options[$record->tid] = $record->name;
 }
 //省份表单元素
 $form['sheng'] = array(   
   '#title' => t('请选择您所在的省份?'),   
   '#type' => 'select',   
   '#options' => $sheng_options,   
   '#default_value' => $default_sheng,
    //#ajax属性数组  
   '#ajax' => array(     
     'callback' => 'shengshixian_sheng_callback',     
     'wrapper' => 'shi-wrapper-div',     
     'method' => 'replace',     
     'effect' => 'fade',   
   ), 
 );
 
 //构建市的选项数组,首先设置了一个提示语
 $shi_options = array(
   '' => '请选择市',
 );
 //在省份不为空的情况下,取该省份下的所有的市
 if(!empty($default_sheng)){
 
   //向数据库中查询术语信息,
  $query_shi = db_select('taxonomy_term_data','ttd')
  ->fields('ttd', array('tid', 'name'));
  //将其父术语限定在前面的省份的具体值上
  $query_shi->leftJoin('taxonomy_term_hierarchy', 'tth', 'ttd.tid = tth.tid ');
  $query_shi->condition('tth.parent', $default_sheng);
  //由于省份信息里面,已经包含了词汇表信息,所以我们不再需要关联这个taxonomy_vocabulary表。
  //$query_sheng->leftJoin('taxonomy_vocabulary', 'tv', 'ttd.vid = tv.vid AND tv.machine_name = :machine_name', array(':machine_name' => 'diqu'));
  
  //按照tid排序,并执行
  $result_shi = $query_shi->orderBy('tid')->execute();
  
  //将返回的结果,进行迭代,为$shi_options赋值。
  foreach ($result_shi as $record) {
   $shi_options[$record->tid] = $record->name;
  }

 }
 /*
 //测试代码,中间测试的时候用的,这里保留了,开发模块所用到的测试代码很多,多数都已删除。
  $form['test'] = array( 
   '#markup' => '123456:'.$default_sheng
 );
 */
 //表单元素市
 $form['shi'] = array(   
   '#title' => t('请选择您所在的市?'),   
  '#prefix' => '<div id="shi-wrapper-div">',   
  '#suffix' => '</div>',
   '#type' => 'select',   
   '#options' => $shi_options,   
   '#default_value' => $default_shi,
    '#ajax' => array(     
     'callback' => 'shengshixian_shi_callback',     
     'wrapper' => 'xian-wrapper-div',     
     'method' => 'replace',     
     'effect' => 'fade',   
   ),     
 );
 
 //构建县的选项数组,首先设置了一个提示语
 $xian_options = array(
   '' => '请选择县',
 );
 //在市不为空的情况下,取该市下的所有的县
 if(!empty($form_state['values']['shi'])){
 
   //向数据库中查询术语信息,
  $query_xian = db_select('taxonomy_term_data','ttd')
  ->fields('ttd', array('tid', 'name'));
  
  //将其父术语限定在前面的市的具体值上
  $query_xian->leftJoin('taxonomy_term_hierarchy', 'tth', 'ttd.tid = tth.tid AND tth.parent = :parent', array(':parent' => $form_state['values']['shi']));
  $query_xian->condition('tth.parent', $default_shi);
  
  //由于最前面省份信息里面,已经包含了词汇表信息,所以我们不再需要关联这个taxonomy_vocabulary表。
  //$query_sheng->leftJoin('taxonomy_vocabulary', 'tv', 'ttd.vid = tv.vid AND tv.machine_name = :machine_name', array(':machine_name' => 'diqu'));
  
  //按照tid排序,并执行
  $result_xian = $query_xian->orderBy('tid')->execute();
  
  //将返回的结果,进行迭代,为$xian_options赋值。
  foreach ($result_xian as $record) {
   $xian_options[$record->tid] = $record->name;
  }
 }
 
 //表单元素县
 $form['xian'] = array(   
   '#title' => t('请选择您所在的县/区?'),   
  '#prefix' => '<div id="xian-wrapper-div">',   
  '#suffix' => '</div>',
   '#type' => 'select',   
   '#options' => $xian_options,   
   '#default_value' => $default_xian,
   
 );
 
  //提交按钮
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('提交'),
  );
  return $form;
}

/**
 * 表单元素sheng,它的值变更时,对应的Ajax回调函数。
 */
function shengshixian_sheng_callback($form,&$form_state){
  //根据当前省份,重新确定市的可选项。返回重新构建的表单元素shi
 return $form['shi'];
}

/**
 * 表单元素sheng,它的值变更时,对应的Ajax回调函数。
 */
function shengshixian_shi_callback($form,&$form_state){
  //根据当前所选的市,重新确定县的可选项。返回重新构建的表单元素xian
 return $form['xian'];
}

Drupal版本:

Drupal 7 中文教程 简单的同步登陆 Drupal7同步Drupal6的用户

<?php

/**
 * @file
 * 当登录Drupal7站点时,检查是否在drupal6站点存在这个帐户,
 * 如果存在,将其保存到新的站点.
 */

/**
 * 实现钩子hook_form_FORMID_alter().
 */
function d6user_form_alter(&$form, &$form_state, $form_id){
  //这里我们对于表单user_login,user_login_block同时添加了一个验证器
  if($form_id == 'user_login' || $form_id == 'user_login_block'){
   $form['#validate'] = d6user_login_default_validators();
 }
}

/**
 * 我们自己的登录验证函数集合,.
 */
function d6user_login_default_validators(){
  //注意这里面保留了Drupal自带的验证器,只是在中间加上了一个自定义的验证器。这些验证器的执行存在先后顺序的
  return array('user_login_name_validate', 'd6user_user_form_validate', 'user_login_authenticate_validate', 'user_login_final_validate');
}

/**
 * 我们自己定义的登录验证函数,它在user_login_authenticate_validate前面执行.
 */
function d6user_user_form_validate($form, &$form_state){
  //form_set_error('name',t('用户名,密码不匹配.')); 这里保留了调试信息
  $name = $form_state['values']['name'];
 $pass = $form_state['values']['pass'];
 if (!empty($name) && !empty($pass)) {
   //drupal_set_message('123'); 这里保留了调试信息,用户调试代码,方便大家测试
   $account = db_query("SELECT * FROM {users} WHERE name = :name ", array(':name' => $name))->fetchObject();
  //如果用户名存在,则返回.
  if ($account) {
    return;
  }else{
   // $sql = "SELECT * FROM {users} WHERE name = :name AND pass = :pass";
   //drupal_set_message('123456');
   //我们向Drupal6站点的用户表进行查询,检查该用户是否存在。
   db_set_active('d6user');
   $account = db_query("SELECT * FROM users WHERE name = :name AND pass = :pass", array(':name' => $name, ':pass' => md5($pass)))->fetchObject();
   db_set_active('default');
   if($account){
    // drupal_set_message('1234567');
        //此时,用户帐号在Drupal6中存在,并且用户名密码正确
    $userinfo = array(
     'name' => $name,
     'pass' => $pass,
     'mail' => $account->mail,
     'init' => $name,
     'status' => 1,
     'access' => REQUEST_TIME
    );
    //我们将查询到的信息保存到Drupal7的用户表中
    $account = user_save(drupal_anonymous_user(), $userinfo);
   }
  }
 }

}

Drupal版本:

Drupal 7 中文教程 联系我们 两步表单 module 文件 代码部分

<?php

/**
 * @file
 * 方便用户联系我们.
 */

/**
 * 实现钩子hook_menu().
 */
function contactus_menu() {
  $items = array();
 //联系我们菜单项
  $items['contactus'] = array(
    'tilte' => '联系我们',
      'page callback' => 'contactus_page',
      'type'     => MENU_CALLBACK,
      'access callback' =>TRUE,
   'file' => 'contactus.pages.inc',
  );
 //确认页面菜单项
  $items['contactus/confirm'] = array(
      'page callback' => 'contactus_confirm_page',
      'type'     => MENU_CALLBACK,
      'access callback' =>TRUE,
   'file' => 'contactus.pages.inc',
  );
 //致谢页面菜单项
  $items['contactus/thanks'] = array(
      'page callback' => 'contactus_thanks_page',
      'type'     => MENU_CALLBACK,
      'access callback' =>TRUE,
   'file' => 'contactus.pages.inc',
  );
  return $items;
}

/**
 * 实现钩子hook_mail().
 */
function contactus_mail($key, &$message, $params){
 $language = $message['language'];
  switch ($key) {
   case 'contact':
  
    //邮件的标题
    $message['subject'] = '联系我们';
   
   //邮件正文,这里面包含:姓名、单位名称、电子邮件、电话号码、邮件正文、访问来源
      $message['body'][] = '姓名:'.$params['name'];
      $message['body'][] = '单位名称:'.$params['company_name'];
      $message['body'][] = '电子邮件:'.$params['mail'];
      $message['body'][] = '电话号码:'.$params['phone'];
      $message['body'][] = '邮件正文:'.$params['contact'];
   
      //对于访问来源,如果visit的值我们选择了“其它”,那么此时我们取$params['other'],否则取$params['visit']
      $visit = "";
      if($params['visit'] == 'other'){
        $visit = $params['other'];
      }else{
        $visit = $params['visit'];
      }
      $message['body'][] = '访问来源:'. $visit;
  }
}
 

Drupal版本:

Drupal 7 中文教程 联系我们 两步表单 “确认”页面回调

/**
 * “确认”页面的回调函数
 */
function contactus_confirm_page(){
  //我们为这个页面设置标题
 drupal_set_title('联系我们');
 
 //这里首先作了判断,如果会话中没有设置contactus_form,返回contactus
 if(empty($_SESSION['contactus_form'])){
  drupal_goto('contactus');
 }else{
 }

 $render_array = array(
   '#markup' => '',
 );
 //该页面的正文为一个表单,注意对于表单,这里需要使用drupal_render呈现一下。
 $render_array['#markup'] .= drupal_render(drupal_get_form('contactus_confirm_form'));
 //Drupal7的页面回调,返回的应该是一个数组
 return $render_array;
}

/**
 * “确认”表单的构建函数
 */
function contactus_confirm_form(){
  //添加我们自己的CSS,用来控制表单的样式
 drupal_add_css(drupal_get_path('module', 'contactus').'/contactus.css');
 //drupal_set_message(print_r($_SESSION['contactus_form']));
 //表单元素“姓名”
 $form['name'] = array(
  '#title' => t('姓名'),
  //表单元素的类型,这里为item
  '#type' => 'item',
  //'#default_value' => $_SESSION['contactus_form']['name'],
  //表单元素的#markup,在Drupal6下面,我用的是#value,在7下面就无法工作,改为了#default_value,还是不行,
  //最后改为#markup,才可以了
  '#markup' => isset($_SESSION['contactus_form']['name'])?$_SESSION['contactus_form']['name']:"",
 );
 
  //表单元素“单位名称”
 $form['company_name'] = array(
  '#title' => t('单位名称'),
  '#type' => 'item',
  //这是我在调试的时候,使用#value、#default_value、#description分别测试时的代码,这里保留了。
  //'#value' => $_SESSION['contactus_form']['company_name'],
  //'#value' => '123456',
  '#markup' => isset($_SESSION['contactus_form']['company_name'])?$_SESSION['contactus_form']['company_name']:"",
  //'#description' => '123456',
 );
 
 //表单元素“电子邮件”
 $form['mail'] = array(
  '#title' => t('电子邮件'),
  '#type' => 'item',
  '#markup' => isset($_SESSION['contactus_form']['mail'])?$_SESSION['contactus_form']['mail']:"",
 );
 
 //表单元素“电话号码”
 $form['phone'] = array(
  '#title' => t('电话号码'),
  '#type' => 'item',
  '#markup' => isset($_SESSION['contactus_form']['phone'])?$_SESSION['contactus_form']['phone']:"",
 );
 
  //表单元素“邮件正文”
 $form['contact'] = array(
  '#title' => t('邮件正文'),
  '#type' => 'item',
  '#markup' => isset($_SESSION['contactus_form']['contact'])?$_SESSION['contactus_form']['contact']:"",
 );
 
 //表单元素“访问来源”
 $form['visit'] = array(
  '#title' => t('访问来源'),
  '#type' => 'item',
  '#markup' => isset($_SESSION['contactus_form']['visit'])?$_SESSION['contactus_form']['visit']:"",
 );
 
 //如果访问来源,我们选择了“其它”,此时使用other表单元素的值来替换$form['visit']['#markup']。
 if( isset($_SESSION['contactus_form']['visit']) && $_SESSION['contactus_form']['visit'] == 'other'){
  $form['visit']['#markup'] = isset($_SESSION['contactus_form']['other'])?$_SESSION['contactus_form']['other']:"";
 } 
 /*
 //表单元素“返回”按钮
  $form['back'] = array(
    '#type' => 'submit',
    '#value' => t('返回'),
    '#submit' => array('contactus_confirm_form_back'),
  );
 //表单元素“提交”按钮
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('提交'),
  );
  */
 
  //表单元素“返回”图片按钮
  $form['image_back'] = array(
    '#type' => 'image_button',
    '#src' => drupal_get_path('module','contactus').'/images/button2-1.jpg',
  //使用这个按钮提交时,对应的提交处理函数为contactus_confirm_form_back
    '#submit' => array('contactus_confirm_form_back'),
    '#executes_submit_callback' => TRUE,
  //为表单元素添加两个属性,onmouseout、onmouseover,为了在鼠标移到按钮上时,显示不同的图片效果
    '#attributes' =>array(
      'onmouseout' => "this.src='".base_path().drupal_get_path('module','contactus')."/images/button2-1.jpg'",
      'onmouseover' => "this.src='".base_path().drupal_get_path('module','contactus')."/images/button2-2.jpg'",
    ),
  );
 
  //表单元素“提交”图片按钮
  $form['image_submit'] = array(
    '#type' => 'image_button',
    '#src' => drupal_get_path('module','contactus').'/images/button3-1.jpg',
    '#executes_submit_callback' => TRUE,
  //使用这个按钮提交时,对应的提交处理函数为contactus_confirm_form_submit
    '#submit' => array('contactus_confirm_form_submit'),
    '#attributes' =>array(
      'onmouseout' => "this.src='".base_path().drupal_get_path('module','contactus')."/images/button3-1.jpg'",
      'onmouseover' => "this.src='".base_path().drupal_get_path('module','contactus')."/images/button3-2.jpg'",
    ),
  );
 
  return $form;
}

/**
 * 返回按钮对应的提交函数
 */
function contactus_confirm_form_back($form, &$form_state){
  //简单的重定向到contactus页面
 $form_state['redirect'] = 'contactus';
}

/**
 * 提交按钮对应的提交函数
 */
function contactus_confirm_form_submit($form, &$form_state){
 $values = NULL;
 //从会话中获取用户最初提交的值,并将$_SESSION['contactus_form']置为空。
 if(empty($_SESSION['contactus_form'])){
  drupal_goto('contact');
 }else{
  $values = $_SESSION['contactus_form'];
  unset($_SESSION['contactus_form']);
 }
 
 //收件人地址,这里为作者的邮箱
 $to = 'g089h515r806@gmail.com';
 //用户填写的邮箱地址
 $from = $values['mail'];
 
 //发送邮件
 drupal_mail('contactus', 'contact', $to, language_default(), $values, $from);
 
 //简单的重定向到致谢页面
 $form_state['redirect'] = 'contactus/thanks';
}

/**
 * “致谢”页面的回调函数
 */
function contactus_thanks_page(){
  //我们为这个页面设置标题
 drupal_set_title('联系我们');
 $render_array = array(
   '#markup' => '',
 );
 //Drupal7的页面回调,返回的应该是一个数组
 $render_array['#markup'] .= '<div id="contactus-thanks">';
 $render_array['#markup'] .= t('感谢您的来信,我们会在第一时间给您回复。');
 $render_array['#markup'] .= '</div>';
 
 return $render_array;
}
 

Drupal版本:

Drupal 7 中文教程 联系我们 两步表单 “联系我们”页面回调

<?php

/**
 * @file
 * 各种页面的回调函数.
 */
 
/**
 * “联系我们”页面的回调函数
 */
function contactus_page(){
  //我们为这个页面设置标题
 drupal_set_title('联系我们');
 
 $render_array = array(
   '#markup' => '',
 );
 
 //该页面的正文为一个表单,注意对于表单,这里需要使用drupal_render呈现一下。
 $render_array['#markup'] .= drupal_render(drupal_get_form('contactus_form'));
 
 //Drupal7的页面回调,返回的应该是一个数组
 return $render_array;
}

/**
 * “联系我们”表单的构建函数
 */
function contactus_form(){
  //添加我们自己的CSS,用来控制表单的样式
 drupal_add_css(drupal_get_path('module', 'contactus').'/contactus.css');
 
  //提示信息,默认为markup类型。
 $form['tips'] = array(
  '#prefix' =>'<div id="tips">',
  '#markup' => t('<span class="form-required">*</span> 号为必填项。'),
  '#suffix' =>'</div>',
 );
 
 //表单元素“姓名”
 $form['name'] = array(
   //表单元素的#title属性,对应于实际输出中的label
  '#title' => t('姓名'),
  //表单元素的类型,这里为textfield
  '#type' => 'textfield',
  //这个表单元素是必填的
  '#required' => TRUE,
  //表单元素的默认值,这里使用了三位运算符和isset进行判定
  '#default_value' =>isset($_SESSION['contactus_form']['name'])?$_SESSION['contactus_form']['name']:"",
  //表单元素的描述,
  '#description' => t('例如:周星驰'),
 );
 
  //表单元素“单位名称”
 $form['company_name'] = array(
  '#title' => t('单位名称'),
  '#type' => 'textfield',
  '#required' => TRUE,
  '#default_value' =>isset($_SESSION['contactus_form']['company_name'])?$_SESSION['contactus_form']['company_name']:"",
  '#description' => t('例如:北京无名信息技术公司'),
 );
 
  //表单元素“电子邮件”
 $form['mail'] = array(
  '#title' => t('电子邮件'),
  '#type' => 'textfield',
  '#required' => TRUE,
  '#default_value' =>isset($_SESSION['contactus_form']['mail'])?$_SESSION['contactus_form']['mail']:"",
  '#description' => t('例如:info@example.com'),
 );
 
 //表单元素“电话号码”
 $form['phone'] = array(
  '#title' => t('电话号码'),
  '#type' => 'textfield',
  '#required' => TRUE,
  '#default_value' =>isset($_SESSION['contactus_form']['phone'])?$_SESSION['contactus_form']['phone']:"",
  '#description' => t('例如:010-88888888'),
 );
 
  //表单元素“邮件正文”
 $form['contact'] = array(
  '#title' => t('邮件正文'),
  //表单元素的类型,这里为textarea
  '#type' => 'textarea',
  '#required' => TRUE,
  '#default_value' =>isset($_SESSION['contactus_form']['contact'])?$_SESSION['contactus_form']['contact']:"",
 );
 
 //访问来源的可选项
 $visit_options = array(
  'baidu' =>t('百度'),
  'google' =>t('谷歌'),
  'sohu' =>t('搜狐'),
  'other' =>t('其它'),
 );
 //表单元素“访问来源”
 $form['visit'] = array(
  '#title' => t('访问来源'),
  //表单元素的类型,这里为radios
  '#type' => 'radios',
  //单选按钮的可选项。
  '#options' => $visit_options,
  '#default_value' =>isset($_SESSION['contactus_form']['visit'])?$_SESSION['contactus_form']['visit']:"",
  //为了便于控制radios的外观,我们使用#prefix、#suffix为其添加了一个带有ID的div
  '#prefix' => '<div id="visit-radios">',
  '#suffix' => '</div>',
 );
 
 //表单元素“其它”,它依赖于表单元素“访问来源”
 $form['other'] = array(
  '#title' => t('其它'),
  '#type' => 'textfield',
  '#default_value' =>isset($_SESSION['contactus_form']['other'])?$_SESSION['contactus_form']['other']:"",
  //这里的意思是,当表单元素“访问来源”的值为“other”时,这个表单元素才显示出来
   '#states' => array(
    'visible' => array(
     ':input[name="visit"]' => array('value' => 'other'),
   ),
  ),
 );
 /*
 //表单元素“确认”提交按钮
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('确认'),
  );
  */
 
  //表单元素“确认”提交按钮,这里采用了图片的形式
  $form['image_submit'] = array(
   //表单元素的类型,这里为image_button
    '#type' => 'image_button',
  
  //图片按钮特有的#src属性,
    '#src' => drupal_get_path('module','contactus').'/images/button1-1.jpg',
    '#value' => 'image_sub',
  
  //为表单元素添加两个属性,onmouseout、onmouseover,为了在鼠标移到按钮上时,显示不同的图片效果
    '#attributes' =>array(
      'onmouseout' => "this.src='".base_path().drupal_get_path('module','contactus')."/images/button1-1.jpg'",
      'onmouseover' => "this.src='".base_path().drupal_get_path('module','contactus')."/images/button1-2.jpg'",
    ),
  
  //为了便于控制image_button的外观,我们使用#prefix、#suffix为其添加了一个带有ID的div
    '#prefix' => '<div id="image-submit">',
    '#suffix' => '</div>',
  );

  return $form;
}

/**
 * contactus_form表单的验证函数
 */
function contactus_form_validate($form, &$form_state){
  //这里使用正则表达式,来验证邮箱的有效性,注意,这里的正则表达式,包围在"/...../"之间。
 if(!preg_match("/^[\w\-\.]+@[\w\-\.]+(\.\w+)+$/", $form_state['values']['mail'])){
  form_set_error('mail',t('您输入的电子邮件地址格式不正确'));
 }
}

/**
 * contactus_form表单的提交函数
 */
function contactus_form_submit($form, &$form_state){
  //把表单的值存放在会话中去,由于这里涉及到了两个不同的表单之间传值。
 $_SESSION['contactus_form'] = $form_state['values'];
 //表单重定向到确认页面
 $form_state['redirect'] = 'contactus/confirm';
}
 

Drupal版本:

Notice: Undefined index: integer:normal in DatabaseSchema_mysql->processField()

在自定义一个字段模块时,为节点类型添加一个这个类型的字段实例时,报了以下错误信息:

 
Notice: Undefined index: integer:normal 在 DatabaseSchema_mysql->processField() (行 201F:\xampp\htdocs\drupal\includes\database\mysql\schema.inc).
 
  • 创建字段 t t t 遇到问题:SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NOT NULL DEFAULT 0, PRIMARY KEY (`entity_type`, `entity_id`, `deleted`, `delta`' at line 10 。
  • 你的设置已被保存。
   分析了半天,始终找不到原因,google了一下,发现drupal.org上有同样的问题,http://drupal.org/node/735602。看看这个问题的解决办法:
 
=== modified file 'shipping/uc_shipping/uc_shipping.install'
--- shipping/uc_shipping/uc_shipping.install    2010-03-03 15:47:24 +0000
+++ shipping/uc_shipping/uc_shipping.install    2010-03-08 14:35:33 +0000
@@ -251,7 +251,7 @@
         'not null' => FALSE,
       ),
       'label_image' => array(
-        'type' => 'integer',
+        'type' => 'int',
         'unsigned' => TRUE,
         'not null' => FALSE,
       ),
@@ -303,7 +303,7 @@
   $sandbox['#finished'] = 0;
 
   $schema = array(
-    'type' => 'integer',
+    'type' => 'int',
     'unsigned' => TRUE,
     'not null' => FALSE,
   );
 
 
原来,我犯了同样的错误,将”int” 写成了“integer”,看来写程序,仅凭记忆还是不可靠的。下面是我定义的代码:
 return array(
    'columns' => array(
      'value' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => FALSE,
        'sortable' => TRUE,
      ),
      'manual' => array(
        'type' => 'integer',
                            'not null' => TRUE,
        'default' => 0,
      ),
    ),
 );

Think in Drupal 7, 区块更多链接

info文件:

name = Block More Link
description = Provide a more link for all blocks.
package = Other
version = VERSION
core = 7.x
configure = admin/config/block/morelink

install文件:

<?php

/**
 * @file
 * Install, update and uninstall functions for the block_morelink module.
 */

/**
 * Implements hook_schema().
 */
function block_morelink_schema() {
  $schema['block_morelink'] = array(
    'description' => 'Stores more link path.',
    'fields' => array(
      'module' => array(
        'type' => 'varchar',
        'length' => 64,
        'not null' => TRUE,
        'description' => "The block's origin module, from {block}.module.",
      ),
      'delta' => array(
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'description' => "The block's unique delta within module, from {block}.delta.",
      ),
      'url' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'description' => "The more link url of a block.",
      ),
      'title' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'description' => "The more link title of a block.",
      ),
    ),
    'primary key' => array('module', 'delta'),
    'indexes' => array(
      'url' => array('url'),
    ),
  );
  return $schema;
}

/**
 * change 'primary key' to array('module', 'delta').
 */
function block_morelink_update_7000(&$sandbox) {
  db_drop_primary_key('block_morelink');
  db_add_primary_key('block_morelink', array('module', 'delta'));
}

 

Think in Drupal 7, 区块更多链接 module文件

module文件中的代码,你可以在drupal.org上下载最新的模块代码:

http://drupal.org/project/block_morelink

<?php

/**
 * Implements hook_form_FORMID_alter().
 *
 * Adds more link path textfield to add block form.
 */
function block_morelink_form_block_add_block_form_alter(&$form, &$form_state) {
  block_morelink_form_block_admin_configure_alter($form, $form_state);
}
function block_morelink_form_block_admin_configure_alter(&$form, &$form_state){
 $result = db_query("SELECT url, title FROM {block_morelink} WHERE module = :module AND delta = :delta", array(
    ':module' => $form['module']['#value'],
    ':delta' => $form['delta']['#value'],
  ))->fetch();
  $default_morelink_url = empty($result)?'':$result->url;
  $default_morelink_title = empty($result)?'':$result->title;
 //$default_value = '';
 // More link settings.
  $form['settings']['morelink'] = array(
    '#type' => 'fieldset',
    '#title' => t('More link settings'),
    '#collapsible' => FALSE,
    //'#description' => t('Specify more link url and title.'),
  '#weight' => -1,
  );
 $form['settings']['morelink']['morelink_url'] = array(
    '#type' => 'textfield',
    '#title' => t('More Link url'),
    '#maxlength' => 255,
    '#description' => t('The More Link url of the block as shown to the user.') ,
    '#default_value' =>  $default_morelink_url,
    '#weight' => 0,
  );
  $form['settings']['morelink']['morelink_title'] = array(
    '#type' => 'textfield',
    '#title' => t('More Link title'),
    '#maxlength' => 255,
    '#description' => t('The More Link title of the block as shown to the user.') ,
    '#default_value' =>  $default_morelink_title,
    '#weight' => 1,
  );
  $form['#submit'][] = 'block_morelink_block_admin_configure_submit';
}

/**
 * Form submit handler for block configuration form.
 */
function block_morelink_block_admin_configure_submit($form, &$form_state){
 db_delete('block_morelink')
    ->condition('module', $form_state['values']['module'])
    ->condition('delta', $form_state['values']['delta'])
    ->execute();
   
  if(!empty($form_state['values']['morelink_url'])){
   $query = db_insert('block_morelink')->fields(array('url', 'title', 'module', 'delta'));
   //foreach (array_filter($form_state['values']['types']) as $type) {
     $query->values(array(
       'url' => $form_state['values']['morelink_url'],
       'title' => $form_state['values']['morelink_title'],
       'module' => $form_state['values']['module'],
       'delta' => $form_state['values']['delta'],
     ));
   //}
   $query->execute();
  }
 
}

/**
 * Process variables for block.tpl.php
 *
 * The $variables array contains the following arguments:
 * - $block
 *
 * @see block.tpl.php
 */
function block_morelink_preprocess_block(&$variables) {
 $result = db_query("SELECT url, title FROM {block_morelink} WHERE module = :module AND delta = :delta", array(
    ':module' => $variables['block']->module,
    ':delta' => $variables['block']->delta,
  ))->fetch();
  $morelink_url = empty($result)?'':$result->url;
  $morelink_title = empty($result)?'':$result->title;
 $variables['block']->more = theme('block_more_link',array('url'=>$morelink_url,'title'=>$morelink_title));
}

/**
 * Implements hook_menu().
 */
function block_morelink_menu() {
 // Block settings.
  $items['admin/config/block'] = array(
    'title' => 'Block',
    'description' => 'Block configuration.',
    'position' => 'left',
    'weight' => -10,
    'page callback' => 'system_admin_menu_block_page',
    'access arguments' => array('access administration pages'),
    'file' => 'system.admin.inc',
    'file path' => drupal_get_path('module', 'system'),
  );
  $items['admin/config/block/morelink'] = array(
    'title' => 'More link',
    'description' => 'the more link lable of block.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('block_morelink_label_settings'),
    'access arguments' => array('administer site configuration'),
    'weight' => -10,
   // 'file' => 'system.admin.inc',
  );
   return $items;
}
function block_morelink_label_settings(){
  $form['morelink_label'] = array(
    '#type' => 'textfield',
    '#title' => t('More Link lable'),
    '#maxlength' => 40,
    '#description' => t('The More Link lable of the block as shown to the user.') ,
    '#default_value' =>  variable_get('morelink_label', 'more'),
    '#weight' => -17,
  );
 
  return system_settings_form($form, TRUE);
}
function block_morelink_theme(){
 return array(
    'block_more_link' => array(
       'variables' => array('url' => NULL,'title' => NULL,)
    ),
   
  );
}

/**
 * Returns HTML for a "more" link, like those used in blocks.
 *
 * @param $variables
 *   An associative array containing:
 *   - url: The url of the main page.
 *   - title: A descriptive verb for the link, like 'Read more'.
 */
function theme_block_more_link($variables) {
 $output = "";
 if(!empty($variables['url'])){
    if (!empty($variables['title'])) {
      $morelink_label = $variables['title'];
    }
    else {
    $morelink_label = variable_get('morelink_label', 'more');
    }
   $output .= '<span class="block-more-link">' . l($morelink_label,$variables['url'],array('attributes'=>array('title'=>$variables['title']))). '</span>';
   //$output .='<span class="block-more-link">' . t('<a href="@link" title="@title">More</a>', array('@link' => check_url($variables['url']), '@title' => $variables['title'])) . '</div>';
 }
 return $output;
}
 

Drupal版本: