diff --git a/includes/class-slider-shortcode.php b/includes/class-slider-shortcode.php index 9bf8bd7..6ae5d84 100644 --- a/includes/class-slider-shortcode.php +++ b/includes/class-slider-shortcode.php @@ -55,6 +55,35 @@ public function register() { public function init($atts) { + // === OPIO DEBUG (TEMP) — track per-request invocations of this shortcode + static $invocation_count = 0; + $invocation_count++; + $debug_call = array( + 't_start_ms' => round(microtime(true) * 1000, 2), + 'invocation' => $invocation_count, + 'pid' => function_exists('getmypid') ? getmypid() : null, + 'ob_level_at_entry' => ob_get_level(), + 'mem_mb' => round(memory_get_usage(true) / 1048576, 2), + 'mem_peak_mb' => round(memory_get_peak_usage(true) / 1048576, 2), + 'atts' => $atts, + // who invoked us — short backtrace identifies Yoast vs theme vs other + 'backtrace' => array_map(function($f){ + return (isset($f['class']) ? $f['class'] . $f['type'] : '') + . (isset($f['function']) ? $f['function'] : '') + . (isset($f['file']) ? ' @ ' . basename($f['file']) . ':' . (isset($f['line']) ? $f['line'] : '') : ''); + }, array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), 0, 12)), + 'helper_fns_already_defined' => array( + 'getStarRating' => function_exists('getStarRating'), + 'getStarRatingWidget' => function_exists('getStarRatingWidget'), + 'randomColor' => function_exists('randomColor'), + 'isMobileDevice' => function_exists('isMobileDevice'), + ), + 'current_filter' => current_filter(), + 'doing_filter_the_content' => doing_filter('the_content'), + 'is_admin' => is_admin(), + ); + // === END OPIO DEBUG + if (get_option('opio_active') === '0') { return ''; } @@ -148,15 +177,48 @@ public function init($atts) { . ''; } + // include (not include_once): shortcode can be invoked multiple times + // per request (e.g. Yoast running the_content for meta generation + + // the actual page render). include_once would no-op on subsequent + // calls, leaving the slider markup empty. Helper functions inside + // each template are guarded with function_exists() so repeat-include + // does not fatal. + // === OPIO DEBUG (TEMP) — capture template execution + $debug_template = array( + 'slider_type' => (string) $slider_type, + 'feed_id_attr' => isset($atts['id']) ? $atts['id'] : null, + 'feed_loaded' => $feed != null, + 'feed_post_status' => $feed ? $feed->post_status : null, + 'feed_object_keys' => $feed_object ? array_keys((array) $feed_object) : null, + 'ob_level_before_include' => ob_get_level(), + 'buffer_len_before_include' => function_exists('ob_get_length') && ob_get_length() !== false ? ob_get_length() : null, + ); + $marker_before_include = "\n\n"; + echo $marker_before_include; + // === END OPIO DEBUG + if($slider_type == 'horizontal') { - include_once 'reviews-slider-horizontal-template.php'; + include 'reviews-slider-horizontal-template.php'; } else if($slider_type == 'horizontal-carousel') { - include_once 'reviews-slider-horizontal-carousel-template.php'; + include 'reviews-slider-horizontal-carousel-template.php'; } else if($slider_type == 'vertical') { - include_once 'reviews-slider-vertical-template.php'; + include 'reviews-slider-vertical-template.php'; } ob_get_contents(); + // === OPIO DEBUG (TEMP) — capture state after template ran + $marker_after_include = "\n\n"; + echo $marker_after_include; + $debug_template['ob_level_after_include'] = ob_get_level(); + $debug_template['buffer_len_after_include'] = function_exists('ob_get_length') && ob_get_length() !== false ? ob_get_length() : null; + $debug_template['helper_fns_defined_after_include'] = array( + 'getStarRating' => function_exists('getStarRating'), + 'getStarRatingWidget' => function_exists('getStarRatingWidget'), + 'randomColor' => function_exists('randomColor'), + 'isMobileDevice' => function_exists('isMobileDevice'), + ); + // === END OPIO DEBUG + // Post-render stats — counters were populated during template execution above. if ($opio_translator) { $stats = $opio_translator->get_stats(); @@ -213,7 +275,20 @@ public function init($atts) { return $counts; }; + // Was the marker actually rendered by the buffer? Detects whether + // template output ended up in our parent buffer or somewhere else. + $debug_template['contains_marker_before'] = strpos($raw_output, 'OPIO_DEBUG_MARKER_BEFORE_INCLUDE') !== false; + $debug_template['contains_marker_after'] = strpos($raw_output, 'OPIO_DEBUG_MARKER_AFTER_INCLUDE') !== false; + $debug_template['chars_between_markers'] = $debug_template['contains_marker_before'] && $debug_template['contains_marker_after'] + ? strpos($raw_output, 'OPIO_DEBUG_MARKER_AFTER_INCLUDE') - strpos($raw_output, 'OPIO_DEBUG_MARKER_BEFORE_INCLUDE') - strlen('') + : null; + $debug_call['t_end_ms'] = round(microtime(true) * 1000, 2); + $debug_call['elapsed_ms'] = round($debug_call['t_end_ms'] - $debug_call['t_start_ms'], 2); + $debug_call['ob_level_at_exit'] = ob_get_level(); + $debug = array( + 'call' => $debug_call, + 'template' => $debug_template, 'raw_length' => strlen($raw_output), 'prepared_length' => strlen($prepared_output), 'kses_length' => strlen($kses_output), @@ -225,22 +300,46 @@ public function init($atts) { 'kses_b64' => base64_encode($kses_output), ); - $debug_script = ''; + // Also emit to PHP error log so the call sequence is visible + // server-side (useful when JS is mid-page and console output gets + // tangled with cache layers). + error_log(sprintf( + '[OPIO debug] invocation=%d current_filter=%s raw_len=%d kses_len=%d marker_before=%s marker_after=%s feed_loaded=%s slider_type=%s elapsed_ms=%s', + $debug_call['invocation'], + $debug_call['current_filter'] ?: '(none)', + strlen($raw_output), + strlen($kses_output), + $debug_template['contains_marker_before'] ? 'yes' : 'NO', + $debug_template['contains_marker_after'] ? 'yes' : 'NO', + $debug_template['feed_loaded'] ? 'yes' : 'no', + $debug_template['slider_type'], + $debug_call['elapsed_ms'] + )); + return $debug_script . $kses_output; // === END OPIO DEBUG === diff --git a/includes/reviews-slider-horizontal-carousel-template.php b/includes/reviews-slider-horizontal-carousel-template.php index 21c0138..1e6d5c1 100644 --- a/includes/reviews-slider-horizontal-carousel-template.php +++ b/includes/reviews-slider-horizontal-carousel-template.php @@ -16,6 +16,7 @@ ?> 0.5) ? '#ffc600' : '#E6E8EB'; $starGrey = '#E6E8EB'; @@ -34,7 +35,9 @@ function getStarRating($average) { } return $stars; } + } + if (!function_exists('getStarRatingWidget')) { function getStarRatingWidget($average) { $starColor = ($average > 0.5) ? '#ffc600' : '#E6E8EB'; $starGrey = '#E6E8EB'; @@ -53,7 +56,9 @@ function getStarRatingWidget($average) { } return $stars; } + } + if (!function_exists('randomColor')) { function randomColor() { $colors = [ '#2c3e50', // Dark Blue @@ -70,12 +75,15 @@ function randomColor() { $randomIndex = mt_rand(0, count($colors) - 1); return $colors[$randomIndex]; } + } // Function to check if the user is on a mobile device + if (!function_exists('isMobileDevice')) { function isMobileDevice() { return (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(android|avantgo|blackberry|bolt|boost|cricket|docomo|fone|hiptop|mini|mobi|palm|phone|pie|tablet|up\.browser|up\.link|webos|wos)/i', $_SERVER['HTTP_USER_AGENT'])); } + } // Check if it's a mobile device $isMobile = isMobileDevice(); diff --git a/includes/reviews-slider-horizontal-template.php b/includes/reviews-slider-horizontal-template.php index 026a40f..1154720 100644 --- a/includes/reviews-slider-horizontal-template.php +++ b/includes/reviews-slider-horizontal-template.php @@ -20,13 +20,16 @@ 0.5) ? '#ffc600' : '#E6E8EB'; $starGrey = '#E6E8EB'; @@ -45,7 +48,9 @@ function getStarRating($average) { } return $stars; } + } + if (!function_exists('getStarRatingWidget')) { function getStarRatingWidget($average) { $starColor = ($average > 0.5) ? '#ffc600' : '#E6E8EB'; $starGrey = '#E6E8EB'; @@ -64,7 +69,9 @@ function getStarRatingWidget($average) { } return $stars; } + } + if (!function_exists('randomColor')) { function randomColor() { $colors = [ '#2c3e50', // Dark Blue @@ -81,6 +88,7 @@ function randomColor() { $randomIndex = mt_rand(0, count($colors) - 1); return $colors[$randomIndex]; } + } // Define the function to include the template with parameters // Make API call to get reviews diff --git a/includes/reviews-slider-vertical-template.php b/includes/reviews-slider-vertical-template.php index ae71d1b..f708e9a 100644 --- a/includes/reviews-slider-vertical-template.php +++ b/includes/reviews-slider-vertical-template.php @@ -17,6 +17,7 @@ ?> 0.5) ? '#ffc600' : '#E6E8EB'; $starGrey = '#E6E8EB'; @@ -35,7 +36,9 @@ function getStarRating($average) { } return $stars; } + } + if (!function_exists('getStarRatingWidget')) { function getStarRatingWidget($average) { $starColor = ($average > 0.5) ? '#ffc600' : '#E6E8EB'; $starGrey = '#E6E8EB'; @@ -54,7 +57,9 @@ function getStarRatingWidget($average) { } return $stars; } + } + if (!function_exists('randomColor')) { function randomColor() { $colors = [ '#2c3e50', // Dark Blue @@ -71,6 +76,7 @@ function randomColor() { $randomIndex = mt_rand(0, count($colors) - 1); return $colors[$randomIndex]; } + } // Define the function to include the template with parameters // Make API call to get reviews diff --git a/opio.php b/opio.php index c46bd7a..ac8f057 100644 --- a/opio.php +++ b/opio.php @@ -3,7 +3,7 @@ Plugin Name: Widget for OPIO Reviews Plugin URI: Description: Instantly add OPIO Reviews on your website to increase user confidence and SEO. -Version: 1.1.28 +Version: 1.1.29 Author: Dhiraj Timalsina Text Domain: widget-for-opio-reviews Domain Path: /languages @@ -22,7 +22,7 @@ require(ABSPATH . 'wp-includes/version.php'); -define('OPIO_PLUGIN_VERSION' , '1.1.28'); +define('OPIO_PLUGIN_VERSION' , '1.1.29'); define('OPIO_PLUGIN_FILE' , __FILE__); define('OPIO_PLUGIN_URL' , plugins_url(basename(plugin_dir_path(__FILE__ )), basename(__FILE__))); define('OPIO_ASSETS_URL' , OPIO_PLUGIN_URL . '/assets/'); diff --git a/readme.txt b/readme.txt index b456c6f..66a652d 100644 --- a/readme.txt +++ b/readme.txt @@ -2,7 +2,7 @@ Author: Dhiraj Timalsina Tags: Widget for OPIO Reviews, opio, reviews, rating, widget, google business, testimonials Tested up to: 6.4 -Stable tag: 1.1.28 +Stable tag: 1.1.29 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html