You are here

function _file_resource_create in Services 6.3

Same name and namespace in other branches
  1. 7.3 resources/file_resource.inc \_file_resource_create()

Adds a new file and returns the fid.

Parameters

$file: An array as representing the file.

Return value

Unique identifier for the file (fid) or errors if there was a problem.

1 string reference to '_file_resource_create'
_file_resource_definition in resources/file_resource.inc
THERE SHOULD BE NO UPDATE!!! Drupal doesn't allow updating or replacing a file in the files table. If you need to, create a new file and remove the old file.

File

resources/file_resource.inc, line 167
File resource.

Code

function _file_resource_create($file) {
  $file = _services_arg_value($file, 'file');
  global $user;

  // If the file data is empty then bail.
  if (!isset($file['file'])) {
    return services_error('No file data received.');
  }

  // Check whether we have filename or filepath for the file.
  if ((!isset($file['filename']) || empty($file['filename'])) && (!isset($file['filepath']) || empty($file['filepath']))) {
    return services_error('No filename and no filepath specified or they are both empty.');
  }

  // Ensure we create new file.
  $file['fid'] = NULL;

  // 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'));
  }

  // If filename has not been specified extract it from filepath.
  if (!isset($file['filename']) || empty($file['filename'])) {
    $file['filename'] = trim(basename($file['filepath']), '.');
  }

  // If no filepath specified use standard directory.
  if (!isset($file['filepath']) || empty($file['filepath'])) {
    $file['filepath'] = file_directory_path() . '/' . $file['filename'];
  }

  // Get the directory name for the location of the file:
  $dir = dirname($file['filepath']);

  // Build the destination folder tree if it doesn't already exists.
  // @see http://drupal.org/node/180970
  $dir_array = explode('/', $dir);
  $file_check_directory_array = array();
  foreach ($dir_array as $dir_element) {
    $file_check_directory_array[] = $dir_element;
    $dir_path_element = implode('/', $file_check_directory_array);
    file_check_directory($dir_path_element, FILE_CREATE_DIRECTORY);
  }
  if (!file_check_directory($dir, FILE_CREATE_DIRECTORY)) {
    return services_error("Could not create destination directory for file. " . $dir);
  }

  // Update file data 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']);
  $destination = file_destination(file_create_path($file['filepath']), FILE_EXISTS_RENAME);

  // Rename potentially executable files, to help prevent exploits.
  if (preg_match('/\\.(php|pl|py|cgi|asp|js)$/i', $file['filename']) && drupal_substr($file['filename'], -4) != '.txt') {
    $file['filemime'] = 'text/plain';
    $file['filepath'] .= '.txt';
    $file['filename'] .= '.txt';

    // As the file may be named example.php.txt, we need to munge again to
    // convert to example.php_.txt, then create the correct destination.
    $file['filename'] = file_munge_filename($file['filename'], $extensions, TRUE);
    $destination = file_destination(file_create_path($file['filepath']), FILE_EXISTS_RENAME);
  }
  if (!($filename = file_save_data(base64_decode($file['file']), $destination))) {
    return services_error("Could not write file to destination");
  }
  $file['filepath'] = $destination;

  // Set the file user id.
  $file['uid'] = $user->uid;

  // Update the timestamp to the current time, otherwise the file could
  // get deleted on the next cron run if its status is set to 0.
  $file['timestamp'] = time();

  // If we made it this far it's safe to record this file in the database.
  drupal_write_record('files', $file);
  return array(
    'fid' => $file['fid'],
    'uri' => services_resource_uri(array(
      'file',
      $file['fid'],
    )),
  );
}