diff --git a/core/lib/Drupal/Core/Datetime/Date.php b/core/lib/Drupal/Core/Datetime/Date.php index 93fd00f..ba64a23 100644 --- a/core/lib/Drupal/Core/Datetime/Date.php +++ b/core/lib/Drupal/Core/Datetime/Date.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\Component\Datetime\Date. + * Contains \Drupal\Core\Datetime\Date. */ namespace Drupal\Core\Datetime; @@ -104,13 +104,13 @@ public function format($timestamp, $type = 'medium', $format = '', $timezone = N // If we have a non-custom date format use the provided date format pattern. $config = $this->configFactory->get('system.date'); - if ($type != 'custom') { - $format = $config->get('formats.' . $type . '.pattern.' . $key); + if ($date_format = entity_load('date_format', $type)) { + $format = $date_format->getPattern($key); } // Fall back to medium if a format was not found. if (empty($format)) { - $format = $config->get('formats.medium.pattern.' . $key); + $format = entity_load('date_format', 'medium')->getPattern($key); } // Call $date->format(). diff --git a/core/modules/datetime/datetime.module b/core/modules/datetime/datetime.module index 88e6a77..91c163c 100644 --- a/core/modules/datetime/datetime.module +++ b/core/modules/datetime/datetime.module @@ -30,18 +30,14 @@ * Implements hook_element_info(). */ function datetime_element_info() { - $format_type = datetime_default_format_type(); - $types['datetime'] = array( '#input' => TRUE, '#element_validate' => array('datetime_datetime_validate'), '#process' => array('datetime_datetime_form_process'), '#theme' => 'datetime_form', '#theme_wrappers' => array('datetime_wrapper'), - '#date_date_format' => config('system.date')->get('formats.html_date.pattern.' . $format_type), '#date_date_element' => 'date', '#date_date_callbacks' => array(), - '#date_time_format' => config('system.date')->get('formats.html_time.pattern.' . $format_type), '#date_time_element' => 'time', '#date_time_callbacks' => array(), '#date_year_range' => '1900:2050', @@ -430,7 +426,7 @@ function theme_datetime_wrapper($variables) { * list of the possible formats and HTML5 standards for the HTML5 * requirements. Defaults to the right HTML5 format for the chosen element * if a HTML5 element is used, otherwise defaults to - * config('system.date')->get('formats.html_date.pattern.php'). + * entity_load('date_format', 'html_date')->getPattern(). * - #date_date_element: The date element. Options are: * - datetime: Use the HTML5 datetime element type. * - datetime-local: Use the HTML5 datetime-local element type. @@ -450,7 +446,7 @@ function theme_datetime_wrapper($variables) { * a list of the possible formats and HTML5 standards for the HTML5 * requirements. Defaults to the right HTML5 format for the chosen element * if a HTML5 element is used, otherwise defaults to - * config('system.date')->get('formats.html_time.pattern.php'). + * entity_load('date_format', 'html_time')->getPattern(). * - #date_time_callbacks: An array of optional callbacks for the time * element. Can be used to add a jQuery timepicker or an 'All day' checkbox. * - #date_year_range: A description of the range of years to allow, like @@ -491,6 +487,13 @@ function theme_datetime_wrapper($variables) { * The form element whose value has been processed. */ function datetime_datetime_form_process($element, &$form_state) { + $format_type = datetime_default_format_type(); + if (!isset($element['#date_date_format']) && $date_format_entity = entity_load('date_format', 'html_date')) { + $element['#date_date_format'] = $date_format_entity->getPattern($format_type); + } + if (!isset($element['#date_time_format']) && $time_format_entity = entity_load('date_format', 'html_time')) { + $element['#date_time_format'] = $time_format_entity->getPattern($format_type); + } // The value callback has populated the #value array. $date = !empty($element['#value']['object']) ? $element['#value']['object'] : NULL; @@ -711,11 +714,11 @@ function datetime_html5_format($part, $element) { case 'date': switch ($element['#date_date_element']) { case 'date': - return config('system.date')->get('formats.html_date.pattern.' . $format_type); + return entity_load('date_format', 'html_date')->getPattern($format_type); case 'datetime': case 'datetime-local': - return config('system.date')->get('formats.html_datetime.pattern.' . $format_type); + return entity_load('date_format', 'html_datetime')->getPattern($format_type); default: return $element['#date_date_format']; @@ -725,7 +728,7 @@ function datetime_html5_format($part, $element) { case 'time': switch ($element['#date_time_element']) { case 'time': - return config('system.date')->get('formats.html_time.pattern.' . $format_type); + return entity_load('date_format', 'html_time')->getPattern($format_type); default: return $element['#date_time_format']; @@ -1141,9 +1144,9 @@ function datetime_form_node_form_alter(&$form, &$form_state, $form_id) { // Alter the 'Authored on' date to use datetime. $form['author']['date']['#type'] = 'datetime'; - $config = Drupal::config('system.date'); - $format = $config->get('formats.html_date.pattern.' . $format_type) . ' ' . $config->get('formats.html_time.pattern.' . $format_type); - $form['author']['date']['#description'] = t('Format: %format. Leave blank to use the time of form submission.', array('%format' => datetime_format_example($format))); + $date_format = entity_load('date_format', 'html_date')->getPattern($format_type); + $time_format = entity_load('date_format', 'html_time')->getPattern($format_type); + $form['author']['date']['#description'] = t('Format: %format. Leave blank to use the time of form submission.', array('%format' => datetime_format_example($date_format . ' ' . $time_format))); unset($form['author']['date']['#maxlength']); } diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimeDefaultFormatter.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimeDefaultFormatter.php index 729c44e..41b20f2 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimeDefaultFormatter.php +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/formatter/DatetimeDefaultFormatter.php @@ -100,11 +100,11 @@ public function settingsForm(array $form, array &$form_state) { $element = array(); $time = new DrupalDateTime(); - $format_types = system_get_date_formats(); - if (!empty($format_types)) { - foreach ($format_types as $type => $type_info) { - $options[$type] = $type_info['name'] . ' (' . format_date($time->format('U'), $type) . ')'; - } + $format_types = \Drupal::entityManager() + ->getStorageController('date_format') + ->load(); + foreach ($format_types as $type => $type_info) { + $options[$type] = $type_info->label() . ' (' . format_date($time->format('U'), $type) . ')'; } $elements['format_type'] = array( diff --git a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php index 79f12bc..6e243f4 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php +++ b/core/modules/datetime/lib/Drupal/datetime/Plugin/field/widget/DatetimeDefaultWidget.php @@ -74,7 +74,7 @@ public function formElement(array $items, $delta, array $element, $langcode, arr case 'date': $date_type = 'date'; $time_type = 'none'; - $date_format = config('system.date')->get('formats.html_date.pattern.' . $format_type); + $date_format = entity_load('date_format', 'html_date')->getPattern($format_type); $time_format = ''; $element_format = $date_format; $storage_format = DATETIME_DATE_STORAGE_FORMAT; @@ -83,8 +83,8 @@ public function formElement(array $items, $delta, array $element, $langcode, arr default: $date_type = 'date'; $time_type = 'time'; - $date_format = config('system.date')->get('formats.html_date.pattern.' . $format_type); - $time_format = config('system.date')->get('formats.html_time.pattern.' . $format_type); + $date_format = entity_load('date_format', 'html_date')->getPattern($format_type); + $time_format = entity_load('date_format', 'html_time')->getPattern($format_type); $element_format = $date_format . ' ' . $time_format; $storage_format = DATETIME_DATETIME_STORAGE_FORMAT; break; diff --git a/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php b/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php index a0538d7..af66e0d 100644 --- a/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php +++ b/core/modules/datetime/lib/Drupal/datetime/Tests/DatetimeFieldTest.php @@ -104,8 +104,8 @@ function testDateField() { $value = '2012-12-31 00:00:00'; $date = new DrupalDateTime($value); $format_type = $date->canUseIntl() ? DrupalDateTime::INTL : DrupalDateTime::PHP; - $date_format = config('system.date')->get('formats.html_date.pattern.' . $format_type); - $time_format = config('system.date')->get('formats.html_time.pattern.' . $format_type); + $date_format = entity_load('date_format', 'html_date')->getPattern($format_type); + $time_format = entity_load('date_format', 'html_time')->getPattern($format_type); $edit = array( 'user_id' => 1, @@ -175,8 +175,8 @@ function testDatetimeField() { $value = '2012-12-31 00:00:00'; $date = new DrupalDateTime($value); $format_type = $date->canUseIntl() ? DrupalDateTime::INTL : DrupalDateTime::PHP; - $date_format = config('system.date')->get('formats.html_date.pattern.' . $format_type); - $time_format = config('system.date')->get('formats.html_time.pattern.' . $format_type); + $date_format = entity_load('date_format', 'html_date')->getPattern($format_type); + $time_format = entity_load('date_format', 'html_time')->getPattern($format_type); $edit = array( 'user_id' => 1, diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php b/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php index ed3c151..42d9656 100644 --- a/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php +++ b/core/modules/field/lib/Drupal/field/Tests/FieldUnitTestBase.php @@ -38,7 +38,11 @@ function setUp() { $this->installSchema('entity_test', 'entity_test'); $this->installSchema('field_test', array('test_entity', 'test_entity_revision', 'test_entity_bundle')); - // Set default storage backend and configure the theme system. + // Set default storage backend and configure the theme system. If the child + // test depends on the language module, enable the language table first. + if ($this->container->get('module_handler')->moduleExists('language')) { + $this->installSchema('language', 'language'); + } $this->installConfig(array('field', 'system')); } diff --git a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php index ae52f2e..8952bcb 100644 --- a/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php +++ b/core/modules/field/lib/Drupal/field/Tests/TranslationTest.php @@ -36,7 +36,6 @@ public static function getInfo() { function setUp() { parent::setUp(); - $this->installSchema('language', array('language')); $this->installSchema('node', array('node_type')); $this->field_name = drupal_strtolower($this->randomName() . '_field_name'); diff --git a/core/modules/language/lib/Drupal/language/Tests/Views/LanguageTestBase.php b/core/modules/language/lib/Drupal/language/Tests/Views/LanguageTestBase.php index 9057a5a..85dbbfb 100644 --- a/core/modules/language/lib/Drupal/language/Tests/Views/LanguageTestBase.php +++ b/core/modules/language/lib/Drupal/language/Tests/Views/LanguageTestBase.php @@ -24,9 +24,8 @@ protected function setUp() { parent::setUp(); - $this->installSchema('language', 'language'); - $this->installSchema('system', 'variable'); + $this->installSchema('system', 'variable'); // Create English and another language beside English. $language = new Language(array('langcode' => 'en')); diff --git a/core/modules/locale/locale.install b/core/modules/locale/locale.install index 92b28ea..e503ecf 100644 --- a/core/modules/locale/locale.install +++ b/core/modules/locale/locale.install @@ -948,22 +948,14 @@ function locale_update_8015() { * Converts localized date formats. */ function locale_update_8016() { - $configs = array(); - // Fetch all date types from {date_format_type}. $result = db_query('SELECT * FROM {date_format_locale}'); foreach ($result as $format) { $language = $format->language; // Create config objects for the language if not yet done. - if (!isset($configs[$language])) { - $configs[$language] = config('locale.config.' . $language . '.system.date'); - } - $configs[$language]->set('formats.' . $format->type . '.pattern.php', $format->format); - } - - // Save all instantiated config objects. - foreach ($configs as $config) { - $config->save(); + config("locale.config.$language.system.date_format." . $format->type) + ->set('pattern.php', $format->format) + ->save(); } } diff --git a/core/modules/system/config/system.date.yml b/core/modules/system/config/system.date.yml index 55c6e75..55a35c1 100644 --- a/core/modules/system/config/system.date.yml +++ b/core/modules/system/config/system.date.yml @@ -1,64 +1,3 @@ first_day: '0' country: default: '' -formats: - long: - name: 'Default Long Date' - pattern: - php: 'l, F j, Y - H:i' - intl: 'EEEE, LLLL d, yyyy - kk:mm' - locked: 0 - medium: - name: 'Default Medium Date' - pattern: - php: 'D, m/d/Y - H:i' - intl: 'ccc, MM/dd/yyyy - kk:mm' - locked: 0 - short: - name: 'Default Short Date' - pattern: - php: 'm/d/Y - H:i' - intl: 'MM/dd/yyyy - kk:mm' - locked: 0 - html_datetime: - name: 'HTML Datetime' - pattern: - php: 'Y-m-d\TH:i:sO' - intl: 'yyyy-MM-dd''T''kk:mm:ssZZ' - locked: 1 - html_date: - name: 'HTML Date' - pattern: - php: 'Y-m-d' - intl: 'yyyy-MM-dd' - locked: 1 - html_time: - name: 'HTML Time' - pattern: - php: 'H:i:s' - intl: 'H:mm:ss' - locked: 1 - html_yearless_date: - name: 'HTML Yearless date' - pattern: - php: 'm-d' - intl: 'MM-d' - locked: 1 - html_week: - name: 'HTML Week' - pattern: - php: 'Y-\WW' - intl: 'Y-''W''WW' - locked: 1 - html_month: - name: 'HTML Month' - pattern: - php: 'Y-m' - intl: 'Y-MM' - locked: 1 - html_year: - name: 'HTML Year' - pattern: - php: 'Y' - intl: 'Y' - locked: 1 diff --git a/core/modules/system/config/system.date_format.html_date.yml b/core/modules/system/config/system.date_format.html_date.yml new file mode 100644 index 0000000..9098f3e --- /dev/null +++ b/core/modules/system/config/system.date_format.html_date.yml @@ -0,0 +1,8 @@ +id: html_date +label: 'HTML Date' +pattern: + php: 'Y-m-d' + intl: 'yyyy-MM-dd' +status: '1' +langcode: en +locked: '1' diff --git a/core/modules/system/config/system.date_format.html_datetime.yml b/core/modules/system/config/system.date_format.html_datetime.yml new file mode 100644 index 0000000..fd9e9a0 --- /dev/null +++ b/core/modules/system/config/system.date_format.html_datetime.yml @@ -0,0 +1,8 @@ +id: html_datetime +label: 'HTML Datetime' +pattern: + php: 'Y-m-d\TH:i:sO' + intl: 'yyyy-MM-dd''T''kk:mm:ssZZ' +status: '1' +langcode: en +locked: '1' diff --git a/core/modules/system/config/system.date_format.html_month.yml b/core/modules/system/config/system.date_format.html_month.yml new file mode 100644 index 0000000..cd5a358 --- /dev/null +++ b/core/modules/system/config/system.date_format.html_month.yml @@ -0,0 +1,8 @@ +id: html_month +label: 'HTML Month' +pattern: + php: 'Y-m' + intl: 'Y-MM' +status: '1' +langcode: en +locked: '1' diff --git a/core/modules/system/config/system.date_format.html_time.yml b/core/modules/system/config/system.date_format.html_time.yml new file mode 100644 index 0000000..79139f9 --- /dev/null +++ b/core/modules/system/config/system.date_format.html_time.yml @@ -0,0 +1,8 @@ +id: html_time +label: 'HTML Time' +pattern: + php: 'H:i:s' + intl: 'H:mm:ss' +status: '1' +langcode: en +locked: '1' diff --git a/core/modules/system/config/system.date_format.html_week.yml b/core/modules/system/config/system.date_format.html_week.yml new file mode 100644 index 0000000..49ff980 --- /dev/null +++ b/core/modules/system/config/system.date_format.html_week.yml @@ -0,0 +1,8 @@ +id: html_week +label: 'HTML Week' +pattern: + php: 'Y-\WW' + intl: 'Y-''W''WW' +status: '1' +langcode: en +locked: '1' diff --git a/core/modules/system/config/system.date_format.html_year.yml b/core/modules/system/config/system.date_format.html_year.yml new file mode 100644 index 0000000..2c8b3d5 --- /dev/null +++ b/core/modules/system/config/system.date_format.html_year.yml @@ -0,0 +1,8 @@ +id: html_year +label: 'HTML Year' +pattern: + php: 'Y' + intl: 'Y' +status: '1' +langcode: en +locked: '1' diff --git a/core/modules/system/config/system.date_format.html_yearless_date.yml b/core/modules/system/config/system.date_format.html_yearless_date.yml new file mode 100644 index 0000000..ae29991 --- /dev/null +++ b/core/modules/system/config/system.date_format.html_yearless_date.yml @@ -0,0 +1,8 @@ +id: html_yearless_date +label: 'HTML Yearless date' +pattern: + php: 'm-d' + intl: 'MM-d' +status: '1' +langcode: en +locked: '1' diff --git a/core/modules/system/config/system.date_format.long.yml b/core/modules/system/config/system.date_format.long.yml new file mode 100644 index 0000000..9eebff4 --- /dev/null +++ b/core/modules/system/config/system.date_format.long.yml @@ -0,0 +1,7 @@ +id: long +label: 'Default long date' +pattern: + php: 'l, F j, Y - H:i' + intl: 'EEEE, LLLL d, yyyy - kk:mm' +status: '1' +langcode: en diff --git a/core/modules/system/config/system.date_format.medium.yml b/core/modules/system/config/system.date_format.medium.yml new file mode 100644 index 0000000..0390e88 --- /dev/null +++ b/core/modules/system/config/system.date_format.medium.yml @@ -0,0 +1,7 @@ +id: medium +label: 'Default medium date' +pattern: + php: 'D, m/d/Y - H:i' + intl: 'ccc, MM/dd/yyyy - kk:mm' +status: '1' +langcode: en diff --git a/core/modules/system/config/system.date_format.short.yml b/core/modules/system/config/system.date_format.short.yml new file mode 100644 index 0000000..7a2bc8e --- /dev/null +++ b/core/modules/system/config/system.date_format.short.yml @@ -0,0 +1,7 @@ +id: short +label: 'Default short date' +pattern: + php: 'm/d/Y - H:i' + intl: 'MM/dd/yyyy - kk:mm' +status: '1' +langcode: en diff --git a/core/modules/system/lib/Drupal/system/DateFormatAccessController.php b/core/modules/system/lib/Drupal/system/DateFormatAccessController.php new file mode 100644 index 0000000..dff5d74 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/DateFormatAccessController.php @@ -0,0 +1,34 @@ +isLocked()) { + return FALSE; + } + return user_access('administer site configuration', $account); + } + +} diff --git a/core/modules/system/lib/Drupal/system/DateFormatAddFormController.php b/core/modules/system/lib/Drupal/system/DateFormatAddFormController.php new file mode 100644 index 0000000..ad077f9 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/DateFormatAddFormController.php @@ -0,0 +1,32 @@ + format_date(REQUEST_TIME, $this->entity->id()))); + $form['date_format_pattern']['#field_suffix'] = ' ' . $now . ''; + $form['date_format_pattern']['#default_value'] = $this->entity->getPattern($this->patternType); + + return $form; + } + + /** + * {@inheritdoc} + */ + protected function actions(array $form, array &$form_state) { + $actions = parent::actions($form, $form_state); + $actions['submit']['#value'] = t('Save format'); + unset($actions['delete']); + return $actions; + } + + /** + * {@inheritdoc} + */ + public function submit(array $form, array &$form_state) { + parent::submit($form, $form_state); + drupal_set_message(t('Custom date format updated.')); + } + +} diff --git a/core/modules/system/lib/Drupal/system/DateFormatFormControllerBase.php b/core/modules/system/lib/Drupal/system/DateFormatFormControllerBase.php new file mode 100644 index 0000000..75909c8 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/DateFormatFormControllerBase.php @@ -0,0 +1,194 @@ +patternType = $date->canUseIntl() ? DrupalDateTime::INTL : DrupalDateTime::PHP; + + $this->entityQuery = $factory->get('date_format'); + } + + /** + * {@inheritdoc} + */ + public static function createInstance(ContainerInterface $container, $entity_type, array $entity_info) { + return new static( + $container->get('entity.query') + ); + } + + /** + * Checks for an existing date format. + * + * @param string|int $entity_id + * The entity ID. + * @param array $element + * The form element. + * @param array $form_state + * The form state. + * + * @return bool + * TRUE if this format already exists, FALSE otherwise. + */ + public static function exists($entity_id, array $element, array $form_state) { + return (bool) entity_load('date_format', $entity_id); + } + + /** + * @param array $form + * @param array $form_state + * + * @return \Drupal\Core\Ajax\AjaxResponse + */ + public static function dateTimeLookup(array $form, array $form_state) { + $format = ''; + if (!empty($form_state['values']['date_format_pattern'])) { + $format = t('Displayed as %date_format', array('%date_format' => format_date(REQUEST_TIME, 'custom', $form_state['values']['date_format_pattern']))); + } + // Return a command instead of a string, since the Ajax framework + // automatically prepends an additional empty DIV element for a string, which + // breaks the layout. + $response = new AjaxResponse(); + $response->addCommand(new ReplaceCommand('#edit-date-format-suffix', '' . $format . '')); + return $response; + } + + /** + * {@inheritdoc} + */ + public function form(array $form, array &$form_state) { + $form = parent::form($form, $form_state); + form_load_include($form_state, 'admin.inc', 'system'); + + $form['label'] = array( + '#type' => 'textfield', + '#title' => 'Name', + '#maxlength' => 100, + '#description' => t('Name of the date format'), + '#default_value' => $this->entity->label(), + ); + + $form['id'] = array( + '#type' => 'machine_name', + '#title' => t('Machine-readable name'), + '#description' => t('A unique machine-readable name. Can only contain lowercase letters, numbers, and underscores.'), + '#disabled' => !$this->entity->isNew(), + '#default_value' => $this->entity->id(), + '#machine_name' => array( + 'exists' => array($this, 'exists'), + ), + ); + + if (class_exists('intlDateFormatter')) { + $description = t('A user-defined date format. See the PHP manual for available options.', array('@url' => 'http://userguide.icu-project.org/formatparse/datetime')); + } + else { + $description = t('A user-defined date format. See the PHP manual for available options.', array('@url' => 'http://php.net/manual/function.date.php')); + } + $form['date_format_pattern'] = array( + '#type' => 'textfield', + '#title' => t('Format string'), + '#maxlength' => 100, + '#description' => $description, + '#default_value' => '', + '#field_suffix' => ' ', + '#ajax' => array( + 'callback' => array($this, 'dateTimeLookup'), + 'event' => 'keyup', + 'progress' => array('type' => 'throbber', 'message' => NULL), + ), + '#required' => TRUE, + ); + + $languages = language_list(); + + $options = array(); + foreach ($languages as $langcode => $data) { + $options[$langcode] = $data->name; + } + + if (!empty($options)) { + $form['locales'] = array( + '#title' => t('Select localizations'), + '#type' => 'select', + '#options' => $options, + '#multiple' => TRUE, + '#default_value' => $this->entity->getLocales(), + ); + } + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validate(array $form, array &$form_state) { + parent::validate($form, $form_state); + + // The machine name field should already check to see if the requested + // machine name is available. Regardless of machine_name or human readable + // name, check to see if the provided pattern exists. + $format = trim($form_state['values']['date_format_pattern']); + $formats = $this->entityQuery + ->condition('pattern.' . $this->patternType, $format) + ->execute(); + + // Exclude the current format. + unset($formats[$this->entity->id()]); + if (!empty($formats)) { + form_set_error('date_format_pattern', t('This format already exists. Enter a unique format string.')); + } + } + + /** + * {@inheritdoc} + */ + public function submit(array $form, array &$form_state) { + $form_state['redirect'] = 'admin/config/regional/date-time'; + $form_state['values']['pattern'][$this->patternType] = trim($form_state['values']['date_format_pattern']); + + parent::submit($form, $form_state); + $this->entity->save(); + } + +} diff --git a/core/modules/system/lib/Drupal/system/DateFormatInterface.php b/core/modules/system/lib/Drupal/system/DateFormatInterface.php new file mode 100644 index 0000000..eb456a4 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/DateFormatInterface.php @@ -0,0 +1,62 @@ +isLocked(); + }); + } + + /** + * {@inheritdoc} + */ + public function buildHeader() { + $header['id'] = t('Machine name'); + $header['label'] = t('Name'); + $header['pattern'] = t('Pattern'); + $header['operations'] = t('Operations'); + return $header; + } + + /** + * {@inheritdoc} + */ + public function getOperations(EntityInterface $entity) { + $operations = parent::getOperations($entity); + $uri = $entity->uri(); + $operations['edit']['href'] = $uri['path']; + return $operations; + } + + /** + * {@inheritdoc} + */ + public function buildRow(EntityInterface $entity) { + $row['id'] = $entity->id(); + $row['label'] = $entity->label(); + $row['pattern'] = format_date(REQUEST_TIME, $entity->id()); + $row['operations']['data'] = $this->buildOperations($entity); + return $row; + } + +} diff --git a/core/modules/system/lib/Drupal/system/DateFormatStorageController.php b/core/modules/system/lib/Drupal/system/DateFormatStorageController.php new file mode 100644 index 0000000..b3d5571 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/DateFormatStorageController.php @@ -0,0 +1,53 @@ +getLocales() as $langcode) { + if (isset($languages[$langcode])) { + config('locale.config.' . $langcode . '.system.date_format.' . $entity->id()) + ->setData($entity->getExportProperties()) + ->save(); + } + } + } + + /** + * {inheritdoc} + */ + protected function postDelete($entities) { + parent::postDelete($entities); + + // Clean up the localized entry if required. + if (module_exists('language')) { + $languages = language_list(); + foreach ($entities as $entity) { + $format_id = $entity->id(); + foreach ($languages as $langcode => $data) { + config("locale.config.$langcode.system.date_format.$format_id")->delete(); + } + } + } + } + +} diff --git a/core/modules/system/lib/Drupal/system/Form/DateFormatAddForm.php b/core/modules/system/lib/Drupal/system/Form/DateFormatAddForm.php deleted file mode 100644 index 6dec855..0000000 --- a/core/modules/system/lib/Drupal/system/Form/DateFormatAddForm.php +++ /dev/null @@ -1,93 +0,0 @@ - 'textfield', - '#title' => 'Name', - '#maxlength' => 100, - '#description' => t('Name of the date format'), - '#default_value' => '', - ); - - $form['date_format_id'] = array( - '#type' => 'machine_name', - '#title' => t('Machine-readable name'), - '#description' => t('A unique machine-readable name. Can only contain lowercase letters, numbers, and underscores.'), - '#default_value' => '', - '#machine_name' => array( - 'exists' => 'system_date_format_exists', - 'source' => array('date_format_name'), - ), - ); - - if (class_exists('intlDateFormatter')) { - $description = t('A user-defined date format. See the PHP manual for available options.', array('@url' => 'http://userguide.icu-project.org/formatparse/datetime')); - } - else { - $description = t('A user-defined date format. See the PHP manual for available options.', array('@url' => 'http://php.net/manual/function.date.php')); - } - $form['date_format_pattern'] = array( - '#type' => 'textfield', - '#title' => t('Format string'), - '#maxlength' => 100, - '#description' => $description, - '#default_value' => '', - '#field_suffix' => ' ', - '#ajax' => array( - 'callback' => 'system_date_time_lookup', - 'event' => 'keyup', - 'progress' => array('type' => 'throbber', 'message' => NULL), - ), - '#required' => TRUE, - ); - - $languages = language_list(); - - $options = array(); - foreach ($languages as $langcode => $data) { - $options[$langcode] = $data->name; - } - - if (!empty($options)) { - $form['date_langcode'] = array( - '#title' => t('Select localizations'), - '#type' => 'select', - '#options' => $options, - '#multiple' => TRUE, - '#default_value' => '', - ); - } - - $form['actions'] = array('#type' => 'actions'); - $form['actions']['update'] = array( - '#type' => 'submit', - '#value' => t('Add format'), - ); - - return $form; - } - -} diff --git a/core/modules/system/lib/Drupal/system/Form/DateFormatDeleteForm.php b/core/modules/system/lib/Drupal/system/Form/DateFormatDeleteForm.php index 327fb3f..8356faa 100644 --- a/core/modules/system/lib/Drupal/system/Form/DateFormatDeleteForm.php +++ b/core/modules/system/lib/Drupal/system/Form/DateFormatDeleteForm.php @@ -7,68 +7,20 @@ namespace Drupal\system\Form; -use Drupal\Core\Form\ConfirmFormBase; -use Drupal\Core\Controller\ControllerInterface; -use Drupal\Core\Config\ConfigFactory; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\HttpFoundation\Request; +use Drupal\Core\Entity\EntityConfirmFormBase; /** * Builds a form to delete a date format. */ -class DateFormatDeleteForm extends ConfirmFormBase implements ControllerInterface { - - /** - * The date format data to be deleted. - * - * @var array - */ - protected $format; - - /** - * The ID of the date format to be deleted. - * - * @var string - */ - protected $formatID; - - /** - * The config factory. - * - * @var \Drupal\Core\Config\ConfigFactory - */ - protected $configFactory; - - /** - * Constructs a DateFormatDeleteForm object. - */ - public function __construct(ConfigFactory $config_factory) { - $this->configFactory = $config_factory; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('config.factory') - ); - } - - /** - * {@inheritdoc} - */ - public function getFormID() { - return 'system_date_delete_format_form'; - } +class DateFormatDeleteForm extends EntityConfirmFormBase { /** * {@inheritdoc} */ public function getQuestion() { return t('Are you sure you want to remove the format %name : %format?', array( - '%name' => $this->format['name'], - '%format' => format_date(REQUEST_TIME, $this->formatID)) + '%name' => $this->entity->label(), + '%format' => format_date(REQUEST_TIME, $this->entity->id())) ); } @@ -83,31 +35,17 @@ public function getConfirmText() { * {@inheritdoc} */ public function getCancelPath() { - return 'admin/config/regional/date-time/formats'; - } - - /** - * {@inheritdoc} - * - * @param string $format_id - * The date format ID. - */ - public function buildForm(array $form, array &$form_state, $format_id = NULL, Request $request = NULL) { - // We don't get the format ID in the returned format array. - $this->formatID = $format_id; - $this->format = $this->configFactory->get('system.date')->get("formats.$format_id"); - - return parent::buildForm($form, $form_state, $request); + return 'admin/config/regional/date-time'; } /** * {@inheritdoc} */ - public function submitForm(array &$form, array &$form_state) { - system_date_format_delete($this->formatID); - drupal_set_message(t('Removed date format %format.', array('%format' => $this->format['name']))); + public function submit(array $form, array &$form_state) { + $this->entity->delete(); + drupal_set_message(t('Removed date format %format.', array('%format' => $this->entity->label()))); - $form_state['redirect'] = 'admin/config/regional/date-time/formats'; + $form_state['redirect'] = 'admin/config/regional/date-time'; } } diff --git a/core/modules/system/lib/Drupal/system/Form/DateFormatFormBase.php b/core/modules/system/lib/Drupal/system/Form/DateFormatFormBase.php deleted file mode 100644 index eef17d8..0000000 --- a/core/modules/system/lib/Drupal/system/Form/DateFormatFormBase.php +++ /dev/null @@ -1,71 +0,0 @@ -patternType = $date->canUseIntl() ? DrupalDateTime::INTL : DrupalDateTime::PHP; - } - - /** - * {@inheritdoc} - */ - public function validateForm(array &$form, array &$form_state) { - $formats = system_get_date_formats(); - $format = trim($form_state['values']['date_format_pattern']); - - // The machine name field should already check to see if the requested - // machine name is available. Regardless of machine_name or human readable - // name, check to see if the provided pattern exists. - if (!empty($formats) && in_array($format, array_values($formats)) && (!isset($form_state['values']['date_format_id']) || $form_state['values']['date_format_id'] != $formats[$format]['date_format_id'])) { - form_set_error('date_format', t('This format already exists. Enter a unique format string.')); - } - } - - /** - * {@inheritdoc} - */ - public function submitForm(array &$form, array &$form_state) { - $format = array(); - $format['name'] = String::checkPlain($form_state['values']['date_format_name']); - $format['pattern'][$this->patternType] = trim($form_state['values']['date_format_pattern']); - $format['locales'] = !empty($form_state['values']['date_langcode']) ? $form_state['values']['date_langcode'] : array(); - // Formats created in the UI are not locked. - $format['locked'] = 0; - - system_date_format_save($form_state['values']['date_format_id'], $format); - if (!empty($form_state['values']['date_format_id'])) { - drupal_set_message(t('Custom date format updated.')); - } - else { - drupal_set_message(t('Custom date format added.')); - } - - $form_state['redirect'] = 'admin/config/regional/date-time/formats'; - } - -} diff --git a/core/modules/system/lib/Drupal/system/Form/DateFormatLocalizeResetForm.php b/core/modules/system/lib/Drupal/system/Form/DateFormatLocalizeResetForm.php index cbce81f..15f4239 100644 --- a/core/modules/system/lib/Drupal/system/Form/DateFormatLocalizeResetForm.php +++ b/core/modules/system/lib/Drupal/system/Form/DateFormatLocalizeResetForm.php @@ -102,7 +102,9 @@ public function buildForm(array $form, array &$form_state, $langcode = NULL, Req * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { - $this->configFactory->get('locale.config.' . $this->language->langcode . '.system.date')->delete(); + foreach (config_get_storage_names_with_prefix('locale.config.' . $this->language->langcode . '.system.date_format') as $config_id) { + $this->configFactory->get($config_id)->delete(); + } $form_state['redirect'] = 'admin/config/regional/date-time/locale'; } diff --git a/core/modules/system/lib/Drupal/system/Plugin/Core/Entity/DateFormat.php b/core/modules/system/lib/Drupal/system/Plugin/Core/Entity/DateFormat.php new file mode 100644 index 0000000..1f25c01 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Plugin/Core/Entity/DateFormat.php @@ -0,0 +1,165 @@ + 'admin/config/regional/date-time/formats/manage/' . $this->id(), + 'options' => array( + 'entity_type' => $this->entityType, + 'entity' => $this, + ), + ); + } + + /** + * {@inheritdoc} + */ + public function getExportProperties() { + $properties = parent::getExportProperties(); + $names = array( + 'locked', + 'pattern', + 'locales', + ); + foreach ($names as $name) { + $properties[$name] = $this->get($name); + } + return $properties; + } + + /** + * {@inheritdoc} + */ + public function getPattern($type = DrupalDateTime::PHP) { + return isset($this->pattern[$type]) ? $this->pattern[$type] : ''; + } + + /** + * {@inheritdoc} + */ + public function setPattern($pattern, $type = DrupalDateTime::PHP) { + $this->pattern[$type] = $pattern; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getLocales() { + return $this->locales; + } + + /** + * {@inheritdoc} + */ + public function setLocales(array $locales) { + $this->locales = $locales; + return $this; + } + + /** + * {@inheritdoc} + */ + public function hasLocales() { + return !empty($this->locales); + } + + /** + * {@inheritdoc} + */ + public function addLocale($locale) { + $this->locales[] = $locale; + $this->locales = array_unique($this->locales); + return $this; + } + + /** + * {@inheritdoc} + */ + public function isLocked() { + return (bool) $this->locked; + } + +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/FormatDateTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/FormatDateTest.php index 118a059..6090f60 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/FormatDateTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/FormatDateTest.php @@ -40,11 +40,12 @@ function setUp() { config('system.timezone') ->set('user.configurable', 1) ->save(); - config('system.date') - ->set('formats.long.pattern.php', 'l, j. F Y - G:i') - ->set('formats.medium.pattern.php', 'j. F Y - G:i') - ->set('formats.short.pattern.php', 'Y M j - g:ia') - ->save(); + $formats = $this->container->get('plugin.manager.entity') + ->getStorageController('date_format') + ->load(array('long', 'medium', 'short')); + $formats['long']->setPattern('l, j. F Y - G:i')->save(); + $formats['medium']->setPattern('j. F Y - G:i')->save(); + $formats['short']->setPattern('Y M j - g:ia')->save(); variable_set('locale_custom_strings_' . self::LANGCODE, array( '' => array('Sunday' => 'domingo'), @@ -64,20 +65,20 @@ function testAdminDefinedFormatDate() { // Add new date format. $edit = array( - 'date_format_id' => 'example_style', - 'date_format_name' => 'Example Style', + 'id' => 'example_style', + 'label' => 'Example Style', 'date_format_pattern' => 'j M y', ); $this->drupalPost('admin/config/regional/date-time/formats/add', $edit, t('Add format')); // Add a second date format with a different case than the first. $edit = array( - 'date_format_id' => 'example_style_uppercase', - 'date_format_name' => 'Example Style Uppercase', + 'id' => 'example_style_uppercase', + 'label' => 'Example Style Uppercase', 'date_format_pattern' => 'j M Y', ); $this->drupalPost('admin/config/regional/date-time/formats/add', $edit, t('Add format')); - $this->assertText(t('Custom date format updated.')); + $this->assertText(t('Custom date format added.')); $timestamp = strtotime('2007-03-10T00:00:00+00:00'); $this->assertIdentical(format_date($timestamp, 'example_style', '', 'America/Los_Angeles'), '9 Mar 07', 'Test format_date() using an admin-defined date type.'); diff --git a/core/modules/system/lib/Drupal/system/Tests/Datetime/DateTimePlusIntlTest.php b/core/modules/system/lib/Drupal/system/Tests/Datetime/DateTimePlusIntlTest.php index 5fe2b82..6316b19 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Datetime/DateTimePlusIntlTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Datetime/DateTimePlusIntlTest.php @@ -8,6 +8,7 @@ namespace Drupal\system\Tests\Datetime; use Drupal\Component\Datetime\DateTimePlus; +use Drupal\Core\Datetime\DrupalDateTime; use Drupal\simpletest\DrupalUnitTestBase; /** @@ -75,11 +76,13 @@ function testDateTimestampIntl() { $this->assertTrue($intl_date->canUseIntl(), 'DateTimePlus object can use intl when provided with country and langcode settings.'); $this->assertFalse($php_date->canUseIntl(), 'DateTimePlus object will fallback to use PHP when not provided with country setting.'); - $default_formats = config('system.date')->get('formats'); + $default_formats = $this->container->get('plugin.manager.entity') + ->getStorageController('date_format') + ->load(); foreach ($default_formats as $format) { - $php_format = $php_date->format($format['pattern']['php'], $php_settings); - $intl_format = $intl_date->format($format['pattern']['intl'], $intl_settings); + $php_format = $php_date->format($format->getPattern(DrupalDateTime::PHP), $php_settings); + $intl_format = $intl_date->format($format->getPattern(DrupalDateTime::INTL), $intl_settings); $this->assertIdentical($intl_format, $php_format); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/System/DateFormatsLanguageTest.php b/core/modules/system/lib/Drupal/system/Tests/System/DateFormatsLanguageTest.php index 4d98340..27e126a 100644 --- a/core/modules/system/lib/Drupal/system/Tests/System/DateFormatsLanguageTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/System/DateFormatsLanguageTest.php @@ -60,19 +60,19 @@ function testLocalizeDateFormats() { // Add new date format for French. $edit = array( - 'date_format_id' => 'example_style_fr', - 'date_format_name' => 'Example Style', + 'id' => 'example_style_fr', + 'label' => 'Example Style', 'date_format_pattern' => 'd.m.Y - H:i', - 'date_langcode[]' => array('fr'), + 'locales[]' => array('fr'), ); $this->drupalPost('admin/config/regional/date-time/formats/add', $edit, t('Add format')); // Add new date format for English. $edit = array( - 'date_format_id' => 'example_style_en', - 'date_format_name' => 'Example Style', + 'id' => 'example_style_en', + 'label' => 'Example Style', 'date_format_pattern' => 'j M Y - g:ia', - 'date_langcode[]' => array('en'), + 'locales[]' => array('en'), ); $this->drupalPost('admin/config/regional/date-time/formats/add', $edit, t('Add format')); diff --git a/core/modules/system/lib/Drupal/system/Tests/System/DateFormatsLockedTest.php b/core/modules/system/lib/Drupal/system/Tests/System/DateFormatsLockedTest.php new file mode 100644 index 0000000..e10f106 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/System/DateFormatsLockedTest.php @@ -0,0 +1,52 @@ + 'Locked date formats', + 'description' => 'Tests the locked functionality of date formats.', + 'group' => 'System', + ); + } + + /** + * Tests attempts at listing, editing, and deleting locked date formats. + */ + public function testDateLocking() { + $this->drupalLogin($this->root_user); + + // Locked date formats do not show on the listing page. + $this->drupalGet('admin/config/regional/date-time'); + $this->assertLinkByHref('admin/config/regional/date-time/formats/manage/short'); + $this->assertNoLinkByHref('admin/config/regional/date-time/formats/manage/html_date'); + + // Locked date formats are not editable. + $this->drupalGet('admin/config/regional/date-time/formats/manage/short'); + $this->assertResponse(200); + $this->drupalGet('admin/config/regional/date-time/formats/manage/html_date'); + $this->assertResponse(403); + + // Locked date formats are not deletable. + $this->drupalGet('admin/config/regional/date-time/formats/manage/short/delete'); + $this->assertResponse(200); + $this->drupalGet('admin/config/regional/date-time/formats/manage/html_date/delete'); + $this->assertResponse(403); + } + +} diff --git a/core/modules/system/lib/Drupal/system/Tests/System/DateTimeTest.php b/core/modules/system/lib/Drupal/system/Tests/System/DateTimeTest.php index c867581..b9752b4 100644 --- a/core/modules/system/lib/Drupal/system/Tests/System/DateTimeTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/System/DateTimeTest.php @@ -47,8 +47,8 @@ function testTimeZoneHandling() { ->set('default', 'Pacific/Honolulu') ->set('user.configurable', 0) ->save(); - config('system.date') - ->set('formats.medium.pattern.php', 'Y-m-d H:i:s O') + entity_load('date_format', 'medium') + ->setPattern('Y-m-d H:i:s O') ->save(); // Create some nodes with different authored-on dates. @@ -78,7 +78,7 @@ function testTimeZoneHandling() { */ function testDateFormatConfiguration() { // Confirm 'no custom date formats available' message appears. - $this->drupalGet('admin/config/regional/date-time/formats'); + $this->drupalGet('admin/config/regional/date-time'); // Add custom date format. $this->clickLink(t('Add format')); @@ -86,59 +86,56 @@ function testDateFormatConfiguration() { $name = ucwords($date_format_id); $date_format = 'd.m.Y - H:i'; $edit = array( - 'date_format_id' => $date_format_id, - 'date_format_name' => $name, + 'id' => $date_format_id, + 'label' => $name, 'date_format_pattern' => $date_format, ); $this->drupalPost('admin/config/regional/date-time/formats/add', $edit, t('Add format')); - $this->assertEqual($this->getUrl(), url('admin/config/regional/date-time/formats', array('absolute' => TRUE)), 'Correct page redirection.'); - $this->assertText(t('Custom date format updated.'), 'Date format added confirmation message appears.'); + $this->assertEqual($this->getUrl(), url('admin/config/regional/date-time', array('absolute' => TRUE)), 'Correct page redirection.'); + $this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.'); $this->assertText($date_format_id, 'Custom date format appears in the date format list.'); $this->assertText(t('Delete'), 'Delete link for custom date format appears.'); // Edit custom date format. - $this->drupalGet('admin/config/regional/date-time/formats'); + $this->drupalGet('admin/config/regional/date-time'); $this->clickLink(t('Edit')); $edit = array( 'date_format_pattern' => 'Y m', ); $this->drupalPost($this->getUrl(), $edit, t('Save format')); - $this->assertEqual($this->getUrl(), url('admin/config/regional/date-time/formats', array('absolute' => TRUE)), 'Correct page redirection.'); + $this->assertEqual($this->getUrl(), url('admin/config/regional/date-time', array('absolute' => TRUE)), 'Correct page redirection.'); $this->assertText(t('Custom date format updated.'), 'Custom date format successfully updated.'); // Delete custom date format. $this->clickLink(t('Delete')); - $this->drupalPost('admin/config/regional/date-time/formats/' . $date_format_id . '/delete', array(), t('Remove')); - $this->assertEqual($this->getUrl(), url('admin/config/regional/date-time/formats', array('absolute' => TRUE)), 'Correct page redirection.'); + $this->drupalPost('admin/config/regional/date-time/formats/manage/' . $date_format_id . '/delete', array(), t('Remove')); + $this->assertEqual($this->getUrl(), url('admin/config/regional/date-time', array('absolute' => TRUE)), 'Correct page redirection.'); $this->assertText(t('Removed date format ' . $name), 'Custom date format removed.'); // Make sure the date does not exist in config. - $date_format = config('system.date')->get('formats.' . $date_format_id); - $this->assertIdentical($date_format, NULL); + $date_format = entity_load('date_format', $date_format_id); + $this->assertFalse($date_format); } /** * Test if the date formats are stored properly. */ function testDateFormatStorage() { - $date_format_info = array( - 'name' => 'testDateFormatStorage Short Format', + $date_format = entity_create('date_format', array( + 'id' => 'test_short', + 'label' => 'testDateFormatStorage Short Format', 'pattern' => array('php' => 'dmYHis'), - ); - - system_date_format_save('test_short', $date_format_info); + )); + $date_format->save(); - $format = config('system.date')->get('formats.test_short.pattern.php'); + $format = $date_format->getPattern(); $this->assertEqual('dmYHis', $format, 'Unlocalized date format resides in general config.'); - $date_format_info['locales'] = array('en'); - - system_date_format_save('test_short_en', $date_format_info); - - $format = config('system.date')->get('formats.test_short_en.pattern.php'); + $date_format->addLocale('en')->save(); + $format = $date_format->getPattern(); $this->assertEqual('dmYHis', $format, 'Localized date format resides in general config too.'); - $format = config('locale.config.en.system.date')->get('formats.test_short_en.pattern.php'); + $format = config('locale.config.en.system.date_format.test_short')->get('pattern.php'); $this->assertEqual('dmYHis', $format, 'Localized date format resides in localized config.'); } @@ -146,11 +143,12 @@ function testDateFormatStorage() { * Test that date formats are sanitized. */ function testDateFormatXSS() { - $date_format_info = array( - 'name' => 'XSS format', + $date_format = entity_create('date_format', array( + 'id' => 'xss_short', + 'label' => 'XSS format', 'pattern' => array('php' => '\<\s\c\r\i\p\t\>\a\l\e\r\t\(\'\X\S\S\'\)\;\<\/\s\c\r\i\p\t\>'), - ); - system_date_format_save('xss_short', $date_format_info); + )); + $date_format->save(); $this->drupalGet('admin/config/regional/date-time'); $this->assertNoRaw("", 'The date format was properly sanitized'); diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/DateUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/DateUpgradePathTest.php index e1720d1..990cbd5 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/DateUpgradePathTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/DateUpgradePathTest.php @@ -65,12 +65,12 @@ public function testDateUpgrade() { 'locked' => '0', ); + $actual_formats = entity_load_multiple('date_format', array_keys($expected_formats)); foreach ($expected_formats as $type => $format) { - $format_info = config('system.date')->get('formats.' . $type); - - $this->assertEqual($format_info['name'], $format['name'], format_string('Config value for @type name is the same', array('@type' => $type))); - $this->assertEqual($format_info['locked'], $format['locked'], format_string('Config value for @type locked is the same', array('@type' => $type))); - $this->assertEqual($format_info['pattern']['php'], $format['pattern']['php'], format_string('Config value for @type PHP date pattern is the same', array('@type' => $type))); + $format_info = $actual_formats[$type]; + $this->assertEqual($format_info->label(), $format['name'], format_string('Config value for @type name is the same', array('@type' => $type))); + $this->assertEqual($format_info->get('locked'), $format['locked'], format_string('Config value for @type locked is the same', array('@type' => $type))); + $this->assertEqual($format_info->getPattern(), $format['pattern']['php'], format_string('Config value for @type PHP date pattern is the same', array('@type' => $type))); // Make sure that the variable was deleted. $this->assertNull(update_variable_get('date_format_' . $type), format_string('Date format variable for @type was deleted.', array('@type' => $type))); @@ -91,10 +91,10 @@ public function testDateUpgrade() { ), ); - $config = config('locale.config.de.system.date'); foreach ($expected_de_formats as $locale_format) { - $format = $config->get('formats.' . $locale_format['type'] . '.pattern.php'); + $format = config('locale.config.de.system.date_format.' . $locale_format['type'])->get('pattern.php'); $this->assertEqual($locale_format['format'], $format); } } + } diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc index c499692..cce835d 100644 --- a/core/modules/system/system.admin.inc +++ b/core/modules/system/system.admin.inc @@ -5,15 +5,12 @@ * Admin page callbacks for the system module. */ -use Drupal\Core\Ajax\AjaxResponse; -use Drupal\Core\Ajax\ReplaceCommand; -use Symfony\Component\HttpFoundation\JsonResponse; +use Drupal\system\DateFormatInterface; +use Drupal\system\Form\ModulesInstallConfirmForm; +use Drupal\system\Form\ModulesUninstallConfirmForm; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; -use Drupal\Core\Datetime\DrupalDateTime; -use Drupal\system\Form\ModulesInstallConfirmForm; -use Drupal\system\Form\ModulesUninstallConfirmForm; /** * Menu callback; Provide the administration overview page. @@ -1700,69 +1697,6 @@ function theme_system_themes_page($variables) { } /** - * Displays the date format strings overview page. - */ -function system_date_time_formats() { - $header = array( - array('data' => t('Machine name'), 'field' => 'machine_name'), - array('data' => t('Name'), 'field' => 'name'), - array('data' => t('Pattern'), 'field' => 'pattern'), - array('data' => t('Operations')) - ); - $rows = array(); - - $formats = system_get_date_formats(); - - if (!empty($formats)) { - foreach ($formats as $date_format_id => $format_info) { - // Do not display date formats that are locked. - if (empty($format_info['locked'])) { - $row = array(); - $row[] = array('data' => $date_format_id); - $row[] = array('data' => $format_info['name']); - $row[] = array('data' => format_date(REQUEST_TIME, $date_format_id)); - - // Prepare Operational links. - $links = array(); - $links['edit'] = array( - 'title' => t('Edit'), - 'href' => 'admin/config/regional/date-time/formats/' . $date_format_id . '/edit', - ); - $links['delete'] = array( - 'title' => t('Delete'), - 'href' => 'admin/config/regional/date-time/formats/' . $date_format_id . '/delete', - ); - $row['operations'] = array('data' => array( - '#type' => 'operations', - '#links' => $links, - )); - - $rows[] = $row; - } - } - } - - $build['date_formats_table'] = array( - '#theme' => 'table', - '#header' => $header, - '#rows' => $rows, - '#empty' => t('No custom date formats available. Add date format.', array('@link' => url('admin/config/regional/date-time/formats/add'))), - ); - - return $build; -} - -/** - * Checks if the chosen machine_name exists or not. - */ -function system_date_format_exists($candidate_machine_name) { - if ($formats = system_get_date_formats()) { - return array_key_exists($candidate_machine_name, $formats); - } - return FALSE; -} - -/** * Page callback: Displays edit date format links for each language. * * @see locale_menu() @@ -1819,25 +1753,22 @@ function system_date_format_localize_form($form, &$form_state, $langcode) { ); // Get list of available formats. - $formats = system_get_date_formats(); + $formats = Drupal::entityManager() + ->getStorageController('date_format') + ->load(); $choices = array(); foreach ($formats as $date_format_id => $format_info) { // Ignore values that are localized. - if (empty($format_info['locales'])) { + if (!$format_info->hasLocales()) { $choices[$date_format_id] = format_date(REQUEST_TIME, $date_format_id); } - else { - unset($formats[$date_format_id]); - } } // Get configured formats for each language. - $locale_formats = system_date_format_locale($langcode); - if (!empty($locale_formats)) { - $formats += $locale_formats; - foreach ($locale_formats as $date_format_id => $format_info) { - $choices[$date_format_id] = format_date(REQUEST_TIME, $date_format_id); - } + $config_prefix = 'locale.config.' . $langcode . '.system.date_format'; + foreach (config_get_storage_names_with_prefix($config_prefix) as $config_id) { + $date_format_id = substr($config_id, strlen($config_prefix. '.')); + $choices[$date_format_id] = format_date(REQUEST_TIME, $date_format_id); } // Display a form field for each format type. @@ -1845,7 +1776,7 @@ function system_date_format_localize_form($form, &$form_state, $langcode) { // Show date format select list. $form['date_formats']['date_format_' . $date_format_id] = array( '#type' => 'select', - '#title' => check_plain($format_info['name']), + '#title' => check_plain($format_info->label()), '#attributes' => array('class' => array('date-format')), '#default_value' => isset($choices[$date_format_id]) ? $date_format_id : 'custom', '#options' => $choices, @@ -1862,32 +1793,16 @@ function system_date_format_localize_form($form, &$form_state, $langcode) { } /** - * Ajax callback; Returns the date for a given format string. - */ -function system_date_time_lookup($form, &$form_state) { - $format = ''; - if (!empty($form_state['values']['date_format_pattern'])) { - $format = t('Displayed as %date_format', array('%date_format' => format_date(REQUEST_TIME, 'custom', $form_state['values']['date_format_pattern']))); - } - // Return a command instead of a string, since the Ajax framework - // automatically prepends an additional empty DIV element for a string, which - // breaks the layout. - $response = new AjaxResponse(); - $response->addCommand(new ReplaceCommand('#edit-date-format-suffix', '' . $format . '')); - return $response; -} - -/** * Form submission handler for system_date_format_localize_form(). */ function system_date_format_localize_form_submit($form, &$form_state) { $langcode = $form_state['values']['langcode']; - $formats = system_get_date_formats(); + $formats = entity_load_multiple('date_format'); foreach ($formats as $date_format_id => $format_info) { if (isset($form_state['values']['date_format_' . $date_format_id])) { $format = $form_state['values']['date_format_' . $date_format_id]; - system_date_format_localize_form_save($langcode, $date_format_id, $formats[$format]['pattern']); + system_date_format_localize_form_save($langcode, $date_format_id, $formats[$format]); } } drupal_set_message(t('Configuration saved.')); @@ -1928,16 +1843,17 @@ function theme_system_date_format_localize_form($variables) { /** * Save locale specific date formats to the database. * - * @param $langcode + * @param string $langcode * Language code, can be 2 characters, e.g. 'en' or 5 characters, e.g. * 'en-CA'. - * @param $date_format_id + * @param string $date_format_id * Date format id, e.g. 'short', 'medium'. - * @param $format - * The date format string. + * @param \Drupal\system\DateFormatInterface $format + * The date format entity. */ -function system_date_format_localize_form_save($langcode, $date_format_id, $format) { - config('locale.config.' . $langcode . '.system.date') - ->set('formats.' . $date_format_id . '.pattern', $format) +function system_date_format_localize_form_save($langcode, $date_format_id, DateFormatInterface $format) { + $format->addLocale($langcode)->save(); + config('locale.config.' . $langcode . '.system.date_format.' . $date_format_id) + ->set('pattern', $format->get('pattern')) ->save(); } diff --git a/core/modules/system/system.install b/core/modules/system/system.install index d3b67eb..e87f300 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -4,7 +4,9 @@ * @file * Install, update and uninstall functions for the system module. */ + use Drupal\Component\Utility\Crypt; +use Drupal\Component\Uuid\Uuid; use Drupal\Core\Config\FileStorage; use Drupal\Core\Database\Database; use Drupal\Core\Language\Language; @@ -1884,33 +1886,50 @@ function system_update_8044() { /** * Convert existing date formats to the new config system. + * + * @ingroup config_upgrade */ function system_update_8045() { - // Get the date config object. - $config = config('system.date'); - + $uuid = new Uuid(); // Fetch all date types from {date_format_type}. $date_formats = db_query('SELECT * FROM {date_format_type}')->fetchAllAssoc('type', PDO::FETCH_ASSOC); if (!empty($date_formats)) { foreach ($date_formats as $type => $format) { // Set name and locked properties. - $config->set("formats.{$type}.name", $format['title']); - $config->set("formats.{$type}.locked", $format['locked']); + $config = config("system.date_format.$type") + ->set('id', $type) + ->set('label', $format['title']) + ->set('locked', $format['locked']) + ->set('status', 1) + ->set('uuid', $uuid->generate()); // Get the default date format for this type. $variable_name = 'date_format_' . $type; $default_format = update_variable_get($variable_name, NULL); if ($default_format) { // In Drupal 7 we only used PHP date types. - $config->set("formats.{$type}.pattern.php", $default_format); + $config->set('pattern.php', $default_format); // Delete the migrated variables. update_variable_del($variable_name); } + // Save the date configuration object. + $config->save(); } + } - // Save the date configuration object. - $config->save(); + // Install the new HTML date formats. + $new_formats = array( + 'system.date_format.html_date', + 'system.date_format.html_datetime', + 'system.date_format.html_month', + 'system.date_format.html_time', + 'system.date_format.html_week', + 'system.date_format.html_year', + 'system.date_format.html_yearless_date', + ); + foreach ($new_formats as $new_format) { + update_7_to_8_install_default_config('module', $new_format); } } diff --git a/core/modules/system/system.module b/core/modules/system/system.module index abc9f9c..410a2cd 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -864,10 +864,8 @@ function system_menu() { $items['admin/config/regional/date-time'] = array( 'title' => 'Date and time formats', 'description' => 'Configure display format strings for date and time.', - 'page callback' => 'system_date_time_formats', - 'access arguments' => array('administer site configuration'), + 'route_name' => 'date_format_list', 'weight' => -9, - 'file' => 'system.admin.inc', ); $items['admin/config/regional/date-time/formats/add'] = array( 'title' => 'Add format', @@ -876,26 +874,16 @@ function system_menu() { 'route_name' => 'date_format_add', 'weight' => -10, ); - $items['admin/config/regional/date-time/formats/%/edit'] = array( + $items['admin/config/regional/date-time/formats/manage/%'] = array( 'title' => 'Edit date format', 'description' => 'Allow users to edit a configured date format.', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('system_configure_date_formats_form', 5), - 'access arguments' => array('administer site configuration'), - 'file' => 'system.admin.inc', + 'route_name' => 'date_format_edit', ); - $items['admin/config/regional/date-time/formats/%/delete'] = array( + $items['admin/config/regional/date-time/formats/manage/%/delete'] = array( 'title' => 'Delete date format', 'description' => 'Allow users to delete a configured date format.', 'route_name' => 'date_format_delete', ); - $items['admin/config/regional/date-time/formats/lookup'] = array( - 'title' => 'Date and time lookup', - 'page callback' => 'system_date_time_lookup', - 'access arguments' => array('administer site configuration'), - 'type' => MENU_CALLBACK, - 'file' => 'system.admin.inc', - ); // Search settings. $items['admin/config/search'] = array( @@ -2530,26 +2518,6 @@ function system_page_build(&$page) { } /** - * Select locale date format details from database. - * - * @param $languages - * An array of language codes. - * - * @return - * An array of date formats. - */ -function system_get_localized_date_format($languages) { - // Get list of different format types. - foreach ($languages as $language) { - $date_formats = config('locale.config.' . $language . '.system.date')->get('formats'); - if (!empty($date_formats)) { - return $date_formats; - } - } - return array(); -} - -/** * Implements hook_custom_theme(). */ function system_custom_theme() { @@ -3657,114 +3625,6 @@ function system_run_automated_cron() { } /** - * Gets the list of defined date formats and attributes. - * - * @return array - * An associative array of date formats. The top-level keys are the - * machine-readable names of the date formats. The values are associative - * arrays with the following keys: - * - name: The string human readable name of the date format. - * - pattern: An associative array of patterns that will modify the format - * of the date, keyed with 'php' for normal PHP date pattern and 'intl' - * for the alternate pattern used by the IntlDateFormatter. - */ -function system_get_date_formats() { - return config('system.date')->get('formats'); -} - -/** - * Gets the appropriate date format string for a date type and locale. - * - * @param $langcode - * (optional) String language code for the current locale. This can be a 2 character - * language code like 'en' and 'fr' or a 5 character language code like - * 'en-gb' and 'en-us'. - * @param $date_format_id - * (optional) String machine name for the date format. - * - * @return - * If $date_format_id and $langcode are specified, returns the corresponding - * date format string. If only $langcode is specified, returns an array of - * all date format strings for that locale, keyed by the date type. If - * neither is specified returns FALSE. - */ -function system_date_format_locale($langcode = NULL, $date_format_id = NULL) { - $formats = &drupal_static(__FUNCTION__); - - if (!isset($formats[$langcode])) { - $formats[$langcode] = config('locale.config.' . $langcode . '.system.date')->get('formats'); - } - - if ($date_format_id && $langcode && !empty($formats[$langcode][$date_format_id])) { - return $formats[$langcode][$date_format_id]; - } - elseif ($langcode && !empty($formats[$langcode])) { - return $formats[$langcode]; - } - - return FALSE; -} - -/** - * Saves a date format to the database. - * - * @param string $date_format_id - * If set, replace the existing date format having this ID with the - * information specified in $format_info. - * @param array $format_info - * A date format array containing the following keys: - * - name: The string name of the date type this format is associated with. - * - pattern: An associative array keyed by 'php' and 'intl' with the PHP - * and/or IntlDateFormatter date format strings for each. - * - locked: A boolean indicating whether or not this format should be - * configurable from the user interface. - * - * @see http://php.net/date - */ -function system_date_format_save($date_format_id, $format_info) { - config('system.date') - ->set('formats.' . $date_format_id, $format_info) - ->save(); - - $languages = language_list(); - - $locale_format = array( - 'name' => $format_info['name'], - 'pattern' => $format_info['pattern'], - ); - - // Check if the suggested language codes are configured. - if (!empty($format_info['locales'])) { - foreach ($format_info['locales'] as $langcode) { - if (isset($languages[$langcode])) { - config('locale.config.' . $langcode . '.system.date') - ->set('formats.' . $date_format_id, $locale_format) - ->save(); - } - } - } -} - -/** - * Deletes a date format from the database. - * - * @param $date_format_id - * The date format ID. - */ -function system_date_format_delete($date_format_id) { - $format_id = 'formats.' . $date_format_id; - config('system.date')->clear($format_id)->save(); - - // Clean up the localized entry if required. - foreach (language_list() as $langcode => $data) { - $config = config('locale.config.' . $langcode . '.system.date'); - if ($config->get($format_id)) { - $config->clear($format_id)->save(); - } - } -} - -/** * Returns HTML for a confirmation form. * * By default this does not alter the appearance of a form at all, diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml index 0ba8674..8b94355 100644 --- a/core/modules/system/system.routing.yml +++ b/core/modules/system/system.routing.yml @@ -74,33 +74,41 @@ system_site_maintenance_mode: requirements: _permission: 'administer site configuration' -date_format_add: - pattern: '/admin/config/regional/date-time/formats/add' +system_run_cron: + pattern: '/admin/reports/status/run-cron' defaults: - _form: '\Drupal\system\Form\DateFormatAddForm' + _controller: '\Drupal\system\CronController::runManually' requirements: _permission: 'administer site configuration' -date_format_edit: - pattern: '/admin/config/regional/date-time/formats/{date_format_id}/edit' +date_format_list: + pattern: '/admin/config/regional/date-time' defaults: - _form: '\Drupal\system\Form\DateFormatEditForm' + _content: '\Drupal\Core\Entity\Controller\EntityListController::listing' + entity_type: 'date_format' requirements: _permission: 'administer site configuration' -system_run_cron: - pattern: '/admin/reports/status/run-cron' +date_format_add: + pattern: '/admin/config/regional/date-time/formats/add' defaults: - _controller: '\Drupal\system\CronController::runManually' + _entity_form: 'date_format.add' requirements: _permission: 'administer site configuration' +date_format_edit: + pattern: '/admin/config/regional/date-time/formats/manage/{date_format}' + defaults: + _entity_form: 'date_format.edit' + requirements: + _entity_access: 'date_format.update' + date_format_delete: - pattern: 'admin/config/regional/date-time/formats/{format_id}/delete' + pattern: 'admin/config/regional/date-time/formats/manage/{date_format}/delete' defaults: - _form: '\Drupal\system\Form\DateFormatDeleteForm' + _entity_form: 'date_format.delete' requirements: - _permission: 'administer site configuration' + _entity_access: 'date_format.delete' date_format_localize_reset: pattern: 'admin/config/regional/date-time/locale/{langcode}/reset' diff --git a/core/modules/user/lib/Drupal/user/Tests/UserTimeZoneTest.php b/core/modules/user/lib/Drupal/user/Tests/UserTimeZoneTest.php index 8b77915..894555e 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserTimeZoneTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserTimeZoneTest.php @@ -30,8 +30,8 @@ function testUserTimeZone() { ->set('user.configurable', 1) ->set('default', 'America/Los_Angeles') ->save(); - config('system.date') - ->set('formats.medium.pattern.php', 'Y-m-d H:i T') + entity_load('date_format', 'medium') + ->setPattern('Y-m-d H:i T') ->save(); // Create a user account and login. diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/field/Date.php b/core/modules/views/lib/Drupal/views/Plugin/views/field/Date.php index a19c50b..7e30140 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/field/Date.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/field/Date.php @@ -31,9 +31,11 @@ protected function defineOptions() { public function buildOptionsForm(&$form, &$form_state) { $date_formats = array(); - $date_types = system_get_date_formats(); + $date_types = \Drupal::entityManager() + ->getStorageController('date_format') + ->load(); foreach ($date_types as $machine_name => $value) { - $date_formats[$machine_name] = t('@name format: @date', array('@name' => $value['name'], '@date' => format_date(REQUEST_TIME, $machine_name))); + $date_formats[$machine_name] = t('@name format: @date', array('@name' => $value->label(), '@date' => format_date(REQUEST_TIME, $machine_name))); } $form['date_format'] = array( diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewUnitTestBase.php b/core/modules/views/lib/Drupal/views/Tests/ViewUnitTestBase.php index 1213cc0..670e2e5 100644 --- a/core/modules/views/lib/Drupal/views/Tests/ViewUnitTestBase.php +++ b/core/modules/views/lib/Drupal/views/Tests/ViewUnitTestBase.php @@ -63,7 +63,11 @@ protected function setUpFixtures() { $query->execute(); // Tests implementing ViewUnitTestBase depend on the theme system being - // properly configured. + // properly configured. If the child test depends on the language module, + // enable the language table first. + if ($this->container->get('module_handler')->moduleExists('language')) { + $this->installSchema('language', 'language'); + } $this->installConfig(array('system')); ViewTestData::importTestViews(get_class($this), array('views_test_config')); } diff --git a/core/modules/views/lib/Drupal/views/Tests/Wizard/WizardPluginBaseUnitTest.php b/core/modules/views/lib/Drupal/views/Tests/Wizard/WizardPluginBaseUnitTest.php index b191e9a..20c0109 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Wizard/WizardPluginBaseUnitTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Wizard/WizardPluginBaseUnitTest.php @@ -43,7 +43,6 @@ public static function getInfo() { protected function setUp() { parent::setUp(); - $this->installSchema('language', 'language'); $this->installSchema('system', 'variable'); $this->enableModules(array('views_ui'));