From fef11ae71ec1198b6eccde87aff0aec971d5debf Mon Sep 17 00:00:00 2001 From: webchick Date: Tue, 24 May 2011 08:58:16 -0700 Subject: Issue #1096340 by plach, fietserwin, sun: Fixed Stale language types/negotation info after enabling/disabling modules. --- includes/language.inc | 65 ++++++++++++- modules/locale/locale.admin.inc | 32 ++----- modules/locale/locale.module | 20 +++- modules/locale/locale.test | 163 +++++++++++++++++++++++++++++++- modules/locale/tests/locale_test.module | 81 +++++++++++++++- 5 files changed, 331 insertions(+), 30 deletions(-) diff --git a/includes/language.inc b/includes/language.inc index eb13eacc3..b7057f2a1 100644 --- a/includes/language.inc +++ b/includes/language.inc @@ -83,6 +83,44 @@ function language_types_disable($types) { variable_set('language_types', $enabled_types); } +/** + * Updates the language type configuration. + */ +function language_types_set() { + // Ensure that we are getting the defined language negotiation information. An + // invocation of module_enable() or module_disable() could outdate the cached + // information. + drupal_static_reset('language_types_info'); + drupal_static_reset('language_negotiation_info'); + + // Determine which language types are configurable and which not by checking + // whether the 'fixed' key is defined. Non-configurable (fixed) language types + // have their language negotiation settings stored there. + $defined_providers = language_negotiation_info(); + foreach (language_types_info() as $type => $info) { + if (isset($info['fixed'])) { + $language_types[$type] = FALSE; + $negotiation = array(); + foreach ($info['fixed'] as $weight => $id) { + if (isset($defined_providers[$id])) { + $negotiation[$id] = $weight; + } + } + language_negotiation_set($type, $negotiation); + } + else { + $language_types[$type] = TRUE; + } + } + + // Save language types. + variable_set('language_types', $language_types); + + // Ensure that subsequent calls of language_types_configurable() return the + // updated language type information. + drupal_static_reset('language_types_configurable'); +} + /** * Check if a language provider is enabled. * @@ -173,6 +211,28 @@ function language_negotiation_get_switch_links($type, $path) { return $links; } +/** + * Updates language configuration to remove any language provider that is no longer defined. + */ +function language_negotiation_purge() { + // Ensure that we are getting the defined language negotiation information. An + // invocation of module_enable() or module_disable() could outdate the cached + // information. + drupal_static_reset('language_negotiation_info'); + drupal_static_reset('language_types_info'); + + $defined_providers = language_negotiation_info(); + foreach (language_types_info() as $type => $type_info) { + $weight = 0; + $negotiation = array(); + foreach (variable_get("language_negotiation_$type", array()) as $id => $provider) { + if (isset($defined_providers[$id])) { + $negotiation[$id] = $weight++; + } + } + language_negotiation_set($type, $negotiation); + } +} /** * Save a list of language providers. @@ -180,7 +240,8 @@ function language_negotiation_get_switch_links($type, $path) { * @param $type * The language negotiation type. * @param $language_providers - * An array of language provider ids. + * An array of language provider weights keyed by id. + * @see language_provider_weight() */ function language_negotiation_set($type, $language_providers) { // Save only the necessary fields. @@ -189,7 +250,7 @@ function language_negotiation_set($type, $language_providers) { $negotiation = array(); $providers_weight = array(); $defined_providers = language_negotiation_info(); - $default_types = language_types_configurable(); + $default_types = language_types_configurable(FALSE); // Initialize the providers weight list. foreach ($language_providers as $id => $provider) { diff --git a/modules/locale/locale.admin.inc b/modules/locale/locale.admin.inc index de16133fb..d8201dbf2 100644 --- a/modules/locale/locale.admin.inc +++ b/modules/locale/locale.admin.inc @@ -541,6 +541,12 @@ function _locale_languages_configure_form_language_table(&$form, $type) { asort($providers_weight); foreach ($providers_weight as $id => $weight) { + // A language provider might be no more available if the defining module has + // been disabled after the last configuration saving. + if (!isset($language_providers[$id])) { + continue; + } + $enabled = isset($enabled_providers[$id]); $provider = $language_providers[$id]; @@ -658,7 +664,6 @@ function theme_locale_languages_configure_form($variables) { * Submit handler for language negotiation settings. */ function locale_languages_configure_form_submit($form, &$form_state) { - $language_types = array(); $configurable_types = $form['#language_types']; foreach ($configurable_types as $type) { @@ -666,7 +671,6 @@ function locale_languages_configure_form_submit($form, &$form_state) { $enabled_providers = $form_state['values'][$type]['enabled']; $enabled_providers[LANGUAGE_NEGOTIATION_DEFAULT] = TRUE; $providers_weight = $form_state['values'][$type]['weight']; - $language_types[$type] = TRUE; foreach ($providers_weight as $id => $weight) { if ($enabled_providers[$id]) { @@ -680,27 +684,11 @@ function locale_languages_configure_form_submit($form, &$form_state) { variable_set("locale_language_providers_weight_$type", $providers_weight); } - // Save non-configurable language types negotiation. - $language_types_info = language_types_info(); - $defined_providers = $form['#language_providers']; - foreach ($language_types_info as $type => $info) { - if (isset($info['fixed'])) { - $language_types[$type] = FALSE; - $negotiation = array(); - foreach ($info['fixed'] as $weight => $id) { - if (isset($defined_providers[$id])) { - $negotiation[$id] = $defined_providers[$id]; - $negotiation[$id]['weight'] = $weight; - } - } - language_negotiation_set($type, $negotiation); - } - } - - // Save language types. - variable_set('language_types', $language_types); + // Update non-configurable language types and the related language negotiation + // configuration. + language_types_set(); - $form_state['redirect'] = 'admin/config/regional/language'; + $form_state['redirect'] = 'admin/config/regional/language/configure'; drupal_set_message(t('Language negotiation configuration saved.')); } diff --git a/modules/locale/locale.module b/modules/locale/locale.module index c1cdd434b..07884614a 100644 --- a/modules/locale/locale.module +++ b/modules/locale/locale.module @@ -513,6 +513,8 @@ function locale_language_types_info() { 'description' => t('Order of language detection methods for user interface text. If a translation of user interface text is available in the detected language, it will be displayed.'), ), LANGUAGE_TYPE_CONTENT => array( + 'name' => t('Content'), + 'description' => t('Order of language detection methods for content. If a version of content is available in the detected language, it will be displayed.'), 'fixed' => array(LOCALE_LANGUAGE_NEGOTIATION_INTERFACE), ), LANGUAGE_TYPE_URL => array( @@ -593,6 +595,22 @@ function locale_language_negotiation_info() { return $providers; } +/** + * Implements hook_modules_enabled(). + */ +function locale_modules_enabled($modules) { + include_once DRUPAL_ROOT . '/includes/language.inc'; + language_types_set(); + language_negotiation_purge(); +} + +/** + * Implements hook_modules_disabled(). + */ +function locale_modules_disabled($modules) { + locale_modules_enabled($modules); +} + // --------------------------------------------------------------------------------- // Locale core functionality @@ -928,7 +946,7 @@ function locale_block_info() { include_once DRUPAL_ROOT . '/includes/language.inc'; $block = array(); $info = language_types_info(); - foreach (language_types_configurable() as $type) { + foreach (language_types_configurable(FALSE) as $type) { $block[$type] = array( 'info' => t('Language switcher (@type)', array('@type' => $info[$type]['name'])), // Not worth caching. diff --git a/modules/locale/locale.test b/modules/locale/locale.test index 5e9e8336c..42a6dbc48 100644 --- a/modules/locale/locale.test +++ b/modules/locale/locale.test @@ -17,6 +17,7 @@ * - a functional test for multilingual support by content type and on nodes. * - a functional test for multilingual fields. * - a functional test for comment language. + * - a functional test fot language types/negotiation info. */ @@ -2248,10 +2249,13 @@ class LocaleCommentLanguageFunctionalTest extends DrupalWebTestCase { variable_set('locale_test_content_language_type', TRUE); // Set interface language detection to user and content language detection - // to URL. + // to URL. Disable inheritance from interface language to ensure content + // language will fall back to the default language if no URL language can be + // detected. $edit = array( 'language[enabled][locale-user]' => TRUE, - 'language_content[enabled][locale-url]' => TRUE + 'language_content[enabled][locale-url]' => TRUE, + 'language_content[enabled][locale-interface]' => FALSE, ); $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings')); @@ -2373,3 +2377,158 @@ class LocaleDateFormatsFunctionalTest extends DrupalWebTestCase { $this->assertText($french_date, t('French date format appears')); } } + +/** + * Functional test for language types/negotiation info. + */ +class LocaleLanguageNegotiationInfoFunctionalTest extends DrupalWebTestCase { + + public static function getInfo() { + return array( + 'name' => 'Language negotiation info', + 'description' => 'Tests alterations to language types/negotiation info.', + 'group' => 'Locale', + ); + } + + function setUp() { + parent::setUp('locale'); + require_once DRUPAL_ROOT .'/includes/language.inc'; + $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages', 'view the administration theme')); + $this->drupalLogin($admin_user); + $this->drupalPost('admin/config/regional/language/add', array('langcode' => 'it'), t('Add language')); + } + + /** + * Tests alterations to language types/negotiation info. + */ + function testInfoAlterations() { + // Enable language type/negotiation info alterations. + variable_set('locale_test_language_types', TRUE); + variable_set('locale_test_language_negotiation_info', TRUE); + $this->languageNegotiationUpdate(); + + // Check that fixed language types are properly configured without the need + // of saving the language negotiation settings. + $this->checkFixedLanguageTypes(); + + // Make the content language type configurable by updating the language + // negotiation settings with the proper flag enabled. + variable_set('locale_test_content_language_type', TRUE); + $this->languageNegotiationUpdate(); + $type = LANGUAGE_TYPE_CONTENT; + $language_types = variable_get('language_types', drupal_language_types()); + $this->assertTrue($language_types[$type], t('Content language type is configurable.')); + + // Enable some core and custom language providers. The test language type is + // supposed to be configurable. + $test_type = 'test_language_type'; + $provider = LOCALE_LANGUAGE_NEGOTIATION_INTERFACE; + $test_provider = 'test_language_provider'; + $form_field = $type . '[enabled]['. $provider .']'; + $edit = array( + $form_field => TRUE, + $type . '[enabled][' . $test_provider . ']' => TRUE, + $test_type . '[enabled][' . $test_provider . ']' => TRUE, + ); + $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings')); + + // Remove the interface language provider by updating the language + // negotiation settings with the proper flag enabled. + variable_set('locale_test_language_negotiation_info_alter', TRUE); + $this->languageNegotiationUpdate(); + $negotiation = variable_get("language_negotiation_$type", array()); + $this->assertFalse(isset($negotiation[$provider]), t('Interface language provider removed from the stored settings.')); + $this->assertNoFieldByXPath("//input[@name=\"$form_field\"]", NULL, t('Interface language provider unavailable.')); + + // Check that type-specific language providers can be assigned only to the + // corresponding language types. + foreach (language_types_configurable() as $type) { + $form_field = $type . '[enabled][test_language_provider_ts]'; + if ($type == $test_type) { + $this->assertFieldByXPath("//input[@name=\"$form_field\"]", NULL, t('Type-specific test language provider available for %type.', array('%type' => $type))); + } + else { + $this->assertNoFieldByXPath("//input[@name=\"$form_field\"]", NULL, t('Type-specific test language provider unavailable for %type.', array('%type' => $type))); + } + } + + // Check language negotiation results. + $this->drupalGet(''); + $last = variable_get('locale_test_language_negotiation_last', array()); + foreach (language_types() as $type) { + $langcode = $last[$type]; + $value = $type == LANGUAGE_TYPE_CONTENT || strpos($type, 'test') !== FALSE ? 'it' : 'en'; + $this->assertEqual($langcode, $value, t('The negotiated language for %type is %language', array('%type' => $type, '%language' => $langcode))); + } + + // Disable locale_test and check that everything is set back to the original + // status. + $this->languageNegotiationUpdate('disable'); + + // Check that only the core language types are available. + foreach (language_types() as $type) { + $this->assertTrue(strpos($type, 'test') === FALSE, t('The %type language is still available', array('%type' => $type))); + } + + // Check that fixed language types are properly configured, even those + // previously set to configurable. + $this->checkFixedLanguageTypes(); + + // Check that unavailable language providers are not present in the + // negotiation settings. + $negotiation = variable_get("language_negotiation_$type", array()); + $this->assertFalse(isset($negotiation[$test_provider]), t('The disabled test language provider is not part of the content language negotiation settings.')); + + // Check that configuration page presents the correct options and settings. + $this->assertNoRaw(t('Test language detection'), t('No test language type configuration available.')); + $this->assertNoRaw(t('This is a test language provider'), t('No test language provider available.')); + } + + /** + * Update language types/negotiation information. + * + * Manually invoke locale_modules_enabled()/locale_modules_disabled() since + * they would not be invoked after enabling/disabling locale_test the first + * time. + */ + private function languageNegotiationUpdate($op = 'enable') { + static $last_op = NULL; + $modules = array('locale_test'); + + // Enable/disable locale_test only if we did not already before. + if ($last_op != $op) { + $function = "module_{$op}"; + $function($modules); + // Reset hook implementation cache. + module_implements(NULL, FALSE, TRUE); + } + + drupal_static_reset('language_types_info'); + drupal_static_reset('language_negotiation_info'); + $function = "locale_modules_{$op}d"; + if (function_exists($function)) { + $function($modules); + } + + $this->drupalGet('admin/config/regional/language/configure'); + } + + /** + * Check that language negotiation for fixed types matches the stored one. + */ + private function checkFixedLanguageTypes() { + drupal_static_reset('language_types_info'); + foreach (language_types_info() as $type => $info) { + if (isset($info['fixed'])) { + $negotiation = variable_get("language_negotiation_$type", array()); + $equal = count($info['fixed']) == count($negotiation); + while ($equal && list($id) = each($negotiation)) { + list(, $info_id) = each($info['fixed']); + $equal = $info_id == $id; + } + $this->assertTrue($equal, t('language negotiation for %type is properly set up', array('%type' => $type))); + } + } + } +} diff --git a/modules/locale/tests/locale_test.module b/modules/locale/tests/locale_test.module index f256b5c86..14a2588dd 100644 --- a/modules/locale/tests/locale_test.module +++ b/modules/locale/tests/locale_test.module @@ -27,14 +27,89 @@ function locale_test_boot() { } } +/** + * Implements hook_init(). + */ +function locale_test_init() { + locale_test_store_language_negotiation(); +} + +/** + * Implements hook_language_types_info(). + */ +function locale_test_language_types_info() { + if (variable_get('locale_test_language_types', FALSE)) { + return array( + 'test_language_type' => array( + 'name' => t('Test'), + 'description' => t('A test language type.'), + ), + 'fixed_test_language_type' => array( + 'fixed' => array('test_language_provider'), + ), + ); + } +} + /** * Implements hook_language_types_info_alter(). */ function locale_test_language_types_info_alter(array &$language_types) { if (variable_get('locale_test_content_language_type', FALSE)) { - $language_types[LANGUAGE_TYPE_CONTENT] = array( - 'name' => t('Content'), - 'description' => t('Order of language detection methods for content. If a version of content is available in the detected language, it will be displayed.'), + unset($language_types[LANGUAGE_TYPE_CONTENT]['fixed']); + } +} + +/** + * Implements hook_language_negotiation_info(). + */ +function locale_test_language_negotiation_info() { + if (variable_get('locale_test_language_negotiation_info', FALSE)) { + $info = array( + 'callbacks' => array( + 'language' => 'locale_test_language_provider', + ), + 'file' => drupal_get_path('module', 'locale_test') .'/locale_test.module', + 'weight' => -10, + 'description' => t('This is a test language provider.'), ); + + return array( + 'test_language_provider' => array( + 'name' => t('Test'), + 'types' => array(LANGUAGE_TYPE_CONTENT, 'test_language_type', 'fixed_test_language_type'), + ) + $info, + 'test_language_provider_ts' => array( + 'name' => t('Type-specific test'), + 'types' => array('test_language_type'), + ) + $info, + ); + } +} + +/** + * Implements hook_language_negotiation_info_alter(). + */ +function locale_test_language_negotiation_info_alter(array &$language_providers) { + if (variable_get('locale_test_language_negotiation_info_alter', FALSE)) { + unset($language_providers[LOCALE_LANGUAGE_NEGOTIATION_INTERFACE]); } } + +/** + * Store the last negotiated languages. + */ +function locale_test_store_language_negotiation() { + $last = array(); + foreach (language_types() as $type) { + $last[$type] = $GLOBALS[$type]->language; + } + variable_set('locale_test_language_negotiation_last', $last); +} + +/** + * Test language provider. + */ +function locale_test_language_provider($languages) { + return 'it'; +} -- cgit v1.2.3 From c09a969d96e70cd2470849fc159d74f54b552181 Mon Sep 17 00:00:00 2001 From: webchick Date: Tue, 24 May 2011 14:00:57 -0700 Subject: Issue #1021270 by larowlan, wojtha: Fixed Blocks for custom menus are impossible to theme. --- modules/block/block.module | 10 +++++++++- modules/block/block.test | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/modules/block/block.module b/modules/block/block.module index 2f7e372fe..73eba3311 100644 --- a/modules/block/block.module +++ b/modules/block/block.module @@ -943,7 +943,15 @@ function template_preprocess_block(&$variables) { $variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->region; $variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->module; - $variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->module . '__' . $variables['block']->delta; + // Hyphens (-) and underscores (_) play a special role in theme suggestions. + // Theme suggestions should only contain underscores, because within + // drupal_find_theme_templates(), underscores are converted to hyphens to + // match template file names, and then converted back to underscores to match + // pre-processing and other function names. So if your theme suggestion + // contains a hyphen, it will end up as an underscore after this conversion, + // and your function names won't be recognized. So, we need to convert + // hyphens to underscores in block deltas for the theme suggestions. + $variables['theme_hook_suggestions'][] = 'block__' . $variables['block']->module . '__' . strtr($variables['block']->delta, '-', '_'); // Create a valid HTML ID and make sure it is unique. $variables['block_html_id'] = drupal_html_id('block-' . $variables['block']->module . '-' . $variables['block']->delta); diff --git a/modules/block/block.test b/modules/block/block.test index af118a940..022bf3830 100644 --- a/modules/block/block.test +++ b/modules/block/block.test @@ -666,3 +666,45 @@ class BlockHTMLIdTestCase extends DrupalWebTestCase { $this->assertRaw('block-block-test-test-html-id', t('HTML id for test block is valid.')); } } + + +/** + * Unit tests for template_preprocess_block(). + */ +class BlockTemplateSuggestionsUnitTest extends DrupalUnitTestCase { + public static function getInfo() { + return array( + 'name' => 'Block template suggestions', + 'description' => 'Test the template_preprocess_block() function.', + 'group' => 'Block', + ); + } + + /** + * Test if template_preprocess_block() handles the suggestions right. + */ + function testBlockThemeHookSuggestions() { + // Define block delta with underscore to be preprocessed + $block1 = new stdClass(); + $block1->module = 'block'; + $block1->delta = 'underscore_test'; + $block1->region = 'footer'; + $variables1 = array(); + $variables1['elements']['#block'] = $block1; + $variables1['elements']['#children'] = ''; + template_preprocess_block($variables1); + $this->assertEqual($variables1['theme_hook_suggestions'], array('block__footer', 'block__block', 'block__block__underscore_test'), t('Found expected block suggestions for delta with underscore')); + + // Define block delta with hyphens to be preprocessed. Hyphens should be + // replaced with underscores. + $block2 = new stdClass(); + $block2->module = 'block'; + $block2->delta = 'hyphen-test'; + $block2->region = 'footer'; + $variables2 = array(); + $variables2['elements']['#block'] = $block2; + $variables2['elements']['#children'] = ''; + template_preprocess_block($variables2); + $this->assertEqual($variables2['theme_hook_suggestions'], array('block__footer', 'block__block', 'block__block__hyphen_test'), t('Hyphens (-) in block delta were replaced by underscore (_)')); + } +} -- cgit v1.2.3 From ee61c8eacd3efde0a0e23dafd6bdc885e9555efa Mon Sep 17 00:00:00 2001 From: webchick Date: Tue, 24 May 2011 15:50:37 -0700 Subject: Issue #1137074 by plach, Jose Reyero: notices and wrong links on translation tab for unpublished nodes. --- modules/translation/translation.pages.inc | 6 +++--- modules/translation/translation.test | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/modules/translation/translation.pages.inc b/modules/translation/translation.pages.inc index 102d1b882..7e4f0af26 100644 --- a/modules/translation/translation.pages.inc +++ b/modules/translation/translation.pages.inc @@ -37,12 +37,12 @@ function translation_node_overview($node) { $translation_node = node_load($translations[$langcode]->nid); $path = 'node/' . $translation_node->nid; $links = language_negotiation_get_switch_links($type, $path); - $title = empty($links->links[$langcode]) ? l($translation_node->title, $path) : l($translation_node->title, $links->links[$langcode]['href'], $links->links[$langcode]); + $title = empty($links->links[$langcode]['href']) ? l($translation_node->title, $path) : l($translation_node->title, $links->links[$langcode]['href'], $links->links[$langcode]); if (node_access('update', $translation_node)) { $text = t('edit'); $path = 'node/' . $translation_node->nid . '/edit'; $links = language_negotiation_get_switch_links($type, $path); - $options[] = empty($links->links[$langcode]) ? l($text, $path) : l($text, $links->links[$langcode]['href'], $links->links[$langcode]); + $options[] = empty($links->links[$langcode]['href']) ? l($text, $path) : l($text, $links->links[$langcode]['href'], $links->links[$langcode]); } $status = $translation_node->status ? t('Published') : t('Not published'); $status .= $translation_node->translate ? ' - ' . t('outdated') . '' : ''; @@ -58,7 +58,7 @@ function translation_node_overview($node) { $path = 'node/add/' . str_replace('_', '-', $node->type); $links = language_negotiation_get_switch_links($type, $path); $query = array('query' => array('translation' => $node->nid, 'target' => $langcode)); - $options[] = empty($links->links[$langcode]) ? l($text, $path, $query) : l($text, $links->links[$langcode]['href'], array_merge_recursive($links->links[$langcode], $query)); + $options[] = empty($links->links[$langcode]['href']) ? l($text, $path, $query) : l($text, $links->links[$langcode]['href'], array_merge_recursive($links->links[$langcode], $query)); } $status = t('Not translated'); } diff --git a/modules/translation/translation.test b/modules/translation/translation.test index fa8c6b63f..54b53d9fd 100644 --- a/modules/translation/translation.test +++ b/modules/translation/translation.test @@ -20,7 +20,7 @@ class TranslationTestCase extends DrupalWebTestCase { parent::setUp('locale', 'translation', 'translation_test'); // Setup users. - $this->admin_user = $this->drupalCreateUser(array('bypass node access', 'administer nodes', 'administer languages', 'administer content types', 'administer blocks', 'access administration pages')); + $this->admin_user = $this->drupalCreateUser(array('bypass node access', 'administer nodes', 'administer languages', 'administer content types', 'administer blocks', 'access administration pages', 'translate content')); $this->translator = $this->drupalCreateUser(array('create page content', 'edit own page content', 'translate content')); $this->drupalLogin($this->admin_user); @@ -67,6 +67,14 @@ class TranslationTestCase extends DrupalWebTestCase { $node_body = $this->randomName(); $node = $this->createPage($node_title, $node_body, 'en'); + // Unpublish the original node to check that this has no impact on the + // translation overview page, publish it again afterwards. + $this->drupalLogin($this->admin_user); + $this->drupalPost('node/' . $node->nid . '/edit', array('status' => FALSE), t('Save')); + $this->drupalGet('node/' . $node->nid . '/translate'); + $this->drupalPost('node/' . $node->nid . '/edit', array('status' => NODE_PUBLISHED), t('Save')); + $this->drupalLogin($this->translator); + // Check that the "add translation" link uses a localized path. $languages = language_list(); $this->drupalGet('node/' . $node->nid . '/translate'); -- cgit v1.2.3 From 2ce86d77f7b06d21da0a7e67a6ded3a0eba94e46 Mon Sep 17 00:00:00 2001 From: webchick Date: Wed, 25 May 2011 08:54:21 -0700 Subject: Get CHANGELOG.txt caught up to speed with changes in Drupal 6 and Drupal 5 in the past three years. --- CHANGELOG.txt | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 232 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 70c837cdb..5059cc194 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,8 @@ -Drupal 7.0, xxxx-xx-xx (development version) +Drupal 7.1-dev, xxxx-xx-xx (development version) +---------------------- + +Drupal 7.0, 2011-01-05 ---------------------- - Database: * Fully rewritten database layer utilizing PHP 5's PDO abstraction layer. @@ -218,6 +221,145 @@ Drupal 7.0, xxxx-xx-xx (development version) * Added a locking framework to coordinate long-running operations across requests. +Drupal 6.20, 2010-12-15 +---------------------- +- Fixed a variety of small bugs, improved code documentation. + +Drupal 6.19, 2010-08-11 +---------------------- +- Fixed a variety of small bugs, improved code documentation. + +Drupal 6.18, 2010-08-11 +---------------------- +- Fixed security issues (OpenID authentication bypass, File download access + bypass, Comment unpublishing bypass, Actions cross site scripting), + see SA-CORE-2010-002. + +Drupal 6.17, 2010-06-02 +---------------------- +- Improved PostgreSQL compatibility +- Better PHP 5.3 and PHP 4 compatibility +- Better browser compatibility of CSS and JS aggregation +- Improved logging for login failures +- Fixed an incompatibility with some contributed modules and the locking system +- Fixed a variety of other bugs. + +Drupal 6.16, 2010-03-03 +---------------------- +- Fixed security issues (Installation cross site scripting, Open redirection, + Locale module cross site scripting, Blocked user session regeneration), + see SA-CORE-2010-001. +- Better support for updated jQuery versions. +- Reduced resource usage of update.module. +- Fixed several issues relating to support of install profiles and + distributions. +- Added a locking framework to avoid data corruption on long operations. +- Fixed a variety of other bugs. + +Drupal 6.15, 2009-12-16 +---------------------- +- Fixed security issues (Cross site scripting), see SA-CORE-2009-009. +- Fixed a variety of other bugs. + +Drupal 6.14, 2009-09-16 +---------------------- +- Fixed security issues (OpenID association cross site request forgeries, + OpenID impersonation and File upload), see SA-CORE-2009-008. +- Changed the system modules page to not run all cache rebuilds; use the + button on the performance settings page to achieve the same effect. +- Added support for PHP 5.3.0 out of the box. +- Fixed a variety of small bugs. + +Drupal 6.13, 2009-07-01 +---------------------- +- Fixed security issues (Cross site scripting, Input format access bypass and + Password leakage in URL), see SA-CORE-2009-007. +- Fixed a variety of small bugs. + +Drupal 6.12, 2009-05-13 +---------------------- +- Fixed security issues (Cross site scripting), see SA-CORE-2009-006. +- Fixed a variety of small bugs. + +Drupal 6.11, 2009-04-29 +---------------------- +- Fixed security issues (Cross site scripting and limited information + disclosure), see SA-CORE-2009-005 +- Fixed performance issues with the menu router cache, the update + status cache and improved cache invalidation +- Fixed a variety of small bugs. + +Drupal 6.10, 2009-02-25 +---------------------- +- Fixed a security issue, (Local file inclusion on Windows), + see SA-CORE-2009-003 +- Fixed node_feed() so custom fields can show up in RSS feeds. +- Improved PostgreSQL compatibility. +- Fixed a variety of small bugs. + +Drupal 6.9, 2009-01-14 +---------------------- +- Fixed security issues, (Access Bypass, Validation Bypass and Hardening + against SQL injection), see SA-CORE-2009-001 +- Made HTTP request checking more robust and informative. +- Fixed HTTP_HOST checking to work again with HTTP 1.0 clients and + basic shell scripts. +- Removed t() calls from all schema documentation. Suggested best practice + changed for contributed modules, see http://drupal.org/node/322731. +- Fixed a variety of small bugs. + +Drupal 6.8, 2008-12-11 +---------------------- +- Removed a previous change incompatible with PHP 5.1.x and lower. + +Drupal 6.7, 2008-12-10 +---------------------- +- Fixed security issues, (Cross site request forgery and Cross site scripting), see SA-2008-073 +- Updated robots.txt and .htaccess to match current file use. +- Fixed a variety of small bugs. + +Drupal 6.6, 2008-10-22 +---------------------- +- Fixed security issues, (File inclusion, Cross site scripting), see SA-2008-067 +- Fixed a variety of small bugs. + +Drupal 6.5, 2008-10-08 +---------------------- +- Fixed security issues, (File upload access bypass, Access rules bypass, + BlogAPI access bypass), see SA-2008-060. +- Fixed a variety of small bugs. + +Drupal 6.4, 2008-08-13 +---------------------- +- Fixed a security issue (Cross site scripting, Arbitrary file uploads via + BlogAPI, Cross site request forgeries and Various Upload module + vulnerabilities), see SA-2008-047. +- Improved error messages during installation. +- Fixed a bug that prevented AHAH handlers to be attached to radios widgets. +- Fixed a variety of small bugs. + +Drupal 6.3, 2008-07-09 +---------------------- +- Fixed security issues, (Cross site scripting, cross site request forgery, + session fixation and SQL injection), see SA-2008-044. +- Slightly modified installation process to prevent file ownership issues on + shared hosts. +- Improved PostgreSQL compatibility (rewritten queries; custom blocks). +- Upgraded to jQuery 1.2.6. +- Performance improvements to search, menu handling and form API caches. +- Fixed Views compatibility issues (Views for Drupal 6 requires Drupal 6.3+). +- Fixed a variety of small bugs. + +Drupal 6.2, 2008-04-09 +---------------------- +- Fixed a variety of small bugs. +- Fixed a security issue (Access bypasses), see SA-2008-026. + +Drupal 6.1, 2008-02-27 +---------------------- +- Fixed a variety of small bugs. +- Fixed a security issue (Cross site scripting), see SA-2008-018. + Drupal 6.0, 2008-02-13 ---------------------- - New, faster and better menu system. @@ -320,6 +462,95 @@ Drupal 6.0, 2008-02-13 - Removed old system updates. Updates from Drupal versions prior to 5.x will require upgrading to 5.x before upgrading to 6.x. +Drupal 5.23, 2010-08-11 +----------------------- +- Fixed security issues (File download access bypass, Comment unpublishing + bypass), see SA-CORE-2010-002. + +Drupal 5.22, 2010-03-03 +----------------------- +- Fixed security issues (Open redirection, Locale module cross site scripting, + Blocked user session regeneration), see SA-CORE-2010-001. + +Drupal 5.21, 2009-12-16 +----------------------- +- Fixed a security issue (Cross site scripting), see SA-CORE-2009-009. +- Fixed a variety of small bugs. + +Drupal 5.20, 2009-09-16 +----------------------- +- Avoid security problems resulting from writing Drupal 6-style menu + declarations. +- Fixed security issues (session fixation), see SA-CORE-2009-008. +- Fixed a variety of small bugs. + +Drupal 5.19, 2009-07-01 +----------------------- +- Fixed security issues (Cross site scripting and Password leakage in URL), see + SA-CORE-2009-007. +- Fixed a variety of small bugs. + +Drupal 5.18, 2009-05-13 +----------------------- +- Fixed security issues (Cross site scripting), see SA-CORE-2009-006. +- Fixed a variety of small bugs. + +Drupal 5.17, 2009-04-29 +----------------------- +- Fixed security issues (Cross site scripting and limited information + disclosure) see SA-CORE-2009-005. +- Fixed a variety of small bugs. + +Drupal 5.16, 2009-02-25 +----------------------- +- Fixed a security issue, (Local file inclusion on Windows), see SA-CORE-2009-004. +- Fixed a variety of small bugs. + +Drupal 5.15, 2009-01-14 +----------------------- +- Fixed security issues, (Hardening against SQL injection), see + SA-CORE-2009-001 +- Fixed HTTP_HOST checking to work again with HTTP 1.0 clients and basic shell + scripts. +- Fixed a variety of small bugs. + +Drupal 5.14, 2008-12-11 +----------------------- +- removed a previous change incompatible with PHP 5.1.x and lower. + +Drupal 5.13, 2008-12-10 +----------------------- +- fixed a variety of small bugs. +- fixed security issues, (Cross site request forgery and Cross site scripting), see SA-2008-073 +- updated robots.txt and .htaccess to match current file use. + +Drupal 5.12, 2008-10-22 +----------------------- +- fixed security issues, (File inclusion), see SA-2008-067 + +Drupal 5.11, 2008-10-08 +----------------------- +- fixed a variety of small bugs. +- fixed security issues, (File upload access bypass, Access rules bypass, + BlogAPI access bypass, Node validation bypass), see SA-2008-060 + +Drupal 5.10, 2008-08-13 +----------------------- +- fixed a variety of small bugs. +- fixed security issues, (Cross site scripting, Arbitrary file uploads via + BlogAPI and Cross site request forgery), see SA-2008-047 + +Drupal 5.9, 2008-07-23 +---------------------- +- fixed a variety of small bugs. +- fixed security issues, (Session fixation), see SA-2008-046 + +Drupal 5.8, 2008-07-09 +---------------------- +- fixed a variety of small bugs. +- fixed security issues, (Cross site scripting, cross site request forgery, and + session fixation), see SA-2008-044 + Drupal 5.7, 2008-01-28 ---------------------- - fixed the input format configuration page. -- cgit v1.2.3 From 316bd96ebff36284f5f3e33268760ff9c672b6f8 Mon Sep 17 00:00:00 2001 From: webchick Date: Wed, 25 May 2011 13:07:13 -0700 Subject: Drupal 7.1 --- CHANGELOG.txt | 5 ++++- includes/bootstrap.inc | 2 +- modules/color/color.install | 15 +++++++++++++++ modules/color/color.module | 13 +++++++++++++ modules/file/file.module | 2 +- 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index e56850485..ea91e0de9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,4 +1,7 @@ -// $Id$ + +Drupal 7.1, 2011-05-25 +---------------------- +- Fixed security issues (Cross site scripting, File access bypass), see SA-CORE-2011-001. Drupal 7.0, 2011-01-05 ---------------------- diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index be9813cc1..fb73528ff 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -9,7 +9,7 @@ /** * The current system version. */ -define('VERSION', '7.0'); +define('VERSION', '7.1'); /** * Core API compatibility. diff --git a/modules/color/color.install b/modules/color/color.install index 0655e797e..ff1e835a4 100644 --- a/modules/color/color.install +++ b/modules/color/color.install @@ -41,3 +41,18 @@ function color_requirements($phase) { return $requirements; } + +/** + * Warn site administrator if unsafe CSS color codes are found in the database. + */ +function color_update_7001() { + $theme_palettes = db_query("SELECT name FROM {variable} WHERE name LIKE 'color_%_palette'")->fetchCol(); + foreach ($theme_palettes as $name) { + $palette = variable_get($name, array()); + foreach ($palette as $key => $color) { + if (!preg_match('/^#([a-f0-9]{3}){1,2}$/iD', $color)) { + drupal_set_message('Some of the custom CSS color codes specified via the color module are invalid. Please examine the themes which are making use of the color module at the Appearance settings page to verify their CSS color values.', 'warning'); + } + } + } +} diff --git a/modules/color/color.module b/modules/color/color.module index d94cadc33..ab8fb9b79 100644 --- a/modules/color/color.module +++ b/modules/color/color.module @@ -43,6 +43,7 @@ function color_form_system_theme_settings_alter(&$form, &$form_state) { '#theme' => 'color_scheme_form', ); $form['color'] += color_scheme_form($form, $form_state, $theme); + $form['#validate'][] = 'color_scheme_form_validate'; $form['#submit'][] = 'color_scheme_form_submit'; } } @@ -271,6 +272,18 @@ function theme_color_scheme_form($variables) { return $output; } +/** + * Validation handler for color change form. + */ +function color_scheme_form_validate($form, &$form_state) { + // Only accept hexadecimal CSS color strings to avoid XSS upon use. + foreach ($form_state['values']['palette'] as $key => $color) { + if (!preg_match('/^#([a-f0-9]{3}){1,2}$/iD', $color)) { + form_set_error('palette][' . $key, t('%name must be a valid hexadecimal CSS color value.', array('%name' => $form['color']['palette'][$key]['#title']))); + } + } +} + /** * Submit handler for color change form. */ diff --git a/modules/file/file.module b/modules/file/file.module index 13a8024b2..3b6e18580 100644 --- a/modules/file/file.module +++ b/modules/file/file.module @@ -976,7 +976,7 @@ function file_get_file_references($file, $field = NULL, $age = FIELD_LOAD_REVISI } } - return isset($field) ? $references[$field['field_name']] : $references; + return isset($field) ? $references[$field['field_name']] : array_filter($references); } /** -- cgit v1.2.3 From e708195f3114659458b6cd7aa5d8c09049bb0c9a Mon Sep 17 00:00:00 2001 From: webchick Date: Wed, 25 May 2011 14:23:22 -0700 Subject: Back to 7.x-dev --- CHANGELOG.txt | 3 +++ includes/bootstrap.inc | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 131e17241..087177073 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,4 +1,7 @@ +Drupal 7.3-dev, xxxx-xx-xx (development version) +---------------------- + Drupal 7.2, 2011-05-25 ---------------------- - Added a default .gitignore file. diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index b70149cd3..d96072abe 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -8,7 +8,7 @@ /** * The current system version. */ -define('VERSION', '7.2'); +define('VERSION', '7.x-dev'); /** * Core API compatibility. -- cgit v1.2.3 From fad397b1f131fe10674d29bd4d49ba404c1cd070 Mon Sep 17 00:00:00 2001 From: webchick Date: Wed, 25 May 2011 14:26:11 -0700 Subject: Ahem. Once again. --- CHANGELOG.txt | 3 +++ includes/bootstrap.inc | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 087177073..1b3830880 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -239,6 +239,9 @@ Drupal 7.0, 2011-01-05 * Added a locking framework to coordinate long-running operations across requests. +Drupal 6.23-dev, xxxx-xx-xx (development release) +----------------------- + Drupal 6.22, 2011-05-25 ----------------------- - Made Drupal 6 work better with IIS and Internet Explorer. diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index d96072abe..a5dec6997 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -8,7 +8,7 @@ /** * The current system version. */ -define('VERSION', '7.x-dev'); +define('VERSION', '7.3-dev'); /** * Core API compatibility. -- cgit v1.2.3