/** * Renders a list with all custom links. * * @return array * The list to be rendered. */ public function render() { $build['xmlsitemap_add_custom'] = array('#type' => 'link', '#title' => t('Add custom link'), '#href' => 'admin/config/search/xmlsitemap/custom/add'); $header = array('loc' => array('data' => t('Location'), 'field' => 'loc', 'sort' => 'asc'), 'priority' => array('data' => t('Priority'), 'field' => 'priority'), 'changefreq' => array('data' => t('Change frequency'), 'field' => 'changefreq'), 'language' => array('data' => t('Language'), 'field' => 'language'), 'operations' => array('data' => t('Operations'))); $rows = array(); $destination = drupal_get_destination(); $query = db_select('xmlsitemap'); $query->fields('xmlsitemap'); $query->condition('type', 'custom'); $query->extend('Drupal\\Core\\Database\\Query\\PagerSelectExtender')->limit(50); $query->extend('Drupal\\Core\\Database\\Query\\TableSortExtender')->orderByHeader($header); $result = $query->execute(); foreach ($result as $link) { $language = $this->languageManager->getLanguage($link->language); $row = array(); $row['loc'] = $this->l($link->loc, Url::fromUri($link->loc)); $row['priority'] = number_format($link->priority, 1); $row['changefreq'] = $link->changefreq ? drupal_ucfirst(xmlsitemap_get_changefreq($link->changefreq)) : t('None'); if (isset($header['language'])) { $row['language'] = t($language->name); } $operations['edit'] = array('title' => t('Edit'), 'route_name' => 'xmlsitemap_custom.edit', 'route_parameters' => array('link' => $link->id)); $operations['delete'] = array('title' => t('Delete'), 'route_name' => 'xmlsitemap_custom.delete', 'route_parameters' => array('link' => $link->id)); $row['operations'] = array('data' => array('#type' => 'operations', '#theme' => 'links', '#links' => $operations, '#attributes' => array('class' => array('links', 'inline')))); $rows[] = $row; } // @todo Convert to tableselect $build['xmlsitemap_custom_table'] = array('#type' => 'tableselect', '#theme' => 'table', '#header' => $header, '#rows' => $rows, '#empty' => $this->t('No custom links available. <a href="@custom_link">Add custom link</a>', array('@custom_link' => Url::fromRoute('xmlsitemap_custom.add', [], array('query' => $destination))))); $build['xmlsitemap_custom_pager'] = array('#theme' => 'pager'); return $build; }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { $form = array(); // Initialize a language list to the ones available, including English. $languages = $this->languageManager->getLanguages(); $existing_languages = array(); foreach ($languages as $langcode => $language) { $existing_languages[$langcode] = $language->getName(); } // If we have no languages available, present the list of predefined languages // only. If we do have already added languages, set up two option groups with // the list of existing and then predefined languages. if (empty($existing_languages)) { $language_options = $this->languageManager->getStandardLanguageListWithoutConfigured(); } else { $language_options = array($this->t('Existing languages') => $existing_languages, $this->t('Languages not yet added') => $this->languageManager->getStandardLanguageListWithoutConfigured()); } $form['mappings'] = array('#tree' => TRUE, '#theme' => 'language_negotiation_configure_browser_form_table'); $mappings = $this->language_get_browser_drupal_langcode_mappings(); foreach ($mappings as $browser_langcode => $drupal_langcode) { $form['mappings'][$browser_langcode] = array('browser_langcode' => array('#title' => $this->t('Browser language code'), '#title_display' => 'invisible', '#type' => 'textfield', '#default_value' => $browser_langcode, '#size' => 20, '#required' => TRUE), 'drupal_langcode' => array('#title' => $this->t('Site language'), '#title_display' => 'invisible', '#type' => 'select', '#options' => $language_options, '#default_value' => $drupal_langcode, '#required' => TRUE)); } // Add empty row. $form['new_mapping'] = array('#type' => 'details', '#title' => $this->t('Add a new mapping'), '#tree' => TRUE); $form['new_mapping']['browser_langcode'] = array('#type' => 'textfield', '#title' => $this->t('Browser language code'), '#description' => $this->t('Use language codes as <a href="@w3ctags">defined by the W3C</a> for interoperability. <em>Examples: "en", "en-gb" and "zh-hant".</em>', array('@w3ctags' => 'http://www.w3.org/International/articles/language-tags/')), '#size' => 20); $form['new_mapping']['drupal_langcode'] = array('#type' => 'select', '#title' => $this->t('Site language'), '#options' => $language_options); return parent::buildForm($form, $form_state); }
/** * {@inheritdoc} */ public function buildRow(EntityInterface $entity) { $row['label'] = $this->getLabel($entity); if ($this->moduleHandler->moduleExists('language')) { if (isset($entity->context['language'])) { $language = $this->languageManager->getLanguage($entity->context['language']); $row['language'] = $language->getName(); } else { $row['language'] = $this->t('Undefined'); } } $row['id'] = $entity->id(); // You probably want a few more properties here... return $row + parent::buildRow($entity); }
/** * Deletes a language override. * * This will invoke LocaleConfigSubscriber through the event dispatcher. To * make sure the configuration was persisted correctly, the configuration * value is checked. Because LocaleConfigSubscriber temporarily disables the * override state of the configuration factory we check that the correct value * is restored afterwards. * * @param string $config_name * The configuration name. * @param string $key * The configuration key. * @param string $source_value * The source configuration value to verify the correct value is returned * from the configuration factory after the deletion. */ protected function deleteLanguageOverride($config_name, $key, $source_value) { $translation_override = $this->languageManager->getLanguageConfigOverride($this->langcode, $config_name); $translation_override->clear($key)->save(); $this->configFactory->reset($config_name); $this->assertConfigValue($config_name, $key, $source_value); }
/** * Initializes the local cache for language path processors. * * @param string $scope * The scope of the processors: "inbound" or "outbound". */ protected function initProcessors($scope) { $interface = '\\Drupal\\Core\\PathProcessor\\' . Unicode::ucfirst($scope) . 'PathProcessorInterface'; $this->processors[$scope] = array(); $weights = []; foreach ($this->languageManager->getLanguageTypes() as $type) { foreach ($this->negotiator->getNegotiationMethods($type) as $method_id => $method) { if (!isset($this->processors[$scope][$method_id])) { $reflector = new \ReflectionClass($method['class']); if ($reflector->implementsInterface($interface)) { $this->processors[$scope][$method_id] = $this->negotiator->getNegotiationMethodInstance($method_id); $weights[$method_id] = $method['weight']; } } } } // Sort the processors list, so that their functions are called in the // order specified by the weight of the methods. uksort($this->processors[$scope], function ($method_id_a, $method_id_b) use($weights) { $a_weight = $weights[$method_id_a]; $b_weight = $weights[$method_id_b]; if ($a_weight == $b_weight) { return 0; } return $a_weight < $b_weight ? -1 : 1; }); }
/** * Sets the request on the language manager. * * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event * The Event to process. */ public function onKernelRequestLanguage(GetResponseEvent $event) { if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) { $request = $event->getRequest(); $this->negotiator->setCurrentUser($this->currentUser); $this->negotiator->reset(); if ($this->languageManager instanceof ConfigurableLanguageManagerInterface) { $this->languageManager->setNegotiator($this->negotiator); $this->languageManager->setConfigOverrideLanguage($this->languageManager->getCurrentLanguage()); } // After the language manager has initialized, set the default langcode // for the string translations. $langcode = $this->languageManager->getCurrentLanguage()->getId(); $this->translation->setDefaultLangcode($langcode); } }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state, $link = '') { $query = db_select('xmlsitemap'); $query->fields('xmlsitemap'); $query->condition('type', 'custom'); $query->condition('id', $link); $result = $query->execute(); $link = $result->fetchAssoc(); if (!$link) { drupal_set_message(t('No valid custom link specified.'), 'error'); return new RedirectResponse('/admin/config/search/xmlsitemap/custom/'); } else { $this->custom_link = $link; } $query = db_select('xmlsitemap', 'x'); $query->addExpression('MAX(id)'); $id = $query->execute()->fetchField(); $this->custom_link += array('id' => $id + 1, 'loc' => '', 'priority' => XMLSITEMAP_PRIORITY_DEFAULT, 'lastmod' => 0, 'changefreq' => 0, 'changecount' => 0, 'language' => LanguageInterface::LANGCODE_NOT_SPECIFIED); $form['type'] = array('#type' => 'value', '#value' => 'custom'); $form['id'] = array('#type' => 'value', '#value' => $this->custom_link['id']); $form['loc'] = array('#type' => 'textfield', '#title' => t('Path to link'), '#field_prefix' => Url::fromRoute('<front>', [], array('absolute' => TRUE)), '#default_value' => $this->custom_link['loc'], '#required' => TRUE, '#size' => 30); $form['priority'] = array('#type' => 'select', '#title' => t('Priority'), '#options' => xmlsitemap_get_priority_options(), '#default_value' => number_format($this->custom_link['priority'], 1), '#description' => t('The priority of this URL relative to other URLs on your site.')); $form['changefreq'] = array('#type' => 'select', '#title' => t('Change frequency'), '#options' => array(0 => t('None')) + xmlsitemap_get_changefreq_options(), '#default_value' => $link['changefreq'], '#description' => t('How frequently the page is likely to change. This value provides general information to search engines and may not correlate exactly to how often they crawl the page.')); $languages = $this->languageManager->getLanguages(); $languages_list = array(); foreach ($languages as $key => $value) { $languages_list[$key] = $value->getName(); } $form['language'] = array('#type' => 'select', '#title' => t('Language'), '#default_value' => $this->custom_link['language'], '#options' => array(LanguageInterface::LANGCODE_NOT_SPECIFIED => t('Language neutral')) + $languages_list, '#access' => $languages_list); $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Save'), '#weight' => 5); $cancel_link = Url::fromRoute('xmlsitemap_custom.list'); $form['actions']['cancel'] = array('#markup' => l(t('Cancel'), $cancel_link), '#weight' => 10); return $form; }
/** * {@inheritdoc} */ function updateConfiguration(array $types) { // Ensure that we are getting the defined language negotiation information. // An invocation of \Drupal\Core\Extension\ModuleHandler::install() or // \Drupal\Core\Extension\ModuleHandler::uninstall() could invalidate the // cached information. $this->negotiatorManager->clearCachedDefinitions(); $this->languageManager->reset(); $language_types = array(); $language_types_info = $this->languageManager->getDefinedLanguageTypesInfo(); $method_definitions = $this->getNegotiationMethods(); foreach ($language_types_info as $type => $info) { $configurable = in_array($type, $types); // The default language negotiation settings, if available, are stored in // $info['fixed']. $has_default_settings = !empty($info['fixed']); // Check whether the language type is unlocked. Only the status of // unlocked language types can be toggled between configurable and // non-configurable. if (empty($info['locked'])) { if (!$configurable && !$has_default_settings) { // If we have an unlocked non-configurable language type without // default language negotiation settings, we use the values // negotiated for the interface language which, should always be // available. $method_weights = array(LanguageNegotiationUI::METHOD_ID); $method_weights = array_flip($method_weights); $this->saveConfiguration($type, $method_weights); } } else { // The language type is locked. Locked language types with default // settings are always considered non-configurable. In turn if default // settings are missing, the language type is always considered // configurable. // If the language type is locked we can just store its default language // negotiation settings if it has some, since it is not configurable. if ($has_default_settings) { $method_weights = array(); // Default settings are in $info['fixed']. foreach ($info['fixed'] as $weight => $method_id) { if (isset($method_definitions[$method_id])) { $method_weights[$method_id] = $weight; } } $this->saveConfiguration($type, $method_weights); } else { // It was missing default settings, so force it to be configurable. $configurable = TRUE; } } // Accumulate information for each language type so it can be saved later. $language_types[$type] = $configurable; } // Store the language type configuration. $config = array('configurable' => array_keys(array_filter($language_types)), 'all' => array_keys($language_types)); $this->languageManager->saveLanguageTypesConfiguration($config); }
/** * Compute the list of configuration names that match predefined languages. * * @return array * The list of configuration names that match predefined languages. */ protected function predefinedConfiguredLanguages() { $names = $this->configStorage->listAll('language.entity.'); $predefined_languages = $this->languageManager->getStandardLanguageList(); foreach ($names as $id => $name) { $langcode = str_replace('language.entity.', '', $name); if (!isset($predefined_languages[$langcode])) { unset($names[$id]); } } return array_values($names); }
/** * Updates all configuration translations for the names / languages provided. * * To be used when interface translation changes result in the need to update * configuration translations to keep them in sync. * * @param array $names * Array of names of configuration objects to update. * @param array $langcodes * (optional) Array of language codes to update. Defaults to all * configurable languages. * * @return int * Total number of configuration override and active configuration objects * updated (saved or removed). */ public function updateConfigTranslations(array $names, array $langcodes = array()) { $langcodes = $langcodes ? $langcodes : array_keys($this->languageManager->getLanguages()); $count = 0; foreach ($names as $name) { $translatable = $this->getTranslatableDefaultConfig($name); if (empty($translatable)) { // If there is nothing translatable in this configuration or not // supported, skip it. continue; } $active_langcode = $this->getActiveConfigLangcode($name); $active = $this->configStorage->read($name); foreach ($langcodes as $langcode) { $processed = $this->processTranslatableData($name, $active, $translatable, $langcode); if ($langcode != $active_langcode) { // If the language code is not the same as the active storage // language, we should update a configuration override. if (!empty($processed)) { // Update translation data in configuration override. $this->saveTranslationOverride($name, $langcode, $processed); $count++; } else { $override = $this->languageManager->getLanguageConfigOverride($langcode, $name); if (!$override->isNew()) { $data = $this->filterOverride($override->get(), $translatable); if (empty($data)) { // Delete language override if there is no data left at all. // This means all prior translations in the override were locale // managed. $this->deleteTranslationOverride($name, $langcode); $count++; } else { // If there were translatable elements besides locale managed // items, save with only those, and remove the ones managed // by locale only. $this->saveTranslationOverride($name, $langcode, $data); $count++; } } } } elseif (locale_is_translatable($langcode)) { // If the language code is the active storage language, we should // update. If it is English, we should only update if English is also // translatable. $active = NestedArray::mergeDeepArray(array($active, $processed), TRUE); $this->saveTranslationActive($name, $active); $count++; } } } return $count; }
/** * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { foreach ($this->mapper->getConfigNames() as $name) { $this->languageManager->getLanguageConfigOverride($this->language->id, $name)->delete(); } // Flush all persistent caches. $this->moduleHandler->invokeAll('cache_flush'); foreach (Cache::getBins() as $service_id => $cache_backend) { $cache_backend->deleteAll(); } drupal_set_message($this->t('@language translation of %label was deleted', array('%label' => $this->mapper->getTitle(), '@language' => $this->language->name))); $form_state['redirect_route'] = $this->getCancelUrl(); }
/** * Initializes the local cache for language path processors. * * @param string $scope * The scope of the processors: "inbound" or "outbound". */ protected function initProcessors($scope) { $interface = '\\Drupal\\Core\\PathProcessor\\' . Unicode::ucfirst($scope) . 'PathProcessorInterface'; $this->processors[$scope] = array(); foreach ($this->languageManager->getLanguageTypes() as $type) { foreach ($this->negotiator->getNegotiationMethods($type) as $method_id => $method) { if (!isset($this->processors[$scope][$method_id])) { $reflector = new \ReflectionClass($method['class']); if ($reflector->implementsInterface($interface)) { $this->processors[$scope][$method_id] = $this->negotiator->getNegotiationMethodInstance($method_id); } } } } }
/** * Updates all configuration translations for the names / languages provided. * * To be used when interface translation changes result in the need to update * configuration translations to keep them in sync. * * @param array $names * Array of names of configuration objects to update. * @param array $langcodes * (optional) Array of language codes to update. Defaults to all * configurable languages. * * @return int * Total number of configuration override and active configuration objects * updated (saved or removed). */ public function updateConfigTranslations(array $names, array $langcodes = array()) { $langcodes = $langcodes ? $langcodes : array_keys($this->languageManager->getLanguages()); $count = 0; foreach ($names as $name) { $translatable = $this->getTranslatableDefaultConfig($name); if (empty($translatable)) { // If there is nothing translatable in this configuration or not // supported, skip it. continue; } $active_langcode = $this->getActiveConfigLangcode($name); $active = $this->configStorage->read($name); foreach ($langcodes as $langcode) { $processed = $this->processTranslatableData($name, $active, $translatable, $langcode); // If the language code is not the same as the active storage // language, we should update the configuration override. if ($langcode != $active_langcode) { $override = $this->languageManager->getLanguageConfigOverride($langcode, $name); // Filter out locale managed configuration keys so that translations // removed from Locale will be reflected in the config override. $data = $this->filterOverride($override->get(), $translatable); if (!empty($processed)) { // Merge in the Locale managed translations with existing data. $data = NestedArray::mergeDeepArray(array($data, $processed), TRUE); } if (empty($data) && !$override->isNew()) { // The configuration override contains Locale overrides that no // longer exist. $this->deleteTranslationOverride($name, $langcode); $count++; } elseif (!empty($data)) { // Update translation data in configuration override. $this->saveTranslationOverride($name, $langcode, $data); $count++; } } elseif (locale_is_translatable($langcode)) { // If the language code is the active storage language, we should // update. If it is English, we should only update if English is also // translatable. $active = NestedArray::mergeDeepArray(array($active, $processed), TRUE); $this->saveTranslationActive($name, $active); $count++; } } } return $count; }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { // Add language, if not yet supported. $language = $this->languageManager->getLanguage($form_state->getValue('langcode')); if (empty($language)) { $language = ConfigurableLanguage::createFromLangcode($form_state->getValue('langcode')); $language->save(); drupal_set_message($this->t('The language %language has been created.', array('%language' => $this->t($language->label())))); } $options = array('langcode' => $form_state->getValue('langcode'), 'overwrite_options' => $form_state->getValue('overwrite_options'), 'customized' => $form_state->getValue('customized') ? LOCALE_CUSTOMIZED : LOCALE_NOT_CUSTOMIZED); $this->moduleHandler->loadInclude('locale', 'bulk.inc'); $file = locale_translate_file_attach_properties($this->file, $options); $batch = locale_translate_batch_build(array($file->uri => $file), $options); batch_set($batch); $form_state->setRedirect('locale.translate_page'); }
/** * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { // Add language, if not yet supported. $language = $this->languageManager->getLanguage($form_state['values']['langcode']); if (empty($language)) { $language = new Language(array('id' => $form_state['values']['langcode'])); $language = language_save($language); drupal_set_message($this->t('The language %language has been created.', array('%language' => $this->t($language->name)))); } $options = array('langcode' => $form_state['values']['langcode'], 'overwrite_options' => $form_state['values']['overwrite_options'], 'customized' => $form_state['values']['customized'] ? LOCALE_CUSTOMIZED : LOCALE_NOT_CUSTOMIZED); $this->moduleHandler->loadInclude('locale', 'bulk.inc'); $file = locale_translate_file_attach_properties($this->file, $options); $batch = locale_translate_batch_build(array($file->uri => $file), $options); batch_set($batch); $form_state['redirect_route']['route_name'] = 'locale.translate_page'; }
/** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { $configurable = $this->languageTypes->get('configurable'); $form = array('#theme' => 'language_negotiation_configure_form', '#language_types_info' => $this->languageManager->getDefinedLanguageTypesInfo(), '#language_negotiation_info' => $this->negotiator->getNegotiationMethods()); $form['#language_types'] = array(); foreach ($form['#language_types_info'] as $type => $info) { // Show locked language types only if they are configurable. if (empty($info['locked']) || in_array($type, $configurable)) { $form['#language_types'][] = $type; } } foreach ($form['#language_types'] as $type) { $this->configureFormTable($form, $type); } $form['actions'] = array('#type' => 'actions'); $form['actions']['submit'] = array('#type' => 'submit', '#button_type' => 'primary', '#value' => $this->t('Save settings')); return $form; }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $form_values = $form_state->getValue(array('translation', 'config_names')); foreach ($this->mapper->getConfigNames() as $name) { $schema = $this->typedConfigManager->get($name); // Set configuration values based on form submission and source values. $base_config = $this->configFactory()->getEditable($name); $config_translation = $this->languageManager->getLanguageConfigOverride($this->language->getId(), $name); $element = $this->createFormElement($schema); $element->setConfig($base_config, $config_translation, $form_values[$name]); // If no overrides, delete language specific configuration file. $saved_config = $config_translation->get(); if (empty($saved_config)) { $config_translation->delete(); } else { $config_translation->save(); } } $form_state->setRedirect($this->mapper->getOverviewRoute(), $this->mapper->getOverviewRouteParameters()); }
/** * {@inheritdoc} */ public function saveTranslation(JobItemInterface $job_item, $target_langcode) { try { $config_mapper = $this->getMapper($job_item); } catch (TMGMTException $e) { $job_item->addMessage('The entity %id of type %type does not exist, the job can not be completed.', array('%id' => $job_item->getItemId(), '%type' => $job_item->getItemType()), 'error'); return FALSE; } $data = $job_item->getData(); $config_names = $config_mapper->getConfigNames(); // We need to refactor the array just as we did in getData. if (count($config_names) == 1) { $data[$config_names[0]] = $data; } else { // Replace the arrays keys back. foreach ($data as $key => $value) { $new_key = str_replace('__', '.', $key); $data[$new_key] = $value; unset($data[$key]); } } foreach ($config_mapper->getConfigNames() as $name) { $schema = $this->typedConfig->get($name); // Set configuration values based on form submission and source values. $base_config = $this->configFactoryManager->getEditable($name); $config_translation = $this->languageManager->getLanguageConfigOverride($target_langcode, $name); $element = ConfigTranslationFormBase::createFormElement($schema); $element->setConfig($base_config, $config_translation, $this->convertToTranslation($data[$name])); // If no overrides, delete language specific configuration file. $saved_config = $config_translation->get(); if (empty($saved_config)) { $config_translation->delete(); } else { $config_translation->save(); } } return TRUE; }
/** * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { $form_values = $form_state['values']['config_names']; // For the form submission handling, use the raw data. $config_factory = $this->configFactory(); $old_state = $config_factory->getOverrideState(); $config_factory->setOverrideState(FALSE); foreach ($this->mapper->getConfigNames() as $name) { // Set configuration values based on form submission and source values. $base_config = $config_factory->get($name); $config_translation = $this->languageManager->getLanguageConfigOverride($this->language->id, $name); $locations = $this->localeStorage->getLocations(array('type' => 'configuration', 'name' => $name)); $this->setConfig($this->language, $base_config, $config_translation, $form_values[$name], !empty($locations)); // If no overrides, delete language specific configuration file. $saved_config = $config_translation->get(); if (empty($saved_config)) { $config_translation->delete(); } else { $config_translation->save(); } } $config_factory->setOverrideState($old_state); $form_state['redirect_route'] = array('route_name' => $this->mapper->getOverviewRoute(), 'route_parameters' => $this->mapper->getOverviewRouteParameters()); }
/** * Checks whether a language has configuration translation. * * @param string $name * Configuration name. * @param \Drupal\Core\Language\LanguageInterface $language * A language object. * * @return bool * A boolean indicating if a language has configuration translations. */ public function hasTranslation($name, LanguageInterface $language) { $translation = $this->languageManager->getLanguageConfigOverride($language->id, $name); return !$translation->isNew(); }
/** * Ensures configuration was saved correctly. * * @param string $config_name * The configuration name. * @param string $key * The configuration key. * @param string $value * The configuration value. * @param string $langcode * The language code. * * @return bool * TRUE if the assertion succeeded, FALSE otherwise. */ protected function assertConfigOverride($config_name, $key, $value, $langcode) { $config_langcode = $this->configFactory->getEditable($config_name)->get('langcode'); $override = $this->languageManager->getLanguageConfigOverride($langcode, $config_name); return $this->assertNotEqual($config_langcode, $langcode) && $this->assertEqual($override->get($key), $value); }