time() ) { return $s['access_token']; } if ( empty( $s['refresh_token'] ) ) { self::end(); return null; } $client = new Vimine_Client(); $res = $client->refresh( $s['refresh_token'] ); if ( is_wp_error( $res ) ) { self::end(); return null; } self::update( $res ); return $res['access_token']; } /** * The response carries what belongs to this member (their card, their events, their sign-out link): no shared * cache may keep it for the next visitor. Page caches that honour `DONOTCACHEPAGE` skip the page, and the * response says so to proxies while its headers can still be sent. */ public static function personal(): void { if ( ! defined( 'DONOTCACHEPAGE' ) ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedConstantFound -- the page caches' shared signal (WP Super Cache, W3 Total Cache, WP Rocket, LiteSpeed Cache…), not a name of this plugin's. define( 'DONOTCACHEPAGE', true ); } if ( ! headers_sent() ) { nocache_headers(); } } private static function id(): string { return isset( $_COOKIE[ self::COOKIE ] ) ? sanitize_key( wp_unslash( $_COOKIE[ self::COOKIE ] ) ) : ''; } private static function from_tokens( array $t, array $prev = [] ): array { return [ 'access_token' => (string) ( $t['access_token'] ?? '' ), 'refresh_token' => (string) ( $t['refresh_token'] ?? ( $prev['refresh_token'] ?? '' ) ), 'expires_at' => time() + (int) ( $t['expires_in'] ?? 600 ), 'scope' => (string) ( $t['scope'] ?? ( $prev['scope'] ?? '' ) ), 'sub' => (string) ( $t['sub'] ?? ( $prev['sub'] ?? '' ) ), ]; } // A refresh that fails while a shortcode renders ends the session after the headers have gone: the transient is // gone all the same, and the stale cookie then names nothing. private static function cookie( string $value, int $expires ): void { if ( ! headers_sent() ) { setcookie( self::COOKIE, $value, [ 'expires' => $expires, 'path' => '/', 'secure' => is_ssl(), 'httponly' => true, 'samesite' => 'Lax', ] ); } $_COOKIE[ self::COOKIE ] = $value; } }