crypto = $crypto; $this->provider = preg_replace( '/[^a-z0-9_]/', '', (string) $provider ); } /** * The key store for another provider: each provider keeps its own key. * * @param string $provider Provider ID. * @return self */ public function for_provider( $provider ) { return new self( $this->crypto, $provider ); } /** * The option this provider's key lives in. * * @return string */ public function option() { return 'openai' === $this->provider ? self::OPTION : self::OPTION . '_' . $this->provider; } /** * Whether a key looks usable: no spaces, a sensible length. * * @param string $key Key. * @return bool */ public static function valid( $key ) { return (bool) preg_match( '/^[A-Za-z0-9_\-]{20,300}$/', (string) $key ); } /** * Whether a key is saved. * * @return bool */ public function configured() { return '' !== $this->key(); } /** * Saves a key. * * @param string $key Key. * @return bool False when it doesn't look like a key. */ public function save( $key ) { $key = trim( (string) $key ); if ( ! self::valid( $key ) ) { return false; } update_option( $this->option(), $this->crypto->encrypt( $key ), false ); delete_transient( 'turtlereport_ai_models_' . $this->provider ); return true; } /** * Removes the key. * * @return void */ public function forget() { delete_option( $this->option() ); delete_transient( 'turtlereport_ai_models_' . $this->provider ); } /** * The key, for the server-side request only. * * @return string */ public function key() { $stored = get_option( $this->option(), '' ); return is_string( $stored ) && '' !== $stored ? $this->crypto->decrypt( $stored ) : ''; } /** * "…a1b2" for Settings. * * @return string */ public function hint() { $key = $this->key(); return '' === $key ? '' : '…' . substr( $key, -4 ); } }