$task) { $tmp[$tname] = $task; if ($tname == 'install_select_profile') { $tmp['install_select_subprofile'] = array( 'display_name' => st('Choose subprofile'), 'display' => !empty($install_state['subprofiles']) && count($install_state['subprofiles']) != 1, 'run' => INSTALL_TASK_RUN_IF_REACHED, ); } if ($tname == 'install_profile_modules') { $tmp['install_load_subprofile'] = array( 'display_name' => st('Load chosen subprofile'), 'display' => TRUE, 'type' => 'batch', 'run' => INSTALL_TASK_RUN_IF_NOT_COMPLETED, 'function' => 'install_load_subprofile', ); } } $tasks = $tmp; } //------------------------------------------------------------------------------ // Callbacks /** * Build subprofile selection form */ function install_select_subprofile(&$install_state) { if (empty($install_state['subprofiles'])) { $install_state['subprofiles'] = array(); } $install_state['subprofiles'] += install_find_profiles(); // Removing current profilte unset($install_state['subprofiles'][$install_state['parameters']['profile']]); // Adding a "none" option $tmp = new stdClass(); $tmp->uri = './profiles/lp_core/lp_core.profile'; $tmp->filename = 'lp_core.profile'; $tmp->name = 'None'; $install_state['subprofiles']['none'] = $tmp; if (empty($install_state['parameters']['subprofile'])) { // Try to find a profile. $subprofile = _install_select_profile($install_state['subprofiles']); if (empty($subprofile)) { // We still don't have a profile, so display a form for selecting one. // Only do this in the case of interactive installations, since this is // not a real form with submit handlers (the database isn't even set up // yet), rather just a convenience method for setting parameters in the // URL. if ($install_state['interactive']) { include_once DRUPAL_ROOT . '/includes/form.inc'; drupal_set_title(st('Select an installation subprofile')); $form = drupal_get_form('install_select_profile_form', $install_state['subprofiles']); return drupal_render($form); } else { throw new Exception(install_no_profile_error()); } } else { $install_state['parameters']['subprofile'] = $subprofile; } } } /** * Load chosen subprofile */ function install_load_subprofile(&$install_state) { $subprofile = $install_state['parameters']['subprofile']; // Handle "none" fake subprofile if (strtolower($subprofile) == 'none') { return; } // Build subprofile path $path = DRUPAL_ROOT . '/profiles/' . $subprofile; // Load subprofile dependencies $info = drupal_parse_info_file($path . '/' . $subprofile . '.info'); $modules = $info['dependencies']; $modules[] = $install_state['parameters']['subprofile']; $files = system_rebuild_module_data(); $files += _module_build_dependencies(array($subprofile => _install_get_subprofile_object($subprofile))); ksort($files); // Always install required modules first. Respect the dependencies between // the modules. $required = array(); $non_required = array(); // Although the profile module is marked as required, it needs to go after // every dependency, including non-required ones. So clear its required // flag for now to allow it to install late. $files[$install_state['parameters']['subprofile']]->info['required'] = FALSE; // Add modules that other modules depend on. foreach ($modules as $module) { if ($files[$module]->requires) { $modules = array_merge($modules, array_keys($files[$module]->requires)); } } $modules = array_unique($modules); foreach ($modules as $module) { if (!empty($files[$module]->info['required'])) { $required[$module] = $files[$module]->sort; } else { $non_required[$module] = $files[$module]->sort; } } arsort($required); arsort($non_required); $operations = array(); foreach ($required + $non_required as $module => $weight) { $operations[] = array('_install_module_batch', array($module, $files[$module]->info['name'])); } $operations[] = array('_install_subprofile_modules_finished', array($subprofile)); $batch = array( 'operations' => $operations, 'title' => st('Installing @drupal - Subprofile', array('@drupal' => drupal_install_profile_distribution_name())), 'error_message' => st('The installation has encountered an error.'), 'finished' => '_install_profile_modules_finished', ); return $batch; } /** * Run the chose subprofile install function * @param string $subprofile * @param array $context */ function _install_subprofile_modules_finished($subprofile, &$context) { // Build subprofile path $path = DRUPAL_ROOT . '/profiles/' . $subprofile; // Launch subprofile install script include_once $path . '/' . $subprofile . '.install'; call_user_func($subprofile . '_install'); $context['results'][] = $subprofile; $context['message'] = st('Enabled %name subprofile.', array('%name' => $subprofile)); } /** * Load the subprofile object * @param string $subprofile */ function _install_get_subprofile_object($subprofile) { // Include the install profile in modules that are loaded. $object = new stdClass(); $object->name = $subprofile; $object->uri = 'profiles/' . $subprofile . '/' . $subprofile . '.profile'; $object->filename = $subprofile . '.profile'; // Install profile hooks are always executed last. $object->weight = 1000; // Set defaults for module info. $defaults = array( 'dependencies' => array(), 'description' => '', 'package' => 'Other', 'version' => NULL, 'php' => DRUPAL_MINIMUM_PHP, 'files' => array(), 'bootstrap' => 0, ); // The module system uses the key 'filename' instead of 'uri' so copy the // value so it will be used by the modules system. $object->filename = $object->uri; // Look for the info file. $object->info = drupal_parse_info_file(dirname($object->uri) . '/' . $object->name . '.info'); // Skip modules that don't provide info. if (empty($object->info)) { return null; } // Merge in defaults and save. $object->info = $object->info + $defaults; // Prefix stylesheets and scripts with module path. $path = dirname($object->uri); if (isset($object->info['stylesheets'])) { $object->info['stylesheets'] = _system_info_add_path($object->info['stylesheets'], $path); } if (isset($object->info['scripts'])) { $object->info['scripts'] = _system_info_add_path($object->info['scripts'], $path); } $object->info['hidden'] = FALSE; // Invoke hook_system_info_alter() to give installed modules a chance to // modify the data in the .info files if necessary. $type = 'module'; drupal_alter('system_info', $object->info, $object, $type); // The install profile is required, if it's a valid module. $object->info['required'] = TRUE; // Add a default distribution name if the profile did not provide one. This // matches the default value used in install_profile_info(). if (!isset($object->info['distribution_name'])) { $object->info['distribution_name'] = 'Drupal'; } return $object; }