'', 'client_secret' => '', 'api_url' => 'https://api.vimine.network', 'app_url' => 'https://app.vimine.network', 'scopes' => 'profile:read membership:read', 'callback_path' => 'vimine-callback', 'enroll_scheme' => '', 'enroll_accent' => '', 'enroll_background' => '', 'enroll_font' => '', ]; $saved = get_option( self::OPTION, [] ); return array_merge( $defaults, is_array( $saved ) ? $saved : [] ); } public static function configured(): bool { $s = self::get(); return '' !== $s['client_id'] && '' !== $s['client_secret']; } /** The redirect URI registered on the Vimine client (must match exactly). */ public static function redirect_uri(): string { return home_url( '/' . ltrim( self::get()['callback_path'], '/' ) . '/' ); } public static function menu(): void { add_options_page( 'Vimine', 'Vimine', 'manage_options', 'vimine', [ __CLASS__, 'page' ] ); } public static function register(): void { register_setting( 'vimine', self::OPTION, [ 'sanitize_callback' => [ __CLASS__, 'sanitize' ] ] ); } /** @param mixed $input */ public static function sanitize( $input ): array { $input = is_array( $input ) ? $input : []; $current = self::get(); $text = static fn( string $key ): string => isset( $input[ $key ] ) && is_string( $input[ $key ] ) ? $input[ $key ] : ''; $out = []; $out['client_id'] = sanitize_text_field( $text( 'client_id' ) ); $secret = sanitize_text_field( $text( 'client_secret' ) ); $out['client_secret'] = '' === $secret ? $current['client_secret'] : $secret; // an empty field keeps the stored secret $out['api_url'] = self::url( $text( 'api_url' ), $current['api_url'] ); $out['app_url'] = self::url( $text( 'app_url' ), $current['app_url'] ); $out['scopes'] = sanitize_text_field( '' !== $text( 'scopes' ) ? $text( 'scopes' ) : $current['scopes'] ); $out['callback_path'] = sanitize_title( '' !== $text( 'callback_path' ) ? $text( 'callback_path' ) : $current['callback_path'] ) ?: 'vimine-callback'; // The enrolment form's look: empty, or Automatic, is the theme's. $out['enroll_scheme'] = Vimine_Appearance::scheme( $text( 'enroll_scheme' ) ); $out['enroll_accent'] = self::colour( $text( 'enroll_accent' ), false, $current['enroll_accent'] ); $out['enroll_background'] = self::colour( $text( 'enroll_background' ), true, $current['enroll_background'] ); $out['enroll_font'] = Vimine_Appearance::font( $text( 'enroll_font' ) ); return $out; } /** A colour of the enrolment form: empty is the theme's; anything but a colour keeps the stored value, with a notice. */ private static function colour( string $raw, bool $transparent, string $current ): string { if ( '' === trim( $raw ) ) { return ''; } $colour = Vimine_Appearance::colour( $raw, $transparent ); if ( '' === $colour ) { if ( ! in_array( 'vimine_colour', array_column( get_settings_errors( self::OPTION ), 'code' ), true ) ) { // one notice for both fields add_settings_error( self::OPTION, 'vimine_colour', __( 'Vimine: a colour is a hex code, such as #1e3a5f; the background can also be transparent. The previous value was kept.', 'vimine' ) ); } return $current; } return $colour; } /** * The `