You are here

9 与Drupal6站点整合用户

admin 的头像
Submitted by admin on 星期四, 2015-06-25 09:42

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

    我们首先来看一个简单的实例。如果一个单位使用了Drupal6搭建了自己的网站,觉得比较好用,在另一个新建网站上使用了Drupal7,然后提出了这样的需求,那就是Drupal6站点的用户能够直接登录到Drupal7上,这里假定两个网站都放在同一个服务器上。

 

    我们把这个模块的名字命名为d6user,表示Drupal 6的用户集成,先创建两个文件d6user.info, d6user.module。接着我们向info文件中添加以下代码: 

 

name = Drupal 6 User

description = Drupal 6 老网站用户的同步登录.

core = 7.x  

 

    注意文件的编码格式,UTF-8。接着我们向module文件中添加逻辑代码:

<?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();

}

}

 

    我们需要在用户登录时,提前检查Drupal6站点是否存在该用户,所以我们需要修改user_loginuser_login_block表单,把它的验证函数集合,替换成我们自己的。我们先来看一下Drupal核心为登录定义的验证器函数:

 

function user_login_default_validators() {

  return array('user_login_name_validate', 'user_login_authenticate_validate', 'user_login_final_validate');

}

 

    我们看到,这里定义了3个验证器函数:

 

user_login_name_validate:用来检查是否设置了用户名,并且它对应用户的状态是否为0,如果属于这种情况,则为表单返回错误信息;

 

user_login_authenticate_validate:首先会检查连续尝试登录未成功的次数,如果超过了最大次数,则返回;反之,会根据用户名、密码、以及状态为1,来对users表进行查询,如果返回结果的不为空,为user_login_name_validate设置对应的标记$form_state['uid']

 

user_login_final_validate:会根据$form_state['uid']是否存在进行判断,如果不存在,则为表单返回错误信息,反之登录用户。

 

    对于大多数的外部验证系统,只需要修改第二个验证器就可以了。在我们的这个例子当中,我们将三个验证器全部保留了下来,并在第一个验证器函数后面追加我们自定义的验证器函数。代码如下:

 

/**

 * 我们自己的登录验证函数集合,.

 */

function d6user_login_default_validators(){

  //注意这里面保留了Drupal自带的验证器,只是在中间加上了一个自定义的验证器。这些验证器的执行存在先后顺序的

  return array('user_login_name_validate', 'd6user_user_form_validate', 'user_login_authenticate_validate', 'user_login_final_validate');

}

 

    最后,我们看一下d6user_user_form_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);

}

}

}

 

}

    上述代码中,有详细的注释,这里就不再过多解释。我们需要做的是,修改settings.php文件,让Drupal7站点能够直接访问Drupal6站点的数据库。有关Drupal连接多个数据库,可参看数据库API一章。修改的代码如下:

$databases['default']['default'] = array(

  'driver' => 'mysql',

  'database' => 'thinkindrupal',

  'username' => 'root',

  'password' => '',

  'host' => 'localhost',

  'prefix' => '',)

;

$databases['d6user']['default'] = array(

  'driver' => 'mysql',

  'database' => 'drupal6',

  'username' => 'root',

  'password' => '',

  'host' => 'localhost',

  'prefix' => '',

);

    这样,当用户登录时,如果该用户名在Drupal7站点上不存在,那么我们会检查它是否存在于Drupal6站点上,如果存在,自动将其保存到Drupal7的系统中去。


Drupal版本: