Index: l10n_community/export.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/export.inc,v retrieving revision 1.1.2.15.2.15 diff -u -p -r1.1.2.15.2.15 export.inc --- l10n_community/export.inc 18 Sep 2009 18:03:18 -0000 1.1.2.15.2.15 +++ l10n_community/export.inc 11 Nov 2009 18:18:02 -0000 @@ -216,6 +216,7 @@ function l10n_community_export_form_subm */ function _l10n_community_export_string_files(&$string_files, $uri, $language, $template, $version, $export_string, $compact = FALSE) { $po_folder = ($version == 'drupal-5' ? 'po' : 'translations'); + $output = ''; if (!empty($export_string)) { Index: l10n_community/l10n_community.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_community/Attic/l10n_community.module,v retrieving revision 1.1.2.23.2.59 diff -u -p -r1.1.2.23.2.59 l10n_community.module --- l10n_community/l10n_community.module 6 Nov 2009 15:38:16 -0000 1.1.2.23.2.59 +++ l10n_community/l10n_community.module 11 Nov 2009 18:18:03 -0000 @@ -304,7 +304,7 @@ function l10n_community_menu() { 'type' => MENU_LOCAL_TASK, 'weight' => 10, ); - + // Development helpers. if (module_exists('devel_generate')) { $items['admin/generate/languages'] = array( @@ -1164,7 +1164,7 @@ function l10n_community_target_save($sid } else { // No active translation yet -> INSERT. - db_query("INSERT INTO {l10n_community_translation} (sid, translation, language, uid_entered, time_entered, is_active) VALUES (%d, '%s', '%s', %d, %d, 1)", $sid, $translation, $langcode, $uid, time()); + db_query("INSERT INTO {l10n_community_translation} (sid, translation, language, uid_entered, uid_approved, time_entered, time_approved, is_active) VALUES (%d, '%s', '%s', %d, %d, %d, %d, 1)", $sid, $translation, $langcode, $uid, $uid, time(), time()); $inserted++; } } Index: l10n_packager/l10n_packager.admin.inc =================================================================== RCS file: l10n_packager/l10n_packager.admin.inc diff -N l10n_packager/l10n_packager.admin.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ l10n_packager/l10n_packager.admin.inc 11 Nov 2009 18:18:03 -0000 @@ -0,0 +1,208 @@ + t('Generate packages on every Drupal cron run'), + '#type' => 'checkbox', + '#default_value' => variable_get('l10n_packager_cron', 0), + ); + $form['l10n_packager_directory'] = array( + '#title' => t('Directory for generated packages'), + '#description' => t('The directory on the local file system to use to store packages generated. Either relative to the Drupal installation directory or an absolute path on your file system. Drupal should have read and write access to the files and directories found there.'), + '#type' => 'textfield', + '#required' => TRUE, + '#default_value' => l10n_packager_directory(), + // Create directory by default if possible. + '#after_build' => array('l10n_packager_admin_check_directory'), + ); + $form['l10n_packager_filepath'] = array( + '#title' => t('Path structure for generated packages'), + '#type' => 'textfield', + '#required' => TRUE, + '#default_value' => variable_get('l10n_packager_filepath', L10N_PACKAGER_FILEPATH), + '#description' => t("Available tokens are: %project, %release, %core, %version, %extra, %language."), + ); + $form['l10n_packager_release_limit'] = array( + '#title' => t('Number of releases to check at once'), + '#description' => t('The number of releases to check on a manual or cron run.'), + '#type' => 'select', + '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 30, 40, 50)), + '#default_value' => variable_get('l10n_packager_release_limit', 10), + ); + $form['l10n_packager_file_limit'] = array( + '#title' => t('Maximum number of files to package at once'), + '#description' => t('The number of files to package on a manual or cron run.'), + '#type' => 'select', + '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 30, 40, 50)), + '#default_value' => variable_get('l10n_packager_file_limit', 1), + ); + // Logging settings + $period = array(0 => t('Never')) + drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 9676800), 'format_interval'); + $form['l10n_packager_update'] = array( + '#title' => t('Repackaging interval'), + '#type' => 'select', + '#options' => $period, + '#default_value' => variable_get('l10n_packager_update', 0), + '#description' => t('Time interval for the translations to be automatically repackaged.'), + ); + + return system_settings_form($form); +} + +/** + * Check/create directory if not there already. + */ +function l10n_packager_admin_check_directory($form_element) { + file_check_directory($form_element['#value'], FILE_CREATE_DIRECTORY, $form_element['#parents'][0]); + return $form_element; +} + +/** + * Join two independent forms on one page. + */ +function l10n_packager_admin_repackage_page() { + $output = drupal_get_form('l10n_packager_admin_projects_form'); + $output .= drupal_get_form('l10n_packager_admin_languages_form'); + return $output; +} + +/** + * Form callback. Repackage translations manually. + */ +function l10n_packager_admin_languages_form() { + $form['languages'] = array( + '#type' => 'fieldset', + '#title' => t('List of languages'), + '#description' => t('This list is rebuilt on every change to any languages, but you can force a rebuild here.'), + ); + $form['languages']['submit'] = array( + '#type' => 'submit', + '#value' => t('Rebuild language list'), + '#submit' => array('l10n_packager_export_language_list'), + ); + return $form; +} + +/** + * Rebuild language list on form submission. + */ +function l10n_packager_admin_languages_form_submit() { + l10n_packager_export_language_list(); +} + +/** + * Form callback. Repackage translations manually. + */ +function l10n_packager_admin_projects_form() { + $form['projects'] = array( + '#type' => 'fieldset', + '#title' => t('Project translations'), + '#description' => t('Repackage all translations of a single project or release.'), + ); + $form['projects']['project'] = array( + '#title' => t('Project'), + '#type' => 'textfield', + '#autocomplete_path' => 'translate/projects/autocomplete', + '#description' => t('Type the name of a project, eg. Drupal.'), + '#required' => TRUE, + ); + $form['projects']['release'] = array( + '#title' => t('Release'), + '#type' => 'textfield', + '#description' => t('Optionally select a release name like 6.x-1.0-beta1 or a partial release name like 6.x%.'), + ); + $form['projects']['languages'] = array( + '#type' => 'select', + '#title' => t('Only for these languages'), + '#multiple' => TRUE, + '#default_value' => array(), + '#options' => l10n_community_get_languages('name'), + '#description' => t('Select none for all languages. Otherwise pick the languages you want repackaged.'), + ); + + $form['projects']['buttons']['repackage'] = array('#type' => 'submit', '#value' => t('Repackage now')); + $form['projects']['buttons']['mark'] = array('#type' => 'submit', '#value' => t('Mark for repackaging')); + return $form; +} + +/** + * Repackage form validation + */ +function l10n_packager_admin_projects_form_validate($form, &$form_state) { + if (!empty($form_state['values']['project'])) { + if ($project = l10n_community_get_projects(array('uri' => l10n_community_project_uri_by_title($form_state['values']['project'])))) { + $form_state['values']['pid'] = $project->pid; + } + else { + form_set_error('project', t('Invalid project name.')); + } + } + if (!empty($form_state['values']['release'])) { + $query = "SELECT COUNT(rid) FROM {l10n_community_release} WHERE title LIKE '%s'"; + $args = array($form_state['values']['release']); + if ($project) { + $query .= " AND pid = %d"; + $args[] = $project->pid; + } + if (!db_result(db_query($query, $args))) { + form_set_error('release', t('Invalid release name.')); + } + } + if (empty($form_state['values']['project']) && empty($form_state['values']['release'])) { + form_set_error('project', t('You must select a project and optionally a release.')); + } +} + +/** + * Repackage form submission + */ +function l10n_packager_admin_projects_form_submit($form, $form_state) { + module_load_include('inc', 'l10n_packager'); + + $op = $form_state['values']['op']; + $languages = array_filter($form_state['values']['languages']); + $pid = !empty($form_state['values']['pid']) ? $form_state['values']['pid'] : NULL; + $release = !empty($form_state['values']['release']) ? $form_state['values']['release'] : NULL; + + // Prepare search parameters + $where = $args = array(); + if ($pid) { + $where[] = "pid = %d"; + $args[] = $pid; + } + if ($release) { + $where[] = "title = '%s'"; + $args[] = $release; + } + // Build the query that will be used in different ways depending on the operation + $query = 'SELECT rid FROM {l10n_community_release} WHERE '. implode(' AND ', $where); + + // Now check results and run operations + if ($op == t('Repackage now')) { + $result = db_query($query, $args); + while ($release = db_fetch_object($result)) { + $rids[] = $release->rid; + } + if (!empty($rids)) { + $batch = l10n_packager_release_batch($rids, $languages); + batch_set($batch); + } + else { + drupal_set_message(t('No releases found for repackaging.'), 'error'); + } + } + elseif ($op == t('Mark for repackaging')) { + $args = array_merge(array(L10N_PACKAGER_ACTIVE), $args); + db_query("UPDATE {l10n_packager_release} SET updated = 0, checked = 0, status = %d WHERE rid IN ($query)", $args); + drupal_set_message(t("Marked %count releases for repackaging.", array('%count' => db_affected_rows()))); + } +} Index: l10n_packager/l10n_packager.inc =================================================================== RCS file: l10n_packager/l10n_packager.inc diff -N l10n_packager/l10n_packager.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ l10n_packager/l10n_packager.inc 11 Nov 2009 18:18:03 -0000 @@ -0,0 +1,270 @@ +language => $language) : l10n_community_get_languages(); + $updated = array(); + // We get update time before creating files so the release checked time + // is <= file timestamp. + $timestamp = time(); + + $files = l10n_packager_release_get_files($release->rid); + $last_updated = l10n_packager_translation_last_updated($release->rid); + + // Get only the languages we have translations for, that need updating + $languages = array(); + foreach($check_languages as $langcode => $language) { + if (!empty($last_updated[$langcode]) && ($force || empty($files[$langcode]) || ($last_updated[$langcode] > $files[$langcode]->checked))) { + $languages[$langcode] = $language; + } + } + + // For this special case we check we didn't stop before in the middle of a + // release. Otherwise it could stick on a release forever when forcing. + if ($force && $cron && $release->checked < $release->updated) { + foreach($files as $lang => $file) { + if (!empty($file->checked) && ($file->checked > $release->checked)) { + unset($languages[$lang]); + } + } + } + + // Repackage this relase for the remaining language list. + while ((!$limit || $limit > count($updated)) && ($language = array_shift($languages))) { + $langcode = $language->language; + // Warning: this may upload release data with or without file. + $existing = !empty($files[$langcode]) ? $files[$langcode] : NULL; + $updated[$langcode] = l10n_packager_release_package($release, $language, $existing, $timestamp); + } + + // Update the release data. + if (!count($languages)) { + // We only mark the release checked if there are no languages left. + $release->checked = $timestamp; + } + if ($updated) { + $release->updated = $timestamp; + } + + if (isset($release->status)) { + // Just update status of existing record. + drupal_write_record('l10n_packager_release', $release, 'rid'); + } + else { + // The first time we checked this release, we need to add a new record. + $release->status = L10N_PACKAGER_ACTIVE; + drupal_write_record('l10n_packager_release', $release); + } + return $updated; +} + +/** + * Generate a new file for a given release or update an existing one. + * + * @param $release + * Release object with uri and rid properties. + * @param $language + * Language object. + * @param $file + * Release file object to be updated. + * @param $timestamp + * Timestamp to mark the files, for it to be consistent across tables. + * + * @return + * Drupal file object or FALSE on error. + */ +function l10n_packager_release_package($release, $language, $file = NULL, $timestamp = NULL) { + + $timestamp = $timestamp ? $timestamp : time(); + $variables = array( + '%release' => l10n_packager_release_name($release), + '%language' => $language->name + ); + + if (!$file) { + $file = new stdClass(); + $file->rid = $release->rid; + $file->language = $language->language; + } + + // Generate PO file. Always export all-in-one format in compact form. + $export_result = l10n_community_export($release->uri, $release->rid, $language, FALSE, 'all-in-one', TRUE); + + if (!empty($export_result) && is_array($export_result)) { + + // If we got an array back from the export build, tear that into pieces. + list($mime_type, $export_name, $serve_name) = $export_result; + + // Get the destination file path. + $file_path = l10n_packager_get_filepath($release, $language); + // Build the full path and make sure the directory exits. + $file_path = l10n_packager_create_path($file_path); + + // Now build the Drupal file object or update the old one. + if (!empty($file->fid) && !empty($file->filepath)) { + file_delete($file->filepath); + } + + // Check / upate / create all file data. + $file->status = FILE_STATUS_PERMANENT; + $file->timestamp = $file->checked = $timestamp; + $file->filename = basename($file_path); + $file->filemime = $mime_type; + $file->filepath = $file_path; + file_move($export_name, $file->filepath, FILE_EXISTS_REPLACE); + $file->filesize = filesize($file->filepath); + + // Create / update file record and link to release. + drupal_write_record('files', $file, !empty($file->fid) ? 'fid' : array()); + drupal_write_record('l10n_packager_file', $file, !empty($file->drid) ? 'drid' : array()); + $variables['%filename'] = $file->filename; + watchdog('l10n_packager', 'Packaged release %release for language %language, created file %filename.', $variables); + return $file; + + } + else { + watchdog('l10n_packager', 'Failed packaging release %release for language %language.', $variables); + return FALSE; + } +} + +// == Batch functions ========================================================== + +/** + * Create batch for repackaging releases. + * + * @param $rid + * Release id or array of release ids. + * @param $languages + * Array of language codes to repackage or none. + * + * @return + * Batch array. + */ +function l10n_packager_release_batch($rid, $languages = NULL) { + $rids = is_array($rid) ? $rid : array($rid); + + // All languages if no languages passed + $languages = !empty($languages) ? $languages : array_keys(l10n_community_get_languages()); + foreach ($rids as $rid) { + foreach ($languages as $langcode) { + $operations[] = array('_l10n_packager_batch_repackage', array($rid, $langcode)); + } + } + + if (!empty($operations)) { + return _l10n_packager_build_batch($operations, t('Repackaging translation files.')); + } +} + +/** + * Get batch stub. + */ +function _l10n_packager_build_batch($operations = array(), $title = '') { + $batch = array( + 'title' => $title ? $title : t('Translations packager.'), + 'operations' => $operations, + // Tell the batch engine which file to load before calling operations. + 'file' => drupal_get_path('module', 'l10n_packager') .'/l10n_packager.inc', + ); + return $batch; +} + +/** + * Batch callback to repackage a release. + * + * @param $rid + * Release id. + * @param $langcode + * Language object to package. + */ +function _l10n_packager_batch_repackage($rid, $langcode) { + if ($release = l10n_packager_get_release($rid)) { + $languages = l10n_community_get_languages(); + $language = $languages[$langcode]; + $updates = l10n_packager_release_check($release, TRUE, 0, $language); + if ($file = current($updates)) { + drupal_set_message(t("Repackaged release %release for %language. Created file %filename.", array('%release' => l10n_packager_release_name($release), '%filename' => $file->filename, '%language' => $language->name))); + } + } +} + +// == Utility functions ======================================================== + +/** + * Get release object with packager data and some project data. + */ +function l10n_packager_get_release($rid) { + if (is_object($rid)) { + return $rid; + } + else { + return db_fetch_object(db_query("SELECT r.rid, r.pid, r.title, pr.checked, pr.updated, pr.status, p.uri FROM {l10n_community_project} p INNER JOIN {l10n_community_release} r ON p.pid = r.pid LEFT JOIN {l10n_packager_release} pr ON r.rid = pr.rid WHERE r.rid = %d", $rid)); + } +} + +/** + * Get release name. + */ +function l10n_packager_release_name($rid) { + if ($release = l10n_packager_get_release($rid)) { + return $release->uri .'-'. $release->title; + } + else { + return ''; + } +} + +/** + * Get timestamp of the last updated string for a release, for each language. + */ +function l10n_packager_translation_last_updated($rid) { + $updated = array(); + $result = db_query("SELECT t.language, MAX(t.time_approved) AS latest_time FROM {l10n_community_translation} t INNER JOIN {l10n_community_line} l ON t.sid = l.sid INNER JOIN {l10n_community_file} f ON f.fid = l.fid WHERE t.is_active = 1 AND t.is_suggestion = 0 AND f.rid = %d GROUP BY t.language", $rid); + while ($latest = db_fetch_object($result)) { + $updated[$latest->language] = $latest->latest_time; + } + return $updated; +} + +/** + * Get files for a release, indexed by language. + */ +function l10n_packager_release_get_files($rid) { + $files = array(); + $result = db_query('SELECT * FROM {l10n_packager_file} r LEFT JOIN {files} f ON r.fid = f.fid WHERE r.rid = %d', $rid); + while ($file = db_fetch_object($result)) { + $files[$file->language] = $file; + } + return $files; +} Index: l10n_packager/l10n_packager.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_packager/Attic/l10n_packager.info,v retrieving revision 1.1.2.2 diff -u -p -r1.1.2.2 l10n_packager.info --- l10n_packager/l10n_packager.info 5 Sep 2009 17:19:24 -0000 1.1.2.2 +++ l10n_packager/l10n_packager.info 11 Nov 2009 18:18:03 -0000 @@ -1,6 +1,6 @@ ; $Id: l10n_packager.info,v 1.1.2.2 2009/09/05 17:19:24 goba Exp $ name = "Localizacion packager" -description = "Language export and packaging tools for the localization server" +description = "Translation packaging tools for the localization server" package = "Localization server" dependencies[] = l10n_community core = 6.x Index: l10n_packager/l10n_packager.install =================================================================== RCS file: l10n_packager/l10n_packager.install diff -N l10n_packager/l10n_packager.install --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ l10n_packager/l10n_packager.install 11 Nov 2009 18:18:03 -0000 @@ -0,0 +1,94 @@ + 'Information about packaging for each release.', + 'fields' => array( + 'rid' => array( + 'description' => 'Reference to {l10n_community_release}.rid', + 'type' => 'int', + 'not null' => TRUE, + 'unsigned' => TRUE, + ), + 'status' => array( + 'description' => 'Packaging status for this release. One of L10N_PACKAGER_DISABLED, L10N_PACKAGER_ACTIVE and L10N_PACKAGER_ERROR.', + 'type' => 'int', + 'not null' => TRUE, + 'default value' => 1, + 'disp-width' => '11' + ), + 'checked' => array( + 'description' => 'Unix timestamp of last time this release was checked.', + 'type' => 'int', + 'not null' => FALSE, + 'disp-width' => '11' + ), + 'updated' => array( + 'description' => 'Unix timestamp of last time files for this release were updated.', + 'type' => 'int', + 'not null' => FALSE, + 'disp-width' => '11' + ), + ), + 'primary key' => array('rid'), + ); + $schema['l10n_packager_file'] = array( + 'description' => 'Links releases and languages to files.', + 'fields' => array( + 'drid' => array( + 'description' => 'Internal numeric identifier for a release file.', + 'type' => 'serial', + 'not null' => TRUE, + ), + 'rid' => array( + 'description' => 'Reference to {l10n_community_release}.rid', + 'type' => 'int', + 'not null' => TRUE, + 'unsigned' => TRUE, + ), + 'language' => array( + 'description' => 'Reference to the {languages}.language for the translation package.', + 'type' => 'varchar', + 'length' => '12', + 'not null' => TRUE + ), + 'fid' => array( + 'description' => 'Reference to {files}.fid.', + 'type' => 'int', + 'not null' => TRUE, + 'unsigned' => TRUE, + ), + 'checked' => array( + 'description' => 'Unix timestamp of last time translation for this language was checked.', + 'type' => 'int', + 'not null' => FALSE, + 'disp-width' => '11' + ), + ), + 'primary key' => array('drid'), + ); + return $schema; +} + +/** + * Implementation of hook_install() + */ +function l10n_packager_install() { + drupal_install_schema('l10n_packager'); +} + +/** + * Implementation of hook_uninstall() + */ +function l10n_packager_uninstall() { + drupal_uninstall_schema('l10n_packager'); +} Index: l10n_packager/l10n_packager.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/l10n_server/l10n_packager/Attic/l10n_packager.module,v retrieving revision 1.1.2.2 diff -u -p -r1.1.2.2 l10n_packager.module --- l10n_packager/l10n_packager.module 5 Sep 2009 17:15:58 -0000 1.1.2.2 +++ l10n_packager/l10n_packager.module 11 Nov 2009 18:18:03 -0000 @@ -7,20 +7,79 @@ */ /** + * Release packager status: do not repackage anymore. + */ +define('L10N_PACKAGER_DISABLED', 0); + +/** + * Release packager status: keep repackaging. + */ +define('L10N_PACKAGER_ACTIVE', 1); + +/** + * Release packager status: error. + */ +define('L10N_PACKAGER_ERROR', 2); + +/** + * Default path structure for generated files + */ +define('L10N_PACKAGER_FILEPATH', '%core/%project/%project-%release.%language.po'); + +/** * Implementation of hook_menu(). */ function l10n_packager_menu() { - $items['admin/settings/language/packager'] = array( - 'title' => 'Export language list', - 'page callback' => 'l10n_packager_page', - 'access arguments' => array('administer languages'), - 'weight' => 20, + $items['admin/l10n_server/packager'] = array( + 'title' => 'Packaging tools', + 'description' => 'Select project, releases and languages to repackage.', + 'page callback' => 'l10n_packager_admin_repackage_page', + 'file' => 'l10n_packager.admin.inc', + 'access arguments' => array('administer localization community'), + ); + $items['admin/l10n_server/packager/package'] = array( + 'title' => 'Package', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ); + $items['admin/l10n_server/packager/configure'] = array( + 'title' => 'Configure', + 'description' => 'Configure automatic packaging for translations.', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('l10n_packager_settings_form'), + 'file' => 'l10n_packager.admin.inc', + 'access arguments' => array('administer localization community'), 'type' => MENU_LOCAL_TASK, + 'weight' => 10, ); return $items; } /** + * Implementation of hook_cron(). + */ +function l10n_packager_cron() { + if (variable_get('l10n_packager_cron', 0) && ($interval = variable_get('l10n_packager_update', 0))) { + module_load_include('inc', 'l10n_packager'); + $timestamp = time() - $interval; + $file_limit = variable_get('l10n_packager_file_limit', 1); + $count_files = $count_check = 0; + + // Go for it: check releases for repackaging. We need project_uri for later + $result = db_query_range("SELECT r.rid, r.pid, r.title, pr.checked, pr.updated, pr.status, p.uri FROM {l10n_community_release} r INNER JOIN {l10n_community_project} p ON r.pid = p.pid LEFT JOIN {l10n_packager_release} pr ON pr.rid = r.rid WHERE pr.status IS NULL OR (pr.status = %d AND (pr.checked < %d OR pr.updated < %d)) ORDER BY pr.checked", L10N_PACKAGER_ACTIVE, $timestamp, $timestamp, 0, variable_get('l10n_packager_release_limit', 10)); + + while ((!$file_limit || $file_limit > $count_files) && ($release = db_fetch_object($result))) { + $updates = l10n_packager_release_check($release, FALSE, $file_limit - $count_files, NULL, TRUE); + $count_files += count($updates); + $count_check++; + } + watchdog('l10n_packager', 'Checked %checked releases. Repackaged %repack translations.', array('%checked' => $count_check, '%repack' => $count_files)); + } +} + +// == Language list export ===================================================== + +/** * Implementation of hook_form_alter(). */ function l10n_packager_form_alter(&$form, $form_state, $form_id) { @@ -32,14 +91,14 @@ function l10n_packager_form_alter(&$form 'locale_languages_custom_form', ); if (in_array($form_id, $languages_forms)) { - $form['#submit'][] = 'l10n_packager_export'; + $form['#submit'][] = 'l10n_packager_export_language_list'; } } /** * Export languages in a simple XML format for remote use. */ -function l10n_packager_export() { +function l10n_packager_export_language_list() { $languages = language_list('language', TRUE); $xml = simplexml_load_string("\n"); @@ -49,7 +108,7 @@ function l10n_packager_export() { $item->addChild($key, $language->$key); } } - $xml_path = file_create_path('l10n_packager'); + $xml_path = l10n_packager_directory(); file_check_directory($xml_path, FILE_CREATE_DIRECTORY); if ($xml->asXML($xml_path .'/languages.xml')) { drupal_set_message(t('Languages XML exported.')); @@ -59,10 +118,49 @@ function l10n_packager_export() { } } +// == Utility functions ======================================================== + +/** + * Get directory for creating files + */ +function l10n_packager_directory() { + return variable_get('l10n_packager_directory', file_directory_path() .'/l10n_packager'); +} + +/** + * Ensure that directories on the $path exist in our packager directory. + */ +function l10n_packager_create_path($path) { + $directory = dirname($path); + $basepath = $currentpath = l10n_packager_directory(); + $finalpath = $basepath .'/'. $directory; + $parts = explode('/', $directory); + while (is_dir($currentpath) && !is_dir($finalpath) && ($more = array_shift($parts))) { + $currentpath .= '/'. $more; + file_check_directory($currentpath, FILE_CREATE_DIRECTORY); + } + return $basepath .'/'. $path; +} + /** - * Dummy page for export menu. + * Build target filepath from release object based on the set pattern. */ -function l10n_packager_page() { - l10n_packager_export(); - drupal_goto('admin/settings/language/overview'); +function l10n_packager_get_filepath($release, $language) { + // Release name should be like 6.x-1.2-beta1 for contrib modules + // and 6.11 for core (where $core is actually $version). + @list($core, $version, $extra) = explode('-', $release->title); + if (empty($version)) { + $version = $core; + list($major, $minor) = explode('.', $core); + $core = $major .'-x'; + } + $replace = array( + '%project' => $release->uri, + '%release' => $release->title, + '%core' => $core, + '%version' => $version, + '%extra' => !empty($extra) ? '-'. $extra : '', + '%language' => $language->language, + ); + return strtr(variable_get('l10n_packager_filepath', L10N_PACKAGER_FILEPATH), $replace); }