'admin/settings/node_images', 'title' => t('Node images'), 'description' => t('Control how to upload node images.'), 'callback' => 'drupal_get_form', 'callback arguments' => array('node_images_admin_settings'), 'access' => $admin ); $items[] = array('path' => 'admin/build/node_images', 'title' => t('Node images'), 'description' => t('Resize uploaded node images.'), 'callback' => 'drupal_get_form', 'callback arguments' => array('node_images_form_resize'), 'access' => $admin ); } else { if (arg(0) == 'node' && is_numeric(arg(1))) { $node = node_load(arg(1)); if ($node->nid && variable_get('node_images_position_'.$node->type, 'hide') != 'hide') { $items[] = array( 'path' => 'node/' . arg(1) . '/images', 'title' => t('Images'), 'callback' => '_node_images_edit_form', 'callback arguments' => array($node), 'access' => $access && node_access('update', $node), 'type' => MENU_LOCAL_TASK, 'weight' => 2 ); $items[] = array( 'path' => 'node/' . arg(1) . '/image_gallery', 'title' => t('Gallery'), 'callback' => '_node_images_gallery', 'callback arguments' => array($node), 'access' => node_access('view', $node), 'type' => MENU_CALLBACK ); } } } $items[] = array( 'path' => 'node_images/js', 'callback' => '_node_images_js', 'access' => $access, 'type' => MENU_CALLBACK ); return $items; } function node_images_form_resize() { $form['thumbnails'] = array( '#type' => 'checkbox', '#title' => t('Resize thumbnails'), '#default_value' => 0, '#description' => t('Check if you want to resize the thumbnails images.'), ); $form['medium'] = array( '#type' => 'checkbox', '#title' => t('Resize medium size images'), '#default_value' => 0, '#description' => t('Check if you want to resize the medium size images.'), ); $form['submit'] = array('#type' => 'submit', '#value' => t('Submit')); return $form; } function node_images_form_resize_validate($form_id, $form_values) { if (!$form_values['thumbnails'] && !$form_values['medium']) { form_set_error('thumbnails', t('Select at least one type for this to do something'));} } function node_images_form_resize_submit($form_id, $form_values) { $count = node_images_get_images($form_id, $form_values); $all = $count*2; if ($form_values['thumbnails'] && $form_values['medium']) { drupal_set_message(t('You selected to resize both type of images. There were '.$all.' images resized')); } elseif ($form_values['thumbnails']) { drupal_set_message(t('You selected to resize thumbnail images. There were '.$count.' images resized')); } elseif ($form_values['medium']) { drupal_set_message(t('You selected to resize medium size images. There were '.$count.' images resized')); } } function node_images_get_images($form_id, $form_values) { $result = db_query('SELECT * FROM {node_images}'); while ($images = db_fetch_array($result)){ $i++; if (is_file($images['filepath'])) { if ($form_values['thumbnails'] && is_file($images['thumbpath'])) { file_delete($images['thumbpath']); } if ($form_values['medium'] && is_file($images['mediumpath'])) { file_delete($images['mediumpath']); } if ($form_values['thumbnails']) { $thumb = _node_images_create_thumbnail($images['filepath']); $images['thumbsize'] = $thumb->filesize; $images['thumbpath'] = $thumb->filepath; } if ($form_values['medium']) { $medium = _node_images_create_medium_size($images['filepath']); $images['mediumsize'] = $medium->filesize; $images['mediumpath'] = $medium->filepath; } db_query('UPDATE {node_images} SET mediumpath = "%s", mediumsize = %d, thumbpath = "%s", thumbsize = %d WHERE id = %d', $images['mediumpath'], $images['mediumsize'], $images['thumbpath'], $images['thumbsize'], $images['id']); } } return $i; } /** * implementation of hook_form_alter() */ function node_images_form_alter($form_id, &$form) { $type = $form['#node_type']->type; if ($form_id == 'node_type_form' && isset($form['identity']['type'])) { // radio button in the node's content type configuration page _node_images_check_settings(); $form['node_images'] = array( '#type' => 'fieldset', '#title' => t('Node images'), '#collapsible' => TRUE, ); $form['node_images']['node_images_position'] = array( '#type' => 'radios', '#title' => t('Position'), '#default_value' => variable_get('node_images_position_'.$type, 'hide'), '#options' => array('hide' => t('Do not show'), 'above' => t('Show above node body'), 'below' => t('Show below node body'), 'node_template' => t('Manually set in node template by variable $node->node_images')), '#description' => t('The position of images in the node view.'), ); $form['node_images']['node_images_gallery_link'] = array( '#type' => 'radios', '#title' => t('Link to image gallery'), '#default_value' => variable_get('node_images_gallery_link_'.$type, TRUE), '#options' => array(t('Do not show'), t('Show')), '#description' => t('Choose whether to show or not the link to the image gallery.'), ); $form['node_images']['node_images_teaser_images'] = array( '#type' => 'textfield', '#title' => t('Number of images in node teaser'), '#default_value' => variable_get('node_images_teaser_images_'.$type, 2), '#size' => 5, '#maxlength' => 2, '#description' => t('The maximum number of images to show in the node teaser. 0 will not show images. Leave blank to show all images.'), ); $form['node_images']['node_images_body_images'] = array( '#type' => 'textfield', '#title' => t('Number of images in node body'), '#size' => 5, '#maxlength' => 2, '#default_value' => variable_get('node_images_body_images_'.$type, NULL), '#description' => t('The maximum number of images to show in the node body. 0 will not show images. Leave blank to show all images.'), ); $form['node_images']['node_images_teaser_format'] = array( '#type' => 'radios', '#title' => t('Image format in node teaser'), '#default_value' => variable_get('node_images_teaser_format_'.$type, 'thumbs'), '#options' => array('thumbs' => t('Thumbnails'), 'medium' => t('Medium size'), 'fullsize' => t('Full size images')), '#description' => t('Image format in node teaser.'), ); $form['node_images']['node_images_body_format'] = array( '#type' => 'radios', '#title' => t('Image format in node body'), '#default_value' => variable_get('node_images_body_format_'.$type, 'thumbs'), '#options' => array('thumbs' => t('Thumbnails'), 'medium' => t('Medium size'), 'fullsize' => t('Full size images')), '#description' => t('Image format in node body.'), ); $form['submit']['#weight'] = 30; $form['delete']['#weight'] = 31; $form['reset']['#weight'] = 32; } } /** * Implementation of hook_nodeapi(). */ function node_images_nodeapi(&$node, $op, $teaser, $page) { // test if images are allowed for this node if ($op == 'load' || $op == 'view') { if (variable_get('node_images_position_'.$node->type, 'hide') == 'hide') return; // fire an additional hook for the specific node type // i.e. node images might be a pro feature, so only subscribed users can view them // if the hook is not present in the node type module, images are loaded by default $show = module_invoke($node->type, 'node_images', $op, $node); if ($show === FALSE) return; } switch ($op) { case 'load': // load node images for the current node $sql = db_query('SELECT * FROM {node_images} WHERE nid=%d AND status=1 ORDER BY weight', $node->nid); while ($r = db_fetch_object($sql)) { $node->node_images[$r->id] = $r; } break; case 'insert': if (user_access('create node images') && node_access('update', $node) && variable_get('node_images_position_'.$node->type, 'hide') != 'hide') { drupal_set_message(t('Click the !images tab to add images to this node.', array('!images' => l(t('images'), 'node/'.$node->nid.'/images')))); } break; case 'delete': // Delete image and thumbnail files $sql = db_query('SELECT filepath, mediumpath, thumbpath FROM {node_images} WHERE nid=%d', $node->nid); while ($r = db_fetch_object($sql)) { file_delete($r->filepath); file_delete($r->mediumpath); file_delete($r->thumbpath); } // Delete all images associated with the node db_query('DELETE FROM {node_images} WHERE nid=%d', $node->nid); break; case 'view': if (empty($node->node_images)) return; // search for a themed view for the current node type $nodetype_function = 'theme_'.$node->type.'_node_images_view'; if (function_exists($nodetype_function)) { $output = $nodetype_function($node, $teaser, $page); } else { // use the default theme function $output = theme('node_images_view', $node, $teaser, $page); } $node->node_images = $output; $output = '
'.$output.'
'; $position = variable_get('node_images_position_'.$node->type, 'hide'); switch ($position) { case 'node_template': case 'hide': break; case 'above': $node->content['node_images'] = array('#value' => $output, '#weight' => -1); break; default: $node->content['node_images'] = array('#value' => $output, '#weight' => 1); break; } return $node; } } /** * Implementation of hook_link(). */ function node_images_link($type, $node = null, $teaser = false) { $links = array(); if ($type == 'node' && $node->nid && variable_get('node_images_position_'.$node->type, 'hide') != 'hide') { if (node_access('update', $node) && user_access('create node images')) { $links['node_images_edit'] = array( 'title' => t('Edit node images'), 'href' => "node/$node->nid/images", ); } if (count($node->node_images) && variable_get('node_images_gallery_link_'.$node->type, TRUE)) { $links['node_images_gallery'] = array( 'title' => t('Open the image gallery'), 'href' => "node/$node->nid/image_gallery", ); } } return $links; } /** * Implementation of hook_user(). */ function node_images_user($type, &$edit, &$user, $category = NULL) { switch ($type) { case 'delete': // Set uid=0 for images uploaded by the deleted user db_query('UPDATE {node_images} SET uid=0 WHERE uid=%d', $user->uid); } } /** * Implementation of hook_file_download(). * Find out if an image is accessible when download method is set to private */ function node_images_file_download($file) { $path = file_create_path($file); $result = db_query("SELECT * FROM {node_images} WHERE filepath='%s' OR thumbpath='%s' OR mediumpath='%s'", $path, $path, $path); if ($file = db_fetch_object($result)) { $node = node_load($file->nid); if (node_access('view', $node)) { if ($path == $file->thumbpath) { // update header info if thumb is requested $name = mime_header_encode(basename($file->thumbpath)); $size = $file->thumbsize; } elseif ($path == $file->mediumpath) { // update header info if medium size is requested $name = mime_header_encode(basename($file->mediumpath)); $size = $file->mediumsize; } else { $name = mime_header_encode($file->filename); $size = $file->filesize; } $type = mime_header_encode($file->filemime); return array( 'Content-Type: '. $type .'; name='. $name, 'Content-Length: '. $size, 'Cache-Control: private' ); } else { return -1; } } } /************************************************************ * Node edit functions ************************************************************/ /** * Display the page to edit and upload node images. * * @param $node * the current node * @return * the node images page. */ function _node_images_edit_form($node) { global $user; $output = '
'; // Generate image list $sql = db_query('SELECT * FROM {node_images} WHERE nid=%d ORDER BY weight', $node->nid); if (db_num_rows($sql)>0) $output .= drupal_get_form('_node_images_list', $node, $sql); // test if this node can accept new images // i.e. there might be limits to the number of uploaded images for certain node types or user roles // if the hook is not present in the node type module, upload is enabled by default $upload = module_invoke($node->type, 'node_images', 'upload', $node); if ($upload !== FALSE) { $output .= drupal_get_form('_node_images_edit_form_upload', $node); } $output .= '
'; drupal_set_title(check_plain($node->title)); return $output; } function _node_images_edit_form_upload($node) { $path = variable_get('node_images_path', 'files'); _node_images_check_directory(NULL, $path); $extensions = variable_get('node_images_extensions', 'jpg jpeg gif png'); drupal_add_js('misc/progress.js'); drupal_add_js('misc/upload.js'); // Generate upload form $form['new'] = array( '#type'=>'fieldset', '#title'=>t('Upload a new image'), ); $form['new']['description'] = array( '#type' => 'textfield', '#title' => t('Description'), '#size' => 50, '#maxlength' => 255, '#default_value' => $edit['new']['description'], '#description' => t('Enter a description for the new image, max 255 chars.'), '#prefix' => '
', '#suffix' => '
', ); $form['new']['weight'] = array( '#type' => 'weight', '#title' => t('Weight'), '#prefix' => '
', '#suffix' => '
', ); $form['new']['upload'] = array( '#type' => 'file', '#title' => t('Image file'), '#size' => 50, '#description' => t('Allowed file types: %extensions', array('%extensions' => $extensions)), '#prefix' => '
', '#suffix' => '
', ); $form['new']['submit'] = array( '#type' => 'button', '#value' => t('Upload'), '#name'=> 'submit', '#id' => 'attach-button', ); // The class "upload" triggers the js upload behaviour. $form['attach-url'] = array( '#type' => 'hidden', '#value' => url('node_images/js', NULL, NULL, TRUE), '#attributes' => array('class' => 'upload'), ); // Needed for JS $form['nid'] = array( '#type' => 'hidden', '#value' => $node->nid, ); $form['#attributes']['enctype'] = 'multipart/form-data'; return $form; } /** * Generate a list of images associated to the current node. * * @param $node * the current node * @param $result * SQL result containing the node images * @return * a form representing the image list. */ function _node_images_list($node, $result) { global $user; $images = array(); $form['rows'] = array('#tree' => TRUE); $delete_access = node_access('delete', $node); while ($image = db_fetch_object($result)) { $images[$image->id] = $image; $form['rows'][$image->id]['description'] = array( '#type' => 'textfield', '#default_value' => $image->description, '#size' => 30, '#maxlength' => 255, ); $form['rows'][$image->id]['weight'] = array( '#type' => 'weight', '#default_value' => $image->weight, ); // images can be deleted only by users having delete access or users who uploaded the images $disabled = (!$delete_access && $user->uid != $image->uid); $form['rows'][$image->id]['delete'] = array('#type' => 'checkbox', '#disabled' => $disabled); } $form['nid'] = array('#type' => 'value', '#value' => $node->nid); $form['save'] = array( '#type' => 'submit', '#value' => t('Save changes'), ); $form['images'] = array( '#type' => 'value', '#value' => $images, ); $form['#theme'] = 'node_images_list'; // action must be set, otherwise it will be replaced by "node_images/js" (current $_GET['q'] on JS uploads) $form['#action'] = url('node/'.$node->nid.'/images'); return $form; } /** * Theme node images list. */ function theme_node_images_list($form) { $header = array(t('Thumbnail'), t('Description'), t('Path'), t('Size'), t('Weight'), t('Delete')); $rows = array(); foreach($form['images']['#value'] as $id=>$image) { $row = array(); $row[] = ''; $row[] = drupal_render($form['rows'][$image->id]['description']); $row[] = $image->filepath; $row[] = format_size($image->filesize); $row[] = drupal_render($form['rows'][$image->id]['weight']); $row[] = array('data' => drupal_render($form['rows'][$image->id]['delete']), 'align' => 'center'); $rows[] = $row; } $output = '
'.t('Uploaded images').''; $output .= theme('table', $header, $rows); $output .= drupal_render($form); $output .= '
'; return $output; } /** * Process result from node images list. */ function _node_images_list_submit($form_id, $form_values) { global $user; $node = node_load($form_values['nid']); if (!node_access('update', $node)) return; $delete_access = node_access('delete', $node); foreach($form_values['rows'] as $id => $edit) { if ($edit['delete']) { $r = db_fetch_object(db_query('SELECT filepath, mediumpath, thumbpath, uid FROM {node_images} WHERE id=%d AND nid=%d', $id, $node->nid)); // if user has no delete access to the node, he can delete his own images only if (!$delete_access && $user->uid != $r->uid) continue; // delete selected image file_delete($r->filepath); file_delete($r->mediumpath); file_delete($r->thumbpath); db_query('DELETE FROM {node_images} WHERE id=%d AND nid=%d', $id, $node->nid); } else { // update image data db_query('UPDATE {node_images} SET description="%s", weight=%d WHERE id=%d AND nid=%d', $edit['description'], $edit['weight'], $id, $node->nid); } } drupal_set_message(t('The changes have been saved.')); } /** * Upload a new image and associate it to the current node. * * @param $edit * array containing the submitted values * @param $node * the image file * @return * the uploaded image file, or FALSE if upload fails */ function _node_images_upload($edit, $node) { global $user; if (($file = file_check_upload()) && user_access('create node images')) { //Munge the filename as needed for security purposes. $file->filename = upload_munge_filename($file->filename, NULL, 0); // Validate file extension $extensions = variable_get('node_images_extensions', 'jpg jpeg gif png'); $regex = '/\.('. ereg_replace(' +', '|', preg_quote($extensions)) .')$/i'; if (!preg_match($regex, $file->filename)) { 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)))); return FALSE; } // Validate max images for the current node $sql = db_query('SELECT * FROM {node_images} WHERE nid=%d', $node->nid); $max = variable_get('node_images_max_images', 4); $count = db_num_rows($sql); if ($count >= $max) { drupal_set_message(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'); return FALSE; } // Scale image $file = _upload_image($file); // Validation from upload.module $fid = 'upload_'.$user->uid; $node->files = array($fid => $file); _upload_validate($node); if (!isset($node->files[$fid])) return FALSE; // Save uploaded image $dest = _node_images_get_directory(); if (variable_get('node_images_md5name', FALSE)) { // set md5 file name $extension = substr($file->filename, strrpos($file->filename, '.') + 1); $file->filename = md5($dest.'/'.$file->filename); if ($extension) $file->filename .= '.'.$extension; } if ($file = file_save_upload($file, $dest.'/'.$file->filename)) { $thumb = _node_images_create_thumbnail($file->filepath); $medium = _node_images_create_medium_size($file->filepath); $file->filesize = filesize($file->filepath); db_query("INSERT INTO {node_images} (nid, uid, filename, filepath, filemime, filesize, mediumpath, mediumsize, thumbpath, thumbsize, weight, description) VALUES (%d, %d, '%s', '%s', '%s', %d, '%s', %d, '%s', %d, %d, '%s')", $edit['nid'], $user->uid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $medium->filepath, $medium->filesize, $thumb->filepath, $thumb->filesize, $edit['weight'], $edit['description']); } return $file; } } /************************************************************ * Node view functions ************************************************************/ /** * Show node images in the node view. */ function theme_node_images_view($node, $teaser, $page, $format = NULL) { if (arg(2) == 'image_gallery' || empty($node->node_images)) return; $output = ''; $i = 0; // set maximum number of images for teaser/body $view = ($teaser ? 'teaser' : 'body'); $count = variable_get('node_images_'.$view.'_images_'.$node->type, 2); if (isset($count) && $count === 0) return; if (!$format) { $format = variable_get('node_images_'.$view.'_format_'.$node->type, 'thumbs'); } foreach((array)$node->node_images as $id=>$image) { $description = check_plain($image->description); $pattern = '%description'; $thumb = strtr($pattern, array('%path'=>file_create_url($image->thumbpath), '%description'=>$description, '%class'=>'node_image_tn')); $medium = strtr($pattern, array('%path'=>file_create_url($image->mediumpath), '%description'=>$description, '%class'=>'node_image_md')); $fullsize = strtr($pattern, array('%path'=>file_create_url($image->filepath), '%description'=>$description, '%class'=>'node_image_xl')); if ($info = getimagesize($image->filepath)) { $width = $info[0] + 36; $height = $info[1] + 36; } else { $width = 420; $height = 315; } if ($format == 'thumbs') { $output .= ''.$thumb.' '; } elseif ($format == 'medium') { $output .= ''.$medium.' '; } else { $output .= $fullsize.' '; } if ($count>0 && ++$i >= $count) break; } return $output; } /************************************************************ * Gallery functions ************************************************************/ function _node_images_gallery($node) { if (empty($node->node_images)) { drupal_set_message(t('No images uploaded for this content.')); if (user_access('create node images') && node_access('update', $node)) { $output = t('Click here to upload new images.', array('!url' => url('node/'.$node->nid.'/images'))); } return '

