file_save_upload($form_field_name, $validators = array(), $destination = FALSE, $delta = NULL, $replace = FILE_EXISTS_RENAME)
Saves file uploads to a new location.
The files will be added to the {file_managed} table as temporary files. Temporary files are periodically cleaned. Use the 'file.usage' service to register the usage of the file which will automatically mark it as permanent.
Parameters
string $form_field_name: A string that is the associative array key of the upload form element in the form array.
array $validators: (optional) An associative array of callback functions used to validate the file. See file_validate() for a full discussion of the array format. If the array is empty, it will be set up to call file_validate_extensions() with a safe list of extensions, as follows: "jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp". To allow all extensions, you must explicitly set this array to ['file_validate_extensions' => '']. (Beware: this is not safe and should only be allowed for trusted users, if at all.)
string|false $destination: (optional) A string containing the URI that the file should be copied to. This must be a stream wrapper URI. If this value is omitted or set to FALSE, Drupal's temporary files scheme will be used ("temporary://").
null|int $delta: (optional) The delta of the file to return the file entity. Defaults to NULL.
int $replace: (optional) The replace behavior when the destination file already exists. Possible values include:
- FILE_EXISTS_REPLACE: Replace the existing file.
- FILE_EXISTS_RENAME: (default) Append _{incrementing number} until the filename is unique.
- FILE_EXISTS_ERROR: Do nothing and return FALSE.
Return value
array|\Drupal\file\FileInterface|null|false An array of file entities or a single file entity if $delta != NULL. Each array element contains the file entity if the upload succeeded or FALSE if there was an error. Function returns NULL if no file was uploaded.
File
- core/modules/file/file.module, line 714
- Defines a "managed_file" Form API field and a "file" field for Field module.
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | function file_save_upload( $form_field_name , $validators = array (), $destination = FALSE, $delta = NULL, $replace = FILE_EXISTS_RENAME) { $user = \Drupal::currentUser(); static $upload_cache ; $all_files = \Drupal::request()->files->get( 'files' , array ()); // Make sure there's an upload to process. if ( empty ( $all_files [ $form_field_name ])) { return NULL; } $file_upload = $all_files [ $form_field_name ]; // 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. $uploaded_files = $file_upload ; if (! is_array ( $file_upload )) { $uploaded_files = array ( $file_upload ); } $files = 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: 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' ); $files [ $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' ); $files [ $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 ; } // Unknown error default : drupal_set_message(t( 'The file %file could not be saved. An unknown error has occurred.' , array ( '%file' => $file_info ->getFilename())), 'error' ); $files [ $i ] = FALSE; continue ; } // Begin building file entity. $values = array ( 'uid' => $user ->id(), 'status' => 0, 'filename' => $file_info ->getClientOriginalName(), 'uri' => $file_info ->getRealPath(), 'filesize' => $file_info ->getSize(), ); $values [ 'filemime' ] = \Drupal::service( 'file.mime_type.guesser' )->guess( $values [ 'filename' ]); $file = File::create( $values ); $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 ->setFilename(file_munge_filename( $file ->getFilename(), $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 (!\Drupal::config( 'system.file' )->get( 'allow_insecure_uploads' ) && preg_match( '/\.(php|pl|py|cgi|asp|js)(\.|$)/i' , $file ->getFilename()) && ( substr ( $file ->getFilename(), -4) != '.txt' )) { $file ->setMimeType( 'text/plain' ); // The destination filename will also later be used to create the URI. $file ->setFilename( $file ->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 [ 'file_validate_extensions' ][0] .= ' txt' ; drupal_set_message(t( 'For security reasons, your upload has been renamed to %filename.' , array ( '%filename' => $file ->getFilename()))); } } // If the destination is not provided, use the temporary directory. if ( empty ( $destination )) { } // Assert that the destination contains a valid stream. $destination_scheme = file_uri_scheme( $destination ); 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 )), 'error' ); $files [ $i ] = FALSE; continue ; } $file ->source = $form_field_name ; // 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(), $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) { 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 )), 'error' ); $files [ $i ] = FALSE; continue ; } // Add in our check of 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 = array ( 'error' => array ( '#markup' => t( 'The specified file %name could not be uploaded.' , array ( '%name' => $file ->getFilename())), ), 'item_list' => array ( '#theme' => 'item_list' , '#items' => $errors , ), ); // @todo Add support for render arrays in drupal_set_message()? See drupal_set_message(\Drupal::service( 'renderer' )->renderPlain( $message ), 'error' ); $files [ $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. $file ->setFileUri( $file ->destination); if (!drupal_move_uploaded_file( $file_info ->getRealPath(), $file ->getFileUri())) { 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' => $file ->getFilename(), '%destination' => $file ->getFileUri())); $files [ $i ] = FALSE; continue ; } // Set the permissions on the new file. drupal_chmod( $file ->getFileUri()); // 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 if ( $replace == FILE_EXISTS_REPLACE) { $existing_files = entity_load_multiple_by_properties( 'file' , array ( 'uri' => $file ->getFileUri())); if ( count ( $existing_files )) { $existing = reset( $existing_files ); $file ->fid = $existing ->id(); $file ->setOriginalId( $existing ->id()); } } // If we made it this far it's safe to record this file in the database. $file ->save(); $files [ $i ] = $file ; } // Add files to the cache. $upload_cache [ $form_field_name ] = $files ; return isset( $delta ) ? $files [ $delta ] : $files ; } |
Please login to continue.