PageRenderTime 26ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/gravityforms 2/includes/upload.php

https://gitlab.com/plusplusminus/isissoftware
PHP | 245 lines | 184 code | 37 blank | 24 comment | 55 complexity | 1e8e1ede853e3dc566d45b746a53ed12 MD5 | raw file
  1. <?php
  2. if ( ! class_exists( 'GFForms' ) ) {
  3. die();
  4. }
  5. /**
  6. * upload.php
  7. *
  8. *
  9. * Copyright 2009, Moxiecode Systems AB
  10. * Released under GPL License.
  11. *
  12. * License: http://www.plupload.com/license
  13. *
  14. * Modified by Rocketgenius
  15. */
  16. class GFAsyncUpload {
  17. public static function upload() {
  18. GFCommon::log_debug( 'GFAsyncUpload::upload(): Starting.' );
  19. if ( $_SERVER['REQUEST_METHOD'] != 'POST' ) {
  20. status_header( 404 );
  21. die();
  22. }
  23. header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
  24. send_nosniff_header();
  25. nocache_headers();
  26. status_header( 200 );
  27. // If the file is bigger than the server can accept then the form_id might not arrive.
  28. // This might happen if the file is bigger than the max post size ini setting.
  29. // Validation in the browser reduces the risk of this happening.
  30. if ( ! isset( $_REQUEST['form_id'] ) ) {
  31. GFCommon::log_debug( 'GFAsyncUpload::upload(): File upload aborted because the form_id was not found. The file may have been bigger than the max post size ini setting.' );
  32. die( '{"status" : "error", "error" : {"code": 500, "message": "' . __( 'Failed to upload file.', 'gravityforms' ) . '"}}' );
  33. }
  34. $form_id = absint( $_REQUEST['form_id'] );
  35. $form_unique_id = rgpost( 'gform_unique_id' );
  36. $form = GFAPI::get_form( $form_id );
  37. if ( empty( $form ) || ! $form['is_active'] ) {
  38. die();
  39. }
  40. if ( rgar( $form, 'requireLogin' ) ) {
  41. if ( ! is_user_logged_in() ) {
  42. die();
  43. }
  44. check_admin_referer( 'gform_file_upload_' . $form_id, '_gform_file_upload_nonce_' . $form_id );
  45. }
  46. if ( ! ctype_alnum( $form_unique_id ) ) {
  47. die();
  48. }
  49. $target_dir = GFFormsModel::get_upload_path( $form_id ) . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
  50. if ( ! is_dir( $target_dir ) ) {
  51. if ( ! wp_mkdir_p( $target_dir ) ) {
  52. GFCommon::log_debug( "GFAsyncUpload::upload(): Couldn't create the tmp folder: " . $target_dir );
  53. die( '{"status" : "error", "error" : {"code": 500, "message": "' . __( 'Failed to upload file.', 'gravityforms' ) . '"}}' );
  54. }
  55. }
  56. $time = current_time( 'mysql' );
  57. $y = substr( $time, 0, 4 );
  58. $m = substr( $time, 5, 2 );
  59. //adding index.html files to all subfolders
  60. if ( ! file_exists( GFFormsModel::get_upload_root() . '/index.html' ) ) {
  61. GFForms::add_security_files();
  62. } else if ( ! file_exists( GFFormsModel::get_upload_path( $form_id ) . '/index.html' ) ) {
  63. GFCommon::recursive_add_index_file( GFFormsModel::get_upload_path( $form_id ) );
  64. } else if ( ! file_exists( GFFormsModel::get_upload_path( $form_id ) . "/$y/index.html" ) ) {
  65. GFCommon::recursive_add_index_file( GFFormsModel::get_upload_path( $form_id ) . "/$y" );
  66. } else {
  67. GFCommon::recursive_add_index_file( GFFormsModel::get_upload_path( $form_id ) . "/$y/$m" );
  68. }
  69. if ( ! file_exists( $target_dir . '/index.html' ) ) {
  70. GFCommon::recursive_add_index_file( $target_dir );
  71. }
  72. $cleanup_target_dir = true; // Remove old files
  73. $maxFileAge = 5 * 3600; // Temp file age in seconds
  74. // Chunking is not currently implemented in the front-end because it's not widely supported. The code is left here for when browsers catch up.
  75. $chunk = isset( $_REQUEST['chunk'] ) ? intval( $_REQUEST['chunk'] ) : 0;
  76. $chunks = isset( $_REQUEST['chunks'] ) ? intval( $_REQUEST['chunks'] ) : 0;
  77. $uploaded_filename = $_FILES['file']['name'];
  78. $file_name = isset( $_REQUEST['name'] ) ? $_REQUEST['name'] : '';
  79. $field_id = rgpost( 'field_id' );
  80. $field_id = absint( $field_id );
  81. $field = GFFormsModel::get_field( $form, $field_id );
  82. if ( empty( $field ) || GFFormsModel::get_input_type( $field ) != 'fileupload' ) {
  83. die();
  84. }
  85. $file_name = sanitize_file_name( $file_name );
  86. $uploaded_filename = sanitize_file_name( $uploaded_filename );
  87. $allowed_extensions = ! empty( $field->allowedExtensions ) ? GFCommon::clean_extensions( explode( ',', strtolower( $field->allowedExtensions ) ) ) : array();
  88. $max_upload_size_in_bytes = $field->maxFileSize > 0 ? $field->maxFileSize * 1048576 : wp_max_upload_size();
  89. $max_upload_size_in_mb = $max_upload_size_in_bytes / 1048576;
  90. if ( $_FILES['file']['size'] > 0 && $_FILES['file']['size'] > $max_upload_size_in_bytes ) {
  91. die( '{"status" : "error", "error" : {"code": 104, "message": "' . sprintf( __( 'File exceeds size limit. Maximum file size: %dMB', 'gravityforms' ), $max_upload_size_in_mb ) . '"}}' );
  92. }
  93. if ( GFCommon::file_name_has_disallowed_extension( $file_name ) || GFCommon::file_name_has_disallowed_extension( $uploaded_filename ) ) {
  94. GFCommon::log_debug( "GFAsyncUpload::upload(): Illegal file extension: {$file_name}" );
  95. die( '{"status" : "error", "error" : {"code": 104, "message": "' . __( 'The uploaded file type is not allowed.', 'gravityforms' ) . '"}}' );
  96. }
  97. if ( ! empty( $allowed_extensions ) ) {
  98. if ( ! GFCommon::match_file_extension( $file_name, $allowed_extensions ) || ! GFCommon::match_file_extension( $uploaded_filename, $allowed_extensions ) ) {
  99. GFCommon::log_debug( "GFAsyncUpload::upload(): The uploaded file type is not allowed: {$file_name}" );
  100. die( '{"status" : "error", "error" : {"code": 104, "message": "' . sprintf( __( 'The uploaded file type is not allowed. Must be one of the following: %s', 'gravityforms' ), strtolower( $field['allowedExtensions'] ) ) . '"}}' );
  101. }
  102. }
  103. $tmp_file_name = $form_unique_id . '_input_' . $field_id . '_' . $file_name;
  104. $tmp_file_name = sanitize_file_name( $tmp_file_name );
  105. $file_path = $target_dir . $tmp_file_name;
  106. // Remove old temp files
  107. if ( $cleanup_target_dir ) {
  108. if ( is_dir( $target_dir ) && ( $dir = opendir( $target_dir ) ) ) {
  109. while ( ( $file = readdir( $dir ) ) !== false ) {
  110. $tmp_file_path = $target_dir . $file;
  111. // Remove temp file if it is older than the max age and is not the current file
  112. if ( preg_match( '/\.part$/', $file ) && ( filemtime( $tmp_file_path ) < time() - $maxFileAge ) && ( $tmp_file_path != "{$file_path}.part" ) ) {
  113. GFCommon::log_debug( 'GFAsyncUpload::upload(): Deleting file: ' . $tmp_file_path );
  114. @unlink( $tmp_file_path );
  115. }
  116. }
  117. closedir( $dir );
  118. } else {
  119. GFCommon::log_debug( 'GFAsyncUpload::upload(): Failed to open temp directory: ' . $target_dir );
  120. die( '{"status" : "error", "error" : {"code": 100, "message": "' . __( 'Failed to open temp directory.', 'gravityforms' ) . '"}}' );
  121. }
  122. }
  123. // Look for the content type header
  124. if ( isset( $_SERVER['HTTP_CONTENT_TYPE'] ) ) {
  125. $contentType = $_SERVER['HTTP_CONTENT_TYPE'];
  126. }
  127. if ( isset( $_SERVER['CONTENT_TYPE'] ) ) {
  128. $contentType = $_SERVER['CONTENT_TYPE'];
  129. }
  130. // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5
  131. if ( strpos( $contentType, 'multipart' ) !== false ) {
  132. if ( isset( $_FILES['file']['tmp_name'] ) && is_uploaded_file( $_FILES['file']['tmp_name'] ) ) {
  133. // Open temp file
  134. $out = @fopen( "{$file_path}.part", $chunk == 0 ? 'wb' : 'ab' );
  135. if ( $out ) {
  136. // Read binary input stream and append it to temp file
  137. $in = @fopen( $_FILES['file']['tmp_name'], 'rb' );
  138. if ( $in ) {
  139. while ( $buff = fread( $in, 4096 ) ) {
  140. fwrite( $out, $buff );
  141. }
  142. } else {
  143. die( '{"status" : "error", "error" : {"code": 101, "message": "' . __( 'Failed to open input stream.', 'gravityforms' ) . '"}}' );
  144. }
  145. @fclose( $in );
  146. @fclose( $out );
  147. @unlink( $_FILES['file']['tmp_name'] );
  148. } else {
  149. die( '{"status" : "error", "error" : {"code": 102, "message": "' . __( 'Failed to open output stream.', 'gravityforms' ) . '"}}' );
  150. }
  151. } else {
  152. die( '{"status" : "error", "error" : {"code": 103, "message": "' . __( 'Failed to move uploaded file.', 'gravityforms' ) . '"}}' );
  153. }
  154. } else {
  155. // Open temp file
  156. $out = @fopen( "{$file_path}.part", $chunk == 0 ? 'wb' : 'ab' );
  157. if ( $out ) {
  158. // Read binary input stream and append it to temp file
  159. $in = @fopen( 'php://input', 'rb' );
  160. if ( $in ) {
  161. while ( $buff = fread( $in, 4096 ) ) {
  162. fwrite( $out, $buff );
  163. }
  164. } else {
  165. die( '{"status" : "error", "error" : {"code": 101, "message": "' . __( 'Failed to open input stream.', 'gravityforms' ) . '"}}' );
  166. }
  167. @fclose( $in );
  168. @fclose( $out );
  169. } else {
  170. die( '{"status" : "error", "error" : {"code": 102, "message": "' . __( 'Failed to open output stream.', 'gravityforms' ) . '"}}' );
  171. }
  172. }
  173. // Check if file has been uploaded
  174. if ( ! $chunks || $chunk == $chunks - 1 ) {
  175. // Strip the temp .part suffix off
  176. rename( "{$file_path}.part", $file_path );
  177. }
  178. if ( file_exists( $file_path ) ) {
  179. GFFormsModel::set_permissions( $file_path );
  180. } else {
  181. die( '{"status" : "error", "error" : {"code": 105, "message": "' . __( 'Upload unsuccessful:', 'gravityforms' ) . ' '. $uploaded_filename . '"}}' );
  182. }
  183. $output = array(
  184. 'status' => 'ok',
  185. 'data' => array(
  186. 'temp_filename' => $tmp_file_name,
  187. 'uploaded_filename' => str_replace( "\\'", "'", urldecode( $uploaded_filename ) ) //Decoding filename to prevent file name mismatch.
  188. )
  189. );
  190. $output = json_encode( $output );
  191. GFCommon::log_debug( sprintf( 'GFAsyncUpload::upload(): File upload complete. temp_filename: %s uploaded_filename: %s ', $tmp_file_name, $uploaded_filename ) );
  192. do_action( 'gform_post_multifile_upload', $form, $field, $uploaded_filename, $tmp_file_name, $file_path );
  193. do_action( "gform_post_multifile_upload_{$form['id']}", $form, $field, $uploaded_filename, $tmp_file_name, $file_path );
  194. die( $output );
  195. }
  196. }
  197. GFAsyncUpload::upload();