Blog entry

IMCE, FileField Sources, private and public files

The issue still isn't solved. So today I made another attempt. Things shouldn't be that complicated. All I want is create nodes with images and links to other files that can be visible for anonymous users or users of a special role. And I want to use IMCE as the file browser.

But now I'm running in circles: with admin/config/media/file-system set to 'public local files served by webserver' IMCE works as expected and finds and inserts the files for public access. But the private section is off limits.

So I added a FileField to a special content type that is only visible to authenticated users. The FileField is set to serve only private files and IMCE is set up as file browser. So far so good. But the files in the private folder cannot be found unless the admin/config/media/file-system is set to 'private local files served by Drupal', otherwise a big 'permission denied' is put up on the screen.

So I switched to 'private', fixed two issues in FileField sources (see below) and was able to select a previously uploaded file. I checked and I could only access the file through the node which was hidden from anonymous users. But..... now the public files are inaccessible for IMCE in the other content types. So I'm back to square one.

Here's a write up of the changes I made to FileField sources to fix the "The selected file could not be used because the file does not exist in the database." error and the fact that there were no upload buttons, just an 'insert file' button on the file browser window.

To fix the last one, just delete or comment out all code in filefield_sources/source/ in the function filefield_source_imce_custom_process.

The error is fixed by a change in the same file, but to the filefield_source_imce_value function. There are several fixes on the Drupal website (a.o. but they don't take into account the fact that for private files Drupal changes the URL to $base_path/system/files/<private path> nor the fact that the base_path could be suffixed by a language indicator. So after reading all the patches and experimenting I added the following code:

global $base_path;

at the top of the function. The line calculating the $uri variable is replaced by

    $searchsrc = '/^(.*)' . preg_quote($base_path . $file_directory_prefix . '/', '/') . '/';
    if ($scheme == 'private') {
        $searchsrc = '/^(.*)' . preg_quote('/system/files' . '/', '/') . '/';
    $uri = preg_replace($searchsrc, $scheme . '://', $item['filefield_imce']['file_path']);


Now I only need to figure out how to make IMCE and FileField play nice with public and private files.