#370531: Properly handle revisions of FileFields.
[project/filefield.git] / filefield_field.inc
1 <?php
2 // $Id$
3
4 /**
5 * @file
6 * FileField field hooks and callbacks.
7 */
8
9 function filefield_field_settings_form($field) {
10 drupal_add_js(drupal_get_path('module', 'filefield') .'/filefield.js');
11
12 $form = array();
13
14 $form['list_field'] = array(
15 '#type' => 'radios',
16 '#title' => t('List field'),
17 '#options' => array(0 => t('Disabled'), 1 => t('Enabled')),
18 '#default_value' => $field['list_field'] === '' ? 0 : (int) $field['list_field'],
19 '#description' => t('The "list" option lets a user choose if a file should shown in a list when viewing the content after creation.'),
20 '#attributes' => array('class' => 'filefield-list-field'),
21 );
22 $form['list_default'] = array(
23 '#type' => 'checkbox',
24 '#title' => t('Files listed by default'),
25 '#default_value' => $field['list_default'] === '' ? 1 : (int) $field['list_default'],
26 );
27 $form['description_field'] = array(
28 '#type' => 'radios',
29 '#title' => t('Description field'),
30 '#default_value' => $field['description_field'] === '' ? 0 : (int) $field['description_field'],
31 '#options' => array(0 => t('Disabled'), 1 => t('Enabled')),
32 '#description' => t('When enabled, will display a text field where users may enter a description about the uploaded file.'),
33 );
34
35 return $form;
36 }
37
38 function filefield_field_settings_validate($field) {
39 }
40
41 function filefield_field_settings_save($field) {
42 return array('list_field', 'list_default', 'description_field');
43 }
44
45 function filefield_field_settings_database_columns($field) {
46 return array(
47 'fid' => array('type' => 'int', 'not null' => FALSE),
48 'list' => array('type' => 'int', 'size' => 'tiny', 'not null' => FALSE),
49 'data' => array('type' => 'text', 'serialize' => true),
50 );
51 }
52
53 function filefield_field_settings_views_data($field) {
54 $data = content_views_field_views_data($field);
55 $db_info = content_database_info($field);
56 $table_alias = content_views_tablename($field);
57
58 // Set our own field handler so that we can hook the file formatter
59 // configuration table into the options form.
60
61 // By defining the relationship, we already have a "Has file" filter
62 // plus all the filters that Views already provides for files.
63 // No need for having a filter by ourselves.
64 unset($data[$table_alias][$field['field_name'] .'_fid']['filter']);
65
66 // Add a relationship for related file.
67 $data[$table_alias][$field['field_name'] .'_fid']['relationship'] = array(
68 'base' => 'files',
69 'field' => $db_info['columns']['fid']['column'],
70 'handler' => 'content_handler_relationship',
71 'label' => t($field['widget']['label']),
72 'content_field_name' => $field['field_name'],
73 );
74 return $data;
75 }
76
77
78
79 /**
80 * Implementation of CCK's hook_field().
81 */
82 function filefield_field_load($node, $field, &$items, $teaser, $page) {
83 if (empty($items)) {
84 return array();
85 }
86 foreach ($items as $delta => $item) {
87 // Despite hook_content_is_empty(), CCK still doesn't filter out
88 // empty items from $op = 'load', so we need to do that ourselves.
89 if (empty($item['fid']) || !($file = field_file_load($item['fid']))) {
90 unset($items[$delta]);
91 }
92 else {
93 $item['data'] = unserialize($item['data']);
94 $items[$delta] = array_merge($item, $file);
95 }
96 }
97 $items = array_values($items); // compact deltas
98 return array($field['field_name'] => $items);
99 }
100
101 function filefield_field_insert($node, $field, &$items, $teaser, $page) {
102 return filefield_field_update($node, $field, $items, $teaser, $page);
103 }
104
105 function filefield_field_update($node, $field, &$items, $teaser, $page) {
106
107 // Accumulator to gather current fid to compare with the original node
108 // for deleting replaced files.
109 $curfids = array();
110 foreach ($items as $delta => $item) {
111 $items[$delta] = field_file_save($node, $item);
112 // Remove items from the array if they have been deleted.
113 if (empty($items[$delta])) unset($items[$delta]);
114 $curfids[] = $item['fid'];
115 }
116 $items = array_values($items); // compact deltas
117
118
119 // if this is a new node... there are no
120 // old items to worry about.
121 if ($node->is_new) {
122 return;
123 }
124
125 // Delete items from original node if no new revision was created.
126 $orig = node_load($node->nid);
127 // If there are, figure out which ones must go.
128 if ($node->revision == 0 && !empty($orig->$field['field_name'])) {
129 foreach ($orig->$field['field_name'] as $oitem) {
130 if (!in_array($oitem['fid'], $curfids)) {
131 // For hook_file_references, remember that this is being deleted.
132 $oitem['field_name'] = $field['field_name'];
133 field_file_delete($oitem);
134 }
135 }
136 }
137 }
138
139 function filefield_field_delete_revision($node, $field, &$items, $teaser, $page) {
140 foreach ($items as $delta => $item) {
141 // For hook_file_references, remember that this is being deleted.
142 $item['field_name'] = $field['field_name'];
143 if (field_file_delete($item)) unset($items[$delta]);
144 $items = array_values($items); // compact deltas
145 }
146 }
147
148
149 function filefield_field_delete($node, $field, &$items, $teaser, $page) {
150 foreach ($items as $delta => $item) {
151 // For hook_file_references, remember that this is being deleted.
152 $item['field_name'] = $field['field_name'];
153 field_file_delete($item);
154 }
155 }
156
157 function filefield_field_sanitize($node, $field, &$items, $teaser, $page) {
158 foreach ($items as $delta => $item) {
159 // Cleanup $items during node preview.
160 if (empty($item['fid']) || !empty($item['delete'])) {
161 unset($items[$delta]);
162 continue;
163 }
164 // Load the complete file if a filepath is not available.
165 if (!empty($item['fid']) && empty($item['filepath'])) {
166 $items[$delta] = array_merge($item, field_file_load($item['fid']));
167 }
168 // Extract data array from serialized string.
169 if (is_string($item['data'])){
170 $items[$delta]['data'] = unserialize($item['data']);
171 }
172 // Add nid so formatters can create a link to the node.
173 $items[$delta]['nid'] = $node->nid;
174 }
175 }
176
177