[44] | 1 | <?php
|
---|
| 2 | /**
|
---|
| 3 | ** A base module for [file] and [file*]
|
---|
| 4 | **/
|
---|
| 5 |
|
---|
| 6 | function wpcf7_file_shortcode_handler( $tag ) {
|
---|
| 7 | global $wpcf7_contact_form;
|
---|
| 8 |
|
---|
| 9 | if ( ! is_array( $tag ) )
|
---|
| 10 | return '';
|
---|
| 11 |
|
---|
| 12 | $type = $tag['type'];
|
---|
| 13 | $name = $tag['name'];
|
---|
| 14 | $options = (array) $tag['options'];
|
---|
| 15 | $values = (array) $tag['values'];
|
---|
| 16 |
|
---|
| 17 | if ( empty( $name ) )
|
---|
| 18 | return '';
|
---|
| 19 |
|
---|
| 20 | $atts = '';
|
---|
| 21 | $id_att = '';
|
---|
| 22 | $class_att = '';
|
---|
| 23 |
|
---|
| 24 | if ( 'file*' == $type )
|
---|
| 25 | $class_att .= ' wpcf7-validates-as-required';
|
---|
| 26 |
|
---|
| 27 | foreach ( $options as $option ) {
|
---|
| 28 | if ( preg_match( '%^id:([-0-9a-zA-Z_]+)$%', $option, $matches ) ) {
|
---|
| 29 | $id_att = $matches[1];
|
---|
| 30 |
|
---|
| 31 | } elseif ( preg_match( '%^class:([-0-9a-zA-Z_]+)$%', $option, $matches ) ) {
|
---|
| 32 | $class_att .= ' ' . $matches[1];
|
---|
| 33 |
|
---|
| 34 | }
|
---|
| 35 | }
|
---|
| 36 |
|
---|
| 37 | if ( $id_att )
|
---|
| 38 | $atts .= ' id="' . trim( $id_att ) . '"';
|
---|
| 39 |
|
---|
| 40 | if ( $class_att )
|
---|
| 41 | $atts .= ' class="' . trim( $class_att ) . '"';
|
---|
| 42 |
|
---|
| 43 | $html = '<input type="file" name="' . $name . '"' . $atts . ' value="1" />';
|
---|
| 44 |
|
---|
| 45 | $validation_error = '';
|
---|
| 46 | if ( is_a( $wpcf7_contact_form, 'WPCF7_ContactForm' ) )
|
---|
| 47 | $validation_error = $wpcf7_contact_form->validation_error( $name );
|
---|
| 48 |
|
---|
| 49 | $html = '<span class="wpcf7-form-control-wrap ' . $name . '">' . $html . $validation_error . '</span>';
|
---|
| 50 |
|
---|
| 51 | return $html;
|
---|
| 52 | }
|
---|
| 53 |
|
---|
| 54 | wpcf7_add_shortcode( 'file', 'wpcf7_file_shortcode_handler', true );
|
---|
| 55 | wpcf7_add_shortcode( 'file*', 'wpcf7_file_shortcode_handler', true );
|
---|
| 56 |
|
---|
| 57 |
|
---|
| 58 | /* Encode type filter */
|
---|
| 59 |
|
---|
| 60 | function wpcf7_file_form_enctype_filter( $enctype ) {
|
---|
| 61 | global $wpcf7_contact_form;
|
---|
| 62 |
|
---|
| 63 | $multipart = (bool) $wpcf7_contact_form->form_scan_shortcode(
|
---|
| 64 | array( 'type' => array( 'file', 'file*' ) ) );
|
---|
| 65 |
|
---|
| 66 | if ( $multipart )
|
---|
| 67 | $enctype = ' enctype="multipart/form-data"';
|
---|
| 68 |
|
---|
| 69 | return $enctype;
|
---|
| 70 | }
|
---|
| 71 |
|
---|
| 72 | add_filter( 'wpcf7_form_enctype', 'wpcf7_file_form_enctype_filter' );
|
---|
| 73 |
|
---|
| 74 |
|
---|
| 75 | /* Validation + upload handling filter */
|
---|
| 76 |
|
---|
| 77 | function wpcf7_file_validation_filter( $result, $tag ) {
|
---|
| 78 | global $wpcf7_contact_form;
|
---|
| 79 |
|
---|
| 80 | $type = $tag['type'];
|
---|
| 81 | $name = $tag['name'];
|
---|
| 82 | $options = (array) $tag['options'];
|
---|
| 83 |
|
---|
| 84 | $file = $_FILES[$name];
|
---|
| 85 |
|
---|
| 86 | if ( $file['error'] ) {
|
---|
| 87 | $result['valid'] = false;
|
---|
| 88 | $result['reason'][$name] = $wpcf7_contact_form->message( 'upload_failed_php_error' );
|
---|
| 89 | return $result;
|
---|
| 90 | }
|
---|
| 91 |
|
---|
| 92 | if ( empty( $file['tmp_name'] ) && 'file*' == $type ) {
|
---|
| 93 | $result['valid'] = false;
|
---|
| 94 | $result['reason'][$name] = $wpcf7_contact_form->message( 'invalid_required' );
|
---|
| 95 | return $result;
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | if ( ! is_uploaded_file( $file['tmp_name'] ) )
|
---|
| 99 | return $result;
|
---|
| 100 |
|
---|
| 101 | $file_type_pattern = '';
|
---|
| 102 | $allowed_size = 1048576; // default size 1 MB
|
---|
| 103 |
|
---|
| 104 | foreach ( $options as $option ) {
|
---|
| 105 | if ( preg_match( '%^filetypes:(.+)$%', $option, $matches ) ) {
|
---|
| 106 | $file_types = explode( '|', $matches[1] );
|
---|
| 107 | foreach ( $file_types as $file_type ) {
|
---|
| 108 | $file_type = trim( $file_type, '.' );
|
---|
| 109 | $file_type = str_replace(
|
---|
| 110 | array( '.', '+', '*', '?' ), array( '\.', '\+', '\*', '\?' ), $file_type );
|
---|
| 111 | $file_type_pattern .= '|' . $file_type;
|
---|
| 112 | }
|
---|
| 113 |
|
---|
| 114 | } elseif ( preg_match( '/^limit:([1-9][0-9]*)([kKmM]?[bB])?$/', $option, $matches ) ) {
|
---|
| 115 | $allowed_size = (int) $matches[1];
|
---|
| 116 |
|
---|
| 117 | $kbmb = strtolower( $matches[2] );
|
---|
| 118 | if ( 'kb' == $kbmb ) {
|
---|
| 119 | $allowed_size *= 1024;
|
---|
| 120 | } elseif ( 'mb' == $kbmb ) {
|
---|
| 121 | $allowed_size *= 1024 * 1024;
|
---|
| 122 | }
|
---|
| 123 |
|
---|
| 124 | }
|
---|
| 125 | }
|
---|
| 126 |
|
---|
| 127 | /* File type validation */
|
---|
| 128 |
|
---|
| 129 | // Default file-type restriction
|
---|
| 130 | if ( '' == $file_type_pattern )
|
---|
| 131 | $file_type_pattern = 'jpg|jpeg|png|gif|pdf|doc|docx|ppt|pptx|odt|avi|ogg|m4a|mov|mp3|mp4|mpg|wav|wmv';
|
---|
| 132 |
|
---|
| 133 | $file_type_pattern = trim( $file_type_pattern, '|' );
|
---|
| 134 | $file_type_pattern = '(' . $file_type_pattern . ')';
|
---|
| 135 | $file_type_pattern = '/\.' . $file_type_pattern . '$/i';
|
---|
| 136 |
|
---|
| 137 | if ( ! preg_match( $file_type_pattern, $file['name'] ) ) {
|
---|
| 138 | $result['valid'] = false;
|
---|
| 139 | $result['reason'][$name] = $wpcf7_contact_form->message( 'upload_file_type_invalid' );
|
---|
| 140 | return $result;
|
---|
| 141 | }
|
---|
| 142 |
|
---|
| 143 | /* File size validation */
|
---|
| 144 |
|
---|
| 145 | if ( $file['size'] > $allowed_size ) {
|
---|
| 146 | $result['valid'] = false;
|
---|
| 147 | $result['reason'][$name] = $wpcf7_contact_form->message( 'upload_file_too_large' );
|
---|
| 148 | return $result;
|
---|
| 149 | }
|
---|
| 150 |
|
---|
| 151 | $uploads_dir = wpcf7_upload_tmp_dir();
|
---|
| 152 | wpcf7_init_uploads(); // Confirm upload dir
|
---|
| 153 |
|
---|
| 154 | $filename = wp_unique_filename( $uploads_dir, $file['name'] );
|
---|
| 155 |
|
---|
| 156 | // If you get script file, it's a danger. Make it TXT file.
|
---|
| 157 | if ( preg_match( '/\.(php|pl|py|rb|cgi)\d?$/', $filename ) )
|
---|
| 158 | $filename .= '.txt';
|
---|
| 159 |
|
---|
| 160 | $new_file = trailingslashit( $uploads_dir ) . $filename;
|
---|
| 161 |
|
---|
| 162 | if ( false === @move_uploaded_file( $file['tmp_name'], $new_file ) ) {
|
---|
| 163 | $result['valid'] = false;
|
---|
| 164 | $result['reason'][$name] = $wpcf7_contact_form->message( 'upload_failed' );
|
---|
| 165 | return $result;
|
---|
| 166 | }
|
---|
| 167 |
|
---|
| 168 | // Make sure the uploaded file is only readable for the owner process
|
---|
| 169 | @chmod( $new_file, 0400 );
|
---|
| 170 |
|
---|
| 171 | $wpcf7_contact_form->uploaded_files[$name] = $new_file;
|
---|
| 172 |
|
---|
| 173 | return $result;
|
---|
| 174 | }
|
---|
| 175 |
|
---|
| 176 | add_filter( 'wpcf7_validate_file', 'wpcf7_file_validation_filter', 10, 2 );
|
---|
| 177 | add_filter( 'wpcf7_validate_file*', 'wpcf7_file_validation_filter', 10, 2 );
|
---|
| 178 |
|
---|
| 179 |
|
---|
| 180 | /* File uploading functions */
|
---|
| 181 |
|
---|
| 182 | function wpcf7_init_uploads() {
|
---|
| 183 | $dir = wpcf7_upload_tmp_dir();
|
---|
| 184 | wp_mkdir_p( trailingslashit( $dir ) );
|
---|
| 185 | @chmod( $dir, 0733 );
|
---|
| 186 |
|
---|
| 187 | $htaccess_file = trailingslashit( $dir ) . '.htaccess';
|
---|
| 188 | if ( file_exists( $htaccess_file ) )
|
---|
| 189 | return;
|
---|
| 190 |
|
---|
| 191 | if ( $handle = @fopen( $htaccess_file, 'w' ) ) {
|
---|
| 192 | fwrite( $handle, "Deny from all\n" );
|
---|
| 193 | fclose( $handle );
|
---|
| 194 | }
|
---|
| 195 | }
|
---|
| 196 |
|
---|
| 197 | function wpcf7_cleanup_upload_files() {
|
---|
| 198 | $dir = trailingslashit( wpcf7_upload_tmp_dir() );
|
---|
| 199 |
|
---|
| 200 | if ( ! is_dir( $dir ) )
|
---|
| 201 | return false;
|
---|
| 202 | if ( ! is_readable( $dir ) )
|
---|
| 203 | return false;
|
---|
| 204 | if ( ! is_writable( $dir ) )
|
---|
| 205 | return false;
|
---|
| 206 |
|
---|
| 207 | if ( $handle = @opendir( $dir ) ) {
|
---|
| 208 | while ( false !== ( $file = readdir( $handle ) ) ) {
|
---|
| 209 | if ( $file == "." || $file == ".." || $file == ".htaccess" )
|
---|
| 210 | continue;
|
---|
| 211 |
|
---|
| 212 | $stat = stat( $dir . $file );
|
---|
| 213 | if ( $stat['mtime'] + 60 < time() ) // 60 secs
|
---|
| 214 | @unlink( $dir . $file );
|
---|
| 215 | }
|
---|
| 216 | closedir( $handle );
|
---|
| 217 | }
|
---|
| 218 | }
|
---|
| 219 |
|
---|
| 220 | if ( ! is_admin() && 'GET' == $_SERVER['REQUEST_METHOD'] )
|
---|
| 221 | wpcf7_cleanup_upload_files();
|
---|
| 222 |
|
---|
| 223 | ?> |
---|