Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/pod.git
<?php
class ExchangeRate {
  private array $rates = [];
  private string $base;
  private string $cacheFile;

  // How long until we refresh the exchange rate cache (in minutes).
  private int $cacheLifetime = 14400;

  public function __construct(
    Currency $base, string $url, string $cache, int $lifetime
  ) {
    $this->cacheFile = $cache;
    $this->cacheLifetime = $lifetime;
    $url = $base->replace( $url, '{{currency}}' );

    if( $this->expired( $cache ) ) {
      $this->fetch( $url, $cache );
    } else {
      $this->fetch( $cache, $cache );
    }
  }

  public function convert( Money $money, Currency $targetCurrency ): Money {
    return $money->convert( $this, $targetCurrency );
  }

  public function rate( Currency $source, Currency $target ): float {
    $sourceRate = $this->rateFor( $source );
    $targetRate = $this->rateFor( $target );

    return $targetRate / $sourceRate;
  }

  public function clearCache(): void {
    if( file_exists( $this->cacheFile ) ) {
      unlink( $this->cacheFile );
    }
  }

  private function expired( string $cache ): bool {
    return
      !file_exists( $cache ) ||
      (time() - filemtime( $cache )) > $this->cacheLifetime;
  }

  private function fetch( string $source, string $cache ): void {
    $response = @file_get_contents( $source );

    if( is_string( $response ) ) {
      $payload = json_decode( $response, true );

      if( isset( $payload['rates'] ) ) {
        $this->rates = $payload['rates'];
        $this->rates[ 'CAD' ] = 1.0;

        if( $source !== $cache ) {
          file_put_contents( $cache, json_encode( $payload ) );
        }
      }
    }
  }

  private function rateFor( Currency $currency ): float {
    return (float)$this->rates[ $currency->toString() ];
  }
}