date_tools.change_type.inc 6.5 KB

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