/[drupal]/contributions/modules/cck_download_dropdown/cck_download_dropdown.module
ViewVC logotype

Contents of /contributions/modules/cck_download_dropdown/cck_download_dropdown.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download) (as text)
Fri Dec 14 18:33:18 2007 UTC (23 months, 2 weeks ago) by rconstantine
Branch: MAIN
CVS Tags: DRUPAL-5--1-0, HEAD
Branch point for: DRUPAL-5
File MIME type: text/x-php
Initial release for Drupal 5.X
1 <?php
2 /**
3 * This is the cck_download_dropdown module for use with CCK.
4 *
5 * <p>This file contains code and information on the cck_download_dropdown module. By attaching
6 * many files to a single node, you can then use this module on another node to present the
7 * user with a dropdown listing of the attachments from the first node.</p>
8 * <p>This effectively allows you to organize and categorize file downloads by using nodes as
9 * containers. You can place several of these drop downs on a node with each linking to a
10 * different container node.</p>
11 * TODO make this work with 'multiple' option so admin doesn't have to create custom content
12 * types just to accomodate a certain number of download categories. In other words, presently,
13 * a user cannot add download categories without help from an admin.
14 *
15 * @version $Id$;
16 * @package CCK_Download_Dropdown
17 * @category NeighborForge
18 * @author Ryan Constantine
19 * @filesource
20 * @license http://www.gnu.org/licenses/gpl.txt GNU_GENERAL_PUBLIC_LICENSE
21 * @link none yet
22 */
23
24 /**
25 * Implementation of hook_menu().
26 */
27 function cck_download_dropdown_menu($may_cache) {
28 $items = array();
29
30 if (!$may_cache) {
31 $items[] = array('path' => 'cck_download_dropdown/get_file',
32 'title' => t('Get file'),
33 'callback' => 'cck_download_dropdown_get_file',
34 'access' => user_access('view uploaded files'),
35 'type' => MENU_CALLBACK);
36 }
37 return $items;
38 }
39
40 //-----------------------------------------CCK Field Hooks-------------------------------------
41 //-----------------------------------------CCK Field Hooks-------------------------------------
42 //-----------------------------------------CCK Field Hooks-------------------------------------
43
44 /**
45 * Implementation of hook_field_info().
46 *
47 * @return
48 * An array keyed by field type name. Each element of the array is an associative
49 * array with these keys and values:
50 * - "label": The human-readable label for the field type.
51 */
52 function cck_download_dropdown_field_info() {
53 return array(
54 'cck_download_dropdown' => array('label' => 'Download dropdown'),
55 );
56 } //function cck_download_dropdown_field_info()
57
58 /**
59 * Implementation of hook_field_settings().
60 *
61 * See the README.txt for more info.
62 *
63 * @param $op
64 * The operation to be performed.
65 * @param $field
66 * The field on which the operation is to be performed.
67 * @return
68 * This varies depending on the operation.
69 * - "form": an array of form elements to add to
70 * the settings page.
71 * - "validate": no return value. Use form_set_error().
72 * - "save": an array of names of form elements to
73 * be saved in the database.
74 * - "database columns": an array keyed by column name, with arrays of column
75 * information as values.
76 * - "filters": an array whose values are 'filters'
77 * definitions as expected by views.module (see Views Documentation).
78 * - "callbacks": an array describing the field's behaviour regarding hook_field
79 * operations. The array is keyed by hook_field operations ('view', 'validate'...)
80 * and has the following possible values :
81 * CONTENT_CALLBACK_NONE : do nothing for this operation
82 * CONTENT_CALLBACK_CUSTOM : use the behaviour in hook_field(operation)
83 * CONTENT_CALLBACK_DEFAULT : use content.module's default bahaviour
84 * Note : currently only the 'view' operation implements this feature.
85 * All other field operation implemented by the module _will_ be executed
86 * no matter what.
87 */
88 function cck_download_dropdown_field_settings($op, $field) {
89 switch ($op) {
90 /*case 'validate':
91 break;*/
92
93 case 'database columns':
94 $columns = array(
95 'value' => array('type' => 'int', 'length' => 10, 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
96 );
97 return $columns;
98
99 case 'filters':
100 return array(
101 'default' => array(
102 'operator' => 'views_handler_operator_like',
103 'handler' => 'views_handler_filter_like',
104 ),
105 );
106
107 case 'callbacks'://pairs up with cck_download_dropdown_field::view
108 return array(
109 'view' => CONTENT_CALLBACK_CUSTOM,
110 );
111 }
112 } // function cck_download_dropdown_field_settings()
113
114 /**
115 * Implementation of hook_field().
116 *
117 * @param $op
118 * What kind of action is being performed.
119 * @param &$node
120 * The node the action is being performed on.
121 * @param $field
122 * The field the action is being performed on.
123 * @param &$node_field
124 * The contents of the field in this node. Changes to this variable will
125 * be saved back to the node object.
126 * @return
127 * This varies depending on the operation.
128 * - The "load" operation should return an object containing extra values
129 * to be merged into the node object.
130 * - The "view" operation should return a string containing an HTML
131 * representation of the field data.
132 * - The "insert", "update", "delete", "validate", and "submit" operations
133 * have no return value.
134 */
135 function cck_download_dropdown_field($op, &$node, $field, &$items, $teaser, $page) {
136 switch ($op) {
137 /*case 'validate':
138
139 break;
140
141 case 'load':
142
143 break;*/
144
145 case 'view':
146 $context = $teaser ? 'teaser' : 'full';
147 $formatter = isset($field['display_settings'][$context]['format']) ? $field['display_settings'][$context]['format'] : 'default';
148 foreach ($items as $delta => $item) {
149 $items[$delta]['view'] = content_format($field, $item, $formatter, $node);
150 }
151 return theme('field', $node, $field, $items, $teaser, $page);
152 break;
153 }
154 } // function cck_download_dropdown_field()
155
156 /**
157 * Implementation of hook_field_formatter_info().
158 */
159 function cck_download_dropdown_field_formatter_info() {
160 return array(
161 'default' => array(
162 'label' => t('Default'),
163 'field types' => array('cck_download_dropdown'),
164 ),
165 );
166 } // function cck_download_dropdown_field_formatter_info()
167
168 /**
169 * Implementation of hook_field_formatter().
170 *
171 * <p>Here we pull the list of attachments from the designated node and present them as a select list.</p>
172 * <p>The $node argument is necessary so that filter access can be checked on node preview.</p>
173 * @param $field
174 * The field the action is being performed on.
175 * @param $item
176 * An array, keyed by column, of the data stored for this item in this field.
177 * @param $formatter
178 * The name of the formatter being used to display the field. In our case, we name
179 * it directly, rather than send it through content_format() and therefore we don't
180 * use hook_field_formatter_info either.
181 * @param $node
182 * The node object, for context. Will be NULL in some cases.
183 * Warning : when displaying field retrieved by Views, $node will not
184 * be a "full-fledged" node object, but an object containg the data returned
185 * by the Views query (at least nid, vid, changed)
186 * @return
187 * An HTML string containing the formatted item.
188 */
189 function cck_download_dropdown_field_formatter($field, $item, $formatter, $node) {
190 switch ($formatter) {
191 default:
192 $links = array();
193 if ($field['widget']['list_order'] == 0) {
194 $sort = 'ASC';
195 }
196 else {
197 $sort = 'DESC';
198 }
199 $selections = db_query('SELECT fid, filename, filepath FROM {files} WHERE nid = %d ORDER BY filename '. $sort, $item['value']);
200 while ($selection = db_fetch_object($selections)) {
201 $options[$selection->fid] = $selection->filename;
202 $link_path = file_create_url($selection->filepath);
203 $links[$selection->fid] = $link_path;
204 }
205 cck_download_dropdown_link_js($links, $item['value']);
206 $output = '';
207 $output .= '<form action="/cck_download_dropdown/get_file" method="post" id="cck_download_dropdown_field_formatter_'. $item['value'] .'" class="selector">';
208 $output .= '<SELECT name="cck_download_dropdown_'. $item['value'] .'" id="cck_download_dropdown_'. $item['value'] .'">';
209 $first = TRUE;
210 foreach ($options as $value => $label) {
211 if ($first == TRUE) {
212 $output .= '<option id="download_option_'. $item['value'] .'_'. $value .'" value="'. $value .'" selected="selected">'. $label .'</option>';
213 $link_path_start = $links[$value];
214 $first = FALSE;
215 }
216 else {
217 $output .= '<option id="download_option_'. $item['value'] .'_'. $value .'" value="'. $value .'">'. $label .'</option>';
218 }
219 }
220 $output .= '</SELECT>';
221 $output .= '<input type="submit" id="download_'. $item['value'] .'" value="Download">';
222 $image_path = drupal_get_path('module', 'cck_download_dropdown');
223 $output .= '<a href="'. $link_path_start .'" target="_blank" id="download_link_'. $item['value'] .'"><img src="/'. $image_path .'/disk.png" id="download_button_'. $item['value'] .'" class="hideme" /></a>';
224 $output .= '<input type="hidden" name="nid" value="'. $node->nid .'">';
225 $output .= '<input type="hidden" name="source_nid" value="'. $item['value'] .'">';
226 $output .= '</form>';
227 return $output;
228 }
229 } // function cck_download_dropdown_field_formatter()
230
231 /**
232 * Implementation of hook_widget_info().
233 *
234 * @return
235 * An array keyed by widget name. Each element of the array is an associative
236 * array with these keys and values:
237 * - "label": The human-readable label for the widget.
238 * - "field types": An array of field type names that can be edited using
239 * this widget.
240 */
241 function cck_download_dropdown_widget_info() {
242 return array(
243 'cck_download_dropdown' => array(
244 'label' => 'Download dropdown node',
245 'field types' => array('cck_download_dropdown'),
246 ),
247 );
248 } //function cck_download_dropdown_widget_info()
249
250 /**
251 * Implementation of hook_widget_settings().
252 *
253 * @param $op
254 * The operation to be performed.
255 * @param $widget
256 * The widget on which the operation is to be performed.
257 * @return
258 * This varies depending on the operation.
259 * - "form": an array of form elements to add to the settings page.
260 * - "validate": no return value. Use form_set_error().
261 * - "save": an array of names of form elements to be saved in the database.
262 * - "callbacks": an array describing the widget's behaviour regarding hook_widget
263 * operations. The array is keyed by hook_widget operations ('form', 'validate'...)
264 * and has the following possible values :
265 * CONTENT_CALLBACK_NONE : do nothing for this operation
266 * CONTENT_CALLBACK_CUSTOM : use the behaviour in hook_widget(operation)
267 * CONTENT_CALLBACK_DEFAULT : use content.module's default bahaviour
268 * Note : currently only the 'default value' operation implements this feature.
269 * All other widget operation implemented by the module _will_ be executed
270 * no matter what.
271 */
272 function cck_download_dropdown_widget_settings($op, $widget) {
273 switch ($op) {
274 case 'form':
275 $form = array();
276 $form['list_order'] = array(
277 '#type' => 'radios',
278 '#title' => t('List order'),
279 '#default_value' => isset($widget['list_order']) ? $widget['list_order'] : 0,
280 '#options' => array(t('Ascending'), t('Descending')),
281 '#description' => t('Which direction should this file list be sorted?'),
282 '#required' => TRUE,
283 );
284 $form['description'] = array(
285 '#type' => 'textfield',
286 '#title' => t('Description'),
287 '#default_value' => isset($widget['description']) ? $widget['description'] : 0,
288 '#description' => t('Give the user a hint as to what node they should select.'),
289 '#required' => FALSE,
290 );
291 return $form;
292
293 case 'save':
294 return array('list_order', 'description');
295
296 case 'callbacks':
297 return array(
298 'default value' => CONTENT_CALLBACK_CUSTOM,
299 );
300 }
301 } //function cck_download_dropdown_widget_settings()
302
303 /**
304 * Implementation of hook_widget().
305 *
306 * @param $op
307 * What kind of action is being performed.
308 * @param &$node
309 * The node the action is being performed on.
310 * @param $field
311 * The field the action is being performed on.
312 * @param &$node_field
313 * The contents of the field in this node. Changes to this variable will
314 * be saved back to the node object.
315 * @return
316 * This varies depending on the operation.
317 * - The "form" operation should return an array of form elements to display.
318 * - Other operations have no return value.
319 */
320 function cck_download_dropdown_widget($op, &$node, $field, &$items) {
321 switch ($op) {
322 case 'form':
323 $possible_nodes = db_query('SELECT DISTINCT n.nid, n.title FROM {node} n INNER JOIN {files} f ON n.nid = f.nid ORDER BY n.title');
324 while ($option = db_fetch_object($possible_nodes)) {
325 $options[$option->nid] = $option->title;
326 }
327 $form = array();
328 $form[$field['field_name']] = array('#tree' => TRUE);
329 $form[$field['field_name']][0]['value'] = array(
330 '#type' => 'select',
331 '#title' => t($field['widget']['label']),
332 '#multiple' => FALSE,
333 '#options' => $options,
334 '#required' => TRUE,
335 '#default_value' => $items[0]['value'],
336 '#description' => $field['widget']['description'],
337 );
338 return $form;
339 }
340 } // function cck_download_dropdown_widget_settings()
341
342 //-----------------------------------------Support Functions-------------------------------------
343 //-----------------------------------------Support Functions-------------------------------------
344 //-----------------------------------------Support Functions-------------------------------------
345
346 /**
347 * Javascript and such to support the changing of the download links dynamically
348 * based on the choices in the drop down lists
349 *
350 * @param array $links A keyed array of fid => filepath pairs
351 * @param string $value The node ID tied to the current drop down.
352 * @return string The javascript to place inline on the page for one drop down.
353 */
354 function cck_download_dropdown_link_js($links, $value) {
355 $js_output = '';
356 $js_output .= "
357 if (Drupal.jsEnabled) {
358 $(document).ready(function(){
359 $('#download_". $value ."').addClass('hideme');
360 $('#download_button_". $value ."').addClass('showme');
361 var allLinks = ". drupal_to_js($links) .";
362 $('#cck_download_dropdown_". $value ."').change(function(){
363 var newSelection = this.value;
364 $('#cck_download_dropdown_". $value ." option').removeAttr('selected');
365 $('#download_link_". $value ."').attr('href', allLinks[newSelection]);
366 $('#download_option_". $value ."_' + newSelection).attr('selected', 'selected');
367 });
368 });
369 }
370 ";
371 $css_path = drupal_get_path('module', 'cck_download_dropdown');
372 drupal_add_css($css_path .'/cck_download_dropdown.css', 'module', 'all', FALSE);
373 return drupal_add_js($js_output, 'inline', 'header');
374 } // function cck_download_dropdown_link_js()
375
376 /**
377 * If javascript isn't enabled, this should allow the download button to work. The only unfortunate
378 * thing is that the download won't open in a new window and the user will have to browse back for
379 * more downloads.
380 */
381 function cck_download_dropdown_get_file() {
382 global $_POST;
383 $start = reset($_POST);
384 $container_nid = $_POST['source_nid'];
385 $fid = $_POST['cck_download_dropdown_'.$container_nid];
386 $file_path = db_fetch_object(db_query('SELECT filepath, filename FROM {files} WHERE fid = %d AND nid = %d', $fid, $container_nid));
387 $users_path = file_create_url($file_path->filepath);
388 drupal_goto($users_path);
389 //the following doesn't work - would be nice to open the above in a new window... oh, well
390 drupal_set_message('<pre>Downloading... ' .print_r($file_path->filename, TRUE). '</pre>');
391 drupal_goto("node/". $_POST['nid']);
392 } // function cck_download_dropdown_get_file()
393
394 //-----------------------------------------Misc Drupal Hooks-------------------------------------
395 //-----------------------------------------Misc Drupal Hooks-------------------------------------
396 //-----------------------------------------Misc Drupal Hooks-------------------------------------
397
398 /**
399 * We can't presently handle multiple drop downs as a single field so remove the option of multiples;
400 * It actually doesn't make sense to have multiples in a single field does it? Currently, you can
401 * create multiple fields, each with a single drop down.
402 *
403 * @param string $form_id
404 * @param array $form
405 */
406 function cck_download_dropdown_form_alter($form_id, &$form) {
407 if ($form_id == '_content_admin_field' && $form['field_type']['#value'] == 'cck_download_dropdown') {
408 $form['field']['multiple']['#access'] = FALSE;
409 }
410 } // function cck_download_dropdown_form_alter()

  ViewVC Help
Powered by ViewVC 1.1.2