? system_locale_1.patch ? system_locale_2.patch ? modules/watchdog ? modules/aggregator/po ? modules/block/po ? modules/blog/po ? modules/blogapi/po ? modules/book/po ? modules/comment/po ? modules/contact/po ? modules/drupal/po ? modules/filter/po ? modules/forum/po ? modules/locale/po ? modules/menu/po ? modules/node/po ? modules/path/po ? modules/poll/po ? modules/profile/po ? modules/search/po ? modules/statistics/po ? modules/system/po ? modules/taxonomy/po ? modules/throttle/po ? modules/tracker/po ? modules/upload/po ? modules/user/po ? profiles/default/po ? sites/default/settings.php Index: INSTALL.txt =================================================================== RCS file: /cvs/drupal/drupal/INSTALL.txt,v retrieving revision 1.39 diff -u -p -r1.39 INSTALL.txt --- INSTALL.txt 8 Jan 2007 11:59:16 -0000 1.39 +++ INSTALL.txt 16 May 2007 14:31:42 -0000 @@ -3,7 +3,6 @@ CONTENTS OF THIS FILE --------------------- - * Changes * Requirements * Optional requirements * Installation @@ -12,17 +11,10 @@ CONTENTS OF THIS FILE * Multisite Configuration * More Information -CHANGES -------- - -As of Drupal 5.0 installation has been automated by an install script. It is no -longer necessary to manually edit the "settings.php" file, and database tables -are created automatically. - REQUIREMENTS ------------ -Drupal requires a web server, PHP4 (4.3.3 or greater) or PHP5 +Drupal requires a web server, PHP 4 (4.3.3 or greater) or PHP 5 (http://www.php.net/) and either MySQL (http://www.mysql.com/) or PostgreSQL (http://www.postgresql.org/). The Apache web server and MySQL database are recommended; other web server and database combinations such as IIS and @@ -34,14 +26,13 @@ For more detailed information about Drup Guidelines for setting up a server environment with a variety of operating systems and in special cases are available in the Drupal handbook -(http://drupal.org/node/260) +(http://drupal.org/node/260). OPTIONAL REQUIREMENTS --------------------- -- To use XML-based services such as the Blogger API, Jabber, and RSS -syndication, you will need PHP's XML extension. This extension is enabled by -default. +- To use XML-based services such as the Blogger API and RSS syndication, +you will need PHP's XML extension. This extension is enabled by default. - If you want support for clean URLs, you'll need mod_rewrite and the ability to use local .htaccess files. @@ -49,7 +40,7 @@ to use local .htaccess files. INSTALLATION ------------ -1. DOWNLOAD DRUPAL +1. DOWNLOAD DRUPAL AND OPTIONALLY A TRANSLATION You can obtain the latest Drupal release from http://drupal.org/. The files are in .tar.gz format and can be extracted using most compression tools. On a @@ -63,8 +54,25 @@ INSTALLATION your web server's document root or your public HTML directory: mv drupal-x.x/* drupal-x.x/.htaccess /var/www/html + + If you would like to have the default English interface translated to a + different language, we have good news. You can install and use Drupal in + other languages from the start. Check whether a released package of the + language desired is available for this Drupal version at + http://drupal.org/project/Translations and download the package. Extract + the contents to the same directory where you extracted Drupal into. + +2. GIVE PERMISSION TO DRUPAL TO BE ABLE TO CREATE THE CONFIGURATION FILE + + Drupal comes with a default.settings.php file in the sites/default + directory. The installer will create a copy of this file filled with + the details you provide through the install process, in the same + directory. For Drupal to be able to create the file, you need to + give the web server write privileges to the sites/default directory: + + chmod o+w default -2. CREATE THE DRUPAL DATABASE +3. CREATE THE DRUPAL DATABASE Drupal requires access to a database in order to be installed. Your database user will need sufficient privileges to run Drupal. Additional information @@ -78,29 +86,28 @@ INSTALLATION Take note of the username, password, database name and hostname as you create the database. You will enter these items in the install script. -3. RUN THE INSTALL SCRIPT - - The install script will set the base URL, connect Drupal to the database, and - create tables in the database. +4. RUN THE INSTALL SCRIPT To run the install script point your browser to the base url of your website - (i.e. http://www.example.com). You will be presented with the "Database - Configuration" page. - - The install script will attempt to write-protect the settings.php after - updating it with the information you provide in the installation routine. - If you make manual changes to that file later, be sure to protect it again - after making your modifications. Failure to remove write permissions to - that file is a security risk. The default location for the settings.php - file is at sites/default/settings.php, but it may be in another location + (i.e. http://www.example.com). + + You will be guided through several screens to set up the database, + create tables, add the first user account and provide basic web + site settings. + + The install script will attempt to write-protect the sites/default + directory after creating the settings.php file. If you make manual + changes to that file later, be sure to protect it again after making + your modifications. Failure to remove write permissions to that file + is a security risk. Although the default location for the settings.php + file is at sites/default/settings.php, it may be in another location if you use the multi-site setup, as explained below. -4. CONFIGURE DRUPAL +5. CONFIGURE DRUPAL - When the install script succeeds, you will be directed to the "Welcome" page. - In "step one" click "create the first account" which will become the main - administrator account with total control. Login as the administrator and - complete the initial configuration steps on the "Welcome" page. + When the install script succeeds, you will be directed to the "Welcome" + page, and you will be logged in as the administrator already. Proceed with + the initial configuration steps suggested on the "Welcome" page. Consider creating a "files" subdirectory in your Drupal installation directory. This subdirectory stores files such as custom logos, user avatars, @@ -109,7 +116,7 @@ INSTALLATION the name of this subdirectory at "administer > site configuration > file system". -5. CRON TASKS +6. CRON TASKS Many Drupal modules (such as the search functionality) have periodic tasks that must be triggered by a cron job. To activate these tasks, call the cron @@ -135,9 +142,9 @@ few active modules and minimal user acce Use your administration panel to enable and configure services. For example: General Settings administer > site configuration > site information -Enable Modules administer > site configuration > modules -Set User Permissions administer > users management > access control +Enable Modules administer > site building > modules Configure Themes administer > site building > themes +Set User Permissions administer > users management > access control For more information on configuration options, read the instructions which accompany the different configuration settings and consult the various help @@ -153,7 +160,7 @@ your site. Several sample themes are inc drupal.org. Simple customization of your theme can be done using only CSS. Further changes -require understanding the phptemplate engine that is now part of Drupal. See +require understanding the phptemplate engine that is part of Drupal. See http://drupal.org/handbook/customization to find out more. MULTISITE CONFIGURATION Index: includes/install.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/install.inc,v retrieving revision 1.39 diff -u -p -r1.39 install.inc --- includes/install.inc 15 May 2007 15:29:47 -0000 1.39 +++ includes/install.inc 16 May 2007 14:31:43 -0000 @@ -273,7 +273,7 @@ function drupal_verify_profile($profile, // Get a list of modules required by this profile. $function = $profile .'_profile_modules'; - $module_list = array_merge(drupal_required_modules(), $function(), ($locale ? array('locale') : array())); + $module_list = array_merge(drupal_required_modules(), $function(), ($locale != 'en' ? array('locale') : array())); // Get a list of modules that exist in Drupal's assorted subdirectories. $present_modules = array(); Index: includes/locale.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/locale.inc,v retrieving revision 1.125 diff -u -p -r1.125 locale.inc --- includes/locale.inc 16 May 2007 13:45:15 -0000 1.125 +++ includes/locale.inc 16 May 2007 14:31:44 -0000 @@ -2098,7 +2098,7 @@ function _locale_get_predefined_list() { */ /** - * Prepare a batch to use to import translations. + * Prepare a batch to use to import translations on install time. * * @param $langcode * Language code to import translations for. @@ -2118,68 +2118,72 @@ function locale_batch_installer($langcod $files = array_merge($files, file_scan_directory(dirname($component->filename) .'/po/', '(^|\.)'. $langcode .'\.po$', array('.', '..', 'CVS'), 0, FALSE)); } - if (count($files)) { - $$operations = array(); - foreach($files as $file) { - // We call _locale_batch_import for every batch operation - // with the file name and language code. - $operations[] = array('_locale_batch_import', array($file->filename, $langcode)); - } - return _locale_batch_build($operations, '_locale_batch_installer_finished'); - } - - // Found nothing to import. - return FALSE; + return _locale_batch_build($files, '_locale_batch_installer_finished'); } /** * Build a locale batch from an array of files. * - * @param $operations - * Array of operations to perform + * @param $files + * Array of files to import * @param $finished * A finished callback to use for the batch * @return * A batch structure */ -function _locale_batch_build($operations, $finished) { +function _locale_batch_build($files, $finished = NULL) { $t = get_t(); - if (count($operations)) { - $batch = array( - 'operations' => $operations, - 'title' => $t('Importing interface translations'), - 'init_message' => $t('Starting import'), - 'error_message' => $t('Error importing interface translations'), - 'finished' => $finished, - ); + if (count($files)) { + $operations = array(); + foreach($files as $file) { + // We call _locale_batch_import for every batch operation. + $operations[] = array('_locale_batch_import', array($file->filename)); } + $batch = array( + 'operations' => $operations, + 'title' => $t('Importing interface translations'), + 'init_message' => $t('Starting import'), + 'error_message' => $t('Error importing interface translations'), + ); + if (isset($finished)) { + $batch['finished'] = $finished; + } return $batch; } return FALSE; } /** - * Perform interface translation import as a batch step. - * - * @param $filepath - * Path to a file to import. - * @param $langcode - * Language to import file into. - * @param $results - * Contains a list of files imported. - */ -function _locale_batch_import($filepath, $langcode, &$context) { - $file = (object) array('filename' => basename($filepath), 'filepath' => $filepath); - _locale_import_read_po('db-store', $file, 'keep', $langcode); - $context['results'][] = $filepath; -} - -/** * Batch callback invoked when installer import processing finishes. * Advance installer task to the finished screen. */ function _locale_batch_installer_finished($success, $results) { variable_set('install_task', 'finished'); } + +/** + * Prepare a batch to run when enabling modules and themes + */ +function locale_batch_system($components) { + $files = array(); + $languages = language_list('enabled'); + unset($languages[1]['en']); + if (count($languages[1])) { + $language_list = join('|', array_keys($languages[1])); + // Collect all files to import for all $components (modules or themes). + $result = db_query("SELECT name, filename FROM {system} WHERE status = 1"); + while ($component = db_fetch_object($result)) { + if (in_array($component->name, $components)) { + // Collect all files for this component in all enabled languages, named + // as $langcode.po or with names ending with $langcode.po. This allows + // for filenames like node-module.de.po to let translators use small + // files and be able to import in smaller chunks. + $files = array_merge($files, file_scan_directory(dirname($component->filename) .'/po/', '(^|\.)('. $language_list .')\.po$', array('.', '..', 'CVS'), 0, FALSE)); + } + } + return _locale_batch_build($files); + } + return FALSE; +} /** * @} End of "locale-autoimport" */ Index: modules/locale/locale.module =================================================================== RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v retrieving revision 1.172 diff -u -p -r1.172 locale.module --- modules/locale/locale.module 15 May 2007 20:19:47 -0000 1.172 +++ modules/locale/locale.module 16 May 2007 14:31:45 -0000 @@ -424,3 +424,55 @@ function locale_language_list($field = ' } return $list; } + +/** + * Imports translations when new modules or themes are + * installed or enabled. This function will either import + * translation for the component change right away, or + * start a batch if more files need to be imported. + * + * @param $type + * Either 'module' or 'theme', depending on the type of system change. + * @param $disabled + * A list of the names of disabled components. + * @param $enabled + * A list of the names of enabled components. + * @param $new + * A list of the names of new components, if applicable. + */ +function locale_system_update($type, $disabled, $enabled, $new = array()) { + include_once 'includes/locale.inc'; + switch ($type) { + case 'module': + // Import files for newly installed modules. + $components = $new; + break; + case 'theme': + // Import files for enabled themes (we don't know whether + // these were enabled anytime before) + $components = $enabled; + break; + default: + $components = array(); + } + if ($batch = locale_batch_system($components)) { + batch_set($batch); + } +} + +/** + * Perform interface translation import as a batch step. + * + * @param $filepath + * Path to a file to import. + * @param $results + * Contains a list of files imported. + */ +function _locale_batch_import($filepath, &$context) { + include_once 'includes/locale.inc'; + if (preg_match('!(/|\.)([^\.]+)\.po$!', $filepath, $langcode)) { + $file = (object) array('filename' => basename($filepath), 'filepath' => $filepath); + _locale_import_read_po('db-store', $file, 'keep', $langcode[2]); + $context['results'][] = $filepath; + } +} Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.477 diff -u -p -r1.477 system.module --- modules/system/system.module 16 May 2007 13:45:16 -0000 1.477 +++ modules/system/system.module 16 May 2007 14:31:47 -0000 @@ -1394,6 +1394,13 @@ function theme_system_themes_form($form) function system_themes_form_submit($form_values, $form, &$form_state) { + // Store list of previously enabled themes and disable all themes + $old_theme_list = $new_theme_list = array(); + foreach (list_themes() as $theme) { + if ($theme->status) { + $old_theme_list[] = $theme->name; + } + } db_query("UPDATE {system} SET status = 0 WHERE type = 'theme'"); if ($form_values['op'] == t('Save configuration')) { @@ -1402,6 +1409,7 @@ function system_themes_form_submit($form // Always enable the default theme, despite its status checkbox being checked: if ($choice || $form_values['theme_default'] == $key) { system_initialize_theme_blocks($key); + $new_theme_list[] = $key; db_query("UPDATE {system} SET status = 1 WHERE type = 'theme' and name = '%s'", $key); } } @@ -1416,14 +1424,24 @@ function system_themes_form_submit($form variable_set('theme_default', $form_values['theme_default']); } else { + // Revert to defaults: only Garland is enabled. variable_del('theme_default'); db_query("UPDATE {system} SET status = 1 WHERE type = 'theme' AND name = 'garland'"); + $new_theme_list = array('garland'); } list_themes(TRUE); menu_rebuild(); drupal_set_message(t('The configuration options have been saved.')); $form_state['redirect'] = 'admin/build/themes'; + + // Notify locale module about new themes being enabled, so translations can + // be imported. This might start a batch, and only return to the redirect + // path after that. + if (module_exists('locale')) { + locale_system_update('theme', array_diff($old_theme_list, $new_theme_list), array_diff($new_theme_list, $old_theme_list)); + } + return; } @@ -1578,12 +1596,17 @@ function system_modules_disable($form, $ return $form; } -function system_modules_confirm_form($modules, $dependencies) { +function system_modules_confirm_form($modules, $storage) { $form = array(); $items = array(); + list($dependencies, $status) = $storage; $form['validation_modules'] = array('#type' => 'value', '#value' => $modules); $form['status']['#tree'] = TRUE; + // Remember list of modules selected on the module listing page already. + foreach ($status as $key => $choice) { + $form['status'][$key] = array('#type' => 'value', '#value' => $choice); + } foreach ($dependencies as $name => $missing_dependencies) { $form['status'][$name] = array('#type' => 'hidden', '#value' => 1); foreach ($missing_dependencies as $k => $dependency) { @@ -1660,8 +1683,31 @@ function system_modules_submit($form_val $dependencies = NULL; } + // Update throttle settings, if present + if (isset($form_values['throttle'])) { + foreach ($form_values['throttle'] as $key => $choice) { + db_query("UPDATE {system} SET throttle = %d WHERE type = 'module' and name = '%s'", $choice ? 1 : 0, $key); + } + } + // Temporarily disable menu module while it's broken. unset($form_values['status']['menu']); + + // If there where unmet dependencies and they haven't confirmed don't process + // the submission yet. Store the form submission data needed later. + if ($dependencies) { + if (!isset($form_values['confirm'])) { + $form_state['storage'] = array($dependencies, $form_values['status']); + return; + } + else { + $form_values['status'] = array_merge($form_values['status'], $form_storage[1]); + } + } + // If we have no dependencies, or the dependencies are confirmed + // to be installed, we don't need the temporary storage anymore. + unset($form_state['storage']); + $enable_modules = array(); $disable_modules = array(); foreach ($form_values['status'] as $key => $choice) { @@ -1696,13 +1742,6 @@ function system_modules_submit($form_val drupal_install_modules($new_modules); $current_module_list = module_list(TRUE, FALSE); - - if (isset($form_values['throttle'])) { - foreach ($form_values['throttle'] as $key => $choice) { - db_query("UPDATE {system} SET throttle = %d WHERE type = 'module' and name = '%s'", $choice ? 1 : 0, $key); - } - } - if ($old_module_list != $current_module_list) { drupal_rebuild_theme_registry(); node_types_rebuild(); @@ -1710,17 +1749,18 @@ function system_modules_submit($form_val drupal_set_message(t('The configuration options have been saved.')); } - // If there where unmet dependencies and they haven't confirmed don't redirect. - if ($dependencies && !isset($form_values['confirm'])) { - $form_state['storage'] = $dependencies; - return; - } - drupal_clear_css_cache(); - // Unset storage to indicate this form cycle is over. - unset($form_state['storage']); $form_state['redirect'] = 'admin/build/modules'; + + // Notify locale module about module changes, so translations can be + // imported. This might start a batch, and only return to the redirect + // path after that. + if (module_exists('locale')) { + $old_module_names = array_keys($old_module_list); + locale_system_update('module', array_diff($old_module_names, $enable_modules), array_diff($enable_modules, $old_module_names), $new_modules); + } + return; }