#342336 by drewish: follow up to fix a bug.
[project/filefield.git] / filefield.install
1 <?php
2 // $Id$
3 /**
4 * @file
5 * FileField: Defines a CCK file field type.
6 *
7 * Uses content.module to store the fid and field specific metadata,
8 * and Drupal's {files} table to store the actual file data.
9 */
10
11 include_once('field_file.inc');
12
13 /**
14 * Implementation of hook_install().
15 */
16 function filefield_install() {
17 drupal_load('module', 'content');
18 content_notify('install', 'filefield');
19 }
20
21 /**
22 * Implementation of hook_uninstall().
23 */
24 function filefield_uninstall() {
25 drupal_load('module', 'content');
26 content_notify('uninstall', 'filefield');
27 }
28
29 /**
30 * Implementation of hook_enable().
31 */
32 function filefield_enable() {
33 drupal_load('module', 'content');
34 content_notify('enable', 'filefield');
35 }
36
37 /**
38 * Implementation of hook_disable().
39 */
40 function filefield_disable() {
41 drupal_load('module', 'content');
42 content_notify('disable', 'filefield');
43 }
44
45 // Update procedures.
46
47 function filefield_update_1() {
48 $ret = array();
49
50 include_once(drupal_get_path('module', 'content') .'/content.module');
51 include_once(drupal_get_path('module', 'content') .'/includes/content.admin.inc');
52
53 $fields = content_fields();
54
55 foreach ($fields as $field) {
56 switch ($field['type']) {
57 case 'file':
58 $columns = array(
59 'list' => array('type' => 'int', 'not null' => TRUE, 'default' => '0'),
60 );
61 content_alter_db_field(array(), array(), $field, $columns);
62 break;
63 }
64 }
65 db_query('DELETE FROM {cache}');
66 return $ret;
67 }
68
69 function filefield_update_2() {
70 cache_clear_all('*', 'cache_menu', TRUE);
71 return array();
72 }
73
74 /**
75 * Update to filefield 5.x-2.3: Move the 'show_list' widget setting
76 * to the (inverse) 'force_list' field setting.
77 */
78 function filefield_update_3() {
79 $ret = array();
80
81 include_once(drupal_get_path('module', 'content') .'/content.module');
82 include_once(drupal_get_path('module', 'content') .'/includes/content.admin.inc');
83
84 $fields = content_fields();
85 foreach ($fields as $field) {
86 switch ($field['type']) {
87 case 'file':
88 $result = db_query("SELECT * FROM {node_field_instance} WHERE field_name = '%s'", $field['field_name']);
89
90 while ($instance = db_fetch_object($result)) {
91 $widget_settings = unserialize($instance->widget_settings);
92
93 if (isset($widget_settings['show_list'])) {
94 $show_list = $widget_settings['show_list'];
95 unset($widget_settings['show_list']);
96
97 // write the widget settings without 'show_list' to the instance
98 $ret[] = update_sql(
99 "UPDATE {node_field_instance}
100 SET widget_settings = '". serialize($widget_settings) ."'
101 WHERE field_name = '". $field['field_name'] ."'
102 AND type_name = '". $instance->type_name ."'"
103 );
104
105 // write the field settings with the new $force_list to the global settings
106 $global = db_result(db_query(
107 "SELECT * FROM {node_field} WHERE field_name = '%s'", $field['field_name']
108 ));
109 $field_settings = unserialize($global->global_settings);
110 $field_settings['force_list'] = ($show_list == 0) ? 1 : 0;
111 $ret[] = update_sql(
112 "UPDATE {node_field}
113 SET global_settings = '". serialize($field_settings) ."'
114 WHERE field_name = '". $field['field_name'] ."'"
115 );
116 }
117 }
118 break;
119 }
120 }
121 db_query('DELETE FROM {cache}');
122 db_query('DELETE FROM {cache_content}');
123 return $ret;
124 }
125
126 function filefield_update_6001() {
127 if ($abort = content_check_update('filefield')) {
128 return $abort;
129 }
130
131 $ret = array();
132 include_once(drupal_get_path('module','content') .'/includes/content.admin.inc');
133
134 // rename the field type from file to filefield. adhere to module namespace.
135 $ret[] = update_sql("UPDATE {content_node_field} SET type='filefield' WHERE type='file'");
136 // rename default widget to filefield_widget. adhere to module namespace.
137 $ret[] = update_sql("UPDATE {content_node_field_instance} SET widget_type='filefield_widget' WHERE widget_type='file'");
138
139 // update list default value and force list settings.
140 $result = db_query("SELECT * FROM {content_node_field} WHERE type = 'filefield'");
141 while ($field = db_fetch_object($result)) {
142 $updated = false;
143 $field_settings = unserialize($field->global_settings);
144 if (!isset($field_settings['list_default']) || !is_numeric($field_settings['list_default'])) {
145 $field_settings['list_default'] = 1;
146 $updated = true;
147
148 }
149 // set behavior to match old force_list behavior.
150 if (!empty($field_settings['force_list'])) {
151 $field_settings['list_default'] = 1;
152 $field_settings['force_list_default'] = 1;
153 $updated = true;
154 }
155 if ($updated) {
156 $ret[] = update_sql("UPDATE {content_node_field} SET global_settings = '". serialize($field_settings) ."' WHERE field_name = '$field->field_name'");
157 }
158 }
159
160
161 // add data column to filefields.
162 $fields = content_fields();
163 foreach($fields as $field) {
164 if ($field['type'] != 'filefield') continue;
165 $new_field = $field;
166 $new_field['columns']['data'] = array('type' => 'text');
167 content_alter_db($field, $new_field);
168 }
169
170 // Build a batch that migrates the data in each filefield
171 $batch = array(
172 'title' => t('Migrating filefield values'),
173 'operations' => array(),
174 'file' => drupal_get_path('module', 'filefield') .'/filefield.install',
175 );
176 $content_info = _content_type_info();
177 foreach ($content_info['content types'] as $node_type => $node_info) {
178 foreach ($node_info['fields'] as $field_name => $field) {
179 if ($field['type'] == 'filefield') {
180 $batch['operations'][] = array('_filefield_update_6001_move_operation', array($field));
181 $batch['operations'][] = array('_filefield_update_6001_drop_operation', array($field));
182 }
183 }
184 }
185 batch_set($batch);
186
187
188 // clear them caches.
189 cache_clear_all('*', content_cache_tablename(), true);
190 cache_clear_all('*', 'cache', true);
191 return $ret;
192 }
193
194 /**
195 * Move the list and descriptions column into the serialized data column.
196 */
197 function _filefield_update_6001_move_operation($field, &$context) {
198 // Setup the first through
199 if (!isset($context['sandbox']['progress'])) {
200 $db_info = content_database_info($field);
201 $context['sandbox']['db_info'] = $db_info;
202 $context['sandbox']['table'] = $db_info['table'];
203 $context['sandbox']['col_data'] = $db_info['columns']['data']['column'];
204 $context['sandbox']['col_desc'] = $db_info['columns']['description']['column'];
205 $context['sandbox']['max'] = db_result(db_query("SELECT COUNT(*) FROM {". $db_info['table'] ."}"));
206 $context['sandbox']['progress'] = 0;
207 $context['sandbox']['current_node'] = 0;
208 }
209
210 // Work our way through the field values 50 rows at a time.
211 $limit = 50;
212 $result = db_query_range("SELECT * FROM {{$context['sandbox']['table']}} WHERE vid > %d ORDER BY nid ASC", $context['sandbox']['current_node'], 0, $limit);
213 while ($row = db_fetch_array($result)) {
214 // Try to unserialize the data column.
215 if (!empty($row[$context['sandbox']['col_data']])) {
216 $data = unserialize($row[$context['sandbox']['col_data']]);
217 }
218 if (empty($data)) {
219 $data = array();
220 }
221
222 // Copy move the values from the columns into the array...
223 $data['description'] = $row[$context['sandbox']['col_desc']];
224
225 // ...serialize it and store it back to the db.
226 db_query("UPDATE {{$context['sandbox']['table']}} SET {$context['sandbox']['col_data']} = '%s' WHERE vid = %d", serialize($data), $row['vid']);
227
228 // Update our progress information.
229 $context['sandbox']['progress']++;
230 $context['sandbox']['current_node'] = $row['vid'];
231 }
232
233 // Inform the batch engine that we are not finished,
234 // and provide an estimation of the completion level we reached.
235 if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
236 $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
237 }
238 }
239
240 /**
241 * Drop the list and description columns.
242 */
243 function _filefield_update_6001_drop_operation($field, &$context) {
244 $ret = array();
245 $db_info = content_database_info($field);
246 // TODO: Now that the data has been migrated we can drop the columns.
247 db_drop_field($ret, $db_info['table'], $db_info['columns']['description']['column']);
248 $context['finished'] = 1;
249 }