Now all modules are in core modules folder
This commit is contained in:
parent
5ba1cdfa0b
commit
05b6a91b0c
1907 changed files with 0 additions and 0 deletions
13
modules/date/date/date.info
Normal file
13
modules/date/date/date.info
Normal file
|
@ -0,0 +1,13 @@
|
|||
name = Date
|
||||
description = Defines CCK date/time fields and widgets.
|
||||
dependencies[] = content
|
||||
dependencies[] = date_api
|
||||
dependencies[] = date_timezone
|
||||
package = Date/Time
|
||||
core = 6.x
|
||||
; Information added by Drupal.org packaging script on 2014-03-31
|
||||
version = "6.x-2.10"
|
||||
core = "6.x"
|
||||
project = "date"
|
||||
datestamp = "1396284252"
|
||||
|
457
modules/date/date/date.install
Normal file
457
modules/date/date/date.install
Normal file
|
@ -0,0 +1,457 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Implementation of hook_install().
|
||||
* Reset the date caches.
|
||||
*/
|
||||
function date_install() {
|
||||
drupal_load('module', 'content');
|
||||
content_notify('install', 'date');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_uninstall().
|
||||
*/
|
||||
function date_uninstall() {
|
||||
drupal_load('module', 'content');
|
||||
content_notify('uninstall', 'date');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_enable().
|
||||
* Reset the calendar caches.
|
||||
*/
|
||||
function date_enable() {
|
||||
drupal_load('module', 'content');
|
||||
content_notify('enable', 'date');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_disable().
|
||||
* Empty the date caches.
|
||||
*/
|
||||
function date_disable() {
|
||||
drupal_load('module', 'content');
|
||||
content_notify('disable', 'date');
|
||||
}
|
||||
|
||||
function date_update_last_removed() {
|
||||
return 5210;
|
||||
}
|
||||
|
||||
/**
|
||||
* Granularity options were not saved correctly by CCK if created using checkboxes.
|
||||
* Checkboxes have been changed back to a select and we need to fix the values
|
||||
* stored in the settings.
|
||||
*
|
||||
* The bad values would have been stored in the form
|
||||
* array(
|
||||
* 'year' => 'year'
|
||||
* 'month' => 'month',
|
||||
* 'day' => 0,
|
||||
* 'hour' => 0,
|
||||
* 'minute' => 0,
|
||||
* 'second' => 0,
|
||||
* );
|
||||
*
|
||||
* Good values would have been stored in the form
|
||||
* array(
|
||||
* 'year' => 'year',
|
||||
* 'month' => 'month',
|
||||
* );
|
||||
*
|
||||
* This might or might not have gotten updated in D5.2,
|
||||
* we need to force it again in D6 just in case.
|
||||
*
|
||||
* @return unknown
|
||||
*/
|
||||
function date_update_6000() {
|
||||
include_once(drupal_get_path('module', 'content') .'/content.install');
|
||||
if ($abort = content_check_update('date')) {
|
||||
return $abort;
|
||||
}
|
||||
drupal_load('module', 'content');
|
||||
$ret = array();
|
||||
$result = db_query("SELECT field_name, global_settings from {". content_field_tablename() ."} where type LIKE 'date_%'");
|
||||
while ($field = db_fetch_array($result)) {
|
||||
// Change the format to one date_popup can use.
|
||||
$field_settings = unserialize($field['global_settings']);
|
||||
$granularity = array_filter($field_settings['granularity']);
|
||||
$field_settings['granularity'] = $granularity;
|
||||
db_query("UPDATE {". content_field_tablename() ."} SET global_settings = '%s' WHERE field_name = '%s'", serialize($field_settings), $field['field_name']);
|
||||
}
|
||||
content_clear_type_cache();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rid of jscalendar popup widget.
|
||||
* Originally update_5201, but that was broken.
|
||||
*/
|
||||
function date_update_6001() {
|
||||
include_once(drupal_get_path('module', 'content') .'/content.install');
|
||||
if ($abort = content_check_update('date')) {
|
||||
return $abort;
|
||||
}
|
||||
drupal_load('module', 'content');
|
||||
$ret = array();
|
||||
if (db_result(db_query("SELECT COUNT(*) FROM {". content_instance_tablename() ."} WHERE widget_type = 'date_js'"))) {
|
||||
$replace = module_exists('date_popup') ? 'date_popup' : 'date_text';
|
||||
$result = db_query("SELECT field_name, type_name, widget_type from {". content_instance_tablename() ."} where widget_type = 'date_js'");
|
||||
while ($widget = db_fetch_array($result)) {
|
||||
db_query("UPDATE {". content_instance_tablename() ."} SET widget_type = '$replace' WHERE field_name = '%s' AND type_name = '%s'", $widget['field_name'], $widget['type_name']);
|
||||
}
|
||||
drupal_set_message(t('All date fields using the jscalendar widget have been changed to use the text widget instead, since the jscalendar widget is no longer supported. Enable the Date Popup module to make a jQuery popup calendar available and edit the field settings to select it.'));
|
||||
content_clear_type_cache();
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch to using different widgets for repeating dates so non-repeats
|
||||
* can use standard Content module multiple values handling.
|
||||
*/
|
||||
function date_update_6002() {
|
||||
include_once(drupal_get_path('module', 'content') .'/content.install');
|
||||
if ($abort = content_check_update('date')) {
|
||||
return $abort;
|
||||
}
|
||||
drupal_load('module', 'content');
|
||||
$ret = array();
|
||||
$types = content_types();
|
||||
$repeating_fields = array();
|
||||
foreach ($types as $type) {
|
||||
foreach ($type['fields'] as $field_name => $field) {
|
||||
if (!empty($field['repeat'])) {
|
||||
$repeating_fields[] = $field_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($repeating_fields)) {
|
||||
$replace = array(
|
||||
'date_select' => 'date_select_repeat',
|
||||
'date_text' => 'date_text_repeat',
|
||||
'date_popup' => 'date_popup_repeat',
|
||||
);
|
||||
$result = db_query("SELECT * from {". content_instance_tablename() ."} WHERE widget_type IN('date_select', 'date_text', 'date_popup') AND field_name IN('". implode("','", $repeating_fields) ."')");
|
||||
while ($widget = db_fetch_array($result)) {
|
||||
db_query("UPDATE {". content_field_tablename() ."} SET multiple = 1 WHERE field_name = '%s'", $widget['field_name']);
|
||||
db_query("UPDATE {". content_instance_tablename() ."} SET widget_type = '". $replace[$widget['widget_type']] ."' WHERE field_name = '%s' AND type_name = '%s'", $widget['field_name'], $widget['type_name']);
|
||||
}
|
||||
drupal_set_message(t('All repeating date fields have been updated to use the new repeating widgets.'));
|
||||
content_clear_type_cache();
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all repeating date delta values with the RRULE
|
||||
* so we can use that info in Views when we pull individual items
|
||||
* out in a query.
|
||||
*/
|
||||
function date_update_6003() {
|
||||
$ret = array();
|
||||
drupal_load('module', 'content');
|
||||
$fields = content_fields();
|
||||
foreach ($fields as $field) {
|
||||
if (strstr($field['type'], 'date') && !empty($field['repeat'])) {
|
||||
$db_info = content_database_info($field);
|
||||
$table = $db_info['table'];
|
||||
$column = $field['field_name'] .'_rrule';
|
||||
$result = db_query("SELECT DISTINCT nid, vid, $column FROM {". $table ."} WHERE $column <> ''");
|
||||
while ($row = db_fetch_array($result)) {
|
||||
$ret[] = update_sql("UPDATE {". $table ."} SET $column='". $row[$column] ."' WHERE nid=". $row['nid'] ." AND vid=". $row['vid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty the stored db for timezones that use timezone 'none'.
|
||||
*/
|
||||
function date_update_6004() {
|
||||
$ret = array();
|
||||
drupal_load('module', 'content');
|
||||
$fields = content_fields();
|
||||
foreach ($fields as $field) {
|
||||
if (strstr($field['type'], 'date') && !empty($field['tz_handling']) && $field['tz_handling'] == 'none') {
|
||||
$row = db_result(db_query("SELECT global_settings FROM {". content_field_tablename() ."} WHERE field_name='". $field['field_name'] ."'"));
|
||||
$settings = unserialize($row);
|
||||
$settings['timezone_db'] = '';
|
||||
$settings = serialize($settings);
|
||||
db_query("UPDATE {". content_field_tablename() ."} SET global_settings='%s' WHERE field_name='%s'", $settings, $field['field_name']);
|
||||
}
|
||||
}
|
||||
drupal_set_message(t("The database has been updated to correct the stored timezone for fields using timezone 'none'."));
|
||||
content_clear_type_cache();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function date_update_6005() {
|
||||
include_once(drupal_get_path('module', 'content') .'/content.install');
|
||||
if ($abort = content_check_update('date')) {
|
||||
return $abort;
|
||||
}
|
||||
// The new format table won't get built before the system tries to run this update.
|
||||
// We need to abort and tell the user to re-run it.
|
||||
// We need a custom abort process because the content_check_update could be OK
|
||||
// but we still need to update these values.
|
||||
if ((!db_table_exists('date_format') && !db_table_exists('date_formats')) || !db_table_exists('date_format_types')) {
|
||||
drupal_set_message(t('Some updates are still pending. Please return to <a href="@update-php">update.php</a> and run the remaining updates.', array('@update-php' => base_path() .'update.php?op=selection')), 'error', FALSE);
|
||||
$ret['#abort'] = array('success' => FALSE, 'query' => t('Some updates are still pending.<br/>Please re-run the update script.'));
|
||||
return $ret;
|
||||
}
|
||||
drupal_load('module', 'content');
|
||||
$ret = array();
|
||||
|
||||
$new_map = array(
|
||||
'short' => 'short',
|
||||
'medium' => 'medium',
|
||||
'long' => 'long',
|
||||
'time' => 'time',
|
||||
'time_timezone' => 'time_timezone',
|
||||
'iso' => 'iso',
|
||||
'timestamp' => 'timestamp',
|
||||
'ical' => 'ical',
|
||||
'feed' => 'feed',
|
||||
);
|
||||
|
||||
// Create new custom formats for each of these:
|
||||
date_install_create_format(NULL, t('Time'), 'time', date_limit_format(variable_get('date_format_short', 'm/d/Y - H:i'), array('hour', 'minute', 'second')));
|
||||
date_install_create_format(NULL, t('Time with timezone'), 'time_timezone', date_limit_format(variable_get('date_format_short', 'm/d/Y - H:i') .' e', array('hour', 'minute', 'second', 'timezone')));
|
||||
date_install_create_format(NULL, t('iCal'), 'ical', 'Ymd\THis');
|
||||
date_install_create_format(NULL, t('Timestamp'), 'timestamp', 'U');
|
||||
date_install_create_format(NULL, t('Feed'), 'feed', 'D, j M Y H:i:s O');
|
||||
date_install_create_format(NULL, t('ISO'), 'iso', DATE_FORMAT_ISO);
|
||||
|
||||
$result = db_query("SELECT field_name, global_settings from {". content_field_tablename() ."} where type='date' OR type='datestamp' OR type='datetime'");
|
||||
while ($field = db_fetch_array($result)) {
|
||||
$field_settings = unserialize($field['global_settings']);
|
||||
$field_name = $field['field_name'];
|
||||
|
||||
$default = !empty($field_settings['output_format_custom']) ? $field_settings['output_format_custom'] : $field_settings['output_format_date'];
|
||||
$short = !empty($field_settings['output_format_custom_short']) ? $field_settings['output_format_custom_short'] : $field_settings['output_format_date_short'];
|
||||
$med = !empty($field_settings['output_format_custom_medium']) ? $field_settings['output_format_custom_medium'] : $field_settings['output_format_date_medium'];
|
||||
$long = !empty($field_settings['output_format_custom_long']) ? $field_settings['output_format_custom_long'] : $field_settings['output_format_date_long'];
|
||||
$system_short = variable_get('date_format_short', 'm/d/Y - H:i');
|
||||
$system_med = variable_get('date_format_medium', 'D, m/d/Y - H:i');
|
||||
$system_long = variable_get('date_format_long', 'l, F j, Y - H:i');
|
||||
|
||||
// The only thing we'll keep is the name of a default format type.
|
||||
$new_setting = 'default_format';
|
||||
|
||||
// Create a map of the old and new formats.
|
||||
$map = $new_map;
|
||||
|
||||
// If the field's long, medium, or short formats don't match the system
|
||||
// values, create custom format types for them.
|
||||
|
||||
// If the default value matches a custom format, set that new format
|
||||
// type as the default format type.
|
||||
|
||||
if ($system_short != $short) {
|
||||
$name = $field_name .'_short';
|
||||
date_install_create_format($field, NULL, $name, $short);
|
||||
$map['short'] = $name;
|
||||
if ($default == $short) {
|
||||
$field_settings[$new_setting] = $name;
|
||||
$map['default'] = $name;
|
||||
}
|
||||
}
|
||||
if ($system_med != $med) {
|
||||
$name = $field_name .'_medium';
|
||||
date_install_create_format($field, NULL, $name, $med);
|
||||
$map['medium'] = $name;
|
||||
if ($default == $med) {
|
||||
$field_settings[$new_setting] = $name;
|
||||
$map['default'] = $name;
|
||||
}
|
||||
}
|
||||
if ($system_long != $long) {
|
||||
$name = $field_name .'_long';
|
||||
date_install_create_format($field, NULL, $name, $long);
|
||||
$map['long'] = $name;
|
||||
if ($default == $long) {
|
||||
$field_settings[$new_setting] = $name;
|
||||
$map['default'] = $name;
|
||||
}
|
||||
}
|
||||
// If we haven't found a format type for the default format yet,
|
||||
// see if it matches any of the system formats.
|
||||
if (empty($field_settings[$new_setting])) {
|
||||
if ($default == $system_med) {
|
||||
$field_settings[$new_setting] = 'medium';
|
||||
$map['default'] = 'medium';
|
||||
}
|
||||
elseif ($default == $system_long) {
|
||||
$field_settings[$new_setting] = 'long';
|
||||
$map['default'] = 'long';
|
||||
}
|
||||
elseif ($default == $system_short) {
|
||||
$field_settings[$new_setting] = 'short';
|
||||
$map['default'] = 'short';
|
||||
}
|
||||
else {
|
||||
// If all else fails, create a new format type
|
||||
// for the default format.
|
||||
$name = $field_name .'_default';
|
||||
date_install_create_format($field, NULL, $name, $default);
|
||||
$field_settings[$new_setting] = $name;
|
||||
$map['default'] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
// Store the map of old and new formats in a variable.
|
||||
variable_set('date_format_map_'. $field['field_name'], $map);
|
||||
$ret[] = array('success' => TRUE, 'query' => t('Field %field formats were converted to custom formats.', array('%field' => $field_name)));
|
||||
foreach ($map as $key => $value) {
|
||||
if (in_array($key, array('default', 'short', 'medium', 'long'))) {
|
||||
$ret[] = array('success' => TRUE, 'query' => t("The old format type %from_format for field %field was converted to the new format type %to_format.", array('%field' => $field_name, '%from_format' => $key, '%to_format' => $value)));
|
||||
}
|
||||
}
|
||||
|
||||
// Unset all the old values, we won't use them any more.
|
||||
unset($field_settings['output_format_date']);
|
||||
unset($field_settings['output_format_custom']);
|
||||
unset($field_settings['output_format_date_short']);
|
||||
unset($field_settings['output_format_custom_short']);
|
||||
unset($field_settings['output_format_date_medium']);
|
||||
unset($field_settings['output_format_custom_medium']);
|
||||
unset($field_settings['output_format_date_long']);
|
||||
unset($field_settings['output_format_custom_long']);
|
||||
|
||||
db_query("UPDATE {". content_field_tablename() ."} SET global_settings = '%s' WHERE field_name = '%s'", serialize($field_settings), $field_name);
|
||||
|
||||
// Update the display settings to point to the new format types.
|
||||
$result2 = db_query("SELECT * FROM {". content_instance_tablename() ."} WHERE field_name = '$field_name'");
|
||||
while ($instance = db_fetch_array($result2)) {
|
||||
$display_settings = unserialize($instance['display_settings']);
|
||||
foreach ($display_settings as $key => $setting) {
|
||||
if ($key != 'label' && array_key_exists($display_settings[$key]['format'], $map)) {
|
||||
$display_settings[$key]['format'] = $map[$display_settings[$key]['format']];
|
||||
}
|
||||
}
|
||||
db_query("UPDATE {". content_instance_tablename() ."} SET display_settings = '%s' WHERE field_name = '%s' AND type_name = '%s'", serialize($display_settings), $field_name, $instance['type_name']);
|
||||
$ret[] = array('success' => TRUE, 'query' => t("The display settings for field %field in content type %type_name were updated.", array('%field' => $field_name, '%type_name' => $instance['type_name'])));
|
||||
}
|
||||
|
||||
// See if any views stored in the database need date formats updated.
|
||||
/*
|
||||
$result2 = db_query("SELECT * FROM {views_display}");
|
||||
while ($row = db_fetch_array($result2)) {
|
||||
$updated = FALSE;
|
||||
$display_options = unserialize($row['display_options']);
|
||||
if (array_key_exists('fields', $display_options)) {
|
||||
if (array_key_exists($field_name .'_value', $display_options['fields'])) {
|
||||
$display_options['fields'][$field_name .'_value']['format'] = $map[$display_options['fields'][$field_name .'_value']['format']];
|
||||
$updated = TRUE;
|
||||
}
|
||||
if (array_key_exists($field_name .'_value2', $display_options['fields'])) {
|
||||
$display_options['fields'][$field_name .'_value2']['format'] = $map[$display_options['fields'][$field_name .'_value2']['format']];
|
||||
$updated = TRUE;
|
||||
}
|
||||
if ($updated) {
|
||||
db_query("UPDATE {views_display} SET display_options='%s'", serialize($display_options));
|
||||
$ret[] = array('success' => TRUE, 'query' => t("The format used for field %field in view %vid %display display was updated to the new format name.", array('%field' => $field_name, '%display' => $row['display_title'], '%vid' => $row['vid'])));
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
// Clear any caches that may have old formats in them.
|
||||
content_clear_type_cache();
|
||||
drupal_set_message(t('Date display formats are now included with the system date and time settings. Please visit <a href="@date-time-page">the Date and time format page</a> to see the new format types.', array('@date-time-page' => url('admin/settings/date-time/formats'))));
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function date_install_create_format($field, $title, $name, $format) {
|
||||
if (empty($name) || empty($format)) {
|
||||
return;
|
||||
}
|
||||
$fields = content_fields();
|
||||
if (empty($title)) {
|
||||
$type = str_replace($field['field_name'] .'_', '', $name);
|
||||
$field = $fields[$field['field_name']];
|
||||
$title = $field['widget']['label'];
|
||||
}
|
||||
variable_set('date_format_'. $name, $format);
|
||||
db_query("INSERT INTO {date_format_types} (type, title, locked) VALUES('%s', '%s', 0)", $name, $title);
|
||||
if (!db_result(db_query("SELECT dfid FROM {date_formats} WHERE format='%s' AND type='%s'", $format, $type))) {
|
||||
db_query("INSERT INTO {date_formats} (format, type, locked) VALUES('%s', '%s', 0)", $format, 'custom');
|
||||
}
|
||||
}
|
||||
|
||||
function date_db_integrity($name) {
|
||||
$ret = array();
|
||||
if (!module_exists('content') || !module_exists('date_api')) {
|
||||
return $ret;
|
||||
}
|
||||
drupal_load('module', 'content');
|
||||
require_once('./'. drupal_get_path('module', 'content') .'/includes/content.admin.inc');
|
||||
$ret = array();
|
||||
$fields = content_fields();
|
||||
foreach ($fields as $field) {
|
||||
$db_info = content_database_info($field);
|
||||
if ($field['type'] == 'date' || $field['type'] == 'datestamp') {
|
||||
$table = $db_info['table'];
|
||||
|
||||
// start with the new column patterns.
|
||||
$columns_start = $db_info['columns'];
|
||||
$columns_end = $db_info['columns'];
|
||||
|
||||
// alter the start column values to invalid or empty
|
||||
// values to force the new columns to be reset.
|
||||
$columns_start['value']['length'] = 90;
|
||||
if (!empty($field['todate'])) {
|
||||
if (!db_column_exists($table, $columns_start['value2']['column'])) {
|
||||
unset($columns_start['value2']);
|
||||
}
|
||||
else {
|
||||
$columns_start['value2']['length'] = 80;
|
||||
}
|
||||
}
|
||||
if ($field['tz_handling'] == 'date') {
|
||||
if (!db_column_exists($table, $columns_start['timezone']['column'])) {
|
||||
unset($columns_start['timezone']);
|
||||
}
|
||||
else {
|
||||
$columns_start['timezone']['length'] = 80;
|
||||
}
|
||||
if (!db_column_exists($table, $columns_start['offset']['column'])) {
|
||||
unset($columns_start['offset']);
|
||||
}
|
||||
else {
|
||||
$columns_start['offset']['length'] = 80;
|
||||
}
|
||||
if ($field['todate']) {
|
||||
if (!db_column_exists($table, $columns_start['offset2']['column'])) {
|
||||
unset($columns_start['offset2']);
|
||||
}
|
||||
else {
|
||||
$columns_start['offset2']['length'] = 80;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($field['repeat'])) {
|
||||
if (!db_column_exists($table, $columns_start['rrule']['column'])) {
|
||||
unset($columns_start['rrule']);
|
||||
}
|
||||
else {
|
||||
$columns_start['rrule']['length'] = 80;
|
||||
}
|
||||
}
|
||||
$start_field = $field;
|
||||
$start_field['columns'] = $columns_start;
|
||||
$end_field = $field;
|
||||
$end_field['columns'] = $columns_end;
|
||||
content_alter_db($start_field, $end_field);
|
||||
$message = 'Date database integrity check. Updated table '. $table .' to set all columns to accept NULL values.';
|
||||
$ret[] = array('success' => TRUE, 'query' => $message);
|
||||
}
|
||||
}
|
||||
content_clear_type_cache();
|
||||
return $ret;
|
||||
}
|
||||
|
887
modules/date/date/date.module
Normal file
887
modules/date/date/date.module
Normal file
|
@ -0,0 +1,887 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Defines date/time field types for the Content Construction Kit (CCK).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of hook_init().
|
||||
*/
|
||||
function date_init() {
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date.theme');
|
||||
if (module_exists('token')) {
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date_token.inc');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_menu().
|
||||
*/
|
||||
function date_menu() {
|
||||
$items = array();
|
||||
// Repeat dates tab on node
|
||||
if (!module_exists('date_repeat')) {
|
||||
return $items;
|
||||
}
|
||||
$items['node/%node/repeats'] = array(
|
||||
'title' => 'Repeats',
|
||||
'page callback' => 'date_repeat_page',
|
||||
'page arguments' => array(1),
|
||||
'access callback' => 'date_repeat_node',
|
||||
'access arguments' => array(1),
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
function date_perm() {
|
||||
return array('view date repeats');
|
||||
}
|
||||
|
||||
function date_repeat_node($node) {
|
||||
if (date_repeat_type($node->type)) {
|
||||
return user_access('view date repeats');
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function date_repeat_type($type_name) {
|
||||
$type = content_types($type_name);
|
||||
if (!empty($type['fields'])) {
|
||||
foreach ($type['fields'] as $field_name => $field) {
|
||||
if (in_array($field['type'], array('date', 'datestamp', 'datetime')) && $field['repeat']) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
function date_repeat_fields($type_name) {
|
||||
$type = content_types($type_name);
|
||||
$fields = array();
|
||||
if (!empty($type['fields'])) {
|
||||
foreach ($type['fields'] as $field_name => $field) {
|
||||
if (in_array($field['type'], array('date', 'datestamp', 'datetime')) && $field['repeat']) {
|
||||
$fields[] = $field_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
function date_repeat_page($node) {
|
||||
drupal_set_title(check_plain($node->title));
|
||||
$node->date_repeat_show_all = TRUE;
|
||||
$node->build_mode = NODE_BUILD_NORMAL;
|
||||
$node->content = array();
|
||||
$field_names = date_repeat_fields($node->type);
|
||||
$view = content_view($node, FALSE, TRUE);
|
||||
$output = '';
|
||||
foreach ($field_names as $field_name) {
|
||||
$output .= drupal_render($node->content[$field_name]);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
function date_is_repeat_field($field) {
|
||||
$repeat_widgets = array(
|
||||
'date_select_repeat',
|
||||
'date_text_repeat',
|
||||
'date_popup_repeat',
|
||||
);
|
||||
if (in_array($field['widget']['type'], $repeat_widgets)) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_content_is_empty().
|
||||
*/
|
||||
function date_content_is_empty($item, $field) {
|
||||
if (empty($item['value'])) {
|
||||
return TRUE;
|
||||
}
|
||||
elseif ($field['todate'] == 'required' && empty($item['value2'])) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_field_info().
|
||||
*/
|
||||
function date_field_info() {
|
||||
return array(
|
||||
'date' => array(
|
||||
'label' => 'Date',
|
||||
'description' => t('Store a date in the database as an ISO date, recommended for historical or partial dates.'),
|
||||
),
|
||||
'datestamp' => array(
|
||||
'label' => 'Datestamp',
|
||||
'description' => t('Store a date in the database as a timestamp, deprecated format to suppport legacy data.'),
|
||||
),
|
||||
'datetime' => array(
|
||||
'label' => 'Datetime',
|
||||
'description' => t('Store a date in the database as a datetime field, recommended for complete dates and times that may need timezone conversion.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_widget_info().
|
||||
*/
|
||||
function date_widget_info() {
|
||||
$info = array(
|
||||
'date_select' => array(
|
||||
'label' => t('Select List'),
|
||||
'field types' => array('date', 'datestamp', 'datetime'),
|
||||
'multiple values' => CONTENT_HANDLE_CORE,
|
||||
'callbacks' => array(
|
||||
'default value' => CONTENT_CALLBACK_CUSTOM,
|
||||
),
|
||||
),
|
||||
'date_select_repeat' => array(
|
||||
'label' => t('Select List with Repeat options'),
|
||||
'field types' => array('date', 'datestamp', 'datetime'),
|
||||
'multiple values' => CONTENT_HANDLE_MODULE,
|
||||
'callbacks' => array(
|
||||
'default value' => CONTENT_CALLBACK_CUSTOM,
|
||||
),
|
||||
),
|
||||
'date_text' => array(
|
||||
'label' => t('Text Field with custom input format'),
|
||||
'field types' => array('date', 'datestamp', 'datetime'),
|
||||
'multiple values' => CONTENT_HANDLE_CORE,
|
||||
'callbacks' => array(
|
||||
'default value' => CONTENT_CALLBACK_CUSTOM,
|
||||
),
|
||||
),
|
||||
'date_text_repeat' => array(
|
||||
'label' => t('Text Field with Repeat options'),
|
||||
'field types' => array('date', 'datestamp', 'datetime'),
|
||||
'multiple values' => CONTENT_HANDLE_MODULE,
|
||||
'callbacks' => array(
|
||||
'default value' => CONTENT_CALLBACK_CUSTOM,
|
||||
),
|
||||
),
|
||||
);
|
||||
if (module_exists('date_popup')) {
|
||||
$info['date_popup'] = array(
|
||||
'label' => t('Text Field with Date Pop-up calendar'),
|
||||
'field types' => array('date', 'datestamp', 'datetime'),
|
||||
'multiple values' => CONTENT_HANDLE_CORE,
|
||||
'callbacks' => array(
|
||||
'default value' => CONTENT_CALLBACK_CUSTOM,
|
||||
),
|
||||
);
|
||||
$info['date_popup_repeat'] = array(
|
||||
'label' => t('Text Field with Date Pop-up and Repeat options'),
|
||||
'field types' => array('date', 'datestamp', 'datetime'),
|
||||
'multiple values' => CONTENT_HANDLE_MODULE,
|
||||
'callbacks' => array(
|
||||
'default value' => CONTENT_CALLBACK_CUSTOM,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (!module_exists('date_repeat')) {
|
||||
unset($info['date_select_repeat']);
|
||||
unset($info['date_text_repeat']);
|
||||
if (isset($info['date_popup_repeat'])) {
|
||||
unset($info['date_popup_repeat']);
|
||||
}
|
||||
}
|
||||
return $info;
|
||||
}
|
||||
|
||||
function date_default_format($type) {
|
||||
if (stristr($type, 'date_popup') && module_exists('date_popup')) {
|
||||
$formats = date_popup_formats();
|
||||
$default_format = array_shift($formats);
|
||||
}
|
||||
else {
|
||||
// example input formats must show all possible date parts, so add seconds.
|
||||
$default_format = str_replace('i', 'i:s', variable_get('date_format_short', 'm/d/Y - H:i'));
|
||||
}
|
||||
return $default_format;
|
||||
}
|
||||
|
||||
function date_input_value($field, $element) {
|
||||
switch ($field['widget']['type']) {
|
||||
case 'date_text':
|
||||
case 'date_text_repeat':
|
||||
$function = 'date_text_input_value';
|
||||
break;
|
||||
case 'date_popup':
|
||||
case 'date_popup_repeat':
|
||||
$function = 'date_popup_input_value';
|
||||
break;
|
||||
default:
|
||||
$function = 'date_select_input_value';
|
||||
}
|
||||
return $function($element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_field_formatter_info().
|
||||
*/
|
||||
function date_field_formatter_info() {
|
||||
$formatters = array(
|
||||
'default' => array('label' => t('Default'),
|
||||
'field types' => array('date', 'datestamp', 'datetime'),
|
||||
'multiple values' => CONTENT_HANDLE_CORE),
|
||||
'format_interval' => array('label' => t('As Time Ago'),
|
||||
'field types' => array('date', 'datestamp', 'datetime'),
|
||||
'multiple values' => CONTENT_HANDLE_CORE),
|
||||
);
|
||||
|
||||
$format_types = date_get_format_types('', TRUE);
|
||||
if (!empty($format_types)) {
|
||||
foreach ($format_types as $type => $type_info) {
|
||||
$formatters[$type] = array(
|
||||
'label' => $type_info['title'],
|
||||
'field types' => array('date', 'datestamp', 'datetime'),
|
||||
'multiple values' => CONTENT_HANDLE_CORE,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $formatters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_theme().
|
||||
*/
|
||||
function date_theme() {
|
||||
$path = drupal_get_path('module', 'date');
|
||||
require_once "./$path/date.theme";
|
||||
|
||||
$base = array(
|
||||
'file' => 'date.theme',
|
||||
'path' => "$path",
|
||||
);
|
||||
$themes = array(
|
||||
'date_combo' => array(
|
||||
'arguments' => array('element' => NULL)),
|
||||
'date_all_day' => array(
|
||||
'arguments' => array(
|
||||
'which' => NULL, 'date1' => NULL, 'date2' => NULL,
|
||||
'format' => NULL, 'node' => NULL, 'view' => NULL)),
|
||||
'date_all_day_label' => array(
|
||||
'arguments' => array()),
|
||||
'date_display_single' => array(
|
||||
'arguments' => array('date' => NULL, 'timezone' => NULL)),
|
||||
'date_display_range' => array(
|
||||
'arguments' => array('date1' => NULL, 'date2' => NULL, 'timezone' => NULL)),
|
||||
'date_text_parts' => array(
|
||||
'arguments' => array('element' => NULL)),
|
||||
'date' => array(
|
||||
'arguments' => array('element' => NULL)),
|
||||
'date_formatter_default' => $base + array(
|
||||
'arguments' => array('element' => NULL),
|
||||
'function' => 'theme_date_display_combination'),
|
||||
'date_formatter_format_interval' => $base + array(
|
||||
'arguments' => array('element' => NULL),
|
||||
'function' => 'theme_date_format_interval'),
|
||||
'date_formatter_format_calendar_day' => $base + array(
|
||||
'arguments' => array('element' => NULL),
|
||||
'function' => 'theme_date_format_calendar_day'),
|
||||
'date_repeat_display' => $base + array(
|
||||
'arguments' => array('field' => NULL,
|
||||
'item' => NULL, 'node' => NULL, 'dates' => NULL),
|
||||
'function' => 'theme_date_repeat_display',
|
||||
),
|
||||
);
|
||||
|
||||
// Table isn't available first time date_theme() is called in update.php.
|
||||
if (db_table_exists('date_format_types')) {
|
||||
$format_types = date_get_format_types('', TRUE);
|
||||
if (!empty($format_types)) {
|
||||
foreach ($format_types as $type => $type_info) {
|
||||
$themes['date_formatter_' . $type] = $base + array(
|
||||
'arguments' => array('element' => NULL),
|
||||
'function' => 'theme_date_display_combination',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $themes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for creating formatted date arrays from a formatter.
|
||||
*
|
||||
* Use the Date API to get an object representation of a date field
|
||||
*
|
||||
* @param array $field
|
||||
* @param array $item - a node field item, like $node->myfield[0]
|
||||
*
|
||||
* @return array that holds the From and To date objects
|
||||
* Each date object looks like:
|
||||
* date [value] => array(
|
||||
* [db] => array( // the value stored in the database
|
||||
* [object] => the datetime object
|
||||
* [datetime] => 2007-02-15 20:00:00
|
||||
* )
|
||||
* [local] => array( // the local representation of that value
|
||||
* [object] => the datetime object
|
||||
* [datetime] => 2007-02-15 14:00:00
|
||||
* [timezone] => US/Central
|
||||
* [offset] => -21600
|
||||
* )
|
||||
* )
|
||||
*/
|
||||
function date_formatter_process($element) {
|
||||
$node = $element['#node'];
|
||||
$dates = array();
|
||||
$timezone = date_default_timezone_name();
|
||||
if (empty($timezone)) {
|
||||
return $dates;
|
||||
}
|
||||
$field_name = $element['#field_name'];
|
||||
$fields = content_fields();
|
||||
$field = $fields[$field_name];
|
||||
$formatter = $element['#formatter'];
|
||||
$format = date_formatter_format($formatter, $field_name);
|
||||
$item = $element['#item'];
|
||||
$timezone = isset($item['timezone']) ? $item['timezone'] : '';
|
||||
$timezone = date_get_timezone($field['tz_handling'], $timezone);
|
||||
$timezone_db = date_get_timezone_db($field['tz_handling']);
|
||||
$process = date_process_values($field);
|
||||
foreach ($process as $processed) {
|
||||
if (empty($item[$processed])) {
|
||||
$dates[$processed] = NULL;
|
||||
}
|
||||
else {
|
||||
// create a date object with a gmt timezone from the database value
|
||||
$value = $item[$processed];
|
||||
if ($field['type'] == DATE_ISO) {
|
||||
$value = str_replace(' ', 'T', date_fuzzy_datetime($value));
|
||||
}
|
||||
$date = date_make_date($value, $timezone_db, $field['type'], $field['granularity']);
|
||||
$dates[$processed] = array();
|
||||
$dates[$processed]['db']['object'] = $date;
|
||||
$dates[$processed]['db']['datetime'] = date_format($date, DATE_FORMAT_DATETIME);
|
||||
|
||||
date_timezone_set($date, timezone_open($timezone));
|
||||
$dates[$processed]['local']['object'] = $date;
|
||||
$dates[$processed]['local']['datetime'] = date_format($date, DATE_FORMAT_DATETIME);
|
||||
$dates[$processed]['local']['timezone'] = $timezone;
|
||||
$dates[$processed]['local']['offset'] = date_offset_get($date);
|
||||
|
||||
//format the date, special casing the 'interval' format which doesn't need to be processed
|
||||
$dates[$processed]['formatted'] = '';
|
||||
if (is_object($date)) {
|
||||
if ($format == 'format_interval') {
|
||||
$dates[$processed]['interval'] = date_format_interval($date);
|
||||
}
|
||||
elseif ($format == 'format_calendar_day') {
|
||||
$dates[$processed]['calendar_day'] = date_format_calendar_day($date);
|
||||
}
|
||||
elseif ($format == 'U') {
|
||||
$dates[$processed]['formatted'] = date_format_date($date, 'custom', $format);
|
||||
$dates[$processed]['formatted_date'] = date_format_date($date, 'custom', $format);
|
||||
$dates[$processed]['formatted_time'] = '';
|
||||
$dates[$processed]['formatted_timezone'] = '';
|
||||
}
|
||||
elseif (!empty($format)) {
|
||||
$dates[$processed]['formatted'] = date_format_date($date, 'custom', $format);
|
||||
$dates[$processed]['formatted_date'] = date_format_date($date, 'custom', date_limit_format($format, array('year', 'month', 'day')));
|
||||
$dates[$processed]['formatted_time'] = date_format_date($date, 'custom', date_limit_format($format, array('hour', 'minute', 'second')));
|
||||
$dates[$processed]['formatted_timezone'] = date_format_date($date, 'custom', date_limit_format($format, array('timezone')));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($dates['value2'])) {
|
||||
$dates['value2'] = $dates['value'];
|
||||
}
|
||||
$date1 = $dates['value']['local']['object'];
|
||||
$date2 = $dates['value2']['local']['object'];
|
||||
|
||||
$all_day = '';
|
||||
$all_day2 = '';
|
||||
if ($format != 'format_interval') {
|
||||
$all_day1 = theme('date_all_day', $field, 'date1', $date1, $date2, $format, $node);
|
||||
$all_day2 = theme('date_all_day', $field, 'date2', $date1, $date2, $format, $node);
|
||||
}
|
||||
if ((!empty($all_day1) && $all_day1 != $dates['value']['formatted'])
|
||||
|| (!empty($all_day2) && $all_day2 != $dates['value2']['formatted'])) {
|
||||
$dates['value']['formatted_time'] = theme('date_all_day_label');
|
||||
$dates['value2']['formatted_time'] = theme('date_all_day_label');
|
||||
$dates['value']['formatted'] = $all_day1;
|
||||
$dates['value2']['formatted'] = $all_day2;
|
||||
}
|
||||
$dates['format'] = $format;
|
||||
return $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* $field['granularity'] will contain an array like ('hour' => 'hour', 'month' => 0)
|
||||
* where the values turned on return their own names and the values turned off return a zero
|
||||
* need to reconfigure this into a simple array of the turned on values
|
||||
*/
|
||||
function date_granularity($field) {
|
||||
if (!is_array($field) || !is_array($field['granularity'])) {
|
||||
$field['granularity'] = drupal_map_assoc(array('year', 'month', 'day'));
|
||||
}
|
||||
return array_values(array_filter($field['granularity']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to create an array of the date values in a
|
||||
* field that need to be processed.
|
||||
*/
|
||||
function date_process_values($field) {
|
||||
return $field['todate'] ? array('value', 'value2') : array('value');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_help().
|
||||
*/
|
||||
function date_help($path, $arg) {
|
||||
switch ($path) {
|
||||
case 'admin/help#date':
|
||||
return '<p>' . t('Complete documentation for the Date and Date API modules is available at <a href="@link">http://drupal.org/node/92460</a>.', array('@link' => 'http://drupal.org/node/92460')) . '</p>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_form_alter().
|
||||
* Make sure date information gets updated.
|
||||
*/
|
||||
function date_form_alter(&$form, &$form_state, $form_id) {
|
||||
if ($form_id == 'content_display_overview_form') {
|
||||
date_content_display_form($form, $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_field().
|
||||
*
|
||||
* Validation and submission operation code is moved into a separate
|
||||
* file and included only when processing forms.
|
||||
*/
|
||||
function date_field($op, &$node, $field, &$items, $teaser, $page) {
|
||||
// Add some information needed to interpret token values.
|
||||
$additions[$field['field_name']] = $items;
|
||||
foreach ($items as $delta => $item) {
|
||||
$timezone = isset($item['timezone']) ? $item['timezone'] : '';
|
||||
if (is_array($additions[$field['field_name']][$delta])) {
|
||||
$additions[$field['field_name']][$delta]['timezone'] = date_get_timezone($field['tz_handling'], $timezone);
|
||||
$additions[$field['field_name']][$delta]['timezone_db'] = date_get_timezone_db($field['tz_handling']);
|
||||
$additions[$field['field_name']][$delta]['date_type'] = $field['type'];
|
||||
}
|
||||
}
|
||||
switch ($op) {
|
||||
case 'load':
|
||||
return $additions;
|
||||
break;
|
||||
case 'validate':
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date_elements.inc');
|
||||
return _date_field_validate($op, $node, $field, $items, $teaser, $page);
|
||||
break;
|
||||
case 'presave':
|
||||
case 'insert':
|
||||
case 'update':
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date_elements.inc');
|
||||
$items = $additions[$field['field_name']];
|
||||
if ($additions[$field['field_name']]) {
|
||||
$node->$field['field_name'] = $additions;
|
||||
}
|
||||
return _date_field_update($op, $node, $field, $items, $teaser, $page);
|
||||
break;
|
||||
case 'sanitize':
|
||||
//foreach ($items as $delta => $item) {
|
||||
//$dates = date_formatter_process($field, $item, $node, $formatter);
|
||||
//$node->$field['field_name'][$delta]['dates'] = $dates;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_widget().
|
||||
*
|
||||
* This code and all the processes it uses are in a separate file,
|
||||
* included only when processing forms.
|
||||
*/
|
||||
function date_widget(&$form, &$form_state, &$field, $items, $delta) {
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date_elements.inc');
|
||||
return _date_widget($form, $form_state, $field, $items, $delta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_elements().
|
||||
*
|
||||
* This code and all the processes it uses are in a separate file,
|
||||
* included only when processing forms.
|
||||
*/
|
||||
function date_elements() {
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date_elements.inc');
|
||||
return _date_elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of Devel module's hook_content_generate().
|
||||
*/
|
||||
function date_content_generate($node, $field) {
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date_content_generate.inc');
|
||||
return _date_content_generate($node, $field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper functions for date administration, included only when
|
||||
* processing field settings.
|
||||
*/
|
||||
function date_widget_settings($op, $widget) {
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date_admin.inc');
|
||||
return _date_widget_settings($op, $widget);
|
||||
}
|
||||
|
||||
function date_field_settings($op, $field) {
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date_admin.inc');
|
||||
return _date_field_settings($op, $field);
|
||||
}
|
||||
|
||||
function date_formatter_settings($form_state = NULL, $field, $options = array(), $views_form = FALSE) {
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date_admin.inc');
|
||||
return _date_formatter_settings($form_state, $field, $options, $views_form);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return the date format used by a specific formatter.
|
||||
*/
|
||||
function date_formatter_format($formatter, $field_name) {
|
||||
$fields = content_fields();
|
||||
$field = $fields[$field_name];
|
||||
$default = variable_get('date_format_medium', 'D, m/d/Y - H:i');
|
||||
switch ($formatter) {
|
||||
case 'format_interval':
|
||||
return 'format_interval';
|
||||
case 'default':
|
||||
$format = variable_get('date_format_'. $field['default_format'], $default);
|
||||
break;
|
||||
default:
|
||||
$format = variable_get('date_format_'. $formatter, $default);
|
||||
break;
|
||||
}
|
||||
|
||||
if (empty($format)) {
|
||||
$format = $default;
|
||||
}
|
||||
// A selected format might include timezone information.
|
||||
$granularity = date_granularity($field);
|
||||
array_push($granularity, 'timezone');
|
||||
return date_limit_format($format, $granularity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_views_api().
|
||||
*/
|
||||
function date_views_api() {
|
||||
return array(
|
||||
'api' => 2,
|
||||
'path' => drupal_get_path('module', 'date'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to adapt node date fields to formatter settings.
|
||||
*/
|
||||
function date_prepare_node($node, $field, $type_name, $context, $options) {
|
||||
|
||||
// If there are options to limit multiple values,
|
||||
// alter the node values to match.
|
||||
$field_name = $field['field_name'];
|
||||
|
||||
$max_count = $options['multiple']['multiple_number'];
|
||||
|
||||
// If no results should be shown, empty the values and return.
|
||||
if (is_numeric($max_count) && $max_count == 0) {
|
||||
$node->{$field_name} = array();
|
||||
return $node;
|
||||
}
|
||||
|
||||
// Otherwise removed values that should not be displayed.
|
||||
if (!empty($options['multiple']['multiple_from']) || !empty($options['multiple']['multiple_to']) || !empty($max_count)) {
|
||||
$format = date_type_format($field['type']);
|
||||
include_once(drupal_get_path('module', 'date_api') .'/date_api_sql.inc');
|
||||
$date_handler = new date_sql_handler($field);
|
||||
$arg0 = !empty($options['multiple']['multiple_from']) ? date_format(date_create($options['multiple']['multiple_from'], date_default_timezone()), DATE_FORMAT_DATETIME) : variable_get('date_min_year', 100) .'-01-01T00:00:00';
|
||||
$arg1 = !empty($options['multiple']['multiple_to']) ? date_format(date_create($options['multiple']['multiple_to'], date_default_timezone()), DATE_FORMAT_DATETIME) : variable_get('date_max_year', 4000) .'-12-31T23:59:59';
|
||||
|
||||
if (!empty($arg0) && !empty($arg1)) {
|
||||
$arg = $arg0 .'--'. $arg1;
|
||||
}
|
||||
elseif (!empty($arg0)) {
|
||||
$arg = $arg0;
|
||||
}
|
||||
elseif (!empty($arg1)) {
|
||||
$arg = $arg1;
|
||||
}
|
||||
if (!empty($arg)) {
|
||||
$range = $date_handler->arg_range($arg);
|
||||
$start = date_format($range[0], $format);
|
||||
$end = date_format($range[1], $format);
|
||||
// Empty out values we don't want to see.
|
||||
$count = 0;
|
||||
foreach ($node->$field_name as $delta => $value) {
|
||||
if (!empty($node->date_repeat_show_all)) {
|
||||
break;
|
||||
}
|
||||
elseif ((!empty($max_count) && is_numeric($max_count) && $count >= $max_count) ||
|
||||
(!empty($value['value']) && $value['value'] < $start) ||
|
||||
(!empty($value['value2']) && $value['value2'] > $end)) {
|
||||
unset($node->{$field_name}[$delta]);
|
||||
}
|
||||
else {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify all fields in this view that use the CCK Date handler.
|
||||
*/
|
||||
function date_handler_fields($view) {
|
||||
$field_names = array();
|
||||
if (empty($view->date_info->date_fields)) {
|
||||
if (empty($view->date_info)) {
|
||||
$view->date_info = new stdClass;
|
||||
}
|
||||
$view->date_info->date_fields = array();
|
||||
}
|
||||
foreach ($view->field as $field) {
|
||||
if ($field->definition['handler'] == 'date_handler_field_multiple') {
|
||||
$name = $field->field;
|
||||
$group = $field->options['multiple'];
|
||||
if (drupal_substr($name, -7) == '_value2') {
|
||||
$field_name = drupal_substr($name, 0, strlen($name) - 7);
|
||||
}
|
||||
elseif (drupal_substr($name, -6) == '_value') {
|
||||
$field_name = drupal_substr($name, 0, strlen($name) - 6);
|
||||
}
|
||||
else {
|
||||
$field_name = '';
|
||||
$group = array();
|
||||
continue;
|
||||
}
|
||||
foreach ($view->date_info->date_fields as $date_field) {
|
||||
if (strstr($date_field, '.'. $field_name)) {
|
||||
$delta_field = 'node_data_'. $field_name .'_delta';
|
||||
$field_names[$field_name] = array('options' => $group, 'delta_field' => $delta_field, 'view_field' => drupal_clone($field));
|
||||
// Get rid of the huge view object in the field handler.
|
||||
unset($field_names[$field_name]['view_field']->view);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $field_names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a DateAPI SQL handler for the given CCK date field.
|
||||
*
|
||||
* The handler will be set up to make the correct timezone adjustments
|
||||
* for the field settings.
|
||||
*
|
||||
* @param $field
|
||||
* - a $field array.
|
||||
* @param $compare_tz
|
||||
* - the timezone used for comparison values in the SQL.
|
||||
*/
|
||||
function date_field_get_sql_handler($field, $compare_tz = NULL) {
|
||||
module_load_include('inc', 'date_api', 'date_api_sql');
|
||||
|
||||
$db_info = content_database_info($field);
|
||||
|
||||
// Create a DateAPI SQL handler class for this field type.
|
||||
$handler = new date_sql_handler();
|
||||
$handler->construct($field['type']);
|
||||
|
||||
// If this date field stores a timezone in the DB, tell the handler about it.
|
||||
if ($field['tz_handling'] == 'date') {
|
||||
$handler->db_timezone_field = $db_info['columns']['timezone']['column'];
|
||||
}
|
||||
else {
|
||||
$handler->db_timezone = date_get_timezone_db($field['tz_handling']);
|
||||
}
|
||||
|
||||
if (empty($compare_tz)) {
|
||||
$compare_tz = date_get_timezone($field['tz_handling']);
|
||||
}
|
||||
$handler->local_timezone = $compare_tz;
|
||||
|
||||
// Now that the handler is properly initialized, force the DB
|
||||
// to use UTC so no timezone conversions get added to things like
|
||||
// NOW() or FROM_UNIXTIME().
|
||||
$handler->set_db_timezone();
|
||||
|
||||
return $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_form_alter().
|
||||
*
|
||||
* Adding ability to configure new date format types.
|
||||
*/
|
||||
function date_form_date_api_date_formats_form_alter(&$form, $form_state, $form_id = 'date_api_date_formats_form') {
|
||||
// Add form entry field for adding new format type.
|
||||
$form['add_format_type'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Add format type'),
|
||||
'#weight' => 1,
|
||||
);
|
||||
$form['add_format_type']['add_date_format_title'] = array(
|
||||
'#title' => t('Name'),
|
||||
'#description' => t('The human-readable name for this format type.'),
|
||||
'#type' => 'textfield',
|
||||
'#size' => 20,
|
||||
'#prefix' => '<div class="date-container"><div class="date-format-name">',
|
||||
'#suffix' => '</div>',
|
||||
);
|
||||
$form['add_format_type']['add_date_format_type'] = array(
|
||||
'#title' => t('Type'),
|
||||
'#description' => t('The machine-readable name of this format type. <br>This name must contain only lowercase letters, numbers, and underscores and must be unique.'),
|
||||
'#type' => 'textfield',
|
||||
'#size' => 20,
|
||||
'#prefix' => '<div class="date-format-type">',
|
||||
'#suffix' => '</div></div>',
|
||||
);
|
||||
|
||||
$form['#submit'][] = 'date_date_time_settings_submit';
|
||||
$form['#validate'][] = 'date_date_time_settings_validate';
|
||||
$form['buttons']['#weight'] = 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate new date format type details.
|
||||
*/
|
||||
function date_date_time_settings_validate($form, &$form_state) {
|
||||
if (!empty($form_state['values']['add_date_format_type']) && !empty($form_state['values']['add_date_format_title'])) {
|
||||
if (!preg_match("/^[a-zA-Z0-9_]+$/", $form_state['values']['add_date_format_type'])) {
|
||||
form_set_error('add_date_format_type', t('The format type must contain only alphanumeric characters and underscores.'));
|
||||
}
|
||||
$types = date_get_format_types();
|
||||
if (in_array($form_state['values']['add_date_format_type'], array_keys($types))) {
|
||||
form_set_error('add_date_format_type', t('This format type already exists. Please enter a unique type.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save date format type to database.
|
||||
*/
|
||||
function date_date_time_settings_submit($form, &$form_state) {
|
||||
if (!empty($form_state['values']['add_date_format_type']) && !empty($form_state['values']['add_date_format_title'])) {
|
||||
$format_type = array();
|
||||
$format_type['title'] = $form_state['values']['add_date_format_title'];
|
||||
$format_type['type'] = $form_state['values']['add_date_format_type'];
|
||||
$format_type['locked'] = 0;
|
||||
$format_type['is_new'] = 1;
|
||||
date_format_type_save($format_type);
|
||||
}
|
||||
|
||||
// Unset, to prevent this getting saved as a variables.
|
||||
unset($form_state['values']['add_date_format_type']);
|
||||
unset($form_state['values']['add_date_format_title']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert Date field formatter settings into the Display Fields form.
|
||||
*/
|
||||
function date_content_display_form(&$form, &$form_state) {
|
||||
$fields = content_fields();
|
||||
$date_fields = array();
|
||||
foreach ($fields as $field) {
|
||||
if (in_array($field['type'], array('date', 'datestamp', 'datetime'))) {
|
||||
$date_fields[$field['field_name']] = $field;
|
||||
}
|
||||
}
|
||||
foreach ($form as $field_name => $element) {
|
||||
if (drupal_substr($field_name, 0, 6) == 'field_') {
|
||||
if (array_key_exists($field_name, $date_fields)) {
|
||||
$field = $date_fields[$field_name];
|
||||
foreach ($element as $context => $value) {
|
||||
if (!in_array($context, array('human_name', 'weight', 'parent', 'label'))) {
|
||||
$options['type_name'] = $form['#type_name'];
|
||||
$options['context'] = $context;
|
||||
$base_form = $form[$field_name][$context]['format'];
|
||||
$form[$field_name][$context]['format'] = array();
|
||||
$form[$field_name][$context]['format']['base'] = $base_form;
|
||||
$form[$field_name][$context]['format']['extra'] = date_formatter_settings($form_state, $field, $options);
|
||||
$form[$field_name][$context]['format']['#element_validate'] = array('date_formatter_settings_validate');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the formatter settings
|
||||
* and reset the form back to the value CCK expects.
|
||||
*/
|
||||
function date_formatter_settings_validate(&$form, &$form_state) {
|
||||
$field = $form['extra']['field']['#value'];
|
||||
$field_name = $field['field_name'];
|
||||
|
||||
$type_name = $form['extra']['type_name']['#value'];
|
||||
$context = $form['extra']['context']['#value'];
|
||||
$form_values = $form_state['values'][$field_name][$context]['format']['extra'];
|
||||
$value = 'date:'. $type_name .':'. $context .':'. $field_name;
|
||||
variable_set($value .'_show_repeat_rule', $form_values['repeat']['show_repeat_rule']);
|
||||
variable_set($value .'_multiple_number', $form_values['multiple']['multiple_number']);
|
||||
variable_set($value .'_multiple_from', $form_values['multiple']['multiple_from']);
|
||||
variable_set($value .'_multiple_to', $form_values['multiple']['multiple_to']);
|
||||
variable_set($value .'_fromto', $form_values['fromto']['fromto']);
|
||||
|
||||
form_set_value($form, $form_state['values'][$field_name][$context]['format']['base'], $form_state);
|
||||
}
|
||||
|
||||
function date_formatter_get_settings($field_name, $type_name, $context) {
|
||||
$options = array();
|
||||
$value = 'date:'. $type_name .':'. $context .':'. $field_name;
|
||||
$options['repeat']['show_repeat_rule'] = variable_get($value .'_show_repeat_rule', 'show');
|
||||
$options['multiple']['multiple_number'] = variable_get($value .'_multiple_number', '');
|
||||
$options['multiple']['multiple_from'] = variable_get($value .'_multiple_from', '');
|
||||
$options['multiple']['multiple_to'] = variable_get($value .'_multiple_to', '');
|
||||
$options['fromto']['fromto'] = variable_get($value .'_fromto', 'both');
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a from/to date combination qualify as 'All day'.
|
||||
*
|
||||
* @param array $field, the field definition for this date field.
|
||||
* @param object $date1, a date/time object for the 'from' date.
|
||||
* @param object $date2, a date/time object for the 'to' date.
|
||||
* @return TRUE or FALSE.
|
||||
*/
|
||||
function date_field_all_day($field, $date1, $date2 = NULL) {
|
||||
if (empty($date1) || !is_object($date1)) {
|
||||
return FALSE;
|
||||
}
|
||||
elseif (!date_has_time($field['granularity'])) {
|
||||
return TRUE;
|
||||
}
|
||||
if (empty($date2)) {
|
||||
$date2 = $date1;
|
||||
}
|
||||
$granularity = date_granularity_precision($field['granularity']);
|
||||
$increment = isset($field['widget']['increment']) ? $field['widget']['increment'] : 1;
|
||||
$date1 = date_format($date1, DATE_FORMAT_DATETIME);
|
||||
$date2 = date_format($date2, DATE_FORMAT_DATETIME);
|
||||
return date_is_all_day($date1, $date2, $granularity, $increment);
|
||||
|
||||
}
|
||||
|
283
modules/date/date/date.theme
Normal file
283
modules/date/date/date.theme
Normal file
|
@ -0,0 +1,283 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Theme functions.
|
||||
*/
|
||||
/**
|
||||
* @addtogroup themeable
|
||||
* @{
|
||||
*
|
||||
* Formatter themes
|
||||
*/
|
||||
/**
|
||||
* Theme from/to date combination in the view.
|
||||
*
|
||||
* Useful values:
|
||||
*
|
||||
* $node->date_id
|
||||
* If set, this will show only an individual date on a field with
|
||||
* multiple dates. The value should be a string that contains
|
||||
* the following values, separated with periods:
|
||||
* - module name of the module adding the item
|
||||
* - node nid
|
||||
* - field name
|
||||
* - delta value of the field to be displayed
|
||||
* - other information the module's custom theme might need
|
||||
*
|
||||
* Used by the calendar module and available for other uses.
|
||||
* example: 'date.217.field_date.3.test'
|
||||
*
|
||||
* $node->date_repeat_show
|
||||
* If true, tells the theme to show all the computed values
|
||||
* of a repeating date. If not true or not set, only the
|
||||
* start date and the repeat rule will be displayed.
|
||||
*
|
||||
* $dates['format'] - the format string used on these dates
|
||||
* $dates['value']['local']['object'] - the local date object for the From date
|
||||
* $dates['value2']['local']['object'] - the local date object for the To date
|
||||
* $dates['value']['local']['datetime'] - the datetime value of the From date database (GMT) value
|
||||
* $dates['value2']['local']['datetime'] - the datetime value of the To date database (GMT) value
|
||||
* $dates['value']['formatted'] = formatted From date, i.e. 'February 15, 2007 2:00 pm';
|
||||
* $dates['value']['formatted_date'] - only the date part of the formatted From date
|
||||
* $dates['value']['formatted_time'] - only the time part of the formatted From date
|
||||
* $dates['value2']['formatted'] = formatted To date, i.e. 'February 15, 2007 6:00 pm';
|
||||
* $dates['value2']['formatted_date'] - only the date part of the formatted To date
|
||||
* $dates['value2']['formatted_time'] - only the time part of the formatted To date
|
||||
*/
|
||||
function theme_date_display_combination($element) {
|
||||
static $repeating_ids = array();
|
||||
|
||||
$node = $element['#node'];
|
||||
$field_name = $element['#field_name'];
|
||||
$context = !empty($node->content) && !empty($node->content[$field_name]) ? $node->content[$field_name]['#context'] : 'full';
|
||||
$type_name = $element['#type_name'];
|
||||
$fields = content_fields();
|
||||
$field = $fields[$field_name];
|
||||
$item = $element['#item'];
|
||||
|
||||
// Get the formatter settings, either the default settings for this node
|
||||
// type or the View settings stored in $node->date_info.
|
||||
$options = date_formatter_get_settings($field_name, $type_name, $context);
|
||||
if (!empty($node->date_info) && !empty($node->date_info->formatter_settings)) {
|
||||
$options = $node->date_info->formatter_settings;
|
||||
}
|
||||
|
||||
$output = '';
|
||||
|
||||
// If date_id is set for this field and the delta doesn't match, don't display it.
|
||||
if (!empty($node->date_id)) {
|
||||
foreach ((array) $node->date_id as $key => $id) {
|
||||
list($module, $nid, $field_name, $delta, $other) = explode('.', $id);
|
||||
if ($field_name == $field['field_name'] && isset($item['#delta']) && $delta != $item['#delta']) {
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the formatter settings to see if the repeat rule should be
|
||||
// displayed. Show it only with the first multiple value date.
|
||||
if (!in_array($node->nid, $repeating_ids) && module_exists('date_repeat')
|
||||
&& !empty($item['rrule']) && $options['repeat']['show_repeat_rule'] == 'show') {
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date_repeat.inc');
|
||||
$output .= theme('date_repeat_display', $field, $item, $node);
|
||||
$repeating_ids[] = $node->nid;
|
||||
}
|
||||
|
||||
// If this is a full node or a pseudo node created by grouping
|
||||
// multiple values, see exactly which values are supposed to be visible.
|
||||
if (isset($node->$field_name)) {
|
||||
$node = date_prepare_node($node, $field, $type_name, $context, $options);
|
||||
// Did the current value get removed by formatter settings?
|
||||
if (empty($node->{$field_name}[$item['#delta']])) {
|
||||
return $output;
|
||||
}
|
||||
// Adjust the $element values to match the changes.
|
||||
$element['#node'] = $node;
|
||||
}
|
||||
|
||||
// Call the right theme for this formatter.
|
||||
// Update the element with values that might have been altered by
|
||||
// date_prepare_node() and figure out which values to display.
|
||||
$dates = date_formatter_process($element);
|
||||
switch ($options['fromto']['fromto']) {
|
||||
case 'value':
|
||||
$date1 = $dates['value']['formatted'];
|
||||
$date2 = $date1;
|
||||
break;
|
||||
case 'value2':
|
||||
$date2 = $dates['value2']['formatted'];
|
||||
$date1 = $date2;
|
||||
break;
|
||||
default:
|
||||
$date1 = $dates['value']['formatted'];
|
||||
$date2 = $dates['value2']['formatted'];
|
||||
break;
|
||||
}
|
||||
|
||||
// Pull the timezone, if any, out of the formatted result and tack it
|
||||
// back on at the end, if it is in the current formatted date.
|
||||
$timezone = $dates['value']['formatted_timezone'];
|
||||
if ($timezone) {
|
||||
$timezone = ' ' . $timezone;
|
||||
}
|
||||
$date1 = str_replace($timezone, '', $date1);
|
||||
$date2 = str_replace($timezone, '', $date2);
|
||||
|
||||
// No date values, display nothing.
|
||||
if (empty($date1) && empty($date2)) {
|
||||
$output .= '';
|
||||
}
|
||||
// From and To dates match or there is no To date, display a complete single date.
|
||||
elseif ($date1 == $date2 || empty($date2)) {
|
||||
$output .= theme('date_display_single', $date1, $timezone);
|
||||
}
|
||||
// Same day, different times, don't repeat the date but show both From and To times.
|
||||
elseif (date_has_time($field['granularity']) && $dates['value']['formatted_date'] == $dates['value2']['formatted_date']) {
|
||||
// Replace the original time with the from/to time in the formatted start date.
|
||||
// Make sure that parentheses or brackets wrapping the time will be retained in the
|
||||
// final result.
|
||||
$time1 = preg_replace('`^([\(\[])`', '', $dates['value']['formatted_time']);
|
||||
$time1 = preg_replace('([\)\]]$)', '', $time1);
|
||||
$time2 = preg_replace('`^([\(\[])`', '', $dates['value2']['formatted_time']);
|
||||
$time2 = preg_replace('([\)\]]$)', '', $time2);
|
||||
$time = theme('date_display_range', $time1, $time2);
|
||||
$replaced = str_replace($time1, $time, $date1);
|
||||
$output .= theme('date_display_single', $replaced, $timezone);
|
||||
}
|
||||
// Different days, display both in their entirety.
|
||||
else {
|
||||
$output .= theme('date_display_range', $date1, $date2, $timezone);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
function theme_date_display_single($date, $timezone = NULL) {
|
||||
return '<span class="date-display-single">'. $date . $timezone .'</span>';
|
||||
}
|
||||
|
||||
function theme_date_display_range($date1, $date2, $timezone = NULL) {
|
||||
return '<span class="date-display-start">'. $date1 .'</span>'.
|
||||
'<span class="date-display-separator"> - </span>' .
|
||||
'<span class="date-display-end">'. $date2 . $timezone. '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme a format interval for a date element
|
||||
*
|
||||
* @param $field = the field settings
|
||||
* @param $node = node information, this is not always available and not
|
||||
* always the full node, it depends on what value was provided to the formatter.
|
||||
* Only the nid is always guaranteed to be available.
|
||||
* @param $dates - an array of date information, see explanation for date_field_object for details.
|
||||
* @return a formatted display
|
||||
*
|
||||
*/
|
||||
function theme_date_format_interval($element) {
|
||||
$node = $element['#node'];
|
||||
$field_name = $element['#field_name'];
|
||||
$context = !empty($node->content) ? $node->content[$field_name]['#context'] : 'full';
|
||||
$type_name = $element['#type_name'];
|
||||
$fields = content_fields();
|
||||
$field = $fields[$field_name];
|
||||
$item = $element['#item'];
|
||||
|
||||
// Get the formatter settings, either the default settings for this node
|
||||
// type or the View settings stored in $node->date_info.
|
||||
$options = date_formatter_get_settings($field_name, $type_name, $context);
|
||||
if (!empty($node->date_info) && !empty($node->date_info->formatter_settings)) {
|
||||
$options = $node->date_info->formatter_settings;
|
||||
}
|
||||
|
||||
// If date_id is set for this field and the delta doesn't match, don't display it.
|
||||
if (!empty($node->date_id)) {
|
||||
foreach ((array) $node->date_id as $key => $id) {
|
||||
list($module, $nid, $field_name, $delta, $other) = explode('.', $id);
|
||||
if ($field_name == $field['field_name'] && isset($item['#delta']) && $delta != $item['#delta']) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this is not coming from Views, it is the full node.
|
||||
// If we aren't retrieving a specific value, adjust the node values
|
||||
// to match the formatter settings, removing values we should not see.
|
||||
if (!empty($node->content) && empty($node->date_id)) {
|
||||
$node = date_prepare_node($node, $field, $type_name, $context, $options);
|
||||
|
||||
// Did the current value get removed by formatter settings?
|
||||
if (empty($node->{$field_name}[$item['#delta']])) {
|
||||
return;
|
||||
}
|
||||
// Adjust the $element values to match the changes.
|
||||
$element['#node'] = $node;
|
||||
}
|
||||
$dates = date_formatter_process($element);
|
||||
return theme('date_time_ago', $dates['value']['local']['object'], $dates['value2']['local']['object']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme the human-readable description for a Date Repeat rule.
|
||||
*
|
||||
* TODO -
|
||||
* add in ways to store the description in the date so it isn't regenerated
|
||||
* over and over and find a way to allow description to be shown or hidden.
|
||||
*/
|
||||
function theme_date_repeat_display($field, $item, $node = NULL) {
|
||||
$output = '';
|
||||
if (!empty($item['rrule'])) {
|
||||
$output = date_repeat_rrule_description($item['rrule']);
|
||||
$output = '<div>'. $output .'</div>';
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust from/to date format to account for 'all day'.
|
||||
*
|
||||
* @param array $field, the field definition for this date field.
|
||||
* @param string $which, which value to return, 'date1' or 'date2'.
|
||||
* @param object $date1, a date/time object for the 'from' date.
|
||||
* @param object $date2, a date/time object for the 'to' date.
|
||||
* @param string $format
|
||||
* @param object $node, the node this date comes from (may be incomplete, always contains nid).
|
||||
* @param object $view, the view this node comes from, if applicable.
|
||||
* @return formatted date.
|
||||
*/
|
||||
function theme_date_all_day($field, $which, $date1, $date2, $format, $node, $view = NULL) {
|
||||
|
||||
if (empty($date1) || !is_object($date1) || $format == 'format_interval') {
|
||||
return;
|
||||
}
|
||||
if (empty($date2)) {
|
||||
$date2 = $date1;
|
||||
}
|
||||
|
||||
$suffix = '';
|
||||
if (!date_has_time($field['granularity'])) {
|
||||
$format = date_limit_format($format, array('year', 'month', 'day'));
|
||||
}
|
||||
else {
|
||||
$format_granularity = date_format_order($format);
|
||||
$format_has_time = FALSE;
|
||||
if (in_array('hour', $format_granularity)) {
|
||||
$format_has_time = TRUE;
|
||||
}
|
||||
$all_day = date_field_all_day($field, $date1, $date2);
|
||||
if ($all_day && $format_has_time) {
|
||||
$format = date_limit_format($format, array('year', 'month', 'day'));
|
||||
# $suffix = ' ' . theme('date_all_day_label');
|
||||
}
|
||||
}
|
||||
|
||||
return trim(date_format_date($$which, 'custom', $format) . $suffix);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme the way an 'all day' label will look.
|
||||
*/
|
||||
function theme_date_all_day_label() {
|
||||
# return '('. date_t('All day', 'datetime') .')';
|
||||
return '';
|
||||
}
|
||||
/** @} End of addtogroup themeable */
|
282
modules/date/date/date.theme.original
Normal file
282
modules/date/date/date.theme.original
Normal file
|
@ -0,0 +1,282 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Theme functions.
|
||||
*/
|
||||
/**
|
||||
* @addtogroup themeable
|
||||
* @{
|
||||
*
|
||||
* Formatter themes
|
||||
*/
|
||||
/**
|
||||
* Theme from/to date combination in the view.
|
||||
*
|
||||
* Useful values:
|
||||
*
|
||||
* $node->date_id
|
||||
* If set, this will show only an individual date on a field with
|
||||
* multiple dates. The value should be a string that contains
|
||||
* the following values, separated with periods:
|
||||
* - module name of the module adding the item
|
||||
* - node nid
|
||||
* - field name
|
||||
* - delta value of the field to be displayed
|
||||
* - other information the module's custom theme might need
|
||||
*
|
||||
* Used by the calendar module and available for other uses.
|
||||
* example: 'date.217.field_date.3.test'
|
||||
*
|
||||
* $node->date_repeat_show
|
||||
* If true, tells the theme to show all the computed values
|
||||
* of a repeating date. If not true or not set, only the
|
||||
* start date and the repeat rule will be displayed.
|
||||
*
|
||||
* $dates['format'] - the format string used on these dates
|
||||
* $dates['value']['local']['object'] - the local date object for the From date
|
||||
* $dates['value2']['local']['object'] - the local date object for the To date
|
||||
* $dates['value']['local']['datetime'] - the datetime value of the From date database (GMT) value
|
||||
* $dates['value2']['local']['datetime'] - the datetime value of the To date database (GMT) value
|
||||
* $dates['value']['formatted'] = formatted From date, i.e. 'February 15, 2007 2:00 pm';
|
||||
* $dates['value']['formatted_date'] - only the date part of the formatted From date
|
||||
* $dates['value']['formatted_time'] - only the time part of the formatted From date
|
||||
* $dates['value2']['formatted'] = formatted To date, i.e. 'February 15, 2007 6:00 pm';
|
||||
* $dates['value2']['formatted_date'] - only the date part of the formatted To date
|
||||
* $dates['value2']['formatted_time'] - only the time part of the formatted To date
|
||||
*/
|
||||
function theme_date_display_combination($element) {
|
||||
static $repeating_ids = array();
|
||||
|
||||
$node = $element['#node'];
|
||||
$field_name = $element['#field_name'];
|
||||
$context = !empty($node->content) && !empty($node->content[$field_name]) ? $node->content[$field_name]['#context'] : 'full';
|
||||
$type_name = $element['#type_name'];
|
||||
$fields = content_fields();
|
||||
$field = $fields[$field_name];
|
||||
$item = $element['#item'];
|
||||
|
||||
// Get the formatter settings, either the default settings for this node
|
||||
// type or the View settings stored in $node->date_info.
|
||||
$options = date_formatter_get_settings($field_name, $type_name, $context);
|
||||
if (!empty($node->date_info) && !empty($node->date_info->formatter_settings)) {
|
||||
$options = $node->date_info->formatter_settings;
|
||||
}
|
||||
|
||||
$output = '';
|
||||
|
||||
// If date_id is set for this field and the delta doesn't match, don't display it.
|
||||
if (!empty($node->date_id)) {
|
||||
foreach ((array) $node->date_id as $key => $id) {
|
||||
list($module, $nid, $field_name, $delta, $other) = explode('.', $id);
|
||||
if ($field_name == $field['field_name'] && isset($item['#delta']) && $delta != $item['#delta']) {
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the formatter settings to see if the repeat rule should be
|
||||
// displayed. Show it only with the first multiple value date.
|
||||
if (!in_array($node->nid, $repeating_ids) && module_exists('date_repeat')
|
||||
&& !empty($item['rrule']) && $options['repeat']['show_repeat_rule'] == 'show') {
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date_repeat.inc');
|
||||
$output .= theme('date_repeat_display', $field, $item, $node);
|
||||
$repeating_ids[] = $node->nid;
|
||||
}
|
||||
|
||||
// If this is a full node or a pseudo node created by grouping
|
||||
// multiple values, see exactly which values are supposed to be visible.
|
||||
if (isset($node->$field_name)) {
|
||||
$node = date_prepare_node($node, $field, $type_name, $context, $options);
|
||||
// Did the current value get removed by formatter settings?
|
||||
if (empty($node->{$field_name}[$item['#delta']])) {
|
||||
return $output;
|
||||
}
|
||||
// Adjust the $element values to match the changes.
|
||||
$element['#node'] = $node;
|
||||
}
|
||||
|
||||
// Call the right theme for this formatter.
|
||||
// Update the element with values that might have been altered by
|
||||
// date_prepare_node() and figure out which values to display.
|
||||
$dates = date_formatter_process($element);
|
||||
switch ($options['fromto']['fromto']) {
|
||||
case 'value':
|
||||
$date1 = $dates['value']['formatted'];
|
||||
$date2 = $date1;
|
||||
break;
|
||||
case 'value2':
|
||||
$date2 = $dates['value2']['formatted'];
|
||||
$date1 = $date2;
|
||||
break;
|
||||
default:
|
||||
$date1 = $dates['value']['formatted'];
|
||||
$date2 = $dates['value2']['formatted'];
|
||||
break;
|
||||
}
|
||||
|
||||
// Pull the timezone, if any, out of the formatted result and tack it
|
||||
// back on at the end, if it is in the current formatted date.
|
||||
$timezone = $dates['value']['formatted_timezone'];
|
||||
if ($timezone) {
|
||||
$timezone = ' ' . $timezone;
|
||||
}
|
||||
$date1 = str_replace($timezone, '', $date1);
|
||||
$date2 = str_replace($timezone, '', $date2);
|
||||
|
||||
// No date values, display nothing.
|
||||
if (empty($date1) && empty($date2)) {
|
||||
$output .= '';
|
||||
}
|
||||
// From and To dates match or there is no To date, display a complete single date.
|
||||
elseif ($date1 == $date2 || empty($date2)) {
|
||||
$output .= theme('date_display_single', $date1, $timezone);
|
||||
}
|
||||
// Same day, different times, don't repeat the date but show both From and To times.
|
||||
elseif (date_has_time($field['granularity']) && $dates['value']['formatted_date'] == $dates['value2']['formatted_date']) {
|
||||
// Replace the original time with the from/to time in the formatted start date.
|
||||
// Make sure that parentheses or brackets wrapping the time will be retained in the
|
||||
// final result.
|
||||
$time1 = preg_replace('`^([\(\[])`', '', $dates['value']['formatted_time']);
|
||||
$time1 = preg_replace('([\)\]]$)', '', $time1);
|
||||
$time2 = preg_replace('`^([\(\[])`', '', $dates['value2']['formatted_time']);
|
||||
$time2 = preg_replace('([\)\]]$)', '', $time2);
|
||||
$time = theme('date_display_range', $time1, $time2);
|
||||
$replaced = str_replace($time1, $time, $date1);
|
||||
$output .= theme('date_display_single', $replaced, $timezone);
|
||||
}
|
||||
// Different days, display both in their entirety.
|
||||
else {
|
||||
$output .= theme('date_display_range', $date1, $date2, $timezone);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
function theme_date_display_single($date, $timezone = NULL) {
|
||||
return '<span class="date-display-single">'. $date . $timezone .'</span>';
|
||||
}
|
||||
|
||||
function theme_date_display_range($date1, $date2, $timezone = NULL) {
|
||||
return '<span class="date-display-start">'. $date1 .'</span>'.
|
||||
'<span class="date-display-separator"> - </span>' .
|
||||
'<span class="date-display-end">'. $date2 . $timezone. '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme a format interval for a date element
|
||||
*
|
||||
* @param $field = the field settings
|
||||
* @param $node = node information, this is not always available and not
|
||||
* always the full node, it depends on what value was provided to the formatter.
|
||||
* Only the nid is always guaranteed to be available.
|
||||
* @param $dates - an array of date information, see explanation for date_field_object for details.
|
||||
* @return a formatted display
|
||||
*
|
||||
*/
|
||||
function theme_date_format_interval($element) {
|
||||
$node = $element['#node'];
|
||||
$field_name = $element['#field_name'];
|
||||
$context = !empty($node->content) ? $node->content[$field_name]['#context'] : 'full';
|
||||
$type_name = $element['#type_name'];
|
||||
$fields = content_fields();
|
||||
$field = $fields[$field_name];
|
||||
$item = $element['#item'];
|
||||
|
||||
// Get the formatter settings, either the default settings for this node
|
||||
// type or the View settings stored in $node->date_info.
|
||||
$options = date_formatter_get_settings($field_name, $type_name, $context);
|
||||
if (!empty($node->date_info) && !empty($node->date_info->formatter_settings)) {
|
||||
$options = $node->date_info->formatter_settings;
|
||||
}
|
||||
|
||||
// If date_id is set for this field and the delta doesn't match, don't display it.
|
||||
if (!empty($node->date_id)) {
|
||||
foreach ((array) $node->date_id as $key => $id) {
|
||||
list($module, $nid, $field_name, $delta, $other) = explode('.', $id);
|
||||
if ($field_name == $field['field_name'] && isset($item['#delta']) && $delta != $item['#delta']) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this is not coming from Views, it is the full node.
|
||||
// If we aren't retrieving a specific value, adjust the node values
|
||||
// to match the formatter settings, removing values we should not see.
|
||||
if (!empty($node->content) && empty($node->date_id)) {
|
||||
$node = date_prepare_node($node, $field, $type_name, $context, $options);
|
||||
|
||||
// Did the current value get removed by formatter settings?
|
||||
if (empty($node->{$field_name}[$item['#delta']])) {
|
||||
return;
|
||||
}
|
||||
// Adjust the $element values to match the changes.
|
||||
$element['#node'] = $node;
|
||||
}
|
||||
$dates = date_formatter_process($element);
|
||||
return theme('date_time_ago', $dates['value']['local']['object'], $dates['value2']['local']['object']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme the human-readable description for a Date Repeat rule.
|
||||
*
|
||||
* TODO -
|
||||
* add in ways to store the description in the date so it isn't regenerated
|
||||
* over and over and find a way to allow description to be shown or hidden.
|
||||
*/
|
||||
function theme_date_repeat_display($field, $item, $node = NULL) {
|
||||
$output = '';
|
||||
if (!empty($item['rrule'])) {
|
||||
$output = date_repeat_rrule_description($item['rrule']);
|
||||
$output = '<div>'. $output .'</div>';
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust from/to date format to account for 'all day'.
|
||||
*
|
||||
* @param array $field, the field definition for this date field.
|
||||
* @param string $which, which value to return, 'date1' or 'date2'.
|
||||
* @param object $date1, a date/time object for the 'from' date.
|
||||
* @param object $date2, a date/time object for the 'to' date.
|
||||
* @param string $format
|
||||
* @param object $node, the node this date comes from (may be incomplete, always contains nid).
|
||||
* @param object $view, the view this node comes from, if applicable.
|
||||
* @return formatted date.
|
||||
*/
|
||||
function theme_date_all_day($field, $which, $date1, $date2, $format, $node, $view = NULL) {
|
||||
|
||||
if (empty($date1) || !is_object($date1) || $format == 'format_interval') {
|
||||
return;
|
||||
}
|
||||
if (empty($date2)) {
|
||||
$date2 = $date1;
|
||||
}
|
||||
|
||||
$suffix = '';
|
||||
if (!date_has_time($field['granularity'])) {
|
||||
$format = date_limit_format($format, array('year', 'month', 'day'));
|
||||
}
|
||||
else {
|
||||
$format_granularity = date_format_order($format);
|
||||
$format_has_time = FALSE;
|
||||
if (in_array('hour', $format_granularity)) {
|
||||
$format_has_time = TRUE;
|
||||
}
|
||||
$all_day = date_field_all_day($field, $date1, $date2);
|
||||
if ($all_day && $format_has_time) {
|
||||
$format = date_limit_format($format, array('year', 'month', 'day'));
|
||||
$suffix = ' ' . theme('date_all_day_label');
|
||||
}
|
||||
}
|
||||
|
||||
return trim(date_format_date($$which, 'custom', $format) . $suffix);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme the way an 'all day' label will look.
|
||||
*/
|
||||
function theme_date_all_day_label() {
|
||||
return '('. date_t('All day', 'datetime') .')';
|
||||
}
|
||||
/** @} End of addtogroup themeable */
|
18
modules/date/date/date.views.inc
Normal file
18
modules/date/date/date.views.inc
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Implementation of hook_views_handlers().
|
||||
*/
|
||||
function date_views_handlers() {
|
||||
return array(
|
||||
'info' => array(
|
||||
'path' => drupal_get_path('module', 'date'),
|
||||
),
|
||||
// A date-specific handler for grouping multiple values.
|
||||
'handlers' => array(
|
||||
'date_handler_field_multiple' => array(
|
||||
'parent' => 'content_handler_field_multiple',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
87
modules/date/date/date.views_convert.inc
Normal file
87
modules/date/date/date.views_convert.inc
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Implementation of hook_views_convert().
|
||||
*/
|
||||
function date_views_convert($display, $type, &$view, $field, $id = NULL) {
|
||||
static $date_fields;
|
||||
if (!isset($date_fields)) {
|
||||
$date_fields = array();
|
||||
$content_types = content_types();
|
||||
foreach ($content_types as $content_type) {
|
||||
foreach ($content_type['fields'] as $content_field) {
|
||||
if ($content_field['module'] == 'date') {
|
||||
$date_fields["$content_field[field_name]_value_default"] = 'default';
|
||||
$date_fields["$content_field[field_name]_value_year"] = 'year';
|
||||
$date_fields["$content_field[field_name]_value_month"] = 'month';
|
||||
$date_fields["$content_field[field_name]_value_day"] = 'day';
|
||||
$date_fields["$content_field[field_name]_value_to|default"] = 'to|default';
|
||||
$date_fields["$content_field[field_name]_value_to|year"] = 'to|year';
|
||||
$date_fields["$content_field[field_name]_value_to|month"] = 'to|month';
|
||||
$date_fields["$content_field[field_name]_value_to|day"] = 'to|day';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch ($type) {
|
||||
case 'filter':
|
||||
if (isset($date_fields[$field['field']])) {
|
||||
$item = $view->get_item($display, 'filter', $id);
|
||||
switch ($date_fields[$field['field']]) {
|
||||
case 'default':
|
||||
$field_name = drupal_substr($field['field'], 0, -14);
|
||||
$item['date_fields'] = array('node_data_'. $field_name .'.'. $field_name .'_value');
|
||||
$item['granularity'] = 'second';
|
||||
break;
|
||||
case 'year':
|
||||
$field_name = drupal_substr($field['field'], 0, -11);
|
||||
$item['date_fields'] = array('node_data_'. $field_name .'.'. $field_name .'_value');
|
||||
$item['granularity'] = 'year';
|
||||
break;
|
||||
case 'month':
|
||||
$field_name = drupal_substr($field['field'], 0, -12);
|
||||
$item['date_fields'] = array('node_data_'. $field_name .'.'. $field_name .'_value');
|
||||
$item['granularity'] = 'month';
|
||||
break;
|
||||
case 'day':
|
||||
$field_name = drupal_substr($field['field'], 0, -10);
|
||||
$item['date_fields'] = array('node_data_'. $field_name .'.'. $field_name .'_value');
|
||||
$item['granularity'] = 'day';
|
||||
break;
|
||||
case 'to|default':
|
||||
$field_name = drupal_substr($field['field'], 0, -17);
|
||||
$item['date_fields'] = array('node_data_'. $field_name .'.'. $field_name .'_value2');
|
||||
$item['granularity'] = 'second';
|
||||
break;
|
||||
case 'to|year':
|
||||
$field_name = drupal_substr($field['field'], 0, -14);
|
||||
$item['date_fields'] = array('node_data_'. $field_name .'.'. $field_name .'_value2');
|
||||
$item['granularity'] = 'year';
|
||||
break;
|
||||
case 'to|month':
|
||||
$field_name = drupal_substr($field['field'], 0, -15);
|
||||
$item['date_fields'] = array('node_data_'. $field_name .'.'. $field_name .'_value2');
|
||||
$item['granularity'] = 'month';
|
||||
break;
|
||||
case 'to|day':
|
||||
$field_name = drupal_substr($field['field'], 0, -13);
|
||||
$item['date_fields'] = array('node_data_'. $field_name .'.'. $field_name .'_value2');
|
||||
$item['granularity'] = 'day';
|
||||
break;
|
||||
}
|
||||
$item['table'] = 'node';
|
||||
$item['field'] = 'date_filter';
|
||||
$item['form_type'] = 'date_text';
|
||||
$item['operator'] = $field['operator'] == '<>' ? '!=' : $field['operator'];
|
||||
if ($field['value'] == 'now' || $field['options'] == 'now') {
|
||||
$item['default_date'] = 'now';
|
||||
}
|
||||
else {
|
||||
$item['value'] = $field['value'];
|
||||
$item['default_date'] = $field['options'];
|
||||
}
|
||||
$view->set_item($display, 'filter', $id, $item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
717
modules/date/date/date_admin.inc
Normal file
717
modules/date/date/date_admin.inc
Normal file
|
@ -0,0 +1,717 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Date administration code.
|
||||
* Moved to separate file since there is a lot of code here that is not needed often.
|
||||
*/
|
||||
/**
|
||||
* Implementation of hook_widget_settings().
|
||||
*/
|
||||
function _date_widget_settings($op, &$field) {
|
||||
switch ($op) {
|
||||
case 'callbacks':
|
||||
return array('default value' => CONTENT_CALLBACK_CUSTOM);
|
||||
case 'form':
|
||||
return date_widget_settings_form($field);
|
||||
|
||||
case 'save':
|
||||
return array('default_value', 'default_value_code', 'default_value2', 'default_value_code2', 'input_format', 'input_format_custom', 'increment', 'text_parts', 'year_range', 'label_position');
|
||||
|
||||
case 'validate':
|
||||
if ($field['default_value'] == 'strtotime') {
|
||||
$is_strtotime = @strtotime($field['default_value_code']);
|
||||
if (!$is_strtotime) {
|
||||
form_set_error('default_value_code', t('The Strtotime default value is invalid.'));
|
||||
}
|
||||
}
|
||||
if ($field['default_value2'] == 'strtotime') {
|
||||
$is_strtotime = @strtotime($field['default_value_code2']);
|
||||
if (!$is_strtotime) {
|
||||
form_set_error('default_value_code2', t('The Strtotime default value for the To Date is invalid.'));
|
||||
}
|
||||
}
|
||||
if (in_array($field['widget']['type'], array('date_select', 'date_popup', 'date_select_repeat', 'date_popup_repeat')) && !date_range_valid($field['year_range'])) {
|
||||
form_set_error('year_range', t('Years back and forward must be in the format -9:+9.'));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom widget settings manipulation.
|
||||
*
|
||||
* CCK widget settings can't use form_set_value(),
|
||||
* so do it in a custom function.
|
||||
*/
|
||||
function date_widget_settings_validate(&$form, &$form_state) {
|
||||
// TODO Not sure there is any limitation any more in this version. Need to check.
|
||||
if ($form_state['values']['widget_type'] == 'date_popup') {
|
||||
// Only a limited set of formats is available for the Date Popup module
|
||||
if (!empty($form_state['values']['input_format_custom']) || !in_array($form_state['values']['input_format'], date_popup_formats())) {
|
||||
form_set_value($form['input_format_custom'], NULL, $form_state);
|
||||
form_set_value($form['input_format'], DATE_FORMAT_DATETIME, $form_state);
|
||||
}
|
||||
}
|
||||
if (isset($form_state['values']['advanced']['label_position'])) {
|
||||
form_set_value($form['label_position'], $form_state['values']['advanced']['label_position'], $form_state);
|
||||
}
|
||||
// Munge the table display for text parts back into an array of text parts.
|
||||
if (is_array($form_state['values']['advanced']['text_parts'])) {
|
||||
form_set_value($form['text_parts'], array_keys(array_filter($form_state['values']['advanced']['text_parts'])), $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
function date_widget_settings_form($widget) {
|
||||
$form = array(
|
||||
'#element_validate' => array('date_widget_settings_validate'),
|
||||
);
|
||||
$form['input']['default_value'] = array(
|
||||
'#type' => 'select', '#title' => t('Default value'),
|
||||
'#default_value' => !empty($widget['default_value']) ? $widget['default_value'] : 'blank',
|
||||
'#options' => array('blank' => t('Blank'), 'now' => t('Now'), 'strtotime' => t('Relative')),
|
||||
'#description' => t("A default value to use for this field. If you select 'Relative', add details below."),
|
||||
);
|
||||
$form['input']['default_value2'] = array(
|
||||
'#type' => 'select', '#title' => t('Default value for To date'),
|
||||
'#default_value' => !empty($widget['default_value2']) ? $widget['default_value2'] : 'same',
|
||||
'#options' => array('same' => t('Same as From date'), 'blank' => t('Blank'), 'now' => t('Now'), 'strtotime' => t('Relative')),
|
||||
'#description' => t("A default value to use for this field. If you select 'Relative', add details below."),
|
||||
);
|
||||
$form['input']['default'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Customize Default Value'),
|
||||
'#description' => '<p>' . t("The custom value for a Relative default should be something that describes a time by reference to the current day using strtotime, like '+90 days' (90 days from the day the field is created) or '+1 Saturday' (the next Saturday). See !strtotime for more details.", array('!strtotime' => l(t('strtotime'), 'http://www.php.net/manual/en/function.strtotime.php'))) . '</p>',
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
);
|
||||
$form['input']['default']['default_value_code'] = array(
|
||||
'#type' => 'textfield', '#title' => t('Custom value for From date'),
|
||||
'#default_value' => isset($widget['default_value_code']) ? $widget['default_value_code'] : '',
|
||||
);
|
||||
|
||||
$form['input']['default']['default_value_code2'] = array(
|
||||
'#type' => 'textfield', '#title' => t('Custom value for To date'),
|
||||
'#default_value' => !empty($widget['default_value_code2']) ? $widget['default_value_code2'] : '',
|
||||
);
|
||||
|
||||
$options = array();
|
||||
if ($widget['type'] == 'date_popup' && module_exists('date_popup')) {
|
||||
$formats = date_popup_formats();
|
||||
$default_format = array_shift($formats);
|
||||
}
|
||||
else {
|
||||
// example input formats must show all possible date parts, so add seconds.
|
||||
$formats = str_replace('i', 'i:s', array_keys(date_get_formats('short')));
|
||||
$formats = drupal_map_assoc($formats);
|
||||
$default_format = str_replace('i', 'i:s', variable_get('date_format_short', 'm/d/Y - H:i'));
|
||||
}
|
||||
$now = date_example_date();
|
||||
foreach ($formats as $f) {
|
||||
$options[$f] = date_format_date($now, 'custom', $f);
|
||||
}
|
||||
$form['input']['input_format'] = array(
|
||||
'#type' => 'select', '#title' => t('Input format'),
|
||||
'#default_value' => !empty($widget['input_format']) ? $widget['input_format'] : $default_format,
|
||||
'#options' => $options,
|
||||
'#description' => t('Set the order and format for the date parts in the input form. The format will be adapted to remove values not in the granularity for this field.'),
|
||||
);
|
||||
|
||||
// Only a limited set of formats is available for the Date Popup module
|
||||
if ($widget['type'] != 'date_popup') {
|
||||
$form['input']['format']['input_format_custom'] = array(
|
||||
'#type' => 'textfield', '#title' => t('Custom input format'),
|
||||
'#default_value' => !empty($widget['input_format_custom']) ? $widget['input_format_custom'] : '',
|
||||
'#description' => t("The custom format, if provided, will override the input format selected above. The custom format, if provided, will override the selected display or input options. Define a php date format string like 'm-d-Y H:i' (see <a href=\"@link\">http://php.net/date</a> for more details).", array('@link' => 'http://php.net/date')),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$form['input']['format']['input_format_custom'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#value' => '',
|
||||
);
|
||||
}
|
||||
if (in_array($widget['type'], array('date_select', 'date_popup', 'date_select_repeat', 'date_popup_repeat'))) {
|
||||
$form['input']['year_range'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Years back and forward'),
|
||||
'#default_value' => !empty($widget['year_range']) ? $widget['year_range'] : '-3:+3',
|
||||
'#size' => 10,
|
||||
'#maxsize' => 10,
|
||||
'#description' => t('Number of years to go back and forward in the year selection list, default is -3:+3.'),
|
||||
);
|
||||
$form['input']['increment'] = array(
|
||||
'#type' => 'select', '#title' => t('Time increment'),
|
||||
'#default_value' => isset($widget['increment']) ? $widget['increment'] : 1,
|
||||
'#options' => array(1 => 1, 5 => 5, 10 => 10, 15 => 15, 30 => 30),
|
||||
'#description' => t('Increment the minute and second fields by this amount.'),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$form['increment'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#value' => !empty($widget['increment']) ? $widget['increment'] : 1,
|
||||
);
|
||||
$form['year_range'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#value' => isset($widget['year_range']) ? $widget['year_range'] : '-3:+3',
|
||||
);
|
||||
}
|
||||
|
||||
$form['label_position'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => !empty($widget['label_position']) ? $widget['label_position'] : 'above',
|
||||
);
|
||||
$form['text_parts'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => isset($widget['text_parts']) ? $widget['text_parts'] : '',
|
||||
);
|
||||
$form['input']['advanced'] = array(
|
||||
'#tree' => TRUE,
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Customize Date Parts'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
);
|
||||
$form['input']['advanced']['label_position'] = array(
|
||||
'#type' => 'radios',
|
||||
'#options' => array('above' => t('Above'), 'within' => t('Within'), 'none' => t('None')),
|
||||
'#default_value' => !empty($widget['label_position']) ? $widget['label_position'] : 'above',
|
||||
'#title' => t('Position of date part labels'),
|
||||
'#description' => t("The location of date part labels, like 'Year', 'Month', or 'Day'. 'Above' will display them as titles above each date part. 'Within' will insert the label as the first option in the select list and in blank textfields. 'None' will not label any of the date parts. The exact text in the label is controlled by themes like 'date_part_label_year' and 'date_part_label_month'."),
|
||||
);
|
||||
$form['input']['advanced']['text_parts'] = array(
|
||||
'#theme' => $widget['type'] == 'date_select' ? 'date_text_parts' : '',
|
||||
);
|
||||
$text_parts = isset($widget['text_parts']) ? (array) $widget['text_parts'] : array();
|
||||
foreach (date_granularity_names() as $key => $value) {
|
||||
if ($widget['type'] == 'date_select') {
|
||||
$form['input']['advanced']['text_parts'][$key] = array(
|
||||
'#type' => 'radios',
|
||||
'#default_value' => in_array($key, $text_parts) ? 1 : 0,
|
||||
'#options' => array(0 => '', 1 => ''),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$form['input']['advanced']['text_parts'][$key] = array(
|
||||
'#type' => 'hidden',
|
||||
'#value' => in_array($key, (array) $widget['text_parts']) ? 1 : 0,
|
||||
);
|
||||
}
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the text/select options for date parts in a table
|
||||
* for easier readability.
|
||||
*/
|
||||
function theme_date_text_parts($element) {
|
||||
$names = date_granularity_names();
|
||||
$rows = array();
|
||||
foreach ($names as $key => $part) {
|
||||
if ($element[$key]['#type'] == 'hidden') {
|
||||
$rows[] = drupal_render($element[$key]);
|
||||
}
|
||||
else {
|
||||
$rows[] = array($names[$key], drupal_render($element[$key][0]), drupal_render($element[$key][1]));
|
||||
}
|
||||
}
|
||||
if ($element['year']['#type'] == 'hidden') {
|
||||
return implode($rows);
|
||||
}
|
||||
else {
|
||||
$header = array(t('Input Type'), t('Select list'), t('Text field'));
|
||||
return theme('table', $header, $rows);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_field_settings().
|
||||
*/
|
||||
function _date_field_settings($op, $field) {
|
||||
switch ($op) {
|
||||
case 'form':
|
||||
return date_field_settings_form($field);
|
||||
|
||||
case 'validate':
|
||||
if (!in_array('year', $field['granularity'])) {
|
||||
form_set_error('granularity', t('Granularity must include a year.'));
|
||||
}
|
||||
if ($field['tz_handling'] != 'none' && !in_array('hour', array_filter($field['granularity']))) {
|
||||
form_set_error('tz_handling', t('Dates without hours granularity must not use any timezone handling.'));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'save':
|
||||
|
||||
$options = array('granularity', 'timezone_db', 'tz_handling', 'todate', 'repeat', 'repeat_collapsed', 'default_format');
|
||||
return $options;
|
||||
|
||||
case 'database columns':
|
||||
return date_columns($field);
|
||||
|
||||
case 'views data':
|
||||
$data = content_views_field_views_data($field);
|
||||
$db_info = content_database_info($field);
|
||||
$table_alias = content_views_tablename($field);
|
||||
|
||||
// Swap in the date multiple value handler for
|
||||
// CCK's regular multiple value handler.
|
||||
$data[$table_alias][$field['field_name'] .'_value']['field']['handler'] = 'date_handler_field_multiple';
|
||||
|
||||
// Unset the filter and argument handlers, dates can use the generic
|
||||
// date argument and filter handlers created by the Date API.
|
||||
//unset($data[$table_alias][$field['field_name'] .'_value']['argument']);
|
||||
//unset($data[$table_alias][$field['field_name'] .'_value']['filter']);
|
||||
$data[$table_alias][$field['field_name'] .'_value']['argument']['handler'] = 'date_api_argument_handler';
|
||||
$data[$table_alias][$field['field_name'] .'_value']['filter']['handler'] = 'date_api_filter_handler';
|
||||
|
||||
// Add in another set of fields for the To date.
|
||||
if (!empty($field['todate'])) {
|
||||
$data[$table_alias][$field['field_name'] .'_value']['field']['title'] = $data[$table_alias][$field['field_name'] .'_value']['title'];
|
||||
$data[$table_alias][$field['field_name'] .'_value']['field']['title short'] = $data[$table_alias][$field['field_name'] .'_value']['title short'];
|
||||
|
||||
$data[$table_alias][$field['field_name'] .'_value2'] = $data[$table_alias][$field['field_name'] .'_value'];
|
||||
|
||||
$data[$table_alias][$field['field_name'] .'_value']['title'] .= ' - ' . t('From date');
|
||||
$data[$table_alias][$field['field_name'] .'_value']['title short'] .= ' - ' . t('From date');
|
||||
$data[$table_alias][$field['field_name'] .'_value']['field']['title'] .= ' - ' . t('From date');
|
||||
$data[$table_alias][$field['field_name'] .'_value']['field']['title short'] .= ' - ' . t('From date');
|
||||
|
||||
$data[$table_alias][$field['field_name'] .'_value2']['title'] .= ' - ' . t('To date');
|
||||
$data[$table_alias][$field['field_name'] .'_value2']['title short'] .= ' - ' . t('To date');
|
||||
$data[$table_alias][$field['field_name'] .'_value2']['field']['title'] .= ' - ' . t('To date');
|
||||
$data[$table_alias][$field['field_name'] .'_value2']['field']['title short'] .= ' - ' . t('To date');
|
||||
|
||||
$data[$table_alias][$field['field_name'] .'_value2']['field']['field'] .= '2';
|
||||
$data[$table_alias][$field['field_name'] .'_value2']['sort']['field'] .= '2';
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for field columns.
|
||||
*/
|
||||
function date_columns($field) {
|
||||
if ($field['type'] == 'date') {
|
||||
$db_columns['value'] = array('type' => 'varchar', 'length' => 20, 'not null' => FALSE, 'sortable' => TRUE, 'views' => TRUE);
|
||||
}
|
||||
elseif ($field['type'] == 'datestamp') {
|
||||
$db_columns['value'] = array('type' => 'int', 'not null' => FALSE, 'sortable' => TRUE, 'views' => TRUE);
|
||||
}
|
||||
elseif ($field['type'] == 'datetime') {
|
||||
$db_columns['value'] = array('type' => 'datetime', 'not null' => FALSE, 'sortable' => TRUE, 'views' => TRUE);
|
||||
}
|
||||
// If a second date is needed for 'To date', just make a copy of the first one.
|
||||
if (!empty($field['todate'])) {
|
||||
$db_columns['value2'] = $db_columns['value'];
|
||||
|
||||
// We don't want CCK to create additional columns, just the first.
|
||||
// We modify them our own way in views data.
|
||||
$db_columns['value2']['views'] = FALSE;
|
||||
}
|
||||
// timezone and offset columns are used only if date-specific dates are chosen.
|
||||
if (isset($field['tz_handling']) && $field['tz_handling'] == 'date') {
|
||||
$db_columns['timezone'] = array('type' => 'varchar', 'length' => 50, 'not null' => FALSE, 'sortable' => TRUE, 'views' => FALSE);
|
||||
$db_columns['offset'] = array('type' => 'int', 'not null' => FALSE, 'sortable' => TRUE, 'views' => FALSE);
|
||||
if (!empty($field['todate'])) $db_columns['offset2'] = array('type' => 'int', 'not null' => FALSE, 'sortable' => TRUE, 'views' => FALSE);
|
||||
}
|
||||
if (isset($field['repeat']) && $field['repeat'] == 1) {
|
||||
$db_columns['rrule'] = array('type' => 'text', 'not null' => FALSE, 'sortable' => FALSE, 'views' => FALSE);
|
||||
}
|
||||
return $db_columns;
|
||||
}
|
||||
|
||||
function date_field_settings_form($field) {
|
||||
$form = array(
|
||||
'#element_validate' => array('date_field_settings_validate'),
|
||||
);
|
||||
// Make sure granularity is in the right format and has no empty values.
|
||||
if (!empty($field['granularity']) && is_array($field['granularity'])) {
|
||||
$granularity = array_filter($field['granularity']);
|
||||
}
|
||||
else {
|
||||
$granularity = array('year', 'month', 'day', 'hour', 'minute');
|
||||
}
|
||||
$tz_handling = isset($field['tz_handling']) ? $field['tz_handling'] : (date_has_time($granularity) ? 'site' : 'none');
|
||||
|
||||
// If adding a repeat, override the Content module's handling of the multiple values option.
|
||||
if (module_exists('date_repeat') && date_is_repeat_field($field)) {
|
||||
$form['multiple'] = array('#type' => 'hidden', '#value' => 1);
|
||||
$form['repeat'] = array('#type' => 'hidden', '#value' => 1);
|
||||
}
|
||||
else {
|
||||
$form['repeat'] = array('#type' => 'hidden', '#value' => 0);
|
||||
}
|
||||
|
||||
$description = t("Display a matching second date field as a 'To date'. If marked 'Optional' field will be presented but not required. If marked 'Required' the 'To date' will be required if the 'From date' is required or filled in.");
|
||||
$description .= date_data_loss_warning('To date');
|
||||
$form['input']['todate'] = array(
|
||||
'#type' => 'radios', '#title' => t('To Date'),
|
||||
'#options' => array('' => t('Never'), 'optional' => t('Optional'), 'required' => t('Required')),
|
||||
'#description' => $description,
|
||||
'#default_value' => isset($field['todate']) ? $field['todate'] : '',
|
||||
);
|
||||
$form['input']['granularity'] = array(
|
||||
'#type' => 'select', '#title' => t('Granularity'),
|
||||
'#default_value' => $granularity,
|
||||
'#options' => date_granularity_names(),
|
||||
'#multiple' => TRUE,
|
||||
'#description' => t('Set the date elements to be stored (at least a year is required).'),
|
||||
);
|
||||
$format_types = array();
|
||||
foreach (date_get_format_types('', TRUE) as $name => $info) {
|
||||
$format_types[$name] = $info['title'];
|
||||
}
|
||||
$form['default_format'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Default Display'),
|
||||
'#default_value' => !empty($field['default_format']) ? $field['default_format'] : 'medium',
|
||||
'#options' => $format_types,
|
||||
'#description' => t('Select a default format type to be used for the date display. Visit the <a href="@date-time-page">Date and time date format page</a> to add and edit format types.', array('@date-time-page' => url('admin/settings/date-time/formats'))),
|
||||
);
|
||||
|
||||
$description = t('Select the timezone handling method to be used for this date field.');
|
||||
$description .= date_data_loss_warning('Time zone handling');
|
||||
$form['tz_handling'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Time zone handling'),
|
||||
'#default_value' => $tz_handling,
|
||||
'#options' => date_timezone_handling_options(),
|
||||
'#description' => $description,
|
||||
);
|
||||
// Force this value to hidden because we don't want to allow it to be changed right now,
|
||||
// but allow it to be a variable if needed.
|
||||
$form['timezone_db'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#value' => date_get_timezone_db($tz_handling),
|
||||
);
|
||||
|
||||
if (module_exists('date_repeat') && date_is_repeat_field($field)) {
|
||||
$form['repeat_collapsed'] = array(
|
||||
'#type' => 'radios',
|
||||
'#default_value' => !empty($field['repeat_collapsed']) ? intval($field['repeat_collapsed']) : 0,
|
||||
'#options' => array(0 => t('Expanded'), 1 => t('Collapsed')),
|
||||
'#title' => t('Repeat display'),
|
||||
'#description' => t("Should the repeat options form start out expanded or collapsed? Set to 'Collapsed' to make those options less obtrusive."),
|
||||
);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom field settings manipulation.
|
||||
*
|
||||
* CCK field settings can't use form_set_value(),
|
||||
* so do it in a custom function.
|
||||
*/
|
||||
function date_field_settings_validate(&$form, &$form_state) {
|
||||
if ($form_state['values']['tz_handling'] == 'none') {
|
||||
form_set_value($form['timezone_db'], '', $form_state);
|
||||
}
|
||||
else {
|
||||
form_set_value($form['timezone_db'], date_get_timezone_db($form_state['values']['tz_handling']), $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
function date_data_loss_warning($name) {
|
||||
return '<p class="error">' . t('Changing the %name setting after data has been created could result in the loss of data!', array('%name' => $name)) . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timezone handling options
|
||||
*
|
||||
* the 'none' option will do no timezone conversions and will store and display dates exactly as entered
|
||||
* useful in locales or situations where timezone conversions are not working reliably,
|
||||
* for dates with no times, for historical dates where timezones are irrelevant,
|
||||
* or anytime conversion is unnecessary or undesirable
|
||||
*/
|
||||
function date_timezone_handling_options() {
|
||||
return array(
|
||||
'site' => t("Site's time zone"),
|
||||
'date' => t("Date's time zone"),
|
||||
'user' => t("User's time zone"),
|
||||
'utc' => 'UTC',
|
||||
'none' => t('No time zone conversion'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an example date and make sure the difference between
|
||||
* month and day and 12 and 24 hours will be clear.
|
||||
*/
|
||||
function date_example_date() {
|
||||
$now = date_now();
|
||||
if (date_format($now, 'm') == date_format($now, 'd')) {
|
||||
date_modify($now, '+1 day');
|
||||
}
|
||||
if (date_format($now, 'H') == date_format($now, 'h')) {
|
||||
date_modify($now, '+12 hours');
|
||||
}
|
||||
return $now;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to create a field array with default values for a date
|
||||
* $field, based on field type, widget type, and timezone handling.
|
||||
*
|
||||
* This function can be used to make it easier to create new date fields
|
||||
* in profiles or custom code.
|
||||
*
|
||||
* @param $field_type
|
||||
* Can be 'date', 'datestamp', or 'datetime'.
|
||||
* @param $widget_type
|
||||
* Can be 'date_text', 'date_text_repeat', 'date_select',
|
||||
* 'date_select_repeat', 'date_popup', 'date_popup_repeat'.
|
||||
* @param $tz_handling
|
||||
* Can be 'site', 'date', 'utc', 'none', or 'user'.
|
||||
* @param $overrides
|
||||
* An optional array of field/widget values that should
|
||||
* override the normal defaults.
|
||||
*/
|
||||
function date_field_default_values($field_type, $widget_type, $tz_handling, $overrides = array()) {
|
||||
module_load_include('inc', 'content', 'includes/content.crud');
|
||||
$repeat_widgets = array('date_select_repeat', 'date_text_repeat', 'date_popup_repeat');
|
||||
|
||||
$base_field_values = array(
|
||||
'field_name' => '',
|
||||
'type_name' => '',
|
||||
'multiple' => in_array($widget_type, $repeat_widgets) ? 1 : 0,
|
||||
'module' => 'date',
|
||||
'granularity' => array(
|
||||
'year' => 'year',
|
||||
'month' => 'month',
|
||||
'day' => 'day',
|
||||
'hour' => 'hour',
|
||||
'minute' => 'minute',
|
||||
),
|
||||
'timezone_db' => date_get_timezone_db($tz_handling),
|
||||
'tz_handling' => $tz_handling,
|
||||
'todate' => 'optional',
|
||||
'repeat' => in_array($widget_type, $repeat_widgets) ? 1 : 0,
|
||||
'repeat_collapsed' => 0,
|
||||
'default_format' => 'medium',
|
||||
);
|
||||
$base_widget_values = array(
|
||||
'label' => '',
|
||||
'default_value' => 'now',
|
||||
'default_value_code' => '',
|
||||
'default_value2' => 'same',
|
||||
'default_value_code2' => '',
|
||||
'input_format' => date_default_format($widget_type),
|
||||
'input_format_custom' => '',
|
||||
'increment' => 1,
|
||||
'text_parts' => array(),
|
||||
'year_range' => '-3:+3',
|
||||
'label_position' => 'above',
|
||||
'weight' => 0,
|
||||
'description' => '',
|
||||
'module' => 'date',
|
||||
);
|
||||
$field_values['date'] = $base_field_values;
|
||||
$field_values['date']['type'] = 'date';
|
||||
|
||||
$field_values['datestamp'] = $base_field_values;
|
||||
$field_values['datestamp']['type'] = 'datestamp';
|
||||
|
||||
$field_values['datetime'] = $base_field_values;
|
||||
$field_values['datetime']['type'] = 'datetime';
|
||||
|
||||
$widget_values['date_select'] = $base_widget_values;
|
||||
$widget_values['date_select']['type'] = 'date_select';
|
||||
|
||||
$widget_values['date_text'] = $base_widget_values;
|
||||
$widget_values['date_text']['type'] = 'date_text';
|
||||
|
||||
$widget_values['date_popup'] = $base_widget_values;
|
||||
$widget_values['date_popup']['type'] = 'date_popup';
|
||||
$widget_values['date_popup']['module'] = 'date_popup';
|
||||
|
||||
$widget_values['date_select_repeat'] = $base_widget_values;
|
||||
$widget_values['date_select_repeat']['type'] = 'date_select_repeat';
|
||||
|
||||
$widget_values['date_text_repeat'] = $base_widget_values;
|
||||
$widget_values['date_text_repeat']['type'] = 'date_text_repeat';
|
||||
|
||||
$widget_values['date_popup_repeat'] = $base_widget_values;
|
||||
$widget_values['date_popup_repeat']['type'] = 'date_popup_repeat';
|
||||
|
||||
// Get the basic field array with content module default values.
|
||||
$field = content_field_default_values($field_type);
|
||||
|
||||
// Update it with default values for this date field and widget type.
|
||||
foreach ($field_values[$field_type] as $key => $value) {
|
||||
$field[$key] = $value;
|
||||
}
|
||||
foreach ($widget_values[$widget_type] as $key => $value) {
|
||||
$field['widget'][$key] = $value;
|
||||
}
|
||||
|
||||
// Allow overrides of specific default values.
|
||||
foreach ($overrides as $key => $value) {
|
||||
if ($key != 'widget') {
|
||||
$field[$key] = $value;
|
||||
}
|
||||
else {
|
||||
foreach ($value as $widget_key => $widget_value) {
|
||||
$field['widget'][$widget_key] = $widget_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Make sure multiple gets set correctly for repeating dates.
|
||||
if ($field['repeat']) $field['multiple'] = 1;
|
||||
|
||||
// Reset columns and db_storage, which may need to be
|
||||
// adjusted to the new values.
|
||||
$field['columns'] = date_columns($field);
|
||||
$field['db_storage'] = content_storage_type($field);
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatter settings.
|
||||
*
|
||||
* Form element used both in the date_handler_field_multiple Views handler
|
||||
* and on the CCK Display fields page.
|
||||
*/
|
||||
function _date_formatter_settings($form_state = NULL, $field, $options = array(), $views_form = FALSE) {
|
||||
$field_name = $field['field_name'];
|
||||
$field = content_fields($field_name);
|
||||
$type_name = isset($options['type_name']) ? $options['type_name'] : $field['type_name'];
|
||||
$context = isset($options['context']) ? $options['context'] : 'full';
|
||||
if (empty($options['fromto'])) {
|
||||
$options = date_formatter_get_settings($field_name, $type_name, $context);
|
||||
}
|
||||
|
||||
$form = array();
|
||||
$form['fromto'] = array(
|
||||
'#access' => $field['todate'],
|
||||
'#weight' => 5,
|
||||
);
|
||||
if (isset($options['fromto']) && isset($options['fromto']['fromto'])) {
|
||||
$default = $options['fromto']['fromto'];
|
||||
}
|
||||
else {
|
||||
$default = 'both';
|
||||
}
|
||||
$form['fromto']['fromto'] = array(
|
||||
'#type' => 'select',
|
||||
'#options' => array(
|
||||
'both' => t('Display From and To dates'),
|
||||
'value' => t('Display From date only'),
|
||||
'value2' => t('Display To date only'),
|
||||
),
|
||||
'#default_value' => $default,
|
||||
'#weight' => 1,
|
||||
);
|
||||
|
||||
$form['multiple'] = array(
|
||||
'#access' => $field['multiple'],
|
||||
'#weight' => 6,
|
||||
);
|
||||
|
||||
// Make the string translatable by keeping it as a whole rather than
|
||||
// translating prefix and suffix separately.
|
||||
if (isset($options['multiple']) && isset($options['multiple']['multiple_number'])) {
|
||||
$default = $options['multiple']['multiple_number'];
|
||||
}
|
||||
else {
|
||||
$default = '';
|
||||
}
|
||||
list($prefix, $suffix) = explode('@count', t('Show @count value(s)'));
|
||||
$form['multiple']['multiple_number'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#size' => 5,
|
||||
'#field_prefix' => theme('advanced_help_topic', 'date_api', 'date-display') . $prefix,
|
||||
'#field_suffix' => $suffix,
|
||||
'#default_value' => $default,
|
||||
'#weight' => 1,
|
||||
);
|
||||
if ($views_form) {
|
||||
$form['multiple']['multiple_number'] += array(
|
||||
'#process' => array('views_process_dependency'),
|
||||
'#dependency' => array('edit-options-multiple-group' => array(TRUE)),
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($options['multiple']) && isset($options['multiple']['multiple_from'])) {
|
||||
$default = $options['multiple']['multiple_from'];
|
||||
}
|
||||
else {
|
||||
$default = '';
|
||||
}
|
||||
list($prefix, $suffix) = explode('@count', t('starting from @count'));
|
||||
$form['multiple']['multiple_from'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#size' => 15,
|
||||
'#field_prefix' => $prefix,
|
||||
'#field_suffix' => $suffix,
|
||||
'#default_value' => $default,
|
||||
'#weight' => 2,
|
||||
);
|
||||
if ($views_form) {
|
||||
$form['multiple']['multiple_from'] += array(
|
||||
'#process' => array('views_process_dependency'),
|
||||
'#dependency' => array('edit-options-multiple-group' => array(TRUE)),
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($options['multiple']) && isset($options['multiple']['multiple_to'])) {
|
||||
$default = $options['multiple']['multiple_to'];
|
||||
}
|
||||
else {
|
||||
$default = '';
|
||||
}
|
||||
list($prefix, $suffix) = explode('@count', t('ending on @count'));
|
||||
$form['multiple']['multiple_to'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#size' => 15,
|
||||
'#field_prefix' => $prefix,
|
||||
'#field_suffix' => $suffix,
|
||||
'#default_value' => $default,
|
||||
'#weight' => 3,
|
||||
);
|
||||
if ($views_form) {
|
||||
$form['multiple']['multiple_to'] += array(
|
||||
'#process' => array('views_process_dependency'),
|
||||
'#dependency' => array('edit-options-multiple-group' => array(TRUE)),
|
||||
);
|
||||
}
|
||||
|
||||
$form['repeat'] = array(
|
||||
'#access' => $field['repeat'],
|
||||
'#weight' => 7,
|
||||
);
|
||||
if (isset($options['repeat']) && isset($options['repeat']['show_repeat_rule'])) {
|
||||
$default = $options['repeat']['show_repeat_rule'];
|
||||
}
|
||||
else {
|
||||
$default = 'show';
|
||||
}
|
||||
$form['repeat']['show_repeat_rule'] = array(
|
||||
'#type' => 'select',
|
||||
'#options' => array(
|
||||
'show' => t('Display repeat rule'),
|
||||
'hide' => t('Hide repeat rule')),
|
||||
'#default_value' => $default,
|
||||
);
|
||||
|
||||
if (!$views_form) {
|
||||
$form['field'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $field,
|
||||
);
|
||||
$form['type_name'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $type_name,
|
||||
);
|
||||
$form['context'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => $context,
|
||||
);
|
||||
}
|
||||
return $form;
|
||||
}
|
185
modules/date/date/date_content_generate.inc
Normal file
185
modules/date/date/date_content_generate.inc
Normal file
|
@ -0,0 +1,185 @@
|
|||
<?php
|
||||
/**
|
||||
* Implementation of Devel module's hook_content_generate().
|
||||
*
|
||||
* Included only when needed.
|
||||
*/
|
||||
function _date_content_generate($node, $field) {
|
||||
include_once('./'. drupal_get_path('module', 'date_api') .'/date_api_elements.inc');
|
||||
|
||||
$node_field = array();
|
||||
if (isset($field['widget']['year_range'])) {
|
||||
$split = explode(':', $field['widget']['year_range']);
|
||||
$back = str_replace('-', '', $split[0]);
|
||||
$forward = str_replace('+', '', $split[1]);
|
||||
}
|
||||
else {
|
||||
$back = 2;
|
||||
$forward = 2;
|
||||
}
|
||||
// Pick a random year within the time range,
|
||||
// and a random second within that year.
|
||||
$year = date_format(date_now(), 'Y') - $back + mt_rand(0, ($forward + $back));
|
||||
$start = date_make_date($year .'-01-01 00:00:00', date_get_timezone_db($field['tz_handling']));
|
||||
$leap = date_format($start, 'L');
|
||||
$max_days = $leap ? 366 : 365;
|
||||
$seconds = mt_rand(0, ($max_days * 86400));
|
||||
date_modify($start, "+$seconds seconds");
|
||||
$increment = $field['widget']['increment'];
|
||||
date_increment_round($start, $increment);
|
||||
|
||||
// Modify To date by 1 hour to 3 days, shorter for repeating dates
|
||||
// longer for others.
|
||||
$start2 = drupal_clone($start);
|
||||
$max = !empty($field['repeat']) ? 720 : 4320;
|
||||
$max = 240;
|
||||
date_modify($start2, '+'. mt_rand(60, $max) .' minutes');
|
||||
date_increment_round($start2, $increment);
|
||||
|
||||
if ($field['tz_handling'] == 'date') {
|
||||
// Choose a random timezone.
|
||||
// Not all keys exist, so we have to check.
|
||||
$timezones = array_keys(date_timezone_names(TRUE));
|
||||
$key = mt_rand(0, count($timezones) - 1);
|
||||
if (!array_key_exists($key, $timezones)) {
|
||||
$timezone = date_default_timezone_name();
|
||||
}
|
||||
else {
|
||||
$timezone = $timezones[$key];
|
||||
}
|
||||
}
|
||||
else {
|
||||
$timezone = date_get_timezone($field['tz_handling']);
|
||||
}
|
||||
|
||||
switch ($field['type']) {
|
||||
case 'date':
|
||||
$format = DATE_FORMAT_ISO;
|
||||
break;
|
||||
case 'datestamp':
|
||||
$format = DATE_FORMAT_UNIX;
|
||||
break;
|
||||
case 'datetime':
|
||||
$format = DATE_FORMAT_DATETIME;
|
||||
break;
|
||||
}
|
||||
$node_field['value'] = date_format($start, $format);
|
||||
if ($field['todate']) {
|
||||
$node_field['value2'] = date_format($start2, $format);
|
||||
}
|
||||
date_timezone_set($start, timezone_open($timezone));
|
||||
$node_field['timezone'] = $timezone;
|
||||
$node_field['offset'] = date_offset_get($start);
|
||||
date_timezone_set($start2, timezone_open($timezone));
|
||||
$node_field['offset2'] = date_offset_get($start2);
|
||||
|
||||
if (!empty($field['repeat'])) {
|
||||
include_once('./'. drupal_get_path('module', 'date_repeat') .'/date_repeat_calc.inc');
|
||||
include_once('./'. drupal_get_path('module', 'date') .'/date_repeat.inc');
|
||||
include_once('./'. drupal_get_path('module', 'date_api') .'/date_api_ical.inc');
|
||||
|
||||
// Create a repeating date.
|
||||
$duration = date_difference($start, $start2);
|
||||
$form_values = array();
|
||||
|
||||
// Create the default case more frequently than case 1 or 2.
|
||||
$which = mt_rand(0, 10);
|
||||
$max_items = 10;
|
||||
$intervals = array_keys(INTERVAL_options());
|
||||
unset($intervals[0]);
|
||||
$interval = $intervals[mt_rand(1, 3)];
|
||||
switch ($which) {
|
||||
case 1:
|
||||
$mo = mt_rand(1, 28);
|
||||
$options = array('YEARLY', 'MONTHLY');
|
||||
$freq = date_content_generate_key($options);
|
||||
$freq = $options[$freq];
|
||||
$form_values['FREQ'] = $freq;
|
||||
// Make sure we'll find a match in our range.
|
||||
if ($freq == 'YEARLY') {
|
||||
$interval = 1;
|
||||
}
|
||||
$form_values['BYMONTHDAY'] = array($mo);
|
||||
break;
|
||||
case 2:
|
||||
$mo = mt_rand(1, 12);
|
||||
$options = array('YEARLY', 'MONTHLY');
|
||||
$freq = date_content_generate_key($options);
|
||||
$freq = $options[$freq];
|
||||
$form_values['FREQ'] = $freq;
|
||||
// Make sure we'll find a match in our range.
|
||||
if ($freq == 'YEARLY') {
|
||||
$interval = 1;
|
||||
}
|
||||
$form_values['BYMONTH'] = array($mo);
|
||||
break;
|
||||
default:
|
||||
$dows = array_keys(date_content_repeat_dow_options());
|
||||
$day = date_content_generate_key($dows);
|
||||
$dow = $dows[$day];
|
||||
$options = array('MONTHLY', 'DAILY', 'WEEKLY');
|
||||
$freq = date_content_generate_key($options);
|
||||
$freq = $options[$freq];
|
||||
$form_values['FREQ'] = $freq;
|
||||
$form_values['BYDAY'] = array($dow);
|
||||
break;
|
||||
}
|
||||
|
||||
$form_values['INTERVAL'] = $interval;
|
||||
|
||||
switch ($freq) {
|
||||
case 'YEARLY':
|
||||
$period = 'year';
|
||||
break;
|
||||
case 'MONTHLY':
|
||||
$period = 'month';
|
||||
break;
|
||||
case 'WEEKLY':
|
||||
$period = 'week';
|
||||
break;
|
||||
default:
|
||||
$period = 'day';
|
||||
break;
|
||||
|
||||
}
|
||||
date_modify($start2, '+'. max(1, $forward) .' years');
|
||||
date_increment_round($start2, $increment);
|
||||
$until = date_format($start2, 'Y-m-d H:i:s');
|
||||
$form_values['UNTIL'] = array('datetime' => $until, 'tz' => 'UTC');
|
||||
$form_values['COUNT'] = $max_items;
|
||||
|
||||
$rrule = date_api_ical_build_rrule($form_values);
|
||||
$values = date_repeat_build_dates($rrule, $form_values, $field, $node_field);
|
||||
|
||||
$start = $node_field;
|
||||
$node_field = array(0 => $start);
|
||||
$node_field[0]['rrule'] = $rrule;
|
||||
$node_field += $values;
|
||||
}
|
||||
return $node_field;
|
||||
}
|
||||
|
||||
function date_content_generate_key($array) {
|
||||
$keys = array_keys($array);
|
||||
$min = array_shift($keys);
|
||||
$max = array_pop($keys);
|
||||
return mt_rand($min, $max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for BYDAY options.
|
||||
*
|
||||
* Creates options like -1SU and 2TU
|
||||
* Omit options that won't find many matches, like 5th Sunday.
|
||||
*/
|
||||
function date_content_repeat_dow_options() {
|
||||
$options = array();
|
||||
foreach (date_repeat_dow_count_options() as $count_key => $count_value) {
|
||||
foreach (date_repeat_dow_day_options() as $dow_key => $dow_value) {
|
||||
if ($count_key != 5 && $count_key != -5) {
|
||||
$options[$count_key . $dow_key] = $count_value .' '. $dow_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $options;
|
||||
}
|
586
modules/date/date/date_elements.inc
Normal file
586
modules/date/date/date_elements.inc
Normal file
|
@ -0,0 +1,586 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Date forms and form themes and validation.
|
||||
*
|
||||
* All code used in form editing and processing is in this file,
|
||||
* included only during form editing.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Private implementation of hook_field validate operation.
|
||||
*/
|
||||
function _date_field_validate($op, &$node, $field, &$items, $teaser, $page) {
|
||||
$field_name = $field['field_name'];
|
||||
|
||||
// Don't try to validate if there were any errors before this point
|
||||
// since the element won't have been munged back into a date.
|
||||
if (!form_get_errors()) {
|
||||
foreach ($items as $delta => $item) {
|
||||
$process = date_process_values($field);
|
||||
foreach ($process as $processed) {
|
||||
$error_field = $field['field_name'] .']['. $delta .']['. $processed;
|
||||
$error_field .= $field['widget']['type'] == 'date_select' ? '][year' : '';
|
||||
if ($processed == 'value' && $field['todate']
|
||||
&& !date_is_valid($item['value'], $field['type'], $field['granularity'])
|
||||
&& (date_is_valid($item['value2'], $field['type'], $field['granularity']))) {
|
||||
form_set_error($error_field, t("A 'From date' date is required for field %field %delta.", array('%delta' => $field['multiple'] ? intval($delta + 1) : '', '%field' => t($field['widget']['label']))));
|
||||
}
|
||||
if ($processed == 'value2'
|
||||
&& $field['todate'] == 'required' && ($field['required']
|
||||
&& date_is_valid($item['value'], $field['type'], $field['granularity'])
|
||||
&& !date_is_valid($item['value2'], $field['type'], $field['granularity']))) {
|
||||
form_set_error($error_field, t("A 'To date' is required for field %field %delta.", array('%delta' => $field['multiple'] ? intval($delta + 1) : '', '%field' => t($field['widget']['label']))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Private implementation of hook_field update and insert operations.
|
||||
*/
|
||||
function _date_field_update($op, &$node, $field, &$items, $teaser, $page) {
|
||||
$field_name = $field['field_name'];
|
||||
if (empty($items)) {
|
||||
//$node->$field_name = array(); // Not sure about this, CCK should handle it.
|
||||
return;
|
||||
}
|
||||
|
||||
$values = $items;
|
||||
foreach ($values as $delta => $item) {
|
||||
|
||||
// Special case for ISO dates which may have been given artificial values for
|
||||
// some date parts to make them into valid dates.
|
||||
if (!empty($item['value']) && $field['type'] == DATE_ISO) {
|
||||
$items[$delta]['value'] = date_limit_value($items[$delta]['value'], date_granularity($field), $field['type']);
|
||||
if ($field['todate']) {
|
||||
$items[$delta]['value2'] = date_limit_value($items[$delta]['value2'], date_granularity($field), $field['type']);
|
||||
}
|
||||
}
|
||||
}
|
||||
$node->$field['field_name'] = $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private implementation of hook_widget().
|
||||
*
|
||||
* The widget builds out a complex date element in the following way:
|
||||
*
|
||||
* - A field is pulled out of the database which is comprised of one or
|
||||
* more collections of from/to dates.
|
||||
*
|
||||
* - The dates in this field are all converted from the UTC values stored
|
||||
* in the database back to the local time before passing their values
|
||||
* to FAPI.
|
||||
*
|
||||
* - If values are empty, the field settings rules are used to determine
|
||||
* if the default_values should be empty, now, the same, or use strtotime.
|
||||
*
|
||||
* - Each from/to combination is created using the date_combo element type
|
||||
* defined by the date module. If the timezone is date-specific, a
|
||||
* timezone selector is added to the first combo element.
|
||||
*
|
||||
* - If repeating dates are defined, a form to create a repeat rule is
|
||||
* added to the field element.
|
||||
*
|
||||
* - The date combo element creates two individual date elements, one each
|
||||
* for the from and to field, using the appropriate individual Date API
|
||||
* date elements, like selects, textfields, or popups.
|
||||
*
|
||||
* - In the individual element validation, the data supplied by the user is
|
||||
* used to update the individual date values.
|
||||
*
|
||||
* - In the combo date validation, the timezone is updated, if necessary,
|
||||
* then the user input date values are used with that timezone to create
|
||||
* date objects, which are used update combo date timezone and offset values.
|
||||
*
|
||||
* - In the field's submission processing, the new date values, which are in
|
||||
* the local timezone, are converted back to their UTC values and stored.
|
||||
*
|
||||
*/
|
||||
function _date_widget(&$form, &$form_state, &$field, $items, $delta = 0) {
|
||||
|
||||
// Be sure users that haven't run the update yet don't get
|
||||
// a badly broken value.
|
||||
if (!empty($field['repeat']) && !strstr($field['widget']['type'], '_repeat')) {
|
||||
$field['multiple'] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
require_once('./'. drupal_get_path('module', 'date_api') .'/date_api_elements.inc');
|
||||
$timezone = date_get_timezone($field['tz_handling'], isset($items[0]['timezone']) ? $items[0]['timezone'] : date_default_timezone_name());
|
||||
// TODO see if there's a way to keep the timezone element from ever being
|
||||
// nested as array('timezone' => 'timezone' => value)). After struggling
|
||||
// with this a while, I can find no way to get it displayed in the form
|
||||
// correctly and get it to use the timezone element without ending up
|
||||
// with nesting.
|
||||
if (is_array($timezone)) {
|
||||
$timezone = $timezone['timezone'];
|
||||
}
|
||||
|
||||
// Convert UTC dates to their local values in DATETIME format,
|
||||
// and adjust the default values as specified in the field settings.
|
||||
|
||||
// It would seem to make sense to do this conversion when the data
|
||||
// is loaded instead of when the form is created, but the loaded
|
||||
// field data is cached and we can't cache dates that have been converted
|
||||
// to the timezone of an individual user, so we cache the UTC values
|
||||
// instead and do our conversion to local dates in the form and
|
||||
// in the formatters.
|
||||
$process = date_process_values($field);
|
||||
foreach ($process as $processed) {
|
||||
if (!isset($items[$delta][$processed])) {
|
||||
$items[$delta][$processed] = '';
|
||||
}
|
||||
$date = date_local_date($form, $form_state, $delta, $items[$delta], $timezone, $field, $processed);
|
||||
$items[$delta][$processed] = is_object($date) ? date_format($date, DATE_FORMAT_DATETIME) : '';
|
||||
}
|
||||
|
||||
$element = array(
|
||||
'#type' => 'date_combo',
|
||||
'#weight' => $delta,
|
||||
'#default_value' => isset($items[$delta]) ? $items[$delta] : '',
|
||||
'#date_timezone' => $timezone,
|
||||
'#element_validate' => array('date_combo_validate', 'date_widget_validate'),
|
||||
);
|
||||
|
||||
if ($field['tz_handling'] == 'date') {
|
||||
$element['timezone'] = array(
|
||||
'#type' => 'date_timezone',
|
||||
'#delta' => $delta,
|
||||
'#default_value' => $timezone,
|
||||
'#weight' => $field['widget']['weight'] + .2,
|
||||
);
|
||||
}
|
||||
|
||||
// Add a date repeat form element, if needed.
|
||||
if (module_exists('date_repeat') && $field['repeat'] == 1) {
|
||||
require_once('./'. drupal_get_path('module', 'date') .'/date_repeat.inc');
|
||||
_date_repeat_widget($element, $field, $items, $delta);
|
||||
$element['rrule']['#weight'] = $field['widget']['weight'] + .4;
|
||||
}
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create local date object.
|
||||
*
|
||||
* Create a date object set to local time from the field and
|
||||
* widget settings and item values, using field settings to
|
||||
* determine what to do with empty values.
|
||||
*/
|
||||
function date_local_date($form, $form_state, $delta, $item, $timezone, $field, $part = 'value') {
|
||||
if (!empty($form['nid']['#value'])) {
|
||||
$default_value = '';
|
||||
$default_value_code = '';
|
||||
}
|
||||
elseif ($part == 'value') {
|
||||
$default_value = $field['widget']['default_value'];
|
||||
$default_value_code = $field['widget']['default_value_code'];
|
||||
}
|
||||
else {
|
||||
$default_value = $field['widget']['default_value2'];
|
||||
$default_value_code = $field['widget']['default_value_code2'];
|
||||
}
|
||||
if (empty($item) || empty($item[$part])) {
|
||||
if (empty($default_value) || $default_value == 'blank' || $delta > 0) {
|
||||
return NULL;
|
||||
}
|
||||
elseif ($part == 'value2' && $default_value == 'same') {
|
||||
if ($field['widget']['default_value'] == 'blank' || empty($item['value'])) {
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
$date = date_make_date($item['value'], $timezone, DATE_DATETIME, $field['granularity']);
|
||||
}
|
||||
}
|
||||
// Special case for 'now' when using dates with no timezone,
|
||||
// make sure 'now' isn't adjusted to UTC value of 'now'.
|
||||
elseif ($field['tz_handling'] == 'none') {
|
||||
$date = date_now();
|
||||
}
|
||||
else {
|
||||
$date = date_now($timezone);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$value = $item[$part];
|
||||
|
||||
// Special case for ISO dates to create a valid date object for formatting.
|
||||
if ($field['type'] == DATE_ISO) {
|
||||
$value = date_fuzzy_datetime($value);
|
||||
}
|
||||
else {
|
||||
$db_timezone = date_get_timezone_db($field['tz_handling']);
|
||||
$value = date_convert($value, $field['type'], DATE_DATETIME, $db_timezone);
|
||||
}
|
||||
$date = date_make_date($value, date_get_timezone_db($field['tz_handling']), DATE_DATETIME, $field['granularity']);
|
||||
if (empty($date)) {
|
||||
return NULL;
|
||||
}
|
||||
date_timezone_set($date, timezone_open($timezone));
|
||||
}
|
||||
if (is_object($date) && empty($item[$part]) && $default_value == 'strtotime' && !empty($default_value_code)) {
|
||||
date_modify($date, $default_value_code);
|
||||
}
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_elements().
|
||||
*
|
||||
* date_combo will create a 'from' and optional 'to' date, along with
|
||||
* an optional 'timezone' column for date-specific timezones. Each
|
||||
* 'from' and 'to' date will be constructed from date_select or date_text.
|
||||
*/
|
||||
function _date_elements() {
|
||||
$type = array();
|
||||
$type['date_combo'] = array(
|
||||
'#input' => TRUE,
|
||||
'#delta' => 0,
|
||||
'#columns' => array('value', 'value2', 'timezone', 'offset', 'offset2'),
|
||||
'#process' => array('date_combo_process'),
|
||||
'#element_validate' => array('date_combo_validate'),
|
||||
);
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an individual date element.
|
||||
*/
|
||||
function date_combo_process($element, $edit, &$form_state, $form) {
|
||||
if (isset($element['#access']) && empty($element['#access'])) {
|
||||
return $element;
|
||||
}
|
||||
|
||||
$field_name = $element['#field_name'];
|
||||
$field = $form['#field_info'][$field_name];
|
||||
$delta = $element['#delta'];
|
||||
|
||||
$columns = $element['#columns'];
|
||||
if (isset($columns['rrule'])) {
|
||||
unset($columns['rrule']);
|
||||
}
|
||||
$from_field = 'value';
|
||||
$to_field = 'value2';
|
||||
$tz_field = 'timezone';
|
||||
$offset_field = 'offset';
|
||||
$offset_field2 = 'offset2';
|
||||
|
||||
if ($field['todate'] != 'required' && !empty($element['#default_value'][$to_field]) && $element['#default_value'][$to_field] == $element['#default_value'][$from_field]) {
|
||||
unset($element['#default_value'][$to_field]);
|
||||
}
|
||||
|
||||
$element[$from_field] = array(
|
||||
'#field' => $field,
|
||||
'#title' => (!$field['multiple'] || $field['repeat']) ? t($field['widget']['label']) : '',
|
||||
'#weight' => $field['widget']['weight'],
|
||||
'#required' => ($field['required'] && $delta == 0) ? 1 : 0,
|
||||
'#default_value' => isset($element['#value'][$from_field]) ? $element['#value'][$from_field] : '',
|
||||
'#delta' => $delta,
|
||||
'#date_timezone' => $element['#date_timezone'],
|
||||
'#date_format' => date_limit_format(date_input_format($element, $field), $field['granularity']),
|
||||
'#date_text_parts' => (array) $field['widget']['text_parts'],
|
||||
'#date_increment' => $field['widget']['increment'],
|
||||
'#date_year_range' => $field['widget']['year_range'],
|
||||
'#date_label_position' => $field['widget']['label_position'],
|
||||
);
|
||||
|
||||
$description = !empty($field['widget']['description']) ? t($field['widget']['description']) : '';
|
||||
|
||||
// Give this element the right type, using a Date API
|
||||
// or a Date Popup element type.
|
||||
|
||||
switch ($field['widget']['type']) {
|
||||
case 'date_select':
|
||||
case 'date_select_repeat':
|
||||
// From/to selectors with lots of parts will look better if displayed
|
||||
// on two rows instead of in a single row.
|
||||
if (!empty($field['todate']) && count($field['granularity']) > 3) {
|
||||
$element[$from_field]['#attributes'] = array('class' => 'date-clear');
|
||||
}
|
||||
$element[$from_field]['#type'] = 'date_select';
|
||||
break;
|
||||
case 'date_popup':
|
||||
case 'date_popup_repeat':
|
||||
$element[$from_field]['#type'] = 'date_popup';
|
||||
break;
|
||||
default:
|
||||
$element[$from_field]['#type'] = 'date_text';
|
||||
break;
|
||||
}
|
||||
|
||||
// If this field uses the 'To', add matching element
|
||||
// for the 'To' date, and adapt titles to make it clear which
|
||||
// is the 'From' and which is the 'To'.
|
||||
|
||||
if (!empty($field['todate'])) {
|
||||
$element['#date_float'] = TRUE;
|
||||
$element[$from_field]['#title'] = t('From date');
|
||||
$element[$to_field] = $element[$from_field];
|
||||
$element[$to_field]['#title'] = t('To date');
|
||||
$element[$to_field]['#default_value'] = isset($element['#value'][$to_field]) ? $element['#value'][$to_field] : '';
|
||||
$element[$to_field]['#required'] = FALSE;
|
||||
$element[$to_field]['#weight'] += .1;
|
||||
if (($field['widget']['type'] == 'date_select') && empty($description)) {
|
||||
$description = t("Empty 'To date' values will use the 'From date' values.");
|
||||
}
|
||||
else {
|
||||
if (trim($description) == "") {
|
||||
$description = NULL;
|
||||
}
|
||||
}
|
||||
$element['#fieldset_description'] = $description;
|
||||
}
|
||||
else {
|
||||
$element[$from_field]['#description'] = $description;
|
||||
}
|
||||
|
||||
// Create label for error messages that make sense in multiple values
|
||||
// and when the title field is left blank.
|
||||
if (!empty($field['multiple']) && empty($field['repeat'])) {
|
||||
$element[$from_field]['#date_title'] = t('@field_name From date value #@delta', array('@field_name' => $field['widget']['label'], '@delta' => $delta + 1));
|
||||
if (!empty($field['todate'])) {
|
||||
$element[$to_field]['#date_title'] = t('@field_name To date value #@delta', array('@field_name' => $field['widget']['label'], '@delta' => $delta + 1));
|
||||
}
|
||||
}
|
||||
elseif (!empty($field['todate'])) {
|
||||
$element[$from_field]['#date_title'] = t('@field_name From date', array('@field_name' => $field['widget']['label']));
|
||||
$element[$to_field]['#date_title'] = t('@field_name To date', array('@field_name' => $field['widget']['label']));
|
||||
}
|
||||
else {
|
||||
$element[$from_field]['#date_title'] = $field['widget']['label'];
|
||||
}
|
||||
|
||||
// Make sure field info will be available to the validator which
|
||||
// does not get the values in $form.
|
||||
$form_state['#field_info'][$field['field_name']] = $field;
|
||||
return $element;
|
||||
}
|
||||
|
||||
function date_element_empty($element, &$form_state) {
|
||||
$item = array();
|
||||
$item['value'] = NULL;
|
||||
$item['value2'] = NULL;
|
||||
$item['timezone'] = NULL;
|
||||
$item['offset'] = NULL;
|
||||
$item['offset2'] = NULL;
|
||||
$item['rrule'] = NULL;
|
||||
form_set_value($element, $item, $form_state);
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate and update a combo element.
|
||||
* Don't try this if there were errors before reaching this point.
|
||||
*/
|
||||
function date_combo_validate($element, &$form_state) {
|
||||
$form_values = $form_state['values'];
|
||||
$field_name = $element['#field_name'];
|
||||
$delta = $element['#delta'];
|
||||
|
||||
// If the whole field is empty and that's OK, stop now.
|
||||
if (empty($element['#post'][$field_name]) && !$element['#required']) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Repeating dates have a different form structure, so get the
|
||||
// right item values.
|
||||
$item = isset($form_values[$field_name]['rrule']) ? $form_values[$field_name] : $form_values[$field_name][$delta];
|
||||
$posted = isset($form_values[$field_name]['rrule']) ? $element['#post'][$field_name] : $element['#post'][$field_name][$delta];
|
||||
|
||||
$field = $form_state['#field_info'][$element['#field_name']];
|
||||
$from_field = 'value';
|
||||
$to_field = 'value2';
|
||||
$tz_field = 'timezone';
|
||||
$offset_field = 'offset';
|
||||
$offset_field2 = 'offset2';
|
||||
|
||||
// Unfortunately, due to the fact that much of the processing is already
|
||||
// done by the time we get here, it is not possible highlight the field
|
||||
// with an error, we just try to explain which element is creating the
|
||||
// problem in the error message.
|
||||
$parent = $element['#parents'];
|
||||
$error_field = array_pop($parent);
|
||||
$errors = array();
|
||||
|
||||
// Check for empty 'From date', which could either be an empty
|
||||
// value or an array of empty values, depending on the widget.
|
||||
$empty = TRUE;
|
||||
if (!empty($item[$from_field])) {
|
||||
if (!is_array($item[$from_field])) {
|
||||
$empty = FALSE;
|
||||
}
|
||||
else {
|
||||
foreach ($item[$from_field] as $key => $value) {
|
||||
if (!empty($value)) {
|
||||
$empty = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($empty) {
|
||||
$item = date_element_empty($element, $form_state);
|
||||
if (!$element['#required']) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Don't look for further errors if errors are already flagged
|
||||
// because otherwise we'll show errors on the nested elements
|
||||
// more than once.
|
||||
elseif (!form_get_errors()) {
|
||||
|
||||
// Check todate input for blank values and substitute in fromdate
|
||||
// values where needed, then re-compute the todate with those values.
|
||||
if ($field['todate']) {
|
||||
$merged_date = array();
|
||||
$to_date_empty = TRUE;
|
||||
foreach ($posted[$to_field] as $part => $value) {
|
||||
$to_date_empty = $to_date_empty && empty($value) && !is_numeric($value);
|
||||
$merged_date[$part] = empty($value) && !is_numeric($value) ? $posted[$from_field][$part] : $value;
|
||||
if ($part == 'ampm' && $merged_date['ampm'] == 'pm' && $merged_date['hour'] < 12) {
|
||||
$merged_date['hour'] += 12;
|
||||
}
|
||||
elseif ($part == 'ampm' && $merged_date['ampm'] == 'am' && $merged_date['hour'] == 12) {
|
||||
$merged_date['hour'] -= 12;
|
||||
}
|
||||
}
|
||||
|
||||
// If all date values were empty and a date is required, throw
|
||||
// an error on the first element. We don't want to create
|
||||
// duplicate messages on every date part, so the error will
|
||||
// only go on the first.
|
||||
if ($to_date_empty && $field['todate'] == 'required') {
|
||||
$errors[] = t('Some value must be entered in the To date.');
|
||||
}
|
||||
|
||||
$element[$to_field]['#value'] = $merged_date;
|
||||
|
||||
// Call the right function to turn this altered user input into
|
||||
// a new value for the todate.
|
||||
$item[$to_field] = $merged_date;
|
||||
}
|
||||
else {
|
||||
$item[$to_field] = $item[$from_field];
|
||||
}
|
||||
|
||||
$from_date = date_input_value($field, $element[$from_field]);
|
||||
if (!empty($field['todate'])) {
|
||||
$to_date = date_input_value($field, $element[$to_field]);
|
||||
}
|
||||
else {
|
||||
$to_date = $from_date;
|
||||
}
|
||||
|
||||
// Neither the from date nor the to date should be empty at this point
|
||||
// unless they held values that couldn't be evaluated.
|
||||
if (!$field['required'] && (empty($from_date) || empty($to_date))) {
|
||||
$item = date_element_empty($element, $form_state);
|
||||
$errors[] = t('The dates are invalid.');
|
||||
}
|
||||
elseif (!empty($field['todate']) && $from_date > $to_date) {
|
||||
form_set_value($element[$to_field], $to_date, $form_state);
|
||||
$errors[] = t('The To date must be greater than the From date.');
|
||||
}
|
||||
else {
|
||||
// Convert input dates back to their UTC values and re-format to ISO
|
||||
// or UNIX instead of the DATETIME format used in element processing.
|
||||
$timezone = !empty($item[$tz_field]) ? $item[$tz_field] : $element['#date_timezone'];
|
||||
$timezone_db = date_get_timezone_db($field['tz_handling']);
|
||||
|
||||
$item[$tz_field] = $timezone;
|
||||
|
||||
$from_date = date_make_date($from_date, $timezone);
|
||||
$item[$offset_field] = date_offset_get($from_date);
|
||||
|
||||
$to_date = date_make_date($to_date, $timezone);
|
||||
$test_from = date_format($from_date, 'r');
|
||||
$test_to = date_format($to_date, 'r');
|
||||
$item[$offset_field2] = date_offset_get($to_date);
|
||||
date_timezone_set($from_date, timezone_open($timezone_db));
|
||||
date_timezone_set($to_date, timezone_open($timezone_db));
|
||||
$item[$from_field] = date_format($from_date, date_type_format($field['type']));
|
||||
$item[$to_field] = date_format($to_date, date_type_format($field['type']));
|
||||
if (isset($form_values[$field_name]['rrule'])) {
|
||||
$item['rrule'] = $form_values[$field['field_name']]['rrule'];
|
||||
}
|
||||
|
||||
// If the db timezone is not the same as the display timezone
|
||||
// and we are using a date with time granularity,
|
||||
// test a roundtrip back to the original timezone to catch
|
||||
// invalid dates, like 2AM on the day that spring daylight savings
|
||||
// time begins in the US.
|
||||
$granularity = date_format_order($element[$from_field]['#date_format']);
|
||||
if ($timezone != $timezone_db && date_has_time($granularity)) {
|
||||
date_timezone_set($from_date, timezone_open($timezone));
|
||||
date_timezone_set($to_date, timezone_open($timezone));
|
||||
|
||||
if ($test_from != date_format($from_date, 'r')) {
|
||||
$errors[] = t('The From date is invalid.');
|
||||
}
|
||||
if ($test_to != date_format($to_date, 'r')) {
|
||||
$errors[] = t('The To date is invalid.');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($errors)) {
|
||||
form_set_value($element, $item, $form_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($errors)) {
|
||||
if ($field['multiple']) {
|
||||
form_set_error($error_field, t('There are errors in @field_name value #@delta:', array('@field_name' => $field['widget']['label'], '@delta' => $delta + 1)) . theme('item_list', $errors));
|
||||
}
|
||||
else {
|
||||
form_set_error($error_field, t('There are errors in @field_name:', array('@field_name' => $field['widget']['label'])) . theme('item_list', $errors));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle widget processing.
|
||||
*/
|
||||
function date_widget_validate($element, &$form_state) {
|
||||
$field = $form_state['#field_info'][$element['#field_name']];
|
||||
if (module_exists('date_repeat') && $field['repeat'] == 1) {
|
||||
module_load_include('inc', 'date', 'date_repeat');
|
||||
return _date_repeat_widget_validate($element, $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the input format for this element.
|
||||
*/
|
||||
function date_input_format($element, $field) {
|
||||
if (!empty($field['widget']['input_format_custom'])) {
|
||||
return $field['widget']['input_format_custom'];
|
||||
}
|
||||
elseif (!empty($field['widget']['input_format']) && $field['widget']['input_format'] != 'site-wide') {
|
||||
return $field['widget']['input_format'];
|
||||
}
|
||||
return variable_get('date_format_short', 'm/d/Y - H:i');
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme from/to date combination on form.
|
||||
*/
|
||||
function theme_date_combo($element) {
|
||||
$field = content_fields($element['#field_name'], $element['#type_name']);
|
||||
if (!$field['todate']) {
|
||||
return $element['#children'];
|
||||
}
|
||||
|
||||
// Group from/to items together in fieldset.
|
||||
$fieldset = array(
|
||||
'#title' => check_plain($field['widget']['label']) .' '. ($element['#delta'] > 0 ? intval($element['#delta'] + 1) : ''),
|
||||
'#value' => $element['#children'],
|
||||
'#collapsible' => FALSE,
|
||||
'#collapsed' => FALSE,
|
||||
'#description' => $element['#fieldset_description'],
|
||||
'#attributes' => array(),
|
||||
);
|
||||
return theme('fieldset', $fieldset);
|
||||
}
|
187
modules/date/date/date_handler_field_multiple.inc
Normal file
187
modules/date/date/date_handler_field_multiple.inc
Normal file
|
@ -0,0 +1,187 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* An extended subclass for field handling that adds multiple field grouping.
|
||||
*
|
||||
* Fields that want multiple value grouping options in addition to basic
|
||||
* field and formatter handling can extend this class.
|
||||
*/
|
||||
class date_handler_field_multiple extends content_handler_field_multiple {
|
||||
|
||||
function option_definition() {
|
||||
$options = parent::option_definition();
|
||||
$options['repeat'] = array(
|
||||
'contains' => array(
|
||||
'show_repeat_rule' => array('default' => ''),
|
||||
)
|
||||
);
|
||||
$options['multiple'] = array(
|
||||
'contains' => array(
|
||||
'group' => array('default' => TRUE),
|
||||
'multiple_number' => array('default' => ''),
|
||||
'multiple_from' => array('default' => ''),
|
||||
'multiple_to' => array('default' => ''),
|
||||
)
|
||||
);
|
||||
$options['fromto'] = array(
|
||||
'contains' => array(
|
||||
'fromto' => array('default' => 'both'),
|
||||
)
|
||||
);
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide 'group multiple values' option,
|
||||
* adapted to the needs of the Date module.
|
||||
*/
|
||||
function options_form(&$form, &$form_state) {
|
||||
parent::options_form($form, $form_state);
|
||||
unset($form['multiple']);
|
||||
|
||||
$field = $this->content_field;
|
||||
$options = $this->options;
|
||||
|
||||
$form += date_formatter_settings($form_state, $field, $options, TRUE);
|
||||
$form['multiple']['#weight'] = 1;
|
||||
$form['multiple']['group'] = array(
|
||||
'#title' => t('Group multiple values'),
|
||||
'#type' => 'checkbox',
|
||||
'#default_value' => $options['multiple']['group'],
|
||||
'#description' => t('If unchecked, each item in the field will create a new row, which may appear to cause duplicates. This setting is not compatible with click-sorting in table displays.'),
|
||||
);
|
||||
}
|
||||
|
||||
# function pre_render(&$values) {
|
||||
function pre_render($values) {
|
||||
|
||||
// If there are no values to render (displaying a summary, or query returned no results),
|
||||
// or if this is not a grouped field, do nothing specific.
|
||||
if (isset($this->view->build_info['summary']) || empty($values) || !$this->defer_query) {
|
||||
return parent::pre_render($values);
|
||||
}
|
||||
$field = $this->content_field;
|
||||
$db_info = content_database_info($field);
|
||||
$options = $this->options;
|
||||
$this->view->date_info->date_handler_fields = date_handler_fields($this->view);
|
||||
|
||||
// Build the list of vids to retrieve.
|
||||
// TODO: try fetching from cache_content first ??
|
||||
$vids = array();
|
||||
$this->field_values = array();
|
||||
foreach ($values as $result) {
|
||||
if (isset($result->{$this->field_alias})) {
|
||||
$vids[] = $result->{$this->field_alias};
|
||||
}
|
||||
}
|
||||
|
||||
// List columns to retrieve.
|
||||
$alias = content_views_tablename($field);
|
||||
// Prefix aliases with '_' to avoid clashing with field columns names.
|
||||
$query_columns = array(
|
||||
'node.vid AS _vid',
|
||||
"$alias.delta as _delta",
|
||||
// nid is needed to generate the links for 'link to node' option.
|
||||
'node.nid AS _nid',
|
||||
);
|
||||
// The actual field columns.
|
||||
foreach ($db_info['columns'] as $column => $attributes) {
|
||||
$query_columns[] = "$alias.$attributes[column] AS $column";
|
||||
$query_fields[] = "$alias.$attributes[column]";
|
||||
}
|
||||
// Retrieve all values, we limit them in date_prepare_node(),
|
||||
// a function that is used both by the handler and by the
|
||||
// node theme to take advantage of formatter settings.
|
||||
$where = array('1');
|
||||
$query = 'SELECT '. implode(', ', $query_columns) .
|
||||
' FROM {'. $db_info['table'] ."} $alias".
|
||||
" LEFT JOIN {node} node ON node.vid = $alias.vid".
|
||||
" WHERE node.vid IN (". implode(',', $vids) .') AND '. implode(' OR ', $where) .
|
||||
" ORDER BY node.nid ASC, $alias.delta ASC";
|
||||
$result = db_query($query);
|
||||
|
||||
while ($item = db_fetch_array($result)) {
|
||||
// Clean up the $item from vid and delta. We keep nid for now.
|
||||
$vid = $item['_vid'];
|
||||
unset($item['_vid']);
|
||||
$delta = !empty($item['_delta']) ? $item['_delta'] : 0;
|
||||
$item['#delta'] = $item['_delta'];
|
||||
unset($item['_delta']);
|
||||
$this->field_values[$vid][$delta] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
function render($values) {
|
||||
|
||||
// By this time $values is a pseudo node that will be passed
|
||||
// to the theme. Add view information to it.
|
||||
$values->date_info = !empty($this->view->date_info) ? $this->view->date_info : new stdClass();
|
||||
$values->date_info->date_handler_fields = date_handler_fields($this->view);
|
||||
|
||||
// Add the formatter settings to the pseudo node.
|
||||
$values->date_info->formatter_settings = $this->options;
|
||||
$values->date_info->aliases = $this->aliases;
|
||||
|
||||
// If this is not a grouped field, use content_handler_field::render().
|
||||
if (!$this->defer_query) {
|
||||
return parent::render($values);
|
||||
}
|
||||
|
||||
$field = $this->content_field;
|
||||
$field_name = $field['field_name'];
|
||||
$options = $this->options;
|
||||
|
||||
$vid = $values->{$this->field_alias};
|
||||
if (isset($this->field_values[$vid])) {
|
||||
// Build a pseudo-node from the retrieved values.
|
||||
$node = drupal_clone($values);
|
||||
// content_format and formatters will need a 'type'.
|
||||
$node->type = $values->{$this->aliases['type']};
|
||||
$node->nid = $values->{$this->aliases['nid']};
|
||||
$node->vid = $values->{$this->aliases['vid']};
|
||||
$items = $this->field_values[$vid];
|
||||
$node->$field_name = $items;
|
||||
|
||||
// Some formatters need to behave differently depending on the build_mode
|
||||
// (for instance: preview), so we provide one.
|
||||
$node->build_mode = NODE_BUILD_NORMAL;
|
||||
|
||||
// Render items.
|
||||
$formatter_name = $options['format'];
|
||||
if ($items && ($formatter = _content_get_formatter($formatter_name, $field['type']))) {
|
||||
$rendered = array();
|
||||
if (content_handle('formatter', 'multiple values', $formatter) == CONTENT_HANDLE_CORE) {
|
||||
// Single-value formatter.
|
||||
foreach ($items as $item) {
|
||||
$output = content_format($field, $item, $formatter_name, $node);
|
||||
if (!empty($output)) {
|
||||
$rendered[] = $this->render_link($output, (object) array('nid' => $this->aliases['nid']));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Multiple values formatter.
|
||||
$output = content_format($field, $items, $formatter_name, $values);
|
||||
if (!empty($output)) {
|
||||
$rendered[] = $this->render_link($output, (object) array('nid' => $this->aliases['nid']));
|
||||
}
|
||||
}
|
||||
|
||||
if (count($rendered) > 1) {
|
||||
// TODO: could we use generic field display ?
|
||||
return theme('content_view_multiple_field', $rendered, $field, $values);
|
||||
}
|
||||
elseif ($rendered) {
|
||||
return $rendered[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
209
modules/date/date/date_repeat.inc
Normal file
209
modules/date/date/date_repeat.inc
Normal file
|
@ -0,0 +1,209 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Implementation of Date Repeat API calculations for the CCK Date field.
|
||||
*
|
||||
* Consolidated here so the code isn't parsed if repeats aren't being used
|
||||
* or processed, and to make it easier to maintain.
|
||||
*
|
||||
* The current implementation adds a repeat form to the date field so the user
|
||||
* can select the repeat rules. That selection is built into an RRULE
|
||||
* which is stored in the zero position of the field values. During widget
|
||||
* validation, the rule is parsed to see what dates it will create,
|
||||
* and multiple values are added to the field, one for each repeat date.
|
||||
* That update only happens when the rule, the from date, or the to date
|
||||
* change, no need to waste processing cycles for other changes to the node
|
||||
* values.
|
||||
*
|
||||
* Lots of possible TODOs, the biggest one is figuring out the best
|
||||
* way to handle dates with no UNTIL date since we can't add an infinite
|
||||
* number of values to the field. For now, we require the UNTIL date.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Widget processing for date repeat form element.
|
||||
*
|
||||
* Create the RRULE as a top-level element rather than a delta level
|
||||
* element, we'll compute the repeat sequence in the widget validation
|
||||
* to create the element delta values.
|
||||
*/
|
||||
function _date_repeat_widget(&$element, $field, $items, $delta) {
|
||||
$element['rrule'] = array(
|
||||
'#type' => 'date_repeat_rrule',
|
||||
'#default_value' => isset($items[0]['rrule']) ? $items[0]['rrule'] : '',
|
||||
'#date_timezone' => $element['#date_timezone'],
|
||||
'#date_format' => date_limit_format(date_input_format($element, $field), $field['granularity']),
|
||||
'#date_text_parts' => (array) $field['widget']['text_parts'],
|
||||
'#date_increment' => $field['widget']['increment'],
|
||||
'#date_year_range' => $field['widget']['year_range'],
|
||||
'#date_label_position' => $field['widget']['label_position'],
|
||||
'#prev_value' => isset($items[0]['value']) ? $items[0]['value'] : '',
|
||||
'#prev_value2' => isset($items[0]['value2']) ? $items[0]['value2'] : '',
|
||||
'#prev_rrule' => isset($items[0]['rrule']) ? $items[0]['rrule'] : '',
|
||||
'#date_repeat_widget' => str_replace('_repeat', '', $field['widget']['type']),
|
||||
'#date_repeat_collapsed' => $field['repeat_collapsed'],
|
||||
);
|
||||
|
||||
return $element;
|
||||
}
|
||||
/**
|
||||
* Validation for date repeat form element.
|
||||
*
|
||||
* Create multiple values from the RRULE results.
|
||||
* Lots more work needed here.
|
||||
*/
|
||||
function _date_repeat_widget_validate($element, &$form_state) {
|
||||
require_once('./'. drupal_get_path('module', 'date_repeat') .'/date_repeat_form.inc');
|
||||
$form_values = $form_state['values'];
|
||||
$field_name = $element['#field_name'];
|
||||
$fields = content_fields();
|
||||
$field = $fields[$field_name];
|
||||
$item = $form_values[$field_name];
|
||||
$values = date_repeat_merge($element['#post'][$field_name]['rrule'], $element['rrule']);
|
||||
|
||||
// If no start date was set, clean up the form and return.
|
||||
// If no repeats are set, clean up the form and return.
|
||||
if (empty($form_values[$field_name]['value']) || $values['FREQ'] == 'NONE') {
|
||||
$form_values[$field_name]['rrule'] = NULL;
|
||||
form_set_value($element, array($form_values[$field_name]), $form_state);
|
||||
return;
|
||||
}
|
||||
|
||||
// Require the UNTIL date for now.
|
||||
// The RRULE has already been created by this point, so go back
|
||||
// to the posted values to see if this was filled out.
|
||||
$error_field = implode('][', $element['#parents']) .'][rrule][UNTIL][datetime][date';
|
||||
if (empty($values['UNTIL']['datetime'])) {
|
||||
form_set_error($error_field, t('The UNTIL value is required for repeating dates.'));
|
||||
}
|
||||
if (form_get_errors()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the rule, the start date, or the end date have changed, re-calculate
|
||||
// the repeating dates, wipe out the previous values, and populate the
|
||||
// field with the new values.
|
||||
|
||||
// TODO
|
||||
// Is it right to not do anything unless there are changes? Will that
|
||||
// confuse anyone? Commenting that out for now...
|
||||
$rrule = $form_values[$field_name]['rrule'];
|
||||
if (!empty($rrule)
|
||||
//&& ($rrule != $element['rrule']['#prev_rrule']
|
||||
//|| $form_values[$field_name][0]['value'] != $element['rrule']['#prev_value']
|
||||
//|| $form_values[$field_name][0]['value2'] != $element['rrule']['#prev_value2'])
|
||||
) {
|
||||
|
||||
$item = $form_values[$field_name];
|
||||
|
||||
// Avoid undefined index problems on dates that don't have all parts.
|
||||
$possible_items = array('value', 'value2', 'timezone', 'offset', 'offset2');
|
||||
foreach ($possible_items as $key) {
|
||||
if (empty($item[$key])) {
|
||||
$item[$key] = '';
|
||||
}
|
||||
}
|
||||
$value = date_repeat_build_dates($rrule, $values, $field, $item);
|
||||
form_set_value($element, $value, $form_state);
|
||||
}
|
||||
else {
|
||||
// If no changes are needed, move the RRULE back to the zero value
|
||||
// item of the field.
|
||||
form_set_value(array('#parents' => array($field_name, 0, 'rrule')), $rrule, $form_state);
|
||||
form_set_value($element['rrule'], NULL, $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to build repeating dates from a $node_field.
|
||||
*
|
||||
* Pass in either the RRULE or the $form_values array for the RRULE,
|
||||
* whichever is missing will be created when needed.
|
||||
*/
|
||||
function date_repeat_build_dates($rrule = NULL, $rrule_values = NULL, $field, $item) {
|
||||
module_load_include('inc', 'date_api', 'date_api_ical');
|
||||
$field_name = $field['field_name'];
|
||||
|
||||
if (empty($rrule)) {
|
||||
$rrule = date_api_ical_build_rrule($rrule_values);
|
||||
}
|
||||
elseif (empty($rrule_values)) {
|
||||
$rrule_values = date_ical_parse_rrule(NULL, $rrule);
|
||||
}
|
||||
|
||||
// By the time we get here, the start and end dates have been
|
||||
// adjusted back to UTC, but we want localtime dates to do
|
||||
// things like '+1 Tuesday', so adjust back to localtime.
|
||||
$timezone = date_get_timezone($field['tz_handling'], $item['timezone']);
|
||||
$timezone_db = date_get_timezone_db($field['tz_handling']);
|
||||
$start = date_make_date($item['value'], $timezone_db, $field['type'], $field['granularity']);
|
||||
if ($timezone != $timezone_db) {
|
||||
date_timezone_set($start, timezone_open($timezone));
|
||||
}
|
||||
if (!empty($item['value2']) && $item['value2'] != $item['value']) {
|
||||
$end = date_make_date($item['value2'], date_get_timezone_db($field['tz_handling']), $field['type'], $field['granularity']);
|
||||
date_timezone_set($end, timezone_open($timezone));
|
||||
}
|
||||
else {
|
||||
$end = $start;
|
||||
}
|
||||
$duration = date_difference($start, $end);
|
||||
$start_datetime = date_format($start, DATE_FORMAT_DATETIME);
|
||||
if (!empty($rrule_values['UNTIL']['datetime'])) {
|
||||
if (strlen($rrule_values['UNTIL']['datetime']) < 11) {
|
||||
$rrule_values['UNTIL']['datetime'] .= ' 23:59:59';
|
||||
}
|
||||
$end = date_ical_date($rrule_values['UNTIL'], $timezone);
|
||||
$end_datetime = date_format($end, DATE_FORMAT_DATETIME);
|
||||
}
|
||||
elseif (!empty($rrule_values['COUNT'])) {
|
||||
$end_datetime = NULL;
|
||||
}
|
||||
else {
|
||||
// No UNTIL and no COUNT?
|
||||
return array();
|
||||
}
|
||||
|
||||
// Split the RRULE into RRULE, EXDATE, and RDATE parts.
|
||||
$parts = date_repeat_split_rrule($rrule);
|
||||
$parsed_exceptions = (array) $parts[1];
|
||||
$exceptions = array();
|
||||
foreach ($parsed_exceptions as $exception) {
|
||||
if (strlen($exception['datetime']) < 11) {
|
||||
$exception['datetime'] .= ' 00:00:00';
|
||||
}
|
||||
$date = date_ical_date($exception, $timezone);
|
||||
$exceptions[] = date_format($date, 'Y-m-d');
|
||||
}
|
||||
|
||||
$parsed_rdates = (array) $parts[2];
|
||||
$additions = array();
|
||||
foreach ($parsed_rdates as $rdate) {
|
||||
if (strlen($rdate['datetime']) < 11) {
|
||||
$rdate['datetime'] .= ' 00:00:00';
|
||||
}
|
||||
$date = date_ical_date($rdate, $timezone);
|
||||
$additions[] = date_format($date, 'Y-m-d');
|
||||
}
|
||||
|
||||
$dates = date_repeat_calc($rrule, $start_datetime, $end_datetime, $exceptions, $timezone, $additions);
|
||||
$value = array();
|
||||
foreach ($dates as $delta => $date) {
|
||||
// date_repeat_calc always returns DATE_DATETIME dates, which is
|
||||
// not necessarily $field['type'] dates.
|
||||
// Convert returned dates back to db timezone before storing.
|
||||
$date_start = date_make_date($date, $timezone, DATE_DATETIME, $field['granularity']);
|
||||
date_timezone_set($date_start, timezone_open($timezone_db));
|
||||
$date_end = drupal_clone($date_start);
|
||||
date_modify($date_end, '+' . $duration . ' seconds');
|
||||
$value[$delta] = array(
|
||||
'value' => date_format($date_start, date_type_format($field['type'])),
|
||||
'value2' => date_format($date_end, date_type_format($field['type'])),
|
||||
'offset' => date_offset_get($date_start),
|
||||
'offset2' => date_offset_get($date_end),
|
||||
'timezone' => $timezone,
|
||||
'rrule' => $rrule,
|
||||
);
|
||||
}
|
||||
return $value;
|
||||
}
|
97
modules/date/date/date_token.inc
Normal file
97
modules/date/date/date_token.inc
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Token module integration.
|
||||
*/
|
||||
|
||||
function date_token_list($type = 'all') {
|
||||
if ($type == 'field' || $type == 'all') {
|
||||
$tokens = array();
|
||||
|
||||
$tokens['date']['value'] = t("The raw date value.");
|
||||
$tokens['date']['view'] = t("The formatted date.");
|
||||
$tokens['date']['timestamp'] = t("The raw date timestamp.");
|
||||
$tokens['date']['yyyy'] = t("Date year (four digit)");
|
||||
$tokens['date']['yy'] = t("Date year (two digit)");
|
||||
$tokens['date']['month'] = t("Date month (full word)");
|
||||
$tokens['date']['mon'] = t("Date month (abbreviated)");
|
||||
$tokens['date']['mm'] = t("Date month (two digit, zero padded)");
|
||||
$tokens['date']['m'] = t("Date month (one or two digit)");
|
||||
$tokens['date']['ww'] = t("Date week (two digit)");
|
||||
$tokens['date']['date'] = t("Date date (YYYY-MM-DD)");
|
||||
$tokens['date']['datetime'] = t("Date datetime (YYYY-MM-DDTHH:MM:SS)");
|
||||
$tokens['date']['day'] = t("Date day (full word)");
|
||||
$tokens['date']['ddd'] = t("Date day (abbreviation)");
|
||||
$tokens['date']['dd'] = t("Date day (two digit, zero-padded)");
|
||||
$tokens['date']['d'] = t("Date day (one or two digit)");
|
||||
$tokens['date']['dS'] = t("Date day (one or two digit) with ordinal suffix (st, nd, rd or th)");
|
||||
$tokens['date']['time'] = t("Time H:i");
|
||||
|
||||
$tokens['date']['to-????'] = t("If the field has a to-date defined, the same tokens exist in the form: [to-????], where ???? is the normal token.");
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
}
|
||||
|
||||
function date_token_values($type, $object = NULL) {
|
||||
if ($type == 'field') {
|
||||
$item = $object[0];
|
||||
$item['value'] = trim($item['value']);
|
||||
$item_type = isset($item['date_type']) ? $item['date_type'] : (is_numeric($item['value']) ? DATE_UNIX : DATE_ISO);
|
||||
$timezone = !empty($item['timezone']) ? $item['timezone'] : date_default_timezone_name();
|
||||
$timezone_db = !empty($item['timezone_db']) ? $item['timezone_db'] : 'UTC';
|
||||
$date = date_make_date($item['value'], $timezone_db, $item_type);
|
||||
if (!empty($date) && $timezone_db != $timezone) {
|
||||
date_timezone_set($date, timezone_open($timezone));
|
||||
}
|
||||
|
||||
$tokens['value'] = $item['value'];
|
||||
$tokens['view'] = $item['view'];
|
||||
$tokens['timestamp'] = !empty($date) ? date_format_date($date, 'custom', 'U') : '';
|
||||
$tokens['yyyy'] = !empty($date) ? date_format_date($date, 'custom', 'Y') : '';
|
||||
$tokens['yy'] = !empty($date) ? date_format_date($date, 'custom', 'y') : '';
|
||||
$tokens['month'] = !empty($date) ? date_format_date($date, 'custom', 'F') : '';
|
||||
$tokens['mon'] = !empty($date) ? date_format_date($date, 'custom', 'M') : '';
|
||||
$tokens['mm'] = !empty($date) ? date_format_date($date, 'custom', 'm') : '';
|
||||
$tokens['m'] = !empty($date) ? date_format_date($date, 'custom', 'n') : '';
|
||||
$tokens['ww'] = !empty($date) ? date_format_date($date, 'custom', 'W') : '';
|
||||
$tokens['date'] = !empty($date) ? date_format_date($date, 'custom', DATE_FORMAT_DATE) : '';
|
||||
$tokens['datetime'] = !empty($date) ? date_format_date($date, 'custom', DATE_FORMAT_ISO) : '';
|
||||
$tokens['day'] = !empty($date) ? date_format_date($date, 'custom', 'l') : '';
|
||||
$tokens['ddd'] = !empty($date) ? date_format_date($date, 'custom', 'D') : '';
|
||||
$tokens['dd'] = !empty($date) ? date_format_date($date, 'custom', 'd') : '';
|
||||
$tokens['d'] = !empty($date) ? date_format_date($date, 'custom', 'j') : '';
|
||||
$tokens['dS'] = !empty($date) ? date_format_date($date, 'custom', 'jS') : '';
|
||||
$tokens['time'] = !empty($date) ? date_format_date($date, 'custom', 'H:i') : '';
|
||||
|
||||
if (!empty($item['value2'])) {
|
||||
|
||||
$item['value2'] = trim($item['value2']);
|
||||
$date = date_make_date($item['value2'], $timezone_db, $item_type);
|
||||
if ($timezone_db != $timezone) {
|
||||
date_timezone_set($date, timezone_open($timezone));
|
||||
}
|
||||
|
||||
$tokens['to-value'] = $item['value2'];
|
||||
$tokens['to-view'] = $item['view'];
|
||||
$tokens['to-timestamp'] = !empty($date) ? date_format_date($date, 'custom', 'U') : '';
|
||||
$tokens['to-yyyy'] = !empty($date) ? date_format_date($date, 'custom', 'Y') : '';
|
||||
$tokens['to-yy'] = !empty($date) ? date_format_date($date, 'custom', 'y') : '';
|
||||
$tokens['to-month'] = !empty($date) ? date_format_date($date, 'custom', 'F') : '';
|
||||
$tokens['to-mon'] = !empty($date) ? date_format_date($date, 'custom', 'M') : '';
|
||||
$tokens['to-mm'] = !empty($date) ? date_format_date($date, 'custom', 'm') : '';
|
||||
$tokens['to-m'] = !empty($date) ? date_format_date($date, 'custom', 'n') : '';
|
||||
$tokens['to-ww'] = !empty($date) ? date_format_date($date, 'custom', 'W') : '';
|
||||
$tokens['to-date'] = !empty($date) ? date_format_date($date, 'custom', DATE_FORMAT_DATE) : '';
|
||||
$tokens['to-datetime'] = !empty($date) ? date_format_date($date, 'custom', DATE_FORMAT_ISO) : '';
|
||||
$tokens['to-day'] = !empty($date) ? date_format_date($date, 'custom', 'l') : '';
|
||||
$tokens['to-ddd'] = !empty($date) ? date_format_date($date, 'custom', 'D') : '';
|
||||
$tokens['to-dd'] = !empty($date) ? date_format_date($date, 'custom', 'd') : '';
|
||||
$tokens['to-d'] = !empty($date) ? date_format_date($date, 'custom', 'j') : '';
|
||||
$tokens['to-dS'] = !empty($date) ? date_format_date($date, 'custom', 'jS') : '';
|
||||
$tokens['to-time'] = !empty($date) ? date_format_date($date, 'custom', 'H:i') : '';
|
||||
|
||||
}
|
||||
return $tokens;
|
||||
}
|
||||
}
|
Reference in a new issue