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); } }