| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @file 4 * FileField: Defines a CCK file field type. 5 * 6 * Uses content.module to store the fid and field specific metadata, 7 * and Drupal's {files} table to store the actual file data. 8 */ 9 10 require_once dirname(__FILE__) . '/field_file.inc'; 11 12 /** 13 * Implementation of hook_install(). 14 */ 15 function filefield_install() { 16 drupal_load('module', 'content'); 17 content_notify('install', 'filefield'); 18 } 19 20 /** 21 * Implementation of hook_uninstall(). 22 */ 23 function filefield_uninstall() { 24 drupal_load('module', 'content'); 25 content_notify('uninstall', 'filefield'); 26 } 27 28 /** 29 * Implementation of hook_enable(). 30 */ 31 function filefield_enable() { 32 drupal_load('module', 'content'); 33 content_notify('enable', 'filefield'); 34 } 35 36 /** 37 * Implementation of hook_disable(). 38 */ 39 function filefield_disable() { 40 drupal_load('module', 'content'); 41 content_notify('disable', 'filefield'); 42 } 43 44 /** 45 * Implementation of hook_requirements(). 46 * 47 * Display information about getting upload progress bars working. 48 */ 49 function filefield_requirements($phase) { 50 $requirements = array(); 51 // Ensure translations don't break at install time 52 $t = get_t(); 53 54 // Report Drupal version 55 if ($phase == 'runtime') { 56 drupal_load('module', 'filefield'); 57 $implementation = filefield_progress_implementation(); 58 $apache = strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== FALSE; 59 $fastcgi = strpos($_SERVER['SERVER_SOFTWARE'], 'mod_fastcgi') !== FALSE || strpos($_SERVER["SERVER_SOFTWARE"], 'mod_fcgi') !== FALSE; 60 $php_52 = version_compare(phpversion(), '5.2.0', '>'); 61 $description = NULL; 62 if (!$apache || !$php_52) { 63 $value = $t('Not enabled'); 64 $description = $t('Your server is not capable of displaying file upload progress. File upload progress requires PHP 5.2 and an Apache server.'); 65 $severity = REQUIREMENT_INFO; 66 } 67 elseif ($fastcgi) { 68 $value = $t('Not enabled'); 69 $description = $t('Your server is not capable of displaying file upload progress. File upload progress requires PHP be run with mod_php and not as FastCGI.'); 70 $severity = REQUIREMENT_INFO; 71 } 72 elseif (!$implementation && extension_loaded('apc')) { 73 $value = $t('Not enabled'); 74 $description = $t('Your server is capable of displaying file upload progress through APC, but it is not enabled. Add <code>apc.rfc1867 = 1</code> to your php.ini configuration. Alternatively, it is recommended to use <a href="http://pecl.php.net/package/uploadprogress">PECL uploadprogress</a>, which supports more than one simultaneous upload.'); 75 $severity = REQUIREMENT_INFO; 76 } 77 elseif (!$implementation) { 78 $value = $t('Not enabled'); 79 $description = t('Your server is capable of displaying file upload progress, but does not have the required libraries. It is recommended to install the <a href="http://pecl.php.net/package/uploadprogress">PECL uploadprogress library</a> (preferred) or to install <a href="http://us2.php.net/apc">APC</a>.'); 80 $severity = REQUIREMENT_INFO; 81 } 82 elseif ($implementation == 'apc') { 83 $value = $t('Enabled (<a href="http://php.net/manual/en/apc.configuration.php#ini.apc.rfc1867">APC RFC1867</a>)'); 84 $description = t('Your server is capable of displaying file upload progress using APC RFC1867. Note that only one upload at a time is supported. It is recommended to use the <a href="http://pecl.php.net/package/uploadprogress">PECL uploadprogress library</a> if possible.'); 85 $severity = REQUIREMENT_OK; 86 } 87 elseif ($implementation == 'uploadprogress') { 88 $value = $t('Enabled (<a href="http://pecl.php.net/package/uploadprogress">PECL uploadprogress</a>)'); 89 $severity = REQUIREMENT_OK; 90 } 91 $requirements['filefield_progress'] = array( 92 'title' => $t('Upload progress'), 93 'value' => $value, 94 'severity' => $severity, 95 'description' => $description, 96 ); 97 } 98 99 return $requirements; 100 } 101 102 /** 103 * Implementation of hook_update_last_removed(). 104 */ 105 function filefield_update_last_removed() { 106 return 3; 107 } 108 109 /** 110 * Upgrade FileField to Drupal 6. 111 */ 112 function filefield_update_6001() { 113 if ($abort = content_check_update('filefield')) { 114 return $abort; 115 } 116 117 $ret = array(); 118 module_load_include('inc', 'content', 'includes/content.admin'); 119 120 // Rename the field type from file to filefield. adhere to module namespace. 121 $ret[] = update_sql("UPDATE {content_node_field} SET type = 'filefield', module = 'filefield', active = 1 WHERE type = 'file'"); 122 // Rename default widget to filefield_widget. adhere to module namespace. 123 $ret[] = update_sql("UPDATE {content_node_field_instance} SET widget_type = 'filefield_widget', widget_module = 'filefield', widget_active = 1 WHERE widget_type = 'file'"); 124 125 // Update list default value and force list settings. 126 $result = db_query("SELECT * FROM {content_node_field} WHERE type = 'filefield'"); 127 while ($field = db_fetch_object($result)) { 128 $updated = FALSE; 129 $field_settings = unserialize($field->global_settings); 130 if (!isset($field_settings['list_default']) || !is_numeric($field_settings['list_default'])) { 131 $field_settings['list_default'] = 1; 132 $updated = TRUE; 133 } 134 135 // Set behavior to match old force_list behavior. 136 if (!empty($field_settings['force_list'])) { 137 $field_settings['list_default'] = 1; 138 $field_settings['force_list_default'] = 1; 139 $updated = TRUE; 140 } 141 if ($updated) { 142 db_query("UPDATE {content_node_field} SET global_settings = '%s' WHERE field_name = '%s'", serialize($field_settings), $field->field_name); 143 } 144 } 145 146 // Re-enable all the FileFields on the site. 147 content_associate_fields('filefield'); 148 149 // Build a list of fields that need data updating. 150 $fields = array(); 151 foreach (content_types_install() as $type_name => $type_fields) { 152 foreach ($type_fields as $field) { 153 if ($field['type'] == 'filefield') { 154 // We only process a given field once. 155 $fields[$field['field_name']] = $field; 156 } 157 } 158 } 159 160 // Update database storage (add data column, remove description, set NOT NULL). 161 foreach ($fields as $field) { 162 $new_field = $field; 163 164 // Setup the previous definition. 165 $field['columns']['description'] = array('type' => 'varchar'); 166 $field['columns']['fid']['not null'] = TRUE; 167 $field['columns']['list']['not null'] = TRUE; 168 unset($field['columns']['data']); 169 170 // Setup the new definition. 171 $new_field['columns']['data'] = array('type' => 'text', 'serialize' => TRUE); 172 $new_field['columns']['fid']['not null'] = FALSE; 173 $new_field['columns']['list']['size'] = 'tiny'; 174 $new_field['columns']['list']['not null'] = FALSE; 175 unset($new_field['columns']['description']); 176 177 content_alter_db($field, $new_field); 178 } 179 180 // Build a batch that migrates the data in each filefield 181 $batch = array( 182 'title' => t('Migrating filefield values'), 183 'operations' => array(), 184 'file' => drupal_get_path('module', 'filefield') .'/filefield.install', 185 ); 186 foreach ($fields as $field_name => $field) { 187 if ($field['type'] == 'filefield') { 188 $batch['operations'][] = array('_filefield_update_6001_move_operation', array($field)); 189 $batch['operations'][] = array('_filefield_update_6001_drop_operation', array($field)); 190 } 191 } 192 batch_set($batch); 193 194 195 // Clear caches. 196 cache_clear_all('*', content_cache_tablename(), TRUE); 197 cache_clear_all('*', 'cache', TRUE); 198 return $ret; 199 } 200 201 /** 202 * Migrate field settings from 'force_list_default' and 'show_description'. 203 */ 204 function filefield_update_6100() { 205 $ret = array(); 206 207 module_load_include('inc', 'content', 'includes/content.crud'); 208 209 $fields = content_fields(); 210 foreach ($fields as $field) { 211 if ($field['type'] == 'filefield') { 212 if (isset($field['force_list_default'])) { 213 $field['list_field'] = !$field['force_list_default']; 214 } 215 if (isset($field['show_description'])) { 216 $field['description_field'] = $field['show_description']; 217 } 218 _content_field_write($field); 219 $ret[] = array('success' => TRUE, 'query' => t('The file field %field has been updated with new settings.', array('%field' => $field['field_name']))); 220 } 221 } 222 223 cache_clear_all('*', content_cache_tablename(), TRUE); 224 cache_clear_all('*', 'cache', TRUE); 225 226 return $ret; 227 } 228 229 /** 230 * Set fid to NULL where files have been deleted. 231 * 232 * This is a double-cleanup from Drupal 5 versions, where fid used to be 0 for 233 * empty rows or sometimes referred to a nonexistent FID altogether. 234 */ 235 function filefield_update_6101() { 236 $ret = array(); 237 238 module_load_include('inc', 'content', 'includes/content.crud'); 239 240 $fields = content_fields(); 241 242 foreach ($fields as $field) { 243 if ($field['type'] == 'filefield') { 244 $db_info = content_database_info($field); 245 if (isset($db_info['columns']['fid'])) { 246 $table = $db_info['table']; 247 $fid_column = $db_info['columns']['fid']['column']; 248 $list_column = $db_info['columns']['list']['column']; 249 $ret[] = update_sql("UPDATE {" . $table . "} SET $fid_column = NULL, $list_column = NULL WHERE $fid_column NOT IN (SELECT fid FROM {files})"); 250 } 251 } 252 } 253 254 return $ret; 255 } 256 257 /** 258 * Fix corrupted serialized data in the "data" column. 259 */ 260 function filefield_update_6102(&$sandbox) { 261 // Update removed. This turned out to be a bug in CCK core, so it is being 262 // fixed directly in CCK rather than in FileField. 263 // See http://drupal.org/node/407446. 264 return array(); 265 } 266 267 /** 268 * Convert "Extensible File" to a normal "File" widget. 269 */ 270 function filefield_update_6103() { 271 $ret = array(); 272 273 $ret[] = update_sql("UPDATE {". content_instance_tablename() ."} SET widget_type = 'filefield_widget' WHERE widget_type = 'filefield_combo'"); 274 275 cache_clear_all('*', content_cache_tablename(), TRUE); 276 cache_clear_all('*', 'cache', TRUE); 277 278 return $ret; 279 } 280 281 /** 282 * Delete the filefield_token module entry in the system table. 283 */ 284 function filefield_update_6104() { 285 $ret = array(); 286 287 $ret[] = update_sql("DELETE FROM {system} WHERE type = 'module' AND name = 'filefield_token'"); 288 289 return $ret; 290 } 291 292 /** 293 * Move the list and descriptions column into the serialized data column. 294 */ 295 function _filefield_update_6001_move_operation($field, &$context) { 296 // Setup the first through 297 if (!isset($context['sandbox']['processed_files'])) { 298 $db_info = content_database_info($field); 299 $context['sandbox']['db_info'] = $db_info; 300 $context['sandbox']['table'] = $db_info['table']; 301 $context['sandbox']['col_data'] = $db_info['columns']['data']['column']; 302 $context['sandbox']['col_desc'] = $db_info['columns']['description']['column']; 303 $context['sandbox']['max'] = db_result(db_query("SELECT COUNT(*) FROM {". $db_info['table'] ."}")); 304 $context['sandbox']['current_node'] = 0; 305 $context['sandbox']['current_delta'] = 0; 306 $context['sandbox']['processed_files'] = array(); 307 } 308 309 // Work our way through the field values 50 rows at a time. 310 $limit = 50; 311 $result = NULL; 312 if ($field['multiple']) { 313 $result = db_query_range("SELECT * FROM {{$context['sandbox']['table']}} WHERE (vid = %d AND delta > %d) OR vid > %d ORDER BY vid ASC, delta ASC", $context['sandbox']['current_node'], $context['sandbox']['current_delta'], $context['sandbox']['current_node'], 0, $limit); 314 } 315 else { 316 $result = db_query_range("SELECT * FROM {{$context['sandbox']['table']}} WHERE vid >= %d ORDER BY vid ASC", $context['sandbox']['current_node'], 0, $limit); 317 } 318 while ($row = db_fetch_array($result)) { 319 // Do not process the same file twice. This may happen when a node's files 320 // are split across two separate batch update HTTP requests. 321 $delta = isset($row['delta']) ? $row['delta'] : 0; 322 if (isset($context['sandbox']['processed_files'][$row['vid'] . '_' . $delta])) { 323 continue; 324 } 325 326 // Try to unserialize the data column. 327 if (!empty($row[$context['sandbox']['col_data']])) { 328 $data = unserialize($row[$context['sandbox']['col_data']]); 329 } 330 if (empty($data)) { 331 $data = array(); 332 } 333 334 // Copy move the values from the columns into the array... 335 $data['description'] = $row[$context['sandbox']['col_desc']]; 336 337 // ...serialize it and store it back to the db. 338 db_query("UPDATE {{$context['sandbox']['table']}} SET {$context['sandbox']['col_data']} = '%s' WHERE vid = %d", serialize($data), $row['vid']); 339 340 // Update our progress information. 341 $context['sandbox']['processed_files'][$row['vid'] . '_' . $delta] = TRUE; 342 $context['sandbox']['current_node'] = $row['vid']; 343 $context['sandbox']['current_delta'] = $delta; 344 } 345 346 // Inform the batch engine that we are not finished, 347 // and provide an estimation of the completion level we reached. 348 $processed_count = count($context['sandbox']['processed_files']); 349 if ($processed_count != $context['sandbox']['max']) { 350 $context['finished'] = $processed_count / $context['sandbox']['max']; 351 } 352 } 353 354 /** 355 * Drop the list and description columns. 356 */ 357 function _filefield_update_6001_drop_operation($field, &$context) { 358 $ret = array(); 359 $db_info = content_database_info($field); 360 // TODO: Now that the data has been migrated we can drop the columns. 361 db_drop_field($ret, $db_info['table'], $db_info['columns']['description']['column']); 362 $context['finished'] = 1; 363 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |