Privatizing fields with existing content

Recently, I came across a situation where I needed to convert the file system from public:// to private:// on a project. As anyone in this situation knows, converting the drupal system defaults is easy enough to do from admin/config/media/file-system. But converting fields on existing content types with existing data is not so easy.

There are a couple of methods explaining how to do this, and even a Privatize module to convert all files to private. But converting individual fields takes a little more work. The solution that worked for me was this custom drush command by michaellenahan.

Once you have the drush command installed, you can use it like this:

drush privatize-one-field node article field_article_files public:// private://node/article/field_article_files | tee field_article_files.txt

See the full comment here:
https://www.drupal.org/node/2059619#comment-9924902

This command builds on the Privatize module, by letting you define which content type and field you want to convert to private, define the source and destination path, and output a text file to scan through the results. My favorite feature of the command though, is it returns a nice object for each file assigned to that field right there in command-line to verify the individual file path changes.

FOUND file:
stdClass Object
(
    [fid] => 393
    [uid] => 51954
    [filename] => Weekly Update 8.3.15.pdf
    [uri] => public://weekly_updates/Weekly Update 8.3.15.pdf
    [filemime] => application/pdf
    [filesize] => 671889
    [status] => 1
    [timestamp] => 1438974703
    [type] => document
    [rdf_mapping] => Array
        (
        )

    [metadata] => Array
        (
        )

    [alt] =>
    [title] =>
    [new_uri] => private://node/weekly_update/field_weekly_update_pdf/weekly_updates/Weekly Update 8.3.15.pdf
)

So now, after you've run the command and modified the field to private, if you go back and look at your field settings in drupal you will see that the field settings for Upload Destination are now private. This is assuming of course you have set your drupal default settings to private.

Transversely, if you already have private files and need to switch them to public, there is a good example of code you can add to your module here, using hook_update_N().

=================

Comments

Great delivery. Solid arguments. Keep up the great work.