I'm starting work on an ecommerce module to sell MP3 files. To accomplish this, I'd like to introduce some hooks which the audio.module would invoke, and my ecommerce module would implement. I think the hooks could be applied in other contexts, maybe eventually becoming part of Drupal core. That's why I'm sending this to a large audience. I hope all interested parties will let me know if the direction sounds right. I'd like to start solving my problem immediately, making changes to audio.module and an ecommerce module. But I'm open to other approaches if consensus is that the following ideas need work. SPECIFIC PROBLEM ---------------- I'm creating an ecommerce product to sell access to files, specifically MP3 audio files. While there exists a generic file product in the ecommerce module, the audio module is superior when it comes to MP3s. So, I want to use audio module nodes as my products. The difficulty lies in download permissions. I want only users who have purchased an MP3 to be able to download it. But audio.module controls its own downloads. So how to make audio.module obey my product permissions? GENERAL PROBLEM --------------- In Drupal today there are a handful of modules which deal with the uploading and downloading of files. Examples include upload.module, audio.module and the ecommerce file product. Each of these modules contains it's own functions to handle saving and downloading of files. Each of these modules has overlapping functionality because there is no file management piece of Drupal that meets the needs of all of them. While people are working towards better file management in core, in the 4.7 timeframe we have to accept that many modules will be doing some facet of file management. This is a problem for anyone wishing to develop modules that customize file upload/download behavior. PROPOSAL -------- To solve the problem I propose the following APIs. Any file management module (ie upload.module, audio.module) would have to invoke these hooks to be considered "well behaved". Third-party modules implement the hooks in order to have influence over the file managing modules. The APIs fall into two categories: 1) Notification of file events (uploads, downloads) 2) Grant permission to allow file events. In the APIs, files are identified by a numerical $fid and a string $realm. Together, these combine to form a unique file identifier. In the case of upload.module, each file has an $fid from the files table, and the realm could be 'upload'. In the case of audio.module, each node has one file so the $nid is also the $fid, and the realm would be 'audio'. The file management modules would have to implement logic like this when performing file operations: if (user does not have explicit permission to perform operation) { $result = module_invoke hook_file_access for the operation; if ($result contains TRUE) { perform the operation; module_invoke hook_fileapi; // notify that operation has occurred else do not perform; // (access denied) } else { // user has explicit permission to perform op perform the operation; module_invoke hook_fileapi; // notify that operation has occurred } Here are function signatures for the hooks as I imagine them: /** * hook_fileapi * * This hook is invoked when file events occur. * * @param $fid * A numeric file id * @param $realm * A string, combined with $fid ensures a unique file identification * @param $node * The node, if any, with which the file is associated. * @param $op * The type of event ('upload', 'download', 'update', 'delete') * @param $info * Associative array of file details ('filesize', 'filepath', 'filemime',...) * * @return * Nothing */ function hook_fileapi($fid, $realm, $node, $op, $info) { // third party module code goes here. } /** * hook_file_access * * This hook gives us a chance to allow file operations which would * otherwise not be permitted. * * @param $fid * A numeric file id or NULL if $op is 'upload' * @param $realm * A string, combined with $fid ensures unique file identification * @param $node * The node, if any with which the file is assiciated * @param $op * The type of event ('upload', 'download', 'update', 'delete') * @param $info * Associative array of file details ('filesize', 'filepath', 'filemime',...) * @param $account * The user who may or may not have permission to perform the operation * * @return * TRUE, if and only if the user is allowed to perform the operation */ function hook_file_access($fid, $realm, $node, $op, $info, $account) { // third-party logic here if ($is_allowed) return TRUE; } RELATED READING --------------- http://drupal.org/node/33708 (permissions and audio module) http://groups.drupal.org/file-api (file api discussion on groups.drupal.org) http://dave-cohen.com/node/1045 (my own ideas about Drupal file management) http://dave-cohen.com/node/1050 (creating ecommerce products out of nodes) I realize this is a long post. Thanks for reading.