Current File : /var/www/e360ban/wp-content/plugins/toolset-blocks/embedded/inc/wpv-query-debug.class.php |
<?php
use const OTGS\Toolset\Views\UserCapabilities\EDIT_VIEWS;
global $WPVDebug;
$WPVDebug = new WPV_Debug();
function wpv_debuger()
{
return;
}
/**
* @todo this needs so much comments
*/
class WPV_Debug{
function __construct(){
$this->options = null;
$this->depth = 0;
$this->log_array = array();
$this->status = false;
$this->total_memory = memory_get_usage ( false );
$this->show_type = 'compact';
// FIXME: Use $WPV_settings, if possible.
// WPV_Debug class is initialized before WPV_Settings_Screen, can we change that?
$options = get_option('wpv_options');
if ( !isset($options['wpv_debug_mode']) ) {
$options['wpv_debug_mode'] = '';
}
if ( !isset($options['wpv_debug_mode_type']) ) {
$options['wpv_debug_mode_type'] = 'compact';
}
if ( isset($options['wpv_debug_mode']) && !empty($options['wpv_debug_mode']) ){
$this->status = true;
$this->show_type = $options['wpv_debug_mode_type'];
if ( !defined('SAVEQUERIES') ){
define('SAVEQUERIES', true);
}
}
add_filter('wpv_shortcode_debug', array($this, 'wpv_shortcode_debug_callback'),10,5);
add_action('wp_footer', array($this, 'wpv_show_debug_output'),30,3);
}
function wpv_show_debug_output() {
if ( !$this->user_can_debug() ){return;}
$out = $this->generate_output();
if ( !isset($this->log_array[1]) || count($this->log_array[1]) == 0){
return;
}
ob_start();
?>
<div class="wpv-hidden" style="display:none">
<a class="js-wpv-open-debug-window" href="#">open</a>
<div class="js-debuger-output">
<div class="wpv-debug-table-wrapper">
<?php echo $out;?>
</div> <!-- .wpv-debug-table-wrapper -->
</div> <!-- .js-debuger-output -->
</div>
<?php // TODO: Can we register these files? ?>
<script type="text/javascript" src="<?php echo WPV_URL_EMBEDDED_FRONTEND;?>/res/js/lib/jstorage.min.js"></script>
<script type="text/javascript" src="<?php echo WPV_URL_EMBEDDED_FRONTEND;?>/res/js/lib/prism.js" data-manual></script>
<script type="text/javascript">
jQuery(function($) {
// Define popup size
var popupWidth = $.jStorage.get('debugger_popup_width', 1100); // get width saved in local storage, set 1100 if vaule is not set yet
var popupHeight = $.jStorage.get('debugger_popup_height', 800); // get height saved in local storage, set 800 if vaule is not set yet
// Reduce popup size for small screens
if ( screen.width < 1000 ) { /* less than .wpv-debug-table-wrapper width */
popupWidth = screen.width;
}
if ( screen.height < popupHeight ) {
popupHeight = screen.height;
}
// Get popup position from local storage. Set to center if local storage values are not set
var popupPosLeft = $.jStorage.get('debugger_popup_pos_left', (screen.width/2) - (popupWidth/2) );
var popupPosTop = $.jStorage.get('debugger_popup_pos_top', (screen.height/2) - (popupHeight/2) );
// Get the debug info
var debug_info = $('.js-debuger-output').clone().html();
$('.js-debuger-output').remove();
function nWin() {
// Open popup
var winobj = window.open(
'',
'blank',
'resizable=yes,scrollbars=yes,status=no,location=no,width='+popupWidth+',height='+popupHeight+',left='+popupPosLeft+',top='+popupPosTop
);
if (winobj !== null) {
//var windoc = winobj.document;
var $debugCSS = $('<link rel="stylesheet" href="<?php echo WPV_URL_EMBEDDED_FRONTEND; ?>/res/css/debug.css?<?php echo date( 'l jS \of F Y h:i:s A' ); ?>" type="text/css" media="all" />');
var $prismCSS = $('<link rel="stylesheet" href="<?php echo WPV_URL_EMBEDDED_FRONTEND; ?>/res/css/prism.css?<?php echo date( 'l jS \of F Y h:i:s A' ); ?>" type="text/css" media="all" />');
var cssone = '<link rel="stylesheet" href="<?php echo WPV_URL_EMBEDDED_FRONTEND; ?>/res/css/debug.css?<?php echo date( 'l jS \of F Y h:i:s A' ); ?>" type="text/css" media="all" />';
var csstwo = '<link rel="stylesheet" href="<?php echo WPV_URL_EMBEDDED_FRONTEND; ?>/res/css/prism.css?<?php echo date( 'l jS \of F Y h:i:s A' ); ?>" type="text/css" media="all" />';
// Append debug data into popup
//debug_info.appendTo( winobj.document.body );
//winobj.document.append(debug_info.html());
winobj.document.write(cssone + csstwo + debug_info);
winobj.document.title = "<?php _e( 'Views/Content Templates debug information', 'wpv-views' ); ?>";
winobj.focus();
// Append CSS
//$(windoc).find('head').append( $debugCSS );
//$(windoc).find('head').append( $prismCSS );
// Save popup settings to local storage
var savePopupSettings = function () {
$.jStorage.set('debugger_popup_width', winobj.outerWidth);
$.jStorage.set('debugger_popup_height', winobj.innerHeight); // I have NO IDEA why innerHeight works in a way how outerHeight is suppposed to work...
$.jStorage.set('debugger_popup_pos_left', winobj.screenX);
$.jStorage.set('debugger_popup_pos_top', winobj.screenY);
}
// Close previously opened popups and save popup settings to local storage on parent window unload event
$(window).on('unload', function () {
if ($(winobj).length !== 0) {
savePopupSettings();
winobj.close();
}
});
// Save popup position to local storage on popup unload event
$(winobj).on('unload', function () {
savePopupSettings();
});
$(winobj.document).find('.js-code-wrapper, .wpv-loop-table-wrapper').each(function () {
$(this).addClass("hidden");
});
// Display notice once js-toggle-higlighter is checked
$(winobj.document).find('#js-toggle-higlighter').on('change', function (e) {
var $notice = $(winobj.document).find('.js-higlighter-notice');
var $body = $(winobj.document).find('body');
if ($(this).is(':checked')) {
$notice.removeClass('hidden');
}
else {
$notice.addClass('hidden');
}
});
// Add nobreak class to <body> tag if linebreaks is disabled
$(winobj.document).find('#js-toggle-linebreaks').on('change', function (e) {
var $body = $(winobj.document).find('body');
if ($(this).is(':checked')) {
$body.removeClass('nowrap');
}
else {
$body.addClass('nowrap');
}
});
// Expand/collapse code blocks
$(winobj.document).find('.js-show-code').on('click', function (e) {
e.preventDefault();
var $this = $(this);
var $target = $this.next('.js-code-wrapper');
var codeToHighlight = $target.find('.js-code-highlight')[0];
var expanded = $this.data('expanded');
var isHighlighterEnabled = $(winobj.document).find('#js-toggle-higlighter').is(':checked');
if (expanded) {
$target.addClass("hidden");
$this
.text($this.data('text-collapsed'))
.data('expanded', false);
}
else {
if (isHighlighterEnabled && ( typeof( $target.data('highlighted') ) === 'undefined' )) {
$this
.text($this.data('text-disabled'))
.prop('disabled', true);
Prism.highlightElement(codeToHighlight, true, function () {
$target
.data('highlighted', true)
.removeClass("hidden");
$this
.prop('disabled', false)
.text($this.data('text-expanded'))
.data('expanded', true);
});
}
else {
$target.removeClass("hidden");
$this
.text($this.data('text-expanded'))
.data('expanded', true)
}
}
return false;
});
// Expand/collapse top level section
$(winobj.document).find('.js-show-view').on('click', function (e) {
e.preventDefault();
$elem = $(this).data('target');
var $target = $(winobj.document).find($elem);
var expanded = $(this).data('expanded');
if (expanded) {
$target.addClass("hidden");
$(this).find('.js-wpv-debug-corner').eq(0).text('+');
$(this).data('expanded', false);
}
else {
$target.removeClass("hidden");
$(this).find('.js-wpv-debug-corner').eq(0).text('-');
$(this).data('expanded', true);
}
return false;
});
}
}
$(document).on("click", ".js-wpv-open-debug-window", function(e){
e.preventDefault();
nWin();
return false;
});
$(".js-wpv-open-debug-window").click();
});
</script>
<?php
$output = ob_get_clean();
echo $output;
}
function __destruct(){
}
function user_can_debug(){
global $WP_Views;
if ( $WP_Views->is_embedded() ) {
return false;
}
if ( !$this->status){
return false;
}
if ( !is_user_logged_in() ){
return false;
}
if ( !current_user_can( EDIT_VIEWS ) ) {
return false;
}
return true;
}
function wpv_debug_start( $view_id, $atts="", $type = 'view' ){
if ( !$this->user_can_debug() ){return;}
$this->depth++;
static $correspondences = array();
$this->log_array[$this->depth][] = array( 'view_id'=>$view_id, 'view_parent' => $this->get_parent_view(),'type'=>$type );
/* if ( isset($atts[0]['name']) ){
$this->log_array[$this->depth][$this->get_index()]['view_name'] = $atts[0]['name'] . json_encode($atts[0]) . $view_id;
}else{*/
if ( is_numeric( $view_id ) ) {
$view = get_post($view_id);
$this->log_array[$this->depth][$this->get_index()]['view_name'] = $view->post_title;
}
else{
if ( $type == 'content-template' && ( $view_id == 'None' || $view_id == 'none' ) ) {
$title = __('Current post body', 'wpv-views');
} else {
global $wpdb;
$title = '';
if ( !isset( $correspondences[$view_id] ) ) {
$title = $wpdb->get_var("SELECT post_title FROM $wpdb->posts WHERE post_name = '$view_id'");
if ( empty( $title ) && !empty( $view_id ) ) {
$title = $view_id;
}
$correspondences[$view_id] = $title;
} else {
$title = $correspondences[$view_id];
}
/*
$title = $wpdb->get_var("SELECT post_title FROM $wpdb->posts WHERE post_name = '$view_id'");
if ( empty( $title ) && !empty( $view_id ) ) {
$title = $view_id;
}
*/
}
$this->log_array[$this->depth][$this->get_index()]['view_name'] = $title;
}
// }
if ( $type == 'view' ){
$view_settings = get_post_meta($view_id, '_wpv_settings', true);
if ( isset( $view_settings['view-query-mode'] ) && in_array( $view_settings['view-query-mode'], array( 'archive', 'layouts-loop' ) ) ){
$this->log_array[$this->depth][$this->get_index()]['type'] = 'archive';
}
}
$this->log_array[$this->depth][$this->get_index()]['mysql_query'] = '';
$this->log_array[$this->depth][$this->get_index()]['render_time'] = timer_stop( 0, 5 );
$this->log_array[$this->depth][$this->get_index()]['memory_usage'] = memory_get_usage ( false );
$this->log_array[$this->depth][$this->get_index()]['current_index'] = 0;
$this->log_array[$this->depth][$this->get_index()]['parent_index'] = 0;
$this->log_array[$this->depth][$this->get_index()]['items_found'] = null;
if ( $this->depth > 1 ){
$temp_array = array_keys($this->log_array[($this->depth-1)]);
$this->log_array[$this->depth][$this->get_index()]['parent_index'] = $this->log_array[$this->depth-1][end($temp_array)]['current_index'];
}
//print '<br><br><br><br>'.$this->log_array[$this->depth][$this->get_index()]['view_name'].'<br><br><br><br>';
}
function update_template_id( $id ){
if ( !$this->user_can_debug() ){return;}
$this->log_array[$this->depth][$this->get_index()]['view_id'] = $id;
}
function get_index( $depth = 0 ) {
if ( !$this->user_can_debug() ){
return;
}
if ( is_array($this->log_array) && isset( $this->log_array[$this->depth] ) && is_array( $this->log_array[$this->depth] ) ) {
$tem_array = array_keys($this->log_array[$this->depth]);
return end($tem_array);
}
else{
return 0;
}
}
function get_parent_view(){
if ( !$this->user_can_debug() ){return;}
$out = 0;
if ( $this->depth >1 ){
$temp_array = array_keys($this->log_array[($this->depth-1)]);
$out = $this->log_array[($this->depth-1)][end($temp_array)]['view_id'];
}
return $out;
}
function wpv_debug_end(){
if ( !$this->user_can_debug() ){return;}
$timer = floatval( str_replace( ',', '.', timer_stop( 0, 3 ) ) );
$render_time = floatval( str_replace( ',', '.', $this->log_array[ $this->depth ][ $this->get_index() ]['render_time'] ) );
$time = $timer - $render_time;
$memory = memory_get_usage ( false ) - $this->log_array[$this->depth][$this->get_index()]['memory_usage'];
$this->log_array[$this->depth][$this->get_index()]['render_time'] = $time;
$this->log_array[$this->depth][$this->get_index()]['memory_usage'] = round(($memory/8/1024/1024),4).'MB';
$this->depth--;
}
function set_index( $index = '' ){
if ( !$this->status || !$this->user_can_debug() ){return;}
if ( !isset($this->log_array[$this->depth][$this->get_index()]['current_index']) ){ return; }
if ( empty($index) ){
$this->log_array[$this->depth][$this->get_index()]['current_index']++;
}else{
$this->log_array[$this->depth][$this->get_index()]['current_index'] = $index;
}
}
function clean_index( ){
if ( !$this->status || !$this->user_can_debug() ){return;}
if ( !isset($this->log_array[$this->depth][$this->get_index()]['current_index']) ){ return; }
$this->log_array[$this->depth][$this->get_index()]['current_index'] = -1;
}
function unset_index( $index ){
if ( !$this->status || !$this->user_can_debug() ){return;}
$this->log_array[$this->depth][$this->get_index()]['current_index'] = 0;
}
function add_log( $method = 'info', $in, $index = '', $short = '', $multiple = false ){
if ( !$this->status || !$this->user_can_debug() ){return;}
if ( !isset($this->log_array[$this->depth][$this->get_index()]['render_time']) ){return; }
if ( $method == 'filters' ){
$this->log_array[$this->depth][$this->get_index()]['filters'][] = $in;
$this->log_array[$this->depth][$this->get_index()]['filters_short'][] = $short;
}
elseif( $method == 'items_count'){
$this->log_array[$this->depth][$this->get_index()]['items_found'] = $in;
}
elseif( $method == "content-template" ){
$this->log_array[$this->depth][$this->get_index()]['log'][$this->log_array[$this->depth][$this->get_index()]['current_index']] = array(
// 'title' => "Title: ". $in->post_title .", ID: ". $in->ID ."", NOTE no need of title here, we already display it when opening the table
'data_array' => esc_attr( print_r($in,true) )
);
}
elseif( $method == "posts" ){
$this->log_array[$this->depth][$this->get_index()]['log'][$this->log_array[$this->depth][$this->get_index()]['current_index']] = array(
'title' => __('Title', 'wpv-views') . ": ". $in->post_title .", " . __('ID', 'wpv-views') . ": ". $in->ID ."",
'data_array' => esc_attr( print_r($in,true) )
);
}
elseif( $method == "taxonomy" ){
$this->log_array[$this->depth][$this->get_index()]['log'][$this->log_array[$this->depth][$this->get_index()]['current_index']] = array(
'title' => __('Name', 'wpv-views') . ": ". $in->name .", " . __('ID', 'wpv-views') . ": ". $in->term_id ."",
'data_array' => esc_attr( print_r($in,true) )
);
}
elseif( $method == "users" ){
$login = $in->data->user_login;
$id = $in->data->ID;
$this->log_array[$this->depth][$this->get_index()]['log'][$this->log_array[$this->depth][$this->get_index()]['current_index']] =
array(
'title' => __('User', 'wpv-views') . ": $login, " . __('ID', 'wpv-views') . ": $id",
'data_array' => esc_attr( print_r($in,true) )
);
}
elseif( $method == 'info'){
if ( isset( $this->log_array[$this->depth][$this->get_index()][$index] ) && !empty( $this->log_array[$this->depth][$this->get_index()][$index] ) && $multiple ) {
$this->log_array[$this->depth][$this->get_index()][$index] .= "\n" . $in;
} else {
$this->log_array[$this->depth][$this->get_index()][$index] = $in;
}
if ( !empty($short) ){
$this->log_array[$this->depth][$this->get_index()][$index.'_short'] = $short;
}
}
elseif( $method == 'mysql_query'){
global $post_query;
if ( $index == 'users' ){
for ($i=count($in)-1;$i>=0;$i--){
if( preg_match("/WP_User_Query->query$/",$in[$i][2]) ){
$this->log_array[$this->depth][$this->get_index()]['mysql_query'] = $in[($i-1)][0];
$i = 0;
}
}
}elseif( $index == 'taxonomy' ){
for ($i=count($in)-1;$i>=0;$i--){
if( preg_match("/wp_get_object_terms$/",$in[$i][2]) ){
$this->log_array[$this->depth][$this->get_index()]['mysql_query'] = $in[($i)][0].
"\n\n" . __('Object received from cache. MySQL query was cached in', 'wpv-views') . ": ".$in[($i)][2];
$i = 0;
}
}
}
elseif( $index == 'posts' ){
/*$cur_index = count($in);
$this->log_array[$this->depth][$this->get_index()]['mysql_query'] = 'Posts: '. $in[($cur_index-2)][0];
$this->log_array[$this->depth][$this->get_index()]['mysql_query'] .= "\n\nPost meta: ". $in[($cur_index-1)][0];
* */
if ( isset( $this->log_array[$this->depth][$this->get_index()]['mysql_query'] ) && !empty( $this->log_array[$this->depth][$this->get_index()]['mysql_query'] ) && $multiple ) {
$this->log_array[$this->depth][$this->get_index()]['mysql_query'] .= "\n\n" . $in;
} else {
$this->log_array[$this->depth][$this->get_index()]['mysql_query'] = $in;
}
}
}
}
function add_log_item( $index, $in ){
if ( !$this->status || !$this->user_can_debug() ){return;}
if ( !isset($this->log_array[$this->depth][$this->get_index()]['current_index']) ){ return;}
if ( !isset($this->log_array[$this->depth][$this->get_index()]['log'][$this->log_array[$this->depth][$this->get_index()]['current_index']][$index]) ){
$this->log_array[$this->depth][$this->get_index()]['log'][$this->log_array[$this->depth][$this->get_index()]['current_index']][$index] = '';
}
$this->log_array[$this->depth][$this->get_index()]['log'][$this->log_array[$this->depth][$this->get_index()]['current_index']][$index] .= $in;
}
function generate_output( $level = 1, $parent_view = 0, $index = 0){
$out = '';
if ( !isset($this->log_array[$level]) ){ return;}
for ( $i=0; $i<count($this->log_array[$level]);$i++){
$current = $this->log_array[$level][$i];
if ($level > 1 && $current['parent_index'] != $index){
continue;
}
if ( $current['view_parent'] == $parent_view){
$out .= $this->generate_view_table($current, $level);
}
}
return $out;
}
function generate_view_table( $current, $level = 1 ){
$out = '';
if ( $level == 1 && !empty($this->total_memory) ){
global $wp, $wpdb;
$load = '';
if ( function_exists('sys_getloadavg') ){
$load = sys_getloadavg();
if ( is_array($load) ){
$load = $load[0];
}
}
$current_url = (!empty($_SERVER['HTTPS'])) ? "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] : "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$time = timer_stop( 0, 2 );
$memory = memory_get_usage ( false ) - $this->total_memory;
$memory = round(($memory/8/1024/1024),4).'MB';
$out .= '<div class="wpv-settings-wrapper">';
$out .= '<p>';
$out .= '<input type="checkbox" id="js-toggle-linebreaks" checked> <label for="js-toggle-linebreaks">'. __('Enable line breaks', 'wpv-views') .'</label> ';
$out .= '<input type="checkbox" id="js-toggle-higlighter"> <label for="js-toggle-higlighter">'. __('Enable syntax higlighter', 'wpv-views') .'</label> ';
$out .= '<span class="desc js-higlighter-notice">'. __('Notice: Syntax higlighter can cause performance issues for large blocks of code','wpv-views'). '</span>';
$out .= '</p>';
$out .= '</div> <!-- .wpv-settings-wrapper -->';
$out .= '<h2>' . __('Page info', 'wpv-views') . '</h2>';
$out .= '<table class="wpv-debug-table">'.
'<tr><td>' . __('Current page', 'wpv-views') . '</td><td>'. $current_url .'</td></tr>'.
'<tr><td>' . __('Total memory used', 'wpv-views') . '</td><td>'. $memory .'</td></tr>'.
'<tr><td>' . __('Render time', 'wpv-views') . '</td><td>'. $time .'</td></tr>'.
'<tr><td>' . __('Total MySQL queries', 'wpv-views') . '</td><td>'. count($wpdb->queries) .'</td></tr>';
if ( !empty($load) ){
$out .= '<tr><td>' . __('CPU usage', 'wpv-views') . '</td><td>'. $load .'%</td></tr>';
}
$out .= '</table>';
$out .= '<h2>' . __('Elements info', 'wpv-views') . '</h2>';
$this->total_memory = '';
}
$edit_link = admin_url().'admin.php?page=views-editor&view_id='.$current['view_id'];
if ( $current['type'] == 'content-template' ){
$edit_link = esc_attr( add_query_arg(
array( 'page' => WPV_CT_EDITOR_PAGE_NAME, 'ct_id' => $current['view_id'], 'action' => 'edit' ),
admin_url( 'admin.php' )
) );
}elseif( $current['type'] == 'archive' ){
$edit_link = apply_filters(
'wpv_filter_wpa_edit_link',
admin_url().'admin.php?page=view-archives-editor&view_id='.$current['view_id'],
$current['view_id']
);;
}
$kind = __('View', 'wpv-views');
if ( $current['type'] == 'content-template' ) {
$kind = __('Content Template', 'wpv-views');
if ( $current['view_id'] == 0 ) {
$kind = __('Post body', 'wpv-views');
}
} else if ( $current['type'] == 'archive' ) {
$kind = __('WordPress Archive', 'wpv-views');
}
$table_id = str_replace( '.','', uniqid('table-', true )); // generate unique ID attributes. Str replace is to remove dot character which is not valid for ID attributes.
$out .= '<p><button class="js-show-view wpv-debug-toggle" data-expanded="true" data-target="#'. $table_id .'">';
$out .= '<span class="js-wpv-debug-corner">-</span> '.$current['view_name'];
if ( isset($current['short_query']) ){
$out .= ' ('. $current['short_query'] .')';
}
$out .= '</button></p>';
$out .= '<table class="wpv-debug-table" id="' . $table_id . '">';
if ( $current['type'] == 'content-template' && $current['view_id'] == 0 ) {
// $out .= '<tr><td>' . __('Name', 'wpv-views') . '</td><td>'. $current['view_name'] .' (<a href="'.$edit_link.'" target="_blank">' . __('Edit', 'wpv-views') . '</a>)</td></tr>';
} else {
$out .= '<tr><td>' . __('ID', 'wpv-views') . '</td><td>'. $current['view_id'] .'</td></tr>'.
'<tr><td>' . __('Name', 'wpv-views') . '</td><td>'. $current['view_name'] .' (<a href="'.$edit_link.'" target="_blank">' . __('Edit', 'wpv-views') . '</a>)</td></tr>';
}
$out .= '<tr><td>' . __('Kind of element', 'wpv-views') . '</td><td>'. $kind .'</td></tr>'.
'<tr><td>' . __('Render time', 'wpv-views') . '</td><td>'. $current['render_time'] .'</td></tr>'.
'<tr><td>' . __('Memory used', 'wpv-views') . '</td><td>'. $current['memory_usage'] .'</td></tr>';
if ( isset($current['short_query']) && !empty($current['short_query'])){
$out .= '<tr><td>' . __('Summary', 'wpv-views') . '</td><td>'. str_replace( "'", ''', $current['short_query']) .'</td></tr>';
}
if ( isset($current['additional_info']) && !empty($current['additional_info']) && $this->show_type == 'full'){
$out .= '<tr><td>' . __('Additional info', 'wpv-views') . '</td><td>'. esc_html($current['additional_info']) .'</td></tr>';
}
if ( isset($current['query_args']) && !empty($current['query_args']) && $this->show_type == 'full'){
$out .= '<tr><td>' . __('Query args', 'wpv-views') . '</td><td><button class="js-show-code wpv-code-toggle wpv-debug-toggle" data-text-disabled="'.__('Loading','wpv-views').'…" data-text-expanded="'.__('Hide','wpv-views').'" data-text-collapsed="'.__('Show','wpv-views').'">'.__('Show','wpv-views').'</button><pre class="js-code-wrapper"><code class="language-php js-code-highlight">'. esc_html($current['query_args']) .'</code></pre></td></tr>';
}
if ( isset($current['mysql_query']) && !empty($current['mysql_query']) ){
$out .= '<tr><td>' . __('MySQL query', 'wpv-views') . '</td><td><button class="js-show-code wpv-code-toggle wpv-debug-toggle" data-text-disabled="'.__('Loading','wpv-views').'…" data-text-expanded="'.__('Hide','wpv-views').'" data-text-collapsed="'.__('Show','wpv-views').'">'.__('Show','wpv-views').'</button><pre class="js-code-wrapper"><code class="language-sql js-code-highlight">'. esc_html($current['mysql_query']) .'</code></pre></td></tr>';
}
if ( isset( $current['items_found'] ) ) {
$out .= '<tr><td>' . __('Items found', 'wpv-views') . '</td><td>'. $current['items_found'] .'</td></tr>';
}
if ( isset($current['query_results']) && !empty($current['query_results']) && $this->show_type == 'full'){
$out .= '<tr><td>' . __('Query results', 'wpv-views') . '</td><td><button class="js-show-code wpv-code-toggle wpv-debug-toggle" data-text-disabled="'.__('Loading','wpv-views').'…" data-text-expanded="'.__('Hide','wpv-views').'" data-text-collapsed="'.__('Show','wpv-views').'">'.__('Show','wpv-views').'</button><pre class="js-code-wrapper"><code class="language-php js-code-highlight">'. esc_html($current['query_results']) .'</code></pre></td></tr>';
}
if ( isset($current['filters_short']) && is_array($current['filters_short']) && $this->show_type == 'full' ){
$out .= '<tr><td>' . __('Filters', 'wpv-views') . '</td><td>';
$filter_count = 0;
$filter_count = count($current['filters_short']);
for ($h=0;$h<$filter_count;$h++){
$out .= '<div>'.$current['filters_short'][$h].' <button class="js-show-code wpv-code-toggle wpv-debug-toggle" data-text-disabled="'.__('Loading','wpv-views').'…" data-text-expanded="'.__('Hide','wpv-views').'" data-text-collapsed="'.__('Show','wpv-views').'">'.__('Show','wpv-views').'</button><pre class="js-code-wrapper"><code class="language-php js-code-highlight">'. esc_html($current['filters'][$h]) .'</code></pre></div>';
}
$out .= '</td></tr>';
}
//Show Views that added outside loop
if ( isset( $this->log_array[($level+1)] ) && count($this->log_array[($level+1)]) > 0){
$out_loop = $this->log_array[$level+1];
$zout = '';
$loop_count = 0;
$loop_count = count($out_loop);
for ($p=0;$p<$loop_count; $p++){
if ( $out_loop[$p]['view_parent'] == $current['view_id'] && $out_loop[$p]['parent_index'] == -1){
$zout .= $this->generate_view_table($out_loop[$p],$level+1);
}
}
if ( !empty($zout) ){
$out .= '<tr><td>' . __('Views', 'wpv-views') . '</td><td>'.$zout.'</td></tr>';
}
}
//Start Loop
if ( isset($current['log']) && count($current['log']) > 0 ) {
$loop_label = $kind . ' ' . __('Loop', 'wpv-views');
if ( $current['type'] == 'content-template' ) {
$loop_label = __('Template results', 'wpv-views');
if ( $current['view_id'] == 0 ) {
$loop_label = __('Post body data', 'wpv-views');
}
}
$table_id = str_replace( '.','', uniqid('table-', true )); // generate unique ID attributes. Str replace is to remove dot character which is not valid for ID attributes.
$out .= '<tr><td valign=top colspan=2 class="wpv-debug-loop"><p class="wpv-debug-toggle-wrap"><button class="js-show-view wpv-debug-toggle" data-target="#'. $table_id .'" data-expanded="false"><span class="js-wpv-debug-corner">+</span> ' . $loop_label . '</button></p>';
$out .= '<div class="wpv-loop-table-wrapper" id="'. $table_id .'">';
$log_count = 0;
$log_count = count($current['log']);
for ($k=1;$k<=$log_count;$k++){
$data = $current['log'][$k];
$out .= '<table cellpadding="4" class="wpv-debug-table">';
if ( isset($data['title']) ) {
$out .= '<tr><td>' . __('Title', 'wpv-views') . '</td><td>'. str_replace("'",''',$data['title']) .'</td></tr>';
}
if ( $this->show_type == 'full' ){
$out .= '<tr><td>' . __('Received array', 'wpv-views') . '</td><td>';
$out .= '<button class="js-show-code wpv-code-toggle wpv-debug-toggle" data-text-disabled="'.__('Loading','wpv-views').'…" data-text-expanded="'.__('Hide','wpv-views').'" data-text-collapsed="'.__('Show','wpv-views').'">'.__('Show','wpv-views').'</button>';
$out .= '<pre class="js-code-wrapper"><code class="language-php js-code-highlight">';
$out .= isset($data['data_array']) ? $data['data_array'] : '';
$out .= '</code></pre></td></tr>';
}
$out .= '<tr><td>' . __('Original content', 'wpv-views') . '</td><td><code class="language-markup js-code-highlight">'. esc_attr( isset($data['shortcodes'])? $data['shortcodes']:'' ).'</code></td></tr>';
if ( isset($data['shortcode_info']) && count($data['shortcode_info']) > 0){
$out .= '<tr><td>' . __('Shortcodes', 'wpv-views') . '</td><td>';
$shortcode_info_length = count($data['shortcode_info']);
for ( $j=0; $j<$shortcode_info_length; $j++){
$out .= '<div>'. $data['shortcode_info'][$j]['shortcode'] .': '.
'<button class="js-show-code wpv-code-toggle wpv-debug-toggle" data-text-disabled="'.__('Loading','wpv-views').'…" data-text-expanded="'.__('Hide','wpv-views').'" data-text-collapsed="'.__('Show','wpv-views').'">'.__('Show','wpv-views').'</button><pre class="js-code-wrapper"><code class="language-php js-code-highlight">';
$out .= (!empty($data['shortcode_info'][$j]['atts']) && $data['shortcode_info'][$j]['atts'] != '""') ? __('Attributes', 'wpv-views') . ": " . esc_attr( $data['shortcode_info'][$j]['atts'] ) . "\n" : "";
$out .= !empty($data['shortcode_info'][$j]['query']) ? __('Query', 'wpv-views') . ": " . esc_attr( $data['shortcode_info'][$j]['query'] ) . "\n" : "";
$out .= !empty($data['shortcode_info'][$j]['info']) ? __('Info', 'wpv-views') . ": " . esc_attr( $data['shortcode_info'][$j]['info'] ) . "\n" : "";
$out .= !empty($data['shortcode_info'][$j]['additional']) ? __('Output', 'wpv-views') . ": " . esc_attr( $data['shortcode_info'][$j]['additional'] ) : "";
$out .= '</code></pre></div>';
}
$out .= '</td></tr>';
}
if ( count($this->log_array) > $level ){
$nested = '';
$nested = $this->generate_output( ($level+1), $current['view_id'], $k );
if ( isset( $nested ) && !empty( $nested ) ) {
$out .= '<tr><td>' . __('Nested elements', 'wpv-views') . '</td><td>'. $nested .'</td></tr>';
}
}
if ( isset( $data['output'] ) ) {
$out .= '<tr><td>' . __('Output (RAW)', 'wpv-views') . '</td><td><code class="language-markup js-code-highlight">' . esc_attr( $data['output'] ) . '</code></td></tr>';
}
$out .= '</table>';
}
$out .= '</div></td></tr>'; //End loop
}
$out .= '</table>';
return $out;
}
function wpv_shortcode_debug_callback( $shortcode, $atts = "", $query = "", $info = "", $additional = "" ){
if ( !$this->status || !$this->user_can_debug() ){return;}
if ( isset($this->log_array[$this->depth][$this->get_index()]['current_index']) &&
isset($this->log_array[$this->depth][$this->get_index()]['log'][$this->log_array[$this->depth][$this->get_index()]['current_index']]) &&
count($this->log_array[$this->depth][$this->get_index()]['log'][$this->log_array[$this->depth][$this->get_index()]['current_index']]) > 0 ){
$index = count($this->log_array[$this->depth][$this->get_index()]['log'][$this->log_array[$this->depth][$this->get_index()]['current_index']]);
$shortcode = array(
'shortcode' => $shortcode,
'atts' => $atts,
'query' => $query,
'info' => $info,
'additional' => $additional
);
$this->log_array[$this->depth][$this->get_index()]['log'][$this->log_array[$this->depth][$this->get_index()]['current_index']]['shortcode_info'][] = $shortcode;
}
}
function show_log(){
if ( !$this->user_can_debug() ){return;}
}
function js(){
if ( !$this->user_can_debug() ){return;}
}
function get_mysql_last(){
if ( !$this->user_can_debug() ){return;}
global $wpdb;
$out = '';
if ( !empty($wpdb->queries) ){
$out = $wpdb->queries[(count($wpdb->queries)-1)][0];
}
return $out;
}
}