/[drupal]/contributions/modules/mediafield/audiofield.module
ViewVC logotype

Contents of /contributions/modules/mediafield/audiofield.module

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


Revision 1.11 - (show annotations) (download) (as text)
Thu Jun 26 09:38:36 2008 UTC (17 months ago) by acm
Branch: MAIN
CVS Tags: DRUPAL-5--1-01-RC1, DRUPAL-5--1-1, HEAD
Changes since 1.10: +5 -10 lines
File MIME type: text/x-php
fixing upper case extension bug (http://drupal.org/node/234469) and improving theme_[audio/video]field_icon() functions.
1 <?php
2
3 /**
4 * Implementation of hook_field_info().
5 */
6 function audiofield_field_info() {
7 return array(
8 'file_audio' => array('label' => 'Audio file'),
9 );
10 }
11
12 /**
13 * Implementation of hook_field_settings().
14 */
15 function audiofield_field_settings($op, $field) {
16 switch ($op) {
17 case 'form':
18 $form = array();
19 return $form;
20
21 case 'validate':
22 break;
23
24 case 'save':
25 return array('sample_rate', 'bitrate', 'channel_mode', 'playtime');
26
27 case 'database columns':
28 $columns = array(
29 'fid' => array('type' => 'int', 'not null' => TRUE, 'default' => '0'),
30 'sample_rate' => array('type' => 'int', length => 10, 'not null' => FALSE),
31 'bitrate' => array('type' => 'float unsigned', 'not null' => FALSE),
32 'channel_mode' => array('type' => 'varchar', length => 10, 'not null' => FALSE),
33 'playtime' => array('type' => 'varchar', length => 10, 'not null' => FALSE),
34 );
35 return $columns;
36 }
37 }
38
39 /**
40 * Implementation of hook_field().
41 */
42 function audiofield_field($op, $node, $field, &$node_field, $a1, $a2) {
43 require_once(drupal_get_path('module', 'audiofield') .'/multimediafile.inc');
44 $fieldname = $field['field_name'];
45 switch ($op) {
46 case 'load':
47 $output = array();
48 if (count($node_field)) {
49 $values = array();
50 foreach ($node_field as $delta => $file) {
51 if (!empty($file)) {
52 $values[$delta] = array_merge($node_field[$delta], _field_file_load($file['fid']));
53 $node_field[$delta] = $values[$delta];
54 }
55 $output = array($fieldname => $values);
56 }
57 }
58 break;
59
60 case 'view':
61 $files = array();
62 foreach ($node_field as $delta => $item) {
63 $node_field[$delta]['view'] = content_format($field, $item, 'default');
64 }
65 $output = theme('field', $node, $field, $node_field, $a1, $a2);
66 break;
67
68 case 'insert':
69 foreach ($node_field as $delta => $item) {
70 $node_field[$delta] = _field_file_insert($node, $item, $field);
71 }
72 break;
73
74 case 'update':
75 foreach ($node_field as $delta => $item) {
76 $node_field[$delta] = _field_file_update($node, $item, $field);
77 }
78 break;
79
80 case 'delete':
81 foreach ($node_field as $delta => $item) {
82 _field_file_delete($item, $field['field_name'], $field['type']);
83 }
84 break;
85 }
86 return $output;
87 }
88
89 /**
90 * Implementation of hook_widget_info().
91 */
92 function audiofield_widget_info() {
93 return array(
94 'audio' => array(
95 'label' => 'Audio file',
96 'field types' => array('file_audio'),
97 ),
98 );
99 }
100
101 /**
102 * Implementation of hook_widget_settings().
103 */
104 function audiofield_widget_settings($op, $widget) {
105 require_once(drupal_get_path('module', 'audiofield') .'/multimediafile.inc');
106 switch ($op) {
107 case 'form':
108 $form = array();
109 $form['upload_path'] = array(
110 '#type' => 'textfield',
111 '#title' => t('Path to save uploaded file to'),
112 '#default_value' => $widget['upload_path'] ? $widget['upload_path'] : '',
113 '#size' => 64,
114 '#description' => t('A directory where all files uploaded for this field instance will be saved. Example %ex.', array('%ex' => 'media/funny')),
115 '#after_build' => array('_file_form_check_directory')
116 );
117 $form['file_extensions'] = array(
118 '#type' => 'textfield',
119 '#title' => t('Permitted uploaded file extensions'),
120 '#default_value' => $widget['file_extensions'] ? $widget['file_extensions'] : 'mp3 wav mid',
121 '#size' => 64,
122 '#description' => t('Extensions a user can upload to this field. Enter separate extensions, in lower case, separating them with a space and do not include the leading dot.')
123 );
124 return $form;
125 case 'validate':
126 break;
127 case 'save':
128 return array('file_extensions', 'upload_path');
129 }
130 }
131
132 function _audiofield_widget_prepare_form_values(&$node, $field, &$node_field) {
133 $fieldname = $field['field_name'];
134 $type = $field['type'];
135 if (!count($_POST)) {
136 _field_clear_session($field['type']);
137 }
138
139 if ($file = file_check_upload($fieldname.'_upload')) {
140 $file = (array)$file;
141
142 $ext = strtolower(array_pop(explode('.', $file['filename'])));;
143 $allowed_extensions = array_unique(explode(' ', trim($field['widget']['file_extensions'])));
144 if (!in_array($ext, $allowed_extensions)) {
145 form_set_error($field['field_name'] .'_upload', t('Files with the extension %ext are not allowed. Please upload a file with an extension from the following list: %allowed_extensions.', array('%ext' => $ext, '%allowed_extensions' => $field['widget']['file_extensions'])));
146 return FALSE;
147 }
148
149 $file['upload_path'] = trim($field['widget']['upload_path']);
150
151 $file['fid'] = 'upload';
152 if (!$field['multiple']) {
153 if (is_array($node_field)) {
154 foreach ($node_field as $delta => $session_file) {
155 $node_field[$delta]['flags']['delete'] = TRUE;
156 }
157 }
158 _field_clear_field_session($fieldname, $field['type']);
159 }
160
161 // Add the file to the session
162 $file['sessionid'] = count($node_field) + count($_SESSION[$type][$fieldname]);
163 $_SESSION[$type][$fieldname][$file['sessionid']] = $file;
164 }
165
166 if (is_array($_SESSION[$type][$fieldname]) && count($_SESSION[$type][$fieldname])) {
167 foreach ($_SESSION[$type][$fieldname] as $delta => $file) {
168 $node_field[] = $file;
169 }
170 }
171 }
172
173 function _audiofield_widget_validate(&$node, $field, &$node_field) {
174 if ($field['required']) {
175 if (!count($node_field)) {
176 form_set_error($fieldname, t('Field %name is required', array('%name' => $field['widget']['label'])));
177 }
178 }
179 }
180
181 /**
182 * Implementation of hook_widget().
183 */
184 function audiofield_widget($op, &$node, $field, &$node_field) {
185 $fieldname = $field['field_name'];
186 $type = $field['type'];
187 require_once(drupal_get_path('module', 'audiofield') .'/multimediafile.inc');
188 switch ($op) {
189 case 'prepare form values':
190 _audiofield_widget_prepare_form_values($node, $field, $node_field);
191 break;
192
193 case 'form':
194 $form = _audiofield_widget_form($node, $field, $node_field);
195 return $form;
196
197 case 'validate':
198 _audiofield_widget_validate($node, $field, $node_field);
199 return;
200
201 case 'process form values':
202 break;
203 }
204 }
205
206 /**
207 * A helper function to build a widget form.
208 */
209 function _audiofield_widget_form($node, $field, &$node_field) {
210 drupal_add_js('misc/progress.js');
211 drupal_add_js('misc/upload.js');
212
213 $fieldname = $field['field_name'];
214 drupal_add_css(drupal_get_path('module', 'audiofield') .'/audiofield.css');
215
216 $form = array();
217 $form[$fieldname] = array(
218 '#type' => 'fieldset',
219 '#title' => t($field['widget']['label']),
220 '#weight' => $field['widget']['weight'],
221 '#collapsible' => TRUE,
222 '#collapsed' => FALSE,
223 '#tree' => TRUE,
224 '#prefix' => '<div id="'. form_clean_id($fieldname .'-attach-wrapper') .'">',
225 '#suffix' => '</div>',
226 '#theme' => 'audiofield_current',
227 );
228
229 $form[$fieldname]['new'] = array(
230 '#tree' => FALSE,
231 '#prefix' => '<div id="'. form_clean_id($fieldname .'-attach-hide') .'">',
232 '#suffix' => '</div>',
233 '#weight' => 100,
234 );
235
236 $form[$fieldname]['new'][$fieldname .'_upload'] = array(
237 '#type' => 'file',
238 '#description' => ($field['widget']['description'] ? $field['widget']['description']. '<br/>' : ''). t('Allowed extensions: %ext.', array('%ext' => $field['widget']['file_extensions'])),
239 '#weight' => 9,
240 '#tree' => FALSE,
241 );
242
243 $form[$fieldname]['new']['upload'] = array(
244 '#type' => 'button',
245 '#value' => t('Upload'),
246 '#name' => 'cck_audiofield_'. $fieldname .'_op',
247 '#id' => form_clean_id($fieldname .'-attach-button'),
248 '#tree' => FALSE,
249 '#weight' => 10,
250 );
251
252 if (is_array($node_field) && count($node_field)) {
253 foreach ($node_field as $delta => $file) {
254 if ($file['filepath'] && !$file['flags']['delete']) {
255 $form[$fieldname][$delta]['flags']['delete'] = array(
256 '#type' => 'checkbox',
257 '#default_value' => 0,
258 );
259
260 if ($file['filepath']) {
261 $form[$fieldname][$delta]['icon'] = array(
262 '#type' => 'markup',
263 '#value' => theme('audiofield_icon', $file),
264 );
265
266 if (strpos($file['fid'], 'upload') === false) {
267 $filepath = $file['filepath'];
268 } else {
269 $filepath = file_create_filename($file['filename'], file_create_path());
270 }
271
272 $path = $filepath;
273 if (strpos($file['fid'], 'upload') !== false) {
274 $path = $file['filepath'];
275 }
276
277 $info = audio_getid3_info($path);
278
279 $description = file_create_url($filepath);
280 $description = "<small>". check_plain($description) ."</small>";
281 $form[$fieldname][$delta]['name'] = array('#type' => 'markup', '#value' => (strlen($file['description'])) ? $file['description'] : $file['filename'], '#maxlength' => 256, '#description' => $description );
282 $form[$fieldname][$delta]['size'] = array('#type' => 'markup', '#value' => format_filesize($file['filesize']));
283
284 $form[$fieldname][$delta]['msample_rate'] = array('#type' => 'markup', '#value' => format_samplerate($info['sample_rate']));
285 $form[$fieldname][$delta]['mbitrate'] = array('#type' => 'markup', '#value' => format_bitrate($info['bitrate']));
286 $form[$fieldname][$delta]['mchannel_mode'] = array('#type' => 'markup', '#value' => $info['channelmode']);
287 $form[$fieldname][$delta]['mplaytime'] = array('#type' => 'markup', '#value' => $info['playtime'] .' min');
288
289 $form[$fieldname][$delta]['filename'] = array('#type' => 'value', '#value' => $file['filename']);
290 $form[$fieldname][$delta]['filepath'] = array('#type' => 'value', '#value' => $file['filepath']);
291 $form[$fieldname][$delta]['filemime'] = array('#type' => 'value', '#value' => $file['filemime']);
292 $form[$fieldname][$delta]['filesize'] = array('#type' => 'value', '#value' => $file['filesize']);
293 $form[$fieldname][$delta]['fid'] = array('#type' => 'value', '#value' => $file['fid']);
294
295 $form[$fieldname][$delta]['sample_rate'] = array('#type' => 'value', '#value' => $info['sample_rate']);
296 $form[$fieldname][$delta]['bitrate'] = array('#type' => 'value', '#value' => $info['bitrate']);
297 $form[$fieldname][$delta]['channel_mode'] = array('#type' => 'value', '#value' => $info['channelmode']);
298 $form[$fieldname][$delta]['playtime'] = array('#type' => 'value', '#value' => $info['playtime']);
299
300 // Special handling for single value fields
301 if (!$field['multiple']) {
302 $form[$fieldname][$delta]['replace'] = array(
303 '#type' => 'markup',
304 '#value' => t('If a new file is chosen, the current file will be replaced upon submitting the form.'),
305 );
306 }
307 }
308 } elseif ($file['filepath'] && $file['flags']['delete']) {
309 $form[$fieldname][$delta]['flags']['delete'] = array(
310 '#type' => 'hidden', // A value type will not persist here, must be hidden
311 '#value' => $file['flags']['delete'],
312 );
313 }
314 }
315 }
316 // The class triggers the js upload behaviour.
317 $form[$fieldname.'-attach-url'] = array(
318 '#type' => 'hidden',
319 '#value' => url('audiofield/js', NULL, NULL, TRUE),
320 '#attributes' => array('class' => 'upload'),
321 );
322
323 // Some useful info for our js callback.
324 $form['vid'] = array(
325 '#type' => 'hidden',
326 '#value' => $node->vid,
327 '#tree' => FALSE,
328 );
329 $form['nid'] = array(
330 '#type' => 'hidden',
331 '#value' => $node->nid,
332 '#tree' => FALSE,
333 );
334 $form['type'] = array(
335 '#type' => 'hidden',
336 '#value' => $node->type,
337 '#tree' => FALSE,
338 );
339 return $form;
340 }
341
342 /**
343 * Implementation of hook_field_formatter_info().
344 */
345 function audiofield_field_formatter_info() {
346 $formatters = array(
347 'default' => array(
348 'label' => t('Default'),
349 'field types' => array('file_audio'),
350 ),
351 );
352 return $formatters;
353 }
354
355 /**
356 * Implementation of hook_field_formatter().
357 */
358 function audiofield_field_formatter($field, $item, $formatter) {
359 require_once(drupal_get_path('module', 'audiofield') .'/multimediafile.inc');
360 if (!isset($item['fid'])) {
361 return '';
362 }
363 $file = _field_file_load($item['fid']);
364 return theme('audiofield', $file, $item, $field);
365 }
366
367 /**
368 * Read media information from the specified file.
369 */
370 function audio_getid3_info($path) {
371 $info = &mediafield_getid3_analyze($path);
372
373 $result['format_name'] = @$info['fileformat'];
374 $result['encoder_version'] = @$info['audio']['encoder'];
375 $result['encoder_options'] = @$info['audio']['encoder_options'];
376 $result['bitrate_mode'] = @$info['audio']['bitrate_mode'];
377 $result['bitrate'] = @$info['audio']['bitrate'];
378 $result['channelmode'] = @$info['audio']['channelmode'];
379 $result['sample_rate'] = @$info['audio']['sample_rate'];
380 $result['bits_per_sample'] = @$info['audio']['bits_per_sample'];
381 $result['playtime'] = @$info['playtime_string'];
382 $result['tags'] = @$info['tags'];
383 $result['comments'] = @$info['comments'];
384 $result['warning'] = @$info['warning'];
385
386 return $result;
387 }
388
389 /**
390 * A themed output for a currently uploaded file (used on a node edit form).
391 *
392 * @param array $form
393 * A form array.
394 */
395 function theme_audiofield_current(&$form) {
396 $header = array(t('Type'), t('Filename'), t('Sample rate'), t('Bitrate'), t('Channels'), t('Playtime'), t('Size'), t('Delete'));
397 $output = '';
398
399 foreach (element_children($form) as $key) {
400 if (is_numeric($key)) {
401 if (!($form[$key]['flags']['delete']['#type'] == 'hidden')) {
402 $row = array();
403 $row[] = drupal_render($form[$key]['icon']);
404 $row[] = drupal_render($form[$key]['name']);
405 $row[] = drupal_render($form[$key]['msample_rate']);
406 $row[] = drupal_render($form[$key]['mbitrate']);
407 $row[] = drupal_render($form[$key]['mchannel_mode']);
408 $row[] = drupal_render($form[$key]['mplaytime']);
409 $row[] = drupal_render($form[$key]['size']);
410 $row[] = drupal_render($form[$key]['flags']);
411 $rows[] = $row;
412 } else {
413 $output = drupal_render($form[$key]['flags']);
414 }
415 }
416 }
417 if (count($rows)) {
418 $output .= theme('table', $header, $rows);
419 }
420 if (count($rows) == 1) {
421 $output .= drupal_render($form[0]['replace']);
422 }
423
424 $output .= drupal_render($form);
425 return $output;
426 }
427
428 /**
429 * A themed output for an icon representing a file type.
430 *
431 * @param unknown_type $file
432 * @return unknown
433 */
434 function theme_audiofield_icon($file) {
435 $ext = strtolower(array_pop(explode('.', $file['filename'])));;
436
437 $image = theme('image', _file_get_resource_path($ext, 'audiofield', 'png', 'audio'));
438
439 return <<<OUTPUT
440 <div class="audiofield-icon icon-$ext">
441 $image
442 </div>
443 OUTPUT;
444 }
445
446 /*function theme_audiofield_view_file($file, $item, $field) {
447 return theme('audiofield', $file);
448 }*/
449
450 /**
451 * Themed output for audiofield on a node view page. Called from formatter hook.
452 */
453 function theme_audiofield($file, $item, $field) {
454 $file = (array)$file;
455 if (is_file($file['filepath'])) {
456 if ($file['fid'] == 'upload') {
457 $path = file_create_filename($file['filename'], file_create_path());
458 } else {
459 $path = $file['filepath'];
460 }
461 $name = $file['filename'];
462 $desc = $file['description'];
463
464 $item['sample_rate'] = format_samplerate($item['sample_rate']);
465 $item['bitrate'] = format_bitrate($item['bitrate']);
466 $item['filesize'] = format_filesize($item['filesize']);
467 $url = l($name, file_create_url($path));
468
469 $info = sprintf("<div> %s %s min %s %s (%s) </div>", $item['sample_rate'], $item['bitrate'], $url, $item['playtime'], $item['filesize']);
470
471 return $info;
472 }
473 }
474
475 /**
476 * Menu callback for JavaScript-based uploads.
477 */
478 function audiofield_js() {
479 // Parse fieldname from submit button.
480 $matches = array();
481 foreach(array_keys($_POST) as $key) {
482 if (preg_match('/cck_audiofield_(.*)_op/', $key, $matches)) {
483 $fieldname = $matches[1];
484 break;
485 }
486 }
487
488 $node = (object)$_POST;
489 $field = content_fields($fieldname, $node->type); // load field data
490
491 // Load fids stored by content.module.
492 $node_field = array();
493 $values = content_field('load', $node, $field, $node_field, FALSE, FALSE);
494 $node_field = $values[$fieldname];
495
496 // Load additional field data.
497 audiofield_field('load', $node, $field, $node_field, FALSE, FALSE);
498
499 // Handle uploads and validation.
500 _audiofield_widget_prepare_form_values($node, $field, $node_field);
501 _audiofield_widget_validate($node, $field, $node_field);
502
503 // Get our new form baby, yeah tiger, get em!
504 $form = _audiofield_widget_form($node, $field, $node_field);
505
506 foreach (module_implements('form_alter') as $module) {
507 $function = $module .'_form_alter';
508 $function('audiofield_js', $form);
509 }
510 $form = form_builder('audiofield_js', $form);
511
512 $output = theme('status_messages') . drupal_render($form);
513
514 // Send the updated file attachments form.
515 print drupal_to_js(array('status' => TRUE, 'data' => $output));
516 exit();
517 }
518
519 function audiofield_menu($may_cache) {
520 $items = array();
521
522 if (!$may_cache) {
523 $items[] = array(
524 'path' => 'audiofield/js',
525 'callback' => 'audiofield_js',
526 //'access' => user_access(),
527 'access' => TRUE,
528 'type' => MENU_CALLBACK
529 );
530 }
531 return $items;
532 }

  ViewVC Help
Powered by ViewVC 1.1.2