<?php

/*
Written by Chris Jean for iThemes.com
Version 2.0.4

Version History
	2.0.0 - 2012-07-05 - Chris Jean
		Significant rewrite.
		Moved some functionality to files in the it-error directory.
		Made error reporting much more robust.
		Error message reporting now is conditional on either:
			The user is logged in
			The request has a non-empty GET variable named it_classes_show_errors
			The IT_CLASSES_SHOW_ERRORS define is set and is truthy
	2.0.1 - 2012-07-06 - Chris Jean
		Added support for IT_CLASSES_EXPAND_ERRORS define. When truthy, it shows the error box expanded by default
		Added support for IT_CLASSES_DISABLE_ERRORS. When truthy, it disables the error handler comletely
	2.0.2 - 2013-05-21 - Chris Jean
		Removed assign by reference.
	2.0.3 - 2013-06-25 - Chris Jean
		Changed function declarations to "public static".
	2.0.4 - 2013-11-25 - Chris Jean
		Fixed the improper adding of "public static" in front of the Javascript functions.
*/


if ( ! class_exists( 'ITError' ) ) {
	class ITError {
		public static function fatal( $code, $message ) {
			ob_start();
			
?>
	<table style="font-size:12px;padding:0;margin:0;">
		<tr><td style="font-weight:bold;">Error Code:</td>
			<td><?php echo $code; ?></td>
		</tr>
		<tr><td style="font-weight:bold;">Message:</td>
			<td><?php echo $message; ?></td>
		</tr>
	</table>
	<br />
<?php
			
			ITError::show_fatal_error_message( ob_get_clean() );
		}
		
		public static function show_fatal_error_message( $message ) {
			$message_toggle = ( defined( 'IT_CLASSES_EXPAND_ERRORS' ) && IT_CLASSES_EXPAND_ERRORS ) ? 'hide details' : 'show details';
			$message_display_style = ( defined( 'IT_CLASSES_EXPAND_ERRORS' ) && IT_CLASSES_EXPAND_ERRORS ) ? 'block' : 'none';
			
			
?>
	<div id="it-fatal-error-message-container" style="background:white;border:3px double red;padding:10px;margin:10px;position:absolute;top:0;left:0;z-index:100000;max-width:780px">
		<style scoped>
			h1, h2, table, div, pre, code { color: black; line-height: 1.3; font-size: 13px; font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; margin: 0; padding: 0; text-shadow: none; }
			h1 { color: red; font-weight: bold; font-size: 20px; margin-right: 10px; display: inline; }
			h2 { margin: 2em 0 1em; }
			a { color: blue; text-decoration: underline; }
			p { margin: 1em 0; }
			code, pre { font-family: monospace; white-space: normal; }
			code { margin: 0 5px; padding: 0 5px; background: #EEE; }
			table { border-collapse: collapse; margin: 0 0 0 25px; }
			table, tr, th, td { background: none !important; }
			table code { margin: 0; padding: 0; background: none; }
			th, td { border: 1px solid #CCC; padding: 5px; text-align: left; vertical-align: top; }
			ul { margin: 0; padding: 0 0 0 25px; }
			li { padding: 5px 0; margin: 0; list-style-type: circle; }
			#it-fatal-error-message :last-child { margin-bottom: 0; }
		</style>
		
		<div>
			<h1>Fatal Error</h1>
			<span id="it-fatal-error-message-links" style="display:none;">
				(<a id="it-fatal-error-message-toggle-link" href="javascript:it_fatal_error_toggle_message()"><?php echo $message_toggle; ?></a>)
				(<a href="javascript:it_fatal_error_remove_message()">remove</a>)
			</span>
		</div>
		
		<div id="it-fatal-error-message">
			<p>The site encountered a problem that it cannot recover from. Please use the following information to try to resolve the problem.</p>
			
			<?php echo $message; ?>
			<br />
			
			<p>Note that this message is generated by iThemes.com products when an error is encountered on the site. While an iThemes product is generating this message, it is not necessarily the cause of the problem.</p>
		</div>
	</div>
	<script>
		document.getElementById('it-fatal-error-message').style.display = '<?php echo $message_display_style; ?>';
		document.getElementById('it-fatal-error-message-links').style.display = 'inline';
		
		function it_fatal_error_toggle_message() {
			var container = document.getElementById('it-fatal-error-message');
			var link = document.getElementById('it-fatal-error-message-toggle-link');
			
			if('block' === container.style.display) {
				container.style.display = 'none';
				link.innerHTML = 'show details';
			}
			else {
				container.style.display = 'block';
				link.innerHTML = 'hide details';
			}
		}
		function it_fatal_error_remove_message() {
			document.getElementById('it-fatal-error-message-container').style.display = 'none';
		}
	</script>
<?php
			
			exit;
		}
		
		public static function admin_warn( $code, $message, $capability = 'switch_themes' ) {
			if ( current_user_can( $capability ) || ! empty( $_GET['show_it_error_messages'] ) )
				ITUtility::show_error_message( $message );
		}
		
		public static function warn( $code, $message ) {
			ITUtility::show_error_message( $message );
		}
		
		public static function developer_warn( $message, $show_backtrace = true ) {
			if ( ! WP_DEBUG )
				return;
			
			it_classes_load( 'it-debug.php' );
			
			
			$backtrace = ITDebug::get_backtrace( array( 'offset' => 2, 'remove_abspath' => false ) );
			
			echo "<pre style='color:black;background:white;padding:15px;font-family:\"Courier New\",Courier,monospace;font-size:12px;text-align:left;max-width:100%;'>";
			
			echo "<strong>Developer Notice</strong>\n";
			echo "    $message\n\n";
			
			echo "<strong>Stack Backtrace</strong>\n";
			
			foreach ( $backtrace as $trace )
				echo '    ' . ITDebug::get_backtrace_description( $trace ) . "\n";
			
			echo "</pre>\n";
		}
		
		public static function log( $code, $message, $type = 'warning' ) {
			it_classes_load( 'it-storage.php' );
			
			
			if ( ! preg_match( '/^(warning|error|fatal)$/', $type ) )
				$type = 'warning';
			
			$store = new ITStorage2( 'it-error', array( 'version' => '1.0.0', 'autoload' => 'no' ) );
			
			$data = $store->load();
			
			$log = ITError::get_debug_data( $code );
			$log['message'] = $message;
			
			$data[] = $log;
			
			$store->save( $data );
		}
		
		public static function get_debug_data( $code ) {
			$data = array();
			
			// Implement this at some time... Add info about timestamp, theme, files, permissions, debug_backtrace, etc
			
			return $data;
		}
		
		public static function upgrade_storage( $data ) {
			if ( version_compare( $data['storage_version'], '1.0.0', '<' ) )
				$data = ITError::_upgrade_storage_1_0_0( $data );
			
			return $data;
		}
		
		public static function _upgrade_storage_1_0_0( $data ) {
			$store = new ITStorage( 'ITError', true );
			$data = $store->load( false );
			$store->remove();
			
			$data['storage_version'] = '1.0.0';
			
			return $data;
		}
	}
	
	
	add_filter( 'ninja_shop_storage_upgrade_it-error', array( 'ITError', 'upgrade_storage' ) );
	
	if ( ( is_user_logged_in() || ! empty( $_GET['it_classes_show_errors'] ) || ( defined( 'IT_CLASSES_SHOW_ERRORS' ) && IT_CLASSES_SHOW_ERRORS ) ) && ( ! defined( 'IT_CLASSES_DISABLE_ERRORS' ) || ! IT_CLASSES_DISABLE_ERRORS ) ) {
		require_once( dirname( __FILE__ ) . '/it-error/class-it-classes-fatal-error-handler.php' );
	}
}
