Index: includes/bootstrap.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v retrieving revision 1.15 diff -u -r1.15 bootstrap.inc --- includes/bootstrap.inc 2 Jul 2004 18:46:40 -0000 1.15 +++ includes/bootstrap.inc 8 Jul 2004 14:33:44 -0000 @@ -4,25 +4,42 @@ function conf_init() { /* - ** Try finding a matching configuration file by stripping the website's - ** URI from left to right. If no configuration file is found, return a - ** default value 'conf'. + ** Try finding a matching configuration directory by stripping the + ** website's hostname from left to right and pathname from right to + ** left. If no configuration file is found, return a default value + ** '$confdir/default'. Example for a ficticious site installed at + ** http://www.drupal.org/test: + ** + ** 1. www.drupal.org.test + ** 2. drupal.org.test + ** 3. www.drupal.org + ** 4. drupal.org + ** 5. default */ - $uri = $_SERVER['PHP_SELF']; + static $conf = ''; - $file = strtolower(strtr($_SERVER['HTTP_HOST'] . substr($uri, 0, strrpos($uri, '/')), '/:', '..')); + if ($conf) { + return $conf; + } - while (strlen($file) > 4) { - if (file_exists("includes/$file.php")) { - return $file; - } - else { - $file = substr($file, strpos($file, '.') + 1); + $uri = explode('/', $_SERVER['PHP_SELF']); + $server = explode('.', $_SERVER['HTTP_HOST']); + $confdir = 'conf'; + + for ($i = count($uri) - 1; $i > 0; $i--) { + for ($j = count($server); $j > 1; $j--) { + $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i)); + + if (file_exists("$confdir/$dir/config.php")) { + $conf = "$confdir/$dir"; + return $conf; + } } } - return 'conf'; + $conf = "$confdir/default"; + return $conf; } function variable_init($conf = array()) { @@ -284,7 +301,7 @@ unset($conf); $config = conf_init(); -include_once "includes/$config.php"; +include_once "$config/config.php"; include_once 'includes/database.inc'; include_once 'includes/session.inc'; include_once 'includes/module.inc'; Index: includes/file.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/file.inc,v retrieving revision 1.15 diff -u -r1.15 file.inc --- includes/file.inc 21 Jun 2004 20:05:37 -0000 1.15 +++ includes/file.inc 8 Jul 2004 14:33:44 -0000 @@ -365,23 +365,40 @@ } /** - * Finds all files that match a given mask in a given directory. Searches - * recursively. + * Finds all files that match a given mask in a given + * directory. Searches recursively. + * + * @param $dir The base directory for the scan. + * @param $mask The regular expression of the files to find. + * @param $nomask An array of files/directories to ignore. + * @param $callback The callback function to call for each match. + * @param $key The key to be used for the returned array of files. + * Possible values are "filename", for the path starting with + * $dir, "basename", for the basename of the file, and "name" + * for the name of the file without an extension. + * + * @return An associative array (keyed on the provided key) of objects + * with "filename", "basename", and "name" members + * corresponding to the matching files. */ -function file_scan_directory($dir, $mask, $nomask = array('.', '..', 'CVS'), $callback = 0) { +function file_scan_directory($dir, $mask, $nomask = array('.', '..', 'CVS'), $callback = 0, $key = "filename") { $files = array(); + $key = (strstr("|filename|basename|name|", "|$key|") ? $key : "filename"); if (is_dir($dir) && $handle = opendir($dir)) { while ($file = readdir($handle)) { if (!in_array($file, $nomask)) { if (is_dir("$dir/$file")) { - $files = array_merge($files, file_scan_directory("$dir/$file", $mask, $nomask, $callback)); + $files = array_merge($files, file_scan_directory("$dir/$file", $mask, $nomask, $callback, $key)); } elseif (ereg($mask, $file)) { - $name = basename($file); - $files["$dir/$file"]->filename = "$dir/$file"; - $files["$dir/$file"]->name = substr($name, 0, strrpos($name, '.')); + $filename = "$dir/$file"; + $basename = basename($file); + $name = substr($basename, 0, strrpos($basename, '.')); + $files[$$key]->filename = $filename; + $files[$$key]->basename = $basename; + $files[$$key]->name = $name; if ($callback) { - $callback("$dir/$file"); + $callback($filename); } } } Index: modules/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system.module,v retrieving revision 1.147 diff -u -r1.147 system.module --- modules/system.module 8 Jul 2004 07:56:16 -0000 1.147 +++ modules/system.module 8 Jul 2004 14:33:44 -0000 @@ -203,28 +203,46 @@ } function system_listing($type) { + $config = conf_init(); + // Pick appropriate directory and filetype switch ($type) { case 'modules': - $directory = 'modules'; + $directory[] = 'modules'; + + if (file_exists("$config/modules")) { + $directory[] = "$config/modules"; + } + $type = 'module'; break; case 'themes': default: - $directory = 'themes'; + $directory[] = 'themes'; + + if (file_exists("$config/themes")) { + $directory[] = "$config/themes"; + } + $type = 'theme'; break; } - // Find files in the directory. - $files = file_scan_directory($directory, "\.$type$"); + // Find files in the directories. + $files = array(); + + foreach ($directory as $dir) { + $files = array_merge($files, file_scan_directory($dir, "\.$type$", array('.', '..', 'CVS'), 0, "basename")); + } // Extract current files from database. $result = db_query("SELECT filename, type, status, throttle FROM {system} WHERE type = '%s'", $type); while ($file = db_fetch_object($result)) { - if (is_object($files[$file->filename])) { + $basename = basename($file->filename); + unset($file->filename); + if (is_object($files[$basename])) { foreach ($file as $key => $value) { - $files[$file->filename]->$key = $value; + $files[$basename]->$key = $value; } } } @@ -232,9 +250,9 @@ ksort($files); if ($type == 'module') { - $required = array('modules/admin.module', 'modules/filter.module', 'modules/system.module', 'modules/user.module', 'modules/watchdog.module'); + $required = array('admin.module', 'filter.module', 'system.module', 'user.module', 'watchdog.module'); // the throttle mechanism requires additional modules always be enabled - $throttle_required = array_merge($required, array('modules/statistics.module', 'modules/throttle.module')); + $throttle_required = array_merge($required, array('statistics.module', 'throttle.module')); $header = array(t('name'), t('description'), t('status'), t('throttle')); } @@ -243,10 +261,10 @@ $header = array(t('name'), t('description'), t('enable'), t('default')); } - foreach ($files as $filename => $file) { - include_once($filename); + foreach ($files as $basename => $file) { if ($type == 'module') { - $info->name = module_invoke($file->name, 'help', 'admin/modules#name') ? module_invoke($file->name, 'help', 'admin/modules#name') : module_invoke($file->name, 'system', 'name') ? module_invoke($file->name, 'system', 'name') : $file->name; + include_once($file->filename); + $info->description = module_invoke($file->name, 'help', 'admin/modules#description') ? module_invoke($file->name, 'help', 'admin/modules#description') : module_invoke($file->name, 'system', 'description'); // log the critical hooks implemented by this module $bootstrap = 0; @@ -258,26 +276,28 @@ } } elseif ($type == 'theme') { - $info->name = $file->name; - $info->description = module_invoke($file->name, 'help', 'admin/themes#description'); - $themes[] = $info->name; - - // Enable the default theme: - if ($info->name == variable_get('theme_default', 0)) { + if ($file->name == variable_get('theme_default', 0)) { + // enable the default theme $file->status = 1; } + else { + include_once($file->filename); + } + + $info->description = module_invoke($file->name, 'help', 'admin/themes#description'); + $themes[] = $file->name; } // Update the contents of the system table: - db_query("DELETE FROM {system} WHERE filename = '%s' AND type = '%s'", $filename, $type); - db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $info->name, $info->description, $type, $filename, $file->status, $file->throttle, $bootstrap); + db_query("DELETE FROM {system} WHERE name = '%s' AND type = '%s'", $file->name, $type); + db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $file->name, $info->description, $type, $file->filename, $file->status, $file->throttle, $bootstrap); - $row = array($info->name, $info->description, array('data' => (in_array($filename, $required) ? form_hidden("status][$filename", 1) . t('required') : form_checkbox('', "status][$filename", 1, $file->status)), 'align' => 'center')); + $row = array($file->name, $info->description, array('data' => (in_array($basename, $required) ? form_hidden("status][$file->filename", 1) . t('required') : form_checkbox('', "status][$file->filename", 1, $file->status)), 'align' => 'center')); if ($type == 'module') { - $row[] = array('data' => (in_array($filename, $throttle_required) ? form_hidden("throttle][$filename", 0) . t('required') : form_checkbox(NULL, "throttle][$filename", 1, $file->throttle, NULL, module_exist('throttle') ? NULL : array('disabled' => 'disabled'))), 'align' => 'center'); + $row[] = array('data' => (in_array($basename, $throttle_required) ? form_hidden("throttle][$file->filename", 0) . t('required') : form_checkbox(NULL, "throttle][$file->filename", 1, $file->throttle, NULL, module_exist('throttle') ? NULL : array('disabled' => 'disabled'))), 'align' => 'center'); } else if ($type == 'theme') { - $row[] = array('data' => form_radio('', 'theme_default', $info->name, (variable_get('theme_default', 0) == $info->name) ? 1 : 0), 'align' => 'center'); + $row[] = array('data' => form_radio('', 'theme_default', $file->name, (variable_get('theme_default', 0) == $file->name) ? 1 : 0), 'align' => 'center'); } $rows[] = $row; } @@ -395,4 +415,26 @@ print theme('page', system_settings_form($form)); } +/** + * Returns the path to a system item (module/theme). + * + * @param $name The name of the item for which the path is requested. + * @param $type The type of the item (theme/module). + * + * @return The path to the requested item. + */ +function system_path($name, $type) { + static $paths = array(); + + if (!$paths[$type]) { + $paths[$type] = array(); + } + + if (!$paths[$type][$name]) { + $paths[$type][$name] = dirname(db_result(db_query("SELECT filename FROM {system} WHERE name = '%s' AND type = '%s'", $name, $type))); + } + + return $paths[$type][$name]; +} + ?> Index: themes/xtemplate/xtemplate.theme =================================================================== RCS file: /cvs/drupal/drupal/themes/xtemplate/xtemplate.theme,v retrieving revision 1.63 diff -u -r1.63 xtemplate.theme --- themes/xtemplate/xtemplate.theme 7 Jul 2004 21:15:11 -0000 1.63 +++ themes/xtemplate/xtemplate.theme 8 Jul 2004 14:33:45 -0000 @@ -1,21 +1,25 @@ template = new XTemplate('xtemplate.xtmpl', 'themes/xtemplate/' . $template_directory); -$GLOBALS["xtemplate"]->template->SetNullBlock(" "); // "" doesnt work! +$GLOBALS['xtemplate']->template = new XTemplate('xtemplate.xtmpl', "{$GLOBALS[xtemplate_path]}/$template_directory"); +$GLOBALS['xtemplate']->template->SetNullBlock(' '); // '' doesnt work! function xtemplate_settings() { + global $xtemplate_path; + /* ** Compile a list of the available style sheets: */ - - $fd = opendir('themes/xtemplate'); + $fd = opendir($xtemplate_path); while ($file = readdir($fd)) { - if (is_dir("themes/xtemplate/$file") && !in_array($file, array('.', '..', 'CVS'))) { + if (is_dir("$xtemplate_path/$file") && !in_array($file, array('.', '..', 'CVS'))) { $files[$file] = $file; } } @@ -25,7 +29,7 @@ $group = form_select(t('Template'), 'xtemplate_template', variable_get('xtemplate_template', 'default'), $files, t('Selecting a different template will change the look and feel of your site. To create a new template, create a new directory under themes/xtemplate and copy the contents of an existing template (e.g. themes/xtemplate/default) into it. The new template will automatically become available in the selection menu and will be identified by its directory name.')); $output = form_group(t('Template selection'), $group); - $group = form_textarea(t('Logo'), 'xtemplate_logo', variable_get('xtemplate_logo', "\"Logo\""), 70, 4, t('The HTML code for displaying the logo.')); + $group = form_textarea(t('Logo'), 'xtemplate_logo', variable_get('xtemplate_logo', "\"Logo\""), 70, 4, t('The HTML code for displaying the logo.')); $group .= form_textarea(t('Primary links'), 'xtemplate_primary_links', variable_get('xtemplate_primary_links', l('edit primary links', 'admin/themes/xtemplate')), 70, 8, t('The HTML code for the primary links.')); $group .= form_textarea(t('Secondary links'), 'xtemplate_secondary_links', variable_get('xtemplate_secondary_links', l('edit secondary links', 'admin/themes/xtemplate')), 70, 8, t('The HTML code for the secondary links.')); $group .= form_textarea(t('Message on front page'), 'xtemplate_mission', variable_get('xtemplate_mission', 'edit mission'), 70, 6, t('This text will be displayed on the front page. It can be used to display a mission statement, announcement or site description.')); @@ -134,16 +138,16 @@ drupal_set_breadcrumb($breadcrumb); } - global $xtemplate; + global $xtemplate, $xtemplate_path; $template_directory = variable_get('xtemplate_template', 'default'); $xtemplate->template->assign(array( "head_title" => (drupal_get_title() ? drupal_get_title() ." | ". variable_get("site_name", "drupal") : variable_get("site_name", "drupal") ." | ". variable_get("site_slogan", "")), "site" => variable_get("site_name", "drupal"), "head" => drupal_get_html_head(), - "directory" => "themes/xtemplate/$template_directory", + "directory" => "$xtemplate_path/$template_directory", "onload_attributes" => theme_onload_attribute(), - "logo" => variable_get('xtemplate_logo', "\"Logo\""), + "logo" => variable_get('xtemplate_logo', "\"Logo\""), "primary_links" => variable_get("xtemplate_primary_links", l("edit primary links", "admin/themes/xtemplate")), "secondary_links" => variable_get("xtemplate_secondary_links", l("edit secondary links", "admin/themes/xtemplate")) ));