HEX
Server: Apache/2.4.65 (Debian)
System: Linux wordpress-7cb4c6b6f6-qgbk2 5.15.0-131-generic #141-Ubuntu SMP Fri Jan 10 21:18:28 UTC 2025 x86_64
User: www-data (33)
PHP: 8.3.27
Disabled: NONE
Upload Files
File: /var/www/html/wp-content/plugins/Crocoblock-wizard/includes/tools/files-download.php
<?php
namespace Crocoblock_Wizard\Tools;

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
	die;
}

/**
 * Define Main exporter class
 */
class Files_Download {

	private $filename;
	private $filepath;
	private $format;
	private $content;

	/**
	 * Constructor for the class
	 */
	function __construct( $filename = null, $filepath = null, $format = 'zip', $content = false ) {
		$this->filename = $filename;
		$this->filepath = $filepath;
		$this->format   = $format;
		$this->content  = $content;
	}

	/**
	 * Set download headers
	 */
	public function set_headers() {

		set_time_limit( 0 );

		@session_write_close();

		if( function_exists( 'apache_setenv' ) ) {
			@apache_setenv('no-gzip', 1);
		}

		@ini_set( 'zlib.output_compression', 'Off' );

		nocache_headers();

		header( "Robots: none" );
		header( "Content-Type: application/" . $this->format );
		header( "Content-Description: File Transfer" );
		header( "Content-Disposition: attachment; filename=\"" . $this->filename . "\";" );
		header( "Content-Transfer-Encoding: binary" );

		if ( $this->filepath ) {
			// Set the file size header
			header( "Content-Length: " . @filesize( $this->filepath ) );
		}

	}

	/**
	 * Preocess file download by path and name
	 */
	public function download() {

		$this->set_headers();

		if ( $this->filepath ) {
			$this->readfile_chunked( $this->filepath );
		} elseif ( $this->content ) {
			echo $this->content;
		} else {
			echo 'Incorrect input';
		}

		die();

	}

	/**
	 * Reads file in chunks so big downloads are possible without changing PHP.INI
	 * See http://codeigniter.com/wiki/Download_helper_for_large_files/
	 *	 *
	 * @param    string  $file     The file
	 * @param    boolean $retbytes Return the bytes of file
	 *
	 * @return   bool|string        If string, $status || $cnt
	 */
	private function readfile_chunked( $file, $retbytes = true ) {

		while ( ob_get_level() > 0 ) {
			ob_end_clean();
		}

		ob_start();

		// If output buffers exist, make sure they are closed. See https://github.com/easydigitaldownloads/easy-digital-downloads/issues/6387
		if ( ob_get_length() ) {
			ob_clean();
		}

		$chunksize = 1024 * 1024;
		$buffer    = '';
		$cnt       = 0;
		$handle    = @fopen( $file, 'rb' );

		if ( $size = @filesize( $file ) ) {
			header( "Content-Length: " . $size );
		}

		if ( false === $handle ) {
			return false;
		}

		if ( isset( $_SERVER['HTTP_RANGE'] ) ) {
			list( $size_unit, $range ) = explode( '=', $_SERVER['HTTP_RANGE'], 2 );
			if ( 'bytes' === $size_unit ) {
				if ( strpos( ',', $range ) ) {
					list( $range ) = explode( ',', $range, 1 );
				}
			} else {
				$range = '';
				header( 'HTTP/1.1 416 Requested Range Not Satisfiable' );
				exit;
			}
		} else {
			$range = '';
		}

		if ( empty( $range ) ) {
			$seek_start = null;
			$seek_end   = null;
		} else {
			list( $seek_start, $seek_end ) = explode( '-', $range, 2 );
		}

		$seek_end   = ( empty( $seek_end ) ) ? ( $size - 1 ) : min( abs( intval( $seek_end ) ), ( $size - 1 ) );
		$seek_start = ( empty( $seek_start ) || $seek_end < abs( intval( $seek_start ) ) ) ? 0 : max( abs( intval( $seek_start ) ), 0 );

		// Only send partial content header if downloading a piece of the file (IE workaround)
		if ( $seek_start > 0 || $seek_end < ( $size - 1 ) ) {
			header( 'HTTP/1.1 206 Partial Content' );
			header( 'Content-Range: bytes ' . $seek_start . '-' . $seek_end . '/' . $size );
			header( 'Content-Length: ' . ( $seek_end - $seek_start + 1 ) );
		} else {
			header( "Content-Length: $size" );
		}

		header( 'Accept-Ranges: bytes' );

		set_time_limit( 0 );
		fseek( $handle, $seek_start );

		while ( ! @feof( $handle ) ) {
			$buffer = @fread( $handle, $chunksize );
			echo $buffer;
			ob_flush();

			if ( $retbytes ) {
				$cnt += strlen( $buffer );
			}

			if ( connection_status() != 0 ) {
				@fclose( $handle );
				exit;
			}
		}

		ob_flush();

		$status = @fclose( $handle );

		if ( $retbytes && $status ) {
			return $cnt;
		}

		return $status;
	}


}