class-file-upload-upgrader.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <?php
  2. /**
  3. * Upgrade API: File_Upload_Upgrader class
  4. *
  5. * @package WordPress
  6. * @subpackage Upgrader
  7. * @since 4.6.0
  8. */
  9. /**
  10. * Core class used for handling file uploads.
  11. *
  12. * This class handles the upload process and passes it as if it's a local file
  13. * to the Upgrade/Installer functions.
  14. *
  15. * @since 2.8.0
  16. * @since 4.6.0 Moved to its own file from wp-admin/includes/class-wp-upgrader.php.
  17. */
  18. #[AllowDynamicProperties]
  19. class File_Upload_Upgrader {
  20. /**
  21. * The full path to the file package.
  22. *
  23. * @since 2.8.0
  24. * @var string $package
  25. */
  26. public $package;
  27. /**
  28. * The name of the file.
  29. *
  30. * @since 2.8.0
  31. * @var string $filename
  32. */
  33. public $filename;
  34. /**
  35. * The ID of the attachment post for this file.
  36. *
  37. * @since 3.3.0
  38. * @var int $id
  39. */
  40. public $id = 0;
  41. /**
  42. * Construct the upgrader for a form.
  43. *
  44. * @since 2.8.0
  45. *
  46. * @param string $form The name of the form the file was uploaded from.
  47. * @param string $urlholder The name of the `GET` parameter that holds the filename.
  48. */
  49. public function __construct( $form, $urlholder ) {
  50. if ( empty( $_FILES[ $form ]['name'] ) && empty( $_GET[ $urlholder ] ) ) {
  51. wp_die( __( 'Please select a file' ) );
  52. }
  53. // Handle a newly uploaded file. Else, assume it's already been uploaded.
  54. if ( ! empty( $_FILES ) ) {
  55. $overrides = array(
  56. 'test_form' => false,
  57. 'test_type' => false,
  58. );
  59. $file = wp_handle_upload( $_FILES[ $form ], $overrides );
  60. if ( isset( $file['error'] ) ) {
  61. wp_die( $file['error'] );
  62. }
  63. $this->filename = $_FILES[ $form ]['name'];
  64. $this->package = $file['file'];
  65. // Construct the attachment array.
  66. $attachment = array(
  67. 'post_title' => $this->filename,
  68. 'post_content' => $file['url'],
  69. 'post_mime_type' => $file['type'],
  70. 'guid' => $file['url'],
  71. 'context' => 'upgrader',
  72. 'post_status' => 'private',
  73. );
  74. // Save the data.
  75. $this->id = wp_insert_attachment( $attachment, $file['file'] );
  76. // Schedule a cleanup for 2 hours from now in case of failed installation.
  77. wp_schedule_single_event( time() + 2 * HOUR_IN_SECONDS, 'upgrader_scheduled_cleanup', array( $this->id ) );
  78. } elseif ( is_numeric( $_GET[ $urlholder ] ) ) {
  79. // Numeric Package = previously uploaded file, see above.
  80. $this->id = (int) $_GET[ $urlholder ];
  81. $attachment = get_post( $this->id );
  82. if ( empty( $attachment ) ) {
  83. wp_die( __( 'Please select a file' ) );
  84. }
  85. $this->filename = $attachment->post_title;
  86. $this->package = get_attached_file( $attachment->ID );
  87. } else {
  88. // Else, It's set to something, Back compat for plugins using the old (pre-3.3) File_Uploader handler.
  89. $uploads = wp_upload_dir();
  90. if ( ! ( $uploads && false === $uploads['error'] ) ) {
  91. wp_die( $uploads['error'] );
  92. }
  93. $this->filename = sanitize_file_name( $_GET[ $urlholder ] );
  94. $this->package = $uploads['basedir'] . '/' . $this->filename;
  95. if ( 0 !== strpos( realpath( $this->package ), realpath( $uploads['basedir'] ) ) ) {
  96. wp_die( __( 'Please select a file' ) );
  97. }
  98. }
  99. }
  100. /**
  101. * Delete the attachment/uploaded file.
  102. *
  103. * @since 3.2.2
  104. *
  105. * @return bool Whether the cleanup was successful.
  106. */
  107. public function cleanup() {
  108. if ( $this->id ) {
  109. wp_delete_attachment( $this->id );
  110. } elseif ( file_exists( $this->package ) ) {
  111. return @unlink( $this->package );
  112. }
  113. return true;
  114. }
  115. }