> The connections dropped. * @since 1.4.0 */ public static function sweep_never_used(): array { // Read through the settings chain, not get_option(): a constant or an // `albert/settings/value/{option}` filter pins this the same way it pins // any other setting, and (the part that matters) the Settings screen // renders the field read-only when one is in force. A sweep reading the // stored option while the screen says code owns it would delete // connections on a schedule nobody could see or change. // // The default stays explicit even though Settings\Storage registers one. // That registration runs on `admin_init`, and this sweep runs in cron, // where it has not happened: get_option() would return false, cast to 0, // and quietly disable the sweep it is supposed to configure. $days = (int) Value::get( self::NEVER_USED_OPTION, self::DEFAULT_NEVER_USED_DAYS ); if ( $days <= 0 ) { return []; } $cutoff = time() - ( $days * DAY_IN_SECONDS ); $repo = new ClientRepository(); $dropped = []; foreach ( $repo->getLiveConnections() as $connection ) { if ( $connection['last_used_ts'] > 0 ) { continue; // Has been used at least once; not this sweep's concern. } if ( $connection['created_ts'] > $cutoff ) { continue; // Too recent: still inside the grace window. } self::drop( $repo, $connection['client_id'] ); $dropped[] = $connection; } return $dropped; } /** * Drop every connection that was used before, but not within its window. * * @return array> The connections dropped. * @since 1.4.0 */ public static function sweep_idle(): array { // Settings chain and an explicit default: cron, not admin. See // sweep_never_used(). $days = (int) Value::get( self::IDLE_OPTION, self::DEFAULT_IDLE_DAYS ); if ( $days <= 0 ) { return []; } $cutoff = time() - ( $days * DAY_IN_SECONDS ); $repo = new ClientRepository(); $dropped = []; foreach ( $repo->getLiveConnections() as $connection ) { if ( $connection['last_used_ts'] <= 0 ) { continue; // Never used at all; that's sweep_never_used()'s concern. } if ( $connection['last_used_ts'] > $cutoff ) { continue; // Used recently enough. } self::drop( $repo, $connection['client_id'] ); $dropped[] = $connection; } return $dropped; } /** * Revoke a client's tokens and delete its registration. * * @param ClientRepository $repo The repository to act through. * @param string $client_id The client to drop. * * @return void * @since 1.4.0 */ private static function drop( ClientRepository $repo, string $client_id ): void { $repo->revokeAllTokens( $client_id ); $repo->deleteClient( $client_id ); } }