You are here

Drupal专业开发指南 第23章 运行附加的安装任务

g089h515r806 的头像
Submitted by g089h515r806 on 星期五, 2009-09-04 11:25

Think in Drupal

在安装的profile阶段,将运行我们在university_profile_task_list()中指定的任务。在该阶段期间,安装器将重复的调用university_profile_tasks(),并向其传递参数$task和$url,其中$task变量包含了任务名字,而$url则是一个在表单函数中可能用到的URL。安装器初次调用它时,$task将包含字符串profile

    每个任务完成后,Drupal将使用includes/install.inc中的install_goto()请求浏览器来执行一个HTTP重定向,接着在进入下一个任务以前执行一个完整的引导指定。当所有的任务都完成以后,$task将被设置为profile-finished,安装器将停止对university_profile_tasks()的调用并继续前进。
    下面是university_profile_tasks()的一个骨架:
 
function university_profile_tasks(&$task, $url) {
    if ($task == 'profile') {
        // The value of $task is 'profile' the first time we are called.
        // Set up all the things a default installation profile has.
        require_once 'profiles/default/default.profile';
        default_profile_tasks($task, $url);
        // Then do our custom setup here.
 
        // Set $task to the next task.
        $task = 'dept-info';
        // Display a form requesting some info.
        return drupal_get_form('university_department_info', $url);
    }
    if ($task == 'dept-info') {
        // Send email indicating that a site was set up.
 
        // Set $task to key of next task.
        $task = 'support-message';
        // Build some output.
 
        return $output;
    }
    if ($task == 'support-message') {
        // Return control to the installer.
        $task = 'profile-finished';
    }
}
 
    由于我们想要的大多数设置都与平时的Drupal站点一样,所以我们加载了Drupal的默认轮廓,并简单的调用default_profile_tasks(),而不是在我们的安装轮廓中重复所有的代码。另外的一种方式就是将默认轮廓中的代码复制粘贴到第一个任务中。
 
提示 一个简单的安装轮廓不需要实现多个任务。在它被调用时,它可以忽略传递给它的参数并运行代码。当安装器看见$task变量没有改变的话,它将继续前进,运行后面的安装轮廓步骤。Drupal的默认安装轮廓就是这样的一个轮廓,所以我们可以直接在这里调用default_profile_tasks(),而不用担心它会修改$task的值。
 
    注意前面代码中的结构。它包含了一系列的if语句,每一个语句对应一个任务。在每个任务的结尾处,通过引用传递的$task变量,此时将被修改,并返回任意输出,这样将生成一个附加的界面供用户进行交互。
    由于在自定义安装任务运行以前,已经设立了数据库并建立了连接,所以,安装器可以在每个任务的结尾处调用variable_set('install_task', $task),使用一个持久化变量来追踪当前任务的名字。如果你想从一个任务中向另一个任务传递信息的话,那么也可以使用这一技术。只要记住,在你最后一个任务的结尾处,使用variable_del()来删除你用过的变量,这样就可以了。
    下面是大学安装轮廓的university_profile_tasks()函数的完整版本,让我们仔细的学习一下:
 
/**
 * Perform final installation tasks for this installation profile.
 */
function university_profile_tasks(&$task, $url) {
    if ($task == 'profile') {
        // $task is set to 'profile' the first time this function is called.
        // Set up all the things a default installation profile has.
        require_once 'profiles/default/default.profile';
 
        // Need constants defined by modules/comment/comment.module
        // to be in scope.
        require_once 'modules/comment/comment.module';
 
        default_profile_tasks($task, $url);
        // If the administrator enables the comment module, we want
        // to have comments disabled for pages.
        variable_set('comment_page', COMMENT_NODE_DISABLED);
 
        // Define a News Item node type.
        $node_type = array(
            'type' => 'news',
            'name' => st('News Item'),
            'module' => 'node',
            'description' => st('A news item for the front page.'),
            'custom' => TRUE,
            'modified' => TRUE,
            'locked' => FALSE,
            'has_title' => TRUE,
            'title_label' => st('Title'),
            'has_body' => TRUE,
            'orig_type' => 'news',
            'is_new' => TRUE,
        );
        node_type_save((object)$node_type);
 
        // News items should be published and promoted to front page by default.
        // News items should create new revisions by default.
        variable_set('node_options_news', array('status', 'revision',                   'promote'));   
 
        // If the administrator enables the comment module, we want
        // to have comments enabled for news items.
        variable_set('comment_news', COMMENT_NODE_READ_WRITE);
 
        // Create a News Categories vocabulary so news can be classified.
        $vocabulary = array(
            'name' => st('News Categories'),
            'description' => st('Select the appropriate audience for your news                  item.'),
            'help' => st('You may select multiple audiences.'),
            'nodes' => array('news' => st('News Item')),
            'hierarchy' => 0,
            'relations' => 0,
            'tags' => 0,
            'multiple' => 1,
            'required' => 0,
        );
        taxonomy_save_vocabulary($vocabulary);
 
        // Define some terms to categorize news items.
        $terms = array(
            st('Departmental News'),
            st('Faculty News'),
            st('Staff News'),
            st('Student News'),
        );
 
        // Submit the "Add term" form programmatically for each term.
        $form_id = 'taxonomy_form_term';
        // The taxonomy_form_term form is not in taxonomy.module, so need
        // to bring it into scope by loading taxonomy.admin.inc.
        require_once 'modules/taxonomy/taxonomy.admin.inc';
        foreach ($terms as $name) {
            $form_state['values']['name'] = $name;
            $form_state['clicked_button']['#value'] = st('Save');
            drupal_execute($form_id, $form_state, (object)$vocabulary);
        }
 
        // Add a role.
        db_query("INSERT INTO {role} (name) VALUES ('%s')", 'site administrator');
 
        // Configure the pubcookie module.
        variable_set('pubcookie_login_dir', 'login');
        variable_set('pubcookie_id_is_email', 1);
        // ...other settings go here
 
        // Set $task to next task so the installer UI will be correct.
        $task = 'dept-info';
        drupal_set_title(st('Departmental Information'));
        return drupal_get_form('university_department_info', $url);
    }
    if ($task == 'dept-info') {
        // Report by email that a new Drupal site has been installed.
        $to = 'administrator@example.com';
        $from = ini_get('sendmail_from');
        $subject = st('New Drupal site created!');
        $body = st('A new Drupal site was created: @site', array(
            '@site' => base_path()));
        drupal_mail('university-profile', $to, $subject, $body, $from);
 
        // Set $task to next task so the installer UI will be correct.
        $task = 'support-message';
        drupal_set_title(st('Support'));
        $output = '<p>'. st('For support, please contact the Drupal Support Desk
            at 123-4567.') .'</p>';
        // Build a 'Continue' link that goes to the next task.
        $output .= '<p>'. l(st('Continue'), $url) .'</p>';
        return $output;
    }
    if ($task == 'support-message') {
        // Change to our custom theme.
        $themes = system_theme_data();
        $theme = 'university';
        if (isset($themes[$theme])) {
            system_initialize_theme_blocks($theme);
            db_query("UPDATE {system} SET status = 1 WHERE type = 'theme' AND
                name = '%s'", $theme);
            variable_set('theme_default', $theme);
            menu_rebuild();
            drupal_rebuild_theme_registry();
        }
 
        // Return control to the installer.
        $task = 'profile-finished';
    }
}
 

Drupal版本: