/** * {@inheritdoc} */ public function import(Row $row, array $old_destination_id_values = array()) { $source = $this->configuration['source_base_path'] . $row->getSourceProperty($this->configuration['source_path_property']); $destination = $row->getDestinationProperty($this->configuration['destination_path_property']); $replace = FILE_EXISTS_REPLACE; if (!empty($this->configuration['rename'])) { $entity_id = $row->getDestinationProperty($this->getKey('id')); if (!empty($entity_id) && ($entity = $this->storage->load($entity_id))) { $replace = FILE_EXISTS_RENAME; } } $dirname = drupal_dirname($destination); if (!file_prepare_directory($dirname, FILE_CREATE_DIRECTORY)) { throw new MigrateException(t('Could not create directory %dirname', array('%dirname' => $dirname))); } if ($this->configuration['move']) { $copied = file_unmanaged_move($source, $destination, $replace); } else { // Determine whether we can perform this operation based on overwrite rules. $original_destination = $destination; $destination = file_destination($destination, $replace); if ($destination === FALSE) { throw new MigrateException(t('File %file could not be copied because a file by that name already exists in the destination directory (%destination)', array('%file' => $source, '%destination' => $original_destination))); } $source = $this->urlencode($source); $copied = copy($source, $destination); } if ($copied) { return parent::import($row, $old_destination_id_values); } else { throw new MigrateException(t('File %source could not be copied to %destination.', array('%source' => $source, '%destination' => $destination))); } }
public function parse(ServicesContextInterface $context) { global $user; $destination = DATASET_FILE_STORAGE_DESTINATION; if (substr($destination, -1) != '/') { $destination .= '/'; } $file = new stdClass(); $file->uid = $user->uid; $file->status = 0; $file->filename = uniqid('push-api_'); $file->uri = file_destination($destination . $file->filename, FILE_EXISTS_RENAME); $file->filemime = 'text/csv'; if ( false === file_put_contents($file->uri,$context->getRequestBody()) ) { throw new IllegalArgumentException(t('Could not store received data on file system')); } drupal_chmod($file->uri); file_save($file); return array(PARAMETER_NAME_CONTENT => $file); }
/** * {@inheritdoc} */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { // If we're stubbing a file entity, return a uri of NULL so it will get // stubbed by the general process. if ($row->isStub()) { return NULL; } list($source, $destination) = $value; // Modify the destination filename if necessary. $replace = !empty($this->configuration['rename']) ? FILE_EXISTS_RENAME : FILE_EXISTS_REPLACE; $final_destination = file_destination($destination, $replace); // Try opening the file first, to avoid calling file_prepare_directory() // unnecessarily. We're suppressing fopen() errors because we want to try // to prepare the directory before we give up and fail. $destination_stream = @fopen($final_destination, 'w'); if (!$destination_stream) { // If fopen didn't work, make sure there's a writable directory in place. $dir = $this->fileSystem->dirname($final_destination); if (!file_prepare_directory($dir, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) { throw new MigrateException("Could not create or write to directory '{$dir}'"); } // Let's try that fopen again. $destination_stream = @fopen($final_destination, 'w'); if (!$destination_stream) { throw new MigrateException("Could not write to file '{$final_destination}'"); } } // Stream the request body directly to the final destination stream. $this->configuration['guzzle_options']['sink'] = $destination_stream; // Make the request. Guzzle throws an exception for anything other than 200. $this->httpClient->get($source, $this->configuration['guzzle_options']); return $final_destination; }
function mylog($data, $file_name) { if (file_destination('public://log', FILE_EXISTS_ERROR)) { // The file doesn't exist. do something drupal_mkdir('public://log'); } file_save_data(print_r($data, true), "public://log/{$file_name}", FILE_EXISTS_REPLACE); }
protected function validatePdfUpload(array &$form, FormStateInterface &$form_state, UploadedFile $file_upload, $file_field_name) { /** * @var $file_upload \Symfony\Component\HttpFoundation\File\UploadedFile */ if ($file_upload && $file_upload->isValid()) { // Move it to somewhere we know. $uploaded_filename = $file_upload->getClientOriginalName(); // Ensure the destination is unique; we deliberately use managed files, // but they are keyed on file URI, so we can't save the same one twice. $scheme = $this->config('fillpdf.settings')->get('scheme'); $destination = file_destination(FillPdf::buildFileUri($scheme, 'fillpdf/' . $uploaded_filename), FILE_EXISTS_RENAME); // Ensure our directory exists. $fillpdf_directory = FillPdf::buildFileUri($scheme, 'fillpdf'); $directory_exists = file_prepare_directory($fillpdf_directory, FILE_CREATE_DIRECTORY + FILE_MODIFY_PERMISSIONS); if ($directory_exists) { $file_moved = $this->fileSystem->moveUploadedFile($file_upload->getRealPath(), $destination); if ($file_moved) { // Create a File object from the uploaded file. $new_file = File::create([ 'uri' => $destination, 'uid' => $this->currentUser()->id(), ]); $errors = file_validate_extensions($new_file, 'pdf'); if (count($errors)) { $form_state->setErrorByName('upload_pdf', $this->t('Only PDF files are supported, and they must end in .pdf.')); } else { $form_state->setValue('upload_pdf', $new_file); } } else { $form_state->setErrorByName('upload_pdf', $this->t("Could not move your uploaded file from PHP's temporary location to Drupal file storage.")); } } else { $form_state->setErrorByName('upload_pdf', $this->t('Could not automatically create the <em>fillpdf</em> subdirectory. Please create this manually before uploading your PDF form.')); } } else { $form_state->setErrorByName('upload_pdf', $this->t('Your PDF could not be uploaded. Did you select one?')); } }
/** * {@inheritdoc} */ public function import(Row $row, array $old_destination_id_values = array()) { $file = $row->getSourceProperty($this->configuration['source_path_property']); $destination = $row->getDestinationProperty($this->configuration['destination_path_property']); // We check the destination to see if this is a temporary file. If it is // then we do not prepend the source_base_path because temporary files are // already absolute. $source = $this->isTempFile($destination) ? $file : $this->configuration['source_base_path'] . $file; $dirname = drupal_dirname($destination); if (!file_prepare_directory($dirname, FILE_CREATE_DIRECTORY)) { throw new MigrateException(t('Could not create directory %dirname', array('%dirname' => $dirname))); } // If the start and end file is exactly the same, there is nothing to do. if (drupal_realpath($source) === drupal_realpath($destination)) { return parent::import($row, $old_destination_id_values); } $replace = FILE_EXISTS_REPLACE; if (!empty($this->configuration['rename'])) { $entity_id = $row->getDestinationProperty($this->getKey('id')); if (!empty($entity_id) && ($entity = $this->storage->load($entity_id))) { $replace = FILE_EXISTS_RENAME; } } if ($this->configuration['move']) { $copied = file_unmanaged_move($source, $destination, $replace); } else { // Determine whether we can perform this operation based on overwrite rules. $original_destination = $destination; $destination = file_destination($destination, $replace); if ($destination === FALSE) { throw new MigrateException(t('File %file could not be copied because a file by that name already exists in the destination directory (%destination)', array('%file' => $source, '%destination' => $original_destination))); } $source = $this->urlencode($source); $copied = @copy($source, $destination); } if ($copied) { return parent::import($row, $old_destination_id_values); } else { throw new MigrateException(t('File %source could not be copied to %destination.', array('%source' => $source, '%destination' => $destination))); } }
/** * Copies a file to a new location. This is a powerful function that in many ways * performs like an advanced version of copy(). * - Checks if $source and $dest are valid and readable/writable. * - Performs a file copy if $source is not equal to $dest. * - If file already exists in $dest either the call will error out, replace the * file or rename the file based on the $replace parameter. * * @param $source A string specifying the file location of the original file. * This parameter will contain the resulting destination filename in case of * success. * @param $dest A string containing the directory $source should be copied to. * If this value is omitted, Drupal's 'files' directory will be used. * @param $replace Replace behavior when the destination file already exists. * - FILE_EXISTS_REPLACE - Replace the existing file * - FILE_EXISTS_RENAME - Append _{incrementing number} until the filename is unique * - FILE_EXISTS_ERROR - Do nothing and return FALSE. * @return True for success, FALSE for failure. */ function file_copy(&$source, $dest = 0, $replace = FILE_EXISTS_RENAME) { // $dest is almost always outside of Drupal. 23/01/2008 sun // $dest = file_create_path($dest); $directory = $dest; $basename = file_check_path($directory); // Make sure we at least have a valid directory. if ($basename === FALSE) { $source = is_object($source) ? $source->filepath : $source; drupal_set_message(t('The selected file %file could not be uploaded, because the destination %directory is not properly configured.', array('%file' => $source, '%directory' => $dest)), 'error'); return 0; } // Removed upload handling. coder_format does not deal with uploads. 23/01/2008 sun $source = realpath($source); if (!file_exists($source)) { drupal_set_message(t('The selected file %file could not be copied, because no file by that name exists. Please check that you supplied the correct filename.', array('%file' => $source)), 'error'); return 0; } // If the destination file is not specified then use the filename of the source file. $basename = $basename ? $basename : basename($source); $dest = $directory . '/' . $basename; // Make sure source and destination filenames are not the same, makes no sense // to copy it if they are. In fact copying the file will most likely result in // a 0 byte file. Which is bad. Real bad. if ($source != realpath($dest)) { if (!($dest = file_destination($dest, $replace))) { drupal_set_message(t('The selected file %file could not be copied, because a file by that name already exists in the destination.', array('%file' => $source)), 'error'); return FALSE; } if (!@copy($source, $dest)) { drupal_set_message(t('The selected file %file could not be copied.', array('%file' => $source)), 'error'); return 0; } // Give everyone read access so that FTP'd users or // non-webserver users can see/read these files, // and give group write permissions so group members // can alter files uploaded by the webserver. @chmod($dest, 0664); } // Removed upload handling. coder_format does not deal with uploads. 23/01/2008 sun $source = $dest; return 1; // Everything went ok. }
/** * Tries to move or copy a file. * * @param string $source * The source path or URI. * @param string $destination * The destination path or URI. * @param integer $replace * FILE_EXISTS_REPLACE (default) or FILE_EXISTS_RENAME. * * @return boolean * TRUE on success, FALSE on failure. */ protected function writeFile($source, $destination, $replace = FILE_EXISTS_REPLACE) { if ($this->configuration['move']) { return (bool) file_unmanaged_move($source, $destination, $replace); } else { $destination = file_destination($destination, $replace); $source = $this->urlencode($source); return @copy($source, $destination); } }
public function submitForm(array &$form, FormStateInterface $form_state) { $user_value = $form_state->getValue('user'); if ($user_value) { $form_state->setRebuild(); } else { // @todo check if file is already in use before moving? // - If in use copy? $album = $form_state->getValue('album'); $directory = $form_state->getValue('directory'); $user = \Drupal::currentUser(); $validators = array( 'file_validate_is_image' => array() ); $count = 0; $files_uploaded = array(); $nid = $album; $album_uid = $form_state->getValue('uid'); // If photos_access is enabled check viewid. $scheme = 'default'; $album_viewid = 0; if (\Drupal::moduleHandler()->moduleExists('photos_access')) { $node = \Drupal\node\Entity\Node::load($nid); if (isset($node->privacy) && isset($node->privacy['viewid'])) { $album_viewid = $node->privacy['viewid']; if ($album_viewid > 0) { // Check for private file path. if (PrivateStream::basePath()) { $scheme = 'private'; } else { // Set warning message. drupal_set_message(t('Warning: image files can still be accessed by visiting the direct URL. For better security, ask your website admin to setup a private file path.'), 'warning'); } } } } $account = \Drupal::entityManager()->getStorage('user')->load($album_uid); // Check if zip is included. $allow_zip = \Drupal::config('photos.settings')->get('photos_upzip') ? '|zip|ZIP' : ''; $file_extensions = 'png|PNG|jpg|JPG|jpeg|JPEG|gif|GIF' . $allow_zip; $files = file_scan_directory($directory, '/^.*\.(' . $file_extensions . ')$/'); foreach ($files as $dir_file) { $ext = \Drupal\Component\Utility\Unicode::substr($dir_file->uri, -3); if ($ext <> 'zip' && $ext <> 'ZIP') { // Prepare directory. $photos_path = photos_check_path($scheme, '', $account); $photos_name = _photos_rename($dir_file->filename); $file_uri = file_destination($photos_path . '/' . $photos_name, FILE_EXISTS_RENAME); if (file_unmanaged_move($dir_file->uri, $file_uri)) { // Save file to album. Include title and description. $image = \Drupal::service('image.factory')->get($file_uri); if ($image->getWidth()) { // Create a file entity. $file = entity_create('file', array( 'uri' => $file_uri, 'uid' => $user->id(), 'status' => FILE_STATUS_PERMANENT, 'pid' => $nid, 'nid' => $nid, 'filename' => $photos_name, 'filesize' => $image->getFileSize(), 'filemime' => $image->getMimeType() )); if ($file_fid = _photos_save_data($file)) { $files_uploaded[] = photos_image_date($file); } $count++; } } } else { // Zip upload from manual upload form. if (!\Drupal::config('photos.settings')->get('photos_upzip')) { return form_set_error('error', t('Please update settings to allow zip uploads.')); } $directory = photos_check_path(); file_prepare_directory($directory); $zip = file_destination($directory . '/' . trim(basename($dir_file->uri)), FILE_EXISTS_RENAME); if (file_unmanaged_move($dir_file->uri, $zip)) { $value = new \stdClass(); $value->pid = $nid; $value->nid = $nid; $value->des = ''; $value->title = $dir_file->filename; if (!$file_count = _photos_unzip($zip, $value, $scheme, $account)) { $msg = t('Upload failed.'); } else { $count = $count+$file_count; } } } } // Clear node and album page cache. Cache::invalidateTags(array('node:' . $nid, 'photos:album:' . $nid)); $message = \Drupal::translation()->formatPlural($count, '1 image moved to selected album.', '@count images moved to selected album.'); drupal_set_message($message); } }
/** * (non-PHPdoc) * @see Yamm_FileFetcherInterface::fetchArbitraryFile() */ public function fetchArbitraryFile($filepath, $dest = 0, $replace = FALSE) { throw new Yamm_FileFetcher_CouldNotFetchException("Yamm_FileFetcherInterface::fetchArbitraryFile() must be rewritten."); // Fetch the real file as a temporary file. $src = $this->_fetch($filepath); $filename = end(explode('/', $filepath)); // Create the new file destination. Use the $replace boolean to compute a // new file name if the the user asked for no file replace. $dest = file_destination(file_create_path($dest) . '/' . $filename, $replace ? FILE_EXISTS_REPLACE : FILE_EXISTS_RENAME); // Copy the temporary file as the real file. $error = !file_copy($src, $dest, $replace ? FILE_EXISTS_REPLACE : FILE_EXISTS_ERROR); // Throw our exception in case of any error. if ($error) { throw new Yamm_FileFetcher_CouldNotSaveException("File " . $src . " could not copied to " . $dest); } // In all case, remove the temporary file. Be silent here, whatever happens. // In case of unlink failure, only put a warning message in watchdog. if (!@unlink($src)) { watchdog('yamm', "Temporary file " . $src . " could not be deleted", NULL, WATCHDOG_WARNING); } // Return new file full path. return $dest; }
public function submitForm(array &$form, FormStateInterface $form_state) { $user = \Drupal::currentUser(); $validators = array( 'file_validate_is_image' => array() ); $files_uploaded = array(); if (\Drupal::config('photos.settings')->get('photos_plupload_status')) { $nid = $form_state->getValue('nid'); $album_uid = db_query("SELECT uid FROM {node_field_data} WHERE nid = :nid", array(':nid' => $nid))->fetchField(); if (empty($album_uid)) { $album_uid = $user->id(); } // \Drupal\user\Entity\User::load($album_uid); $account = \Drupal::entityManager()->getStorage('user')->load($album_uid); $plupload_files = $form_state->getValue('plupload'); foreach ($plupload_files as $uploaded_file) { if ($uploaded_file['status'] == 'done') { // Check for zip files. $ext = \Drupal\Component\Utility\Unicode::substr($uploaded_file['name'], -3); if ($ext <> 'zip' && $ext <> 'ZIP') { $photos_path = photos_check_path('default', '', $account); $photos_name = _photos_rename($uploaded_file['name']); $file_uri = file_destination($photos_path . '/' . $photos_name, FILE_EXISTS_RENAME); if (file_unmanaged_move($uploaded_file['tmppath'], $file_uri)) { $path_parts = pathinfo($file_uri); $image = \Drupal::service('image.factory')->get($file_uri); if ($path_parts['extension'] && $image->getWidth()) { // Create a file entity. $file = entity_create('file', array( 'uri' => $file_uri, 'uid' => $user->id(), 'status' => FILE_STATUS_PERMANENT, 'pid' => $form_state->getValue('pid'), 'nid' => $form_state->getValue('nid'), 'filename' => $photos_name, 'filesize' => $image->getFileSize(), 'filemime' => $image->getMimeType() )); if ($file_fid = _photos_save_data($file)) { $files_uploaded[] = photos_image_date($file); } } else { file_delete($file_uri); \Drupal::logger('photos')->notice('Wrong file type', []); } } else { \Drupal::logger('photos')->notice('Upload error. Could not move temp file.', []); } } else { if (!\Drupal::config('photos.settings')->get('photos_upzip')) { drupal_set_message(t('Please set Album photos to open zip uploads.'), 'error'); } $directory = photos_check_path(); file_prepare_directory($directory); $zip = file_destination($directory . '/' . $uploaded_file['name'], FILE_EXISTS_RENAME); if (file_unmanaged_move($uploaded_file['tmppath'], $zip)) { $value = new stdClass(); $value->pid = $form_state->getValue('pid'); $value->nid = $form_state->getValue('nid'); $value->title = $uploaded_file['name']; $value->des = ''; if (!$msg = _photos_unzip($zip, $value)) { drupal_set_message(t('Zip upload failed.'), 'error'); } } } } else { drupal_set_message(t('Error uploading some photos.'), 'error'); } } } }
public function submitForm(array &$form, FormStateInterface $form_state) { $user = \Drupal::currentUser(); $validators = array( 'file_validate_is_image' => array() ); $count = 0; $files_uploaded = array(); $nid = $form_state->getValue('nid'); $album_uid = db_query("SELECT uid FROM {node_field_data} WHERE nid = :nid", array(':nid' => $nid))->fetchField(); // If photos_access is enabled check viewid. $scheme = 'default'; $album_viewid = 0; if (\Drupal::moduleHandler()->moduleExists('photos_access')) { $node = \Drupal\node\Entity\Node::load($nid); if (isset($node->privacy) && isset($node->privacy['viewid'])) { $album_viewid = $node->privacy['viewid']; if ($album_viewid > 0) { // Check for private file path. if (PrivateStream::basePath()) { $scheme = 'private'; } else { // Set warning message. drupal_set_message(t('Warning: image files can still be accessed by visiting the direct URL. For better security, ask your website admin to setup a private file path.'), 'warning'); } } } } if (empty($album_uid)) { $album_uid = $user->id(); } // \Drupal\user\Entity\User::load($album_uid); $account = \Drupal::entityManager()->getStorage('user')->load($album_uid); // Check if plupload is enabled. // @todo check for plupload library? if (\Drupal::config('photos.settings')->get('photos_plupload_status')) { $plupload_files = $form_state->getValue('plupload'); foreach ($plupload_files as $uploaded_file) { if ($uploaded_file['status'] == 'done') { // Check for zip files. $ext = \Drupal\Component\Utility\Unicode::substr($uploaded_file['name'], -3); if ($ext <> 'zip' && $ext <> 'ZIP') { // Prepare directory. $photos_path = photos_check_path($scheme, '', $account); $photos_name = _photos_rename($uploaded_file['name']); $file_uri = file_destination($photos_path . '/' . $photos_name, FILE_EXISTS_RENAME); if (file_unmanaged_move($uploaded_file['tmppath'], $file_uri)) { $path_parts = pathinfo($file_uri); $image = \Drupal::service('image.factory')->get($file_uri); if ($path_parts['extension'] && $image->getWidth()) { // Create a file entity. $file = entity_create('file', array( 'uri' => $file_uri, 'uid' => $user->id(), 'status' => FILE_STATUS_PERMANENT, 'pid' => $form_state->getValue('pid'), 'nid' => $form_state->getValue('nid'), 'filename' => $photos_name, 'filesize' => $image->getFileSize(), 'filemime' => $image->getMimeType() )); if ($file_fid = _photos_save_data($file)) { $files_uploaded[] = photos_image_date($file); } $count++; } else { file_delete($file_uri); \Drupal::logger('photos')->notice('Wrong file type'); } } else { \Drupal::logger('photos')->notice('Upload error. Could not move temp file.'); } } else { if (!\Drupal::config('photos.settings')->get('photos_upzip')) { drupal_set_message(t('Please set Album photos to open zip uploads.'), 'error'); } $directory = photos_check_path(); file_prepare_directory($directory); $zip = file_destination($directory . '/' . $uploaded_file['name'], FILE_EXISTS_RENAME); if (file_unmanaged_move($uploaded_file['tmppath'], $zip)) { $value = new \StdClass(); $value->pid = $form_state->getValue('pid'); $value->nid = $form_state->getValue('nid'); $value->title = $uploaded_file['name']; $value->des = ''; // Unzip it. if (!$file_count = _photos_unzip($zip, $value, $scheme, $account)) { drupal_set_message(t('Zip upload failed.'), 'error'); } else { // Update image upload count. $count = $count+$file_count; } } } } else { drupal_set_message(t('Error uploading some photos.'), 'error'); } } } else { // Manual upload form. $pid = $form_state->getValue('pid'); $photos_num = \Drupal::config('photos.settings')->get('photos_num'); for ($i = 0; $i < $photos_num; ++$i) { if ($_FILES['files']['name']['images_' . $i]) { $ext = \Drupal\Component\Utility\Unicode::substr($_FILES['files']['name']['images_' . $i], -3); if ($ext <> 'zip' && $ext <> 'ZIP') { // Prepare directory. $photos_path = photos_check_path($scheme, '', $account); if ($file = file_save_upload('images_' . $i, $validators, $photos_path, 0)) { // Save file to album. Include title and description. $file->pid = $pid; $file->nid = $form_state->getValue('nid'); $file->des = $form_state->getValue('des_' . $i); $file->title = $form_state->getValue('title_' . $i); $files_uploaded[] = photos_image_date($file); $count++; } } else { // Zip upload from manual upload form. if (!\Drupal::config('photos.settings')->get('photos_upzip')) { return form_set_error('error', t('Please update settings to allow zip uploads.')); } $directory = photos_check_path(); file_prepare_directory($directory); $zip = file_destination($directory . '/' . trim(basename($_FILES['files']['name']['images_' . $i])), FILE_EXISTS_RENAME); if (file_unmanaged_move($_FILES['files']['tmp_name']['images_' . $i], $zip)) { $value = new \stdClass(); $value->pid = $pid; $value->nid = $form_state->getValue('nid') ? $form_state->getValue('nid') : $form_state->getValue('pid'); $value->des = $form_state->getValue('des_' . $i); $value->title = $form_state->getValue('title_' . $i); if (!$file_count = _photos_unzip($zip, $value, $scheme, $account)) { $msg = t('Upload failed.'); } else { $count = $count+$file_count; } } } } } } // Clear node and album page cache. Cache::invalidateTags(array('node:' . $nid, 'photos:album:' . $nid)); $message = \Drupal::translation()->formatPlural($count, '1 image uploaded.', '@count images uploaded.'); drupal_set_message($message); }
/** * Attaches a file to the image node * * @param int $nid ["path","0"] * The nid of the image to update * @param object $file ["data"] * The file object * @return object * * @Access(callback='DocuWalkPictureResource::access', args={'update'}, appendArgs=true) * @RESTRequestParser(mime='image/*', parser='RESTServer::fileRecieve') */ public static function uploadFile($nid, $file) { global $user; $node = node_load($nid); // Mark old file as temporary, then it'll be removed on next cron run, and we don't have to bother // ourselves with the business of deleting the file and the database entry for it if (!empty($node->field_picture) && $node->field_picture[0]['fid']) { $old_file = (object) $node->field_picture[0]; file_set_status($old_file, FILE_STATUS_TEMPORARY); } $dir = file_directory_path() . '/pictures'; if (!file_exists($dir)) { mkdir($dir); } $file->uid = $user->uid; $file->status = FILE_STATUS_PERMANENT; $destination = file_destination(file_create_path($dir . '/' . $file->filename)); rename($file->filepath, $destination); $file->filepath = $destination; drupal_write_record('files', $file, array('fid')); $node->field_picture = array((array) $file); node_save($node); return $file; }
/** * Tries to move or copy a file. * * @param string $source * The source path or URI. * @param string $destination * The destination path or URI. * @param int $replace * (optional) FILE_EXISTS_REPLACE (default) or FILE_EXISTS_RENAME. * * @return string|bool * File destination on success, FALSE on failure. */ protected function writeFile($source, $destination, $replace = FILE_EXISTS_REPLACE) { if ($this->configuration['move']) { return file_unmanaged_move($source, $destination, $replace); } // Check if there is a destination available for copying. If there isn't, // it already exists at the destination and the replace flag tells us to not // replace it. In that case, return the original destination. if (!($final_destination = file_destination($destination, $replace))) { return $destination; } // We can't use file_unmanaged_copy because it will break with remote Urls. if (@copy($source, $final_destination)) { return $final_destination; } return FALSE; }
/** * An adaptation of file_save_upload() that includes more verbose errors. * * @param string $source * A string specifying the filepath or URI of the uploaded file to save. * * @return stdClass * The saved file object. * * @throws \RestfulBadRequestException * @throws \RestfulServiceUnavailable * * @see file_save_upload() */ protected function fileSaveUpload($source) { static $upload_cache; $account = $this->getAccount(); $options = $this->getPluginKey('options'); $validators = $options['validators']; $destination = $options['scheme'] . "://"; $replace = $options['replace']; // Return cached objects without processing since the file will have // already been processed and the paths in _FILES will be invalid. if (isset($upload_cache[$source])) { return $upload_cache[$source]; } // Make sure there's an upload to process. if (empty($_FILES['files']['name'][$source])) { return NULL; } // Check for file upload errors and return FALSE if a lower level system // error occurred. For a complete list of errors: // See http://php.net/manual/features.file-upload.errors.php. switch ($_FILES['files']['error'][$source]) { case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: $message = format_string('The file %file could not be saved, because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $_FILES['files']['name'][$source], '%maxsize' => format_size(file_upload_max_size()))); throw new \RestfulBadRequestException($message); case UPLOAD_ERR_PARTIAL: case UPLOAD_ERR_NO_FILE: $message = format_string('The file %file could not be saved, because the upload did not complete.', array('%file' => $_FILES['files']['name'][$source])); throw new \RestfulBadRequestException($message); case UPLOAD_ERR_OK: // Final check that this is a valid upload, if it isn't, use the // default error handler. if (is_uploaded_file($_FILES['files']['tmp_name'][$source])) { break; } // Unknown error default: $message = format_string('The file %file could not be saved. An unknown error has occurred.', array('%file' => $_FILES['files']['name'][$source])); throw new \RestfulServiceUnavailable($message); } // Begin building file object. $file = new stdClass(); $file->uid = $account->uid; $file->status = 0; $file->filename = trim(drupal_basename($_FILES['files']['name'][$source]), '.'); $file->uri = $_FILES['files']['tmp_name'][$source]; $file->filemime = file_get_mimetype($file->filename); $file->filesize = $_FILES['files']['size'][$source]; $extensions = ''; if (isset($validators['file_validate_extensions'])) { if (isset($validators['file_validate_extensions'][0])) { // Build the list of non-munged extensions if the caller provided them. $extensions = $validators['file_validate_extensions'][0]; } else { // If 'file_validate_extensions' is set and the list is empty then the // caller wants to allow any extension. In this case we have to remove the // validator or else it will reject all extensions. unset($validators['file_validate_extensions']); } } else { // No validator was provided, so add one using the default list. // Build a default non-munged safe list for file_munge_filename(). $extensions = 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp'; $validators['file_validate_extensions'] = array(); $validators['file_validate_extensions'][0] = $extensions; } if (!empty($extensions)) { // Munge the filename to protect against possible malicious extension hiding // within an unknown file type (ie: filename.html.foo). $file->filename = file_munge_filename($file->filename, $extensions); } // Rename potentially executable files, to help prevent exploits (i.e. will // rename filename.php.foo and filename.php to filename.php.foo.txt and // filename.php.txt, respectively). Don't rename if 'allow_insecure_uploads' // evaluates to TRUE. if (!variable_get('allow_insecure_uploads', 0) && preg_match('/\.(php|pl|py|cgi|asp|js)(\.|$)/i', $file->filename) && (substr($file->filename, -4) != '.txt')) { $file->filemime = 'text/plain'; $file->uri .= '.txt'; $file->filename .= '.txt'; // The .txt extension may not be in the allowed list of extensions. We have // to add it here or else the file upload will fail. if (!empty($extensions)) { $validators['file_validate_extensions'][0] .= ' txt'; // Unlike file_save_upload() we don't need to let the user know that // for security reasons, your upload has been renamed, since RESTful // will return the file name in the response. } } // If the destination is not provided, use the temporary directory. if (empty($destination)) { $destination = 'temporary://'; } // Assert that the destination contains a valid stream. $destination_scheme = file_uri_scheme($destination); if (!$destination_scheme || !file_stream_wrapper_valid_scheme($destination_scheme)) { $message = format_string('The file could not be uploaded, because the destination %destination is invalid.', array('%destination' => $destination)); throw new \RestfulServiceUnavailable($message); } $file->source = $source; // A URI may already have a trailing slash or look like "public://". if (substr($destination, -1) != '/') { $destination .= '/'; } $file->destination = file_destination($destination . $file->filename, $replace); // If file_destination() returns FALSE then $replace == FILE_EXISTS_ERROR and // there's an existing file so we need to bail. if ($file->destination === FALSE) { $message = format_string('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $source, '%directory' => $destination)); throw new \RestfulServiceUnavailable($message); } // Add in our check of the the file name length. $validators['file_validate_name_length'] = array(); // Call the validation functions specified by this function's caller. $errors = file_validate($file, $validators); // Check for errors. if (!empty($errors)) { $message = format_string('The specified file %name could not be uploaded.', array('%name' => $file->filename)); if (count($errors) > 1) { $message .= theme('item_list', array('items' => $errors)); } else { $message .= ' ' . array_pop($errors); } throw new \RestfulServiceUnavailable($message); } // Move uploaded files from PHP's upload_tmp_dir to Drupal's temporary // directory. This overcomes open_basedir restrictions for future file // operations. $file->uri = $file->destination; if (!drupal_move_uploaded_file($_FILES['files']['tmp_name'][$source], $file->uri)) { watchdog('file', 'Upload error. Could not move uploaded file %file to destination %destination.', array('%file' => $file->filename, '%destination' => $file->uri)); $message = 'File upload error. Could not move uploaded file.'; throw new \RestfulServiceUnavailable($message); } // Set the permissions on the new file. drupal_chmod($file->uri); // If we are replacing an existing file re-use its database record. if ($replace == FILE_EXISTS_REPLACE) { $existing_files = file_load_multiple(array(), array('uri' => $file->uri)); if (count($existing_files)) { $existing = reset($existing_files); $file->fid = $existing->fid; } } // If we made it this far it's safe to record this file in the database. if ($file = file_save($file)) { // Add file to the cache. $upload_cache[$source] = $file; return $file; } // Something went wrong, so throw a general exception. throw new \RestfulServiceUnavailable('Unknown error has occurred.'); }
/** * Validate and set destination the destination URI. * * @param \Drupal\file\FileInterface $file * The file entity object. * @param string $destination * A string containing the URI that the file should be copied to. This must * be a stream wrapper URI. * * @return bool * True if the destination was sucesfully validated and set, otherwise * false. */ protected function prepareDestination(FileInterface $file, $destination) { // Assert that the destination contains a valid stream. $destination_scheme = file_uri_scheme($destination); if (!file_stream_wrapper_valid_scheme($destination_scheme)) { return FALSE; } // Prepare the destination dir. if (!file_exists($destination)) { $this->fileSystem->mkdir($destination); } // A file URI may already have a trailing slash or look like "public://". if (substr($destination, -1) != '/') { $destination .= '/'; } $file->destination = file_destination($destination . $file->getFilename(), FILE_EXISTS_RENAME); $file->setFileUri($file->destination); return TRUE; }
/** * Tries to move or copy a file. * * @param string $source * The source path or URI. * @param string $destination * The destination path or URI. * @param int $replace * (optional) FILE_EXISTS_REPLACE (default) or FILE_EXISTS_RENAME. * * @return string|bool * File destination on success, FALSE on failure. */ protected function writeFile($source, $destination, $replace = FILE_EXISTS_REPLACE) { // Check if there is a destination available for copying. If there isn't, // it already exists at the destination and the replace flag tells us to not // replace it. In that case, return the original destination. if (!($final_destination = file_destination($destination, $replace))) { return $destination; } $function = 'file_unmanaged_' . ($this->configuration['move'] ? 'move' : 'copy'); return $function($source, $destination, $replace); }
/** * This will test the filepath for a destination based on passed flags and * whether or not the file exists. * * If a file exists, file_destination($destination, $replace) will either * return: * - the existing filepath, if $replace is FILE_EXISTS_REPLACE * - a new filepath if FILE_EXISTS_RENAME * - an error (returning FALSE) if FILE_EXISTS_ERROR. * If the file doesn't currently exist, then it will simply return the * filepath. */ function testFileDestination() { // First test for non-existent file. $destination = 'core/misc/xyz.txt'; $path = file_destination($destination, FILE_EXISTS_REPLACE); $this->assertEqual($path, $destination, 'Non-existing filepath destination is correct with FILE_EXISTS_REPLACE.', 'File'); $path = file_destination($destination, FILE_EXISTS_RENAME); $this->assertEqual($path, $destination, 'Non-existing filepath destination is correct with FILE_EXISTS_RENAME.', 'File'); $path = file_destination($destination, FILE_EXISTS_ERROR); $this->assertEqual($path, $destination, 'Non-existing filepath destination is correct with FILE_EXISTS_ERROR.', 'File'); $destination = 'core/misc/druplicon.png'; $path = file_destination($destination, FILE_EXISTS_REPLACE); $this->assertEqual($path, $destination, 'Existing filepath destination remains the same with FILE_EXISTS_REPLACE.', 'File'); $path = file_destination($destination, FILE_EXISTS_RENAME); $this->assertNotEqual($path, $destination, 'A new filepath destination is created when filepath destination already exists with FILE_EXISTS_RENAME.', 'File'); $path = file_destination($destination, FILE_EXISTS_ERROR); $this->assertEqual($path, FALSE, 'An error is returned when filepath destination already exists with FILE_EXISTS_ERROR.', 'File'); }
/** * Uploads the file to EMDB. * * @param string $form_field_name * A string that is the associative array key of the upload form element in * the form array. * @param string $catalog_id * The catalog id for the catalog we are uploading to. * @param array $metadata * Additional properties that can be passed into EMDB and stored as metadata * on the file. These values are not stored locally in Drupal. * @param array $validators * An optional, associative array of callback functions used to validate the * file. * @param string|bool $destination_dir * A string containing the URI that the file should be copied to. This must * be a stream wrapper URI. If this value is omitted, Drupal's temporary * files scheme will be used ("temporary://"). * @param int $delta * Delta of the file to save or NULL to save all files. Defaults to NULL. * @param int $replace * Replace behavior when the destination file already exists: * - FILE_EXISTS_REPLACE: Replace the existing file. * - FILE_EXISTS_RENAME: Append _{incrementing number} until the filename is * unique. * - FILE_EXISTS_ERROR: Do nothing and return FALSE. * * @return \Drupal\embridge\EmbridgeAssetEntityInterface[] * Function returns array of files or a single file object if $delta * != NULL. Each file object contains the file information if the * upload succeeded or FALSE in the event of an error. Function * returns NULL if no file was uploaded. * * The docs for the "File interface" group, which you can find under * Related topics, or the header at the top of this file, documents the * components of a file entity. In addition to the standard components, * this function adds: * - source: Path to the file before it is moved. * - destination: Path to the file after it is moved (same as 'uri'). */ public static function saveUpload($form_field_name, $catalog_id, $metadata = array(), $validators = array(), $destination_dir = FALSE, $delta = NULL, $replace = FILE_EXISTS_RENAME) { $user = \Drupal::currentUser(); static $upload_cache; $file_upload = \Drupal::request()->files->get("files[{$form_field_name}]", NULL, TRUE); // Make sure there's an upload to process. if (empty($file_upload)) { return NULL; } // Return cached objects without processing since the file will have // already been processed and the paths in $_FILES will be invalid. if (isset($upload_cache[$form_field_name])) { if (isset($delta)) { return $upload_cache[$form_field_name][$delta]; } return $upload_cache[$form_field_name]; } // Prepare uploaded files info. Representation is slightly different // for multiple uploads and we fix that here. /** @var \Symfony\Component\HttpFoundation\File\UploadedFile[] $uploaded_files */ $uploaded_files = $file_upload; if (!is_array($file_upload)) { $uploaded_files = array($file_upload); } $assets = array(); foreach ($uploaded_files as $i => $file_info) { // Check for file upload errors and return FALSE for this file if a lower // level system error occurred. For a complete list of errors: // See http://php.net/manual/features.file-upload.errors.php. switch ($file_info->getError()) { case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: drupal_set_message(t('The file %file could not be saved because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $file_info->getFilename(), '%maxsize' => format_size(file_upload_max_size()))), 'error'); $assets[$i] = FALSE; continue; case UPLOAD_ERR_PARTIAL: case UPLOAD_ERR_NO_FILE: drupal_set_message(t('The file %file could not be saved because the upload did not complete.', array('%file' => $file_info->getFilename())), 'error'); $assets[$i] = FALSE; continue; case UPLOAD_ERR_OK: // Final check that this is a valid upload, if it isn't, use the // default error handler. if (is_uploaded_file($file_info->getRealPath())) { break; } default: // Unknown error. drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array('%file' => $file_info->getFilename())), 'error'); $assets[$i] = FALSE; continue; } // Begin building file entity. $values = array('uid' => $user->id(), 'filename' => $file_info->getClientOriginalName(), 'filesize' => $file_info->getSize(), 'catalog_id' => $catalog_id); $values['filemime'] = \Drupal::service('file.mime_type.guesser')->guess($values['filename']); // Create our Embridge Entity. /** @var \Drupal\embridge\EmbridgeAssetEntityInterface $asset */ $asset = EmbridgeAssetEntity::create($values); $extensions = ''; if (isset($validators['embridge_asset_validate_file_extensions'])) { if (isset($validators['embridge_asset_validate_file_extensions'][0])) { // Build the list of non-munged exts if the caller provided them. $extensions = $validators['embridge_asset_validate_file_extensions'][0]; } else { // If 'file_validate_extensions' is set and the list is empty then the // caller wants to allow any extension. In this case we have to remove // the validator or else it will reject all extensions. unset($validators['embridge_asset_validate_file_extensions']); } } else { // No validator was provided, so add one using the default list. // Build a default non-munged safe list for file_munge_filename(). $extensions = 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp'; $validators['embridge_asset_validate_file_extensions'] = array(); $validators['embridge_asset_validate_file_extensions'][0] = $extensions; } if (!empty($extensions)) { // Munge the filename to protect against possible malicious extension // hiding within an unknown file type (ie: filename.html.foo). $asset->setFilename(file_munge_filename($asset->getFilename(), $extensions)); } // Rename potentially executable files, to help prevent exploits. if (!\Drupal::config('system.file')->get('allow_insecure_uploads') && preg_match('/\\.(php|pl|py|cgi|asp|js)(\\.|$)/i', $asset->getFilename()) && substr($asset->getFilename(), -4) != '.txt') { $asset->setMimeType('text/plain'); // The destination filename will also later be used to create the URI. $asset->setFilename($asset->getFilename() . '.txt'); // The .txt extension may not be in the allowed list of extensions. // We have to add it here or else the file upload will fail. if (!empty($extensions)) { $validators['embridge_asset_validate_file_extensions'][0] .= ' txt'; drupal_set_message(t('For security reasons, your upload has been renamed to %filename.', array('%filename' => $asset->getFilename()))); } } // If the destination is not provided, use the temporary directory. if (empty($destination_dir)) { $destination_dir = 'temporary://'; } // Assert that the destination contains a valid stream. $destination_scheme = file_uri_scheme($destination_dir); if (!file_stream_wrapper_valid_scheme($destination_scheme)) { drupal_set_message(t('The file could not be uploaded because the destination %destination is invalid.', array('%destination' => $destination_dir)), 'error'); $assets[$i] = FALSE; continue; } // A file URI may already have a trailing slash or look like "public://". if (substr($destination_dir, -1) != '/') { $destination_dir .= '/'; } $asset_destination = file_destination($destination_dir . $asset->getFilename(), $replace); // If file_destination() returns FALSE then $replace === FILE_EXISTS_ERROR // and there's an existing file so we need to bail. if ($asset_destination === FALSE) { drupal_set_message(t('The file %source could not be uploaded because a file by that name already exists in the destination %directory.', array('%source' => $form_field_name, '%directory' => $destination_dir)), 'error'); $assets[$i] = FALSE; continue; } // Add in our check of the file name length. // TODO: Do we need this? // $validators['file_validate_name_length'] = array(); // Call the validation functions specified by this function's caller. $errors = embridge_asset_validate($asset, $validators); // Check for errors. if (!empty($errors)) { $message = array('error' => array('#markup' => t('The specified file %name could not be uploaded.', array('%name' => $asset->getFilename()))), 'item_list' => array('#theme' => 'item_list', '#items' => $errors)); // @todo Add support for render arrays in drupal_set_message()? See // https://www.drupal.org/node/2505497. drupal_set_message(\Drupal::service('renderer')->renderPlain($message), 'error'); $assets[$i] = FALSE; continue; } // Move uploaded files from PHP's upload_tmp_dir to Drupal's temporary // directory. This overcomes open_basedir restrictions for future file // operations. $asset->setSourcePath($asset_destination); if (!drupal_move_uploaded_file($file_info->getRealPath(), $asset->getSourcePath())) { drupal_set_message(t('File upload error. Could not move uploaded file.'), 'error'); \Drupal::logger('file')->notice('Upload error. Could not move uploaded file %file to destination %destination.', array('%file' => $asset->getFilename(), '%destination' => $asset->getSourcePath())); $assets[$i] = FALSE; continue; } // Set the permissions on the new file. drupal_chmod($asset->getSourcePath()); // If we are replacing an existing file re-use its database record. // @todo Do not create a new entity in order to update it. See // https://www.drupal.org/node/2241865. if ($replace == FILE_EXISTS_REPLACE) { $existing_files = entity_load_multiple_by_properties('embridge_asset_entity', array('uri' => $asset->getSourcePath())); if (count($existing_files)) { $existing = reset($existing_files); $asset->setOriginalId($existing->id()); } } /** @var \Drupal\embridge\EnterMediaDbClientInterface $embridge_client */ $embridge_client = \Drupal::getContainer()->get('embridge.client'); try { $embridge_client->upload($asset, $metadata); } catch (\Exception $e) { $message = $e->getMessage(); drupal_set_message(t('Uploading the file "%file" to EnterMedia failed with the message "%message".', array('%file' => $asset->getFilename(), '%message' => $message)), 'error'); $assets[$i] = FALSE; continue; } // If we made it this far it's safe to record this file in the database. $asset->save(); $assets[$i] = $asset; } // Add files to the cache. $upload_cache[$form_field_name] = $assets; return isset($delta) ? $assets[$delta] : $assets; }