'Extract', 'page callback' => 'drupal_get_form', 'page arguments' => array('potx_select_form'), 'access arguments' => array('administer locales'), 'weight' => 200, 'type' => MENU_LOCAL_TASK, ); return $items; } /** * Module selection interface. */ function potx_select_form() { $form = array(); $modules = _potx_module_list(); _potx_build_module_form($form, $modules); // Generate translation file for a specific language if possible. $languages = language_list(); if (count($languages) > 1 || !isset($languages['en'])) { // We have more languages, or the single language we have is not English. $options = array('n/a' => t('Language independent template')); foreach ($languages as $langcode => $language) { // Skip English, as we should not have translations for this language. if ($langcode == 'en') { continue; } $options[$langcode] = t('Template file for !langname translations', array('!langname' => t($language->name))); } $form['langcode'] = array( '#type' => 'radios', '#title' => t('Template language'), '#default_value' => 'n/a', '#options' => $options, '#description' => t('Export a language independent or language dependent (plural forms, language team name, etc.) template.'), ); $form['translations'] = array( '#type' => 'checkbox', '#title' => t('Include translations'), '#description' => t('Include translations of strings in the file generated. Not applicable for language independent templates.') ); } $form['submit'] = array( '#type' => 'submit', '#value' => t('Extract'), ); return $form; } /** * Validation handler for potx module selection form. */ function potx_select_form_validate($form, &$form_state) { if (empty($form_state['values']['module'])) { form_set_error('', t('You should select a module to export.')); } } /** * Generate translation template or translation file for the requested module. */ function potx_select_form_submit($form, &$form_state) { // This could take some time. @set_time_limit(0); include_once drupal_get_path('module', 'potx') .'/potx.inc'; // Silence status messages. _potx_status(POTX_STATUS_MESSAGE); // $form_state['values']['module'] either contains a specific module file name // with path, or a directory name for a module or a module suite. // Examples: // modules/watchdog // sites/all/modules/potx // sites/all/modules/i18n/i18n.module $pathinfo = pathinfo($form_state['values']['module']); $strip_prefix = 0; // A specific module file was requested. if (isset($pathinfo['extension']) && $pathinfo['extension'] == 'module') { $filename = basename($pathinfo['basename'], '.module'); $files = _potx_explore_dir($pathinfo['dirname'] .'/', $filename); $strip_prefix = 1 + strlen($pathinfo['dirname']); $outputname = $filename; } // A directory name was requested. else { $files = _potx_explore_dir($form_state['values']['module'] .'/'); $strip_prefix = 1 + strlen($form_state['values']['module']); $outputname = $pathinfo['basename']; } // Decide on template or translation file generation. $template_langcode = $translation_langcode = NULL; if (isset($form_state['values']['langcode']) && ($form_state['values']['langcode'] != 'n/a')) { $template_langcode = $form_state['values']['langcode']; $outputname .= '.'. $template_langcode; if (!empty($form_state['values']['translations'])) { $translation_langcode = $template_langcode; $outputname .= '.po'; } else { $outputname .= '.pot'; } } else { $outputname .= '.pot'; } // Collect every string in affected files. Installer related strings are discared. foreach ($files as $file) { _potx_process_file($file, $strip_prefix); } // Need to include full parameter list to get to passing the language codes. _potx_build_files(POTX_STRING_RUNTIME, POTX_BUILD_SINGLE, 'general', '_potx_save_string', '_potx_save_version', '_potx_get_header', $template_langcode, $translation_langcode); _potx_write_files($outputname, 'attachment'); exit; } /** * Build a chunk of the module selection form. * * @param $form * Form to populate with fields. * @param $modules * Structured array with modules as returned by _potx_module_list(). * @param $dirname * Name of directory handled. */ function _potx_build_module_form(&$form, &$modules, $dirname = '') { // Pop off count of modules in this directory. if (isset($modules['.modulecount'])) { $modules_in_dir = $modules['.modulecount']; unset($modules['.modulecount']); } ksort($modules); $dirkeys = array_keys($modules); // A directory with one module. if (isset($modules_in_dir) && (count($modules) == 1)) { $module_dir = dirname($modules[$dirkeys[0]]->filename); $form[_potx_form_id('dir', $module_dir)] = array( '#type' => 'radio', '#title' => t('Extract from %module_name module, in directory %dir_name', array('%dir_name' => $module_dir, '%module_name' => basename($modules[$dirkeys[0]]->basename, '.module'))), '#description' => t('Generates output from all files found in this directory.'), '#default_value' => 0, '#return_value' => $module_dir, // Get all radio buttons into the same group. '#parents' => array('module'), ); return; } // A directory with multiple modules in it. if (preg_match('!/modules\\b(/.+)?!', $dirname, $pathmatch)) { $subst = array('@dir_name' => substr($dirname, 1)); if (isset($pathmatch[1])) { $form[_potx_form_id('dir', $dirname)] = array( '#type' => 'radio', '#title' => t('Extract from all modules in directory "@dir_name"', $subst), '#description' => t('To extract from a single module in this directory, choose the module entry in the fieldset below.'), '#default_value' => 0, '#return_value' => substr($dirname, 1), // Get all radio buttons into the same group. '#parents' => array('module'), ); } $element = array( '#type' => 'fieldset', '#title' => t('Modules in "@dir_name"', $subst), '#collapsible' => true, '#collapsed' => true, ); $form[_potx_form_id('fs', $dirname)] =& $element; } else { $element =& $form; } foreach ($dirkeys as $entry) { // A module in this directory with multiple modules. if ($entry[0] == '#') { $subst = array( '%module_dir' => dirname($modules[$entry]->filename), '%module_name' => basename($modules[$entry]->basename, '.module'), '%module_pattern' => basename($modules[$entry]->basename, '.module') .'.*', ); $element[_potx_form_id('mod', $modules[$entry]->basename)] = array( '#type' => 'radio', '#title' => t('Extract from module %module_name', $subst), '#description' => t('Extract from files named %module_pattern, in directory %module_dir.', $subst), '#default_value' => 0, '#return_value' => $modules[$entry]->filename, // Get all radio buttons into the same group. '#parents' => array('module'), ); } // A subdirectory we need to look into. else { _potx_build_module_form($element, $modules[$entry], "$dirname/$entry"); } } return count($modules); } /** * Generate a sane form element ID for the current radio button. * * @param $type * Type of ID generated: 'fs' for fieldset, 'dir' for directory, 'mod' for module * @param $path * Path of file we generate an ID for. * @return * The generated ID. */ function _potx_form_id($type, $path) { return 'potx-'. $type .'-'. preg_replace('/[^a-zA-Z0-9]+/', '-', $path); } /** * Generate a hierarchical structured list of modules. */ function _potx_module_list() { // Get current list of enabled modules and their file names. $files = drupal_system_listing('\.module$', 'modules', 'name', 0); system_get_files_database($files, 'module'); ksort($files); $modules = array(); foreach ($files as $file) { // Skip disabled modules if ($file->status != 1) { continue; } // Build directory tree structure. $path_parts = explode('/', dirname($file->filename)); $dir =& $modules; foreach ($path_parts as $dirname) { if (!isset($dir[$dirname])) { $dir[$dirname] = array(); } $dir =& $dir[$dirname]; } // Information about modules in this directory. $dir['#'. $file->basename] = $file; $dir['.modulecount'] = isset($dir['.modulecount']) ? $dir['.modulecount'] + 1 : 1; } return $modules; }