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

Contents of /contributions/modules/node_media/node_media.module

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


Revision 1.1 - (show annotations) (download) (as text)
Mon Dec 31 08:48:28 2007 UTC (22 months, 3 weeks ago) by develCuy
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-5
File MIME type: text/x-php
First release of Node Media includes the following features:
- Upload mpeg videos
- Upload sounds(only upload)
- Limit number of uploads according to type: image, sound, video
- Some minor bug fixing
1 <?php
2 /**
3 * @file
4 * This module will add "Images" tab, "Videos" tab and "Sounds" tab to nodes, allowing users to upload media(images, video and sounds) and associate them with the current node.
5 * Requires upload.module
6 * The hook_node_media() allows to conditionally disable media for the specific node
7 */
8
9 /**
10 * Implementation of hook_perm().
11 */
12
13 function node_media_perm() {
14 return array('create node media', 'administer node media');
15 }
16
17 /**
18 * Implementation of hook_menu().
19 */
20 function node_media_menu($may_cache) {
21 $items = array();
22 $access = user_access('create node media');
23 $admin = user_access('administer site configuration');
24
25 if ($may_cache) {
26 $items[] = array('path' => 'admin/settings/node_media',
27 'title' => t('node media'),
28 'description' => t('Control how to upload node media.'),
29 'callback' => 'drupal_get_form',
30 'callback arguments' => array('node_media_admin_settings'),
31 'access' => $admin
32 );
33 $items[] = array(
34 'path' => 'node_media/js',
35 'callback' => '_node_media_js',
36 'access' => $access,
37 'type' => MENU_CALLBACK
38 );
39 } else {
40 if (arg(0) == 'node' && is_numeric(arg(1))) {
41 $node = node_load(arg(1));
42 if ($node->nid && variable_get('node_media_position_'.$node->type, 'hide') != 'hide') {
43 $items[] = array(
44 'path' => 'node/' . arg(1) . '/media',
45 'title' => t('Media'),
46 'callback' => '_node_media_edit_form',
47 'callback arguments' => array($node),
48 'access' => $access && node_access('update', $node),
49 'type' => MENU_LOCAL_TASK,
50 'weight' => 2
51 );
52 $items[] = array(
53 'path' => 'node/' . arg(1) . '/image_gallery',
54 'title' => t('Image gallery'),
55 'callback' => '_node_media_image_gallery',
56 'callback arguments' => array($node),
57 'access' => count($node->node_media[0]) && node_access('view', $node),
58 'type' => variable_get('node_media_gallery_tabs_'.$node->type, TRUE) ? MENU_LOCAL_TASK : MENU_CALLBACK
59 );
60 $items[] = array(
61 'path' => 'node/' . arg(1) . '/video_gallery',
62 'title' => t('Video gallery'),
63 'callback' => '_node_media_video_gallery',
64 'callback arguments' => array($node),
65 'access' => count($node->node_media[1]) && node_access('view', $node),
66 'type' => variable_get('node_media_gallery_tabs_'.$node->type, TRUE) ? MENU_LOCAL_TASK : MENU_CALLBACK
67 );
68 $items[] = array(
69 'path' => 'node/' . arg(1) . '/sound_gallery',
70 'title' => t('Sound gallery'),
71 'callback' => '_node_media_sound_gallery',
72 'callback arguments' => array($node),
73 'access' => count($node->node_media[2]) && node_access('view', $node),
74 'type' => variable_get('node_media_gallery_tabs_'.$node->type, TRUE) ? MENU_LOCAL_TASK : MENU_CALLBACK
75 );
76 }
77 }
78 }
79
80 return $items;
81 }
82
83 /**
84 * implementation of hook_form_alter()
85 */
86 function node_media_form_alter($form_id, &$form) {
87 $type = $form['#node_type']->type;
88 if ($form_id == 'node_type_form' && isset($form['identity']['type'])) {
89 // radio button in the node's content type configuration page
90 _node_media_check_settings();
91 $form['node_media'] = array(
92 '#type' => 'fieldset',
93 '#title' => t('node media'),
94 '#collapsible' => TRUE,
95 );
96 $form['node_media']['node_media_position'] = array(
97 '#type' => 'radios',
98 '#title' => t('Position'),
99 '#default_value' => variable_get('node_media_position_'.$type, 'hide'),
100 '#options' => array('hide' => t('Do not show'), 'above' => t('Show above node body'), 'below' => t('Show below node body'),
101 'node_template' => t('Manually set in node template by variable $node->node_media')),
102 '#description' => t('The position of images in the node view.'),
103 );
104 $form['node_media']['node_media_gallery_link'] = array(
105 '#type' => 'radios',
106 '#title' => t('Link to image gallery'),
107 '#default_value' => variable_get('node_media_gallery_link_'.$type, TRUE),
108 '#options' => array(t('Do not show'), t('Show')),
109 '#description' => t('Choose whether to show or not the link to the image gallery.'),
110 );
111 $form['node_media']['node_media_gallery_tabs'] = array(
112 '#type' => 'radios',
113 '#title' => t('Media galleries tabs'),
114 '#default_value' => variable_get('node_media_gallery_tabs_'.$type, TRUE),
115 '#options' => array(t('Do not show'), t('Show')),
116 '#description' => t('Choose whether to show or not the tabs to the media galleries.'),
117 );
118 $form['node_media']['node_media_gallery_display_node_details'] = array(
119 '#type' => 'radios',
120 '#title' => t('Node details in media galleries'),
121 '#default_value' => variable_get('node_media_gallery_display_node_details_'.$type, TRUE),
122 '#options' => array(t('Do not show'), t('Show')),
123 '#description' => t('Choose whether to show or not the node details into media galleries.'),
124 );
125 $form['node_media']['node_media_teaser_images'] = array(
126 '#type' => 'textfield',
127 '#title' => t('Number of images in node teaser'),
128 '#default_value' => variable_get('node_media_teaser_images_'.$type, 2),
129 '#size' => 5,
130 '#maxlength' => 2,
131 '#description' => t('The maximum number of images to show in the node teaser. 0 will not show images. Leave blank to show all images.'),
132 );
133 $form['node_media']['node_media_body_images'] = array(
134 '#type' => 'textfield',
135 '#title' => t('Number of images in node body'),
136 '#size' => 5,
137 '#maxlength' => 2,
138 '#default_value' => variable_get('node_media_body_images_'.$type, NULL),
139 '#description' => t('The maximum number of images to show in the node body. 0 will not show images. Leave blank to show all images.'),
140 );
141 $form['node_media']['node_media_teaser_format'] = array(
142 '#type' => 'radios',
143 '#title' => t('Image format in node teaser'),
144 '#default_value' => variable_get('node_media_teaser_format_'.$type, 'thumbs'),
145 '#options' => array('thumbs' => t('Thumbnails'), 'fullsize' => t('Full size images')),
146 '#description' => t('Image format in node teaser.'),
147 );
148 $form['node_media']['node_media_body_format'] = array(
149 '#type' => 'radios',
150 '#title' => t('Image format in node body'),
151 '#default_value' => variable_get('node_media_body_format_'.$type, 'thumbs'),
152 '#options' => array('thumbs' => t('Thumbnails'), 'fullsize' => t('Full size images')),
153 '#description' => t('Image format in node body.'),
154 );
155
156 $form['submit']['#weight'] = 30;
157 $form['delete']['#weight'] = 31;
158 $form['reset']['#weight'] = 32;
159 }
160 }
161
162 /**
163 * Implementation of hook_nodeapi().
164 */
165 function node_media_nodeapi(&$node, $op, $teaser, $page) {
166 // test if images are allowed for this node
167 if ($op == 'load' || $op == 'view') {
168 if (variable_get('node_media_position_'.$node->type, 'hide') == 'hide') return;
169
170 // fire an additional hook for the specific node type
171 // i.e. node media might be a pro feature, so only subscribed users can view them
172 // if the hook is not present in the node type module, images are loaded by default
173 $show = module_invoke($node->type, 'node_media', $op, $node);
174 if ($show === FALSE) return;
175 }
176
177 switch ($op) {
178 case 'load':
179 // load node media for the current node
180 $sql = db_query('SELECT * FROM {node_media} WHERE nid=%d AND status=1 ORDER BY type,weight', $node->nid);
181 while ($r = db_fetch_object($sql)) {
182 $node->node_media[$r->type][$r->id] = $r;
183 }
184 break;
185
186 case 'insert':
187 if (user_access('create node media') && node_access('update', $node) &&
188 variable_get('node_media_position_'.$node->type, 'hide') != 'hide') {
189 drupal_set_message(t('Click the <strong>media</strong> tab to add images, videos and sounds to this node.',
190 array(
191 '!images' => l(t('images'), 'node/'.$node->nid.'/images')/*,
192 '!videos' => l(t('videos'), 'node/'.$node->nid.'/videos'),
193 '!sounds' => l(t('sounds'), 'node/'.$node->nid.'/sounds')*/
194 )));
195 }
196 break;
197
198 case 'delete':
199 // Delete image and thumbnail files
200 $sql = db_query('SELECT filepath, thumbpath FROM {node_media} WHERE nid=%d', $node->nid);
201 while ($r = db_fetch_object($sql)) {
202 file_delete($r->filepath);
203 file_delete($r->thumbpath);
204 }
205 // Delete all images associated with the node
206 db_query('DELETE FROM {node_media} WHERE nid=%d', $node->nid);
207 break;
208
209 case 'view':
210 if (empty($node->node_media)) return;
211
212 // search for a themed view for the current node type
213 $nodetype_function = 'theme_'.$node->type.'_node_media_view';
214 if (function_exists($nodetype_function)) {
215 $output = $nodetype_function($node, $teaser, $page);
216 }
217 else {
218 // use the default theme function
219 $output = theme('node_media_view', $node, $teaser, $page);
220 }
221 $node->node_media = $output;
222
223 $output = '<div class="node_media">'.$output[0].'</div>';
224 $position = variable_get('node_media_position_'.$node->type, 'hide');
225 switch ($position) {
226 case 'node_template':
227 case 'hide':
228 break;
229
230 case 'above':
231 $node->content['node_media'] = array('#value' => $output, '#weight' => -1);
232 break;
233
234 default:
235 $node->content['node_media'] = array('#value' => $output, '#weight' => 1);
236 break;
237 }
238 return $node;
239 }
240 }
241
242 /**
243 * Implementation of hook_link().
244 */
245 function node_media_link($type, $node = null, $teaser = false) {
246 $links = array();
247
248 if ($type == 'node' && $node->nid && variable_get('node_media_position_'.$node->type, 'hide') != 'hide') {
249 if ($node->node_media[0] && variable_get('node_media_gallery_link_'.$node->type, TRUE)) {
250 $links['node_media_image_gallery'] = array(
251 'title' => t('Open the image gallery'),
252 'href' => "node/$node->nid/image_gallery",
253 );
254 }
255
256 if ($node->node_media[1] && variable_get('node_media_gallery_link_'.$node->type, TRUE)) {
257 $links['node_media_video_gallery'] = array(
258 'title' => t('Open the video gallery'),
259 'href' => "node/$node->nid/video_gallery",
260 );
261 }
262
263 if ($node->node_media[2] && variable_get('node_media_gallery_link_'.$node->type, TRUE)) {
264 $links['node_media_sound_gallery'] = array(
265 'title' => t('Open the sound gallery'),
266 'href' => "node/$node->nid/sound_gallery",
267 );
268 }
269 }
270
271 return $links;
272 }
273
274 /**
275 * Implementation of hook_user().
276 */
277 function node_media_user($type, &$edit, &$user, $category = NULL) {
278 switch ($type) {
279 case 'delete':
280 // Set uid=0 for images uploaded by the deleted user
281 db_query('UPDATE {node_media} SET uid=0 WHERE uid=%d', $user->uid);
282 }
283 }
284
285 /**
286 * Implementation of hook_file_download().
287 * Find out if an image is accessible when download method is set to private
288 */
289 function node_media_file_download($file) {
290 $path = file_create_path($file);
291 $result = db_query("SELECT * FROM {node_media} WHERE filepath='%s' OR thumbpath='%s'", $path, $path);
292 if ($file = db_fetch_object($result)) {
293 $node = node_load($file->nid);
294 if (node_access('view', $node)) {
295 if ($path == $file->thumbpath) {
296 // update header info if thumb is requested
297 $name = mime_header_encode(basename($file->thumbpath));
298 $size = $file->thumbsize;
299 }
300 else {
301 $name = mime_header_encode($file->filename);
302 $size = $file->filesize;
303 }
304 $type = mime_header_encode($file->filemime);
305 return array(
306 'Content-Type: '. $type .'; name='. $name,
307 'Content-Length: '. $size,
308 'Cache-Control: private'
309 );
310 }
311 else {
312 return -1;
313 }
314 }
315 }
316
317
318 /************************************************************
319 * Node edit functions
320 ************************************************************/
321
322 /**
323 * Display the page to edit and upload node media.
324 *
325 * @param $node
326 * the current node
327 * @return
328 * the node media page.
329 */
330 function _node_media_edit_form($node) {
331 global $user;
332 $output = '<div id="attach-wrapper">';
333
334 // Generate image list
335 $sql = db_query('SELECT * FROM {node_media} WHERE nid=%d ORDER BY weight', $node->nid);
336 if (db_num_rows($sql)>0) $output .= drupal_get_form('_node_media_list', $node, $sql);
337
338 // test if this node can accept new images
339 // i.e. there might be limits to the number of uploaded images for certain node types or user roles
340 // if the hook is not present in the node type module, upload is enabled by default
341 $upload = module_invoke($node->type, 'node_media', 'upload', $node);
342 if ($upload !== FALSE) {
343 $output .= drupal_get_form('_node_media_edit_form_upload', $node);
344 }
345 $output .= '</div>';
346
347 drupal_set_title(check_plain($node->title));
348 return $output;
349 }
350
351 function _node_media_edit_form_upload($node) {
352 $path = file_directory_path().'/'.variable_get('node_media_path', 'node_media');
353 _node_media_check_directory(NULL, $path);
354 $extensions = variable_get('node_media_extensions', 'jpg jpeg gif png');
355
356 //die;
357
358 drupal_add_js('misc/progress.js');
359 drupal_add_js('misc/upload.js');
360
361 // Generate upload form
362 $form['new'] = array(
363 '#type'=>'fieldset',
364 '#title'=>t('Upload a new media'),
365 );
366 $form['new']['description'] = array(
367 '#type' => 'textfield',
368 '#title' => t('Description'),
369 '#size' => 50,
370 '#maxlength' => 255,
371 '#default_value' => $edit['new']['description'],
372 '#description' => t('Enter a description for the new media, max 255 chars.'),
373 '#prefix' => '<div style="float:left; margin-right:20px;">',
374 '#suffix' => '</div>',
375 );
376 $form['new']['weight'] = array(
377 '#type' => 'weight',
378 '#title' => t('Weight'),
379 '#prefix' => '<div style="float:left; margin-right:20px;">',
380 '#suffix' => '</div><div style="clear:both; height:0.1em;"></div>',
381 );
382 $form['new']['upload'] = array(
383 '#type' => 'file',
384 '#title' => t('Media file'),
385 '#size' => 50,
386 '#description' => t('Allowed file types: %extensions', array('%extensions' => $extensions)),
387 '#prefix' => '<div style="float:left; margin-right:20px;"></div><div id="attach-hide" style="float:left; margin-right:20px;">',
388 '#suffix' => '</div>',
389 );
390 $form['new']['type'] = array(
391 '#type' => 'select',
392 '#options' => array('Image','Video','Sound'),
393 '#title' => t('Type'),
394 '#default_value' => $edit['new']['type'],
395 '#prefix' => '<div style="float:left; margin-right:20px;">',
396 '#suffix' => '</div><div style="clear:both; height:0.1em;"></div>',
397 );
398 $form['new']['submit'] = array(
399 '#type' => 'button',
400 '#value' => t('Upload'),
401 '#name'=> 'submit',
402 '#id' => 'attach-button',
403 );
404 // The class "upload" triggers the js upload behaviour.
405 $form['attach-url'] = array(
406 '#type' => 'hidden',
407 '#value' => url('node_media/js', NULL, NULL, TRUE),
408 '#attributes' => array('class' => 'upload'),
409 );
410 // Needed for JS
411 $form['nid'] = array(
412 '#type' => 'hidden',
413 '#value' => $node->nid,
414 );
415
416 $form['#attributes']['enctype'] = 'multipart/form-data';
417 return $form;
418 }
419
420 /**
421 * Generate a list of images associated to the current node.
422 *
423 * @param $node
424 * the current node
425 * @param $result
426 * SQL result containing the node media
427 * @return
428 * a form representing the image list.
429 */
430 function _node_media_list($node, $result) {
431 global $user;
432 $images = array();
433 $form['rows'] = array('#tree' => TRUE);
434 $delete_access = node_access('delete', $node);
435
436 while ($image = db_fetch_object($result)) {
437 $images[$image->id] = $image;
438 $form['rows'][$image->id]['description'] = array(
439 '#type' => 'textfield',
440 '#default_value' => $image->description,
441 '#size' => 30,
442 '#maxlength' => 255,
443 );
444 $form['rows'][$image->id]['weight'] = array(
445 '#type' => 'weight',
446 '#default_value' => $image->weight,
447 );
448
449 // images can be deleted only by users having delete access or users who uploaded the images
450 $disabled = (!$delete_access && $user->uid != $image->uid);
451 $form['rows'][$image->id]['delete'] = array('#type' => 'checkbox', '#disabled' => $disabled);
452 }
453
454 $form['nid'] = array('#type' => 'value', '#value' => $node->nid);
455 $form['save'] = array(
456 '#type' => 'submit',
457 '#value' => t('Save changes'),
458 );
459 $form['images'] = array(
460 '#type' => 'value',
461 '#value' => $images,
462 );
463 $form['#theme'] = 'node_media_list';
464
465 // action must be set, otherwise it will be replaced by "node_media/js" (current $_GET['q'] on JS uploads)
466 $form['#action'] = url('node/'.$node->nid.'/media');
467
468 return $form;
469 }
470
471 /**
472 * Theme node media list.
473 */
474 function theme_node_media_list($form) {
475 $header = array(t('Thumbnail'), t('Description').' / '.t('Path'), t('Size'), t('Weight'), t('Delete'));
476
477 $rows = array();
478 foreach($form['images']['#value'] as $id=>$image) {
479 $row = array();
480 $row[] = '<img src="'.file_create_url($image->thumbpath).'" vspace="5" />';
481 $row[] = drupal_render($form['rows'][$image->id]['description']).$image->filepath;
482 $row[] = array('data' => format_size($image->filesize), 'style' => 'white-space: nowrap');
483 $row[] = drupal_render($form['rows'][$image->id]['weight']);
484 $row[] = array('data' => drupal_render($form['rows'][$image->id]['delete']), 'align' => 'center');
485 $rows[] = $row;
486 }
487
488 $output = '<fieldset><legend>'.t('Uploaded images').'</legend>';
489 $output .= theme('table', $header, $rows);
490 $output .= drupal_render($form);
491 $output .= '</fieldset>';
492
493 return $output;
494 }
495
496 /**
497 * Process result from node media list.
498 */
499 function _node_media_list_submit($form_id, $form_values) {
500 global $user;
501 $node = node_load($form_values['nid']);
502 if (!node_access('update', $node)) return;
503 $delete_access = node_access('delete', $node);
504
505 foreach($form_values['rows'] as $id => $edit) {
506 if ($edit['delete']) {
507 $r = db_fetch_object(db_query('SELECT filepath, thumbpath, uid FROM {node_media} WHERE id=%d AND nid=%d',
508 $id, $node->nid));
509
510 // if user has no delete access to the node, he can delete his own images only
511 if (!$delete_access && $user->uid != $r->uid) continue;
512
513 // delete selected image
514 file_delete($r->filepath);
515 file_delete($r->thumbpath);
516 db_query('DELETE FROM {node_media} WHERE id=%d AND nid=%d', $id, $node->nid);
517 }
518 else {
519 // update image data
520 db_query('UPDATE {node_media} SET description="%s", weight=%d WHERE id=%d AND nid=%d',
521 $edit['description'], $edit['weight'], $id, $node->nid);
522 }
523 }
524 drupal_set_message(t('The changes have been saved.'));
525 }
526
527 /**
528 * Upload a new image and associate it to the current node.
529 *
530 * @param $edit
531 * array containing the submitted values
532 * @param $node
533 * the image file
534 * @return
535 * the uploaded image file, or FALSE if upload fails
536 */
537 function _node_media_upload($edit, $node) {
538 global $user;
539 if (($file = file_check_upload()) && user_access('create node media')) {
540 switch($edit['type']){
541 case 0:
542 // The uploaded file must be an image
543 $info = image_get_info($file->filepath);
544 if (!$info) {
545 form_set_error('upload', t('The uploaded file !name is not a valid image.', array('!name' => theme('placeholder', $file->filename))));
546 return FALSE;
547 }
548 break;
549 case 1:
550 break;
551 case 2:
552 break;
553 }
554
555 //Munge the filename as needed for security purposes.
556 $file->filename = upload_munge_filename($file->filename, NULL, 0);
557
558 // Validate file extension
559 $extensions = variable_get('node_media_extensions', 'jpg jpeg gif png');
560 $regex = '/\.('. ereg_replace(' +', '|', preg_quote($extensions)) .')$/i';
561 if (!preg_match($regex, $file->filename)) {
562 form_set_error('upload', t('The selected file !name can not be uploaded, because it is only possible to attach files with the following extensions: !files-allowed.', array('!name' => theme('placeholder', $file->filename), '!files-allowed' => theme('placeholder', $extensions))));
563 return FALSE;
564 }
565 switch($edit['type']){
566 case 0:
567 // Validate max images for the current node
568 $sql = db_query('SELECT * FROM {node_media} WHERE nid=%d', $node->nid);
569 $max = variable_get('node_media_max_images', 4);
570 $count = db_num_rows($sql);
571 if ($count >= $max) {
572 form_set_error('upload', t('The selected file !name can not be uploaded, because it exceeds the maximum limit of !max files.', array('!name' => theme('placeholder', $file->filename), '!max' => theme('placeholder', $max))), 'error');
573 return FALSE;
574 }
575 // Scale image to the maximum allowed resolution (default is 400x300)
576 // (if not set in the node_media admin settings, use the default upload max resolution
577 list($width, $height) = explode('x', variable_get('node_media_large_resolution', '400x300'));
578 if (!$width || !$height) {
579 list($width, $height) = explode('x', variable_get('upload_max_resolution', '400x300'));
580 }
581 if (!$width || !$height) {
582 list($width, $height) = explode('x', '400x300');
583 }
584 if ($width && $height) {
585 $result = image_scale($file->filepath, $file->filepath, $width, $height);
586 if ($result) {
587 $file->filesize = filesize($file->filepath);
588 drupal_set_message(t('The image was resized to fit within the maximum allowed resolution of %resolution pixels.',
589 array('%resolution' => $width.'x'.$height)));
590 }
591 }
592 break;
593 case 1:
594 break;
595 case 2:
596 break;
597 }
598 // Validation from upload.module
599 $fid = 'upload_'.$user->uid;
600 $node->files = array($fid => $file);
601 _upload_validate($node);
602 if (!isset($node->files[$fid])) return FALSE;
603
604 // Normalize filename and check description
605 $dest = _node_media_get_directory();
606 if (trim($edit['description']) == '') {
607 $edit['description'] = basename($file->filename);
608 }
609 if (variable_get('node_media_md5name', FALSE)) {
610 // set md5 file name
611 $extension = substr($file->filename, strrpos($file->filename, '.') + 1);
612 $file->filename = substr(md5($dest.'/'.$file->filename), 0, 16);
613 if ($extension) $file->filename .= '.'.$extension;
614 }
615 $file->filename = preg_replace('/ +/', '_', $file->filename);
616
617 // Save uploaded media
618 if ($file = file_save_upload($file, $dest.'/'.strtolower($file->filename))) {
619 $thumb = _node_media_create_thumbnail($file->filepath);
620 $file->filesize = filesize($file->filepath);
621 db_query("INSERT INTO {node_media} (nid, uid, filename, filepath, filemime, filesize, thumbpath, thumbsize, weight, description, type)
622 VALUES (%d, %d, '%s', '%s', '%s', %d, '%s', %d, %d, '%s', %d)",
623 $edit['nid'], $user->uid, $file->filename, $file->filepath, $file->filemime, $file->filesize,
624 $thumb->filepath, $thumb->filesize, $edit['weight'], $edit['description'], $edit['type']);
625 }
626 return $file;
627 }
628 }
629
630
631 /************************************************************
632 * Node view functions
633 ************************************************************/
634
635 /**
636 * Show node media in the node view.
637 */
638 function theme_node_media_view($node, $teaser, $page, $format = NULL) {
639 //if (str_replace(arg(2)) == 'image_gallery' || empty($node->node_media)) return;
640
641 $output = array('','','');
642 $i = 0;
643
644 // set maximum number of images for teaser/body
645 $view = ($teaser ? 'teaser' : 'body');
646 $count = variable_get('node_media_'.$view.'_images_'.$node->type, 2);
647 if (isset($count) && $count === 0) return;
648 if (!$format) {
649 $format = variable_get('node_media_'.$view.'_format_'.$node->type, 'thumbs');
650 }
651
652 foreach((array)$node->node_media[0] as $id=>$image) {
653 $description = check_plain($image->description);
654 $pattern = '<img src="%path" alt="%description" />';
655 $thumb = strtr($pattern, array('%path'=>file_create_url($image->thumbpath), '%description'=>$description));
656 $fullsize = strtr($pattern, array('%path'=>file_create_url($image->filepath), '%description'=>$description));
657
658 if ($info = getimagesize($image->filepath)) {
659 $width = $info[0] + 36;
660 $height = $info[1] + 36;
661 }
662 else {
663 $width = 420;
664 $height = 315;
665 }
666
667 if ($format == 'thumbs') {
668 $output[0] .= '<a href="javascript:void(0);" title="'.$description.'" onclick="window.open(\''.
669 file_create_url($image->filepath).'\', \'\', \'height='.$height.',width='.$width.'\');">'.$thumb.'</a> ';
670 }
671 else {
672 $output[0] .= $fullsize.' ';
673 }
674 if ($count>0 && ++$i >= $count) break;
675 }
676
677 foreach((array)$node->node_media[1] as $id=>$video) {
678 $description = check_plain($video->description);
679 $iconpath = variable_get('video_media_icon_path','/modules/node_media/img/video_icon.gif');
680 $pattern = '<img src="'.$iconpath.'" alt="%description" />';
681 $thumb = strtr($pattern, array('%path'=>file_create_url($iconpath), '%description'=>$description));
682 $fullsize = strtr($pattern, array('%path'=>file_create_url($iconpath), '%description'=>$description));
683
684 list($width, $height) = explode('x', variable_get('video_media_max_resolution', '400x300'));
685
686 if ($format == 'thumbs') {
687 $output[1] .= '<a href="javascript:void(0);" title="'.$description.'" onclick="window.open(\''.
688 file_create_url($video->filepath).'\', \'\', \'height='.$height.',width='.$width.'\');">'.$thumb.'</a> ';
689 }
690 else {
691 $output[1] .= $fullsize.' ';
692 }
693 if ($count>0 && ++$i >= $count) break;
694 }
695
696 return $output;
697 }
698
699
700 /************************************************************
701 * Gallery functions
702 ************************************************************/
703
704 function _node_media_image_gallery($node) {
705 if (empty($node->node_media[0])) {
706 drupal_set_message(t('No images uploaded for this content.'));
707 if (user_access('create node media') && node_access('update', $node)) {
708 $output = t('Click <a href="!url">here</a> to upload new images.', array('!url' => url('node/'.$node->nid.'/media')));
709 }
710 return '<p>'.$output.'</p>';
711 }
712
713 $settings = array('images' => array());
714
715 $i = 1;
716 $thumbs = array();
717 foreach ($node->node_media[0] as $id=>$image) {
718 $thumb_path = file_create_url($image->thumbpath);
719 $thumbs[$i] = array(
720 'src' => $thumb_path,
721 'title' => $image->description,
722 );
723
724 $path = $image->filepath;
725 $info = image_get_info($path);
726 $settings['images'][$i++] = array(
727 'src' => file_create_url($path),
728 'title' => $image->description,
729 'description' => $image->description,
730 'width' => $info['width'],
731 'height' => $info['height'],
732 'thumb' => $thumb_path,
733 );
734 }
735 $total = count($settings['images']);
736
737 if ($total > 0) {
738 $current = (int)$_GET['page'];
739 $current = ($current < 1 || $current > $total) ? 1 : $current;
740
741 $settings['current'] = $current;
742 $settings['total'] = $total;
743
744 $path = drupal_get_path('module', 'node_media');
745 drupal_add_js($path.'/node_media.js');
746 drupal_add_js(array('slideshow' => array($node->nid => $settings)), 'setting');
747 drupal_add_css($path.'/node_media.css');
748
749 $slideshow = array(
750 '#type' => 'node_media_gallery',
751 '#title' => $settings['images'][$current]['title'],
752 '#attributes' => array('class' => 'mediaslideshow-'. $node->nid),
753 '#status' => array(
754 'current' => $current,
755 'total' => $total,
756 'previous' => $current < 1 ? $total : $current - 1,
757 'next' => $current >= $total ? 1 : $current + 1,
758 ),
759 '#media' => $settings['images'][$current],
760 '#weight' => -5,
761 );
762 }
763
764 list($width, $height) = explode('x', variable_get('upload_max_resolution', 0));
765
766 $output = '';
767 if(variable_get('node_media_gallery_display_node_details_'.$node->type, TRUE))
768 $output = node_view($node);
769 $output .= '<table id="mediaslideshow-table"><tr>';
770 $output .= '<td>'.drupal_render($slideshow).'</td>';
771 $output .= '<td>'.theme('node_media_gallery_thumbs', $thumbs).'</td>';
772 $output .= '</tr></table>';
773 //$output .= node_view($node).'<hr />';
774
775 $title = t('Photo gallery for %title', array('%title' => $node->title));
776 drupal_set_title($title);
777 return $output;
778 }
779
780
781 function _node_media_video_gallery($node) {
782 if (empty($node->node_media[1])) {
783 drupal_set_message(t('No images uploaded for this content.'));
784 if (user_access('create node media') && node_access('update', $node)) {
785 $output = t('Click <a href="!url">here</a> to upload new videos.', array('!url' => url('node/'.$node->nid.'/media')));
786 }
787 return '<p>'.$output.'</p>';
788 }
789
790 $settings = array('videos' => array());
791
792 $i = 1;
793 $thumbs = array();
794 $iconpath = variable_get('video_media_icon_path','/modules/node_media/img/video_icon.gif');
795 foreach ($node->node_media[1] as $id=>$video) {
796 $thumb_path = file_create_url($video->thumbpath);
797 $thumbs[$i] = array(
798 'src' => $iconpath,
799 'title' => $video->description,
800 );
801
802 list($width, $height) = explode('x', variable_get('video_media_max_resolution', '400x300'));
803
804 $path = $video->filepath;
805 $settings['videos'][$i++] = array(
806 'src' => file_create_url($path),
807 'title' => $video->description,
808 'description' => $video->description,
809 'width' => $width,
810 'height' => $height,
811 'thumb' => $iconpath,
812 'type' => $video->type
813 );
814 }
815 $total = count($settings['videos']);
816
817 if ($total > 0) {
818 $current = (int)$_GET['page'];
819 $current = ($current < 1 || $current > $total) ? 1 : $current;
820
821 $settings['current'] = $current;
822 $settings['total'] = $total;
823
824 $path = drupal_get_path('module', 'node_media');
825 drupal_add_js($path.'/node_media.js');
826 drupal_add_js(array('slideshow' => array($node->nid => $settings)), 'setting');
827 drupal_add_css($path.'/node_media.css');
828
829 $slideshow = array(
830 '#type' => 'node_media_gallery',
831 '#title' => $settings['videos'][$current]['title'],
832 '#attributes' => array('class' => 'mediaslideshow-'. $node->nid),
833 '#status' => array(
834 'current' => $current,
835 'total' => $total,
836 'previous' => $current < 1 ? $total : $current - 1,
837 'next' => $current >= $total ? 1 : $current + 1,
838 ),
839 '#media' => $settings['videos'][$current],
840 '#weight' => -5,
841 );
842 }
843
844 list($width, $height) = explode('x', variable_get('video_media_max_resolution', '400x300'));
845
846 $output = '';
847 if(variable_get('node_media_gallery_display_node_details_'.$node->type, TRUE))
848 $output = node_view($node).'<hr />';
849 $output .= '<table id="mediaslideshow-table"><tr>';
850 $output .= '<td>'.drupal_render($slideshow).'</td>';
851 $output .= '<td>'.theme('node_media_gallery_thumbs', $thumbs).'</td>';
852 $output .= '</tr></table>';
853 //$output .= node_view($node).'<hr />';
854
855 $title = t('Video gallery for %title', array('%title' => $node->title));
856 drupal_set_title($title);
857 return $output;
858 }
859
860
861 function _node_media_sound_gallery($node) {
862 if (empty($node->node_media[2])) {
863 drupal_set_message(t('No sounds uploaded for this content.'));
864 if (user_access('create node media') && node_access('update', $node)) {
865 $output = t('Click <a href="!url">here</a> to upload new sounds.', array('!url' => url('node/'.$node->nid.'/media')));
866 }
867 return '<p>'.$output.'</p>';
868 }
869
870 $settings = array('sounds' => array());
871
872 $i = 1;
873 $thumbs = array();
874 foreach ($node->node_media[0] as $id=>$image) {
875 $thumb_path = file_create_url($sound->thumbpath);
876 $thumbs[$i] = array(
877 'src' => $thumb_path,
878 'title' => $sound->description,
879 );
880
881 $path = $sound->filepath;
882 $settings['sounds'][$i++] = array(
883 'src' => file_create_url($path),
884 'title' => $sound->description,
885 'description' => $sound->description,
886 'width' => variable_get('sound_media_icon_width',32),
887 'height' => variable_get('sound_media_icon_height',32),
888 'thumb' => $thumb_path,
889 );
890 }
891 $total = count($settings['sounds']);
892
893 if ($total > 0) {
894 $current = (int)$_GET['page'];
895 $current = ($current < 1 || $current > $total) ? 1 : $current;
896
897 $settings['current'] = $current;
898 $settings['total'] = $total;
899
900 $path = drupal_get_path('module', 'node_media');
901 drupal_add_js($path.'/node_media.js');
902 drupal_add_js(array('slideshow' => array($node->nid => $settings)), 'setting');
903 drupal_add_css($path.'/node_media.css');
904
905 $slideshow = array(
906 '#type' => 'node_media_gallery',
907 '#title' => $settings['sounds'][$current]['title'],
908 '#attributes' => array('class' => 'mediaslideshow-'. $node->nid),
909 '#status' => array(
910 'current' => $current,
911 'total' => $total,
912 'previous' => $current < 1 ? $total : $current - 1,
913 'next' => $current >= $total ? 1 : $current + 1,
914 ),
915 '#media' => $settings['sounds'][$current],
916 '#weight' => -5,
917 );
918 }
919
920 list($width, $height) = explode('x', variable_get('sound_media_resolution', 0));
921
922 $output = '';
923 if(variable_get('node_media_gallery_display_node_details_'.$node->type, TRUE))
924 $output = node_view($node).'<hr />';
925 $output .= '<table id="mediaslideshow-table"><tr>';
926 $output .= '<td>'.drupal_render($slideshow).'</td>';
927 $output .= '<td>'.theme('node_media_gallery_thumbs', $thumbs).'</td>';
928 $output .= '</tr></table>';
929 //$output .= node_view($node).'<hr />';
930
931 $title = t('Sound gallery for %title', array('%title' => $node->title));
932 drupal_set_title($title);
933 return $output;
934 }
935
936 function theme_node_media_gallery($element) {
937 switch($element['#media']['type']){
938 case 0:
939 $output = '<div'. drupal_attributes($element['#attributes']) .'>
940 <div class="header">
941 '. l(t('Previous'), $_GET['q'], array('class' => 'previous', 'rel' => 'nofollow'), 'page='. $element['#status']['previous']) .' |
942 '. t('Image !current of !total', array(
943 '!current' => '<span class="current">'. $element['#status']['current'] .'</span>',
944 '!total' => '<span class="total">'. $element['#status']['total'] .'</span>')) .' |
945 '. l(t('Next'), $_GET['q'], array('class' => 'next', 'rel' => 'nofollow'), 'page='. $element['#status']['next']) .'
946 </div>
947 <img src="'. url($element['#media']['src']) .'" class="mediapolaroid" />
948 <p class="description">'. $element['#title'] .'</p>
949 </div>';
950 break;
951 case 1:
952 $output = '<div'. drupal_attributes($element['#attributes']) .'>
953 <div class="header">
954 '. l(t('Previous'), $_GET['q'], array('class' => 'previous', 'rel' => 'nofollow'), 'page='. $element['#status']['previous']) .' |
955 '. t('Image !current of !total', array(
956 '!current' => '<span class="current">'. $element['#status']['current'] .'</span>',
957 '!total' => '<span class="total">'. $element['#status']['total'] .'</span>')) .' |
958 '. l(t('Next'), $_GET['q'], array('class' => 'next', 'rel' => 'nofollow'), 'page='. $element['#status']['next']) .'
959 </div>
960 <embed src="'. url($element['#media']['src']) .'" autostart="0"
961 showcontrols="1" type="application/x-mplayer2" pluginspage="http://www.microsoft.com/windows/windowsmedia/download/"
962 height="'. $element['#media']['height'] .'" width="'. $element['#media']['width'] .'">
963 <p class="description">'. $element['#title'] .'</p>
964 </div>';
965 break;
966 case 2;
967 break;
968 }
969 return $output;
970 }
971
972 function theme_node_media_gallery_thumbs($thumbs, $cols = 2) {
973 $count = count($thumbs);
974 $output = '<table id="thumbs-table">';
975
976 $i = 0;
977 foreach($thumbs as $id => $thumb) {
978 if ($i % $cols == 0) $output .= '<tr>';
979 $description = '<div class="thumb-description">'.truncate_utf8($thumb['title'], 40, FALSE, TRUE).'</div>';
980 $output .= '<td>'.l('<img src="'.$thumb['src'].'" class="slideshow-thumb" id="thumb-'.$id.'" />', $_GET['q'],
981 array('title' => $thumb['title'], 'rel' => 'nofollow'), 'page='.$id, NULL, FALSE, TRUE).$description.'</td>';
982 if ($i % $cols == $cols - 1 || $n >= $count) $output .= "</tr>";
983 $i++;
984 }
985
986 $output .= '</table>';
987 return $output;
988 }
989
990
991 /************************************************************
992 * Helper functions - admin settings
993 ************************************************************/
994
995 /**
996 * Menu callback; admin settings page.
997 */
998 function node_media_admin_settings() {
999 _node_media_check_settings();
1000
1001 $form['node_media_path'] = array(
1002 '#type' => 'textfield',
1003 '#title' => t('Node media path'),
1004 '#default_value' => variable_get('node_media_path', 'node_media'),
1005 '#maxlength' => 255,
1006 '#description' => t('Subdirectory in the directory %dir where the node media will be stored. This directory has to exist and be writable by Drupal. You can use the following variables: %uid, %username', array('%dir' => file_directory_path() .'/')),