diff --git a/core/modules/language/language.local_actions.yml b/core/modules/language/language.local_actions.yml new file mode 100644 index 0000000..32c143d --- /dev/null +++ b/core/modules/language/language.local_actions.yml @@ -0,0 +1,5 @@ +language_add_local_action: + route_name: language_add + title: 'Add language' + appears_on: + - language_admin_overview diff --git a/core/modules/language/language.module b/core/modules/language/language.module index 4d2688c..4e0e4ec 100644 --- a/core/modules/language/language.module +++ b/core/modules/language/language.module @@ -78,20 +78,12 @@ function language_menu() { 'type' => MENU_DEFAULT_LOCAL_TASK, ); $items['admin/config/regional/language/add'] = array( - 'title' => 'Add language', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('language_admin_add_form'), - 'access arguments' => array('administer languages'), - 'type' => MENU_LOCAL_ACTION, - 'file' => 'language.admin.inc', + 'route_name' => 'language_add', + 'type' => MENU_SIBLING_LOCAL_TASK, ); $items['admin/config/regional/language/edit/%language'] = array( 'title' => 'Edit language', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('language_admin_edit_form', 5), - 'access callback' => 'language_access_language_edit_or_delete', - 'access arguments' => array(5), - 'file' => 'language.admin.inc', + 'route_name' => 'language_edit', ); $items['admin/config/regional/language/delete/%language'] = array( 'title' => 'Confirm delete', diff --git a/core/modules/language/language.routing.yml b/core/modules/language/language.routing.yml index e75e1ce..715ee95 100644 --- a/core/modules/language/language.routing.yml +++ b/core/modules/language/language.routing.yml @@ -19,6 +19,20 @@ language_negotiation_selected: requirements: _permission: 'administer languages' +language_add: + pattern: '/admin/config/regional/language/add' + defaults: + _entity_form: 'language_entity.add' + requirements: + _entity_create_access: 'language_entity' + +language_edit: + pattern: '/admin/config/regional/language/edit/{language_entity}' + defaults: + _entity_form: 'language_entity.edit' + requirements: + _entity_access: 'language_entity.update' + language_admin_overview: pattern: '/admin/config/regional/language' defaults: diff --git a/core/modules/language/lib/Drupal/language/Entity/Language.php b/core/modules/language/lib/Drupal/language/Entity/Language.php index 15c6a67..e652906 100644 --- a/core/modules/language/lib/Drupal/language/Entity/Language.php +++ b/core/modules/language/lib/Drupal/language/Entity/Language.php @@ -24,7 +24,11 @@ * controllers = { * "storage" = "Drupal\Core\Config\Entity\ConfigStorageController", * "list" = "Drupal\language\LanguageListController", - * "access" = "Drupal\language\LanguageAccessController" + * "access" = "Drupal\language\LanguageAccessController", + * "form" = { + * "add" = "Drupal\language\Form\LanguageAddForm", + * "edit" = "Drupal\language\Form\LanguageEditForm" + * } * }, * config_prefix = "language.entity", * entity_keys = { diff --git a/core/modules/language/lib/Drupal/language/Form/LanguageAddForm.php b/core/modules/language/lib/Drupal/language/Form/LanguageAddForm.php new file mode 100644 index 0000000..f6b2098 --- /dev/null +++ b/core/modules/language/lib/Drupal/language/Form/LanguageAddForm.php @@ -0,0 +1,144 @@ +moduleHandler->loadInclude('language', 'inc', 'language.admin'); + $predefined_languages = language_admin_predefined_list(); + + $predefined_languages['custom'] = t('Custom language...'); + $predefined_default = !empty($form_state['values']['predefined_langcode']) ? $form_state['values']['predefined_langcode'] : key($predefined_languages); + $form['predefined_langcode'] = array( + '#type' => 'select', + '#title' => t('Language name'), + '#default_value' => $predefined_default, + '#options' => $predefined_languages, + ); + $form['predefined_submit'] = array( + '#type' => 'submit', + '#value' => t('Add language'), + '#limit_validation_errors' => array(array('predefined_langcode'), array('predefined_submit')), + '#states' => array( + 'invisible' => array( + 'select#edit-predefined-langcode' => array('value' => 'custom'), + ), + ), + '#validate' => array(array($this, 'validatePredefined')), + '#submit' => array(array($this, 'submitForm')), + ); + + $form['custom_language'] = array( + '#type' => 'container', + '#states' => array( + 'visible' => array( + 'select#edit-predefined-langcode' => array('value' => 'custom'), + ), + ), + ); + $this->commonForm($form['custom_language']); + $form['custom_language']['submit'] = array( + '#type' => 'submit', + '#value' => t('Add custom language'), + '#validate' => array(array($this, 'validateCustom')), + '#submit' => array(array($this, 'submitForm')), + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + $langcode = $form_state['values']['predefined_langcode']; + if ($langcode == 'custom') { + $langcode = $form_state['values']['langcode']; + // Custom language form. + $language = new Language(array( + 'id' => $langcode, + 'name' => $form_state['values']['name'], + 'direction' => $form_state['values']['direction'], + )); + } + else { + $language = new Language(array('id' => $langcode)); + } + // Save the language and inform the user that it happened. + $language = language_save($language); + drupal_set_message(t('The language %language has been created and can now be used.', array('%language' => $language->name))); + + // Tell the user they have the option to add a language switcher block + // to their theme so they can switch between the languages. + drupal_set_message(t('Use one of the language switcher blocks to allow site visitors to switch between languages. You can enable these blocks on the block administration page.', array('@block-admin' => url('admin/structure/block')))); + $form_state['redirect'] = 'admin/config/regional/language'; + } + + /** + * {@inheritdoc} + */ + public function actions(array $form, array &$form_state) { + // No actions needed. + return array(); + } + + /** + * Validates the language addition form on custom language button. + */ + public function validateCustom(array $form, array &$form_state) { + if ($form_state['values']['predefined_langcode'] == 'custom') { + $langcode = $form_state['values']['langcode']; + // Reuse the editing form validation routine if we add a custom language. + $this->validateCommon($form['custom_language'], $form_state); + + if ($language = language_load($langcode)) { + form_error($form['custom_language']['langcode'], t('The language %language (%langcode) already exists.', array('%language' => $language->name, '%langcode' => $langcode))); + } + } + else { + form_error($form['predefined_langcode'], t('Use the Add language button to save a predefined language.')); + } + } + + /** + * Element specific validator for the Add language button. + */ + public function validatePredefined($form, &$form_state) { + $langcode = $form_state['values']['predefined_langcode']; + if ($langcode == 'custom') { + form_error($form['predefined_langcode'], t('Fill in the language details and save the language with Add custom language.')); + } + else { + if ($language = language_load($langcode)) { + form_error($form['predefined_langcode'], t('The language %language (%langcode) already exists.', array('%language' => $language->name, '%langcode' => $langcode))); + } + } + } + +} diff --git a/core/modules/language/lib/Drupal/language/Form/LanguageEditForm.php b/core/modules/language/lib/Drupal/language/Form/LanguageEditForm.php new file mode 100644 index 0000000..ad35e67 --- /dev/null +++ b/core/modules/language/lib/Drupal/language/Form/LanguageEditForm.php @@ -0,0 +1,60 @@ +commonForm($form); + return parent::form($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function actions(array $form, array &$form_state) { + $actions['submit'] = array( + '#type' => 'submit', + '#value' => t('Save language'), + '#validate' => array(array($this, 'validateCommon')), + '#submit' => array(array($this, 'submitForm')), + ); + return $actions; + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + // Prepare a language object for saving. + $languages = language_list(); + $langcode = $form_state['values']['langcode']; + $language = $languages[$langcode]; + $language->name = $form_state['values']['name']; + $language->direction = $form_state['values']['direction']; + language_save($language); + $form_state['redirect'] = 'admin/config/regional/language'; + } + +} diff --git a/core/modules/language/lib/Drupal/language/Form/LanguageFormBase.php b/core/modules/language/lib/Drupal/language/Form/LanguageFormBase.php new file mode 100644 index 0000000..f34af3a --- /dev/null +++ b/core/modules/language/lib/Drupal/language/Form/LanguageFormBase.php @@ -0,0 +1,80 @@ +entity; + if (isset($language->id)) { + $form['langcode_view'] = array( + '#type' => 'item', + '#title' => t('Language code'), + '#markup' => $language->id + ); + $form['langcode'] = array( + '#type' => 'value', + '#value' => $language->id + ); + } + else { + $form['langcode'] = array( + '#type' => 'textfield', + '#title' => t('Language code'), + '#maxlength' => 12, + '#required' => TRUE, + '#default_value' => '', + '#disabled' => FALSE, + '#description' => t('Use language codes as defined by the W3C for interoperability. Examples: "en", "en-gb" and "zh-hant".', array('@w3ctags' => 'http://www.w3.org/International/articles/language-tags/')), + ); + } + $form['name'] = array( + '#type' => 'textfield', + '#title' => t('Language name in English'), + '#maxlength' => 64, + '#default_value' => $language->label, + '#required' => TRUE, + ); + $form['direction'] = array( + '#type' => 'radios', + '#title' => t('Direction'), + '#required' => TRUE, + '#description' => t('Direction that text in this language is presented.'), + '#default_value' => $language->direction, + '#options' => array( + Language::DIRECTION_LTR => t('Left to right'), + Language::DIRECTION_RTL => t('Right to left'), + ), + ); + + return $form; + } + + /** + * Validates the language editing element. + */ + public function validateCommon(array $form, array &$form_state) { + // Ensure sane field values for langcode and name. + if (!isset($form['langcode_view']) && preg_match('@[^a-zA-Z_-]@', $form_state['values']['langcode'])) { + form_error($form['langcode'], t('%field may only contain characters a-z, underscores, or hyphens.', array('%field' => $form['langcode']['#title']))); + } + if ($form_state['values']['name'] != check_plain($form_state['values']['name'])) { + form_error($form['name'], t('%field cannot contain any markup.', array('%field' => $form['name']['#title']))); + } + } + +} diff --git a/core/modules/language/lib/Drupal/language/LanguageAccessController.php b/core/modules/language/lib/Drupal/language/LanguageAccessController.php index e201dec..1609dd0 100644 --- a/core/modules/language/lib/Drupal/language/LanguageAccessController.php +++ b/core/modules/language/lib/Drupal/language/LanguageAccessController.php @@ -19,7 +19,6 @@ class LanguageAccessController extends EntityAccessController { */ public function access(EntityInterface $entity, $operation, $langcode = Language::LANGCODE_DEFAULT, AccountInterface $account = NULL) { switch ($operation) { - case 'create': case 'update': case 'delete': return !$entity->locked && user_access('administer languages'); @@ -28,4 +27,11 @@ public function access(EntityInterface $entity, $operation, $langcode = Language return FALSE; } + /** + * {@inheritdoc} + */ + protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { + return $account->hasPermission('administer languages'); + } + } diff --git a/core/modules/language/lib/Drupal/language/LanguageInterface.php b/core/modules/language/lib/Drupal/language/LanguageInterface.php index 20ca26c..b2bfe26 100644 --- a/core/modules/language/lib/Drupal/language/LanguageInterface.php +++ b/core/modules/language/lib/Drupal/language/LanguageInterface.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\language\Entity\LanguageInterface. + * Contains \Drupal\language\LanguageInterface. */ namespace Drupal\language; diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index c4ff11f..529e73c 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -805,7 +805,7 @@ function locale_form_language_admin_edit_form_alter(&$form, &$form_state) { '#type' => 'checkbox', '#default_value' => locale_translate_english(), ); - $form['#submit'][] = 'locale_form_language_admin_edit_form_alter_submit'; + $form['actions']['submit']['#submit'][] = 'locale_form_language_admin_edit_form_alter_submit'; } }