'.$output.'

'; } $settings = array('images' => array()); $i = 1; $thumbs = array(); foreach ($node->node_images as $id=>$image) { $thumb_path = file_create_url($image->thumbpath); $thumbs[$i] = array( 'src' => $thumb_path, 'title' => $image->description, ); $path = $image->filepath; $info = image_get_info($path); $settings['images'][$i++] = array( 'src' => file_create_url($path), 'title' => $image->description, 'description' => $image->description, 'width' => $info['width'], 'height' => $info['height'], 'thumb' => $thumb_path, ); } $total = count($settings['images']); if ($total > 0) { $current = (int)$_GET['page']; $current = ($current < 1 || $current > $total) ? 1 : $current; $settings['current'] = $current; $settings['total'] = $total; $path = drupal_get_path('module', 'node_images'); drupal_add_js($path.'/node_images.js'); drupal_add_js(array('slideshow' => array($node->nid => $settings)), 'setting'); drupal_add_css($path.'/node_images.css'); $slideshow = array( '#type' => 'node_images_gallery', '#title' => $settings['images'][$current]['title'], '#attributes' => array('class' => 'slideshow-'. $node->nid), '#status' => array( 'current' => $current, 'total' => $total, 'previous' => $current < 1 ? $total : $current - 1, 'next' => $current >= $total ? 1 : $current + 1, ), '#image' => $settings['images'][$current], '#weight' => -5, ); } list($width, $height) = explode('x', variable_get('upload_max_resolution', 0)); $output = ''; $output .= ''; $output .= ''; $output .= '
'.drupal_render($slideshow).''.theme('node_images_gallery_thumbs', $thumbs).'
'; $output .= '
'.node_view($node); $title = t('Photo gallery for %title', array('%title' => $node->title)); drupal_set_title($title); return $output; } function theme_node_images_gallery($element) { $output = '
'. l(t('Previous'), $_GET['q'], array('class' => 'previous', 'rel' => 'nofollow'), 'page='. $element['#status']['previous']) .' | '. t('Image !current of !total', array( '!current' => ''. $element['#status']['current'] .'', '!total' => ''. $element['#status']['total'] .'')) .' | '. l(t('Next'), $_GET['q'], array('class' => 'next', 'rel' => 'nofollow'), 'page='. $element['#status']['next']) .'

