diff --git a/core/modules/openid/openid.module b/core/modules/openid/openid.module index 7214666c011bcf788e8982357ac18daada6497d9..433ffee5ed8740942dd58cd509fa0ab549dcc872 100644 --- a/core/modules/openid/openid.module +++ b/core/modules/openid/openid.module @@ -218,6 +218,58 @@ function openid_form_user_register_form_alter(&$form, &$form_state) { $form['account']['pass']['#value'] = user_password(); } + $timezone = FALSE; + if (!empty($sreg_values['timezone'])) { + $timezone = $sreg_values['timezone']; + } + elseif ($ax_timezone_values = openid_extract_ax_values($ax_values, array('http://axschema.org/pref/timezone', 'http://openid.net/schema/timezone'))) { + $timezone = current($ax_timezone_values); + } + if (in_array($timezone, timezone_identifiers_list())) { + $form['#user']->timezone = $timezone; + } + + $language = FALSE; + if (!empty($sreg_values['language'])) { + $language = $sreg_values['language']; + } + elseif ($ax_language_values = openid_extract_ax_values($ax_values, array('http://axschema.org/pref/language', 'http://openid.net/schema/language/pref'))) { + $language = current($ax_language_values); + } + if ($language) { + // The OpenID Simple Registration Extension specification is unclear about + // the format of openid.sreg.language. Codes like "EN" and "ZH_CN" have + // been observed. + // AX values are in RFC 4646 format, e.g. "de", "en-GB", "en-Latn-GB", + // "zh-Hans", or "zh-Hans-CN". The first part is the language, the second + // is the script, and the third is the region. Other parts are also + // defined, but we will not use them here. All parts except the first are + // optional. + // We generate a list of all permutations of the first three parts and + // match them against the list of enabled languages. E.g. if the user's + // preferred langugage is "en-GB", we look for "en-gb" (Drupal's language + // codes are lower-case) or fall back to "en". + $parts = preg_split('/[_-]/', strtolower($language)); + $candidate_languages[] = $parts[0]; + if (count($parts) > 1) { + $candidate_languages[] = $parts[0] . '-' . $parts[1]; + } + if (count($parts) > 2) { + $candidate_languages[] = $parts[0] . '-' . $parts[2]; + $candidate_languages[] = $parts[0] . '-' . $parts[1] . '-' . $parts[2]; + } + $all_languages = language_list('enabled'); + $enabled_languages = $all_languages[1]; + // Iterate over the generated permutations starting with the longest (most + // specific) strings. + foreach (array_reverse($candidate_languages) as $candidate_language) { + if (isset($enabled_languages[$candidate_language])) { + $form['locale']['language']['#type'] = 'hidden'; + $form['locale']['language']['#value'] = $candidate_language; + } + } + } + $form['openid_claimed_id'] = array( '#type' => 'value', '#default_value' => $response['openid.claimed_id'], @@ -754,6 +806,7 @@ function openid_authentication_request($claimed_id, $identity, $return_to = '', // that the Endpoint advertise OPENID_NS_SREG in the service description. $request['openid.ns.sreg'] = OPENID_NS_SREG; $request['openid.sreg.required'] = 'nickname,email'; + $request['openid.sreg.optional'] = 'timezone,language'; // Request Attribute Exchange, if available. // We only request the minimum attributes we need here, contributed modules @@ -762,6 +815,7 @@ function openid_authentication_request($claimed_id, $identity, $return_to = '', $request['openid.ns.ax'] = OPENID_NS_AX; $request['openid.ax.mode'] = 'fetch_request'; $request['openid.ax.required'] = 'mail_ao,name_ao,mail_son,name_son'; + $request['openid.ax.if_available'] = 'timezone_ao,language_ao,timezone_son,language_son'; // Implementors disagree on which URIs to use, even for simple // attributes like name and email (*sigh*). We ask for both axschema.org @@ -771,10 +825,14 @@ function openid_authentication_request($claimed_id, $identity, $return_to = '', // Attributes as defined by axschema.org. $request['openid.ax.type.mail_ao'] = 'http://axschema.org/contact/email'; $request['openid.ax.type.name_ao'] = 'http://axschema.org/namePerson/friendly'; + $request['openid.ax.type.timezone_ao'] = 'http://axschema.org/pref/timezone'; + $request['openid.ax.type.language_ao'] = 'http://axschema.org/pref/language'; // Attributes as defined by schema.openid.net. $request['openid.ax.type.mail_son'] = 'http://schema.openid.net/contact/email'; $request['openid.ax.type.name_son'] = 'http://schema.openid.net/namePerson/friendly'; + $request['openid.ax.type.timezone_son'] = 'http://openid.net/schema/timezone'; + $request['openid.ax.type.language_son'] = 'http://openid.net/schema/language/pref'; } drupal_alter('openid_request', $request, $service); diff --git a/core/modules/openid/openid.test b/core/modules/openid/openid.test index b13fb0f388d10b01c1fb25f707faf2e3a1c895e7..93cbb6a1821c3bcb125b8502486f97d9a85b2ff6 100644 --- a/core/modules/openid/openid.test +++ b/core/modules/openid/openid.test @@ -399,9 +399,16 @@ class OpenIDRegistrationTestCase extends OpenIDWebTestCase { */ function testRegisterUserWithEmailVerification() { variable_set('user_email_verification', TRUE); + variable_get('configurable_timezones', 1); + variable_set('date_default_timezone', 'Europe/Brussels'); // Tell openid_test.module to respond with these SREG fields. - variable_set('openid_test_response', array('openid.sreg.nickname' => 'john', 'openid.sreg.email' => 'john@example.com')); + variable_set('openid_test_response', array( + 'openid.sreg.nickname' => 'john', + 'openid.sreg.email' => 'john@example.com', + 'openid.sreg.language' => 'en-GB', + 'openid.sreg.timezone' => 'Europe/London', + )); // Use a User-supplied Identity that is the URL of an XRDS document. $identity = url('openid-test/yadis/xrds', array('absolute' => TRUE)); @@ -413,6 +420,8 @@ class OpenIDRegistrationTestCase extends OpenIDWebTestCase { $user = user_load_by_name('john'); $this->assertTrue($user, t('User was registered with right username.')); $this->assertEqual($user->mail, 'john@example.com', t('User was registered with right email address.')); + $this->assertEqual($user->timezone, 'Europe/London', t('User was registered with right timezone.')); + $this->assertEqual($user->language, 'en', t('User was registered with right language.')); $this->assertFalse($user->data, t('No additional user info was saved.')); $this->submitLoginForm($identity); @@ -434,9 +443,16 @@ class OpenIDRegistrationTestCase extends OpenIDWebTestCase { */ function testRegisterUserWithoutEmailVerification() { variable_set('user_email_verification', FALSE); + variable_get('configurable_timezones', 1); + variable_set('date_default_timezone', 'Europe/Brussels'); // Tell openid_test.module to respond with these SREG fields. - variable_set('openid_test_response', array('openid.sreg.nickname' => 'john', 'openid.sreg.email' => 'john@example.com')); + variable_set('openid_test_response', array( + 'openid.sreg.nickname' => 'john', + 'openid.sreg.email' => 'john@example.com', + 'openid.sreg.language' => 'en-GB', + 'openid.sreg.timezone' => 'Europe/London', + )); // Use a User-supplied Identity that is the URL of an XRDS document. $identity = url('openid-test/yadis/xrds', array('absolute' => TRUE)); @@ -446,6 +462,8 @@ class OpenIDRegistrationTestCase extends OpenIDWebTestCase { $user = user_load_by_name('john'); $this->assertTrue($user, t('User was registered with right username.')); $this->assertEqual($user->mail, 'john@example.com', t('User was registered with right email address.')); + $this->assertEqual($user->timezone, 'Europe/London', t('User was registered with right timezone.')); + $this->assertEqual($user->language, 'en', t('User was registered with right language.')); $this->assertFalse($user->data, t('No additional user info was saved.')); $this->drupalLogout(); @@ -459,9 +477,17 @@ class OpenIDRegistrationTestCase extends OpenIDWebTestCase { * information (a username that is already taken, and no e-mail address). */ function testRegisterUserWithInvalidSreg() { + variable_get('configurable_timezones', 1); + variable_set('date_default_timezone', 'Europe/Brussels'); + // Tell openid_test.module to respond with these SREG fields. $web_user = $this->drupalCreateUser(array()); - variable_set('openid_test_response', array('openid.sreg.nickname' => $web_user->name, 'openid.sreg.email' => 'mail@invalid#')); + variable_set('openid_test_response', array( + 'openid.sreg.nickname' => $web_user->name, + 'openid.sreg.email' => 'mail@invalid#', + 'openid.sreg.timezone' => 'Foo/Bar', + 'openid.sreg.language' => 'foobar', + )); // Use a User-supplied Identity that is the URL of an XRDS document. $identity = url('openid-test/yadis/xrds', array('absolute' => TRUE)); @@ -482,6 +508,7 @@ class OpenIDRegistrationTestCase extends OpenIDWebTestCase { $user = user_load_by_name('john'); $this->assertTrue($user, t('User was registered with right username.')); + $this->assertFalse($user->language, t('No user language was saved.')); $this->assertFalse($user->data, t('No additional user info was saved.')); // Follow the one-time login that was sent in the welcome e-mail. @@ -501,6 +528,8 @@ class OpenIDRegistrationTestCase extends OpenIDWebTestCase { * information (i.e. no username or e-mail address). */ function testRegisterUserWithoutSreg() { + variable_get('configurable_timezones', 1); + // Load the front page to get the user login block. $this->drupalGet(''); @@ -519,6 +548,7 @@ class OpenIDRegistrationTestCase extends OpenIDWebTestCase { $user = user_load_by_name('john'); $this->assertTrue($user, t('User was registered with right username.')); + $this->assertFalse($user->language, t('No user language was saved.')); $this->assertFalse($user->data, t('No additional user info was saved.')); // Follow the one-time login that was sent in the welcome e-mail. @@ -538,6 +568,7 @@ class OpenIDRegistrationTestCase extends OpenIDWebTestCase { */ function testRegisterUserWithAXButNoSREG() { variable_set('user_email_verification', FALSE); + variable_set('date_default_timezone', 'Europe/Brussels'); // Tell openid_test.module to respond with these AX fields. variable_set('openid_test_response', array( @@ -547,6 +578,10 @@ class OpenIDRegistrationTestCase extends OpenIDWebTestCase { 'openid.ext123.type.name789' => 'http://schema.openid.net/namePerson/friendly', 'openid.ext123.count.name789' => '1', 'openid.ext123.value.name789.1' => 'john', + 'openid.ext123.type.timezone' => 'http://axschema.org/pref/timezone', + 'openid.ext123.value.timezone' => 'Europe/London', + 'openid.ext123.type.language' => 'http://axschema.org/pref/language', + 'openid.ext123.value.language' => 'en-GB', )); // Use a User-supplied Identity that is the URL of an XRDS document. @@ -557,6 +592,8 @@ class OpenIDRegistrationTestCase extends OpenIDWebTestCase { $user = user_load_by_name('john'); $this->assertTrue($user, t('User was registered with right username.')); $this->assertEqual($user->mail, 'john@example.com', t('User was registered with right email address.')); + $this->assertEqual($user->timezone, 'Europe/London', t('User was registered with right timezone.')); + $this->assertEqual($user->language, 'en', t('User was registered with right language.')); } } diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 625be0ac4527f92cdb4e61b23671f3ba2280246d..31e0de80aab87f428bda2d1ba62ef0f18d88c015 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -1979,20 +1979,22 @@ function system_form_user_profile_form_alter(&$form, &$form_state) { * Implements hook_form_FORM_ID_alter(). */ function system_form_user_register_form_alter(&$form, &$form_state) { - if (variable_get('configurable_timezones', 1)) { - if (variable_get('user_default_timezone', DRUPAL_USER_TIMEZONE_DEFAULT) == DRUPAL_USER_TIMEZONE_SELECT) { - system_user_timezone($form, $form_state); - } - else { - $form['account']['timezone'] = array( - '#type' => 'hidden', - '#value' => variable_get('user_default_timezone', DRUPAL_USER_TIMEZONE_DEFAULT) ? '' : variable_get('date_default_timezone', ''), - ); - } + if (variable_get('configurable_timezones', 1) && variable_get('user_default_timezone', DRUPAL_USER_TIMEZONE_DEFAULT) == DRUPAL_USER_TIMEZONE_SELECT) { + system_user_timezone($form, $form_state); return $form; } } +/** + * Implements hook_user_insert(). + */ +function system_user_presave(&$edit, $account) { + if (variable_get('configurable_timezones', 1) && empty($account->timezone) && !variable_get('user_default_timezone', DRUPAL_USER_TIMEZONE_DEFAULT)) { + $account->timezone = variable_get('date_default_timezone', ''); + } +} + + /** * Implements hook_user_login(). */