type", 0) == 1)) {
$form = attachment_form($node, $arg);
}
return $form;
case 'form param':
if (user_access('add attachments') && (variable_get("attachment_node_$node->type", 0) == 1)) {
$param['options'] = array('enctype' => 'multipart/form-data');
}
return $param;
case 'settings':
return form_radios(t('Attachments'), 'attachment_node_'. $node->type, variable_get('attachment_node_'. $node->type, 0), array(t('Disabled'), t('Enabled')));
case 'load':
return attachment_load($node);
case 'view':
foreach ((array)$node->attachments as $attachment) {
if ($attachment['working']) {
$file = module_invoke('filemanager', 'get_file_info', $attachment['fid']);
$workingurl = str_replace('&', '&', module_invoke('filemanager', 'url', $file, TRUE));
$activeurl = str_replace('&', '&', module_invoke('filemanager', 'url', $file, FALSE));
$node->body = str_replace($activeurl, $workingurl, $node->body);
$node->teaser = str_replace($activeurl, $workingurl, $node->teaser);
}
}
// If this is not a teaser add our attachment list to the end of the body
if (_attachment_countvisible($node)>0) {
if (!$arg) {
$node->body .= '
' . theme('attachments', $node);
}
if (variable_get('attachment_display_teaser', 0)) {
$node->teaser .= '
' . theme('attachments', $node);
}
}
return;
case 'insert':
case 'update':
foreach ((array)$node->attachments as $attachment) {
if (!$attachment['deleted']) {
module_invoke('filemanager', 'promote_working', $attachment['fid']);
if ($attachment['aid']) {
db_query("UPDATE {attachment} SET title='%s', description = '%s', size=%d, hidden='%s' WHERE aid=%d", $attachment['title'], $attachment['description'], $attachment['size'], $attachment['hidden'], $attachment['aid']);
}
else {
$aid = db_next_id('{attachment}_aid');
db_query("INSERT INTO {attachment} (aid,title,description,nid,fid,filename,size,hidden) VALUES (%d,'%s','%s',%d,%d,'%s',%d,'%s')", $aid, $attachment['title'],$attachment['description'],$node->nid, $attachment['fid'], $attachment['filename'], $attachment['size'], $attachment['hidden']);
}
}
else {
module_invoke('filemanager', 'delete', $attachment['fid']);
if ($attachment['aid']) {
db_query("DELETE FROM {attachment} WHERE aid=%d",$attachment['aid']);
}
}
}
return;
case 'delete':
foreach ((array)$node->attachments as $attachment) {
module_invoke('filemanager', 'delete', $attachment['fid']);
if ($attachment['aid']) {
db_query("DELETE FROM {attachment} WHERE aid=%d",$attachment['aid']);
}
}
return;
case 'validate':
switch ($_POST['fileop']) {
case t('Add'):
return attachment_add($node);
case t('Delete'):
return attachment_delete($node);
case t('Change title/desc'):
return attachment_change($node);
}
return;
}
}
/**
* Implementation of hook_perm()
*/
function attachment_perm() {
return array('add attachments');
}
/**
* Implementation of hook_settings()
*/
function attachment_settings() {
$output = form_textarea(t('File extension whitelist'), 'attachment_text_rename_whitelist', ATTACHMENT_EXTENSION_WHITELIST, 60, 10, t('List of extensions that are allowed to be uploaded without modification. All other extensions can still be uploaded, but they will be renamed to have a .txt file extension to protect your server from attackers.'));
return $output;
}
/**
* Implementation of hook_file_areas()
*/
function attachment_filemanager_areas() {
return array(array('area'=>'attachments','name'=>t('Attachments'),'description'=>t('Area where all node attachments are stored.')));
}
/**
* Implementation of hook_help()
*/
function attachment_help($section) {
switch ($section) {
case 'admin/modules#description':
return t('Adds support for attaching files to nodes and downloading them.');
case 'admin/help#attachment':
return t('
Attachments are files uploaded while creating nodes. These files can be used to add images to stories, blogs, etc as well as just adding documents for download.
There are two factors used to determine whether a user can add attachments to the node they are creating. First the user is checked to make sure they have add attachments permission. These permissions can be set on the permissions page. Second attachments must be enabled for that particular node type. You can enable nodes on the default workfow page.
', array('%permissionurl' => url('admin/user/configure/permission'), '%nodeconfigurl' => url('admin/node/configure/defaults'))); } } /** * Implementation of hook_link() */ function attachment_link($type, $node = 0, $main = 0) { $links = array(); switch($type) { case 'node': if ($main == 1 && !variable_get('attachment_display_teaser', 0)) { $count = _attachment_countvisible($node); if ($count > 0) { $links[] = l(format_plural($count, 'attachment', '%count attachments'), "node/$node->nid", array('title' => t('View attachment list')), NULL, "attachments"); } } break; } return $links; } /** * Counts the number of visible attachments */ function _attachment_countvisible($node) { $count = 0; foreach((array)$node->attachments as $attachment) { if (!$attachment['hidden'] && !$attachment['deleted']) { $count++; } } return $count; } /** * Generates attachment form elements */ function attachment_form(&$node, $arg) { $output = ''; return $output; } /** * Munge the filename as needed for security purposes. Protects site from having * attacments executed as scripts. * * @param object $file * The $file object as obtained by file_check_upload('attachment_file'); */ function attachment_munge_file(&$file) { $whitelist = array_unique(split(' +', ATTACHMENT_EXTENSION_WHITELIST)); $filename_parts = explode('.', $file->filename); $new_filename = array_shift($filename_parts); // Remove file basename. $final_extension = array_pop($filename_parts); // Remove final extension. foreach($filename_parts as $filename_part) { $new_filename .= ".$filename_part"; if (!in_array($filename_part, $whitelist) && preg_match("/^[a-zA-Z]{2,5}\d?$/", $filename_part)) { $new_filename .= '_'; } } $file->filename = "$new_filename.$final_extension"; if ($final_extension == 'txt') { $file->filemime = 'text/plain'; } } /** * Callback function to add an attachment to a node being edited. -------------------------------------------------------------------------------- -- date who what -- -------- ---------- --------------------------------------------------------- -- 20070112 mhweb changed 'title' and 'description' to -- node values -------------------------------------------------------------------------------- */ function attachment_add(&$node) { $file = file_check_upload('attachment_file'); if (!$file) { form_set_error('attachment_file', t('No file selected.')); return $node; } // protect from uploaded files being executed as scripts attachment_munge_file($file); $new_attachment['fid'] = FALSE; $new_attachment['filename'] = $file->filename; $new_attachment['deleted'] = FALSE; $new_attachment['working'] = TRUE; $new_attachment['size'] = $file->filesize; // If we are uploading a file with the same name as an existing // attachment then we should use the same fid and remove the // existing attachment from the array. foreach ((array)$node->attachments as $key => $attachment) { if ($attachment['filename'] == $new_attachment['filename']) { $new_attachment['fid'] = $attachment['fid']; $remove_key = $key; } } if (isset($remove_key)) { array_splice($node->attachments, $key, 1); } else { //mhweb: 20070112 $new_attachment['title'] = $node->attachment_title; //$file->filename; $new_attachment['description'] = $node->attachment_description; //''; $node->attachmentcount++; } // Move the upload file into working filestore $file = module_invoke('filemanager', 'add_upload', 'attachment_file', 'attachments', variable_get('attachment_private_files', 0), $new_attachment["fid"]); if (!$file) { form_set_error('attachment_file', t('Error saving upload to filestore.')); return $node; } $new_attachment['fid'] = $file->fid; $node->attachments[] = $new_attachment; } /** * Load the attachments for the given node */ function attachment_load($node) { $result = db_query("SELECT aid, title, description, fid, filename, size, hidden FROM {attachment} WHERE nid = %d", $node->nid); while ($attachment = db_fetch_array($result)) { $attachment['deleted'] = FALSE; $attachment['working'] = FALSE; $attachments[] = $attachment; } $fields['attachments'] = $attachments; return $fields; } function attachment_filemanager_download($file) { if ($file->area == 'attachments') { // check if current user has right to view the node this file is attached to. $nid = db_result(db_query("SELECT nid FROM {attachment} WHERE {attachment}.fid = %d", $file->fid)); $node = node_load(array('nid'=>$nid)); if (node_access('view', $node)) { return TRUE; } else { return FALSE; } } } /** * Removes an attachment from the node. This removes the file from temporary * if necessary. Attachments are not removed from the database or permanent * storage until the node is submitted. */ function attachment_delete(&$node) { for ($attachindex = 0; $attachindex < count($node->attachments); $attachindex++) { if ($node->attachments[$attachindex]['selected']) { module_invoke('filemanager', 'purge_working', $node->attachments[$attachindex]['fid']); $node->attachments[$attachindex]['working'] = FALSE; $node->attachments[$attachindex]['deleted'] = TRUE; } } unset($node->attachment_title); unset($node->attachment_description); } function attachment_change(&$node) { for ($attachindex = 0; $attachindex < count($node->attachments); $attachindex++) { if ($node->attachments[$attachindex]['selected']) { $node->attachments[$attachindex]['title'] = $node->attachment_title; $node->attachments[$attachindex]['description'] = $node->attachment_description; } } unset($node->attachment_title); unset($node->attachment_description); } /** * @addtogroup themeable * @{ */ /** * Formats a list of attachments for a given node. */ function theme_attachments($node) { $output = "\n"; return $output; } /** * @} end of addtogroup themeable */