Invision Power Services, Inc. * @copyright (c) Invision Power Services, Inc. * @license https://www.invisioncommunity.com/legal/standards/ * @package Invision Community * @since 17 Oct 2013 */ namespace IPS\Output; /* To prevent PHP errors (extending class does not exist) revealing path */ use IPS\Dispatcher; use IPS\Http\Url; use IPS\Output; use IPS\Theme; use function defined; use function strstr; use function uniqid; if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) ) { header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' ); exit; } /** * Output Class */ class System extends Output { /** * Display Error Screen * * @param string $message language key for error message * @param mixed $code Error code * @param int $httpStatusCode HTTP Status Code * @param string|null $adminMessage language key for error message to show to admins * @param array $httpHeaders Additional HTTP Headers * @param string|null $extra Additional information (such as API error) * @param int|string|null $faultyAppOrHookId * @return void */ public function error( string $message, mixed $code, int $httpStatusCode=500, string $adminMessage=NULL, array $httpHeaders=array(), string $extra=NULL, int|string $faultyAppOrHookId=NULL ) : void { /* Send output */ $this->sendOutput( Theme::i()->getTemplate('global', 'core', 'global')->error( $message ), $httpStatusCode, 'text/html', $httpHeaders ); } /** * Send output * * @param string $output Content to output * @param int $httpStatusCode HTTP Status Code * @param string $contentType HTTP Content-type * @param array $httpHeaders Additional HTTP Headers * @param bool $cacheThisPage * @param bool $pageIsCached * @param bool $parseFileObjects * @param bool $parseEmoji * @return void */ public function sendOutput(string $output='', int $httpStatusCode=200, string $contentType='text/html', array $httpHeaders=array(), bool $cacheThisPage=TRUE, bool $pageIsCached=FALSE, bool $parseFileObjects=TRUE, bool $parseEmoji=TRUE ) : void { /* Set HTTP status */ if( isset( $_SERVER['SERVER_PROTOCOL'] ) and strstr( $_SERVER['SERVER_PROTOCOL'], '/1.0' ) !== false ) { header( "HTTP/1.0 {$httpStatusCode} " . static::$httpStatuses[ $httpStatusCode ] ); } else { header( "HTTP/1.1 {$httpStatusCode} " . static::$httpStatuses[ $httpStatusCode ] ); } /* Buffer output */ if ( $output ) { if( isset( $_SERVER['HTTP_ACCEPT_ENCODING'] ) and strstr( $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip' ) !== false and (bool) ini_get('zlib.output_compression') === false ) { ob_start('ob_gzhandler'); } else { ob_start(); } print Theme::i()->getTemplate('global', 'core', 'global')->globalTemplate( $output, static::i()->title, array( 'app' => Dispatcher::i()->application->directory, 'module' => Dispatcher::i()->module->key, 'controller' => Dispatcher::i()->controller ) ); } /* Send headers */ $size = ob_get_length(); header( "Content-type: {$contentType};charset=UTF-8" ); header( "Content-Length: {$size}" ); foreach ( $httpHeaders as $header ) { header( $header ); } header( "Connection: close" ); /* Flush and exit */ ob_end_flush(); flush(); exit; } /** * Redirect * * @param Url|string $url URL to redirect to * @param string|null $message Optional message to display * @param int $httpStatusCode HTTP Status Code * @param bool $forceScreen If TRUE, an intermeditate screen will be shown * @return void */ public function redirect( Url|string $url, ?string $message='', int $httpStatusCode=301, bool $forceScreen=FALSE ) : void { if ( $forceScreen === TRUE ) { $this->sendOutput( Theme::i()->getTemplate( 'global', 'core', 'global' )->redirect( $url, $message ), $httpStatusCode ); } $this->sendOutput( '', $httpStatusCode, '', array( "Location: {$url}" ) ); } /** * Create a HTML file of the MySQL debug backtrace * * @param array $debug * @return string */ public static function generateDbLogHtml( array $debug ): string { $queryCount = count( $debug ) - 1; # The first query is the connection $html = <<
| Function | File | Line | Details | {$data['query']} | HTML; foreach( $data['backtrace'] as $id => $trace ) { $trace['file'] = isset( $trace['file'] ) ? str_replace( \IPS\ROOT_PATH, '', $trace['file'] ) : ''; $trace['line'] = $trace['line'] ?? ''; $html .= << | {$trace['function']} | {$trace['file']} | {$trace['line']} | HTML; } } $html .= << |
|---|