base_dir = THINKRANK_PLUGIN_DIR . 'includes/'; } /** * Register autoloader * * @return void */ public static function register(): void { $autoloader = new self(); spl_autoload_register([$autoloader, 'load_class']); } /** * Load class file * * @param string $class_name Fully qualified class name * @return bool True if file was loaded, false otherwise */ public function load_class(string $class_name): bool { // Check if class uses our namespace if (strpos($class_name, self::NAMESPACE_PREFIX) !== 0) { return false; } // Check class map first for performance if (isset(self::$class_map[$class_name])) { $file = self::$class_map[$class_name]; if (file_exists($file)) { require_once $file; return true; } } // Get relative class name $relative_class = substr($class_name, strlen(self::NAMESPACE_PREFIX)); // Convert namespace to file path $file_path = $this->get_file_path($relative_class); // Load file if it exists if (file_exists($file_path)) { require_once $file_path; // Cache successful loads self::$class_map[$class_name] = $file_path; return true; } return false; } /** * Convert class name to file path * * @param string $relative_class Relative class name * @return string File path */ private function get_file_path(string $relative_class): string { // Replace namespace separators with directory separators $file_path = str_replace('\\', DIRECTORY_SEPARATOR, $relative_class); // Convert to lowercase and add class- prefix for WordPress convention $parts = explode(DIRECTORY_SEPARATOR, $file_path); $class_name = array_pop($parts); // Handle special cases for known acronyms/brands $special_cases = [ 'OpenAI_Client' => 'openai-client', 'Claude_Client' => 'claude-client', 'Gemini_Client' => 'gemini-client', 'Analytics_Endpoint' => 'analytics-endpoint', 'SEO_Manager' => 'seo-manager', 'SEO_Plugin_Detector' => 'seo-plugin-detector', 'SEO_Notice' => 'seo-notice', 'LLMs_Txt_Endpoint' => 'llms-txt-endpoint', 'LLMs_Txt_Manager' => 'llms-txt-manager', 'Prompt_Builder' => 'prompt-builder', 'SEO_Prompts' => 'prompts/seo-prompts', 'Site_Identity_Prompts' => 'prompts/site-identity-prompts', 'Homepage_Prompts' => 'prompts/homepage-prompts', 'LLMs_Txt_Prompts' => 'prompts/llms-txt-prompts', 'Content_Brief_Prompts' => 'prompts/content-brief-prompts', ]; if (isset($special_cases[$class_name])) { $class_file = 'class-' . $special_cases[$class_name] . '.php'; } else { // Convert CamelCase to kebab-case for proper WordPress naming // Handle consecutive uppercase letters (like SEO) properly $class_name = preg_replace('/([A-Z]+)([A-Z][a-z])/', '$1-$2', $class_name); $class_name = preg_replace('/([a-z])([A-Z])/', '$1-$2', $class_name); $class_file = 'class-' . strtolower(str_replace('_', '-', $class_name)) . '.php'; } // Build full path $directory = !empty($parts) ? strtolower(implode(DIRECTORY_SEPARATOR, $parts)) . DIRECTORY_SEPARATOR : ''; return $this->base_dir . $directory . $class_file; } /** * Preload critical classes for performance * * @return void */ public static function preload_critical_classes(): void { $critical_classes = [ 'ThinkRank\\Core\\Database', 'ThinkRank\\Core\\Settings', 'ThinkRank\\Core\\Cache', 'ThinkRank\\API\\Manager', 'ThinkRank\\Admin\\Manager', ]; foreach ($critical_classes as $class) { if (!class_exists($class)) { $autoloader = new self(); $autoloader->load_class($class); } } } /** * Get loaded classes count for debugging * * @return int */ public static function get_loaded_classes_count(): int { return count(self::$class_map); } /** * Get class map for debugging * * @return array */ public static function get_class_map(): array { return self::$class_map; } }