1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* A form to change the type of date used in date fields.
|
6
|
*/
|
7
|
|
8
|
/**
|
9
|
* Form constructor for the date type change form.
|
10
|
*
|
11
|
* @see date_tools_change_type_form_validate()
|
12
|
* @see date_tools_change_type_form_submit()
|
13
|
*/
|
14
|
function date_tools_change_type_form() {
|
15
|
$form = array();
|
16
|
// This is broken, still needs to be adjusted for the D6->D7 changes.
|
17
|
drupal_set_message(t('This operation does not yet work for the Drupal 7 version.'), 'error');
|
18
|
return $form;
|
19
|
$fields = content_fields();
|
20
|
$date_options = array();
|
21
|
$type_options = array();
|
22
|
|
23
|
$labels = array();
|
24
|
foreach (date_field_info() as $type => $info) {
|
25
|
$type_options[$type] = $info['label'] . ': ' . $info['description'];
|
26
|
$labels[$type] = $info['label'];
|
27
|
}
|
28
|
// Get the available date fields.
|
29
|
foreach ($fields as $field_name => $field) {
|
30
|
if ($field['type'] == 'date' || $field['type'] == 'datestamp' || $field['type'] == 'datetime') {
|
31
|
$date_options[$labels[$field['type']]][$field_name] = t('Field @label (@field_name)', array(
|
32
|
'@label' => $field['widget']['label'],
|
33
|
'@field_name' => $field_name,
|
34
|
'@type' => $labels[$field['type']]
|
35
|
));
|
36
|
}
|
37
|
}
|
38
|
if (count($date_options) < 1) {
|
39
|
drupal_set_message(t('There are no date fields in this database.'));
|
40
|
return $form;
|
41
|
}
|
42
|
$form['date_field'] = array(
|
43
|
'#type' => 'select',
|
44
|
'#options' => $date_options,
|
45
|
'#title' => t('Date field'),
|
46
|
'#default_value' => '',
|
47
|
'#description' => t('The date field which whose type should be changed.'),
|
48
|
);
|
49
|
$form['type'] = array(
|
50
|
'#type' => 'radios',
|
51
|
'#options' => $type_options,
|
52
|
'#default_value' => '',
|
53
|
'#required' => TRUE,
|
54
|
'#description' => t('The type of date to change the field to.'),
|
55
|
'#prefix' => '<strong>' . t('New type:') . '</strong>',
|
56
|
);
|
57
|
$form['submit'] = array('#type' => 'submit', '#value' => t('Change'));
|
58
|
return $form;
|
59
|
}
|
60
|
|
61
|
/**
|
62
|
* Form validation handler for date_tools_change_type_form().
|
63
|
*
|
64
|
* @see date_tools_change_type_form_submit()
|
65
|
*/
|
66
|
function date_tools_change_type_form_validate($form, &$form_state) {
|
67
|
$field_name = $form_state['values']['date_field'];
|
68
|
$new_type = $form_state['values']['type'];
|
69
|
$field = content_fields($field_name);
|
70
|
$old_type = $field['type'];
|
71
|
if ($new_type == $old_type) {
|
72
|
form_set_error('type', t('The current type is the same as the chosen type. There is nothing to change.'));
|
73
|
}
|
74
|
}
|
75
|
|
76
|
/**
|
77
|
* Form submission handler for date_tools_change_type_form().
|
78
|
*
|
79
|
* @see date_tools_change_type_form_validate()
|
80
|
*/
|
81
|
function date_tools_change_type_form_submit($form, &$form_state) {
|
82
|
$field_name = $form_state['values']['date_field'];
|
83
|
$new_type = $form_state['values']['type'];
|
84
|
$field = content_fields($field_name);
|
85
|
$old_type = $field['type'];
|
86
|
if ($new_type == $old_type) {
|
87
|
return;
|
88
|
}
|
89
|
$db_info = content_database_info($field);
|
90
|
$table = $db_info['table'];
|
91
|
$columns = $db_info['columns'];
|
92
|
$labels = array();
|
93
|
foreach (date_field_info() as $type => $info) {
|
94
|
$labels[$type] = $info['label'];
|
95
|
}
|
96
|
|
97
|
// Is there any data in this field? If not, we can
|
98
|
// skip some steps.
|
99
|
$has_data = db_query("SELECT COUNT(*) FROM {" . $table . "}")->fetchField();
|
100
|
|
101
|
// Create a backup copy of the original values.
|
102
|
// The values are going to get corrupted when we
|
103
|
// change the column type.
|
104
|
if ($has_data) {
|
105
|
$temp_table = $table . '_temp';
|
106
|
db_query("CREATE TABLE {" . $temp_table . "} SELECT * FROM {" . $table . "}");
|
107
|
}
|
108
|
|
109
|
// Change the field definition to the new type.
|
110
|
$field['type'] = $new_type;
|
111
|
require_once './' . drupal_get_path('module', 'content') . '/includes/content.crud.inc';
|
112
|
content_field_instance_update($field, FALSE);
|
113
|
content_clear_type_cache();
|
114
|
|
115
|
// If there's no data to update, we're finished.
|
116
|
if (!$has_data) {
|
117
|
drupal_set_message(t('The field @field_name has been changed from @old_type to @new_type.', array(
|
118
|
'@field_name' => $field['widget']['label'], '@old_type' => $labels[$old_type], '@new_type' => $labels[$new_type])));
|
119
|
return;
|
120
|
}
|
121
|
|
122
|
// Replace old values with modified values, massaging the original values as
|
123
|
// necessary for the new type.
|
124
|
require_once './' . drupal_get_path('module', 'date_api') . '/date_api_sql.inc';
|
125
|
$date_handler = new date_sql_handler();
|
126
|
$date_handler->granularity = $field['granularity'];
|
127
|
$date_handler->date_type = $old_type;
|
128
|
|
129
|
$new_columns = array();
|
130
|
$old_columns = array('nid', 'vid');
|
131
|
$new_columns[] = $temp_table . '.nid AS nid';
|
132
|
$new_columns[] = $temp_table . '.vid AS vid';
|
133
|
if ($field->multiple) {
|
134
|
$new_columns[] = $temp_table . '.delta AS delta';
|
135
|
$old_columns[] = 'delta';
|
136
|
}
|
137
|
foreach ($columns as $column => $info) {
|
138
|
if ($column != 'value' && $column != 'value2') {
|
139
|
continue;
|
140
|
}
|
141
|
$old_columns[] = $info['column'];
|
142
|
$db_field = $date_handler->sql_field($temp_table . '.' . $info['column'], 0);
|
143
|
switch ($old_type) {
|
144
|
case 'date':
|
145
|
switch ($new_type) {
|
146
|
case 'datestamp':
|
147
|
$new_columns[] = $date_handler->sql_format('U', $db_field) . ' AS ' . $info['column'];
|
148
|
break;
|
149
|
|
150
|
case 'datetime':
|
151
|
$new_columns[] = $date_handler->sql_format('Y-m-d H:i:s', $db_field) . ' AS ' . $info['column'];
|
152
|
break;
|
153
|
}
|
154
|
break;
|
155
|
|
156
|
case 'datestamp':
|
157
|
switch ($new_type) {
|
158
|
case 'date':
|
159
|
$new_columns[] = $date_handler->sql_format('Y-m-d/TH:i:s', $db_field) . ' AS ' . $info['column'];
|
160
|
break;
|
161
|
|
162
|
case 'datetime':
|
163
|
$new_columns[] = $date_handler->sql_format('Y-m-d H:i:s', $db_field) . ' AS ' . $info['column'];
|
164
|
break;
|
165
|
}
|
166
|
break;
|
167
|
|
168
|
case 'datetime':
|
169
|
switch ($new_type) {
|
170
|
case 'date':
|
171
|
$new_columns[] = $date_handler->sql_format('Y-m-d/TH:i:s', $db_field) . ' AS ' . $info['column'];
|
172
|
break;
|
173
|
|
174
|
case 'datestamp':
|
175
|
$new_columns[] = $date_handler->sql_format('U', $db_field) . ' AS ' . $info['column'];
|
176
|
break;
|
177
|
}
|
178
|
break;
|
179
|
}
|
180
|
}
|
181
|
|
182
|
// Make sure database timezone is set to UTC.
|
183
|
$date_handler->set_db_timezone();
|
184
|
|
185
|
// Make the replacement.
|
186
|
$sql = 'REPLACE INTO {' . $table . '} (' . implode(', ', $old_columns) . ') ' . ' SELECT ' . implode(', ', $new_columns) . ' FROM {' . $temp_table . '}';
|
187
|
db_query($sql);
|
188
|
db_query("DROP TABLE {" . $temp_table . "}");
|
189
|
|
190
|
drupal_set_message(t('The field @field_name has been changed from @old_type to @new_type.', array(
|
191
|
'@field_name' => $field['widget']['label'],
|
192
|
'@old_type' => $labels[$old_type],
|
193
|
'@new_type' => $labels[$new_type]
|
194
|
)));
|
195
|
}
|