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

Contents of /contributions/modules/mediafield/videofield.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: +6 -11 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 videofield_field_info() {
7 return array(
8 'file_video' => array('label' => 'Video file'),
9 );
10 }
11
12 /**
13 * Implementation of hook_field_settings().
14 */
15 function videofield_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('fileformat', 'videox', 'videoy', 'bits_per_sample', 'videocodec', 'audiocodec', '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 'fileformat' => array('type' => 'varchar', length => 10, 'not null' => FALSE),
31 'videox' => array('type' => 'smallint', length => 4, 'not null' => TRUE, 'default' => '0'),
32 'videoy' => array('type' => 'smallint', length => 4, 'not null' => TRUE, 'default' => '0'),
33 'bits_per_sample' => array('type' => 'int', length => 10, 'not null' => FALSE),
34 'videocodec' => array('type' => 'varchar', length => 255, 'not null' => FALSE),
35 'audiocodec' => array('type' => 'varchar', length => 255, 'not null' => FALSE),
36 'sample_rate' => array('type' => 'int', length => 10, 'not null' => FALSE),
37 'channel_mode' => array('type' => 'varchar', length => 10, 'not null' => FALSE),
38 'playtime' => array('type' => 'varchar', length => 10, 'not null' => FALSE),
39 );
40 return $columns;
41 }
42 }
43
44 /**
45 * Implementation of hook_field().
46 */
47 function videofield_field($op, $node, $field, &$node_field, $a1, $a2) {
48 require_once(drupal_get_path('module', 'videofield') .'/multimediafile.inc');
49 $fieldname = $field['field_name'];
50 switch ($op) {
51 case 'load':
52 $output = array();
53 if (count($node_field)) {
54 $values = array();
55 foreach ($node_field as $delta => $file) {
56 if (!empty($file)) {
57 $values[$delta] = array_merge($node_field[$delta], _field_file_load($file['fid']));
58 $node_field[$delta] = $values[$delta];
59 }
60 $output = array($fieldname => $values);
61 }
62 }
63 break;
64
65 case 'view':
66 $files = array();
67 foreach ($node_field as $delta => $item) {
68 $node_field[$delta]['view'] = content_format($field, $item, 'default');
69 }
70 $output = theme('field', $node, $field, $node_field, $a1, $a2);
71 break;
72
73 case 'insert':
74 foreach ($node_field as $delta => $item) {
75 $node_field[$delta] = _field_file_insert($node, $item, $field);
76 }
77 break;
78
79 case 'update':
80 foreach ($node_field as $delta => $item) {
81 $node_field[$delta] = _field_file_update($node, $item, $field);
82 }
83 break;
84
85 case 'delete':
86 foreach ($node_field as $delta => $item) {
87 _field_file_delete($item, $field['field_name'], $field['type']);
88 }
89 break;
90 }
91 return $output;
92 }
93
94 /**
95 * Implementation of hook_widget_info().
96 */
97 function videofield_widget_info() {
98 return array(
99 'video' => array(
100 'label' => 'video file',
101 'field types' => array('file_video'),
102 ),
103 );
104 }
105
106 /**
107 * Implementation of hook_widget_settings().
108 */
109 function videofield_widget_settings($op, $widget) {
110 require_once(drupal_get_path('module', 'videofield') .'/multimediafile.inc');
111 switch ($op) {
112 case 'form':
113 $form = array();
114 $form['upload_path'] = array(
115 '#type' => 'textfield',
116 '#title' => t('Path to save uploaded file to'),
117 '#default_value' => $widget['upload_path'] ? $widget['upload_path'] : '',
118 '#size' => 64,
119 '#description' => t('A directory where all files uploaded for this field instance will be saved. Example %ex.', array('%ex' => 'media/funny')),
120 '#after_build' => array('_file_form_check_directory')
121 );
122 $form['file_extensions'] = array(
123 '#type' => 'textfield',
124 '#title' => t('Permitted uploaded file extensions'),
125 '#default_value' => $widget['file_extensions'] ? $widget['file_extensions'] : 'avi mpg ogg wmv',
126 '#size' => 64,
127 '#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.')
128 );
129 return $form;
130 case 'validate':
131 break;
132 case 'save':
133 return array('file_extensions', 'upload_path');
134 }
135 }
136
137 function _videofield_widget_prepare_form_values(&$node, $field, &$node_field) {
138 $fieldname = $field['field_name'];
139 $type = $field['type'];
140 if (!count($_POST)) {
141 _field_clear_session($type);
142 }
143
144 if ($file = file_check_upload($fieldname .'_upload')) {
145 $file = (array)$file;
146
147 $ext = strtolower(array_pop(explode('.', $file['filename'])));
148 $allowed_extensions = array_unique(explode(' ', trim($field['widget']['file_extensions'])));
149 if (!in_array($ext, $allowed_extensions)) {
150 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'])));
151 return FALSE;
152 }
153
154 $file['upload_path'] = trim($field['widget']['upload_path']);
155
156 $file['fid'] = 'upload';
157 if (!$field['multiple']) {
158 if (is_array($node_field)) {
159 foreach ($node_field as $delta => $session_file) {
160 $node_field[$delta]['flags']['delete'] = TRUE;
161 }
162 }
163 _field_clear_field_session($fieldname, $field['type']);
164 }
165
166 // Add the file to the session
167 $file['sessionid'] = count($node_field) + count($_SESSION[$type][$fieldname]);
168 $_SESSION[$type][$fieldname][$file['sessionid']] = $file;
169 }
170
171 if (is_array($_SESSION[$type][$fieldname]) && count($_SESSION[$type][$fieldname])) {
172 foreach ($_SESSION[$type][$fieldname] as $delta => $file) {
173 $node_field[] = $file;
174 }
175 }
176 }
177
178 function _videofield_widget_validate(&$node, $field, &$node_field) {
179 if ($field['required']) {
180 if (!count($node_field)) {
181 form_set_error($fieldname, $field['widget']['label'] .' is required.');
182 }
183 }
184 }
185
186 /**
187 * Implementation of hook_widget().
188 */
189 function videofield_widget($op, &$node, $field, &$node_field) {
190 require_once(drupal_get_path('module', 'videofield') .'/multimediafile.inc');
191 $fieldname = $field['field_name'];
192 $type = $field['type'];
193 switch ($op) {
194 case 'prepare form values':
195 _videofield_widget_prepare_form_values($node, $field, $node_field);
196 break;
197
198 case 'form':
199 $form = _videofield_widget_form($node, $field, $node_field);
200 return $form;
201
202 case 'validate':
203 _videofield_widget_validate($node, $field, $node_field);
204 return;
205
206 case 'process form values':
207 break;
208 }
209 }
210
211 function _videofield_widget_form($node, $field, &$node_field) {
212 drupal_add_js('misc/progress.js');
213 drupal_add_js('misc/upload.js');
214
215 $fieldname = $field['field_name'];
216 drupal_add_css(drupal_get_path('module', 'videofield') .'/videofield.css');
217
218 $form = array();
219 $form[$fieldname] = array(
220 '#type' => 'fieldset',
221 '#title' => t($field['widget']['label']),
222 '#weight' => $field['widget']['weight'],
223 '#collapsible' => TRUE,
224 '#collapsed' => FALSE,
225 '#tree' => TRUE,
226 '#theme' => 'videofield_current',
227 '#prefix' => '<div id="'. form_clean_id($fieldname .'-attach-wrapper') .'">',
228 '#suffix' => '</div>',
229 );
230
231 $form[$fieldname]['new'] = array(
232 '#tree' => FALSE,
233 '#prefix' => '<div id="'. form_clean_id($fieldname .'-attach-hide') .'">',
234 '#suffix' => '</div>',
235 '#weight' => 100,
236 );
237
238 $form[$fieldname]['new'][$fieldname .'_upload'] = array(
239 '#type' => 'file',
240 '#description' => ($field['widget']['description'] ? $field['widget']['description']. '<br/>' : ''). t('Allowed extensions: %ext.', array('%ext' => $field['widget']['file_extensions'])),
241 '#weight' => 9,
242 '#tree' => FALSE,
243 );
244
245 $form[$fieldname]['new']['upload'] = array(
246 '#type' => 'button',
247 '#value' => t('Upload'),
248 '#name' => 'cck_videofield_'. $fieldname .'_op',
249 '#id' => form_clean_id($fieldname .'-attach-button'),
250 '#tree' => FALSE,
251 '#weight' => 10,
252 );
253
254 if (is_array($node_field) && count($node_field)) {
255 foreach ($node_field as $delta => $file) {
256 if ($file['filepath'] && !$file['flags']['delete']) {
257 $form[$fieldname][$delta]['flags']['delete'] = array(
258 '#type' => 'checkbox',
259 '#default_value' => 0,
260 );
261
262 if ($file['filepath']) {
263 $form[$fieldname][$delta]['icon'] = array(
264 '#type' => 'markup',
265 '#value' => theme('videofield_icon', $file),
266 );
267
268 if (strpos($file['fid'], 'upload') === false) {
269 $filepath = $file['filepath'];
270 } else {
271 $filepath = file_create_filename($file['filename'], file_create_path());
272 }
273
274 $path = $filepath;
275 if (strpos($file['fid'], 'upload') !== false) {
276 $path = $file['filepath'];
277 }
278
279 $info = video_getid3_info($path);
280
281 $description = file_create_url($filepath);
282 $description = "<small>". check_plain($description) ."</small>";
283 $form[$fieldname][$delta]['name'] = array('#type' => 'markup', '#value' => (strlen($file['description'])) ? $file['description'] : $file['filename'], '#maxlength' => 256, '#description' => $description );
284 $form[$fieldname][$delta]['size'] = array('#type' => 'markup', '#value' => format_filesize($file['filesize']));
285
286 $form[$fieldname][$delta]['mfileformat'] = array('#type' => 'markup', '#value' => $info['fileformat']);
287 $form[$fieldname][$delta]['mvideosize'] = array('#type' => 'markup', '#value' => $info['videox'] .'x'. $info['videoy']);
288 $form[$fieldname][$delta]['mbps'] = array('#type' => 'markup', '#value' => $info['bps']);
289 $form[$fieldname][$delta]['mvideocodec'] = array('#type' => 'markup', '#value' => $info['videocodec']);
290 $form[$fieldname][$delta]['maudiocodec'] = array('#type' => 'markup', '#value' => $info['audiocodec']);
291
292 $form[$fieldname][$delta]['msample_rate'] = array('#type' => 'markup', '#value' => format_samplerate($info['sample_rate']));
293 $form[$fieldname][$delta]['mchannel_mode'] = array('#type' => 'markup', '#value' => $info['channelmode']);
294 $form[$fieldname][$delta]['mplaytime'] = array('#type' => 'markup', '#value' => $info['playtime'] .' min');
295
296 $form[$fieldname][$delta]['filename'] = array('#type' => 'value', '#value' => $file['filename']);
297 $form[$fieldname][$delta]['filepath'] = array('#type' => 'value', '#value' => $file['filepath']);
298 $form[$fieldname][$delta]['filemime'] = array('#type' => 'value', '#value' => $file['filemime']);
299 $form[$fieldname][$delta]['filesize'] = array('#type' => 'value', '#value' => $file['filesize']);
300 $form[$fieldname][$delta]['fid'] = array('#type' => 'value', '#value' => $file['fid']);
301
302 $form[$fieldname][$delta]['fileformat'] = array('#type' => 'value', '#value' => $info['fileformat']);
303 $form[$fieldname][$delta]['videox'] = array('#type' => 'value', '#value' => $info['videox']);
304 $form[$fieldname][$delta]['videoy'] = array('#type' => 'value', '#value' => $info['videoy']);
305 $form[$fieldname][$delta]['bits_per_sample'] = array('#type' => 'value', '#value' => $info['bps']);
306 $form[$fieldname][$delta]['videocodec'] = array('#type' => 'value', '#value' => $info['videocodec']);
307 $form[$fieldname][$delta]['audiocodec'] = array('#type' => 'value', '#value' => $info['audiocodec']);
308
309 $form[$fieldname][$delta]['sample_rate'] = array('#type' => 'value', '#value' => $info['sample_rate']);
310 $form[$fieldname][$delta]['channel_mode'] = array('#type' => 'value', '#value' => $info['channelmode']);
311 $form[$fieldname][$delta]['playtime'] = array('#type' => 'value', '#value' => $info['playtime']);
312
313 // Special handling for single value fields
314 if (!$field['multiple']) {
315 $form[$fieldname][$delta]['replace'] = array(
316 '#type' => 'markup',
317 '#value' => t('If a new file is chosen, the current file will be replaced upon submitting the form.'),
318 '#weight' => 8,
319 );
320 }
321 }
322 } elseif ($file['filepath'] && $file['flags']['delete']) {
323 $form[$fieldname][$delta]['flags']['delete'] = array(
324 '#type' => 'hidden', // A value type will not persist here, must be hidden
325 '#value' => $file['flags']['delete'],
326 );
327 }
328 }
329 }
330 // The class triggers the js upload behaviour.
331 $form[$fieldname.'-attach-url'] = array(
332 '#type' => 'hidden',
333 '#value' => url('videofield/js', NULL, NULL, TRUE),
334 '#attributes' => array('class' => 'upload'),
335 );
336
337 // Some useful info for our js callback.
338 $form['vid'] = array(
339 '#type' => 'hidden',
340 '#value' => $node->vid,
341 '#tree' => FALSE,
342 );
343 $form['nid'] = array(
344 '#type' => 'hidden',
345 '#value' => $node->nid,
346 '#tree' => FALSE,
347 );
348 $form['type'] = array(
349 '#type' => 'hidden',
350 '#value' => $node->type,
351 '#tree' => FALSE,
352 );
353 return $form;
354 }
355
356 /**
357 * Implementation of hook_field_formatter_info().
358 */
359 function videofield_field_formatter_info() {
360 $formatters = array(
361 'default' => array(
362 'label' => t('Default'),
363 'field types' => array('file_video'),
364 ),
365 );
366 return $formatters;
367 }
368
369 /**
370 * Implementation of hook_field_formatter().
371 */
372 function videofield_field_formatter($field, $item, $formatter) {
373 require_once(drupal_get_path('module', 'videofield') .'/multimediafile.inc');
374 if (!isset($item['fid'])) {
375 return '';
376 }
377 $file = _field_file_load($item['fid']);
378 return theme('videofield', $file, $item, $field);
379 }
380
381 /**
382 * Read media information from the specified file.
383 */
384 function video_getid3_info($path) {
385 $info = &mediafield_getid3_analyze($path);
386
387 $other = @reset($info['video']['streams']);
388 $result['videox'] = @$other['resolution_x'];
389 $result['videoy'] = @$other['resolution_y'];
390 $result['bps'] = @$other['bits_per_sample'];
391 $result['videocodec'] = @$other['codec'];
392
393 $other = @reset($info['audio']['streams']);
394 $result['audiocodec'] = @$other['codec'];
395
396 $result['fileformat'] = @$info['video']['dataformat'];
397 $result['channelmode'] = @$info['audio']['channelmode'];
398 $result['sample_rate'] = @$info['audio']['sample_rate'];
399 $result['playtime'] = @$info['playtime_string'];
400
401 return $result;
402 }
403
404 /**
405 * A themed output for a currently uploaded file (used on a node edit form).
406 *
407 * @param array $form
408 * A form array.
409 */
410 function theme_videofield_current(&$form) {
411 $header = array(t('Type'), t('Filename'), t('Video'), t('Audio'), t('Playtime'), t('Size'), t('Delete'));
412 $output = '';
413
414 foreach (element_children($form) as $key) {
415 if (is_numeric($key)) {
416 if (!($form[$key]['flags']['delete']['#type'] == 'hidden')) {
417 $row = array();
418 $row[] = drupal_render($form[$key]['icon']);
419 $row[] = drupal_render($form[$key]['name']);
420 $row[] = drupal_render($form[$key]['mfileformat']) .','. drupal_render($form[$key]['mvideosize']) .','. drupal_render($form[$key]['mvideocodec']) .','. drupal_render($form[$key]['mbps']);
421 $row[] = drupal_render($form[$key]['msample_rate']) .','. drupal_render($form[$key]['mchannel_mode']) .','. drupal_render($form[$key]['maudiocodec']);
422 $row[] = drupal_render($form[$key]['mplaytime']);
423 $row[] = drupal_render($form[$key]['size']);
424 $row[] = drupal_render($form[$key]['flags']);
425 $rows[] = $row;
426 } else {
427 $output = drupal_render($form[$key]['flags']);
428 }
429 }
430 }
431 if (count($rows)) {
432 $output .= theme('table', $header, $rows);
433 }
434 if (count($rows) == 1) {
435 $output .= drupal_render($form[0]['replace']);
436 }
437
438 $output .= drupal_render($form);
439 return $output;
440 }
441
442 /**
443 * A themed output for an icon representing a file type.
444 *
445 * @param unknown_type $file
446 * @return unknown
447 */
448 function theme_videofield_icon($file) {
449 $ext = strtolower(array_pop(explode('.', $file['filename'])));;
450
451 $image = theme('image', _file_get_resource_path($ext, 'videofield', 'png', 'video'));
452
453 return <<<OUTPUT
454 <div class="videofield-icon icon-$ext">
455 $image
456 </div>
457 OUTPUT;
458 }
459
460 /*function theme_videofield_view_file($file, $item, $field) {
461 return theme('videofield', $file);
462 }*/
463
464 function theme_videofield($file, $item, $field) {
465 $file = (array)$file;
466 if (is_file($file['filepath'])) {
467 if ($file['fid'] == 'upload') {
468 $path = file_create_filename($file['filename'], file_create_path());
469 } else {
470 $path = $file['filepath'];
471 }
472 $name = $file['filename'];
473 $desc = $file['description'];
474 $url = l($name, file_create_url($path));
475
476 $rows = array();
477 $rows[] = array(
478 array('data' => t('Name')),
479 array('data' => $url),
480 );
481 $video = $item['fileformat'] .','. $item['videox'] .'x'. $item['videoy'] .','. $item['videocodec'] .','. $item['bits_per_sample'];
482 $rows[] = array(
483 array('data' => t('Video')),
484 array('data' => $video),
485 );
486 $audio = format_samplerate($item['sample_rate']) .','. $item['channel_mode'] .','. $item['audiocodec'];
487 $rows[] = array(
488 array('data' => t('Audio')),
489 array('data' => $audio),
490 );
491 $rows[] = array(
492 array('data' => t('Duration')),
493 array('data' => $item['playtime'] .' min'),
494 );
495 $rows[] = array(
496 array('data' => t('Size')),
497 array('data' => format_filesize($item['filesize'])),
498 );
499
500 return theme('table', array(), $rows);
501 }
502 }
503
504 /**
505 * Menu callback for JavaScript-based uploads.
506 */
507 function videofield_js() {
508 // Parse fieldname from submit button.
509 $matches = array();
510 foreach(array_keys($_POST) as $key) {
511 if (preg_match('/cck_videofield_(.*)_op/', $key, $matches)) {
512 $fieldname = $matches[1];
513 break;
514 }
515 }
516
517 $node = (object)$_POST;
518 $field = content_fields($fieldname, $node->type); // load field data
519
520 // Load fids stored by content.module.
521 $node_field = array();
522 $values = content_field('load', $node, $field, $node_field, FALSE, FALSE);
523 $node_field = $values[$fieldname];
524
525 // Load additional field data.
526 videofield_field('load', $node, $field, $node_field, FALSE, FALSE);
527
528 // Handle uploads and validation.
529 _videofield_widget_prepare_form_values($node, $field, $node_field);
530 _videofield_widget_validate($node, $field, $node_field);
531
532 // Get our new form baby, yeah tiger, get em!
533 $form = _videofield_widget_form($node, $field, $node_field);
534
535 foreach (module_implements('form_alter') as $module) {
536 $function = $module .'_form_alter';
537 $function('videofield_js', $form);
538 }
539 $form = form_builder('videofield_js', $form);
540
541 $output = theme('status_messages') . drupal_render($form);
542
543 // Send the updated file attachments form.
544 print drupal_to_js(array('status' => TRUE, 'data' => $output));
545 exit();
546 }
547
548 function videofield_menu($may_cache) {
549 $items = array();
550
551 if (!$may_cache) {
552 $items[] = array(
553 'path' => 'videofield/js',
554 'callback' => 'videofield_js',
555 //'access' => user_access(),
556 'access' => TRUE,
557 'type' => MENU_CALLBACK
558 );
559 }
560 return $items;
561 }

  ViewVC Help
Powered by ViewVC 1.1.2