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';
}
}