time(), 'until' => time() + max( 1, (int) $ttl ), 'detail' => (string) $detail, ); self::set( 'breakers', $breakers ); } /** * An open breaker. * * @param string $name Breaker name. * @return array|null Keys since, until, detail. Null when closed. */ public static function breaker( $name ) { $breakers = (array) self::get( 'breakers', array() ); if ( empty( $breakers[ $name ] ) || ! is_array( $breakers[ $name ] ) ) { return null; } if ( (int) $breakers[ $name ]['until'] <= time() ) { return null; } return $breakers[ $name ]; } /** * Closes a breaker. * * @param string $name Breaker name. * @return void */ public static function clear_breaker( $name ) { $breakers = (array) self::get( 'breakers', array() ); if ( isset( $breakers[ $name ] ) ) { unset( $breakers[ $name ] ); self::set( 'breakers', $breakers ); } } /** * Closes every breaker (e.g. after the key changes). * * @return void */ public static function clear_all_breakers() { self::set( 'breakers', null ); } /** * Clears the request cache. * * @return void */ public static function flush() { self::$cache = null; } /** * Unix time of the first day of next month, UTC — when SendFleet quotas reset. * * @return int */ public static function next_month_start_utc() { $now = new \DateTimeImmutable( 'now', new \DateTimeZone( 'UTC' ) ); return $now->modify( 'first day of next month' )->setTime( 0, 0, 0 )->getTimestamp(); } }