home *** CD-ROM | disk | FTP | other *** search
/ PCGUIA 117 / PC Guia 117.iso / Software / Produtividade / Software2 / Product4 / Setup.exe / drupal-4.6.0 / modules / upload.module < prev    next >
Encoding:
Text File  |  2005-04-01  |  14.9 KB  |  424 lines

  1. <?php
  2. /* $Id: upload.module,v 1.31 2005/04/01 15:55:01 dries Exp $ */
  3.  
  4. /**
  5.  * @file
  6.  * File-handling and attaching files to nodes.
  7.  */
  8.  
  9. /**
  10.  * Implementation of hook_help().
  11.  */
  12. function upload_help($section) {
  13.   switch ($section) {
  14.     case 'admin/modules#description':
  15.       return t('Allows users to upload and attach files to content.');
  16.     case 'admin/settings/upload':
  17.       return t('<p>Users with the <a href="%permissions">upload files permission</a> can upload attachments. You can choose which post types can take attachments on the <a href="%types">content types settings</a> page.</p>', array('%permissions' => url('admin/access'), '%types' => url('admin/node/configure/types')));
  18.   }
  19. }
  20.  
  21. /**
  22.  * Implementation of hook_perm().
  23.  */
  24. function upload_perm() {
  25.   return array('upload files', 'view uploaded files');
  26. }
  27.  
  28. /**
  29.  * Implementation of hook_link().
  30.  */
  31. function upload_link($type, $node = 0, $main = 0) {
  32.   $links = array();
  33.  
  34.   // Display a link with the number of attachments
  35.   if ($main && $type == 'node' && $node->files && user_access('view uploaded files')) {
  36.     $num_files = 0;
  37.     foreach ($node->files as $file) {
  38.       if ($file->list) {
  39.         $num_files++;
  40.       }
  41.     }
  42.     if ($num_files) {
  43.       $links[] = l(format_plural($num_files, '1 attachment', '%count attachments'), "node/$node->nid", array('title' => t('Read full article to view attachments.')), NULL, 'attachments');
  44.     }
  45.   }
  46.  
  47.   return $links;
  48. }
  49.  
  50. /**
  51.  * Implementation of hook_menu().
  52.  */
  53. function upload_menu($may_cache) {
  54.   $items = array();
  55.  
  56.   if ($may_cache) {
  57.     $items[] = array(
  58.       'path' => 'admin/settings/upload', 'title' => t('uploads'),
  59.       'callback' => 'upload_admin',
  60.       'access' => user_access('administer site configuration'),
  61.       'type' => MENU_NORMAL_ITEM
  62.     );
  63.   }
  64.   else {
  65.     // Add handlers for previewing new uploads.
  66.     if ($_SESSION['file_uploads']) {
  67.       foreach ($_SESSION['file_uploads'] as $key => $file) {
  68.         $filename = file_create_filename($file->filename, file_create_path());
  69.         $items[] = array(
  70.           'path' => $filename, 'title' => t('file download'),
  71.           'callback' => 'upload_download',
  72.           'access' => user_access('view uploaded files'),
  73.           'type' => MENU_CALLBACK
  74.         );
  75.         $_SESSION['file_uploads'][$key]->_filename = $filename;
  76.       }
  77.     }
  78.   }
  79.  
  80.   return $items;
  81. }
  82.  
  83. function upload_admin() {
  84.   system_settings_save();
  85.  
  86.   $group .= form_textfield(t('Maximum total file size'), 'upload_maxsize_total', variable_get('upload_maxsize_total', 0), 10, 10, t('The maximum size of a file a user can upload in megabytes. Enter 0 for unlimited.'));
  87.   $group .= form_textfield(t('Maximum resolution for uploaded images'), 'upload_max_resolution', variable_get('upload_max_resolution', 0), 10, 10, t('The maximum allowed image size expressed as WIDTHxHEIGHT (e.g. 640x480). Set to 0 for no restriction.'));
  88.  
  89.   $output = form_group(t('General settings'), $group);
  90.  
  91.   $roles = user_roles(0, 'upload files');
  92.  
  93.   foreach ($roles as $rid => $role) {
  94.     $group = form_textfield(t('Permitted file extensions'), "upload_extensions_$rid", variable_get("upload_extensions_$rid", "jpg jpeg gif png txt html doc xls pdf ppt pps"), 60, 255, t('Extensions that users in this role can upload. Separate extensions with a space and do not include the leading dot.'));
  95.     $group .= form_textfield(t('Maximum file size per upload'), "upload_uploadsize_$rid", variable_get("upload_uploadsize_$rid", 1), 5, 5, t('The maximum size of a file a user can upload (in megabytes).'));
  96.     $group .= form_textfield(t('Total file size per user'), "upload_usersize_$rid", variable_get("upload_usersize_$rid", 10), 5, 5, t('The maximum size of all files a user can have on the site (in megabytes).'));
  97.     $output .= form_group(t('Settings for %role', array('%role' => "<em>$role</em>")), $group);
  98.   }
  99.  
  100.   print theme('page', system_settings_form($output));
  101. }
  102.  
  103. function upload_download() {
  104.   foreach ($_SESSION['file_uploads'] as $file) {
  105.     if ($file->_filename == $_GET['q']) {
  106.       file_transfer($file->filepath, array('Content-Type: '. $file->filemime, 'Content-Length: '. $file->filesize));
  107.     }
  108.   }
  109. }
  110.  
  111. function upload_file_download($file) {
  112.   if (user_access('view uploaded files')) {
  113.     $file = file_create_path($file);
  114.     $result = db_query(db_rewrite_sql("SELECT f.nid, f.* from {files} f WHERE filepath = '%s'", 'f'), $file);
  115.     if ($file = db_fetch_object($result)) {
  116.       $name = mime_header_encode($file->filename);
  117.       // Serve images and text inline for the browser to display rather than download.
  118.       $disposition = ereg('^(text/|image/)', $file->filemime) ? 'inline' : 'attachment';
  119.       return array('Content-Type: '. $file->filemime .'; name='. $name,
  120.                    'Content-Length: '. $file->filesize,
  121.                    'Content-Disposition: '. $disposition .'; filename='. $name);
  122.     }
  123.   }
  124. }
  125.  
  126. /**
  127.  * Implementation of hook_nodeapi().
  128.  */
  129. function upload_nodeapi(&$node, $op, $arg) {
  130.   switch ($op) {
  131.     case 'settings':
  132.       return form_radios(t('Attachments'), 'upload_'. $node->type, variable_get('upload_'. $node->type, 1), array(t('Disabled'), t('Enabled')));
  133.  
  134.     case 'form param':
  135.       if (variable_get("upload_$node->type", 1) && user_access('upload files')) {
  136.         $output['options'] = array('enctype' => 'multipart/form-data');
  137.       }
  138.       break;
  139.  
  140.     case 'validate':
  141.       $node->files = upload_load($node);
  142.  
  143.       // Double check existing files:
  144.       if (is_array($node->list)) {
  145.         foreach ($node->list as $key => $value) {
  146.           if ($file = file_check_upload($key)) {
  147.             $node->files[$file->source] = $file;
  148.             $node->files[$key]->list = $node->list[$key];
  149.             $node->files[$key]->remove = $node->remove[$key];
  150.             if ($file->source) {
  151.               $filesize += $file->filesize;
  152.             }
  153.           }
  154.         }
  155.       }
  156.       else {
  157.         foreach ($node->files as $key => $file) {
  158.           $node->list[$key] = $file->list;
  159.         }
  160.       }
  161.  
  162.       if (($file = file_check_upload('upload')) && user_access('upload files')) {
  163.         global $user;
  164.  
  165.         $file = _upload_image($file);
  166.  
  167.         $maxsize = variable_get("upload_maxsize_total", 0);
  168.         $total_size = upload_count_size() + $filesize;
  169.         $total_usersize = upload_count_size($user->uid) + $filesize;
  170.  
  171.         if ($maxsize && $total_size > $maxsize) {
  172.           form_set_error('upload', t('Error attaching file %name: total file size exceeded', array('%name' => theme('placeholder', $file->filename))));
  173.           break;
  174.         }
  175.  
  176.         // Don't do any checks for uid #1.
  177.         if ($user->uid != 1) {
  178.           // Validate file against all users roles. Only denies an upload when
  179.           // all roles prevent it.
  180.           foreach ($user->roles as $rid => $name) {
  181.             $extensions = variable_get("upload_extensions_$rid", 'jpg jpeg gif png txt html doc xls pdf ppt pps');
  182.             $uploadsize = variable_get("upload_uploadsize_$rid", 1);
  183.             $usersize = variable_get("upload_usersize_$rid", 1);
  184.  
  185.             $regex = '/\.('. ereg_replace(' +', '|', preg_quote($extensions)) .')$/i';
  186.  
  187.             if (!preg_match($regex, $file->filename)) {
  188.               $error['extension']++;
  189.             }
  190.  
  191.             if ($file->filesize > $uploadsize * 1024 * 1024) {
  192.               $error['uploadsize']++;
  193.             }
  194.  
  195.             if ($total_usersize + $file->filesize > $usersize * 1024 * 1024) {
  196.               $error['usersize']++;
  197.             }
  198.           }
  199.         }
  200.  
  201.         // Rename possibly executable scripts to prevent accidental execution.
  202.         // Uploaded files are attachments and should be shown in their original
  203.         // form, rather than run.
  204.         if (preg_match('/\.(php|pl|py|cgi|asp)$/i', $file->filename)) {
  205.           $file->filename .= '.txt';
  206.           $file->filemime = 'text/plain';
  207.         }
  208.  
  209.         if ($error['extension'] == count($user->roles) && $user->uid != 1) {
  210.           form_set_error('upload', t('Error attaching file %name: invalid extension', array('%name' => theme('placeholder', $file->filename))));
  211.         }
  212.         elseif ($error['uploadsize'] == count($user->roles) && $user->uid != 1) {
  213.           form_set_error('upload', t('Error attaching file %name: exceeds maximum file size', array('%name' => theme('placeholder', $file->filename))));
  214.         }
  215.         elseif ($error['usersize'] == count($user->roles) && $user->uid != 1) {
  216.           form_set_error('upload', t('Error attaching file %name: exceeds maximum file size', array('%name' => theme('placeholder', $file->filename))));
  217.         }
  218.         else {
  219.           $key = 'upload_'. count($_SESSION['file_uploads']);
  220.           $file->source = $key;
  221.           $file->list = 1;
  222.           $file = file_save_upload($file);
  223.           $node->files[$key] = $file;
  224.         }
  225.       }
  226.       break;
  227.  
  228.     case 'form post':
  229.       if (variable_get("upload_$node->type", 1) == 1 && user_access('upload files')) {
  230.         $output = upload_form($node);
  231.       }
  232.       break;
  233.  
  234.     case 'load':
  235.       if (variable_get("upload_$node->type", 1) == 1) {
  236.         $output['files'] = upload_load($node);
  237.       }
  238.       break;
  239.  
  240.     case 'view':
  241.       if ($node->files && user_access('view uploaded files')) {
  242.         $header = array(t('Attachment'), t('Size'));
  243.         $rows = array();
  244.         $previews = array();
  245.  
  246.         // Build list of attached files
  247.         foreach ($node->files as $file) {
  248.           if ($file->list) {
  249.             $rows[] = array(
  250.               '<a href="'. ($file->fid ? file_create_url($file->filepath) : url(file_create_filename($file->filename, file_create_path()))) . '">'. $file->filename .'</a>',
  251.               format_size($file->filesize)
  252.             );
  253.             // We save the list of files still in preview for later
  254.             if (!$file->fid) {
  255.               $previews[] = $file;
  256.             }
  257.           }
  258.         }
  259.  
  260.         // URLs to files being previewed are actually Drupal paths. When Clean
  261.         // URLs are disabled, the two do not match. We perform an automatic
  262.         // replacement from temporary to permanent URLs. That way, the author
  263.         // can use the final URL in the body before having actually saved (to
  264.         // place inline images for example).
  265.         if (!variable_get('clean_url', 0)) {
  266.           foreach ($previews as $file) {
  267.             $old = file_create_filename($file->filename, file_create_path());
  268.             $new = url($old);
  269.             $node->body = str_replace($old, $new, $node->body);
  270.             $node->teaser = str_replace($old, $new, $node->teaser);
  271.           }
  272.         }
  273.  
  274.         $teaser = $arg;
  275.         // Add the attachments list
  276.         if (count($rows) && !$teaser) {
  277.           $node->body .= theme('table', $header, $rows, array('id' => 'attachments'));
  278.         }
  279.       }
  280.       break;
  281.  
  282.     case 'insert':
  283.     case 'update':
  284.       if (user_access('upload files')) {
  285.         upload_save($node);
  286.       }
  287.       break;
  288.  
  289.     case 'delete':
  290.       upload_delete($node);
  291.       break;
  292.     case 'search result':
  293.       return $node->files ? format_plural(count($node->files), '1 attachment', '%count attachments') : null;
  294.     case 'rss item':
  295.       if ($node->files) {
  296.         $files = array();
  297.         foreach ($node->files as $file) {
  298.           if ($file->list) {
  299.             $files[] = $file;
  300.           }
  301.         }
  302.         if (count($files) > 0) {
  303.           // RSS only allows one enclosure per item
  304.           $file = array_shift($files);
  305.           return array(array('key' => 'enclosure',
  306.                 'attributes' => array('url' => file_create_url($file->filepath),
  307.                   'length' => $file->filesize,
  308.                   'type' => $file->filemime)));
  309.         }
  310.       }
  311.       break;
  312.   }
  313.  
  314.   return $output;
  315. }
  316.  
  317. function upload_count_size($uid = 0) {
  318.   if ($uid) {
  319.     $result = db_query("SELECT SUM(f.filesize) FROM {files} f INNER JOIN {node} n ON f.nid = n.nid WHERE uid = %d", $uid);
  320.   }
  321.   else {
  322.     $result = db_query("SELECT SUM(f.filesize) FROM {files} f INNER JOIN {node} n ON f.nid = n.nid");
  323.   }
  324.  
  325.   return db_result($result);
  326. }
  327.  
  328. function upload_save($node) {
  329.   foreach ((array)$node->files as $key => $file) {
  330.     if ($file->source && !$file->remove) {
  331.       // Clean up the session:
  332.       unset($_SESSION['file_uploads'][$file->source]);
  333.  
  334.       // Insert new files:
  335.       if ($file = file_save_upload($file, $file->filename)) {
  336.         $fid = db_next_id('{files}_fid');
  337.         db_query("INSERT INTO {files} (fid, nid, filename, filepath, filemime, filesize, list) VALUES (%d, %d, '%s', '%s', '%s', %d, %d)",
  338.                  $fid, $node->nid, $file->filename, $file->filepath, $file->filemime, $file->filesize, $node->list[$key]);
  339.       }
  340.     }
  341.     else {
  342.       // Remove or update existing files:
  343.       if ($node->remove[$key]) {
  344.         file_delete($file->filepath);
  345.         db_query("DELETE FROM {files} WHERE fid = %d", $key);
  346.       }
  347.       if ($file->list != $node->list[$key]) {
  348.         db_query("UPDATE {files} SET list = %d WHERE fid = %d", $node->list[$key], $key);
  349.       }
  350.     }
  351.   }
  352.   return;
  353. }
  354.  
  355. function upload_delete($node) {
  356.   $node->files = upload_load($node);
  357.   foreach ($node->files as $file) {
  358.     file_delete($file->filepath);
  359.   }
  360.   db_query("DELETE FROM {files} WHERE nid = %d", $node->nid);
  361. }
  362.  
  363. function upload_form($node) {
  364.   $header = array(t('Delete'), t('List'), t('Url'), t('Size'));
  365.   $rows = array();
  366.  
  367.   if (is_array($node->files)) {
  368.     foreach ($node->files as $key => $file) {
  369.       $rows[] = array(
  370.         form_checkbox('', "remove][$key", 1, $file->remove),
  371.         form_checkbox('', "list][$key", 1, $file->list),
  372.         $file->filename ."<br /><small>". file_create_url(($file->fid ? $file->filepath : file_create_filename($file->filename, file_create_path()))) ."</small>",
  373.         format_size($file->filesize)
  374.       );
  375.     }
  376.   }
  377.  
  378.   if (count($node->files)) {
  379.     $output = theme('table', $header, $rows);
  380.   }
  381.   if (user_access('upload files')) {
  382.     $output .= form_file(t('Attach new file'), "upload", 40);
  383.     $output .= form_button(t('Attach'), 'fileop');
  384.   }
  385.  
  386.   return '<div class="attachments">'. form_group(t('Attachments'), $output, t('Changes made to the attachments are not permanent until you save this post.  The first "listed" file will be included in RSS feeds.')) .'</div>';
  387. }
  388.  
  389. function upload_load($node) {
  390.   $files = array();
  391.  
  392.   if ($node->nid) {
  393.     $result = db_query("SELECT * FROM {files} WHERE nid = %d", $node->nid);
  394.     while ($file = db_fetch_object($result)) {
  395.       $files[$file->fid] = $file;
  396.     }
  397.   }
  398.  
  399.   return $files;
  400. }
  401.  
  402. /**
  403.  * Check an upload, if it is an image, make sure it fits within the
  404.  * maximum dimensions allowed.
  405.  */
  406. function _upload_image($file) {
  407.   $info = image_get_info($file->filepath);
  408.  
  409.   if ($info) {
  410.     list($width, $height) = explode('x', variable_get('upload_max_resolution', 0));
  411.     if ($width && $height) {
  412.       $result = image_scale($file->filepath, $file->filepath, $width, $height);
  413.       if ($result) {
  414.         $file->filesize = filesize($file->filepath);
  415.         drupal_set_message(t('Your image was resized to fit within the maximum allowed resolution of %resolution pixels.', array('%resolution' => variable_get('upload_max_resolution', 0))));
  416.       }
  417.     }
  418.   }
  419.  
  420.   return $file;
  421. }
  422.  
  423. ?>
  424.