$template, 'name' => basename($template), 'type' => self::get_template_type(), 'timestamp' => microtime(true), 'backtrace' => self::get_caller(), ); self::$templates_loaded[] = $template_info; // Log template load if (class_exists('WP_Debug_Logger')) { WP_Debug_Logger::debug("Template loaded: " . basename($template), array( 'type' => $template_info['type'], 'path' => $template, )); } return $template; } /** * Track template part * * @param string $slug Template slug * @param string $name Template name * @param array $args Template args */ public static function track_template_part($slug, $name = null, $args = array()) { $template_file = $slug; if ($name) { $template_file .= '-' . $name; } $template_file .= '.php'; $template_path = locate_template($template_file); $part_info = array( 'slug' => $slug, 'name' => $name, 'file' => $template_file, 'path' => $template_path, 'found' => !empty($template_path), 'args' => $args, 'timestamp' => microtime(true), ); self::$template_parts[] = $part_info; // Log if not found if (!$part_info['found']) { if (class_exists('WP_Debug_Logger')) { WP_Debug_Logger::warning("Template part not found: {$template_file}"); } } } /** * Track template hierarchy * * @param array $templates Template hierarchy * @return array Template hierarchy */ public static function track_template_hierarchy($templates) { if (class_exists('WP_Debug_Logger')) { WP_Debug_Logger::debug("Template hierarchy", array( 'templates' => $templates, )); } return $templates; } /** * Get template type * * @return string Template type */ private static function get_template_type() { if (is_404()) return '404'; if (is_search()) return 'search'; if (is_front_page()) return 'front-page'; if (is_home()) return 'home'; if (is_post_type_archive()) return 'archive-' . get_post_type(); if (is_tax()) return 'taxonomy'; if (is_attachment()) return 'attachment'; if (is_single()) return 'single-' . get_post_type(); if (is_page()) return 'page'; if (is_category()) return 'category'; if (is_tag()) return 'tag'; if (is_author()) return 'author'; if (is_date()) return 'date'; if (is_archive()) return 'archive'; return 'index'; } /** * Get caller information * * @return string Caller info */ private static function get_caller() { $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5); $callers = array(); foreach ($backtrace as $trace) { if (isset($trace['file']) && isset($trace['line'])) { $callers[] = basename($trace['file']) . ':' . $trace['line']; } } return implode(' -> ', $callers); } /** * Get loaded templates * * @return array Templates */ public static function get_templates() { return self::$templates_loaded; } /** * Get template parts * * @return array Template parts */ public static function get_template_parts() { return self::$template_parts; } /** * Get missing template parts * * @return array Missing template parts */ public static function get_missing_parts() { return array_filter(self::$template_parts, function($part) { return !$part['found']; }); } /** * Record templates on shutdown */ public static function record_templates() { $templates_count = count(self::$templates_loaded); $parts_count = count(self::$template_parts); $missing_count = count(self::get_missing_parts()); // Log summary if (class_exists('WP_Debug_Logger')) { WP_Debug_Logger::info("Templates loaded", array( 'templates' => $templates_count, 'parts' => $parts_count, 'missing' => $missing_count, )); } // Store for frontend panel set_transient('wp_debug_templates_data', array( 'templates' => self::$templates_loaded, 'parts' => self::$template_parts, 'missing' => self::get_missing_parts(), ), 3600); } /** * Get template load order * * @return array Template load order */ public static function get_load_order() { $order = array(); // Combine templates and parts $all = array_merge( array_map(function($t) { return array('type' => 'template', 'data' => $t); }, self::$templates_loaded), array_map(function($p) { return array('type' => 'part', 'data' => $p); }, self::$template_parts) ); // Sort by timestamp usort($all, function($a, $b) { return $a['data']['timestamp'] - $b['data']['timestamp']; }); return $all; } }