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 component selection form. */ function potx_select_component_form_validate($form, &$form_state) { if (empty($form_state['values']['component'])) { form_set_error('', t('You should select a component to export.')); } } /** * Generate translation template or translation file for the requested component. */ function potx_select_component_form_submit($form, &$form_state) { global $devel_shutdown; // Avoid devel.module putting extra output to the end of files exported. $devel_shutdown = FALSE; // This could take some time. @set_time_limit(0); include_once drupal_get_path('module', 'potx') . '/potx.inc'; // $form_state['values']['component'] either contains a specific file name // with path, or a directory name for a module/theme or a module suite. // Examples: // modules/watchdog // sites/all/modules/coder // sites/all/modules/i18n/i18n.module // themes/garland $component = $form_state['values']['component']; $pathinfo = pathinfo($component); if (!isset($pathinfo['filename'])) { // The filename key is only available in PHP 5.2.0+ $pathinfo['filename'] = substr($pathinfo['basename'], 0, strrpos($pathinfo['basename'], '.')); } $strip_prefix = 0; if (isset($pathinfo['extension'])) { // A specific module or theme file was requested (otherwise there should be no extension). $files = potx_parser_source_files($pathinfo['dirname'] . '/', $pathinfo['filename']); $strip_prefix = 1 + strlen($pathinfo['dirname']); $outputname = $pathinfo['filename']; } // A directory name was requested. else { $files = potx_parser_source_files($component . '/'); $strip_prefix = 1 + strlen($component); $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_parser_parse_file($file, ($strip_prefix > 0 ? substr($file_path, $strip_prefix) : $file_path)); } // HTTP output. header('Content-Type: text/plain; charset=utf-8'); header('Content-Transfer-Encoding: 8bit'); header("Content-Disposition: 'attachment'; filename=$outputname"); // Need to include full parameter list to get to passing the language codes. print potx_parser_build_output(POTX_STRING_RUNTIME, 'potx_parser_callback_save_string', 'potx_parser_callback_version', 'potx_parser_callback_header', $template_langcode, $translation_langcode); exit; } /** * Build a chunk of the component selection form. * * @param $form * Form to populate with fields. * @param $components * Structured array with components as returned by _potx_component_list(). * @param $dirname * Name of directory handled. */ function _potx_component_selector(&$form, &$components, $dirname = '') { // Pop off count of components in this directory. if (isset($components['#-count'])) { $component_count = $components['#-count']; unset($components['#-count']); } //ksort($components); $dirkeys = array_keys($components); // A directory with one component. if (isset($component_count) && (count($components) == 1)) { $component = array_shift($components); $dirname = dirname($component->filename); $form[_potx_form_id('dir', $dirname)] = array( '#type' => 'radio', '#title' => t('Extract from %name in the %directory directory', array('%directory' => $dirname, '%name' => $component->name)), '#description' => t('Generates output from all files found in this directory.'), '#default_value' => 0, '#return_value' => $dirname, // Get all radio buttons into the same group. '#parents' => array('component'), ); return; } // A directory with multiple components in it. if (preg_match('!/(modules|themes)\\b(/.+)?!', $dirname, $pathmatch)) { $t_args = array('@directory' => substr($dirname, 1)); if (isset($pathmatch[2])) { $form[_potx_form_id('dir', $dirname)] = array( '#type' => 'radio', '#title' => t('Extract from all in directory "@directory"', $t_args), '#description' => t('To extract from a single component in this directory, choose the desired entry in the fieldset below.'), '#default_value' => 0, '#return_value' => substr($dirname, 1), // Get all radio buttons into the same group. '#parents' => array('component'), ); } $element = array( '#type' => 'fieldset', '#title' => t('Directory "@directory"', $t_args), '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form[_potx_form_id('fs', $dirname)] =& $element; } else { $element =& $form; } foreach ($dirkeys as $entry) { // A component in this directory with multiple components. if ($entry[0] == '#') { // Component entry. $t_args = array( '%directory' => dirname($components[$entry]->filename), '%name' => $components[$entry]->name, '%pattern' => $components[$entry]->name . '.*', ); $element[_potx_form_id('com', $components[$entry]->basename)] = array( '#type' => 'radio', '#title' => t('Extract from %name', $t_args), '#description' => t('Extract from files named %pattern in the %directory directory.', $t_args), '#default_value' => 0, '#return_value' => $components[$entry]->filename, // Get all radio buttons into the same group. '#parents' => array('component'), ); } // A subdirectory we need to look into. else { _potx_component_selector($element, $components[$entry], "$dirname/$entry"); } } return count($components); } /** * Generate a sane form element ID for the current radio button. * * @param $type * Type of ID generated: 'fs' for fieldset, 'dir' for directory, 'com' for component. * @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 components. * * @return * Array in the directory structure identified. * - 'normal' keyed elements being subfolders * - '#name' elements being component objects for the 'name' component * - '#-count' being the file count of all components in the directory */ function _potx_component_list() { $components = array(); // Get a list of all enabled modules and themes. $result = db_query("SELECT name, filename, type, status FROM {system} WHERE type IN ('module', 'theme') ORDER BY filename ASC"); foreach ($result as $component) { // Build directory tree structure. $path_parts = explode('/', dirname($component->filename)); $dir =& $components; foreach ($path_parts as $dirname) { if (!isset($dir[$dirname])) { $dir[$dirname] = array(); } $dir =& $dir[$dirname]; } // Information about components in this directory. $component->basename = basename($component->filename); $dir['#' . $component->basename] = $component; $dir['#-count'] = isset($dir['#-count']) ? $dir['#-count'] + 1 : 1; } return $components; }