<?php
# MantisBT - A PHP based bugtracking system

# MantisBT is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# MantisBT is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with MantisBT.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Compression API
 *
 * @package CoreAPI
 * @subpackage CompressionAPI
 * @copyright Copyright 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
 * @copyright Copyright 2002  MantisBT Team - mantisbt-dev@lists.sourceforge.net
 * @link http://www.mantisbt.org
 *
 * @uses constant_inc.php
 * @uses utility_api.php
 */

require_api( 'constant_inc.php' );
require_api( 'utility_api.php' );

# Starts the buffering/compression (only if the compression option is ON)
# This variable is used internally.  It is not used for configuration
# @global bool $g_compression_started
$g_compression_started = false;

/**
 * Check if compression handler (ob_gzhandler) should be enabled.
 *
 * Note: this should not be used as an indicator of whether output received by a
 * client will be compressed, only whether an output handler is used to compress
 * output.
 *
 * @return boolean
 * @access public
 */
function compress_handler_is_enabled() {
	global $g_compress_html;

	# indicates compression should be disabled for a page.
	# Note: php.ini may still enable zlib.output_compression. It may be possible
	# to turn this off through the use of ini_set within that specific page.
	if( defined( 'COMPRESSION_DISABLED' ) ) {
		return false;
	}

	# Do not use config_get() here so only dependency is on constant_inc.php in this module
	# We only actively compress html if global configuration compress_html is set.
	if( OFF == $g_compress_html ) {
		return false;
	}

	# both compression handlers require zlib module to be loaded
	if( !extension_loaded( 'zlib' ) ) {
		return false;
	}

	if( ini_get( 'zlib.output_compression' ) ) {
		# zlib output compression is already enabled - we can't load the gzip output handler
		return false;
	}

	# It's possible to set zlib.output_compression via ini_set.
	# This method is preferred over ob_gzhandler, and effectively starts output buffering.
	if( ini_get( 'output_handler' ) == '' && function_exists( 'ini_set' ) ) {
		ini_set( 'zlib.output_compression', true );
		# do it transparently
		return false;
	}

	# if php.ini does not already use ob_gzhandler by default, return true.
	return ( 'ob_gzhandler' != ini_get( 'output_handler' ) );
}

/**
 * Start compression handler if required
 * @return void
 * @access public
 */
function compress_start_handler() {
	# Don't start compression for CLI or when expressly disabled
	if( php_sapi_name() == 'cli'  || defined( 'COMPRESSION_DISABLED' ) ) {
		return;
	}

	# Do not start compress handler if we got any output so far, as this
	# denotes that an error has occurred. Enabling compression in this case
	# will likely cause a Content Encoding Error when displaying the page.
	if( ob_get_length() ) {
		return;
	}

	if( compress_handler_is_enabled() ) {
		# Before doing anything else, start output buffering so we don't prevent
		# headers from being sent if there's a blank line in an included file
		ob_start( 'compress_handler' );
	} else if( ini_get_bool( 'zlib.output_compression' ) == true ) {
		# @TODO is this really needed ? We already start buffering in core.php
		ob_start();
	}
}

/**
 * Output Buffering handler.
 *
 * Either compresses the buffer or just returns it as-is, depending on the
 * return value of compress_handler_is_enabled()
 *
 * @param string  $p_buffer Buffer.
 * @param integer $p_mode   Mode.
 * @return string
 * @access public
 */
function compress_handler( $p_buffer, $p_mode ) {
	global $g_compression_started;
	if( $g_compression_started && compress_handler_is_enabled() ) {
		/**
		 * @noinspection PhpComposerExtensionStubsInspection
		 *               compress_handler_is_enabled() returns false if zlib
		 *               extension is not available.
		 */
		return ob_gzhandler( $p_buffer, $p_mode );
	} else {
		return $p_buffer;
	}
}

/**
 * Enable output buffering with compression.
 * @return void
 * @access public
 */
function compress_enable() {
	global $g_compression_started;

	$g_compression_started = true;
}

/**
 * Disable output buffering with compression.
 * @return void
 * @access public
 */
function compress_disable() {
	global $g_compression_started;

	$g_compression_started = false;
}
