? 371656.views_service_modify.patch ? file_service_save.patch Index: services/file_service/file_service.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/services/services/file_service/Attic/file_service.inc,v retrieving revision 1.1.2.5 diff -u -p -r1.1.2.5 file_service.inc --- services/file_service/file_service.inc 1 Sep 2008 15:31:06 -0000 1.1.2.5 +++ services/file_service/file_service.inc 13 Mar 2009 22:51:05 -0000 @@ -12,7 +12,7 @@ * @param $fid * Number. File ID * @return - * Array. All elements fomr a given file + * Array. All elements for a given file */ function file_service_get($fid) { if ($file = db_fetch_array(db_query('SELECT * FROM {files} WHERE fid = %d', $fid))) { @@ -95,3 +95,89 @@ function file_service_get_node_files_acc return $node->uid == $user->uid and user_access('get own binary files'); } } + +/** + * Check if the user has permission to save file information. + * + * Will probably want to revisit this down the road to make it + * somewhat tougher, esp if we get to the point where we're saving + * actual files (see below.) + */ +function file_service_save_access() { + global $user; + return user_access('save file information'); +} + +/** + * Save file information. + * + * This is basically a copy of file_save_upload() from includes/file.inc + * without the upload-specific requirements. In D7 with File API this will + * be a lot easier to deal with. + * + * @param $file + * Array representing the file information + */ +function file_service_save($file) { + global $user; + $file = (object) $file; + + // If the file data is empty then bail + if (!isset($file->file)) { + return FALSE; + } + + // If the submitted file is an update, then set the update parameter for + // drupal_write_record(), indicating such. Otherwise we can just pass the + // object in and it will be treated as an insert. + $update = array(); + if (!empty($file->fid)) { + $update = 'fid'; + } + + // Build the list of non-munged extensions. + // @todo: this should not be here. we need to figure out the right place. + // @todo: also isn't that repeated variable get a waste? I mean, I guess it + // is cached but still it is pretty ugly. + $extensions = ''; + foreach ($user->roles as $rid => $name) { + $extensions .= ' '. variable_get("upload_extensions_$rid", + variable_get('upload_extensions_default', 'jpg jpeg gif png txt html doc xls pdf ppt pps odt ods odp')); + } + + // Update file object as necessary + $file->filepath = file_destination(file_create_path($file->filepath), FILE_EXISTS_RENAME); + $file->filename = file_munge_filename(trim(basename($file->filepath), '.'), $extensions, TRUE); + $file->filemime = file_get_mimetype($file->filename); + + // Rename potentially executable files, to help prevent exploits. + if (preg_match('/\.(php|pl|py|cgi|asp|js)$/i', $file->filename) && (substr($file->filename, -4) != '.txt')) { + $file->filemime = 'text/plain'; + $file->filepath .= '.txt'; + $file->filename .= '.txt'; + } + + // If the destination is not provided, or is not writable, error our + if (empty($file->filepath) || file_check_path($file->filepath) === FALSE) { + return services_error("Destintion directory does not exist or is not writeable."); + } + + // Write the file + if (!file_save_data(base64_decode($file->file), $file->filepath .'/'. $file->filename)) { + return services_error("Could not write file to destination"); + } + + // If we made it this far it's safe to record this file in the database. + drupal_write_record('files', $file, $update); + + // hook_file_insert() requires an object + if (empty($update)) { + foreach (module_implements('file_insert') as $module) { + $function = $module .'_file_insert'; + $function($file); + } + } + + // Return the fid + return $file->fid; +} Index: services/file_service/file_service.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/services/services/file_service/Attic/file_service.info,v retrieving revision 1.1.2.1 diff -u -p -r1.1.2.1 file_service.info --- services/file_service/file_service.info 1 Sep 2008 12:39:14 -0000 1.1.2.1 +++ services/file_service/file_service.info 13 Mar 2009 22:51:05 -0000 @@ -3,4 +3,10 @@ core = "6.x" dependencies[] = services description = "Provides a file service." name = "File Service" -package = "Services - services" \ No newline at end of file +package = "Services - services" +; Information added by drupal.org packaging script on 2008-09-06 +version = "6.x-0.13" +core = "6.x" +project = "services" +datestamp = "1220743239" + Index: services/file_service/file_service.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/services/services/file_service/Attic/file_service.module,v retrieving revision 1.1.2.6 diff -u -p -r1.1.2.6 file_service.module --- services/file_service/file_service.module 6 Sep 2008 04:13:07 -0000 1.1.2.6 +++ services/file_service/file_service.module 13 Mar 2009 22:51:05 -0000 @@ -10,7 +10,7 @@ * Implementation of hook_perm(). */ function file_service_perm() { - return array('get any binary files', 'get own binary files'); + return array('get any binary files', 'get own binary files', 'save file information'); } /** @@ -51,5 +51,22 @@ function file_service_service() { '#return' => 'array', '#help' => t('Returns the files attached to a node.') ), + + // file.save + array( + '#method' => 'file.save', + '#callback' => 'file_service_save', + '#access arguments' => 'save file information', + '#file' => array('file' => 'inc', 'module' => 'file_service'), + '#args' => array( + array( + '#name' => 'file', + '#type' => 'struct', + '#description' => t('An object representing a file.'), + ), + ), + '#return' => 'int', + '#help' => t('Saves information about a specific file. Note this does not save files themselves, just the information as stored in the files table. Returns the fid of the new/updated file.'), + ), ); }