Tuxedo Big File Uploads - Version 2.1

Version Description

Download this release

Release Info

Developer uglyrobot
Plugin Icon 128x128 Tuxedo Big File Uploads
Version 2.1
Comparing to
See all releases

Code changes from version 2.0.3 to 2.1

readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: uglyrobot, jdailey, andtrev
3
  Tags: increase file size limit, increase upload limit, max upload file size, post max size, upload limit, file upload, files uploader, ftp, video uploader, AJAX
4
  Requires at least: 5.3
5
  Tested up to: 6.0
6
- Stable tag: 2.0.3
7
  Requires PHP: 5.6
8
  License: GPLv2
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -106,6 +106,10 @@ No. [Infinite Uploads](https://wordpress.org/plugins/infinite-uploads/) is an op
106
 
107
  == Changelog ==
108
 
 
 
 
 
109
  2.0.3 - 2022-7-03
110
  ----------------------------------------------------------------------
111
  - Security fix: Prevent OS command injection in rare hosting configurations. props Marco Nappi.
3
  Tags: increase file size limit, increase upload limit, max upload file size, post max size, upload limit, file upload, files uploader, ftp, video uploader, AJAX
4
  Requires at least: 5.3
5
  Tested up to: 6.0
6
+ Stable tag: 2.1
7
  Requires PHP: 5.6
8
  License: GPLv2
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
106
 
107
  == Changelog ==
108
 
109
+ 2.1 - 2022-8-14
110
+ ----------------------------------------------------------------------
111
+ - Can now handle files of any size, limited only by your disk space, not system temp directory size.
112
+
113
  2.0.3 - 2022-7-03
114
  ----------------------------------------------------------------------
115
  - Security fix: Prevent OS command injection in rare hosting configurations. props Marco Nappi.
templates/modal-upgrade.php CHANGED
@@ -36,7 +36,7 @@
36
  }
37
  ?>
38
  <?php } ?>
39
- <p><small class="text-muted"><?php printf( esc_html__( 'Get 7 days of %s storage FREE. Plans starting at just $9/mo', 'tuxedo-big-file-uploads' ), '<span class="dashicons dashicons-cloud"></span>' ); ?></small></p>
40
  </div>
41
  </div>
42
  </div>
36
  }
37
  ?>
38
  <?php } ?>
39
+ <p><small class="text-muted"><?php printf( esc_html__( 'Get 7 days of %s storage FREE. Plans starting at just $16/mo', 'tuxedo-big-file-uploads' ), '<span class="dashicons dashicons-cloud"></span>' ); ?></small></p>
40
  </div>
41
  </div>
42
  </div>
templates/settings.php CHANGED
@@ -11,8 +11,6 @@
11
  <div class="col-md-6 col-sm-12">
12
  <h5><?php esc_html_e( 'Maximum Upload Size', 'tuxedo-big-file-uploads' ); ?></h5>
13
  <p class="lead"><?php printf( esc_html__( 'Big File Uploads allows you to bypass your hosting file size %s limit by seamlessly uploading in multiple smaller chunks. Set the max filesize you want to allow users to upload in Megabytes (MB) or Gigabytes (GB) up to what your hosting provider can handle. Toggle "Customize by user role" to set the maximum file size for each user role with upload capabilities.', 'tuxedo-big-file-uploads' ), size_format( $this->max_upload_size ) ); ?></p>
14
- <p class="lead"><?php printf( esc_html__( 'Estimated maximum supported size: %s', 'tuxedo-big-file-uploads' ), $this->temp_available_size() ? size_format( $this->temp_available_size() ) : __( 'Unknown (set a reasonable default limit and adjust down if uploads fail)', 'tuxedo-big-file-uploads' ) ); ?>
15
- <span class="dashicons dashicons-info text-muted" data-toggle="tooltip" title="<?php esc_attr_e( 'This is an estimate based on the available space in your server temp directory.', 'tuxedo-big-file-uploads' ); ?>"></span></p>
16
  </div>
