"Makes the files private for a particular field.", 'arguments' => array( 'entity_type' => 'The entity type. Usually \'node\' or \'comment\'.', 'bundle' => 'The content type. For example, \'document\'.', 'field' => 'The field to be made private. For example, \'field_doc_file\'.', 'source' => 'source directory URI, i.e., public://example.', 'destination' => 'destination directory URI.', ), 'examples' => array( 'drush privatize-one-field node document field_doc_file public:// private://node/document/field_doc_file', 'drush privatize-one-field comment comment_node_article field_article_comment_file', ), ); return $items; } /** * Implements drush_hook_COMMAND(). */ function drush_privatize_one_field($entity_type, $bundle, $field, $source = NULL, $destination = NULL) { if (empty($entity_type) || empty($bundle) || empty($field)) { return; }; if (empty($source)) { $source = 'public://'; } if (empty($destination)) { $destination = 'private://' . $entity_type . '/' . $bundle . '/' . $field . '/'; } if (substr($destination, -1) !== '/') { $destination = $destination . '/'; } if (drush_confirm(dt('Do you want to move all %bundle files in %source to %destination?', array( '%bundle' => $bundle, '%source' => $source, '%destination' => $destination)))) { drush_print('================================================================================'); drush_print(date("Y-m-d H:i:s")); drush_print('================================================================================'); module_disable(array('apachesolr_attachments')); _privatize_one_field_move_files_one_field($entity_type, $bundle, $field, $source, $destination); $query = ''; $query .= 'SELECT data FROM field_config WHERE field_name = \'' . $field . '\''; $results = db_query($query)->fetchCol(); $field_config_data = unserialize(reset($results)); $field_config_data['settings']['uri_scheme'] = 'private'; // Change the uri_scheme from public to private. $field_info_field = field_info_field($field); $field_info_field['settings']['uri_scheme'] = 'private'; field_update_field($field_info_field); $field_info_instance = field_info_instance($entity_type, $field, $bundle); // Set the file upload directory. $file_directory = substr($destination, strpos($destination, '//') + 2); $file_directory = rtrim($file_directory, '/'); $field_info_instance['settings']['file_directory'] = $file_directory; // Change the media allowed_schemes settings. if (isset($field_info_instance['widget']['settings']['allowed_schemes'])) { if (in_array('public', $field_info_instance['widget']['settings']['allowed_schemes'])) { $field_info_instance['widget']['settings']['allowed_schemes'] = array( 'private', ); } } field_update_instance($field_info_instance); module_enable(array('apachesolr_attachments')); drush_print('================================================================================'); drush_print(date("Y-m-d H:i:s")); drush_print('================================================================================'); } } /** * Move the files to the new structure. */ function _privatize_one_field_move_files_one_field($entity_type, $bundle, $field, $source, $destination) { $query = ''; $query .= 'SELECT ' . $field . '_fid AS fid'; $query .= ' FROM field_data_' . $field; $query .= ' JOIN file_managed'; $query .= ' ON file_managed.fid = field_data_' . $field . '.' . $field . '_fid'; if ($entity_type == 'node') { $query .= ' JOIN node'; $query .= ' ON node.nid = field_data_' . $field . '.entity_id'; $query .= ' WHERE node.type = \'' . $bundle . '\''; } elseif ($entity_type == 'comment') { $query .= ' JOIN comment'; $query .= ' ON comment.cid = field_data_' . $field . '.entity_id'; } else { drush_print('We currently assume that the entity type is either node or comment.'); exit; } $query .= ' AND file_managed.uri LIKE \'' . $source . '%\''; $results = db_query($query)->fetchCol(); $files = file_load_multiple($results); $moves = array(); foreach ($files as $file) { $file->new_uri = str_replace($source, $destination, $file->uri); $dir = dirname($file->new_uri); // Debug // if (!file_exists($dir)) { // drush_print("Please create the directory on the $destination file system:"); // drush_print($dir); // exit; // } // Break the directory into it's paths, so moves are stored hierarchically. $move = &$moves; $paths = explode('/', substr($dir, strlen($destination))); foreach ($paths as $path) { $move = &$move[$path]; } // Make the move plan. If the directory exists, move the file, otherwise // attempt to move the directory first. if (!file_exists($dir)) { $move['#source'] = dirname($file->uri); } $move['#destination'] = $dir; $move['#files'][] = $file; } // Now move the files and update the database. _privatize_one_field_move_organized_files($moves); return TRUE; } /** * Move files using the organized plan created in _privatize_move_files(). * * This recursively walks the move plan. * * @param array $move * Deep array of directory hierarchy move plan. */ function _privatize_one_field_move_organized_files($move) { // Check if there is something to move at this hierarchical level. if (isset($move['#destination'])) { // Commented out. We explicitly want to move each file individually, // because we don't have a clean directory structure in the public files // folder. // Try moving the directory first. // if (_privatize_move_organized_using_dir($move)) { // return; // } // // When the directory move fails, move each file individually. _privatize_one_field_move_organized_using_files($move); } // Move the sub-directories. $children = element_children($move); if ($children) { foreach ($children as $child) { _privatize_one_field_move_organized_files($move[$child]); } } } /** * @param array $move * #source - source directory URI. * #destination - destination directory URI. * #files - array of File objects found in source directory. * * @return bool * TRUE if all files are moved, FALSE on any one failure. */ function _privatize_one_field_move_organized_using_files(array $move) { // Move the files individually. // Make sure the directory exists first. if (file_prepare_directory($move['#destination'], FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) { // Move all of the files in the directory. $status = TRUE; foreach ($move['#files'] as $file) { if (!file_exists($file->uri)) { $status = FALSE; // watchdog('privatize', 'Missing file %source, file not moved.', array('%source' => $file->uri), WATCHDOG_ERROR); drush_print('================================================================================'); drush_print('MISSING file:'); drush_print_r($file); drush_print('================================================================================'); } elseif (file_move($file, $file->new_uri)) { // watchdog('privatize', 'File moved from %source to %destination.', array('%source' => $file->uri, '%destination' => $file->new_uri)); drush_print('================================================================================'); drush_print('FOUND file:'); drush_print_r($file); drush_print('================================================================================'); } } } else { $status = FALSE; watchdog('privatize', 'Directory %dir cannot be prepared.', array('%dir' => $move['#destination']), WATCHDOG_ERROR); } return $status; }