Skip to content

Instantly share code, notes, and snippets.

@amcgowanca
Created August 9, 2013 06:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amcgowanca/6191652 to your computer and use it in GitHub Desktop.
Save amcgowanca/6191652 to your computer and use it in GitHub Desktop.
Allows for a single base installation profile to exist in Drupal 7.
diff --git a/includes/common.inc b/includes/common.inc
index 262e1c5..5523ada 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -232,6 +232,29 @@ function drupal_get_profile() {
return $profile;
}
+/**
+ * Gets the name of the currently active installation profile's base profile.
+ *
+ * When this function is called during the Drupal's initial installation process,
+ * the name of the base profile that's about to be installed is stored in the global
+ * installation state. At all other times, the standard Drupal systems variable table
+ * contains the name of the current profile's base profile, and we can call
+ * variable_get() to determine what it is.
+ *
+ * @return $base_profile
+ * The name of the installation profile's base installation profile.
+ */
+function drupal_get_base_profile() {
+ global $install_state;
+ if (isset($install_state['parameters']['base_profile'])) {
+ $base_profile = $install_state['parameters']['base_profile'];
+ }
+ else {
+ $base_profile = variable_get('install_base_profile', NULL);
+ }
+
+ return $base_profile;
+}
/**
* Sets the breadcrumb trail for the current page.
@@ -5349,6 +5372,7 @@ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1)
// there in favor of sites/all or sites/<domain> directories.
$profiles = array();
$profile = drupal_get_profile();
+
// For SimpleTest to be able to test modules packaged together with a
// distribution we need to include the profile of the parent site (in which
// test runs are triggered).
@@ -5361,6 +5385,14 @@ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1)
// In case both profile directories contain the same extension, the actual
// profile always has precedence.
$profiles[] = $profile;
+
+ // In the event that the profile is inheriting a base profile, ensure that
+ // the base profile is added to the searchable directories.
+ $base_profile = drupal_get_base_profile();
+ if (!empty($base_profile)) {
+ $profiles[] = $base_profile;
+ }
+
foreach ($profiles as $profile) {
if (file_exists("profiles/$profile/$directory")) {
$searchdir[] = "profiles/$profile/$directory";
diff --git a/includes/install.core.inc b/includes/install.core.inc
index 7a694e9..dcdf1cf 100644
--- a/includes/install.core.inc
+++ b/includes/install.core.inc
@@ -162,6 +162,10 @@ function install_state_defaults() {
// An array of information about the chosen installation profile. This will
// be filled in based on the profile's .info file.
'profile_info' => array(),
+ // An array of information about the chosen installation profile's base.
+ // This will be filled in based on the profile's `base` property value
+ // if the base profile exists and its .info file.
+ 'base_profile_info' => array(),
// An array of available installation profiles.
'profiles' => array(),
// An array of server variables that will be substituted into the global
@@ -565,6 +569,21 @@ function install_tasks($install_state) {
),
);
+ // Now add any tasks defined by the base installation profile, if one exists.
+ if (!empty($install_state['parameters']['base_profile'])) {
+ $base_profile_install_file = DRUPAL_ROOT . '/profiles/' . $install_state['parameters']['base_profile'] . '/' . $install_state['parameters']['profile'] . '.install';
+ if (file_exists($base_profile_install_file)) {
+ include_once $base_profile_install_file;
+ }
+ $function = $install_state['parameters']['base_profile'] . '_install_tasks';
+ if (function_exists($function)) {
+ $result = $function($install_state);
+ if (is_array($result)) {
+ $tasks += $result;
+ }
+ }
+ }
+
// Now add any tasks defined by the installation profile.
if (!empty($install_state['parameters']['profile'])) {
// Load the profile install file, because it is not always loaded when
@@ -595,6 +614,18 @@ function install_tasks($install_state) {
),
);
+ // All the base installation profile to modify the full list of tasks.
+ if (!empty($install_state['parameters']['base_profile'])) {
+ $base_profile_file = DRUPAL_ROOT . '/profiles/' . $install_state['parameters']['base_profile'] . '/' . $install_state['parameters']['base_profile'] . '.profile';
+ if (file_exists($base_profile_file)) {
+ include_once $base_profile_file;
+ $function = $install_state['parameters']['base_profile'] . '_install_tasks_alter';
+ if (function_exists($function)) {
+ $function($tasks, $install_state);
+ }
+ }
+ }
+
// Allow the installation profile to modify the full list of tasks.
if (!empty($install_state['parameters']['profile'])) {
$profile_file = DRUPAL_ROOT . '/profiles/' . $install_state['parameters']['profile'] . '/' . $install_state['parameters']['profile'] . '.profile';
@@ -770,9 +801,21 @@ function install_system_module(&$install_state) {
// upcoming bootstrap step.
module_enable(array('user'), FALSE);
+ $base_profile = drupal_get_base_profile();
+ if (isset($base_profile)) {
+ $modules = $install_state['base_profile_info']['dependencies'];
+ }
+ else {
+ $modules = array();
+ }
+
// Save the list of other modules to install for the upcoming tasks.
// variable_set() can be used now that system.module is installed.
- $modules = $install_state['profile_info']['dependencies'];
+ $modules = array_merge($modules, $install_state['profile_info']['dependencies']);
+
+ if (isset($base_profile)) {
+ $modules[] = $base_profile;
+ }
// The installation profile is also a module, which needs to be installed
// after all the dependencies have been installed.
@@ -1321,6 +1364,14 @@ function install_no_profile_error() {
}
/**
+ * Indicates that there are no base profile available.
+ */
+function install_no_base_profile_error() {
+ drupal_set_title(st('Base profile not available'));
+ return st('Cannot load base profile.');
+}
+
+/**
* Indicates that Drupal has already been installed.
*/
function install_already_done_error() {
@@ -1343,6 +1394,17 @@ function install_load_profile(&$install_state) {
if (file_exists($profile_file)) {
include_once $profile_file;
$install_state['profile_info'] = install_profile_info($install_state['parameters']['profile'], $install_state['parameters']['locale']);
+ if (isset($install_state['profile_info']['base'])) {
+ $base_profile_file = DRUPAL_ROOT . '/profiles/' . $install_state['profile_info']['base'] . '/' . $install_state['profile_info']['base'] . '.profile';
+ if (file_exists($base_profile_file)) {
+ include_once $base_profile_file;
+ $install_state['parameters']['base_profile'] = $install_state['profile_info']['base'];
+ $install_state['base_profile_info'] = install_profile_info($install_state['parameters']['base_profile']);
+ }
+ else {
+ throw new Exception(st('Sorry, the base profile specified cannot be loaded.'));
+ }
+ }
}
else {
throw new Exception(st('Sorry, the profile you have chosen cannot be loaded.'));
@@ -1381,6 +1443,11 @@ function install_profile_modules(&$install_state) {
// every dependency, including non-required ones. So clear its required
// flag for now to allow it to install late.
$files[$install_state['parameters']['profile']]->info['required'] = FALSE;
+
+ if (isset($install_state['parameters']['base_profile'])) {
+ $files[$install_state['parameters']['base_profile']]->info['required'] = FALSE;
+ }
+
// Add modules that other modules depend on.
foreach ($modules as $module) {
if ($files[$module]->requires) {
@@ -1539,6 +1606,9 @@ function install_finished(&$install_state) {
// registered by the installation profile are registered correctly.
drupal_flush_all_caches();
+ // If a base profile exists, remember which was used.
+ variable_set('install_base_profile', drupal_get_base_profile());
+
// Remember the profile which was used.
variable_set('install_profile', drupal_get_profile());
@@ -1591,6 +1661,11 @@ function install_check_requirements($install_state) {
// Check the profile requirements.
$requirements = drupal_check_profile($profile);
+ // If a base profile exists, check the base profile's requirements.
+ if (isset($install_state['parameters']['base_profile'])) {
+ $requirements += drupal_check_profile($install_state['parameters']['base_profile']);
+ }
+
// If Drupal is not set up already, we need to create a settings file.
if (!$install_state['settings_verified']) {
$writable = FALSE;
diff --git a/includes/install.inc b/includes/install.inc
index 3631c36..99af96d 100644
--- a/includes/install.inc
+++ b/includes/install.inc
@@ -680,7 +680,18 @@ function drupal_verify_profile($install_state) {
if (!isset($profile) || !file_exists($profile_file)) {
throw new Exception(install_no_profile_error());
}
- $info = $install_state['profile_info'];
+ $dependencies = $install_state['profile_info']['dependencies'];
+
+ if (isset($install_state['parameters']['base_profile'])) {
+ $base_profile = $install_state['parameters']['base_profile'];
+ $base_profile_file = DRUPAL_ROOT . "/profiles/$base_profile/$base_profile.profile";
+ if (!file_exists($base_profile_file)) {
+ throw new Exception(install_no_base_profile_error());
+ }
+
+ $dependencies = array_merge($dependencies, $install_state['base_profile_info']['dependencies'], array($base_profile));
+ $dependencies = array_unique($dependencies);
+ }
// Get a list of modules that exist in Drupal's assorted subdirectories.
$present_modules = array();
@@ -688,12 +699,18 @@ function drupal_verify_profile($install_state) {
$present_modules[] = $present_module->name;
}
+ // If a base profile exists, like other installation profiles it is also a
+ // module, which needs to be installed after other dependencies have.
+ if (isset($base_profile)) {
+ $present_modules[] = $base_profile;
+ }
+
// The installation profile is also a module, which needs to be installed
// after all the other dependencies have been installed.
$present_modules[] = drupal_get_profile();
// Verify that all of the profile's required modules are present.
- $missing_modules = array_diff($info['dependencies'], $present_modules);
+ $missing_modules = array_diff($dependencies, $present_modules);
$requirements = array();
diff --git a/modules/system/system.module b/modules/system/system.module
index 2bbcd7f..d29783a 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -2369,6 +2369,18 @@ function _system_rebuild_module_data() {
$modules[$profile]->uri = 'profiles/' . $profile . '/' . $profile . '.profile';
$modules[$profile]->filename = $profile . '.profile';
+ $base_profile = drupal_get_base_profile();
+ if (!empty($base_profile)) {
+ $modules[$base_profile] = new stdClass();
+ $modules[$base_profile]->name = $base_profile;
+ $modules[$base_profile]->uri = 'profiles/' . $base_profile . '/' . $base_profile . '.profile';
+ $modules[$base_profile]->filename = $base_profile . '.profile';
+
+ // Base installation profile hooks are always executed immediately prior
+ // to those of the $profile.
+ $modules[$base_profile]->weight = 999;
+ }
+
// Installation profile hooks are always executed last.
$modules[$profile]->weight = 1000;
@@ -2422,6 +2434,16 @@ function _system_rebuild_module_data() {
drupal_alter('system_info', $modules[$key]->info, $modules[$key], $type);
}
+ if (isset($base_profile) && isset($modules[$base_profile])) {
+ // The base installation profile is required. if it's a valid module.
+ $modules[$base_profile]->info['required'] = TRUE;
+ // Add a default distribution name if the base profile did not provide one. This
+ // matches the default value used in the install_profile_info().
+ if (!isset($modules[$base_profile]->info['distribution_name'])) {
+ $modules[$base_profile]->info['distribution_name'] = 'Drupal';
+ }
+ }
+
if (isset($modules[$profile])) {
// The installation profile is required, if it's a valid module.
$modules[$profile]->info['required'] = TRUE;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment