false, 'log' => false ) ) { if ( ! class_exists( 'SucomUtil' ) ) { // Just in case. require_once trailingslashit( dirname( __FILE__ ) ) . 'util.php'; } if ( ! class_exists( 'SucomUtilWP' ) ) { // Just in case. require_once trailingslashit( dirname( __FILE__ ) ) . 'util-wp.php'; } $this->p =& $plugin; $this->const_stats = $this->last_stats = array( 'mtime' => microtime( $get_float = true ), 'mem' => memory_get_usage() ); $this->display_name = isset( $this->p->id ) ? $this->p->id : 'sucom'; $this->log_prefix = strtoupper( $this->display_name ); $this->outputs = $outputs; $this->is_enabled(); // Sets $this->enabled value. if ( ! empty( $this->outputs[ 'log' ] ) ) { if ( ! isset( $_SESSION ) ) { session_start(); } } if ( $this->enabled ) { $this->mark(); } add_action( 'shutdown', array( $this, 'shutdown_stats' ), -1000, 0 ); } public function shutdown_stats() { if ( $this->enabled ) { $cur_stats = array( 'mtime' => microtime( $get_float = true ), 'mem' => memory_get_usage() ); $mtime_diff = $cur_stats[ 'mtime' ] - $this->const_stats[ 'mtime' ]; $mem_diff = $cur_stats[ 'mem' ] - $this->const_stats[ 'mem' ]; $this->log( 'time diff = ' . $this->get_time_text( $mtime_diff ) ); $this->log( 'mem diff = ' . $this->get_bytes_text( $mem_diff ) ); $this->log( 'mem peak = ' . $this->get_bytes_text( memory_get_peak_usage() ) ); } } public function is_enabled( $name = '' ) { if ( ! empty( $name ) ) { return isset( $this->outputs[ $name ] ) ? $this->outputs[ $name ] : false; } return $this->enabled = in_array( true, $this->outputs ) ? true : false; // True if any sybsys is true. } public function enable( $name, $state = true ) { $prev_state = $this->is_enabled( $name ); if ( ! empty( $name ) ) { $this->outputs[ $name ] = $state; if ( 'log' === $name ) { if ( ! isset( $_SESSION ) ) { session_start(); } } } $this->is_enabled(); // Sets $this->enabled value. return $prev_state; // Return the previous state to save and restore. } public function disable( $name, $state = false ) { return $this->enable( $name, $state ); // Return the previous state to save and restore. } public function log_args( array $arr, $class_seq = 1, $func_seq = false ) { if ( ! $this->enabled ) { return; } if ( is_int( $class_seq ) ) { if ( false === $func_seq ) { $func_seq = $class_seq; } $class_seq++; } if ( is_int( $func_seq ) ) { $func_seq++; } elseif ( false === $func_seq ) { $func_seq = 2; } $this->log( 'args ' . SucomUtil::get_array_pretty( $arr, $flatten = true ), $class_seq, $func_seq ); } public function log_arr( $prefix, $mixed, $class_seq = 1, $func_seq = false ) { if ( ! $this->enabled ) { return; } if ( is_int( $class_seq ) ) { if ( false === $func_seq ) { $func_seq = $class_seq; } $class_seq++; } if ( is_int( $func_seq ) ) { $func_seq++; } elseif ( false === $func_seq ) { $func_seq = 2; } if ( is_object( $mixed ) ) { $prefix = trim( $prefix . ' ' . get_class( $mixed ) . ' object vars' ); $mixed = get_object_vars( $mixed ); } if ( is_array( $mixed ) ) { $this->log( $prefix . ' = ' . trim( print_r( SucomUtil::get_array_pretty( $mixed, false ), true ) ), $class_seq, $func_seq ); } else $this->log( $prefix . ' = ' . $mixed, $class_seq, $func_seq ); } public function log_size( $prefix, $mixed, $class_seq = 1, $func_seq = false ) { if ( ! $this->enabled ) { return; } if ( is_int( $class_seq ) ) { if ( false === $func_seq ) { $func_seq = $class_seq; } $class_seq++; } if ( is_int( $func_seq ) ) { $func_seq++; } elseif ( false === $func_seq ) { $func_seq = 2; } $this->log( 'serialized size of ' . $prefix . ' is ' . $this->get_bytes_text( mb_strlen( serialize( $mixed ), '8bit' ) ), $class_seq, $func_seq ); } public function log( $input = '', $class_seq = 1, $func_seq = false ) { if ( ! $this->enabled ) { return; } $log_msg = ''; $stack = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); if ( is_int( $class_seq ) ) { if ( false === $func_seq ) { $func_seq = $class_seq; } $class_name = empty( $stack[ $class_seq ][ 'class' ] ) ? '' : $stack[ $class_seq ][ 'class' ]; $log_msg .= sprintf( $this->log_fmt_cols[ 0 ], $class_name ) . ' '; } else { if ( false === $func_seq ) { $func_seq = 1; } $log_msg .= sprintf( $this->log_fmt_cols[ 0 ], $class_seq ) . ' '; } if ( is_int( $func_seq ) ) { $func_name = empty( $stack[ $func_seq ][ 'function' ] ) ? '' : $stack[ $func_seq ][ 'function' ]; $log_msg .= sprintf( $this->log_fmt_cols[ 1 ], $func_name ) . ' '; } else $log_msg .= sprintf( $this->log_fmt_cols[ 1 ], $func_seq ) . ' '; if ( is_multisite() ) { global $blog_id; $log_msg .= '[blog ' . $blog_id . '] '; } if ( is_array( $input ) ) { $log_msg .= trim( print_r( $input, true ) ); } elseif ( is_object( $input ) ) { $log_msg .= print_r( 'object ' . get_class( $input ), true ); } else $log_msg .= $input; if ( $this->outputs[ 'html' ] ) { $this->log_buffer[] = $log_msg; } if ( $this->outputs[ 'log' ] ) { $session_id = session_id(); $connection_id = $session_id ? $session_id : $_SERVER[ 'REMOTE_ADDR' ]; $connection_id = SucomUtilWP::doing_ajax() ? 'ajax ' . $connection_id : $connection_id; $connection_id = SucomUtilWP::doing_cron() ? 'cron ' . $connection_id : $connection_id; error_log( $connection_id . ' ' . $this->log_prefix . ' ' . $log_msg ); } } public function mark( $id = false, $comment = '', $class_seq = 2 ) { if ( ! $this->enabled ) { return; } $cur_stats = array( 'mtime' => microtime( $get_float = true ), 'mem' => memory_get_usage() ); $comment = $comment ? ' ' . $comment : ''; $sep_text = ''; if ( false !== $id ) { $sep_text .= "\n\t" . '- - - - - - ' . $id; if ( isset( $this->begin_stats[ $id ] ) ) { $mtime_diff = $cur_stats[ 'mtime' ] - $this->begin_stats[ $id ][ 'mtime' ]; $mem_diff = $cur_stats[ 'mem' ] - $this->begin_stats[ $id ][ 'mem' ]; $stats_text = '+' . $this->get_time_text( $mtime_diff ) . ' / +' . $this->get_bytes_text( $mem_diff ); $sep_text .= ' end diff (' . $stats_text . ')'; unset( $this->begin_stats[ $id ] ); } else { $this->begin_stats[ $id ] = array( 'mtime' => $cur_stats[ 'mtime' ], 'mem' => $cur_stats[ 'mem' ] ); $sep_text .= ' begin'; } } /* * $this->const_stats is defined in the class __construct(). */ $mtime_diff = $cur_stats[ 'mtime' ] - $this->const_stats[ 'mtime' ]; $mem_diff = $cur_stats[ 'mem' ] - $this->const_stats[ 'mem' ]; $stats_text = $this->get_time_text( $mtime_diff ) . ' / ' . $this->get_bytes_text( $mem_diff ); $this->log( 'mark (' . $stats_text . ')' . $comment . $sep_text, $class_seq ); } /* * See WpssoComment->get_mod(). * See WpssoComment->get_options(). * See WpssoPost->get_mod(). * See WpssoPost->get_options(). * See WpssoTerm->get_mod(). * See WpssoTerm->get_options(). * See WpssoUser->get_mod(). * See WpssoUser->get_options(). */ public function mark_caller( $comment = '' ) { $stack = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); $class_seq = 2; $class_name = empty( $stack[ $class_seq ][ 'class' ] ) ? '' : $stack[ $class_seq ][ 'class' ]; $this->log( trim( 'called by ' . $class_name . ' ' . $comment ), $class_seq ); } public function mark_diff( $comment = '', $class_seq = 2 ) { if ( ! $this->enabled ) { return; } $comment = $comment ? ' ' . $comment : ''; $cur_stats = array( 'mtime' => microtime( $get_float = true ), 'mem' => memory_get_usage() ); $mtime_diff = $cur_stats[ 'mtime' ] - $this->last_stats[ 'mtime' ]; $mem_diff = $cur_stats[ 'mem' ] - $this->last_stats[ 'mem' ]; $stats_text = '+' . $this->get_time_text( $mtime_diff ) . ' / +' . $this->get_bytes_text( $mem_diff ); $this->last_stats = $cur_stats; $this->log( 'mark diff (' . $stats_text . ')' . $comment, $class_seq ); } private function get_time_text( $time ) { return sprintf( '%f secs', $time ); } private function get_bytes_text( $mem ) { return SucomUtil::format_human_bytes( $mem, $dec = 2 ); } /* * See Wpsso->debug_hooks(). */ public function show_html( $data = null, $title = null ) { if ( ! $this->is_enabled( 'html' ) ) return; echo $this->get_html( $data, $title, 2 ); } public function get_html( $data = null, $title = null, $class_seq = 1, $func_seq = false ) { if ( ! $this->is_enabled( 'html' ) ) return; if ( false === $func_seq ) { $func_seq = $class_seq; } $html = '/Ums', '', $val ); } elseif ( is_array( $val ) ) { // Just in case. $val = print_r( $val, true ); } /* * Firefox does not allow double-dashes inside comment blocks. */ $val = str_replace( array( '--', ), array( '‐‐', ), $val ); $html .= $is_assoc ? "\t$key = $val\n" : "\t$val\n"; unset( $data[ $key ] ); // Optimize memory usage. } } else $html .= $data; } $html .= ' -->' . "\n"; return $html; } } }