Completed
Branch BUG-9548-transaction-completio... (b10ae2)
by
unknown
558:48 queued 538:36
created

EEH_Debug_Tools::__construct()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 18
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 18
rs 9.4285
c 1
b 0
f 1
cc 3
eloc 7
nc 2
nop 0
1
<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {exit('No direct script access allowed');}
2
/**
3
 * Class EEH_Debug_Tools
4
 *
5
 * @package 			Event Espresso
6
 * @subpackage 	core
7
 * @author 				Brent Christensen, Michael Nelson
8
 * @since 				4.0
9
 *
10
 */
11
class EEH_Debug_Tools{
12
13
	/**
14
	 * 	instance of the EEH_Autoloader object
15
	 *	@var 	$_instance
16
	 * 	@access 	private
17
	 */
18
	private static $_instance;
19
20
	/**
21
	 * array containing the start time for the timers
22
	 */
23
	private $_start_times;
24
	/**
25
	 * array containing all the timer'd times, which can be outputted via show_times()
26
	 */
27
	private $_times = array();
28
29
	/**
30
	 *
31
	 * @var array
32
	 */
33
	protected $_memory_usage_points = array();
34
35
36
37
	/**
38
	 *	@singleton method used to instantiate class object
39
	 *	@access public
40
	 *	@return EEH_Debug_Tools
41
	 */
42
	public static function instance() {
43
		// check if class object is instantiated, and instantiated properly
44
		if ( ! self::$_instance instanceof EEH_Debug_Tools ) {
45
			self::$_instance = new self();
46
		}
47
		return self::$_instance;
48
	}
49
50
51
52
	/**
53
	 *    class constructor
54
	 *
55
	 * @access    private
56
	 * @return \EEH_Debug_Tools
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
57
	 */
58
	private function __construct() {
59
		// load Kint PHP debugging library
60
		if ( ! class_exists( 'Kint' ) &&  file_exists( EE_PLUGIN_DIR_PATH . 'tests' . DS . 'kint' . DS . 'Kint.class.php' )){
61
			// despite EE4 having a check for an existing copy of the Kint debugging class,
62
			// if another plugin was loaded AFTER EE4 and they did NOT perform a similar check,
63
			// then hilarity would ensue as PHP throws a "Cannot redeclare class Kint" error
64
			// so we've moved it to our test folder so that it is not included with production releases
65
			// plz use https://wordpress.org/plugins/kint-debugger/  if testing production versions of EE
66
			require_once( EE_PLUGIN_DIR_PATH . 'tests' . DS . 'kint' . DS . 'Kint.class.php' );
67
		}
68
		// if ( ! defined('DOING_AJAX') || $_REQUEST['noheader'] !== 'true' || ! isset( $_REQUEST['noheader'], $_REQUEST['TB_iframe'] ) ) {
69
			//add_action( 'shutdown', array($this,'espresso_session_footer_dump') );
70
		// }
71
		$plugin = basename( EE_PLUGIN_DIR_PATH );
72
		add_action( "activate_{$plugin}", array( 'EEH_Debug_Tools', 'ee_plugin_activation_errors' ));
73
		add_action( 'activated_plugin', array( 'EEH_Debug_Tools', 'ee_plugin_activation_errors' ));
74
		add_action( 'shutdown', array( 'EEH_Debug_Tools', 'show_db_name' ));
75
	}
76
77
78
79
	/**
80
	 * 	show_db_name
81
	 *
82
	 * 	@return void
83
	 */
84
	public static function show_db_name() {
85
		if ( ! defined( 'DOING_AJAX' ) && ( defined( 'EE_ERROR_EMAILS' ) && EE_ERROR_EMAILS )) {
86
			echo '<p style="font-size:10px;font-weight:normal;color:#E76700;margin: 1em 2em; text-align: right;">DB_NAME: '. DB_NAME .'</p>';
87
		}
88
	}
89
90
91
92
	/**
93
	 * 	dump EE_Session object at bottom of page after everything else has happened
94
	 *
95
	 * 	@return void
96
	 */
97
	public function espresso_session_footer_dump() {
98
		if (
99
			( defined( 'WP_DEBUG' ) && WP_DEBUG )
100
			&& ! defined( 'DOING_AJAX' )
101
			&& class_exists( 'Kint' )
102
			&& function_exists( 'wp_get_current_user' )
103
			&& current_user_can( 'update_core' )
104
			&& class_exists( 'EE_Registry' )
105
		) {
106
			Kint::dump(  EE_Registry::instance()->SSN->id() );
107
			Kint::dump( EE_Registry::instance()->SSN );
108
			//			Kint::dump( EE_Registry::instance()->SSN->get_session_data('cart')->get_tickets() );
109
			$this->espresso_list_hooked_functions();
110
			$this->show_times();
111
		}
112
	}
113
114
115
116
	/**
117
	 *    List All Hooked Functions
118
	 *    to list all functions for a specific hook, add ee_list_hooks={hook-name} to URL
119
	 *    http://wp.smashingmagazine.com/2009/08/18/10-useful-wordpress-hook-hacks/
120
	 *
121
	 * @param string $tag
122
	 * @return void
123
	 */
124
	public function espresso_list_hooked_functions( $tag='' ){
125
		global $wp_filter;
126
		echo '<br/><br/><br/><h3>Hooked Functions</h3>';
127
		if ( $tag ) {
128
			$hook[$tag]=$wp_filter[$tag];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$hook was never initialized. Although not strictly required by PHP, it is generally a good practice to add $hook = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
129
			if ( ! is_array( $hook[$tag] )) {
130
				trigger_error( "Nothing found for '$tag' hook", E_USER_WARNING );
131
				return;
132
			}
133
			echo '<h5>For Tag: '. $tag .'</h5>';
134
		}
135
		else {
136
			$hook=$wp_filter;
137
			ksort( $hook );
138
		}
139
		foreach( $hook as $tag_name => $priorities ) {
140
			echo "<br />&gt;&gt;&gt;&gt;&gt;\t<strong>$tag_name</strong><br />";
141
			ksort( $priorities );
142
			foreach( $priorities as $priority => $function ){
143
				echo $priority;
144
				foreach( $function as $name => $properties ) {
145
					echo "\t$name<br />";
146
				}
147
			}
148
		}
149
	}
150
151
152
153
	/**
154
	 *    registered_filter_callbacks
155
	 *
156
	 * @param string $hook_name
157
	 * @return array
158
	 */
159
	public static function registered_filter_callbacks( $hook_name = '' ) {
160
		$filters = array();
161
		global $wp_filter;
162
		if ( isset( $wp_filter[ $hook_name ] ) ) {
163
			$filters[ $hook_name ] = array();
164
			foreach ( $wp_filter[ $hook_name ] as $priority => $callbacks ) {
165
				$filters[ $hook_name ][ $priority ] = array();
166
				foreach ( $callbacks as $callback ) {
167
					$filters[ $hook_name ][ $priority ][] = $callback['function'];
168
				}
169
			}
170
		}
171
		return $filters;
172
	}
173
174
175
176
	/**
177
	 * reset_times
178
	 */
179
	public function reset_times(){
180
		$this->_times = array();
181
	}
182
183
184
185
	/**
186
	 * 	start_timer
187
	 * @param null $timer_name
188
	 */
189
	public function start_timer( $timer_name = NULL ){
190
		$this->_start_times[$timer_name] = microtime( TRUE );
191
	}
192
193
194
195
	/**
196
	 * stop_timer
197
	 * @param string $timer_name
198
	 */
199
	public function stop_timer($timer_name = 'default'){
200
		if( isset( $this->_start_times[ $timer_name ] ) ){
201
			$start_time = $this->_start_times[ $timer_name ];
202
			unset( $this->_start_times[ $timer_name ] );
203
		}else{
204
			$start_time = array_pop( $this->_start_times );
205
		}
206
		$total_time = microtime( TRUE ) - $start_time;
207
		switch ( $total_time ) {
208
			case $total_time < 0.00001 :
209
				$color = '#8A549A';
210
				$bold = 'normal';
211
				break;
212
			case $total_time < 0.0001 :
213
				$color = '#00B1CA';
214
				$bold = 'normal';
215
				break;
216
			case $total_time < 0.001 :
217
				$color = '#70CC50';
218
				$bold = 'normal';
219
				break;
220
			case $total_time < 0.01 :
221
				$color = '#FCC600';
222
				$bold = 'bold';
223
				break;
224
			case $total_time < 0.1 :
225
				$color = '#E76700';
226
				$bold = 'bold';
227
				break;
228
			default :
229
				$color = '#E44064';
230
				$bold = 'bold';
231
				break;
232
		}
233
		$this->_times[] = '<hr /><div style="display: inline-block; min-width: 10px; margin:0 1em; color:'.$color.'; font-weight:'.$bold.'; font-size:1.2em;">' . number_format( $total_time, 8 ) . '</div> ' . $timer_name;
234
	}
235
	/**
236
	 * Measure the memory usage by PHP so far.
237
	 * @param string $label The label to show for this time eg "Start of calling Some_Class::some_function"
238
	 * @param boolean $output_now whether to echo now, or wait until EEH_Debug_Tools::show_times() is called
239
	 * @return void
240
	 */
241
	public function measure_memory( $label, $output_now = false ) {
242
		$memory_used = $this->convert( memory_get_peak_usage( true ) );
243
		$this->_memory_usage_points[ $label ] = $memory_used;
244
		if( $output_now ) {
245
			echo "\r\n<br>$label : $memory_used";
246
		}
247
	}
248
249
	/**
250
	 * Converts a measure of memory bytes into the most logical units (eg kb, mb, etc)
251
	 * @param int $size
252
	 * @return string
253
	 */
254
	public function convert( $size ) {
255
		$unit=array('b','kb','mb','gb','tb','pb');
256
		return @round( $size / pow( 1024, $i = floor( log( $size, 1024 ) ) ), 2 ) . ' ' . $unit[ absint( $i ) ];
257
	}
258
259
260
261
	/**
262
	 * show_times
263
	 * @param bool $output_now
264
	 * @return string
265
	 */
266
	public function show_times($output_now=true){
267
		$output = '<h2>Times:</h2>' . implode("<br>",$this->_times) . '<h2>Memory</h2>' . implode('<br>', $this->_memory_usage_points );
268
		if($output_now){
269
			echo $output;
270
			return '';
271
		}
272
		return $output;
273
	}
274
275
276
277
	/**
278
	 * 	captures plugin activation errors for debugging
279
	 *
280
	 * 	@return void
281
	 */
282
	public static function ee_plugin_activation_errors() {
283
		if ( WP_DEBUG ) {
284
			$activation_errors = ob_get_contents();
285
			if ( ! empty( $activation_errors ) ) {
286
				$activation_errors = date( 'Y-m-d H:i:s' ) . "\n" . $activation_errors;
287
			}
288
			espresso_load_required( 'EEH_File', EE_HELPERS . 'EEH_File.helper.php' );
289
			if ( class_exists( 'EEH_File' )) {
290
				try {
291
					EEH_File::ensure_file_exists_and_is_writable( EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html' );
292
					EEH_File::write_to_file( EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html', $activation_errors );
293
				} catch( EE_Error $e ){
294
					EE_Error::add_error( sprintf( __(  'The Event Espresso activation errors file could not be setup because: %s', 'event_espresso' ), $e->getMessage() ), __FILE__, __FUNCTION__, __LINE__ );
295
				}
296
			} else {
297
				// old school attempt
298
				file_put_contents( EVENT_ESPRESSO_UPLOAD_DIR . 'logs' . DS . 'espresso_plugin_activation_errors.html', $activation_errors );
299
			}
300
			$activation_errors = get_option( 'ee_plugin_activation_errors', '' ) . $activation_errors;
301
			update_option( 'ee_plugin_activation_errors', $activation_errors );
302
		}
303
	}
304
305
306
307
	/**
308
	 * This basically mimics the WordPress _doing_it_wrong() function except adds our own messaging etc.  Very useful for providing helpful messages to developers when the method of doing something has been deprecated, or we want to make sure they use something the right way.
309
	 *
310
	 * @access public
311
	 * @param  string $function The function that was called
312
	 * @param  string $message A message explaining what has been done incorrectly
313
	 * @param  string $version The version of Event Espresso where the error was added
314
	 * @param int     $error_type
315
	 * @uses trigger_error()
316
	 */
317
	public function doing_it_wrong( $function, $message, $version, $error_type = E_USER_NOTICE ) {
318
		do_action( 'AHEE__EEH_Debug_Tools__doing_it_wrong_run', $function, $message, $version);
319
		$version = $version === null ? '' : sprintf( __('(This message was added in version %s of Event Espresso.', 'event_espresso' ), $version );
320
		$error_message = sprintf( esc_html__('%1$s was called %2$sincorrectly%3$s. %4$s %5$s','event_espresso' ), $function, '<strong>', '</strong>', $message, $version );
321
322
		//don't trigger error if doing ajax, instead we'll add a transient EE_Error notice that in theory should show on the next request.
323
		if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
324
			$error_message .= esc_html__( 'This is a doing_it_wrong message that was triggered during an ajax request.  The request params on this request were: ', 'event_espresso' );
325
			$error_message .= '<ul><li>';
326
			$error_message .= implode( '</li><li>', EE_Registry::instance()->REQ->params() );
327
			$error_message .= '</ul>';
328
			EE_Error::add_error( $error_message, 'debug::doing_it_wrong', $function, '42' );
329
			//now we set this on the transient so it shows up on the next request.
330
			EE_Error::get_notices( is_admin(), true );
331
		} else {
332
			trigger_error( $error_message, $error_type );
333
		}
334
	}
335
336
337
338
339
	/**
340
	 * Logger helpers
341
	 */
342
343
	/**
344
	 * debug
345
	 *
346
	 * @param string $class
347
	 * @param string $func
348
	 * @param string $line
349
	 * @param array $info
350
	 * @param bool $display_request
351
	 * @param string $debug_index
352
	 * @param string $debug_key
353
	 */
354
	public static function log( $class='', $func = '', $line = '', $info = array(), $display_request = false,  $debug_index = '', $debug_key = 'EE_DEBUG_SPCO' ) {
355
		if ( WP_DEBUG && false ) {
356
			$debug_key = $debug_key . '_' . EE_Session::instance()->id();
357
			$debug_data = get_option( $debug_key, array() );
358
			$default_data = array(
359
				$class => $func . '() : ' . $line,
360
				'REQ'  => $display_request ? $_REQUEST : '',
361
			);
362
			// don't serialize objects
363
			$info = self::strip_objects( $info );
364
			$index = ! empty( $debug_index ) ? $debug_index : 0;
365
			if ( ! isset( $debug_data[$index] ) ) {
366
				$debug_data[$index] = array();
367
			}
368
			$debug_data[$index][microtime()] = array_merge( $default_data, $info );
369
			update_option( $debug_key, $debug_data );
370
		}
371
	}
372
373
374
375
	/**
376
	 * strip_objects
377
	 *
378
	 * @param array $info
379
	 * @return array
380
	 */
381
	public static function strip_objects( $info = array() ) {
382
		foreach ( $info as $key => $value ) {
383
			if ( is_array( $value ) ) {
384
				$info[ $key ] = self::strip_objects( $value );
385 View Code Duplication
			} else if ( is_object( $value ) ) {
386
				$object_class = get_class( $value );
387
				$info[ $object_class ] = array();
388
				$info[ $object_class ][ 'ID' ] = method_exists( $value, 'ID' ) ? $value->ID() : spl_object_hash( $value );
389
				if ( method_exists( $value, 'ID' ) ) {
390
					$info[ $object_class ][ 'ID' ] = $value->ID();
391
				}
392
				if ( method_exists( $value, 'status' ) ) {
393
					$info[ $object_class ][ 'status' ] = $value->status();
394
				} else if ( method_exists( $value, 'status_ID' ) ) {
395
					$info[ $object_class ][ 'status' ] = $value->status_ID();
396
				}
397
				unset( $info[ $key ] );
398
			}
399
		}
400
		return (array)$info;
401
	}
402
403
404
405
	/**
406
	 * @param mixed  $var
407
	 * @param string $var_name
408
	 * @param string $file
409
	 * @param int    $line
410
	 * @param int    $header
411
	 * @param bool   $die
412
	 */
413
	public static function printv( $var, $var_name = '', $file = __FILE__, $line = __LINE__, $header = 5, $die = false ) {
414
		$var_name = ! $var_name ? 'string' : $var_name;
415
		$heading_tag = 'h';
416
		$heading_tag .= is_int( $header ) ? $header : 5;
417
		$var_name = ucwords( str_replace( '$', '', $var_name ) );
418
		$is_method = method_exists( $var_name, $var );
419
		$var_name = ucwords( str_replace( '_', ' ', $var_name ) );
420
		$result = '<' . $heading_tag . ' style="color:#2EA2CC; margin:25px 0 0;"><b>' . $var_name . '</b>';
421
		$result .= $is_method
422
			? '<span style="color:#999">::</span><span style="color:#E76700">' . $var . '()</span><br />'
423
			: '<span style="color:#999"> : </span><span style="color:#E76700">' . $var . '</span><br />';
424
		$result .= '<span style="font-size:9px;font-weight:normal;color:#666;line-height: 12px;">' . $file;
425
		$result .= '<br />line no: ' . $line . '</span>';
426
		$result .= '</' . $heading_tag . '>';
427
		if ( $die ) {
428
			die( $result );
429
		} else {
430
			echo $result;
431
		}
432
	}
433
434
435
	/**
436
	 * @param mixed $var
437
	 * @param string $var_name
438
	 * @param string $file
439
	 * @param int $line
440
	 * @param int $header
441
	 * @param bool $die
442
	 */
443
	public static function printr( $var, $var_name = '', $file = __FILE__, $line = __LINE__, $header = 5, $die = false ) {
444
		// return;
445
		$file = str_replace( rtrim( ABSPATH, '\\/' ), '', $file );
446
		//$print_r = false;
447
		if ( is_string( $var ) ) {
448
			EEH_Debug_Tools::printv( $var, $var_name, $file, $line, $header, $die );
449
			return;
450
		} else if ( is_object( $var ) ) {
451
			$var_name = ! $var_name ? 'object' : $var_name;
452
			//$print_r = true;
453
		} else if ( is_array( $var ) ) {
454
			$var_name = ! $var_name ? 'array' : $var_name;
455
			//$print_r = true;
456
		} else if ( is_numeric( $var ) ) {
457
			$var_name = ! $var_name ? 'numeric' : $var_name;
458
		} else if ( is_null( $var ) ) {
459
			$var_name = ! $var_name ? 'null' : $var_name;
460
		}
461
		$heading_tag = 'h';
462
		$heading_tag .= is_int( $header ) ? $header : 5;
463
		$var_name = ucwords( str_replace( array( '$', '_' ), array( '', ' ' ), $var_name ) );
464
		$result = '<' . $heading_tag . ' style="color:#2EA2CC; margin:25px 0 0;"><b>' . $var_name . '</b>';
465
		$result .= '<span style="color:#999;"> : </span><span style="color:#E76700;">';
466
		$result .= '<pre style="color:#999; padding:1em; background: #fff">';
467
		$result .= var_export( $var, true );
468
		$result .= '</pre></span><br /><span style="font-size:9px;font-weight:normal;color:#666;line-height: 12px;">' . $file;
469
		$result .= '<br />line no: ' . $line . '</span></' . $heading_tag . '>';
470
		if ( $die ) {
471
			die( $result );
472
		} else {
473
			echo $result;
474
		}
475
	}
476
477
478
479
480
}
481
482
483
484
/**
485
 * borrowed from Kint Debugger
486
 * Plugin URI: http://upthemes.com/plugins/kint-debugger/
487
 */
488
if ( class_exists('Kint') && ! function_exists( 'dump_wp_query' ) ) {
489
	function dump_wp_query(){
490
		global $wp_query;
491
		d($wp_query);
492
	}
493
}
494
495
/**
496
 * borrowed from Kint Debugger
497
 * Plugin URI: http://upthemes.com/plugins/kint-debugger/
498
 */
499
if ( class_exists('Kint') && ! function_exists( 'dump_wp' ) ) {
500
	function dump_wp(){
501
		global $wp;
502
		d($wp);
503
	}
504
}
505
506
/**
507
 * borrowed from Kint Debugger
508
 * Plugin URI: http://upthemes.com/plugins/kint-debugger/
509
 */
510
if ( class_exists('Kint') && ! function_exists( 'dump_post' ) ) {
511
	function dump_post(){
512
		global $post;
513
		d($post);
514
	}
515
}
516
517