'. $element['#title'] .'

'; return $output; } function theme_node_images_gallery_thumbs($thumbs, $cols = 2) { $count = count($thumbs); $output = ''; $i = 0; foreach($thumbs as $id => $thumb) { if ($i % $cols == 0) $output .= ''; $description = '
'.truncate_utf8($thumb['title'], 40, FALSE, TRUE).'
'; $output .= ''; if ($i % $cols == $cols - 1 || $n >= $count) $output .= ""; $i++; } $output .= '
'.l('', $_GET['q'], array('title' => $thumb['title'], 'rel' => 'nofollow'), 'page='.$id, NULL, FALSE, TRUE).$description.'
'; return $output; } /************************************************************ * Helper functions - admin settings ************************************************************/ /** * Menu callback; admin settings page. */ function node_images_admin_settings() { _node_images_check_settings(); $form['node_images_path'] = array( '#type' => 'textfield', '#title' => t('Node images path'), '#default_value' => variable_get('node_images_path', 'files'), '#maxlength' => 255, '#description' => t('A file system path where the node images will be stored. This directory has to exist and be writable by Drupal. You can use the following variables: %uid, %username'), '#after_build' => array('_node_images_check_directory'), ); $form['node_images_thumb_resolution'] = array( '#type' => 'textfield', '#title' => t('Resolution for thumbnails'), '#default_value' => variable_get('node_images_thumb_resolution', '100x100'), '#size' => 15, '#maxlength' => 7, '#description' => t('The thumbnail size expressed as WIDTHxHEIGHT (e.g. 100x75).'), ); $form['node_images_medium_resolution'] = array( '#type' => 'textfield', '#title' => t('Resolution for medium image size'), '#default_value' => variable_get('node_images_medium_resolution', '200x200'), '#size' => 15, '#maxlength' => 7, '#description' => t('The thumbnail size expressed as WIDTHxHEIGHT (e.g. 200x150).'), ); $form['node_images_extensions'] = array( '#type' => 'textfield', '#title' => t('Default permitted image extensions'), '#default_value' => variable_get('node_images_extensions', 'jpg jpeg gif png'), '#maxlength' => 255, '#description' => t('Default image extensions that users can upload. Separate extensions with a space and do not include the leading dot.'), ); $form['node_images_max_images'] = array( '#type' => 'textfield', '#title' => t('Maximum number of images'), '#default_value' => variable_get('node_images_max_images', 4), '#size' => 6, '#maxlength' => 2, '#description' => t('The maximum number of images a user can upload for each node.'), ); $form['node_images_md5name'] = array( '#type' => 'checkbox', '#title'=> t('MD5 filenames'), '#description' => t('Override uploaded filenames with the MD5 hash of the file.'), '#default_value' => variable_get('node_images_md5name', FALSE), ); return system_settings_form($form); } /** * Checks if the upload.module is enabled, and the existence of an image toolkit. * * @param $form_element * The form element containing the name of the directory to check. */ function _node_images_check_settings() { // Make sure upload module is enabled if (!module_exists('upload')) { drupal_set_message(t('node_images.module require upload.module to be enabled.'), 'error'); } // Make sure we've got a working toolkit if (!image_get_toolkit()) { drupal_set_message(t('Make sure you have a working image toolkit installed and enabled, for more information see: %settings', array('%settings' => l(t('the settings page'), 'admin/settings/image-toolkit'))), 'error'); } } /************************************************************ * Helper functions - other ************************************************************/ /** * Checks the existence of the destination directory. * The directory can be specified either in $form_element (when called from the admin settings) * or in $path (when called from the node images edit page). * * @param $form_element * The form element containing the name of the directory to check. */ function _node_images_check_directory($form_element = NULL, $path = '') { global $user; $variables = array('%uid' => $user->uid, '%username' => $user->name); if ($form_element) { $path = strtr($form_element['#value'], $variables); _node_images_mkdir_recursive($path, FILE_CREATE_DIRECTORY, $form_element['#parents'][0]); return $form_element; } $path = strtr($path, $variables); _node_images_mkdir_recursive($path, FILE_CREATE_DIRECTORY, $form_element['#parents'][0]); } function _node_images_mkdir_recursive($path, $mode, $form_item) { $folders = explode("/", $path); $dirs = array(); foreach($folders as $folder) { $dirs[] = $folder; if (!file_check_directory(implode("/", $dirs), $mode, $form_item)) { mkdir(implode("/", $dirs)); } } } /** * Return the destination directory. */ function _node_images_get_directory() { global $user; $path = variable_get('node_images_path', 'files'); return strtr($path, array('%uid' => $user->uid, '%username' => $user->name)); } /** * Create the thumbnail for the uploaded image. */ function _node_images_create_thumbnail($path, $suffix='_tn') { $size = variable_get('node_images_thumb_resolution', '100x100'); list($width, $height) = explode('x', $size); $dest_path = preg_replace('!(\.[^/.]+?)?$!', "$suffix\\1", $path, 1); if ($size = getimagesize($path)) { image_scale($path, $dest_path, $width, $height); $info = image_get_info($dest_path); $thumb = new stdClass(); $thumb->filename = basename($dest_path); $thumb->filepath = $dest_path; $thumb->filesize = $info['file_size']; $thumb->filemime = $info['mime_type']; return $thumb; } return NULL; } /** * Create the full size image for the uploaded image. */ function _node_images_create_medium_size($path, $suffix='_md') { $size = variable_get('node_images_medium_resolution', '200x200'); list($width, $height) = explode('x', $size); $dest_path = preg_replace('!(\.[^/.]+?)?$!', "$suffix\\1", $path, 1); if ($size = getimagesize($path)) { image_scale($path, $dest_path, $width, $height); $info = image_get_info($dest_path); $medium = new stdClass(); $medium->filename = basename($dest_path); $medium->filepath = $dest_path; $medium->filesize = $info['file_size']; $medium->filemime = $info['mime_type']; return $medium; } return NULL; } /** * Determine how much disk space is occupied by a user's uploaded files. * * @param $uid * The integer user id of a user. * @return * The amount of disk space used by the user in bytes. */ function _node_images_space_used($uid) { return db_result(db_query('SELECT SUM(filesize+thumbsize) FROM {node_images} WHERE uid=%d', $uid)); } /** * Menu-callback for JavaScript-based uploads. */ function _node_images_js() { $edit = $_POST; if ($nid = $edit['nid']) { $node = node_load($nid); // upload image _node_images_upload($edit, $node); // generate node images edit page $form = _node_images_edit_form($node); } else { drupal_set_message(t('Unable to attach images to the current node.')); } $output = theme('status_messages'); if ($form) $output .= $form; // We send the updated file attachments form. print drupal_to_js(array('status' => TRUE, 'data' => $output)); exit(); } /************************************************************ * Views API hooks ************************************************************/ /** * Implementation of hook_views_default_tables(). */ function node_images_views_tables() { require_once './'. drupal_get_path('module', 'node_images') .'/node_images.views.inc'; return _node_images_views_tables(); } /** * Implementation of hook_views_pre_query(). */ function node_images_views_pre_query() { require_once './'. drupal_get_path('module', 'node_images') .'/node_images.views.inc'; }