Completed
Push — master ( e08508...e2d78b )
by Benedikt
07:44
created

getRankingSystemsEarliestInfluences()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Created by PhpStorm.
5
 * User: benedikt
6
 * Date: 1/4/18
7
 * Time: 4:09 PM
8
 */
9
10
namespace Tfboe\FmLib\Service;
11
12
13
use Doctrine\DBAL\LockMode;
14
use Doctrine\ORM\EntityManager;
15
use Doctrine\ORM\EntityManagerInterface;
16
use Tfboe\FmLib\Entity\Helpers\TournamentHierarchyInterface;
17
use Tfboe\FmLib\Entity\LastRecalculationInterface;
18
use Tfboe\FmLib\Entity\RankingSystemInterface;
19
use Tfboe\FmLib\Entity\TournamentInterface;
20
use Tfboe\FmLib\Helpers\Logging;
21
22
/**
23
 * Class RankingSystemService
24
 * @package Tfboe\FmLib\Service
25
 */
26
class RankingSystemService implements RankingSystemServiceInterface
27
{
28
//<editor-fold desc="Fields">
29
  /**
30
   * @var DynamicServiceLoadingServiceInterface
31
   */
32
  private $dsls;
33
34
  /** @var EntityManagerInterface */
35
  private $entityManager;
36
//</editor-fold desc="Fields">
37
38
//<editor-fold desc="Constructor">
39
40
  /**
41
   * RankingSystemService constructor.
42
   * @param DynamicServiceLoadingServiceInterface $dsls
43
   * @param EntityManagerInterface $entityManager
44
   */
45
  public function __construct(DynamicServiceLoadingServiceInterface $dsls, EntityManagerInterface $entityManager)
46
  {
47
    $this->dsls = $dsls;
48
    $this->entityManager = $entityManager;
49
  }
50
//</editor-fold desc="Constructor">
51
52
//<editor-fold desc="Public Methods">
53
  /**
54
   * @inheritDoc
55
   */
56
  public function adaptOpenSyncFromValues(TournamentInterface $tournament, array $oldInfluences): void
57
  {
58
    $earliestInfluences = $this->getRankingSystemsEarliestInfluences($tournament);
59
    foreach ($oldInfluences as $id => $arr) {
60
      if (array_key_exists($id, $earliestInfluences)) {
61
        if ($oldInfluences[$id]["earliestInfluence"] < $earliestInfluences[$id]["earliestInfluence"]) {
62
          $earliestInfluences[$id]["earliestInfluence"] = $oldInfluences[$id]["earliestInfluence"];
63
        }
64
      } else {
65
        $earliestInfluences[$id] = $oldInfluences[$id];
66
      }
67
    }
68
    foreach ($earliestInfluences as $arr) {
69
      /** @var RankingSystemInterface $ranking */
70
      $ranking = $arr["rankingSystem"];
71
      $earliestInfluence = $arr["earliestInfluence"];
72
      if ($ranking->getOpenSyncFrom() === null || $ranking->getOpenSyncFrom() > $earliestInfluence) {
73
        $ranking->setOpenSyncFrom($earliestInfluence);
74
      }
75
    }
76
  }
77
78
  /**
79
   * @inheritDoc
80
   */
81
  public function applyRankingSystems(TournamentInterface $tournament, array $earliestInfluences): void
82
  {
83
    $rankingSystems = $this->getRankingSystems($tournament);
84
    foreach ($rankingSystems as $sys) {
85
      if (!array_key_exists($sys->getId(), $earliestInfluences)) {
86
        $earliestInfluences[$sys->getId()] = [
87
          "rankingSystem" => $sys,
88
          "earliestInfluence" => null
89
        ];
90
      }
91
    }
92
    foreach ($earliestInfluences as $arr) {
93
      /** @var RankingSystemInterface $ranking */
94
      $ranking = $arr["rankingSystem"];
95
      $earliestInfluence = $arr["earliestInfluence"];
96
      $service = $this->dsls->loadRankingSystemService($ranking->getServiceName());
97
      $service->updateRankingForTournament($ranking, $tournament, $earliestInfluence);
98
    }
99
  }
100
101
  /**
102
   * @inheritDoc
103
   */
104
  public function getRankingSystemsEarliestInfluences(TournamentInterface $tournament): array
105
  {
106
    $rankingSystems = $this->getRankingSystems($tournament);
107
108
    $result = [];
109
    //compute earliest influences
110
    foreach ($rankingSystems as $sys) {
111
      $service = $this->dsls->loadRankingSystemService($sys->getServiceName());
112
      $result[$sys->getId()] = [
113
        "rankingSystem" => $sys,
114
        "earliestInfluence" => $service->getEarliestInfluence($sys, $tournament)
115
      ];
116
    }
117
118
    return $result;
119
  }
120
121
  /**
122
   * @inheritDoc
123
   */
124
  public function recalculateRankingSystems(): void
125
  {
126
    //clear entityManager to save memory
127
    $this->entityManager->flush();
128
    $this->entityManager->clear();
129
    $rankingSystemOpenSyncFroms = [];
130
    /** @var RankingSystemInterface[] $rankingSystems */
131
    $rankingSystems = [];
132
    $this->entityManager->transactional(
133
      function (EntityManager $em) use (&$rankingSystems, &$rankingSystemOpenSyncFroms) {
134
        $em->find(LastRecalculationInterface::class, 1, LockMode::PESSIMISTIC_WRITE);
135
        $query = $em->createQueryBuilder();
136
        $query
137
          ->from(RankingSystemInterface::class, 's')
138
          ->select('s')
139
          ->where($query->expr()->isNotNull('s.openSyncFrom'));
140
        /** @var RankingSystemInterface[] $rankingSystems */
141
        $rankingSystems = $query->getQuery()->setLockMode(LockMode::PESSIMISTIC_WRITE)->getResult();
142
        foreach ($rankingSystems as $rankingSystem) {
143
          $rankingSystemOpenSyncFroms[$rankingSystem->getId()] = $rankingSystem->getOpenSyncFrom();
144
          Logging::log("Update Ranking System " . $rankingSystem->getName() . " from " .
145
            $rankingSystem->getOpenSyncFrom()->format("Y-m-d H:i:s"));
146
          $rankingSystem->setOpenSyncFrom(null);
147
        }
148
      }
149
    );
150
151
    if (count($rankingSystems) > 0) {
152
      $this->entityManager->transactional(
153
        function (EntityManager $em) use (&$rankingSystems, &$rankingSystemOpenSyncFroms) {
154
          /** @var LastRecalculationInterface $lastRecalculation */
155
          $lastRecalculation = $em->find(LastRecalculationInterface::class, 1, LockMode::PESSIMISTIC_WRITE);
156
          $em->flush();
157
          $lastRecalculation->setStartTime(new \DateTime());
158
          foreach ($rankingSystems as $rankingSystem) {
159
            $service = $this->dsls->loadRankingSystemService($rankingSystem->getServiceName());
160
            $service->updateRankingFrom($rankingSystem, $rankingSystemOpenSyncFroms[$rankingSystem->getId()]);
161
          }
162
          $lastRecalculation->setEndTime(new \DateTime());
163
          $lastRecalculation->setVersion($lastRecalculation->getVersion() + 1);
164
        }
165
      );
166
    }
167
  }
168
//</editor-fold desc="Public Methods">
169
170
//<editor-fold desc="Private Methods">
171
  /**
172
   * @param TournamentHierarchyInterface $entity
173
   * @return RankingSystemInterface[]
174
   */
175
  private function getRankingSystems(TournamentHierarchyInterface $entity): array
176
  {
177
    $result = $entity->getRankingSystems()->toArray();
178
    foreach ($entity->getChildren() as $child) {
179
      $result = array_merge($result, $this->getRankingSystems($child));
180
    }
181
    return $result;
182
  }
183
//</editor-fold desc="Private Methods">
184
}