17
  <div class="col-md-6 col-sm-12 text-right p-4">
18
  <div class="custom-control custom-switch mb-3">
11
  <div class="col-md-6 col-sm-12">
12
  <h5><?php esc_html_e( 'Maximum Upload Size', 'tuxedo-big-file-uploads' ); ?></h5>
13
  <p class="lead"><?php printf( esc_html__( 'Big File Uploads allows you to bypass your hosting file size %s limit by seamlessly uploading in multiple smaller chunks. Set the max filesize you want to allow users to upload in Megabytes (MB) or Gigabytes (GB) up to what your hosting provider can handle. Toggle "Customize by user role" to set the maximum file size for each user role with upload capabilities.', 'tuxedo-big-file-uploads' ), size_format( $this->max_upload_size ) ); ?></p>
 
 
14
  </div>
15
  <div class="col-md-6 col-sm-12 text-right p-4">
16
  <div class="custom-control custom-switch mb-3">
tuxedo_big_file_uploads.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Plugin Name: Big File Uploads
4
  * Description: Enable large file uploads in the built-in WordPress media uploader via multipart uploads, and set maximum upload file size to any value based on user role. Uploads can be as large as available disk space allows.
5
- * Version: 2.0.3
6
  * Author: Infinite Uploads
7
  * Author URI: https://infiniteuploads.com/?utm_source=bfu_plugin&utm_medium=plugin&utm_campaign=bfu_plugin&utm_content=meta
8
  * Network: true
@@ -34,7 +34,7 @@ if ( ! defined( 'ABSPATH' ) ) {
34
  die();
35
  }
36
 
37
- define( 'BIG_FILE_UPLOADS_VERSION', '2.0.3' );
38
 
39
  /**
40
  * Big File Uploads manager class.
@@ -418,6 +418,7 @@ class BigFileUploads {
418
 
419
  /**
420
  * AJAX chunk receiver.
 
421
  * Ajax callback for plupload to handle chunked uploads.
422
  * Based on code by Davit Barbakadze
423
  * https://gist.github.com/jayarjo/5846636
@@ -449,10 +450,38 @@ class BigFileUploads {
449
 
450
  /** Get file name and path + name. */
451
  $fileName = isset( $_REQUEST['name'] ) ? $_REQUEST['name'] : $_FILES['async-upload']['name'];
452
- $filePath = dirname( $_FILES['async-upload']['tmp_name'] ) . '/bfu-' . md5( $fileName ) . '.part';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
 
454
  $tuxbfu_max_upload_size = $this->get_upload_limit();
455
  if ( file_exists( $filePath ) && filesize( $filePath ) + filesize( $_FILES['async-upload']['tmp_name'] ) > $tuxbfu_max_upload_size ) {
 
 
 
456
 
457
  if ( ! $chunks || $chunk == $chunks - 1 ) {
458
  @unlink( $filePath );
@@ -489,12 +518,6 @@ class BigFileUploads {
489
  die();
490
  }
491
 
492
- //debugging
493
- if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
494
- $size = file_exists( $filePath ) ? size_format( filesize( $filePath ), 3 ) : '0 B';
495
- error_log( "BFU: Processing \"$fileName\" part $current_part of $chunks as $filePath. $size processed so far." );
496
- }
497
-
498
  /** Open temp file. */
499
  if ( $chunk == 0 ) {
500
  $out = @fopen( $filePath, 'wb');
@@ -590,23 +613,28 @@ class BigFileUploads {
590
  /** Check if file has finished uploading all parts. */
591
  if ( ! $chunks || $chunk == $chunks - 1 ) {
592
 
 
 
 
 
 
 
593
  /** Recreate upload in $_FILES global and pass off to WordPress. */
594
- rename( $filePath, $_FILES['async-upload']['tmp_name'] );
 
595
  $_FILES['async-upload']['name'] = $fileName;
596
  $_FILES['async-upload']['size'] = filesize( $_FILES['async-upload']['tmp_name'] );
597
- $wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['tmp_name'] );
598
  $_FILES['async-upload']['type'] = $wp_filetype['type'];
599
  header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
600
 
601
- if ( ! isset( $_REQUEST['short'] ) || ! isset( $_REQUEST['type'] ) ) {
602
-
603
  send_nosniff_header();
604
  nocache_headers();
605
- wp_ajax_upload_attachment();
606
  die( '0' );
607
 
608
- } else {
609
-
610
  $post_id = 0;
611
  if ( isset( $_REQUEST['post_id'] ) ) {
612
  $post_id = absint( $_REQUEST['post_id'] );
@@ -614,7 +642,7 @@ class BigFileUploads {
614
  $post_id = 0;
615
  }
616
 
617
- $id = media_handle_upload( 'async-upload', $post_id );
618
  if ( is_wp_error( $id ) ) {
619
  printf(
620
  '<div class="error-div error">%s <strong>%s</strong><br />%s</div>',
@@ -665,6 +693,119 @@ class BigFileUploads {
665
  die();
666
  }
667
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
668
  /**
669
  * Return the maximum upload limit in bytes for the current user.
670
  *
2
  /**
3
  * Plugin Name: Big File Uploads
4
  * Description: Enable large file uploads in the built-in WordPress media uploader via multipart uploads, and set maximum upload file size to any value based on user role. Uploads can be as large as available disk space allows.
5
+ * Version: 2.1
6
  * Author: Infinite Uploads
7
  * Author URI: https://infiniteuploads.com/?utm_source=bfu_plugin&utm_medium=plugin&utm_campaign=bfu_plugin&utm_content=meta
8
  * Network: true
34
  die();
35
  }
36
 
37
+ define( 'BIG_FILE_UPLOADS_VERSION', '2.1' );
38
 
39
  /**
40
  * Big File Uploads manager class.
418
 
419
  /**
420
  * AJAX chunk receiver.
421
+ *
422
  * Ajax callback for plupload to handle chunked uploads.
423
  * Based on code by Davit Barbakadze
424
  * https://gist.github.com/jayarjo/5846636
450
 
451
  /** Get file name and path + name. */
452
  $fileName = isset( $_REQUEST['name'] ) ? $_REQUEST['name'] : $_FILES['async-upload']['name'];
453
+
454
+ // Create temp directory if it doesn't exist
455
+ $bfu_temp_dir = apply_filters( 'bfu_temp_dir', WP_CONTENT_DIR . '/bfu-temp' );
456
+ if ( ! @is_dir( $bfu_temp_dir ) ) {
457
+ wp_mkdir_p( $bfu_temp_dir );
458
+ }
459
+
460
+ //scan temp dir for files older than 24 hours and delete them when starting a new upload
461
+ if ( $chunk === 0 ) {
462
+ $files = glob( $bfu_temp_dir . '/*.part' );
463
+ if ( is_array( $files ) ) {
464
+ foreach ( $files as $file ) {
465
+ if ( @filemtime( $file ) < time() - DAY_IN_SECONDS ) {
466
+ @unlink( $file );
467
+ }
468
+ }
469
+ }
470
+ }
471
+
472
+ $filePath = sprintf( '%s/%d-%s.part', $bfu_temp_dir, get_current_blog_id(), md5( $fileName ) );
473
+
474
+ //debugging
475
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
476
+ $size = file_exists( $filePath ) ? size_format( filesize( $filePath ), 3 ) : '0 B';
477
+ error_log( "BFU: Processing \"$fileName\" part $current_part of $chunks as $filePath. $size processed so far." );
478
+ }
479
 
480
  $tuxbfu_max_upload_size = $this->get_upload_limit();
481
  if ( file_exists( $filePath ) && filesize( $filePath ) + filesize( $_FILES['async-upload']['tmp_name'] ) > $tuxbfu_max_upload_size ) {
482
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
483
+ error_log( "BFU: File size limit exceeded." );
484
+ }
485
 
486
  if ( ! $chunks || $chunk == $chunks - 1 ) {
487
  @unlink( $filePath );
518
  die();
519
  }
520
 
 
 
 
 
 
 
521
  /** Open temp file. */
522
  if ( $chunk == 0 ) {
523
  $out = @fopen( $filePath, 'wb');
613
  /** Check if file has finished uploading all parts. */
614
  if ( ! $chunks || $chunk == $chunks - 1 ) {
615
 
616
+ //debugging
617
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
618
+ $size = file_exists( $filePath ) ? size_format( filesize( $filePath ), 3 ) : '0 B';
619
+ error_log( "BFU: Completing \"$fileName\" upload with a $size final size." );
620
+ }
621
+
622
  /** Recreate upload in $_FILES global and pass off to WordPress. */
623
+ //rename( $filePath, $_FILES['async-upload']['tmp_name'] );
624
+ $_FILES['async-upload']['tmp_name'] = $filePath;
625
  $_FILES['async-upload']['name'] = $fileName;
626
  $_FILES['async-upload']['size'] = filesize( $_FILES['async-upload']['tmp_name'] );
627
+ $wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'] );
628
  $_FILES['async-upload']['type'] = $wp_filetype['type'];
629
  header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
630
 
631
+ if ( ! isset( $_REQUEST['short'] ) || ! isset( $_REQUEST['type'] ) ) { //ajax like media uploader in modal
 
632
  send_nosniff_header();
633
  nocache_headers();
634
+ $this->wp_ajax_upload_attachment();
635
  die( '0' );
636
 
637
+ } else { //non-ajax like add new media page
 
638
  $post_id = 0;
639
  if ( isset( $_REQUEST['post_id'] ) ) {
640
  $post_id = absint( $_REQUEST['post_id'] );
642
  $post_id = 0;
643
  }
644
 
645
+ $id = media_handle_upload( 'async-upload', $post_id, [], [ 'action' => 'wp_handle_sideload', 'test_form' => false ] );
646
  if ( is_wp_error( $id ) ) {
647
  printf(
648
  '<div class="error-div error">%s <strong>%s</strong><br />%s</div>',
693
  die();
694
  }
695
 
696
+ /**
697
+ * Copied from wp-admin/includes/ajax-actions.php because we have to override the args for
698
+ * the media_handle_upload function. As of WP 6.0.1
699
+ */
700
+ function wp_ajax_upload_attachment() {
701
+ check_ajax_referer( 'media-form' );
702
+ /*
703
+ * This function does not use wp_send_json_success() / wp_send_json_error()
704
+ * as the html4 Plupload handler requires a text/html content-type for older IE.
705
+ * See https://core.trac.wordpress.org/ticket/31037
706
+ */
707
+
708
+ if ( ! current_user_can( 'upload_files' ) ) {
709
+ echo wp_json_encode(
710
+ array(
711
+ 'success' => false,
712
+ 'data' => array(
713
+ 'message' => __( 'Sorry, you are not allowed to upload files.' ),
714
+ 'filename' => esc_html( $_FILES['async-upload']['name'] ),
715
+ ),
716
+ )
717
+ );
718
+
719
+ wp_die();
720
+ }
721
+
722
+ if ( isset( $_REQUEST['post_id'] ) ) {
723
+ $post_id = $_REQUEST['post_id'];
724
+
725
+ if ( ! current_user_can( 'edit_post', $post_id ) ) {
726
+ echo wp_json_encode(
727
+ array(
728
+ 'success' => false,
729
+ 'data' => array(
730
+ 'message' => __( 'Sorry, you are not allowed to attach files to this post.' ),
731
+ 'filename' => esc_html( $_FILES['async-upload']['name'] ),
732
+ ),
733
+ )
734
+ );
735
+
736
+ wp_die();
737
+ }
738
+ } else {
739
+ $post_id = null;
740
+ }
741
+
742
+ $post_data = ! empty( $_REQUEST['post_data'] ) ? _wp_get_allowed_postdata( _wp_translate_postdata( false, (array) $_REQUEST['post_data'] ) ) : array();
743
+
744
+ if ( is_wp_error( $post_data ) ) {
745
+ wp_die( $post_data->get_error_message() );
746
+ }
747
+
748
+ // If the context is custom header or background, make sure the uploaded file is an image.
749
+ if ( isset( $post_data['context'] ) && in_array( $post_data['context'], array( 'custom-header', 'custom-background' ), true ) ) {
750
+ $wp_filetype = wp_check_filetype_and_ext( $_FILES['async-upload']['tmp_name'], $_FILES['async-upload']['name'] );
751
+
752
+ if ( ! wp_match_mime_types( 'image', $wp_filetype['type'] ) ) {
753
+ echo wp_json_encode(
754
+ array(
755
+ 'success' => false,
756
+ 'data' => array(
757
+ 'message' => __( 'The uploaded file is not a valid image. Please try again.' ),
758
+ 'filename' => esc_html( $_FILES['async-upload']['name'] ),
759
+ ),
760
+ )
761
+ );
762
+
763
+ wp_die();
764
+ }
765
+ }
766
+
767
+ //this is the modded function from wp-admin/includes/ajax-actions.php
768
+ $attachment_id = media_handle_upload( 'async-upload', $post_id, $post_data, [ 'action' => 'wp_handle_sideload', 'test_form' => false ] );
769
+
770
+ if ( is_wp_error( $attachment_id ) ) {
771
+ echo wp_json_encode(
772
+ array(
773
+ 'success' => false,
774
+ 'data' => array(
775
+ 'message' => $attachment_id->get_error_message(),
776
+ 'filename' => esc_html( $_FILES['async-upload']['name'] ),
777
+ ),
778
+ )
779
+ );
780
+
781
+ wp_die();
782
+ }
783
+
784
+ if ( isset( $post_data['context'] ) && isset( $post_data['theme'] ) ) {
785
+ if ( 'custom-background' === $post_data['context'] ) {
786
+ update_post_meta( $attachment_id, '_wp_attachment_is_custom_background', $post_data['theme'] );
787
+ }
788
+
789
+ if ( 'custom-header' === $post_data['context'] ) {
790
+ update_post_meta( $attachment_id, '_wp_attachment_is_custom_header', $post_data['theme'] );
791
+ }
792
+ }
793
+
794
+ $attachment = wp_prepare_attachment_for_js( $attachment_id );
795
+ if ( ! $attachment ) {
796
+ wp_die();
797
+ }
798
+
799
+ echo wp_json_encode(
800
+ array(
801
+ 'success' => true,
802
+ 'data' => $attachment,
803
+ )
804
+ );
805
+
806
+ wp_die();
807
+ }
808
+
809
  /**
810
  * Return the maximum upload limit in bytes for the current user.
811
  *
uninstall.php CHANGED
@@ -22,3 +22,13 @@ delete_option( 'tuxbfu_settings' );
22
  delete_user_option( get_current_user_id(), 'bfu_notice_dismissed' );
23
  delete_user_option( get_current_user_id(), 'bfu_upgrade_notice_dismissed' );
24
  delete_user_option( get_current_user_id(), 'bfu_subscribe_notice_dismissed' );
 
 
 
 
 
 
 
 
 
 
22
  delete_user_option( get_current_user_id(), 'bfu_notice_dismissed' );
23
  delete_user_option( get_current_user_id(), 'bfu_upgrade_notice_dismissed' );
24
  delete_user_option( get_current_user_id(), 'bfu_subscribe_notice_dismissed' );
25
+
26
+ /** Delete any temp files */
27
+ $bfu_temp_dir = apply_filters( 'bfu_temp_dir', WP_CONTENT_DIR . '/bfu-temp' );
28
+ $files = glob( $bfu_temp_dir . '/*' );
29
+ if ( is_array( $files ) ) {
30
+ foreach ( $files as $file ) {
31
+ @unlink( $file );
32
+ }
33
+ }
34
+ @rmdir( $bfu_temp_dir );