Index: field_file.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/flexinode/field_file.inc,v retrieving revision 1.12 diff -u -u -p -r1.12 field_file.inc --- field_file.inc 16 Apr 2005 12:54:16 -0000 1.12 +++ field_file.inc 2 Aug 2005 17:27:18 -0000 @@ -1,6 +1,11 @@ field_id; - $node->$fieldname = file_save_upload($node->$fieldname, $node->$fieldname->filename); + // either overwrite existing file, or use destination specific to this field + $default_dest = variable_get('file_directory_path', 'files'); + $dest = $default_dest . '/' .$field->options[FLEXINODE_FILE_DESTINATION]; + + // TODO: handle case when file_check_directory fails + // file_check_directory will attempt to create a directory if it does not exist + // how do I abort the insert if directory creation fails??? + file_check_directory($dest, FILE_CREATE_DIRECTORY, $fieldname); + + $node->$fieldname = file_save_upload($node->$fieldname, $dest, FILE_EXISTS_RENAME); + + // when downloading, the textual_data field must match the + // ?file=... parameter as generated by file_create_url. So for + // instance if this node has a file located in + // files/private_stuff/foo.txt, we need the string + // "private_stuff/foo.txt" + // so we emulate file_create_url here. If the code there changes, this could break + $urlpath = trim(substr($node->$fieldname->filepath, strlen($default_dest)), '\\/'); + $serialized = is_object($node->$fieldname) ? serialize($node->$fieldname) : ''; - db_query("INSERT INTO {flexinode_data} (nid, field_id, textual_data, serialized_data) VALUES (%d, %d, '%s', '%s')", $node->nid, $field->field_id, $node->$fieldname->filename, $serialized); + + db_query("INSERT INTO {flexinode_data} (nid, field_id, textual_data, serialized_data) VALUES (%d, %d, '%s', '%s')", $node->nid, $field->field_id, $urlpath, $serialized); } function flexinode_field_file_delete($field, $node, $unconditional = 0) { @@ -61,6 +85,20 @@ function flexinode_field_file_load($fiel return unserialize($node->$fieldname); } +function flexinode_field_file_config($field, $edit) { + $option_fields .= form_textfield(t('Save File In'), + 'options][', + $edit['options'][FLEXINODE_FILE_DESTINATION], + 60, 128); + // TODO: dropdown list of all known permissions, to avoid typos + $option_fields .= form_textfield(t('Permission Required For Download'), + 'options][', + $edit['options'][FLEXINODE_FILE_PERMISSION], + 60, 128); + return form_group(t('Options'), $option_fields, + t('Specify a subdirectory of %default_dest where this file should be saved, and require permission to download. Leave blank to allow anyone to download.', array('%default_dest' => variable_get('file_directory_path', 'files')))); +} + /** * @addtogroup themeable Index: flexinode.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/flexinode/flexinode.module,v retrieving revision 1.50 diff -u -u -p -r1.50 flexinode.module --- flexinode.module 25 Jul 2005 16:43:34 -0000 1.50 +++ flexinode.module 2 Aug 2005 17:27:18 -0000 @@ -716,8 +716,29 @@ function flexinode_content($node, $tease */ function flexinode_file_download($file) { if (!$file) return false; - $result = db_fetch_object(db_query("SELECT f.* FROM {flexinode_data} f WHERE f.textual_data = '%s'", $file)); + $result = db_fetch_object(db_query("SELECT f.*, ff.options FROM {flexinode_data} f LEFT JOIN {flexinode_field} ff ON f.field_id=ff.field_id WHERE f.textual_data = '%s'", $file)); if (!$result) return false; + + // check if file has permissions associated with it + $options = unserialize($result->options); + $permission = $options[FLEXINODE_FILE_PERMISSION]; + if ($permission && !user_access($permission)) { + // returning -1 will cause access to be denied. A watchdog entry will be written. However, because it may be difficult for an admin to determine why access is denied, write a more verbose message here. + watchdog('access denied', t("%page denied access to download files from node %nid because user does not have '%perm' permission.", array('%page' => $file, '%nid' => $result->nid, '%perm' => $permission)), WATCHDOG_NOTICE); + return -1; + } + // Here I try to limit access to the file only if the user can view the node. + // I was thinking node_access would call into the taxonomy_access hooks, + // but it doesn't work that way. Instead it calls flexinode_access() which is only about creating and editing flexinodes. + // Anyone know how I can limit access only to those who can view the node??? + /* -- doesn't work, commented out. + if (!node_access('view', array('nid' => $result->nid))) { + watchdog('access denied', t("%page denied access because user is denied access to view node %nid.", array('%page' => $file, '%nid' => $result->nid)), WATCHDOG_NOTICE); + return -1; + } + */ + + // file exists and user has permission to download $filedb = unserialize($result->serialized_data); if ($filedb->type) { return array('Content-type: '. $filedb->type, 'Content-Disposition: attachment; filename="'. $file .'"');