acceptance.php
15 years ago
akismet.php
14 years ago
captcha.php
15 years ago
checkbox.php
15 years ago
file.php
14 years ago
quiz.php
15 years ago
response.php
15 years ago
select.php
14 years ago
special-mail-tags.php
14 years ago
submit.php
15 years ago
text.php
15 years ago
textarea.php
14 years ago
file.php
346 lines
| 1 | <?php |
| 2 | /** |
| 3 | ** A base module for [file] and [file*] |
| 4 | **/ |
| 5 | |
| 6 | /* Shortcode handler */ |
| 7 | |
| 8 | wpcf7_add_shortcode( 'file', 'wpcf7_file_shortcode_handler', true ); |
| 9 | wpcf7_add_shortcode( 'file*', 'wpcf7_file_shortcode_handler', true ); |
| 10 | |
| 11 | function wpcf7_file_shortcode_handler( $tag ) { |
| 12 | if ( ! is_array( $tag ) ) |
| 13 | return ''; |
| 14 | |
| 15 | $type = $tag['type']; |
| 16 | $name = $tag['name']; |
| 17 | $options = (array) $tag['options']; |
| 18 | $values = (array) $tag['values']; |
| 19 | |
| 20 | if ( empty( $name ) ) |
| 21 | return ''; |
| 22 | |
| 23 | $atts = ''; |
| 24 | $id_att = ''; |
| 25 | $class_att = ''; |
| 26 | $size_att = ''; |
| 27 | $tabindex_att = ''; |
| 28 | |
| 29 | $class_att .= ' wpcf7-file'; |
| 30 | |
| 31 | if ( 'file*' == $type ) |
| 32 | $class_att .= ' wpcf7-validates-as-required'; |
| 33 | |
| 34 | foreach ( $options as $option ) { |
| 35 | if ( preg_match( '%^id:([-0-9a-zA-Z_]+)$%', $option, $matches ) ) { |
| 36 | $id_att = $matches[1]; |
| 37 | |
| 38 | } elseif ( preg_match( '%^class:([-0-9a-zA-Z_]+)$%', $option, $matches ) ) { |
| 39 | $class_att .= ' ' . $matches[1]; |
| 40 | |
| 41 | } elseif ( preg_match( '%^([0-9]*)[/x]([0-9]*)$%', $option, $matches ) ) { |
| 42 | $size_att = (int) $matches[1]; |
| 43 | |
| 44 | } elseif ( preg_match( '%^tabindex:(\d+)$%', $option, $matches ) ) { |
| 45 | $tabindex_att = (int) $matches[1]; |
| 46 | |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | if ( $id_att ) |
| 51 | $atts .= ' id="' . trim( $id_att ) . '"'; |
| 52 | |
| 53 | if ( $class_att ) |
| 54 | $atts .= ' class="' . trim( $class_att ) . '"'; |
| 55 | |
| 56 | if ( $size_att ) |
| 57 | $atts .= ' size="' . $size_att . '"'; |
| 58 | else |
| 59 | $atts .= ' size="40"'; // default size |
| 60 | |
| 61 | if ( '' !== $tabindex_att ) |
| 62 | $atts .= sprintf( ' tabindex="%d"', $tabindex_att ); |
| 63 | |
| 64 | $html = '<input type="file" name="' . $name . '"' . $atts . ' value="1" />'; |
| 65 | |
| 66 | $validation_error = wpcf7_get_validation_error( $name ); |
| 67 | |
| 68 | $html = '<span class="wpcf7-form-control-wrap ' . $name . '">' . $html . $validation_error . '</span>'; |
| 69 | |
| 70 | return $html; |
| 71 | } |
| 72 | |
| 73 | |
| 74 | /* Encode type filter */ |
| 75 | |
| 76 | add_filter( 'wpcf7_form_enctype', 'wpcf7_file_form_enctype_filter' ); |
| 77 | |
| 78 | function wpcf7_file_form_enctype_filter( $enctype ) { |
| 79 | $multipart = (bool) wpcf7_scan_shortcode( array( 'type' => array( 'file', 'file*' ) ) ); |
| 80 | |
| 81 | if ( $multipart ) |
| 82 | $enctype = ' enctype="multipart/form-data"'; |
| 83 | |
| 84 | return $enctype; |
| 85 | } |
| 86 | |
| 87 | |
| 88 | /* Validation + upload handling filter */ |
| 89 | |
| 90 | add_filter( 'wpcf7_validate_file', 'wpcf7_file_validation_filter', 10, 2 ); |
| 91 | add_filter( 'wpcf7_validate_file*', 'wpcf7_file_validation_filter', 10, 2 ); |
| 92 | |
| 93 | function wpcf7_file_validation_filter( $result, $tag ) { |
| 94 | $type = $tag['type']; |
| 95 | $name = $tag['name']; |
| 96 | $options = (array) $tag['options']; |
| 97 | |
| 98 | $file = $_FILES[$name]; |
| 99 | |
| 100 | if ( $file['error'] && UPLOAD_ERR_NO_FILE != $file['error'] ) { |
| 101 | $result['valid'] = false; |
| 102 | $result['reason'][$name] = wpcf7_get_message( 'upload_failed_php_error' ); |
| 103 | return $result; |
| 104 | } |
| 105 | |
| 106 | if ( empty( $file['tmp_name'] ) && 'file*' == $type ) { |
| 107 | $result['valid'] = false; |
| 108 | $result['reason'][$name] = wpcf7_get_message( 'invalid_required' ); |
| 109 | return $result; |
| 110 | } |
| 111 | |
| 112 | if ( ! is_uploaded_file( $file['tmp_name'] ) ) |
| 113 | return $result; |
| 114 | |
| 115 | $file_type_pattern = ''; |
| 116 | $allowed_size = 1048576; // default size 1 MB |
| 117 | |
| 118 | foreach ( $options as $option ) { |
| 119 | if ( preg_match( '%^filetypes:(.+)$%', $option, $matches ) ) { |
| 120 | $file_types = explode( '|', $matches[1] ); |
| 121 | foreach ( $file_types as $file_type ) { |
| 122 | $file_type = trim( $file_type, '.' ); |
| 123 | $file_type = str_replace( |
| 124 | array( '.', '+', '*', '?' ), array( '\.', '\+', '\*', '\?' ), $file_type ); |
| 125 | $file_type_pattern .= '|' . $file_type; |
| 126 | } |
| 127 | |
| 128 | } elseif ( preg_match( '/^limit:([1-9][0-9]*)([kKmM]?[bB])?$/', $option, $matches ) ) { |
| 129 | $allowed_size = (int) $matches[1]; |
| 130 | |
| 131 | $kbmb = strtolower( $matches[2] ); |
| 132 | if ( 'kb' == $kbmb ) { |
| 133 | $allowed_size *= 1024; |
| 134 | } elseif ( 'mb' == $kbmb ) { |
| 135 | $allowed_size *= 1024 * 1024; |
| 136 | } |
| 137 | |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | /* File type validation */ |
| 142 | |
| 143 | // Default file-type restriction |
| 144 | if ( '' == $file_type_pattern ) |
| 145 | $file_type_pattern = 'jpg|jpeg|png|gif|pdf|doc|docx|ppt|pptx|odt|avi|ogg|m4a|mov|mp3|mp4|mpg|wav|wmv'; |
| 146 | |
| 147 | $file_type_pattern = trim( $file_type_pattern, '|' ); |
| 148 | $file_type_pattern = '(' . $file_type_pattern . ')'; |
| 149 | $file_type_pattern = '/\.' . $file_type_pattern . '$/i'; |
| 150 | |
| 151 | if ( ! preg_match( $file_type_pattern, $file['name'] ) ) { |
| 152 | $result['valid'] = false; |
| 153 | $result['reason'][$name] = wpcf7_get_message( 'upload_file_type_invalid' ); |
| 154 | return $result; |
| 155 | } |
| 156 | |
| 157 | /* File size validation */ |
| 158 | |
| 159 | if ( $file['size'] > $allowed_size ) { |
| 160 | $result['valid'] = false; |
| 161 | $result['reason'][$name] = wpcf7_get_message( 'upload_file_too_large' ); |
| 162 | return $result; |
| 163 | } |
| 164 | |
| 165 | $uploads_dir = wpcf7_upload_tmp_dir(); |
| 166 | wpcf7_init_uploads(); // Confirm upload dir |
| 167 | |
| 168 | $filename = $file['name']; |
| 169 | |
| 170 | // If you get script file, it's a danger. Make it TXT file. |
| 171 | if ( preg_match( '/\.(php|pl|py|rb|cgi)\d?$/', $filename ) ) |
| 172 | $filename .= '.txt'; |
| 173 | |
| 174 | $filename = wp_unique_filename( $uploads_dir, $filename ); |
| 175 | |
| 176 | $new_file = trailingslashit( $uploads_dir ) . $filename; |
| 177 | |
| 178 | if ( false === @move_uploaded_file( $file['tmp_name'], $new_file ) ) { |
| 179 | $result['valid'] = false; |
| 180 | $result['reason'][$name] = wpcf7_get_message( 'upload_failed' ); |
| 181 | return $result; |
| 182 | } |
| 183 | |
| 184 | // Make sure the uploaded file is only readable for the owner process |
| 185 | @chmod( $new_file, 0400 ); |
| 186 | |
| 187 | if ( $contact_form = wpcf7_get_current_contact_form() ) |
| 188 | $contact_form->uploaded_files[$name] = $new_file; |
| 189 | |
| 190 | if ( ! isset( $_POST[$name] ) ) |
| 191 | $_POST[$name] = $filename; |
| 192 | |
| 193 | return $result; |
| 194 | } |
| 195 | |
| 196 | |
| 197 | /* Messages */ |
| 198 | |
| 199 | add_filter( 'wpcf7_messages', 'wpcf7_file_messages' ); |
| 200 | |
| 201 | function wpcf7_file_messages( $messages ) { |
| 202 | return array_merge( $messages, array( |
| 203 | 'upload_failed' => array( |
| 204 | 'description' => __( "Uploading a file fails for any reason", 'wpcf7' ), |
| 205 | 'default' => __( 'Failed to upload file.', 'wpcf7' ) |
| 206 | ), |
| 207 | |
| 208 | 'upload_file_type_invalid' => array( |
| 209 | 'description' => __( "Uploaded file is not allowed file type", 'wpcf7' ), |
| 210 | 'default' => __( 'This file type is not allowed.', 'wpcf7' ) |
| 211 | ), |
| 212 | |
| 213 | 'upload_file_too_large' => array( |
| 214 | 'description' => __( "Uploaded file is too large", 'wpcf7' ), |
| 215 | 'default' => __( 'This file is too large.', 'wpcf7' ) |
| 216 | ), |
| 217 | |
| 218 | 'upload_failed_php_error' => array( |
| 219 | 'description' => __( "Uploading a file fails for PHP error", 'wpcf7' ), |
| 220 | 'default' => __( 'Failed to upload file. Error occurred.', 'wpcf7' ) |
| 221 | ) |
| 222 | ) ); |
| 223 | } |
| 224 | |
| 225 | |
| 226 | /* Tag generator */ |
| 227 | |
| 228 | add_action( 'admin_init', 'wpcf7_add_tag_generator_file', 50 ); |
| 229 | |
| 230 | function wpcf7_add_tag_generator_file() { |
| 231 | wpcf7_add_tag_generator( 'file', __( 'File upload', 'wpcf7' ), |
| 232 | 'wpcf7-tg-pane-file', 'wpcf7_tg_pane_file' ); |
| 233 | } |
| 234 | |
| 235 | function wpcf7_tg_pane_file( &$contact_form ) { |
| 236 | ?> |
| 237 | <div id="wpcf7-tg-pane-file" class="hidden"> |
| 238 | <form action=""> |
| 239 | <table> |
| 240 | <tr><td><input type="checkbox" name="required" /> <?php echo esc_html( __( 'Required field?', 'wpcf7' ) ); ?></td></tr> |
| 241 | <tr><td><?php echo esc_html( __( 'Name', 'wpcf7' ) ); ?><br /><input type="text" name="name" class="tg-name oneline" /></td><td></td></tr> |
| 242 | </table> |
| 243 | |
| 244 | <table> |
| 245 | <tr> |
| 246 | <td><code>id</code> (<?php echo esc_html( __( 'optional', 'wpcf7' ) ); ?>)<br /> |
| 247 | <input type="text" name="id" class="idvalue oneline option" /></td> |
| 248 | |
| 249 | <td><code>class</code> (<?php echo esc_html( __( 'optional', 'wpcf7' ) ); ?>)<br /> |
| 250 | <input type="text" name="class" class="classvalue oneline option" /></td> |
| 251 | </tr> |
| 252 | |
| 253 | <tr> |
| 254 | <td><?php echo esc_html( __( "File size limit", 'wpcf7' ) ); ?> (<?php echo esc_html( __( 'bytes', 'wpcf7' ) ); ?>) (<?php echo esc_html( __( 'optional', 'wpcf7' ) ); ?>)<br /> |
| 255 | <input type="text" name="limit" class="filesize oneline option" /></td> |
| 256 | |
| 257 | <td><?php echo esc_html( __( "Acceptable file types", 'wpcf7' ) ); ?> (<?php echo esc_html( __( 'optional', 'wpcf7' ) ); ?>)<br /> |
| 258 | <input type="text" name="filetypes" class="filetype oneline option" /></td> |
| 259 | </tr> |
| 260 | </table> |
| 261 | |
| 262 | <div class="tg-tag"><?php echo esc_html( __( "Copy this code and paste it into the form left.", 'wpcf7' ) ); ?><br /><input type="text" name="file" class="tag" readonly="readonly" onfocus="this.select()" /></div> |
| 263 | |
| 264 | <div class="tg-mail-tag"><?php echo esc_html( __( "And, put this code into the File Attachments field below.", 'wpcf7' ) ); ?><br /><span class="arrow">⬇</span> <input type="text" class="mail-tag" readonly="readonly" onfocus="this.select()" /></div> |
| 265 | </form> |
| 266 | </div> |
| 267 | <?php |
| 268 | } |
| 269 | |
| 270 | |
| 271 | /* Warning message */ |
| 272 | |
| 273 | add_action( 'wpcf7_admin_before_subsubsub', 'wpcf7_file_display_warning_message' ); |
| 274 | |
| 275 | function wpcf7_file_display_warning_message( &$contact_form ) { |
| 276 | if ( ! $contact_form ) |
| 277 | return; |
| 278 | |
| 279 | $has_tags = (bool) $contact_form->form_scan_shortcode( |
| 280 | array( 'type' => array( 'file', 'file*' ) ) ); |
| 281 | |
| 282 | if ( ! $has_tags ) |
| 283 | return; |
| 284 | |
| 285 | $uploads_dir = wpcf7_upload_tmp_dir(); |
| 286 | wpcf7_init_uploads(); |
| 287 | |
| 288 | if ( ! is_dir( $uploads_dir ) || ! is_writable( $uploads_dir ) ) { |
| 289 | $message = sprintf( __( 'This contact form contains 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.', 'wpcf7' ), $uploads_dir ); |
| 290 | |
| 291 | echo '<div class="error"><p><strong>' . esc_html( $message ) . '</strong></p></div>'; |
| 292 | } |
| 293 | } |
| 294 | |
| 295 | |
| 296 | /* File uploading functions */ |
| 297 | |
| 298 | function wpcf7_init_uploads() { |
| 299 | $dir = wpcf7_upload_tmp_dir(); |
| 300 | wp_mkdir_p( trailingslashit( $dir ) ); |
| 301 | @chmod( $dir, 0733 ); |
| 302 | |
| 303 | $htaccess_file = trailingslashit( $dir ) . '.htaccess'; |
| 304 | if ( file_exists( $htaccess_file ) ) |
| 305 | return; |
| 306 | |
| 307 | if ( $handle = @fopen( $htaccess_file, 'w' ) ) { |
| 308 | fwrite( $handle, "Deny from all\n" ); |
| 309 | fclose( $handle ); |
| 310 | } |
| 311 | } |
| 312 | |
| 313 | function wpcf7_upload_tmp_dir() { |
| 314 | if ( defined( 'WPCF7_UPLOADS_TMP_DIR' ) ) |
| 315 | return WPCF7_UPLOADS_TMP_DIR; |
| 316 | else |
| 317 | return wpcf7_upload_dir( 'dir' ) . '/wpcf7_uploads'; |
| 318 | } |
| 319 | |
| 320 | function wpcf7_cleanup_upload_files() { |
| 321 | $dir = trailingslashit( wpcf7_upload_tmp_dir() ); |
| 322 | |
| 323 | if ( ! is_dir( $dir ) ) |
| 324 | return false; |
| 325 | if ( ! is_readable( $dir ) ) |
| 326 | return false; |
| 327 | if ( ! is_writable( $dir ) ) |
| 328 | return false; |
| 329 | |
| 330 | if ( $handle = @opendir( $dir ) ) { |
| 331 | while ( false !== ( $file = readdir( $handle ) ) ) { |
| 332 | if ( $file == "." || $file == ".." || $file == ".htaccess" ) |
| 333 | continue; |
| 334 | |
| 335 | $stat = stat( $dir . $file ); |
| 336 | if ( $stat['mtime'] + 60 < time() ) // 60 secs |
| 337 | @unlink( $dir . $file ); |
| 338 | } |
| 339 | closedir( $handle ); |
| 340 | } |
| 341 | } |
| 342 | |
| 343 | if ( ! is_admin() && 'GET' == $_SERVER['REQUEST_METHOD'] ) |
| 344 | wpcf7_cleanup_upload_files(); |
| 345 | |
| 346 | ?> |