install_6.inc 14.3 KB
Newer Older
1 2 3 4 5 6
<?php
/**
 *  @file
 *    Rebuild all the caches
 */

7 8 9 10 11
$GLOBALS['url'] = d()->uri;
$GLOBALS['profile'] = d()->profile;
$GLOBALS['install_locale'] = d()->language;
$GLOBALS['base_url'] = provision_get_base_url();

12 13 14
// @TODO Document how/why this works.
require_once 'includes/install.inc';  // From the Drupal platform.
require_once 'install.inc';           // From Provision.
15 16

define('MAINTENANCE_MODE', 'install');
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

/**
 * Verify if Drupal is installed.
 */
function install_verify_drupal() {
  $result = @db_query("SELECT name FROM {system} WHERE name = 'system'");
  return $result && db_result($result) == 'system';
}

/**
 * Verify existing settings.php
 */
function install_verify_settings() {
  global $db_prefix, $db_type, $db_url;
  // Verify existing settings (if any).
  if (!empty($db_url)) {

34 35 36
    // We need this because we want to run form_get_errors.
    // @todo why are we setting those variables if they are not
    // reachable outside this scope?!
37
    $url = parse_url(is_array($db_url) ? $db_url['default'] : $db_url);
38 39 40 41 42 43 44 45 46 47 48 49
    if (!empty($url['user']) && !empty($url['pass']) && !empty($url['host'])) {
      $db_user = urldecode($url['user']);
      $db_pass = urldecode($url['pass']);
      $db_host = urldecode($url['host']);
      $db_port = isset($url['port']) ? urldecode($url['port']) : '3306';
      $db_path = ltrim(urldecode($url['path']), '/');
      $settings_file = './'. conf_path() .'/settings.php';
      return TRUE;
    }
    else {
      return FALSE;
    }
50 51 52 53
  }
  return FALSE;
}

54
function install_create_admin_user($client_email) {
55 56
  $name = drush_get_option('admin_user', PROVISION_DEFAULT_ADMIN_USER);
  if ($error = user_validate_name($name)) {
57
    drush_log(dt('Error setting UID username to `!user`: ', array('!user' => $name)) . $error . dt(' Using default (!default) instead.', array('!default' => PROVISION_DEFAULT_ADMIN_USER)), 'warning');
58 59
    $name = PROVISION_DEFAULT_ADMIN_USER;
  }
60

61 62
  // create the admin account
  $account = user_load(1);
63
  $edit['name'] = $name;
64 65 66 67 68 69 70 71 72 73 74 75
  $edit['pass'] = user_password();
  $edit['mail'] = $client_email;
  $edit['status'] = 1;

  // temporarily disable drupal's default mail notification
  $prev = variable_get('user_mail_status_activated_notify', TRUE);
  variable_set('user_mail_status_activated_notify', FALSE);
  $account = user_save($account,  $edit);
  variable_set('user_mail_status_activated_notify', $prev);
  return $account;
}

anarcat's avatar
anarcat committed
76
function install_send_welcome_mail($url, $account, $profile, $language, $client_email, $onetime) {
77
  global $base_url;
78 79
  // Mail one time login URL and instructions.
  $from = variable_get('site_mail', ini_get('sendmail_from'));
anarcat's avatar
anarcat committed
80

81
  $mail_params['variables'] = array(
82
      '!username' => $account->name, '!site' => variable_get('site_name', 'Drupal'), '!login_url' => $onetime,
omega8cc's avatar
omega8cc committed
83 84
      '!uri' => $base_url, '!uri_brief' => preg_replace('!^https?://!', '', $base_url), '!mailto' => $account->mail,
      '!date' => format_date(time()), '!login_uri' => url('user', array('absolute' => TRUE)),
85 86
      '!edit_uri' => url('user/'. $account->uid .'/edit', array('absolute' => TRUE)));

87
  $mail_success = drupal_mail('install', 'welcome-admin', $client_email, user_preferred_language($account), $mail_params, $from, TRUE);
88

89
  if ($mail_success) {
90
    drush_log(dt('Sent welcome mail to @client', array('@client' => $client_email)), 'success');
91 92
  }
  else {
93
    drush_log(dt('Could not send welcome mail to @client', array('@client' => $client_email)), 'warning');
94
  }
95
}
96

