| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @file 5 * FileField CCK field hooks and callbacks. 6 */ 7 8 /** 9 * Implementation of CCK's hook_field_settings($op = 'form'). 10 */ 11 function filefield_field_settings_form($field) { 12 drupal_add_js(drupal_get_path('module', 'filefield') .'/filefield.js'); 13 14 $form = array(); 15 16 $form['list_field'] = array( 17 '#type' => 'radios', 18 '#title' => t('List field'), 19 '#options' => array(0 => t('Disabled'), 1 => t('Enabled')), 20 '#default_value' => $field['list_field'] === '' ? 0 : (int) $field['list_field'], 21 '#description' => t('Display a checkbox where users may choose if a file should be shown when viewing the content. Most formatters other than <em>Generic file</em> do not support this option.'), 22 '#attributes' => array('class' => 'filefield-list-field'), 23 ); 24 $form['list_default'] = array( 25 '#type' => 'checkbox', 26 '#title' => t('Files listed by default'), 27 '#default_value' => $field['list_default'] === '' ? 1 : (int) $field['list_default'], 28 ); 29 $form['description_field'] = array( 30 '#type' => 'radios', 31 '#title' => t('Description field'), 32 '#default_value' => $field['description_field'] === '' ? 0 : (int) $field['description_field'], 33 '#options' => array(0 => t('Disabled'), 1 => t('Enabled')), 34 '#description' => t('Display a text field where users may enter a description about the uploaded file. The description text is used when using the <em>Generic file</em> formatter to link to the file, the file name will be used otherwise. Most other formatters do not use the description field on output.'), 35 ); 36 37 return $form; 38 } 39 40 /** 41 * Implementation of CCK's hook_field_settings($op = 'save'). 42 */ 43 function filefield_field_settings_save($field) { 44 return array('list_field', 'list_default', 'description_field'); 45 } 46 47 /** 48 * Implementation of CCK's hook_field_settings($op = 'database_columns'). 49 */ 50 function filefield_field_settings_database_columns($field) { 51 return array( 52 'fid' => array('type' => 'int', 'not null' => FALSE, 'views' => TRUE), 53 'list' => array('type' => 'int', 'size' => 'tiny', 'not null' => FALSE, 'views' => TRUE), 54 'data' => array('type' => 'text', 'serialize' => TRUE, 'views' => TRUE), 55 ); 56 } 57 58 /** 59 * Implementation of CCK's hook_field_settings($op = 'views_data'). 60 */ 61 function filefield_field_settings_views_data($field) { 62 $data = content_views_field_views_data($field); 63 $db_info = content_database_info($field); 64 $table_alias = content_views_tablename($field); 65 66 // By defining the relationship, we already have a "Has file" filter 67 // plus all the filters that Views already provides for files. 68 // No need for having a filter by ourselves. 69 unset($data[$table_alias][$field['field_name'] .'_fid']['filter']); 70 71 // Add a relationship for related file. 72 $data[$table_alias][$field['field_name'] .'_fid']['relationship'] = array( 73 'base' => 'files', 74 'field' => $db_info['columns']['fid']['column'], 75 'handler' => 'content_handler_relationship', 76 'label' => t($field['widget']['label']), 77 'content_field_name' => $field['field_name'], 78 'skip base' => array('files'), 79 ); 80 81 // Use the Views boolean handler for filtering the list value. 82 $data[$table_alias][$field['field_name'] .'_list']['filter']['handler'] = 'views_handler_filter_boolean_operator'; 83 84 // Add our special handler for serialized data. 85 $data[$table_alias][$field['field_name'] .'_data']['field'] = array( 86 'title' => $data[$table_alias][$field['field_name'] .'_data']['title'], 87 'title short' => $data[$table_alias][$field['field_name'] .'_data']['title short'], 88 'help' => t('Can be used to display specific alt, title, or description information. May cause duplicate rows if grouping fields.'), 89 'field' => $db_info['columns']['data']['column'], 90 'table' => $db_info['table'], 91 'handler' => 'filefield_handler_field_data', 92 'click sortable' => FALSE, 93 'access callback' => 'content_access', 94 'access arguments' => array('view', $field), 95 ); 96 97 // Remove handlers that are probably unnecessary. 98 unset($data[$table_alias][$field['field_name'] .'_data']['filter']); 99 unset($data[$table_alias][$field['field_name'] .'_data']['argument']); 100 unset($data[$table_alias][$field['field_name'] .'_list']['argument']); 101 102 // Set up relationship with file views. 103 $data[$table_alias]['table']['join']['files'] = array( 104 'table' => $db_info['table'], 105 'left_field' => 'fid', 106 'field' => $db_info['columns']['fid']['column'], 107 ); 108 $data[$table_alias]['vid'] = array( 109 'title' => t($field['widget']['label']), 110 'help' => t('The node the uploaded file is attached to'), 111 'relationship' => array( 112 'label' => t($field['widget']['label']), 113 'base' => 'node', 114 'base field' => 'vid', 115 // This allows us to not show this relationship if the base is already 116 // node so users won't create circular relationships. 117 'skip base' => array('node', 'node_revisions'), 118 ), 119 ); 120 121 return $data; 122 } 123 124 /** 125 * Implementation of CCK's hook_field($op = 'load'). 126 */ 127 function filefield_field_load($node, $field, &$items, $teaser, $page) { 128 if (empty($items)) { 129 return array(); 130 } 131 foreach ($items as $delta => $item) { 132 // Despite hook_content_is_empty(), CCK still doesn't filter out 133 // empty items from $op = 'load', so we need to do that ourselves. 134 if (empty($item['fid']) || !($file = field_file_load($item['fid']))) { 135 $items[$delta] = NULL; 136 } 137 else { 138 if (isset($item['data']) && !empty($item['data'])) { 139 $item['data'] = unserialize($item['data']); 140 } 141 // Temporary fix to unserialize data serialized multiple times. 142 // See the FileField issue http://drupal.org/node/402860. 143 // And the CCK issue http://drupal.org/node/407446. 144 while (!empty($item['data']) && is_string($item['data'])) { 145 $item['data'] = unserialize($item['data']); 146 } 147 // Merge any data added by modules in hook_file_load(). 148 if (isset($file['data']) && isset($item['data'])) { 149 $file['data'] = array_merge((array) $file['data'], (array) $item['data']); 150 } 151 $items[$delta] = array_merge($file, $item); 152 } 153 } 154 155 return array($field['field_name'] => $items); 156 } 157 158 /** 159 * Implementation of CCK's hook_field($op = 'insert'). 160 */ 161 function filefield_field_insert($node, $field, &$items, $teaser, $page) { 162 return filefield_field_update($node, $field, $items, $teaser, $page); 163 } 164 165 /** 166 * Implementation of CCK's hook_field($op = 'update'). 167 */ 168 function filefield_field_update($node, $field, &$items, $teaser, $page) { 169 170 // Accumulator to gather current fid to compare with the original node 171 // for deleting replaced files. 172 $curfids = array(); 173 foreach ($items as $delta => $item) { 174 $items[$delta] = field_file_save($node, $item); 175 // Remove items from the array if they have been deleted. 176 if (empty($items[$delta]) || empty($items[$delta]['fid'])) { 177 $items[$delta] = NULL; 178 } 179 else { 180 $curfids[] = $items[$delta]['fid']; 181 } 182 } 183 184 // If this is a new node there are no old items to worry about. 185 // On new revisions, old files are always maintained in the previous revision. 186 if ($node->is_new || !empty($node->revision) || !empty($node->skip_filefield_delete)) { 187 return; 188 } 189 190 // Delete items from original node. 191 $orig = node_load($node->nid); 192 // If there are, figure out which ones must go. 193 if (!empty($orig->$field['field_name'])) { 194 foreach ($orig->$field['field_name'] as $oitem) { 195 if (isset($oitem['fid']) && !in_array($oitem['fid'], $curfids)) { 196 // For hook_file_references, remember that this is being deleted. 197 $oitem['field_name'] = $field['field_name']; 198 $oitem['delete_vid'] = $orig->vid; 199 filefield_field_delete_file($oitem, $field); 200 } 201 } 202 } 203 } 204 205 /** 206 * Implementation of CCK's hook_field($op = 'delete_revision'). 207 */ 208 function filefield_field_delete_revision($node, $field, &$items, $teaser, $page) { 209 foreach ($items as $delta => $item) { 210 if (isset($item['fid'])) { 211 // For hook_file_references, remember that this is being deleted. 212 $item['field_name'] = $field['field_name']; 213 $item['delete_vid'] = $node->vid; 214 if (filefield_field_delete_file($item, $field)) { 215 $items[$delta] = NULL; 216 } 217 } 218 } 219 } 220 221 /** 222 * Implementation of CCK's hook_field($op = 'delete'). 223 */ 224 function filefield_field_delete($node, $field, &$items, $teaser, $page) { 225 foreach ($items as $delta => $item) { 226 if (isset($item['fid'])) { 227 // For hook_file_references(), remember that this is being deleted. 228 $item['field_name'] = $field['field_name']; 229 // Pass in the nid of the node that is being removed so all references can 230 // be counted in hook_file_references(). 231 $item['delete_nid'] = $node->nid; 232 filefield_field_delete_file($item, $field); 233 } 234 } 235 236 // Delete all the remaining items present only in older revisions. 237 $db_info = content_database_info($field); 238 $result = db_query('SELECT vid, f.* FROM {' . $db_info['table'] . '} t INNER JOIN {files} f ON t.' . $db_info['columns']['fid']['column'] . ' = f.fid WHERE nid = %d AND vid != %d', $node->nid, $node->vid); 239 while ($item = db_fetch_array($result)) { 240 if (isset($item['fid'])) { 241 $item['field_name'] = $field['field_name']; 242 $item['delete_vid'] = $item['vid']; 243 filefield_field_delete_file($item, $field); 244 } 245 } 246 } 247 248 /** 249 * Check that FileField controls a file before attempting to deleting it. 250 */ 251 function filefield_field_delete_file($file, $field) { 252 $file = (object) $file; 253 254 // Remove the field_name and delete_nid properties so that references can be 255 // counted including the files to be deleted. 256 $field_name = isset($file->field_name) ? $file->field_name : NULL; 257 $delete_nid = isset($file->delete_nid) ? $file->delete_nid : NULL; 258 unset($file->field_name, $file->delete_nid); 259 260 // To prevent FileField from deleting files it doesn't know about, check the 261 // FileField reference count. Temporary files can be deleted because they 262 // are not yet associated with any content at all. 263 if ($file->status == 0 || filefield_get_file_reference_count($file, $field) > 0) { 264 $file->field_name = $field_name; 265 $file->delete_nid = $delete_nid; 266 return field_file_delete($file); 267 } 268 269 // Even if the file is not deleted, return TRUE to indicate the FileField 270 // record can be removed from the FileField database tables. 271 return TRUE; 272 } 273 274 /** 275 * Implementation of CCK's hook_field($op = 'sanitize'). 276 */ 277 function filefield_field_sanitize($node, $field, &$items, $teaser, $page) { 278 foreach ($items as $delta => $item) { 279 // Cleanup $items during node preview. 280 if (empty($item['fid']) || !empty($item['delete'])) { 281 // Check for default images at the widget level. 282 // TODO: Provide an API to ImageField to do this itself? 283 if (!empty($field['widget']['use_default_image']) && !empty($field['widget']['default_image']['filepath']) && $delta == 0) { 284 $items[$delta] = $field['widget']['default_image']; 285 $items[$delta]['default'] = TRUE; 286 } 287 else { 288 $items[$delta] = NULL; 289 continue; 290 } 291 } 292 293 // Add nid so formatters can create a link to the node. 294 $items[$delta]['nid'] = $node->nid; 295 296 // Get the 'data' column stored by CCK into an array. This is necessary 297 // for Views, which doesn't call the "load" $op and to fix an issue with 298 // CCK double-serializing data. 299 // See the FileField issue http://drupal.org/node/402860. 300 // And the CCK issue http://drupal.org/node/407446. 301 while (!empty($items[$delta]['data']) && is_string($items[$delta]['data'])) { 302 $items[$delta]['data'] = unserialize($items[$delta]['data']); 303 } 304 305 // Load the complete file if a filepath is not available. 306 if (!empty($item['fid']) && empty($item['filepath'])) { 307 $file = (array) field_file_load($item['fid']); 308 if (isset($file['data'])) { 309 $file['data'] = array_merge($file['data'], $items[$delta]['data']); 310 } 311 $items[$delta] = array_merge($file, $items[$delta]); 312 } 313 314 // Verify the file exists on the server. 315 if (!empty($item['filepath']) && !file_exists($item['filepath'])) { 316 watchdog('filefield', 'FileField was trying to display the file %file, but it does not exist.', array('%file' => $item['filepath']), WATCHDOG_WARNING); 317 } 318 } 319 }
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 |