108 lines
3.3 KiB
PHP
108 lines
3.3 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
namespace App\Helper;
|
|
|
|
use App\Entity\ExchangeRates;
|
|
use Doctrine\ORM\EntityManager;
|
|
|
|
class Currency
|
|
{
|
|
public static array $currencies = ["USD","GBP","PLN","EUR","CAD"];
|
|
public static array $currenciesCrypto = ["USDT"];
|
|
private static string $apiUrl = "https://api.nbp.pl/api/exchangerates/rates/a/:code/:date/?format=json";
|
|
private EntityManager $manager;
|
|
private array $ratesPerDate;
|
|
|
|
public function __construct(EntityManager $manager)
|
|
{
|
|
$this->manager = $manager;
|
|
$this->takeRates();
|
|
}
|
|
|
|
public function getRate(string $currency, \DateTime $dateTime) : float
|
|
{
|
|
$dayOfWeek = $dateTime->format("N");
|
|
$minusDay = 1;
|
|
if ($dayOfWeek == 7){
|
|
$minusDay = 2;
|
|
} elseif ($dayOfWeek == 1) {
|
|
$minusDay = 3;
|
|
}
|
|
$dateTime->modify("-$minusDay days");
|
|
$dateStr = $dateTime->format("Ymd");
|
|
|
|
if (isset($this->ratesPerDate[$currency]) && isset($this->ratesPerDate[$currency][$dateStr])) {
|
|
return $this->ratesPerDate[$currency][$dateStr];
|
|
}
|
|
$dateCopy = clone $dateTime;
|
|
$limitLoop = 5;
|
|
do {
|
|
$rate = $this->takePLNOnDate($currency, $dateCopy->format("Y-m-d"));
|
|
if (!$rate) {
|
|
$dateCopy->modify("-1 day");
|
|
}
|
|
if ($limitLoop < 1) {
|
|
break;
|
|
}
|
|
$limitLoop--;
|
|
}while($rate == 0);
|
|
|
|
if ($rate) {
|
|
$ratesEntity = new ExchangeRates();
|
|
$ratesEntity->setIntRate(intval($rate * 10000));
|
|
$ratesEntity->setStrCurrency($currency);
|
|
$ratesEntity->setDateDate($dateTime);
|
|
|
|
$this->manager->persist($ratesEntity);
|
|
$this->manager->flush();
|
|
$this->ratesPerDate[$currency][$dateStr] = $rate;
|
|
return $rate;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
private function takePLNOnDate(string $currency, string $dateStr) : float
|
|
{
|
|
if (!self::isCurrencyExists($currency)) {
|
|
return 0;
|
|
}
|
|
$url = strtr(self::$apiUrl,[
|
|
":code" => mb_strtolower($currency),
|
|
":date" => str_replace(".","-",$dateStr)
|
|
]);
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
$result=curl_exec($ch);
|
|
curl_close($ch);
|
|
$data = json_decode($result, true);
|
|
if (!isset($data['rates']) || !isset($data['rates'][0]) || !isset($data['rates'][0]['mid'])) {
|
|
return 0;
|
|
}
|
|
return $data['rates'][0]['mid'];
|
|
}
|
|
|
|
private function takeRates()
|
|
{
|
|
$rates = $this->manager->getRepository(ExchangeRates::class);
|
|
$rates = $rates->findAll();
|
|
|
|
if ($rates) {
|
|
/** @var ExchangeRates $rate */
|
|
foreach ($rates as $rate) {
|
|
if (!isset($this->ratesPerDate[$rate->getStrCurrency()])) {
|
|
$this->ratesPerDate[$rate->getStrCurrency()] = [];
|
|
}
|
|
$this->ratesPerDate[$rate->getStrCurrency()][$rate->getDateDate()->format("Ymd")] = $rate->getIntRate()/10000;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public static function isCurrencyExists(string $currency) : bool
|
|
{
|
|
return in_array($currency, self::$currencies);
|
|
}
|
|
} |