#193320 by JirkaRybka: _locale_rebuild_js() was invoked on every page view, now optimized
parent
4c040de89b
commit
efbd1db550
|
|
@ -1871,8 +1871,8 @@ function drupal_add_js($data = NULL, $type = 'module', $scope = 'header', $defer
|
||||||
*/
|
*/
|
||||||
function drupal_get_js($scope = 'header', $javascript = NULL) {
|
function drupal_get_js($scope = 'header', $javascript = NULL) {
|
||||||
global $update_mode;
|
global $update_mode;
|
||||||
if (empty($update_mode) && function_exists('locale_inc_callback')) {
|
if (empty($update_mode) && function_exists('locale_update_js_files')) {
|
||||||
locale_inc_callback('_locale_update_js_files');
|
locale_update_js_files();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($javascript)) {
|
if (!isset($javascript)) {
|
||||||
|
|
|
||||||
|
|
@ -408,8 +408,13 @@ function locale_languages_delete_form(&$form_state, $langcode) {
|
||||||
function locale_languages_delete_form_submit($form, &$form_state) {
|
function locale_languages_delete_form_submit($form, &$form_state) {
|
||||||
$languages = language_list();
|
$languages = language_list();
|
||||||
if (isset($languages[$form_state['values']['langcode']])) {
|
if (isset($languages[$form_state['values']['langcode']])) {
|
||||||
db_query("DELETE FROM {languages} WHERE language = '%s'", $form_state['values']['langcode']);
|
// Remove translations first.
|
||||||
db_query("DELETE FROM {locales_target} WHERE language = '%s'", $form_state['values']['langcode']);
|
db_query("DELETE FROM {locales_target} WHERE language = '%s'", $form_state['values']['langcode']);
|
||||||
|
cache_clear_all('locale:'. $form_state['values']['langcode'], 'cache');
|
||||||
|
// With no translations, this removes existing JavaScript translations file.
|
||||||
|
_locale_rebuild_js($form_state['values']['langcode']);
|
||||||
|
// Remove the language.
|
||||||
|
db_query("DELETE FROM {languages} WHERE language = '%s'", $form_state['values']['langcode']);
|
||||||
db_query("UPDATE {node} SET language = '' WHERE language = '%s'", $form_state['values']['langcode']);
|
db_query("UPDATE {node} SET language = '' WHERE language = '%s'", $form_state['values']['langcode']);
|
||||||
$variables = array('%locale' => $languages[$form_state['values']['langcode']]->name);
|
$variables = array('%locale' => $languages[$form_state['values']['langcode']]->name);
|
||||||
drupal_set_message(t('The language %locale has been removed.', $variables));
|
drupal_set_message(t('The language %locale has been removed.', $variables));
|
||||||
|
|
@ -833,8 +838,8 @@ function locale_translate_edit_form_submit($form, &$form_state) {
|
||||||
db_query("DELETE FROM {locales_target} WHERE lid = %d AND language = '%s'", $lid, $key);
|
db_query("DELETE FROM {locales_target} WHERE lid = %d AND language = '%s'", $lid, $key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh the JS file for this language.
|
// Force JavaScript translation file recreation for this language.
|
||||||
_locale_rebuild_js($key);
|
_locale_invalidate_js($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
drupal_set_message(t('The string has been saved.'));
|
drupal_set_message(t('The string has been saved.'));
|
||||||
|
|
@ -858,12 +863,10 @@ function locale_translate_edit_form_submit($form, &$form_state) {
|
||||||
* Delete a language string.
|
* Delete a language string.
|
||||||
*/
|
*/
|
||||||
function locale_translate_delete($lid) {
|
function locale_translate_delete($lid) {
|
||||||
$langcode = db_result(db_query('SELECT language FROM {locales_target} WHERE lid = %d', $lid));
|
|
||||||
db_query('DELETE FROM {locales_source} WHERE lid = %d', $lid);
|
db_query('DELETE FROM {locales_source} WHERE lid = %d', $lid);
|
||||||
db_query('DELETE FROM {locales_target} WHERE lid = %d', $lid);
|
db_query('DELETE FROM {locales_target} WHERE lid = %d', $lid);
|
||||||
if ($langcode) {
|
// Force JavaScript translation file recreation for all languages.
|
||||||
_locale_rebuild_js($langcode);
|
_locale_invalidate_js();
|
||||||
}
|
|
||||||
cache_clear_all('locale:', 'cache', TRUE);
|
cache_clear_all('locale:', 'cache', TRUE);
|
||||||
drupal_set_message(t('The string has been removed.'));
|
drupal_set_message(t('The string has been removed.'));
|
||||||
drupal_goto('admin/build/translate/search');
|
drupal_goto('admin/build/translate/search');
|
||||||
|
|
@ -925,6 +928,9 @@ function locale_add_language($langcode, $name = NULL, $native = NULL, $direction
|
||||||
variable_set('language_count', variable_get('language_count', 1) + 1);
|
variable_set('language_count', variable_get('language_count', 1) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Force JavaScript translation file creation for the newly added language.
|
||||||
|
_locale_invalidate_js($langcode);
|
||||||
|
|
||||||
watchdog('locale', 'The %language language (%code) has been created.', array('%language' => $name, '%code' => $langcode));
|
watchdog('locale', 'The %language language (%code) has been created.', array('%language' => $name, '%code' => $langcode));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|
@ -974,8 +980,8 @@ function _locale_import_po($file, $langcode, $mode, $group = NULL) {
|
||||||
drupal_set_message(t('The translation file %filename appears to have a missing or malformed header.', array('%filename' => $file->filename)), 'error');
|
drupal_set_message(t('The translation file %filename appears to have a missing or malformed header.', array('%filename' => $file->filename)), 'error');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear cache and refresh JavaScript translations.
|
// Clear cache and force refresh of JavaScript translations.
|
||||||
_locale_rebuild_js($langcode);
|
_locale_invalidate_js($langcode);
|
||||||
cache_clear_all('locale:', 'cache', TRUE);
|
cache_clear_all('locale:', 'cache', TRUE);
|
||||||
|
|
||||||
// Rebuild the menu, strings may have changed.
|
// Rebuild the menu, strings may have changed.
|
||||||
|
|
@ -1597,46 +1603,6 @@ function _locale_import_parse_quoted($string) {
|
||||||
* @} End of "locale-api-import"
|
* @} End of "locale-api-import"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* This function checks all JavaScript files currently added via drupal_add_js()
|
|
||||||
* and invokes parsing if they have not yet been parsed for Drupal.t() calls.
|
|
||||||
*/
|
|
||||||
function _locale_update_js_files() {
|
|
||||||
global $language;
|
|
||||||
|
|
||||||
$parsed = variable_get('javascript_parsed', array());
|
|
||||||
|
|
||||||
// The first three parameters are NULL in order to get an array with all
|
|
||||||
// scopes. This is necessary to prevent recreation of JS translation files
|
|
||||||
// when new files are added for example in the footer.
|
|
||||||
$javascript = drupal_add_js(NULL, NULL, NULL);
|
|
||||||
$files = FALSE;
|
|
||||||
|
|
||||||
foreach ($javascript as $scope) {
|
|
||||||
foreach ($scope as $type => $data) {
|
|
||||||
if ($type != 'setting' && $type != 'inline') {
|
|
||||||
foreach ($data as $filepath => $info) {
|
|
||||||
$files = TRUE;
|
|
||||||
if (!in_array($filepath, $parsed)) {
|
|
||||||
_locale_parse_js_file($filepath);
|
|
||||||
watchdog('locale', 'Parsed JavaScript file %file.', array('%file' => $filepath));
|
|
||||||
$parsed[] = $filepath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the parsed files storage array.
|
|
||||||
variable_set('javascript_parsed', $parsed);
|
|
||||||
_locale_rebuild_js();
|
|
||||||
|
|
||||||
// Add the translation JavaScript file to the page.
|
|
||||||
if ($files && !empty($language->javascript)) {
|
|
||||||
drupal_add_js(file_create_path(variable_get('locale_js_directory', 'languages') .'/'. $language->language .'_'. $language->javascript .'.js'), 'core');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a JavaScript file, extracts strings wrapped in Drupal.t() and
|
* Parses a JavaScript file, extracts strings wrapped in Drupal.t() and
|
||||||
* Drupal.formatPlural() and inserts them into the database.
|
* Drupal.formatPlural() and inserts them into the database.
|
||||||
|
|
@ -2043,6 +2009,39 @@ function _locale_translate_seek_query() {
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force the JavaScript translation file(s) to be refreshed.
|
||||||
|
*
|
||||||
|
* This function sets a refresh flag for a specified language, or all
|
||||||
|
* languages except English, if none specified. JavaScript translation
|
||||||
|
* files are rebuilt (with locale_update_js_files()) the next time a
|
||||||
|
* request is served in that language.
|
||||||
|
*
|
||||||
|
* @param $langcode
|
||||||
|
* The language code for which the file needs to be refreshed.
|
||||||
|
* @return
|
||||||
|
* New content of the 'javascript_parsed' variable.
|
||||||
|
*/
|
||||||
|
function _locale_invalidate_js($langcode = NULL) {
|
||||||
|
$parsed = variable_get('javascript_parsed', array());
|
||||||
|
|
||||||
|
if (empty($langcode)) {
|
||||||
|
// Invalidate all languages.
|
||||||
|
$languages = language_list();
|
||||||
|
unset($languages['en']);
|
||||||
|
foreach ($languages as $lcode => $data) {
|
||||||
|
$parsed['refresh:'. $lcode] = 'waiting';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Invalidate single language.
|
||||||
|
$parsed['refresh:'. $langcode] = 'waiting';
|
||||||
|
}
|
||||||
|
|
||||||
|
variable_set('javascript_parsed', $parsed);
|
||||||
|
return $parsed;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (Re-)Creates the JavaScript translation file for a language.
|
* (Re-)Creates the JavaScript translation file for a language.
|
||||||
*
|
*
|
||||||
|
|
@ -2091,9 +2090,10 @@ function _locale_rebuild_js($langcode = NULL) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only operate when there are translations.
|
// Construct the JavaScript file, if there are translations.
|
||||||
|
$data = $status = '';
|
||||||
if (!empty($translations)) {
|
if (!empty($translations)) {
|
||||||
// Construct the JavaScript file.
|
|
||||||
$data = "Drupal.locale = { ";
|
$data = "Drupal.locale = { ";
|
||||||
|
|
||||||
if (!empty($language->formula)) {
|
if (!empty($language->formula)) {
|
||||||
|
|
@ -2101,33 +2101,40 @@ function _locale_rebuild_js($langcode = NULL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$data .= "'strings': ". drupal_to_js($translations) ." };";
|
$data .= "'strings': ". drupal_to_js($translations) ." };";
|
||||||
|
$data_hash = md5($data);
|
||||||
|
}
|
||||||
|
|
||||||
// Construct the directory where JS translation files are stored.
|
// Construct the filepath where JS translation files are stored.
|
||||||
// There is (on purpose) no front end to edit that variable.
|
// There is (on purpose) no front end to edit that variable.
|
||||||
$dir = file_create_path(variable_get('locale_js_directory', 'languages'));
|
$dir = file_create_path(variable_get('locale_js_directory', 'languages'));
|
||||||
|
|
||||||
// Only create a new file if the content has changed.
|
// Delete old file, if we have no translations anymore, or a different file to be saved.
|
||||||
$data_hash = md5($data);
|
if (!empty($language->javascript) && (!$data || $language->javascript != $data_hash)) {
|
||||||
if ($language->javascript != $data_hash) {
|
|
||||||
if (!empty($language->javascript)) {
|
|
||||||
// We are recreating the new file, so delete the old one.
|
|
||||||
file_delete(file_create_path($dir .'/'. $language->language .'_'. $language->javascript .'.js'));
|
file_delete(file_create_path($dir .'/'. $language->language .'_'. $language->javascript .'.js'));
|
||||||
$language->javascript = '';
|
$language->javascript = '';
|
||||||
|
$status = 'deleted';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only create a new file if the content has changed.
|
||||||
|
if ($data && $language->javascript != $data_hash) {
|
||||||
|
// Ensure that the directory exists and is writable, if possible.
|
||||||
|
file_check_directory($dir, TRUE);
|
||||||
|
|
||||||
|
// Save the file.
|
||||||
|
$dest = $dir .'/'. $language->language .'_'. $data_hash .'.js';
|
||||||
|
if (file_save_data($data, $dest)) {
|
||||||
|
$language->javascript = $data_hash;
|
||||||
|
$status = ($status == 'deleted') ? 'updated' : 'created';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// The directory might not exist when there has not been a translation
|
$language->javascript = '';
|
||||||
// file before, so create it.
|
$status = 'error';
|
||||||
file_check_directory($dir, TRUE);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The file name of the new JavaScript translation file.
|
// Save the new JavaScript hash (or an empty value if the file
|
||||||
$dest = $dir .'/'. $language->language .'_'. $data_hash .'.js';
|
// just got deleted). Act only if some operation was executed.
|
||||||
$filepath = file_save_data($data, $dest);
|
if ($status) {
|
||||||
|
|
||||||
// Update the global $language object.
|
|
||||||
$language->javascript = $filepath ? $data_hash : '';
|
|
||||||
|
|
||||||
// Save the new JavaScript hash.
|
|
||||||
db_query("UPDATE {languages} SET javascript = '%s' WHERE language = '%s'", $language->javascript, $language->language);
|
db_query("UPDATE {languages} SET javascript = '%s' WHERE language = '%s'", $language->javascript, $language->language);
|
||||||
|
|
||||||
// Update the default language variable if the default language has been altered.
|
// Update the default language variable if the default language has been altered.
|
||||||
|
|
@ -2138,30 +2145,25 @@ function _locale_rebuild_js($langcode = NULL) {
|
||||||
$default = db_fetch_object(db_query("SELECT * FROM {languages} WHERE language = '%s'", $default_langcode));
|
$default = db_fetch_object(db_query("SELECT * FROM {languages} WHERE language = '%s'", $default_langcode));
|
||||||
variable_set('language_default', $default);
|
variable_set('language_default', $default);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only report updated or creation when there is actually a file created.
|
// Log the operation and return success flag.
|
||||||
if ($filepath) {
|
switch ($status) {
|
||||||
// There has already been a translation file before.
|
case 'updated':
|
||||||
if (!empty($language->javascript)) {
|
|
||||||
watchdog('locale', 'Updated JavaScript translation file for the language %language.', array('%language' => t($language->name)));
|
watchdog('locale', 'Updated JavaScript translation file for the language %language.', array('%language' => t($language->name)));
|
||||||
}
|
return TRUE;
|
||||||
else {
|
case 'created':
|
||||||
watchdog('locale', 'Created JavaScript translation file for the language %language.', array('%language' => t($language->name)));
|
watchdog('locale', 'Created JavaScript translation file for the language %language.', array('%language' => t($language->name)));
|
||||||
}
|
return TRUE;
|
||||||
}
|
case 'deleted':
|
||||||
else {
|
watchdog('locale', 'Removed JavaScript translation file for the language %language, because no translations currently exist for that language.', array('%language' => t($language->name)));
|
||||||
watchdog('locale', 'An error occurred during creation of the JavaScript translation file for the language %language.', array('%language' => t($language->name)));
|
return TRUE;
|
||||||
}
|
case 'error':
|
||||||
}
|
watchdog('locale', 'An error occurred during creation of the JavaScript translation file for the language %language.', array('%language' => t($language->name)), WATCHDOG_ERROR);
|
||||||
}
|
return FALSE;
|
||||||
|
default:
|
||||||
// There are no strings for JavaScript translation. However, if there is a file,
|
// No operation needed.
|
||||||
// delete it and reset the database.
|
return TRUE;
|
||||||
elseif (!empty($language->javascript)) {
|
|
||||||
// Delete the old JavaScript file
|
|
||||||
file_delete(file_create_path(variable_get('locale_js_directory', 'languages') .'/'. $language->language .'_'. $language->javascript .'.js'));
|
|
||||||
db_query("UPDATE {languages} SET javascript = '' WHERE language = '%s'", $language->language);
|
|
||||||
watchdog('locale', 'Deleted JavaScript translation file for the locale %language.', array('%language' => t($language->name)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -458,6 +458,74 @@ function locale_system_update($components) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update JavaScript translation file, if required, and add it to the page.
|
||||||
|
*
|
||||||
|
* This function checks all JavaScript files currently added via drupal_add_js()
|
||||||
|
* and invokes parsing if they have not yet been parsed for Drupal.t()
|
||||||
|
* and Drupal.formatPlural() calls. Also refreshes the JavaScript translation
|
||||||
|
* file if necessary, and adds it to the page.
|
||||||
|
*/
|
||||||
|
function locale_update_js_files() {
|
||||||
|
global $language;
|
||||||
|
|
||||||
|
$dir = file_create_path(variable_get('locale_js_directory', 'languages'));
|
||||||
|
$parsed = variable_get('javascript_parsed', array());
|
||||||
|
|
||||||
|
// The first three parameters are NULL in order to get an array with all
|
||||||
|
// scopes. This is necessary to prevent recreation of JS translation files
|
||||||
|
// when new files are added for example in the footer.
|
||||||
|
$javascript = drupal_add_js(NULL, NULL, NULL);
|
||||||
|
$files = $new_files = FALSE;
|
||||||
|
|
||||||
|
foreach ($javascript as $scope) {
|
||||||
|
foreach ($scope as $type => $data) {
|
||||||
|
if ($type != 'setting' && $type != 'inline') {
|
||||||
|
foreach ($data as $filepath => $info) {
|
||||||
|
$files = TRUE;
|
||||||
|
if (!in_array($filepath, $parsed)) {
|
||||||
|
// Don't parse our own translations files.
|
||||||
|
if (substr($filepath, 0, strlen($dir)) != $dir) {
|
||||||
|
locale_inc_callback('_locale_parse_js_file', $filepath);
|
||||||
|
watchdog('locale', 'Parsed JavaScript file %file.', array('%file' => $filepath));
|
||||||
|
$parsed[] = $filepath;
|
||||||
|
$new_files = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are any new source files we parsed, invalidate existing
|
||||||
|
// JavaScript translation files for all languages, adding the refresh
|
||||||
|
// flags into the existing array.
|
||||||
|
if ($new_files) {
|
||||||
|
$parsed += locale_inc_callback('_locale_invalidate_js');
|
||||||
|
}
|
||||||
|
|
||||||
|
// If necessary, rebuild the translation file for the current language.
|
||||||
|
if (!empty($parsed['refresh:'. $language->language])) {
|
||||||
|
// Don't clear the refresh flag on failure, so that another try will
|
||||||
|
// be performed later.
|
||||||
|
if (locale_inc_callback('_locale_rebuild_js')) {
|
||||||
|
unset($parsed['refresh:'. $language->language]);
|
||||||
|
}
|
||||||
|
// Store any changes after refresh was attempted.
|
||||||
|
variable_set('javascript_parsed', $parsed);
|
||||||
|
}
|
||||||
|
// If no refresh was attempted, but we have new source files, we need
|
||||||
|
// to store them too. This occurs if current page is in English.
|
||||||
|
else if ($new_files) {
|
||||||
|
variable_set('javascript_parsed', $parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the translation JavaScript file to the page.
|
||||||
|
if ($files && !empty($language->javascript)) {
|
||||||
|
drupal_add_js($dir .'/'. $language->language .'_'. $language->javascript .'.js', 'core');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
// Language switcher block
|
// Language switcher block
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue