diff --git a/core/modules/user/lib/Drupal/user/AccountFormController.php b/core/modules/user/lib/Drupal/user/AccountFormController.php index 13ad217..16c870e 100644 --- a/core/modules/user/lib/Drupal/user/AccountFormController.php +++ b/core/modules/user/lib/Drupal/user/AccountFormController.php @@ -2,21 +2,53 @@ /** * @file - * Definition of Drupal\user\AccountFormController. + * Contains \Drupal\user\AccountFormController. */ namespace Drupal\user; use Drupal\Core\Entity\EntityFormController; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Language\Language; +use Drupal\Core\Entity\EntityControllerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Form controller for the user account forms. */ -abstract class AccountFormController extends EntityFormController { +abstract class AccountFormController extends EntityFormController implements EntityControllerInterface { /** - * Overrides Drupal\Core\Entity\EntityFormController::form(). + * The module handler to invoke hooks on. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** + * Constructs a new EntityFormController object. + * + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler to invoke hooks on. + */ + public function __construct($operation, ModuleHandlerInterface $module_handler) { + parent::__construct($operation); + + $this->moduleHandler = $module_handler; + } + + /** + * {@inheritdoc} + */ + public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info, $operation = NULL) { + return new static( + $operation, + $container->get('module_handler') + ); + } + + /** + * Overrides \Drupal\Core\Entity\EntityFormController::form(). */ public function form(array $form, array &$form_state) { $account = $this->entity; @@ -199,13 +231,26 @@ public function form(array $form, array &$form_state) { '#description' => $interface_language_is_default ? t("This account's preferred language for e-mails and site presentation.") : t("This account's preferred language for e-mails."), ); - $form['language']['preferred_admin_langcode'] = array( - '#type' => 'language_select', - '#title' => t('Administration pages language'), - '#languages' => Language::STATE_CONFIGURABLE, - '#default_value' => $user_preferred_admin_langcode, - '#access' => user_access('access administration pages', $account), - ); + // Only show the account setting for Administration pages language to users + // if one of the detection and selection methods uses it. + if ($this->moduleHandler->moduleExists('language')) { + $show_admin_language = FALSE; + if (language_multilingual()) { + foreach (language_types_info() as $type_key => $language_type) { + $negotiation_settings = variable_get("language_negotiation_{$type_key}", array()); + if ($show_admin_language = isset($negotiation_settings[LANGUAGE_NEGOTIATION_USER_ADMIN])) { + break; + } + } + } + $form['language']['preferred_admin_langcode'] = array( + '#type' => 'language_select', + '#title' => t('Administration pages language'), + '#languages' => Language::STATE_CONFIGURABLE, + '#default_value' => $user_preferred_admin_langcode, + '#access' => $show_admin_language && user_access('access administration pages', $account), + ); + } // User entities contain both a langcode property (for identifying the // language of the entity data) and a preferred_langcode property (see diff --git a/core/modules/user/lib/Drupal/user/Tests/UserAdminLanguageTest.php b/core/modules/user/lib/Drupal/user/Tests/UserAdminLanguageTest.php new file mode 100644 index 0000000..c9e21ec --- /dev/null +++ b/core/modules/user/lib/Drupal/user/Tests/UserAdminLanguageTest.php @@ -0,0 +1,112 @@ + 'User administration pages language settings', + 'description' => "Tests user's ability to change their administation pages language.", + 'group' => 'User', + ); + } + + protected function setUp() { + parent::setUp(); + // User to add and remove language. + $this->admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages')); + // User to check non-admin access. + $this->regular_user = $this->drupalCreateUser(); + } + + /** + * Tests that admin language is not configurable in single language sites. + */ + function testUserAdminLanguageConfigurationNotAvailableWithOnlyOneLanguage() { + $this->drupalLogin($this->admin_user); + $this->setLanguageNegotiation(); + $path = 'user/' . $this->admin_user->uid . '/edit'; + $this->drupalGet($path); + // Ensure administration pages language settings widget is not available. + $this->assertNoFieldById('edit-preferred-admin-langcode', '', 'Administration pages language selector not available.'); + } + + /** + * Tests that admin language is configurable only if admin language negotiation + * is enabled. + */ + function testUserAdminLanguageConfigurationNotAvailableWithoutAdminLanguageNegotiation() { + $this->drupalLogin($this->admin_user); + $path = 'user/' . $this->admin_user->uid . '/edit'; + $this->drupalGet($path); + // Ensure administration pages language settings widget is not available. + $this->assertNoFieldById('edit-preferred-admin-langcode', '', 'Administration pages language selector not available.'); + } + + /** + * Tests that the admin language is configurable only for admins. + */ + function testUserAdminLanguageConfigurationAvailableIfAdminLanguageNegotiationIsEnabled() { + $this->drupalLogin($this->admin_user); + $this->addCustomLanguage(); + $this->setLanguageNegotiation(); + $path = 'user/' . $this->admin_user->uid . '/edit'; + $this->drupalGet($path); + // Ensure administration pages language settings widget is available for admin. + $this->assertFieldById('edit-preferred-admin-langcode', 'en', 'Administration pages language selector available for admins.'); + + // Ensure administration pages language settings widget is not available + // for regular users. + $this->drupalLogin($this->regular_user); + $path = 'user/' . $this->regular_user->uid . '/edit'; + $this->drupalGet($path); + $this->assertNoFieldById('edit-preferred-admin-langcode', '', 'Administration pages language selector not available for regular user.'); + } + + /** + * Helper method for setting the language user admin negotiation. + */ + function setLanguageNegotiation() { + $edit = array( + 'language_interface[enabled][language-user-admin]' => TRUE, + 'language_interface[enabled][language-url]' => TRUE, + 'language_interface[weight][language-user-admin]' => -8, + 'language_interface[weight][language-url]' => -10, + ); + $this->drupalPost('admin/config/regional/language/detection', $edit, t('Save settings')); + } + + /** + * Helper meethod for adding a custom language. + */ + function addCustomLanguage() { + $langcode = 'xx'; + // The English name for the language. + $name = $this->randomName(16); + $edit = array( + 'predefined_langcode' => 'custom', + 'langcode' => $langcode, + 'name' => $name, + 'direction' => '0', + ); + $this->drupalPost('admin/config/regional/language/add', $edit, t('Add custom language')); + } +}