/**
* {@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;
}
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.
}
/**
* (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;
}
/**
* 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;
}
//.........这里部分代码省略.........
// 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');
}
请发表评论