| @@ -118,13 +118,17 @@ | ||
| 118 | 118 | // Convert to lowercase and add class- prefix for WordPress convention |
| 119 | 119 | $parts = explode(DIRECTORY_SEPARATOR, $file_path); |
| 120 | 120 | $class_name = array_pop($parts); |
| 121 | 121 | |
| 122 | - // Handle special cases for known acronyms/brands | |
| 122 | + // Handle special cases where the generic CamelCase→kebab conversion | |
| 123 | + // splits a brand/compound word (e.g. PageSpeed → page-speed) or an | |
| 124 | + // acronym differently than the actual file name on disk. | |
| 123 | 125 | $special_cases = [ |
| 124 | 126 | 'OpenAI_Client' => 'openai-client', |
| 125 | 127 | 'Claude_Client' => 'claude-client', |
| 126 | 128 | 'Gemini_Client' => 'gemini-client', |
| 129 | + 'OpenRouter_Client' => 'openrouter-client', | |
| 130 | + 'Google_PageSpeed_Client' => 'google-pagespeed-client', | |
| 127 | 131 | 'Analytics_Endpoint' => 'analytics-endpoint', |
| 128 | 132 | 'SEO_Manager' => 'seo-manager', |
| 129 | 133 | 'SEO_Plugin_Detector' => 'seo-plugin-detector', |
| 130 | 134 | 'SEO_Notice' => 'seo-notice', |
| @@ -130,13 +134,17 @@ | ||
| 130 | 134 | 'SEO_Notice' => 'seo-notice', |
| 131 | 135 | 'LLMs_Txt_Endpoint' => 'llms-txt-endpoint', |
| 132 | 136 | 'LLMs_Txt_Manager' => 'llms-txt-manager', |
| 133 | 137 | 'Prompt_Builder' => 'prompt-builder', |
| 134 | - 'SEO_Prompts' => 'prompts/seo-prompts', | |
| 135 | - 'Site_Identity_Prompts' => 'prompts/site-identity-prompts', | |
| 136 | - 'Homepage_Prompts' => 'prompts/homepage-prompts', | |
| 137 | - 'LLMs_Txt_Prompts' => 'prompts/llms-txt-prompts', | |
| 138 | - 'Content_Brief_Prompts' => 'prompts/content-brief-prompts', | |
| 138 | + 'SEO_Prompts' => 'seo-prompts', | |
| 139 | + 'Site_Identity_Prompts' => 'site-identity-prompts', | |
| 140 | + 'Homepage_Prompts' => 'homepage-prompts', | |
| 141 | + 'LLMs_Txt_Prompts' => 'llms-txt-prompts', | |
| 142 | + 'Content_Brief_Prompts' => 'content-brief-prompts', | |
| 143 | + 'SEOPress_Exporter' => 'seopress-exporter', | |
| 144 | + 'AIOSEO_Exporter' => 'aioseo-exporter', | |
| 145 | + 'Mcp_OAuth' => 'mcp-oauth', | |
| 146 | + 'Google_OAuth_Proxy' => 'google-oauth-proxy', | |
| 139 | 147 | ]; |
| 140 | 148 | |
| 141 | 149 | if (isset($special_cases[$class_name])) { |
| 142 | 150 | $class_file = 'class-' . $special_cases[$class_name] . '.php'; |
| @@ -147,12 +155,24 @@ | ||
| 147 | 155 | $class_name = preg_replace('/([a-z])([A-Z])/', '$1-$2', $class_name); |
| 148 | 156 | $class_file = 'class-' . strtolower(str_replace('_', '-', $class_name)) . '.php'; |
| 149 | 157 | } |
| 150 | 158 | |
| 151 | - // Build full path | |
| 152 | - $directory = !empty($parts) ? strtolower(implode(DIRECTORY_SEPARATOR, $parts)) . DIRECTORY_SEPARATOR : ''; | |
| 159 | + // Build full path. Namespace segments with underscores map to | |
| 160 | + // hyphenated directories (Email_Report_Sections → email-report-sections). | |
| 161 | + $directory = !empty($parts) ? strtolower(str_replace('_', '-', implode(DIRECTORY_SEPARATOR, $parts))) . DIRECTORY_SEPARATOR : ''; | |
| 153 | 162 | |
| 154 | - return $this->base_dir . $directory . $class_file; | |
| 163 | + $file = $this->base_dir . $directory . $class_file; | |
| 164 | + | |
| 165 | + // Interfaces may use the WordPress interface- file prefix instead of class- | |
| 166 | + // (e.g. Email_Report_Section_Interface → interface-email-report-section.php). | |
| 167 | + if (!file_exists($file) && str_ends_with($class_file, '-interface.php')) { | |
| 168 | + $interface_file = $this->base_dir . $directory . 'interface-' . substr($class_file, strlen('class-'), -strlen('-interface.php')) . '.php'; | |
| 169 | + if (file_exists($interface_file)) { | |
| 170 | + return $interface_file; | |
| 171 | + } | |
| 172 | + } | |
| 173 | + | |
| 174 | + return $file; | |
| 155 | 175 | } |
| 156 | 176 | |
| 157 | 177 | /** |
| 158 | 178 | * Preload critical classes for performance |
| @@ -162,9 +182,8 @@ | ||
| 162 | 182 | public static function preload_critical_classes(): void { |
| 163 | 183 | $critical_classes = [ |
| 164 | 184 | 'ThinkRank\\Core\\Database', |
| 165 | 185 | 'ThinkRank\\Core\\Settings', |
| 166 | - 'ThinkRank\\Core\\Cache', | |
| 167 | 186 | 'ThinkRank\\API\\Manager', |
| 168 | 187 | 'ThinkRank\\Admin\\Manager', |
| 169 | 188 | ]; |
| 170 | 189 | |
| @@ -173,24 +192,6 @@ | ||
| 173 | 192 | $autoloader = new self(); |
| 174 | 193 | $autoloader->load_class($class); |
| 175 | 194 | } |
| 176 | 195 | } |
| 177 | - } | |
| 178 | - | |
| 179 | - /** | |
| 180 | - * Get loaded classes count for debugging | |
| 181 | - * | |
| 182 | - * @return int | |
| 183 | - */ | |
| 184 | - public static function get_loaded_classes_count(): int { | |
| 185 | - return count(self::$class_map); | |
| 186 | - } | |
| 187 | - | |
| 188 | - /** | |
| 189 | - * Get class map for debugging | |
| 190 | - * | |
| 191 | - * @return array | |
| 192 | - */ | |
| 193 | - public static function get_class_map(): array { | |
| 194 | - return self::$class_map; | |
| 195 | 196 | } |
| 196 | 197 | } |