',
+ $form['machine_name'] = array(
+ '#title' => t('Machine readable name'),
+ '#description' => t('The unique machine readable name for this date type, can only contain lowercase letters, numbers and underscores.'),
'#type' => 'textfield',
- '#title' => t('Custom medium date format'),
- '#attributes' => array('class' => array('custom-format')),
- '#default_value' => $default_medium_custom,
- '#description' => t('A user-defined medium date format. See the PHP manual for available options. This format is currently set to display as %date.', array('@url' => 'http://php.net/manual/function.date.php', '%date' => format_date(REQUEST_TIME, 'custom', $default_medium_custom))),
+ '#required' => TRUE,
+ '#attached' => array(
+ 'js' => array(drupal_get_path('module', 'system') . '/system.js', $js_settings),
+ ),
);
- $date_format_long = variable_get('date_format_long', $date_long[0]);
- $form['date_formats']['date_format_long'] = array(
- '#prefix' => '
',
- '#suffix' => '
',
+ // Get list of all available date formats.
+ $formats = array();
+ $date_formats = system_get_date_formats('', TRUE); // Call this to rebuild the list, and to have default list.
+ foreach ($date_formats as $type => $format_info) {
+ $formats = array_merge($formats, $format_info);
+ }
+ $custom_formats = system_get_date_formats('custom');
+ if (!empty($custom_formats)) {
+ $formats = array_merge($formats, $custom_formats);
+ }
+ $choices = array();
+ foreach ($formats as $f => $format) {
+ $choices[$f] = format_date(REQUEST_TIME, 'custom', $f);
+ }
+ // Show date format select list.
+ $form['date_format'] = array(
'#type' => 'select',
- '#title' => t('Long date format'),
+ '#title' => t('Date format'),
'#attributes' => array('class' => array('date-format')),
- '#default_value' => (isset($date_long_choices[$date_format_long]) ? $date_format_long : 'custom'),
- '#options' => $date_long_choices,
+ '#options' => $choices,
+ '#required' => TRUE,
);
- $default_long_custom = variable_get('date_format_long_custom', (isset($date_long_choices[$date_format_long]) ? $date_format_long : ''));
- $form['date_formats']['date_format_long_custom'] = array(
- '#prefix' => '
',
- '#suffix' => '
',
- '#type' => 'textfield',
- '#title' => t('Custom long date format'),
- '#attributes' => array('class' => array('custom-format')),
- '#default_value' => $default_long_custom,
- '#description' => t('A user-defined long date format. See the PHP manual for available options. This format is currently set to display as %date.', array('@url' => 'http://php.net/manual/function.date.php', '%date' => format_date(REQUEST_TIME, 'custom', $default_long_custom))),
+ $form['submit'] = array(
+ '#type' => 'submit',
+ '#value' => t('Add date type'),
);
- $form = system_settings_form($form, FALSE);
- // We will call system_settings_form_submit() manually, so remove it for now.
- unset($form['#submit']);
+ $form['#validate'][] = 'system_add_date_format_type_form_validate';
+ $form['#submit'][] = 'system_add_date_format_type_form_submit';
+
return $form;
}
/**
- * Process system_regional_settings form submissions.
+ * Validate system_add_date_format_type form submissions.
*/
-function system_regional_settings_submit($form, &$form_state) {
- if ($form_state['values']['date_format_short'] == 'custom') {
- $form_state['values']['date_format_short'] = $form_state['values']['date_format_short_custom'];
- }
- if ($form_state['values']['date_format_medium'] == 'custom') {
- $form_state['values']['date_format_medium'] = $form_state['values']['date_format_medium_custom'];
- }
- if ($form_state['values']['date_format_long'] == 'custom') {
- $form_state['values']['date_format_long'] = $form_state['values']['date_format_long_custom'];
+function system_add_date_format_type_form_validate($form, &$form_state) {
+ if (!empty($form_state['values']['machine_name']) && !empty($form_state['values']['date_type'])) {
+ if (!preg_match("/^[a-zA-Z0-9_]+$/", trim($form_state['values']['machine_name']))) {
+ form_set_error('machine_name', t('The date type must contain only alphanumeric characters and underscores.'));
+ }
+ $types = system_get_date_types();
+ if (in_array(trim($form_state['values']['machine_name']), array_keys($types))) {
+ form_set_error('machine_name', t('This date type already exists. Please enter a unique type.'));
+ }
}
- return system_settings_form_submit($form, $form_state);
+}
+
+/**
+ * Process system_add_date_format_type form submissions.
+ */
+function system_add_date_format_type_form_submit($form, &$form_state) {
+ include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'system') . '/' . 'system.date.inc';
+ $machine_name = trim($form_state['values']['machine_name']);
+
+ $format_type = array();
+ $format_type['title'] = trim($form_state['values']['date_type']);
+ $format_type['type'] = $machine_name;
+ $format_type['locked'] = 0;
+ $format_type['is_new'] = 1;
+ system_date_format_type_save($format_type);
+ variable_set('date_format_' . $machine_name, $form_state['values']['date_format']);
+
+ drupal_set_message(t('New date type added successfully.'));
+ $form_state['redirect'] = 'admin/config/regional/date-time';
}
/**
@@ -2300,3 +2418,185 @@ function theme_system_themes_form($form)
$output .= drupal_render_children($form);
return $output;
}
+
+/**
+ * Menu callback; present a form for deleting a date format.
+ */
+function system_date_delete_format_form(&$form_state, $dfid) {
+ $form = array();
+ $form['dfid'] = array(
+ '#type' => 'value',
+ '#value' => $dfid,
+ );
+ $format = system_get_date_format($dfid);
+
+ $output = confirm_form($form,
+ t('Are you sure you want to remove the format %format?', array('%format' => format_date(REQUEST_TIME, 'custom', $format->format))),
+ 'admin/config/regional/date-time/formats',
+ t('This action cannot be undone.'),
+ t('Remove'), t('Cancel'),
+ 'confirm'
+ );
+
+ return $output;
+}
+
+/**
+ * Delete a configured date format.
+ */
+function system_date_delete_format_form_submit($form, &$form_state) {
+ include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'system') . '/' . 'system.date.inc';
+ if ($form_state['values']['confirm']) {
+ $format = system_get_date_format($form_state['values']['dfid']);
+ system_date_format_delete($form_state['values']['dfid']);
+ drupal_set_message(t('Removed date format %format.', array('%format' => format_date(REQUEST_TIME, 'custom', $format->format))));
+ $form_state['redirect'] = 'admin/config/regional/date-time/formats';
+ }
+}
+
+/**
+ * Menu callback; present a form for deleting a date type.
+ */
+function system_delete_date_format_type_form(&$form_state, $format_type) {
+ $form = array();
+ $form['format_type'] = array(
+ '#type' => 'value',
+ '#value' => $format_type,
+ );
+ $type_info = system_get_date_types($format_type);
+
+ $output = confirm_form($form,
+ t('Are you sure you want to remove the date type %type?', array('%type' => $type_info['title'])),
+ 'admin/config/regional/date-time',
+ t('This action cannot be undone.'),
+ t('Remove'), t('Cancel'),
+ 'confirm'
+ );
+
+ return $output;
+}
+
+/**
+ * Delete a configured date type.
+ */
+function system_delete_date_format_type_form_submit($form, &$form_state) {
+ include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'system') . '/' . 'system.date.inc';
+ if ($form_state['values']['confirm']) {
+ $type_info = system_get_date_types($form_state['values']['format_type']);
+ system_date_format_type_delete($form_state['values']['format_type']);
+ drupal_set_message(t('Removed date type %type.', array('%type' => $type_info['title'])));
+ $form_state['redirect'] = 'admin/config/regional/date-time';
+ }
+}
+
+
+/**
+ * Displays the date format strings overview page.
+ */
+function system_date_time_formats() {
+ $header = array(t('Format'), array('data' => t('Operations'), 'colspan' => '2'));
+ $rows = array();
+
+ $formats = system_get_date_formats('custom', TRUE);
+ if (!empty($formats)) {
+ foreach ($formats as $format) {
+ $row = array();
+ $row[] = array('data' => format_date(REQUEST_TIME, 'custom', $format['format']));
+ $row[] = array('data' => l(t('edit'), 'admin/config/regional/date-time/formats/edit/' . $format['dfid']));
+ $row[] = array('data' => l(t('delete'), 'admin/config/regional/date-time/formats/delete/' . $format['dfid']));
+ $rows[] = $row;
+ }
+ }
+
+ if (empty($rows)) {
+ $rows[] = array(array('data' => t('No custom date formats available. Add date format.', array('@link' => url('admin/config/regional/date-time/formats/add'))), 'colspan' => '5', 'class' => array('message')));
+ }
+
+ $build['date_formats_table'] = array(
+ '#theme' => 'table',
+ '#header' => $header,
+ '#rows' => $rows
+ );
+
+ return $build;
+}
+
+/**
+ * Allow users to add additional date formats.
+ */
+function system_configure_date_formats_form($edit, $dfid = 0) {
+ $js_settings = array(
+ 'type' => 'setting',
+ 'data' => array(
+ 'dateTime' => array(
+ 'date-format' => array(
+ 'text' => t('Displayed as'),
+ 'lookup' => url('admin/config/regional/date-time/formats/lookup'),
+ ),
+ ),
+ ),
+ );
+
+ if ($dfid) {
+ $form['dfid'] = array(
+ '#type' => 'value',
+ '#value' => $dfid,
+ );
+ $format = system_get_date_format($dfid);
+ }
+
+ $now = ($dfid ? t('Displayed as %date', array('%date' => format_date(REQUEST_TIME, 'custom', $format->format))) : '');
+
+ $form['date_format'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Format string'),
+ '#description' => t('A user-defined date format. See the PHP manual for available options.', array('@url' => 'http://php.net/manual/function.date.php')),
+ '#default_value' => ($dfid ? $format->format : ''),
+ '#field_suffix' => ' ' . $now . '',
+ '#attached' => array(
+ 'js' => array(drupal_get_path('module', 'system') . '/system.js', $js_settings),
+ ),
+ );
+
+ $form['update'] = array(
+ '#type' => 'submit',
+ '#value' => ($dfid ? t('Save format') : t('Add format')),
+ );
+
+ $form['#validate'][] = 'system_add_date_formats_form_validate';
+ $form['#submit'][] = 'system_add_date_formats_form_submit';
+
+ return $form;
+}
+
+/**
+ * Validate new date format string submission.
+ */
+function system_add_date_formats_form_validate($form, &$form_state) {
+ $formats = system_get_date_formats('custom');
+ $format = trim($form_state['values']['date_format']);
+ if (!empty($formats) && in_array($format, array_keys($formats)) && (!isset($form_state['values']['dfid']) || $form_state['values']['dfid'] != $formats[$format]['dfid'])) {
+ form_set_error('date_format', t('This format already exists. Please enter a unique format string.'));
+ }
+}
+
+/**
+ * Process new date format string submission.
+ */
+function system_add_date_formats_form_submit($form, &$form_state) {
+ $format = array();
+ $format['format'] = trim($form_state['values']['date_format']);
+ $format['type'] = 'custom';
+ $format['locked'] = 0;
+ if (!empty($form_state['values']['dfid'])) {
+ system_date_format_save($format, $form_state['values']['dfid']);
+ drupal_set_message(t('Custom date format updated.'));
+ }
+ else {
+ $format['is_new'] = 1;
+ system_date_format_save($format);
+ drupal_set_message(t('Custom date format added.'));
+ }
+
+ $form_state['redirect'] = 'admin/config/regional/date-time/formats';
+}
Index: modules/system/system.date.inc
===================================================================
RCS file: modules/system/system.date.inc
diff -N modules/system/system.date.inc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/system/system.date.inc 15 Sep 2009 08:10:26 -0000
@@ -0,0 +1,238 @@
+ $type_title) {
+ $type = array();
+ $type['module'] = $module;
+ $type['type'] = $module_type;
+ $type['title'] = $type_title;
+ $type['locked'] = 1;
+ $type['is_new'] = TRUE; // Will be over-ridden later if in the db.
+ $types[$module_type] = $type;
+ }
+ }
+
+ // Get custom formats added to the database by the end user.
+ $result = db_query('SELECT dft.type, dft.title, dft.locked FROM {date_format_types} dft ORDER BY dft.title');
+ foreach ($result as $record) {
+ if (!in_array($record->type, $types)) {
+ $type = array();
+ $type['is_new'] = FALSE;
+ $type['module'] = '';
+ $type['type'] = $record->type;
+ $type['title'] = $record->title;
+ $type['locked'] = $record->locked;
+ $types[$record->type] = $type;
+ }
+ else {
+ $type = array();
+ $type['is_new'] = FALSE; // Over-riding previous setting.
+ $types[$record->type] = array_merge($types[$record->type], $type);
+ }
+ }
+
+ // Allow other modules to modify these date types.
+ drupal_alter('date_format_types', $types);
+
+ return $types;
+}
+
+/**
+ * Builds and returns the list of available date formats.
+ *
+ * @return
+ * Array of date formats.
+ */
+function _system_date_formats_build() {
+ $date_formats = array();
+
+ // First handle hook_date_format_types().
+ $types = _system_date_format_types_build();
+ foreach ($types as $type => $info) {
+ system_date_format_type_save($info);
+ }
+
+ // Get formats supplied by various contrib modules.
+ $module_formats = module_invoke_all('date_formats');
+
+ foreach ($module_formats as $module_format) {
+ $module_format['locked'] = 1; // System types are locked.
+ // If no date type is specified, assign 'custom'.
+ if (!isset($module_format['type'])) {
+ $module_format['type'] = 'custom';
+ }
+ if (!in_array($module_format['type'], array_keys($types))) {
+ continue;
+ }
+ if (!isset($date_formats[$module_format['type']])) {
+ $date_formats[$module_format['type']] = array();
+ }
+
+ // If another module already set this format, merge in the new settings.
+ if (isset($date_formats[$module_format['type']][$module_format['format']])) {
+ $date_formats[$module_format['type']][$module_format['format']] = array_merge_recursive($date_formats[$module_format['type']][$module_format['format']], $format);
+ }
+ else {
+ // This setting will be overridden later if it already exists in the db.
+ $module_format['is_new'] = TRUE;
+ $date_formats[$module_format['type']][$module_format['format']] = $module_format;
+ }
+ }
+
+ // Get custom formats added to the database by the end user.
+ $result = db_query('SELECT df.dfid, df.format, df.type, df.locked, dfl.language FROM {date_formats} df LEFT JOIN {date_format_types} dft ON df.type = dft.type LEFT JOIN {date_format_locale} dfl ON df.format = dfl.format AND df.type = dfl.type ORDER BY df.type, df.format');
+ foreach ($result as $record) {
+ // If this date type isn't set, initialise the array.
+ if (!isset($date_formats[$record->type])) {
+ $date_formats[$record->type] = array();
+ }
+ // If this format not already present, add it to the array.
+ if (!isset($date_formats[$record->type][$record->format])) {
+ // We don't set 'is_new' as it is already in the db.
+ $format = array();
+ $format['module'] = '';
+ $format['dfid'] = $record->dfid;
+ $format['format'] = $record->format;
+ $format['type'] = $record->type;
+ $format['locked'] = $record->locked;
+ $format['locales'] = array($record->language);
+ $date_formats[$record->type][$record->format] = $format;
+ }
+ // Format already present, so merge in settings.
+ else {
+ $format = array();
+ $format['is_new'] = FALSE; // It's in the db, so override this setting.
+ $format['dfid'] = $record->dfid;
+ $format['format'] = $record->format;
+ $format['type'] = $record->type;
+ $format['locked'] = $record->locked;
+ if (!empty($record->language)) {
+ $format['locales'] = array_merge($date_formats[$record->type][$record->format]['locales'], array($record->language));
+ }
+ $date_formats[$record->type][$record->format] = array_merge($date_formats[$record->type][$record->format], $format);
+ }
+ }
+
+ // Allow other modules to modify these formats.
+ drupal_alter('date_formats', $date_formats);
+
+ return $date_formats;
+}
+
+/**
+ * Save a date type to the database.
+ *
+ * @param $date_format_type
+ * An array of attributes for a date type.
+ */
+function system_date_format_type_save($date_format_type) {
+ $type = array();
+ $type['type'] = $date_format_type['type'];
+ $type['title'] = $date_format_type['title'];
+ $type['locked'] = $date_format_type['locked'];
+
+ // Update date_format table.
+ if (isset($date_format_type['is_new']) && !empty($date_format_type['is_new'])) {
+ drupal_write_record('date_format_types', $type);
+ }
+ else {
+ drupal_write_record('date_format_types', $type, 'type');
+ }
+}
+
+/**
+ * Delete a date type from the database.
+ *
+ * @param $date_format_type
+ * The date type name.
+ */
+function system_date_format_type_delete($date_format_type) {
+ db_delete('date_formats')
+ ->condition('type', $date_format_type)
+ ->execute();
+ db_delete('date_format_types')
+ ->condition('type', $date_format_type)
+ ->execute();
+ db_delete('date_format_locale')
+ ->condition('type', $date_format_type)
+ ->execute();
+}
+
+/**
+ * Save a date format to the database.
+ *
+ * @param $date_format
+ * An array of attributes for a date format.
+ * @param $dfid
+ * If set, replace an existing date format with a new string using this
+ * identifier.
+ */
+function system_date_format_save($date_format, $dfid = 0) {
+ $format = array();
+ $format['dfid'] = $dfid;
+ $format['type'] = $date_format['type'];
+ $format['format'] = $date_format['format'];
+ $format['locked'] = $date_format['locked'];
+
+ // Update date_format table.
+ if (isset($date_format['is_new']) && !empty($date_format['is_new'])) {
+ drupal_write_record('date_formats', $format);
+ }
+ else {
+ $keys = ($dfid ? array('dfid') : array('format', 'type'));
+ drupal_write_record('date_formats', $format, $keys);
+ }
+
+ $languages = language_list('enabled');
+ $languages = $languages[1];
+
+ $locale_format = array();
+ $locale_format['type'] = $date_format['type'];
+ $locale_format['format'] = $date_format['format'];
+
+ // Check if the suggested language codes are configured and enabled.
+ if (!empty($date_format['locales'])) {
+ foreach ($date_format['locales'] as $langcode) {
+ // Only proceed if language is enabled.
+ if (in_array($langcode, $languages)) {
+ $is_existing = (bool) db_query_range('SELECT 1 FROM {date_format_locale} WHERE type = :type AND language = :language', array(':type' => $date_format['type'], ':language' => $langcode), 0, 1)->fetchField();
+ if (!$is_existing) {
+ $locale_format['language'] = $langcode;
+ drupal_write_record('date_format_locale', $locale_format);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Delete a date format from the database.
+ *
+ * @param $date_format_id
+ * The date format string identifier.
+ */
+function system_date_format_delete($dfid) {
+ db_delete('date_formats')
+ ->condition('dfid', $dfid)
+ ->execute();
+}
+
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.385
diff -u -p -r1.385 system.install
--- modules/system/system.install 10 Sep 2009 06:38:20 -0000 1.385
+++ modules/system/system.install 15 Sep 2009 08:10:28 -0000
@@ -691,6 +691,90 @@ function system_schema() {
$schema['cache_registry'] = $schema['cache'];
$schema['cache_registry']['description'] = 'Cache table for the code registry system to remember what code files need to be loaded on any given page.';
+ $schema['date_format_types'] = array(
+ 'description' => 'For storing configured date format types.',
+ 'fields' => array(
+ 'type' => array(
+ 'description' => 'The date format type, e.g. medium.',
+ 'type' => 'varchar',
+ 'length' => 200,
+ 'not null' => TRUE,
+ ),
+ 'title' => array(
+ 'description' => 'The human readable name of the format type.',
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => TRUE,
+ ),
+ 'locked' => array(
+ 'description' => 'Whether or not this is a system provided format.',
+ 'type' => 'int',
+ 'size' => 'tiny',
+ 'default' => 0,
+ 'not null' => TRUE,
+ ),
+ ),
+ 'primary key' => array('type'),
+ );
+
+ $schema['date_formats'] = array(
+ 'description' => 'For storing configured date formats.',
+ 'fields' => array(
+ 'dfid' => array(
+ 'description' => 'The date format identifier.',
+ 'type' => 'serial',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ ),
+ 'format' => array(
+ 'description' => 'The date format string.',
+ 'type' => 'varchar',
+ 'length' => 100,
+ 'not null' => TRUE,
+ ),
+ 'type' => array(
+ 'description' => 'The date format type, e.g. medium.',
+ 'type' => 'varchar',
+ 'length' => 200,
+ 'not null' => TRUE,
+ ),
+ 'locked' => array(
+ 'description' => 'Whether or not this format can be modified.',
+ 'type' => 'int',
+ 'size' => 'tiny',
+ 'default' => 0,
+ 'not null' => TRUE,
+ ),
+ ),
+ 'primary key' => array('dfid'),
+ 'unique keys' => array('formats' => array('format', 'type')),
+ );
+
+ $schema['date_format_locale'] = array(
+ 'description' => 'For storing configured date formats for each locale.',
+ 'fields' => array(
+ 'format' => array(
+ 'description' => 'The date format string.',
+ 'type' => 'varchar',
+ 'length' => 100,
+ 'not null' => TRUE,
+ ),
+ 'type' => array(
+ 'description' => 'The date format type, e.g. medium.',
+ 'type' => 'varchar',
+ 'length' => 200,
+ 'not null' => TRUE,
+ ),
+ 'language' => array(
+ 'description' => 'A {languages}.language for this format to be used with.',
+ 'type' => 'varchar',
+ 'length' => 12,
+ 'not null' => TRUE,
+ ),
+ ),
+ 'primary key' => array('type', 'language'),
+ );
+
$schema['file'] = array(
'description' => 'Stores information for uploaded files.',
'fields' => array(
@@ -2472,6 +2556,103 @@ function system_update_7037() {
}
/**
+ * Create new date format tables.
+ */
+function system_update_7038() {
+ $ret = array();
+
+ $schema['date_format_types'] = array(
+ 'description' => 'For storing configured date format types.',
+ 'fields' => array(
+ 'type' => array(
+ 'description' => 'The date format type, e.g. medium.',
+ 'type' => 'varchar',
+ 'length' => 200,
+ 'not null' => TRUE,
+ ),
+ 'title' => array(
+ 'description' => 'The human readable name of the format type.',
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => TRUE,
+ ),
+ 'locked' => array(
+ 'description' => 'Whether or not this is a system provided format.',
+ 'type' => 'int',
+ 'size' => 'tiny',
+ 'default' => 0,
+ 'not null' => TRUE,
+ ),
+ ),
+ 'primary key' => array('type'),
+ );
+
+ $schema['date_formats'] = array(
+ 'description' => 'For storing configured date formats.',
+ 'fields' => array(
+ 'dfid' => array(
+ 'description' => 'The date format identifier.',
+ 'type' => 'serial',
+ 'not null' => TRUE,
+ 'unsigned' => TRUE,
+ ),
+ 'format' => array(
+ 'description' => 'The date format string.',
+ 'type' => 'varchar',
+ 'length' => 100,
+ 'not null' => TRUE,
+ ),
+ 'type' => array(
+ 'description' => 'The date format type, e.g. medium.',
+ 'type' => 'varchar',
+ 'length' => 200,
+ 'not null' => TRUE,
+ ),
+ 'locked' => array(
+ 'description' => 'Whether or not this format can be modified.',
+ 'type' => 'int',
+ 'size' => 'tiny',
+ 'default' => 0,
+ 'not null' => TRUE,
+ ),
+ ),
+ 'primary key' => array('dfid'),
+ 'unique keys' => array('formats' => array('format', 'type')),
+ );
+
+ $schema['date_format_locale'] = array(
+ 'description' => 'For storing configured date formats for each locale.',
+ 'fields' => array(
+ 'format' => array(
+ 'description' => 'The date format string.',
+ 'type' => 'varchar',
+ 'length' => 100,
+ 'not null' => TRUE,
+ ),
+ 'type' => array(
+ 'description' => 'The date format type, e.g. medium.',
+ 'type' => 'varchar',
+ 'length' => 200,
+ 'not null' => TRUE,
+ ),
+ 'language' => array(
+ 'description' => 'A {languages}.language for this format to be used with.',
+ 'type' => 'varchar',
+ 'length' => 12,
+ 'not null' => TRUE,
+ ),
+ ),
+ 'primary key' => array('type', 'language'),
+ );
+
+ db_create_table($ret, 'date_format_types', $schema['date_format_types']);
+ db_create_table($ret, 'date_formats', $schema['date_formats']);
+ db_create_table($ret, 'date_format_locale', $schema['date_format_locale']);
+
+ return $ret;
+}
+
+/**
* @} End of "defgroup updates-6.x-to-7.x"
* The next series of updates should start at 8000.
*/
Index: modules/system/system.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.js,v
retrieving revision 1.35
diff -u -p -r1.35 system.js
--- modules/system/system.js 9 Sep 2009 21:53:15 -0000 1.35
+++ modules/system/system.js 15 Sep 2009 08:10:28 -0000
@@ -96,23 +96,21 @@ Drupal.behaviors.copyFieldValue = {
* Show/hide custom format sections on the regional settings page.
*/
Drupal.behaviors.dateTime = {
- attach: function (context, settings) {
- // Show/hide custom format depending on the select's value.
- $('select.date-format', context).once('date-time').change(function () {
- $(this).parents('div.date-container').children('div.custom-container')[$(this).val() == 'custom' ? 'show' : 'hide']();
- });
+ attach: function (context) {
+ for (var value in Drupal.settings.dateTime) {
+ var settings = Drupal.settings.dateTime[value];
+ var source = '#edit-' + value;
+ var suffix = source + '-suffix';
- // Attach keyup handler to custom format inputs.
- $('input.custom-format', context).once('date-time').keyup(function () {
- var input = $(this);
- var url = settings.dateTime.lookup + (settings.dateTime.lookup.match(/\?q=/) ? '&format=' : '?format=') + encodeURIComponent(input.val());
- $.getJSON(url, function (data) {
- $('div.description span', input.parent()).html(data);
+ // Attach keyup handler to custom format inputs.
+ $('input' + source, context).once('date-time').keyup(function () {
+ var input = $(this);
+ var url = settings.lookup + (settings.lookup.match(/\?q=/) ? '&format=' : '?format=') + encodeURIComponent(input.val());
+ $.getJSON(url, function (data) {
+ $(suffix).empty().append(' ' + settings.text + ': ' + data + '');
+ });
});
- });
-
- // Trigger the event handler to show the form input if necessary.
- $('select.date-format', context).trigger('change');
+ }
}
};
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.789
diff -u -p -r1.789 system.module
--- modules/system/system.module 11 Sep 2009 02:14:20 -0000 1.789
+++ modules/system/system.module 15 Sep 2009 08:10:33 -0000
@@ -101,7 +101,7 @@ function system_help($path, $arg) {
$output .= '
' . t('support for enabling and disabling themes, which determine the design and presentation of your site. Drupal comes packaged with several core themes and additional contributed themes are available at the Drupal.org theme page.', array('@themes' => url('admin/appearance'), '@drupal-themes' => 'http://drupal.org/project/themes')) . '
';
$output .= '
' . t('a robust caching system that allows the efficient re-use of previously-constructed web pages and web page components. Drupal stores the pages requested by anonymous users in a compressed format; depending on your site configuration and the amount of your web traffic tied to anonymous visitors, Drupal\'s caching system may significantly increase the speed of your site.', array('@cache-settings' => url('admin/config/development/performance'))) . '
';
$output .= '
' . t('a set of routine administrative operations that rely on a correctly-configured cron maintenance task to run automatically. A number of other modules, including the feed aggregator, and search also rely on cron maintenance tasks. For more information, see the online handbook entry for configuring cron jobs.', array('@cron' => url('admin/reports/status'), '@handbook' => 'http://drupal.org/cron')) . '
';
- $output .= '
' . t('basic configuration options for your site, including date and time settings, file system settings, clean URL support, site name and other information, and a maintenance mode for taking your site temporarily offline.', array('@regional-settings' => url('admin/config/regional/settings'), '@file-system' => url('admin/config/media/file-system'), '@clean-url' => url('admin/config/search/clean-urls'), '@site-info' => url('admin/config/system/site-information'), '@maintenance-mode' => url('admin/config/development/maintenance'))) . '
';
+ $output .= '
' . t('basic configuration options for your site, including date and time settings, file system settings, clean URL support, site name and other information, and a maintenance mode for taking your site temporarily offline.', array('@date-time-settings' => url('admin/config/regional/date-time'), '@file-system' => url('admin/config/media/file-system'), '@clean-url' => url('admin/config/search/clean-urls'), '@site-info' => url('admin/config/system/site-information'), '@maintenance-mode' => url('admin/config/development/maintenance'))) . '
';
$output .= '
' . t('For more information, see the online handbook entry for System module.', array('@system' => 'http://drupal.org/handbook/modules/system/')) . '
';
return $output;
case 'admin/by-module':
@@ -204,6 +204,10 @@ function system_theme() {
'system_run_cron_image' => array(
'arguments' => array('image_path' => NULL),
),
+ 'system_date_time_settings' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'system.admin.inc',
+ ),
));
}
@@ -773,6 +777,8 @@ function system_menu() {
'access arguments' => array('administer site configuration'),
'file' => 'system.admin.inc',
);
+
+ // Regional and date settings.
$items['admin/config/regional'] = array(
'title' => 'Regional and language',
'description' => 'Regional settings, localization and translation.',
@@ -784,20 +790,96 @@ function system_menu() {
);
$items['admin/config/regional/settings'] = array(
'title' => 'Regional settings',
- 'description' => "Settings for how Drupal displays date and time, as well as the system's default time zone.",
+ 'description' => "Settings for the site's default time zone and country settings.",
'page callback' => 'drupal_get_form',
'page arguments' => array('system_regional_settings'),
'access arguments' => array('administer site configuration'),
'weight' => -10,
'file' => 'system.admin.inc',
);
- $items['admin/config/regional/settings/lookup'] = array(
+ $items['admin/config/regional/date-time'] = array(
+ 'title' => 'Date and time',
+ 'description' => 'Configure display formats for date and time.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_date_time_settings'),
+ 'access arguments' => array('administer site configuration'),
+ 'weight' => -9,
+ 'file' => 'system.admin.inc',
+ );
+ $items['admin/config/regional/date-time/types'] = array(
+ 'title' => 'Types',
+ 'description' => 'Configure display formats for date and time.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_date_time_settings'),
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_DEFAULT_LOCAL_TASK,
+ 'weight' => -10,
+ 'file' => 'system.admin.inc',
+ );
+ $items['admin/config/regional/date-time/types/add'] = array(
+ 'title' => 'Add date type',
+ 'description' => 'Add new date type.',
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_add_date_format_type_form'),
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_LOCAL_ACTION,
+ 'weight' => -10,
+ 'file' => 'system.admin.inc',
+ );
+ $items['admin/config/regional/date-time/types/delete/%'] = array(
+ 'title' => 'Delete date type',
+ 'description' => 'Allow users to delete a configured date type.',
+ 'type' => MENU_CALLBACK,
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_delete_date_format_type_form', 6),
+ 'access arguments' => array('administer site configuration'),
+ 'file' => 'system.admin.inc',
+ );
+ $items['admin/config/regional/date-time/formats'] = array(
+ 'title' => 'Formats',
+ 'description' => 'Configure display format strings for date and time.',
+ 'page callback' => 'system_date_time_formats',
+ 'access arguments' => array('administer site configuration'),
+ 'type' => MENU_LOCAL_TASK,
+ 'weight' => -9,
+ 'file' => 'system.admin.inc',
+ );
+ $items['admin/config/regional/date-time/formats/add'] = array(
+ 'title' => 'Add format',
+ 'description' => 'Allow users to add additional date formats.',
+ 'type' => MENU_LOCAL_ACTION,
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_configure_date_formats_form'),
+ 'access arguments' => array('administer site configuration'),
+ 'weight' => -10,
+ 'file' => 'system.admin.inc',
+ );
+ $items['admin/config/regional/date-time/formats/edit/%'] = array(
+ 'title' => 'Edit date format',
+ 'description' => 'Allow users to edit a configured date format.',
+ 'type' => MENU_CALLBACK,
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_configure_date_formats_form', 6),
+ 'access arguments' => array('administer site configuration'),
+ 'file' => 'system.admin.inc',
+ );
+ $items['admin/config/regional/date-time/formats/delete/%'] = array(
+ 'title' => 'Delete date format',
+ 'description' => 'Allow users to delete a configured date format.',
+ 'type' => MENU_CALLBACK,
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('system_date_delete_format_form', 6),
+ 'access arguments' => array('administer site configuration'),
+ 'file' => 'system.admin.inc',
+ );
+ $items['admin/config/regional/date-time/formats/lookup'] = array(
'title' => 'Date and time lookup',
'type' => MENU_CALLBACK,
'page callback' => 'system_date_time_lookup',
'access arguments' => array('administer site configuration'),
'file' => 'system.admin.inc',
);
+
$items['admin/config/search'] = array(
'title' => 'Search and metadata',
'description' => 'Local site search, metadata and SEO.',
@@ -2391,6 +2473,9 @@ function system_cron() {
foreach ($cache_tables as $table) {
cache_clear_all(NULL, $table);
}
+
+ // Rebuild list of date formats.
+ system_date_formats_rebuild();
// Reset expired items in the default queue implementation table. If that's
// not used, this will simply be a no-op.
@@ -3158,3 +3243,141 @@ function theme_system_run_cron_image($im
return '';
}
+/**
+ * Get the list of available date types and attributes.
+ *
+ * @param $type
+ * The date type, e.g. 'short', 'medium', 'long', 'custom'. If empty, then
+ * all attributes for that type will be returned.
+ * @param $reset
+ * Whether or not to reset this function's internal cache (defaults to FALSE).
+ * @return
+ * Array of date types.
+ */
+function system_get_date_types($type = NULL, $reset = FALSE) {
+ static $_date_format_types;
+
+ if ($reset || !isset($_date_format_types)) {
+ include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'system') . '/' . 'system.date.inc';
+ $_date_format_types = _system_date_format_types_build();
+ }
+
+ return $type ? (isset($_date_format_types[$type]) ? $_date_format_types[$type] : FALSE) : $_date_format_types;
+}
+
+/**
+ * Implements hook_date_format_types().
+ */
+function system_date_format_types() {
+ return array(
+ 'long' => t('Long'),
+ 'medium' => t('Medium'),
+ 'short' => t('Short'),
+ );
+}
+
+/**
+ * Implements hook_date_formats().
+ *
+ * @return
+ * An array of date formats with attributes 'type' (short, medium or long),
+ * 'format' (the format string) and 'locales'. The 'locales' attribute is an
+ * array of locales, which can include both 2 character language codes like
+ * 'en', 'fr', but also 5 character language codes like 'en-gb' and 'en-us'.
+ */
+function system_date_formats() {
+ include_once DRUPAL_ROOT . '/includes/date_formats.inc';
+ return system_default_date_formats();
+}
+
+/**
+ * Get the list of date formats for a particular format length.
+ *
+ * @param $type
+ * The date type: 'short', 'medium', 'long', 'custom'. If empty, then all
+ * available types will be returned.
+ * @param $reset
+ * Whether or not to reset this function's internal cache (defaults to FALSE).
+ * @return
+ * Array of date formats.
+ */
+function system_get_date_formats($type = NULL, $reset = FALSE) {
+ static $_date_formats;
+
+ if ($reset || !isset($_date_formats)) {
+ include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'system') . '/' . 'system.date.inc';
+ $_date_formats = _system_date_formats_build();
+ }
+
+ return $type ? (isset($_date_formats[$type]) ? $_date_formats[$type] : FALSE) : $_date_formats;
+}
+
+/**
+ * Get the format details for a particular id.
+ *
+ * @param $dfid
+ * Identifier of a date format string.
+ * @return
+ * Array of date format details.
+ */
+function system_get_date_format($dfid) {
+ $format = db_query('SELECT df.dfid, df.format, df.type, df.locked FROM {date_formats} df WHERE df.dfid = :dfid', array(':dfid' => $dfid))->fetch();
+ return $format;
+}
+
+/**
+ * Resets the database cache of date formats, and saves all new date formats to
+ * the database.
+ */
+function system_date_formats_rebuild() {
+ include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'system') . '/' . 'system.date.inc';
+ $date_formats = system_get_date_formats(NULL, TRUE);
+
+ foreach ($date_formats as $format_type => $formats) {
+ foreach ($formats as $format => $info) {
+ system_date_format_save($info);
+ }
+ }
+
+ // Rebuild configured date formats locale list.
+ system_date_format_locale(NULL, NULL, TRUE);
+
+ _system_date_formats_build();
+}
+
+/**
+ * Get the appropriate date format for a type and locale.
+ *
+ * @param $langcode
+ * Language code for the current locale. This can be a 2 character language
+ * code like 'en', 'fr', or a longer 5 character code like 'en-gb'.
+ * @param $type
+ * Date type: short, medium, long, custom.
+ * @param $reset
+ * Whether or not to reset this function's internal cache (defaults to FALSE).
+ * @return
+ * The format string, or NULL if no matching format found.
+ */
+function system_date_format_locale($langcode = NULL, $type = NULL, $reset = FALSE) {
+ static $formats;
+
+ if ($reset || empty($formats)) {
+ $formats = array();
+ $result = db_query("SELECT format, type, language FROM {date_format_locale}");
+ foreach ($result as $record) {
+ if (!isset($formats[$record->language])) {
+ $formats[$record->language] = array();
+ }
+ $formats[$record->language][$record->type] = $record->format;
+ }
+ }
+
+ if ($type && $langcode && !empty($formats[$langcode][$type])) {
+ return $formats[$langcode][$type];
+ }
+ elseif ($langcode && !empty($formats[$langcode])) {
+ return $formats[$langcode];
+ }
+
+ return FALSE;
+}
Index: modules/system/system.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.test,v
retrieving revision 1.75
diff -u -p -r1.75 system.test
--- modules/system/system.test 1 Sep 2009 16:50:12 -0000 1.75
+++ modules/system/system.test 15 Sep 2009 08:10:33 -0000
@@ -727,6 +727,15 @@ class DateTimeFunctionalTest extends Dru
);
}
+ function setUp() {
+ parent::setUp();
+
+ // Create admin user and log in admin user.
+ $this->admin_user = $this->drupalCreateUser(array('administer site configuration'));
+ $this->drupalLogin($this->admin_user);
+ }
+
+
/**
* Test time zones and DST handling.
*/
@@ -757,6 +766,77 @@ class DateTimeFunctionalTest extends Dru
$this->drupalGet("node/$node2->nid");
$this->assertText('2007-08-01 00:00:00 -0700', t('Date should be three hours ahead, with GMT offset of -7 hours.'));
}
+
+ /**
+ * Test date type configuration.
+ */
+ function testDateTypeConfiguration() {
+ // Confirm system date types appear.
+ $this->drupalGet('admin/config/regional/date-time');
+ $this->assertText(t('Medium'), 'System date types appear in date type list.');
+ $this->assertNoRaw('href="/admin/config/regional/date-time/types/delete/medium"', 'No delete link appear for system date types.');
+
+ // Add custom date type.
+ $this->clickLink(t('Add date type'));
+ $date_type = $this->randomName(8);
+ $machine_name = 'machine_' . $date_type;
+ $date_format = 'd.m.Y - H:i';
+ $edit = array(
+ 'date_type' => $date_type,
+ 'machine_name' => $machine_name,
+ 'date_format' => $date_format,
+ );
+ $this->drupalPost('admin/config/regional/date-time/types/add', $edit, t('Add date type'));
+ $this->assertEqual($this->getUrl(), url('admin/config/regional/date-time', array('absolute' => TRUE)), t('Correct page redirection.'));
+ $this->assertText(t('New date type added successfully.'), 'Date type added confirmation message appears.');
+ $this->assertText($date_type, 'Custom date type appears in the date type list.');
+ $this->assertText(t('delete'), 'Delete link for custom date type appears.');
+
+ // Delete custom date type.
+ $this->clickLink(t('delete'));
+ $this->drupalPost('admin/config/regional/date-time/types/delete/' . $machine_name, array(), t('Remove'));
+ $this->assertEqual($this->getUrl(), url('admin/config/regional/date-time', array('absolute' => TRUE)), t('Correct page redirection.'));
+ $this->assertText(t('Removed date type ' . $date_type), 'Custom date type removed.');
+ }
+
+ /**
+ * Test date format configuration.
+ */
+ function testDateFormatConfiguration() {
+ // Confirm 'no custom date formats available' message appears.
+ $this->drupalGet('admin/config/regional/date-time/formats');
+ $this->assertText(t('No custom date formats available.'), 'No custom date formats message appears.');
+
+ // Add custom date format.
+ $this->clickLink(t('Add format'));
+ $edit = array(
+ 'date_format' => 'Y',
+ );
+ $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)), t('Correct page redirection.'));
+ $this->assertNoText(t('No custom date formats available.'), 'No custom date formats message does not appear.');
+ $this->assertText(t('Custom date format added.'), 'Custom date format added.');
+
+ // Ensure custom date format appears in date type configuration options.
+ $this->drupalGet('admin/config/regional/date-time');
+ $this->assertRaw('