Completed
Push — master ( 7d07ad...9ddc24 )
by BENOIT
05:32
created

DoctrineORMProvider   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 6
lcom 1
cbo 3
dl 0
loc 80
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 2
B getExchangeRate() 0 33 4
1
<?php
2
3
namespace BenTools\Currency\Provider;
4
5
use BenTools\Currency\Model\CurrencyInterface;
6
use BenTools\Currency\Model\ExchangeRateInterface;
7
use BenTools\Currency\Model\ExchangeRateNotFoundException;
8
use DateTimeInterface;
9
use Doctrine\Common\Persistence\ManagerRegistry;
10
11
class DoctrineORMProvider implements ExchangeRateProviderInterface
12
{
13
    private const DEFAULT_PROPERTY_MAP = [
14
        'sourceCurrency' => 'sourceCurrencyCode',
15
        'targetCurrency' => 'targetCurrencyCode',
16
        'date'           => 'date',
17
    ];
18
19
    /**
20
     * @var ManagerRegistry
21
     */
22
    private $managerRegistry;
23
24
    /**
25
     * @var string
26
     */
27
    private $entityClass;
28
29
    /**
30
     * @var array
31
     */
32
    private $propertyMap;
33
34
    /**
35
     * DoctrineORMProvider constructor.
36
     * @param ManagerRegistry $managerRegistry
37
     * @param string          $entityClass
38
     * @param array           $propertyMap
39
     * @throws \InvalidArgumentException
40
     */
41
    public function __construct(
42
        ManagerRegistry $managerRegistry,
43
        string $entityClass,
44
        array $propertyMap = self::DEFAULT_PROPERTY_MAP
45
    ) {
46
        if (!is_a($entityClass, ExchangeRateInterface::class, true)) {
47
            throw new \InvalidArgumentException(sprintf('%s must implement %s', $entityClass, ExchangeRateInterface::class));
48
        }
49
        $this->managerRegistry = $managerRegistry;
50
        $this->entityClass = $entityClass;
51
        $this->propertyMap = $propertyMap;
52
    }
53
54
    /**
55
     * @inheritDoc
56
     */
57
    public function getExchangeRate(CurrencyInterface $sourceCurrency, CurrencyInterface $targetCurrency, DateTimeInterface $date = null): ExchangeRateInterface
58
    {
59
        $em = $this->managerRegistry->getManagerForClass($this->entityClass);
60
        $repository = $em->getRepository($this->entityClass);
61
        if (null !== $date) {
62
            $exchangeRate = $repository->findOneBy([
63
                $this->propertyMap['sourceCurrency'] => $sourceCurrency->getCode(),
64
                $this->propertyMap['targetCurrency'] => $targetCurrency->getCode(),
65
                $this->propertyMap['date']           => $date,
66
            ]);
67
68
            if (null === $exchangeRate) {
69
                throw new ExchangeRateNotFoundException($sourceCurrency, $targetCurrency);
70
            }
71
            return $exchangeRate;
72
        }
73
74
        $criteria = [
75
            $this->propertyMap['sourceCurrency'] => $sourceCurrency->getCode(),
76
            $this->propertyMap['targetCurrency'] => $targetCurrency->getCode(),
77
            $this->propertyMap['date']           => $date,
78
        ];
79
        $orderBy = [
80
            $this->propertyMap['date'] => 'desc'
81
        ];
82
83
        $results = $repository->findBy($criteria, $orderBy, 1);
84
85
        foreach ($results as $exchangeRate) {
86
            return $exchangeRate;
87
        }
88
        throw new ExchangeRateNotFoundException($sourceCurrency, $targetCurrency);
89
    }
90
}
91