PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / trunk
Yoast SEO – Advanced SEO with real-time guidance and built-in AI vtrunk
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / src / ai / authentication / application / ai-request-sender-factory.php

ai-request-sender-factory.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI trunk, at src/ai/authentication/application/ai-request-sender-factory.php

135 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
4
5 namespace Yoast\WP\SEO\AI\Authentication\Application;
6
7 use WP_User;
8 use Yoast\WP\SEO\AI\Authentication\Domain\Auth_Method;
9 use Yoast\WP\SEO\Conditionals\MyYoast_Connection_Conditional;
10 use YoastSEO_Vendor\Psr\Log\LoggerAwareInterface;
11 use YoastSEO_Vendor\Psr\Log\LoggerAwareTrait;
12 use YoastSEO_Vendor\Psr\Log\NullLogger;
13
14 /**
15 * Builds an AI_Request_Sender configured with the right auth strategy (primary + optional fallback)
16 * for each outbound AI request.
17 *
18 * Selection order (first match wins): wpseo_ai_auth_method filter override → MyYoast connection
19 * feature flag. The auth model is site-wide: once any admin has completed the auth-code flow,
20 * every WP user on the site uses the OAuth path.
21 *
22 * @makePublic
23 */
24 class AI_Request_Sender_Factory implements LoggerAwareInterface {
25
26 use LoggerAwareTrait;
27
28 /**
29 * The MyYoast connection feature flag conditional.
30 *
31 * @var MyYoast_Connection_Conditional
32 */
33 private $myyoast_connection_conditional;
34
35 /**
36 * The OAuth strategy.
37 *
38 * @var OAuth_Auth_Strategy
39 */
40 private $oauth_strategy;
41
42 /**
43 * The Token strategy.
44 *
45 * @var Token_Auth_Strategy
46 */
47 private $token_strategy;
48
49 /**
50 * Constructor.
51 *
52 * @param MyYoast_Connection_Conditional $myyoast_connection_conditional The MyYoast connection feature flag.
53 * @param OAuth_Auth_Strategy $oauth_strategy The OAuth strategy.
54 * @param Token_Auth_Strategy $token_strategy The Token strategy.
55 */
56 public function __construct(
57 MyYoast_Connection_Conditional $myyoast_connection_conditional,
58 OAuth_Auth_Strategy $oauth_strategy,
59 Token_Auth_Strategy $token_strategy
60 ) {
61 $this->myyoast_connection_conditional = $myyoast_connection_conditional;
62 $this->oauth_strategy = $oauth_strategy;
63 $this->token_strategy = $token_strategy;
64 $this->logger = new NullLogger();
65 }
66
67 /**
68 * Returns the sender configured to authenticate AI requests for the given user.
69 *
70 * @param WP_User $user The WP user.
71 *
72 * @return AI_Request_Sender The configured sender.
73 */
74 public function create( WP_User $user ): AI_Request_Sender {
75 $forced = $this->get_filter_override( $user );
76 switch ( $forced ) {
77 case Auth_Method::OAUTH:
78 $this->logger->debug( 'AI auth: wpseo_ai_auth_method filter pinned oauth.' );
79 $sender = new AI_Request_Sender( $this->oauth_strategy );
80 break;
81 case Auth_Method::TOKEN:
82 $this->logger->debug( 'AI auth: wpseo_ai_auth_method filter pinned token.' );
83 $sender = new AI_Request_Sender( $this->token_strategy );
84 break;
85 default:
86 if ( $this->myyoast_connection_conditional->is_met() ) {
87 $this->logger->debug( 'AI auth: routing to oauth strategy (feature flag on) with a fallback to legacy token auth.' );
88 $sender = new AI_Request_Sender( $this->oauth_strategy, $this->token_strategy );
89 }
90 else {
91 $this->logger->debug( 'AI auth: routing to token strategy (MYYOAST_CONNECTION feature flag is off).' );
92 $sender = new AI_Request_Sender( $this->token_strategy );
93 }
94 break;
95 }
96
97 // Logger_Aware_Pass only auto-wires container-registered services; the sender is hand-built
98 // here so its logger must be propagated explicitly, otherwise its fallback warning is dropped.
99 $sender->setLogger( $this->logger );
100
101 return $sender;
102 }
103
104 /**
105 * Returns the strategy forced by the wpseo_ai_auth_method filter, or null when not pinned.
106 *
107 * @param WP_User $user The WP user.
108 *
109 * @return string|null One of the Auth_Method constants, or null.
110 */
111 private function get_filter_override( WP_User $user ): ?string {
112 /**
113 * Filter: 'wpseo_ai_auth_method' - Pin a specific AI auth strategy for QA / staged rollout.
114 *
115 * Return 'oauth' to force MyYoast OAuth.
116 * Return 'token' to force the legacy access_jwt flow.
117 * Return any other value (including the default null) to let the factory's normal selection logic run:
118 * If OAuth is available, it will be the primary strategy with a fallback to the legacy token flow.
119 * If OAuth is unavailable, the legacy token flow will be used exclusively.
120 *
121 * @internal
122 *
123 * @param string|null $method The forced strategy, or null for default selection.
124 * @param WP_User $user The WP user the request is on behalf of.
125 */
126 $forced = \apply_filters( 'wpseo_ai_auth_method', null, $user );
127
128 if ( $forced === Auth_Method::OAUTH || $forced === Auth_Method::TOKEN ) {
129 return $forced;
130 }
131
132 return null;
133 }
134 }
135