97
function install_mail($key, &$message, $params) {
98
  global $profile;
99 100 101 102 103 104 105
  switch ($key) {
    case 'welcome-admin':
      // allow the profile to override welcome email text
      if (file_exists("./profiles/$profile/provision_welcome_mail.inc")) {
        require_once "./profiles/$profile/provision_welcome_mail.inc";
        $custom = TRUE;
      }
omega8cc's avatar
omega8cc committed
106
      elseif (file_exists(dirname(__FILE__) . '/../provision_welcome_mail.inc')) {
107 108 109 110 111 112 113 114 115 116 117 118 119
        /** use the module provided welcome email
         * We can not use drupal_get_path here,
         * as we are connected to the provisioned site's database
         */
        require_once dirname(__FILE__) . '/../provision_welcome_mail.inc';
        $custom = TRUE;
      }
      else {
        // last resort use the user-pass mail text
        $custom = FALSE;
      }

      if ($custom) {
120 121
        $message['subject'] = dt($mail['subject'], $params['variables']);
        $message['body'] = dt($mail['body'], $params['variables']);
122 123 124 125 126 127 128 129 130 131
      }
      else {
        $message['subject'] = _user_mail_text('pass_subject', $params['variables']);
        $message['body'] = _user_mail_text('pass_body', $params['variables']);
      }

      break;
    }
}

132 133
function install_main() {
  require_once './includes/bootstrap.inc';
134
  drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_CONFIGURATION);
135 136

  // This must go after drupal_bootstrap(), which unsets globals!
137
  global $profile, $install_locale, $conf, $url;
138 139 140

  require_once './modules/system/system.install';
  require_once './includes/file.inc';
ergonlogic's avatar
ergonlogic committed
141 142 143 144 145
  require_once './includes/database.inc';
  require_once './includes/lock.inc';

  // Ensure the proper DB is active;
  db_set_active();
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172

  // Ensure correct page headers are sent (e.g. caching)
  drupal_page_header();

  // Set up $language, so t() caller functions will still work.
  drupal_init_language();

  // Load module basics (needed for hook invokes).
  include_once './includes/module.inc';
  $module_list['system']['filename'] = 'modules/system/system.module';
  $module_list['filter']['filename'] = 'modules/filter/filter.module';
  module_list(TRUE, FALSE, FALSE, $module_list);
  drupal_load('module', 'system');
  drupal_load('module', 'filter');

  // Set up theme system for the maintenance page.
  drupal_maintenance_theme();  // Check existing settings.php.

  $verify = install_verify_settings();
  // Drupal may already be installed.
  if ($verify) {
    // Since we have a database connection, we use the normal cache system.
    // This is important, as the installer calls into the Drupal system for
    // the clean URL checks, so we should maintain the cache properly.
    require_once './includes/cache.inc';
    $conf['cache_inc'] = './includes/cache.inc';

173
    drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_DATABASE);
174
    // Check if Drupal is installed.
175
    if (install_verify_drupal()) {
176 177
      drush_set_error('PROVISION_DRUPAL_SITE_INSTALLED', st('Site is already installed'));
      return FALSE;
178 179 180
    }
  }
  else {
181 182
    drush_set_error('PROVISION_CONFIG_NOT_VALID', st('Config file could not be loaded'));
    return FALSE;
183 184 185
  }


186
  drush_log(dt("Installing Drupal schema"), 'install');
187 188
  // Load the profile.
  require_once "./profiles/$profile/$profile.profile";
189
  drush_log(dt("Loading @profile install profile", array("@profile" => $profile)), 'install');
190

191
  drush_log(dt("Installing translation : @locale", array("@locale" => $install_locale)), 'install');
