/** * Functional tests for adding, editing and deleting languages. */ public function testLanguageConfiguration() { // Create user with permissions to add and remove languages. $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages')); $this->drupalLogin($admin_user); // Add custom language. $edit = array('predefined_langcode' => 'custom'); $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); // Test validation on missing values. $this->assertText(t('!name field is required.', array('!name' => t('Language code')))); $this->assertText(t('!name field is required.', array('!name' => t('Language name in English')))); $empty_language = new Language(); $this->assertFieldChecked('edit-direction-' . $empty_language->getDirection(), 'Consistent usage of language direction.'); $this->assertUrl(\Drupal::url('language.add', array(), array('absolute' => TRUE)), [], 'Correct page redirection.'); // Test validation of invalid values. $edit = array('predefined_langcode' => 'custom', 'langcode' => 'white space', 'label' => '<strong>evil markup</strong>', 'direction' => LanguageInterface::DIRECTION_LTR); $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); $this->assertRaw(t('%field may only contain characters a-z, underscores, or hyphens.', array('%field' => t('Language code')))); $this->assertRaw(t('%field cannot contain any markup.', array('%field' => t('Language name in English')))); $this->assertUrl(\Drupal::url('language.add', array(), array('absolute' => TRUE)), [], 'Correct page redirection.'); // Test validation of existing language values. $edit = array('predefined_langcode' => 'custom', 'langcode' => 'de', 'label' => 'German', 'direction' => LanguageInterface::DIRECTION_LTR); // Add the language the first time. $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); $this->assertRaw(t('The language %language has been created and can now be used.', array('%language' => $edit['label']))); $this->assertUrl(\Drupal::url('language.admin_overview', array(), array('absolute' => TRUE)), [], 'Correct page redirection.'); // Add the language a second time and confirm that this is not allowed. $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); $this->assertRaw(t('The language %language (%langcode) already exists.', array('%language' => $edit['label'], '%langcode' => $edit['langcode']))); $this->assertUrl(\Drupal::url('language.add', array(), array('absolute' => TRUE)), [], 'Correct page redirection.'); }
public function testOtherIsNotDefault() { // Forces a full bootstrap. $this->getDrupalContainer(); $fr = new Language(); $fr->language = 'fr'; $this->assertFalse($fr->isDefault()); }
/** * Tests that default and custom attributes are handled correctly on links. */ function testLinkAttributes() { /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = $this->container->get('renderer'); // Test that hreflang is added when a link has a known language. $language = new Language(array('id' => 'fr', 'name' => 'French')); $hreflang_link = array('#type' => 'link', '#options' => array('language' => $language), '#url' => Url::fromUri('https://www.drupal.org'), '#title' => 'bar'); $langcode = $language->getId(); // Test that the default hreflang handling for links does not override a // hreflang attribute explicitly set in the render array. $hreflang_override_link = $hreflang_link; $hreflang_override_link['#options']['attributes']['hreflang'] = 'foo'; $rendered = $renderer->renderRoot($hreflang_link); $this->assertTrue($this->hasAttribute('hreflang', $rendered, $langcode), format_string('hreflang attribute with value @langcode is present on a rendered link when langcode is provided in the render array.', array('@langcode' => $langcode))); $rendered = $renderer->renderRoot($hreflang_override_link); $this->assertTrue($this->hasAttribute('hreflang', $rendered, 'foo'), format_string('hreflang attribute with value @hreflang is present on a rendered link when @hreflang is provided in the render array.', array('@hreflang' => 'foo'))); // Test the active class in links produced by // \Drupal\Core\Utility\LinkGeneratorInterface::generate() and #type 'link'. $options_no_query = array(); $options_query = array('query' => array('foo' => 'bar', 'one' => 'two')); $options_query_reverse = array('query' => array('one' => 'two', 'foo' => 'bar')); // Test #type link. $path = 'common-test/type-link-active-class'; $this->drupalGet($path, $options_no_query); $links = $this->xpath('//a[@href = :href and contains(@class, :class)]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_no_query)->toString(), ':class' => 'is-active')); $this->assertTrue(isset($links[0]), 'A link generated by the link generator to the current page is marked active.'); $links = $this->xpath('//a[@href = :href and not(contains(@class, :class))]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_query)->toString(), ':class' => 'is-active')); $this->assertTrue(isset($links[0]), 'A link generated by the link generator to the current page with a query string when the current page has no query string is not marked active.'); $this->drupalGet($path, $options_query); $links = $this->xpath('//a[@href = :href and contains(@class, :class)]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_query)->toString(), ':class' => 'is-active')); $this->assertTrue(isset($links[0]), 'A link generated by the link generator to the current page with a query string that matches the current query string is marked active.'); $links = $this->xpath('//a[@href = :href and contains(@class, :class)]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_query_reverse)->toString(), ':class' => 'is-active')); $this->assertTrue(isset($links[0]), 'A link generated by the link generator to the current page with a query string that has matching parameters to the current query string but in a different order is marked active.'); $links = $this->xpath('//a[@href = :href and not(contains(@class, :class))]', array(':href' => Url::fromRoute('common_test.l_active_class', [], $options_no_query)->toString(), ':class' => 'is-active')); $this->assertTrue(isset($links[0]), 'A link generated by the link generator to the current page without a query string when the current page has a query string is not marked active.'); // Test adding a custom class in links produced by // \Drupal\Core\Utility\LinkGeneratorInterface::generate() and #type 'link'. // Test the link generator. $class_l = $this->randomMachineName(); $link_l = \Drupal::l($this->randomMachineName(), new Url('<current>', [], ['attributes' => ['class' => [$class_l]]])); $this->assertTrue($this->hasAttribute('class', $link_l, $class_l), format_string('Custom class @class is present on link when requested by l()', array('@class' => $class_l))); // Test #type. $class_theme = $this->randomMachineName(); $type_link = array('#type' => 'link', '#title' => $this->randomMachineName(), '#url' => Url::fromRoute('<current>'), '#options' => array('attributes' => array('class' => array($class_theme)))); $link_theme = $renderer->renderRoot($type_link); $this->assertTrue($this->hasAttribute('class', $link_theme, $class_theme), format_string('Custom class @class is present on link when requested by #type', array('@class' => $class_theme))); }
protected function doTestBasicTranslation() { parent::doTestBasicTranslation(); $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); foreach ($this->langcodes as $langcode) { if ($entity->hasTranslation($langcode)) { $language = new Language(array('id' => $langcode)); // Request the front page in this language and assert that the right // translation shows up in the shortcut list with the right path. $this->drupalGet('<front>', array('language' => $language)); $expected_path = \Drupal::urlGenerator()->generateFromRoute('user.page', array(), array('language' => $language)); $label = $entity->getTranslation($langcode)->label(); $elements = $this->xpath('//nav[contains(@class, "toolbar-lining")]/ul[@class="toolbar-menu"]/li/a[contains(@href, :href) and normalize-space(text())=:label]', array(':href' => $expected_path, ':label' => $label)); $this->assertTrue(!empty($elements), format_string('Translated @language shortcut link @label found.', array('@label' => $label, '@language' => $language->getName()))); } } }
/** * Functional tests for adding, editing and deleting languages. */ public function testLanguageConfiguration() { // Create user with permissions to add and remove languages. $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages')); $this->drupalLogin($admin_user); // Add custom language. $edit = array('predefined_langcode' => 'custom'); $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); // Test validation on missing values. $this->assertText(t('!name field is required.', array('!name' => t('Language code')))); $this->assertText(t('!name field is required.', array('!name' => t('Language name')))); $empty_language = new Language(); $this->assertFieldChecked('edit-direction-' . $empty_language->getDirection(), 'Consistent usage of language direction.'); $this->assertUrl(\Drupal::url('language.add', array(), array('absolute' => TRUE)), [], 'Correct page redirection.'); // Test validation of invalid values. $edit = array('predefined_langcode' => 'custom', 'langcode' => 'white space', 'label' => '<strong>evil markup</strong>', 'direction' => LanguageInterface::DIRECTION_LTR); $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); $this->assertRaw(t('%field must be a valid language tag as <a href="@url">defined by the W3C</a>.', array('%field' => t('Language code'), '@url' => 'http://www.w3.org/International/articles/language-tags/'))); $this->assertRaw(t('%field cannot contain any markup.', array('%field' => t('Language name')))); $this->assertUrl(\Drupal::url('language.add', array(), array('absolute' => TRUE)), [], 'Correct page redirection.'); // Test adding a custom language with a numeric region code. $edit = array('predefined_langcode' => 'custom', 'langcode' => 'es-419', 'label' => 'Latin American Spanish', 'direction' => LanguageInterface::DIRECTION_LTR); $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); $this->assertRaw(t('The language %language has been created and can now be used.', array('%language' => $edit['label']))); $this->assertUrl(\Drupal::url('entity.configurable_language.collection', array(), array('absolute' => TRUE)), [], 'Correct page redirection.'); // Test validation of existing language values. $edit = array('predefined_langcode' => 'custom', 'langcode' => 'de', 'label' => 'German', 'direction' => LanguageInterface::DIRECTION_LTR); // Add the language the first time. $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); $this->assertRaw(t('The language %language has been created and can now be used.', array('%language' => $edit['label']))); $this->assertUrl(\Drupal::url('entity.configurable_language.collection', array(), array('absolute' => TRUE)), [], 'Correct page redirection.'); // Add the language a second time and confirm that this is not allowed. $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); $this->assertRaw(t('The language %language (%langcode) already exists.', array('%language' => $edit['label'], '%langcode' => $edit['langcode']))); $this->assertUrl(\Drupal::url('language.add', array(), array('absolute' => TRUE)), [], 'Correct page redirection.'); }
/** * Provides data for testSortArrayOfLanguages. * * @return array * An array of test data. */ public function providerTestSortArrayOfLanguages() { $language9A = new Language(); $language9A->setName('A'); $language9A->setWeight(9); $language9A->setId('dd'); $language10A = new Language(); $language10A->setName('A'); $language10A->setWeight(10); $language10A->setId('ee'); $language10B = new Language(); $language10B->setName('B'); $language10B->setWeight(10); $language10B->setId('ff'); return array(array(array($language9A->getId() => $language9A, $language10B->getId() => $language10B), array($language9A->getId(), $language10B->getId())), array(array($language10B->getId() => $language10B, $language9A->getId() => $language9A), array($language9A->getId(), $language10B->getId())), array(array($language10A->getId() => $language10A, $language10B->getId() => $language10B), array($language10A->getId(), $language10B->getId())), array(array($language10B->getId() => $language10B, $language10A->getId() => $language10A), array($language10A->getId(), $language10B->getId()))); }
/** * {@inheritdoc} */ public function getNativeLanguages() { $languages = $this->getLanguages(LanguageInterface::STATE_CONFIGURABLE); $natives = array(); $original_language = $this->getConfigOverrideLanguage(); foreach ($languages as $langcode => $language) { $this->setConfigOverrideLanguage($language); $natives[$langcode] = ConfigurableLanguage::load($langcode); } $this->setConfigOverrideLanguage($original_language); Language::sort($natives); return $natives; }
/** * Tests the getAliasByPath cache when a different language is requested. * * @covers ::getAliasByPath * @covers ::writeCache */ public function testGetAliasByPathCachedMissLanguage() { $path_part1 = $this->randomMachineName(); $path_part2 = $this->randomMachineName(); $path = $path_part1 . '/' . $path_part2; $alias = $this->randomMachineName(); $language = $this->setUpCurrentLanguage(); $cached_language = new Language(array('id' => 'de')); $cached_paths = array($cached_language->getId() => array($path)); $this->cache->expects($this->once())->method('get')->with($this->cacheKey)->will($this->returnValue((object) array('data' => $cached_paths))); // Simulate a request so that the preloaded paths are fetched. $this->aliasManager->setCacheKey($this->path); $this->aliasWhitelist->expects($this->any())->method('get')->with($path_part1)->will($this->returnValue(TRUE)); // The requested language is different than the cached, so this will // need to load. $this->aliasStorage->expects($this->never())->method('preloadPathAlias'); $this->aliasStorage->expects($this->once())->method('lookupPathAlias')->with($path, $language->getId())->will($this->returnValue($alias)); $this->assertEquals($alias, $this->aliasManager->getAliasByPath($path)); // Call it twice to test the static cache. $this->assertEquals($alias, $this->aliasManager->getAliasByPath($path)); // This needs to write out the cache. $expected_new_cache = array($cached_language->getId() => array($path), $language->getId() => array($path)); $this->cache->expects($this->once())->method('set')->with($this->cacheKey, $expected_new_cache, (int) $_SERVER['REQUEST_TIME'] + 60 * 60 * 24); $this->aliasManager->writeCache(); }
/** * Tests negotiationMethodId getter and setter methods. * * @covers ::getNegotiationMethodId() * @covers ::setNegotiationMethodId() */ public function testGetNegotiationMethodId() { $method_id = $this->randomName(); $this->assertSame($this->language, $this->language->setNegotiationMethodId($method_id)); $this->assertSame($method_id, $this->language->getNegotiationMethodId()); }
/** * Provides data for testSortArrayOfLanguages. * * @return array * An array of test data. */ public function providerTestSortArrayOfLanguages() { $language9A = new Language(array('id' => 'dd', 'name' => 'A', 'weight' => 9)); $language10A = new Language(array('id' => 'ee', 'name' => 'A', 'weight' => 10)); $language10B = new Language(array('id' => 'ff', 'name' => 'B', 'weight' => 10)); return array(array(array($language9A->getId() => $language9A, $language10B->getId() => $language10B), array($language9A->getId(), $language10B->getId())), array(array($language10B->getId() => $language10B, $language9A->getId() => $language9A), array($language9A->getId(), $language10B->getId())), array(array($language10A->getId() => $language10A, $language10B->getId() => $language10B), array($language10A->getId(), $language10B->getId())), array(array($language10B->getId() => $language10B, $language10A->getId() => $language10A), array($language10A->getId(), $language10B->getId()))); }
/** * Tests ConfigNamesMapper::hasTranslation(). * * @param array $mock_return_values * An array of values that the mocked configuration mapper manager should * return for hasTranslation(). * @param bool $expected * The expected return value of ConfigNamesMapper::hasTranslation(). * * @dataProvider providerTestHasTranslation */ public function testHasTranslation(array $mock_return_values, $expected) { $language = new Language(); // As the configuration names are arbitrary, simply use integers. $config_names = range(1, count($mock_return_values)); $this->configNamesMapper->setConfigNames($config_names); $map = array(); foreach ($config_names as $i => $config_name) { $map[] = array($config_name, $language->getId(), $mock_return_values[$i]); } $this->localeConfigManager->expects($this->any())->method('hasTranslation')->will($this->returnValueMap($map)); $result = $this->configNamesMapper->hasTranslation($language); $this->assertSame($expected, $result); }
/** * {@inheritdoc} */ protected function viewValue(FieldItemInterface $item) { $settings = $this->getSettings(); $langcode = $item->value; // Do NOT use the languagemanager, since it only uses installed languages. // $language_manager = \Drupal::languageManager(); // $language = $language_manager->getLanguage($langcode); // Does not work for e.g. Danish (da). $language = new Language(array('id' => $langcode)); // Create the markup for this value. $markup = array(); /* if (!empty($settings['format']['icon']) && \Drupal::moduleHandler()->moduleExists('languageicons')) { // Add a language icon. We might better use languageicons_link_add(). // @TODO: doesn't work for the Widget, even though hook_options_list says the <img>-tab is allowed. $variables = array( 'language' => $language, // TODO: what happens if no icon for this language code. 'title' => $item->getName(), //['name'], ); $markup[] = theme_languageicons_icon($variables); } */ if (!empty($settings['format']['iso'])) { $markup[] = $langcode; } if (!empty($settings['format']['name'])) { $markup[] = t($language->getName()); } if (!empty($settings['format']['name_native'])) { // @todo: Create feature request to add function to D8 core. $markup[] = empty($settings['format']['name']) ? $item->getNativeName() : '(' . $item->getNativeName() . ')'; } if (empty($markup)) { $markup[] = t($language->getName()); } else { $markup = implode(' ', $markup); } // The text value has no text format assigned to it, so the user input // should equal the output, including newlines. return ['#context' => ['value' => $item->value], '#type' => 'processed_text', '#text' => $markup, '#format' => $item->format, '#langcode' => $langcode]; }
/** * {@inheritdoc} */ public function getLanguages($flags = BaseLanguageInterface::STATE_CONFIGURABLE) { if (!isset($this->languages)) { // Prepopulate the language list with the default language to keep things // working even if we have no configuration. $default = $this->getDefaultLanguage(); $this->languages = array($default->id => $default); // Retrieve the config storage to list available languages. $prefix = 'language.entity.'; $config_ids = $this->configFactory->listAll($prefix); // Instantiate languages from config objects. $weight = 0; foreach ($this->configFactory->loadMultiple($config_ids) as $config) { $data = $config->get(); $langcode = $data['id']; // Initialize default property so callers have an easy reference and can // save the same object without data loss. $data['default'] = $langcode == $default->id; $data['name'] = $data['label']; $this->languages[$langcode] = new Language($data); $weight = max(array($weight, $this->languages[$langcode]->weight)); } // Add locked languages, they will be filtered later if needed. $this->languages += $this->getDefaultLockedLanguages($weight); // Sort the language list by weight then title. Language::sort($this->languages); } return parent::getLanguages($flags); }