PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.8.0
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.8.0
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / includes / AI / ProviderFactory.php

ProviderFactory.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.8.0, at includes/AI/ProviderFactory.php

166 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPDeveloper\BetterDocs\AI;
4
5 use WPDeveloper\BetterDocs\Core\Settings;
6 use WPDeveloper\BetterDocs\AI\Providers\OpenAIProvider;
7 use WPDeveloper\BetterDocs\AI\Providers\GeminiProvider;
8 use WPDeveloper\BetterDocs\AI\Providers\ClaudeProvider;
9 use WPDeveloper\BetterDocs\AI\Providers\DeepSeekProvider;
10 use WPDeveloper\BetterDocs\AI\Providers\OpenRouterProvider;
11
12 /**
13 * Resolves the active AI provider from settings and constructs it with the
14 * right per-platform API key and the global model. This is the single entry
15 * point the content-suite features use; they never name a concrete provider.
16 *
17 * @since 4.4.0
18 */
19 class ProviderFactory {
20
21 /**
22 * Per-platform API key settings are stored as ai_api_key_<platform>.
23 */
24 const KEY_PREFIX = 'ai_api_key_';
25
26 /**
27 * @var Settings
28 */
29 private $settings;
30
31 public function __construct( Settings $settings ) {
32 $this->settings = $settings;
33 }
34
35 /**
36 * Platform id => provider class. Filterable so Pro / add-ons can register
37 * or replace providers without editing core.
38 *
39 * @return array<string,string>
40 */
41 public function provider_map() {
42 return apply_filters( 'betterdocs_ai_providers', array(
43 'openai' => OpenAIProvider::class,
44 'gemini' => GeminiProvider::class,
45 'claude' => ClaudeProvider::class,
46 'deepseek' => DeepSeekProvider::class,
47 'openrouter' => OpenRouterProvider::class,
48 ) );
49 }
50
51 /**
52 * Whether a platform id has a registered provider.
53 *
54 * @param string $platform
55 * @return bool
56 */
57 public function is_supported( $platform ) {
58 $map = $this->provider_map();
59 return isset( $map[ $platform ] );
60 }
61
62 /**
63 * Currently selected platform, defaulting to OpenAI.
64 *
65 * @return string
66 */
67 public function active_platform() {
68 $platform = (string) $this->settings->get( 'ai_platform', 'openai' );
69 return $this->is_supported( $platform ) ? $platform : 'openai';
70 }
71
72 /**
73 * Stored API key for a platform. OpenAI falls back to the pre-multi-platform
74 * `ai_autowrite_api_key` so existing installs keep working before migration.
75 *
76 * @param string $platform
77 * @return string
78 */
79 public function api_key_for( $platform ) {
80 $key = (string) $this->settings->get( self::KEY_PREFIX . $platform, '' );
81 if ( '' === $key && 'openai' === $platform ) {
82 $key = (string) $this->settings->get( 'ai_autowrite_api_key', '' );
83 }
84 return $key;
85 }
86
87 /**
88 * Resolved global model for the active platform. Falls back through the
89 * legacy per-feature model and then the platform default, so a not-yet
90 * migrated install still resolves a valid model.
91 *
92 * @param string|null $platform
93 * @return string
94 */
95 public function active_model( $platform = null ) {
96 $platform = $platform ? $platform : $this->active_platform();
97 $model = (string) $this->settings->get( 'ai_model', '' );
98
99 if ( '' !== $model && ModelRegistry::has_model( $platform, $model ) ) {
100 return $model;
101 }
102
103 $legacy = (string) $this->settings->get( 'write_with_ai_model', '' );
104 if ( '' !== $legacy && ModelRegistry::has_model( $platform, $legacy ) ) {
105 return $legacy;
106 }
107
108 return ModelRegistry::default_model( $platform );
109 }
110
111 /**
112 * Build the provider for the active platform (or an explicit one).
113 *
114 * @param string|null $platform Optional platform override.
115 * @param string|null $model Optional model override.
116 * @return \WPDeveloper\BetterDocs\AI\Contracts\AIProvider
117 */
118 public function make( $platform = null, $model = null ) {
119 $platform = $platform ? $platform : $this->active_platform();
120 if ( ! $this->is_supported( $platform ) ) {
121 $platform = 'openai';
122 }
123
124 $map = $this->provider_map();
125 $class = $map[ $platform ];
126 $key = $this->api_key_for( $platform );
127
128 if ( null === $model ) {
129 $model = ( $platform === $this->active_platform() )
130 ? $this->active_model( $platform )
131 : ModelRegistry::default_model( $platform );
132 }
133
134 return new $class( $key, $model );
135 }
136
137 /**
138 * Build a provider with an explicit key/model — used by key validation
139 * before anything is persisted.
140 *
141 * @param string $platform
142 * @param string $api_key
143 * @param string $model
144 * @return \WPDeveloper\BetterDocs\AI\Contracts\AIProvider
145 */
146 public function make_with( $platform, $api_key, $model = '' ) {
147 if ( ! $this->is_supported( $platform ) ) {
148 $platform = 'openai';
149 }
150 $map = $this->provider_map();
151 $class = $map[ $platform ];
152 return new $class( $api_key, $model );
153 }
154
155 /**
156 * Validate a key for a platform.
157 *
158 * @param string $platform
159 * @param string $api_key
160 * @return array array( 'valid' => bool, 'message' => string )
161 */
162 public function validate( $platform, $api_key ) {
163 return $this->make_with( $platform, $api_key )->validate_key( $api_key );
164 }
165 }
166