192 193 194 195 196 197 198 199 200 201

  /**
   * Handles requirement checking
   *
   * This code is based on install_check_requirements in install.php
   * We separate this out because we want to avoid all the user interface
   * code in this function, so we only use the relevant part of it.
   */
  $requirements = drupal_check_profile($profile);
  $severity = drupal_requirements_severity($requirements);
202

203 204 205 206
  // If there are issues, report them.
  if ($severity == REQUIREMENT_ERROR) {
    foreach ($requirements as $requirement) {
      if (isset($requirement['severity']) && $requirement['severity'] == REQUIREMENT_ERROR) {
207
        drush_log($requirement['description'] .' ('. st('Currently using !item !version', array('!item' => $requirement['title'], '!version' => $requirement['value'])) .')', 'error');
208 209 210 211 212 213 214 215 216 217 218
      }
    }
    $missing_requirement = TRUE;
  }
  if ($severity == REQUIREMENT_WARNING) {
    foreach ($requirements as $requirement) {
      if (isset($requirement['severity']) && $requirement['severity'] == REQUIREMENT_WARNING) {
        $message = $requirement['description'];
        if (isset($requirement['value']) && $requirement['value']) {
          $message .= ' ('. st('Currently using !item !version', array('!item' => $requirement['title'], '!version' => $requirement['value'])) .')';
        }
219
        drush_log($message, 'warning');
220 221 222 223
      }
    }
  }

mig5's avatar
mig5 committed
224
  if (isset($missing_requirement)) {
225
    return drush_set_error('PROVISION_INSTALL_MISSING_REQUIREMENTS');
226 227 228
  }

  // Verify existence of all required modules.
229
  $modules = drupal_verify_profile($profile, $install_locale);
230 231

  if (!$modules) {
232
    return drush_set_error('PROVISION_DRUPAL_INSTALL_FAILED');
233 234
  }

235 236 237 238 239 240 241
  $system_path = dirname(drupal_get_filename('module', 'system', NULL));
  require_once './'. $system_path .'/system.install';
  module_invoke('system', 'install');
  $system_versions = drupal_get_schema_versions('system');
  $system_version = $system_versions ? max($system_versions) : SCHEMA_INSTALLED;
  db_query("INSERT INTO {system} (filename, name, type, owner, status, throttle, bootstrap, schema_version) VALUES('%s', '%s', '%s', '%s', %d, %d, %d, %d)", $system_path .'/system.module', 'system', 'module', '', 1, 0, 0, $system_version);
  // Now that we've installed things properly, bootstrap the full Drupal environment
242

243 244 245
  module_rebuild_cache();
  drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_FULL);
  $modules = array_diff($modules, array('system'));
246

247 248 249
  if ($install_locale != 'en') {
    $modules = array_merge($modules, array('locale'));
  }
250 251 252 253 254 255 256 257 258 259 260 261 262 263
  /**
   * Further installation tasks
   *
   * This code is based on install_tasks() in install.php
   * It has been modified to remove any calls to the user interface,
   * and run all batches in the same process, instead of in a single page
   * load.
   */

  // profile-install and profile-install-batch tasks
  $files = module_rebuild_cache();
  foreach ($modules as $module) {
    _drupal_install_module($module);
    module_enable(array($module));
omega8cc's avatar
omega8cc committed
264
    drush_log(dt("Installed @module module.",
265 266 267
      array("@module" => $files[$module]->info['name'])));
  }

268 269
  module_invoke_all('init');

270
  drush_log("Initial locale import");
271 272
  // locale-initial-import and locale-inintial-batch tasks
  if (!empty($install_locale) && ($install_locale != 'en')) {
273
    include_once 'includes/locale.inc';
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
    // Enable installation language as default site language.
    locale_add_language($install_locale, NULL, NULL, NULL, NULL, NULL, 1, TRUE);
    // Collect files to import for this language.
    $batch = locale_batch_by_language($install_locale);
    if (!empty($batch)) {
      $install_locale_batch_components = $batch['#components'];
      batch_set($batch);
      $batch =& batch_get();
      $batch['progressive'] = FALSE;
      batch_process();
    }
  }

  // configure-task
  variable_set('site_name', $url);
  variable_set('site_mail', 'webmaster@' . $url);
  variable_set('clean_url', TRUE);
  variable_set('install_time', time());

293 294 295 296
  // Get the timezone offset from system time
  $tz_offset = date('Z');
  variable_set('date_default_timezone', $tz_offset);

297 298 299 300 301
  menu_rebuild();

  // profile task
  // @TODO support install profiles with multiple additional tasks
  $task = 'profile';
302

303
  $function = $profile .'_profile_tasks';
304

305
  if (function_exists($function)) {
306
    while (!in_array($task, array('profile-finished', 'finished'))) {
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
      drush_log(dt("Running profile specific task : !task", array('!task' => $task)));
      module_rebuild_cache();
      module_load_all();
      // stop batch api from re-directing. ever.
      $batch =& batch_get();
      $batch['progressive'] = FALSE;
      $batch['redirect'] = null;
      $batch['operations'] = array();
      $batch['url'] = 'batch';
      batch_set($batch);

      // The profile needs to run more code, maybe even more tasks.
      // $task is sent through as a reference and may be changed!
      $output = $function($task, $url);

      $task = variable_get('install_task', $task);
      variable_del('install_task');

      // If the profile doesn't move on to a new task we assume
      // that it is done.
      if ($task == 'profile') {
        $task = 'profile-finished';
      }
    }
331 332
  }

333 334
  if ($task == 'profile-finished') {
    // profile-finished task
omega8cc's avatar
omega8cc committed
335
    // Secondary locale import
336 337 338 339 340 341 342 343 344 345 346 347
    if (!empty($install_locale) && ($install_locale != 'en')) {
      // Collect files to import for this language. Skip components
      // already covered in the initial batch set.
      $batch = locale_batch_by_language($install_locale, NULL, $install_locale_batch_components);
      if (!empty($batch)) {
        // Start a batch, switch to 'locale-remaining-batch' task. We need to
        // set the variable here, because batch_process() redirects.
        batch_set($batch);
        $batch =& batch_get();
        $batch['progressive'] = FALSE;
        batch_process();
      }
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
    }
  }

  // done task
  // Rebuild menu to get content type links registered by the profile,
  // and possibly any other menu items created through the tasks.
  menu_rebuild();

  // Register actions declared by any modules.
  actions_synchronize();

  // Randomize query-strings on css/js files, to hide the fact that
  // this is a new install, not upgraded yet.
  _drupal_flush_css_js();

  cache_clear_all();
  variable_set('install_profile', $profile);

366
  $client_email = install_validate_client_email(drush_get_option('client_email', FALSE));
367

368
  $account = install_create_admin_user($client_email);
369 370 371 372 373 374 375 376

  // If a redirect is defined, the symlink to the alias needs to exist before
  // we generate the login link, below.
  _provision_drupal_maintain_aliases();

  // Store the one time login link in an option so the front end can direct the
  // user to their new site.
  $onetime = provision_generate_login_reset();
377
  drush_set_option('login_link', $onetime . '/login');
378
  drush_log(dt('Login url: !onetime', array('!onetime' => $onetime . '/login')), 'success');
anarcat's avatar
anarcat committed
379

380
  if ($client_email) {
anarcat's avatar
anarcat committed
381
    install_send_welcome_mail($url, $account, $profile, $install_locale, $client_email, $onetime);
382
  }
383
  variable_set('install_task', 'done');
384
}
385 386 387 388 389 390 391 392 393 394 395 396
/**
 * Batch callback for batch installation of modules.
 */
function _install_module_batch($module, $module_name, &$context) {
  drush_log(dt("Enabling module : !module", array("!module" => $module)), 'success');
  _drupal_install_module($module);
  // We enable the installed module right away, so that the module will be
  // loaded by drupal_bootstrap in subsequent batch requests, and other
  // modules possibly depending on it can safely perform their installation
  // steps.
  module_enable(array($module));
  $context['results'][] = $module;
397
  $context['message'] = dt('Installed %module module.', array('%module' => $module_name));
398
}
399
install_main();