AbstractTimeConstraintUtils.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Service\Constraint;
  4. /**
  5. * Classe Utils qui fournit de méthodes pour calculer les contraintes de temps.
  6. */
  7. abstract class AbstractTimeConstraintUtils
  8. {
  9. public const NULL = 0;
  10. public const INF = 1;
  11. public const EQUAL = 3;
  12. public const SUP = 5;
  13. public const CANCEL_OPERATION = 9;
  14. public const START_KEY = 'start';
  15. public const END_KEY = 'end';
  16. public const NULL_VALUE = 'NULL';
  17. /**
  18. * Retourne true si l'utilisateur veux une période précise.
  19. *
  20. * @param array<bool|string> $historical
  21. *
  22. * @see DateTimeConstraintTest::testHasCustomPeriods()
  23. */
  24. protected function hasCustomPeriods(array $historical): bool
  25. {
  26. return array_key_exists('dateStart', $historical) && $historical['dateStart'] && array_key_exists('dateEnd', $historical) && $historical['dateEnd'];
  27. }
  28. /**
  29. * Fonction permettant d'ajouter une nouvelle contrainte de date.
  30. *
  31. * @param array<string, array<string, list<int>>> $contraints
  32. * @param array<string, list<int>> $newContraint
  33. *
  34. * @return array<string, array<string, int[]>>
  35. *
  36. * @see DateTimeConstraintTest::testAddConstraint()
  37. */
  38. protected function addConstraint(array $contraints, array $newContraint): array
  39. {
  40. $contraints = $this->mergeConstraint($contraints, $newContraint, self::START_KEY);
  41. return $this->mergeConstraint($contraints, $newContraint, self::END_KEY);
  42. }
  43. /**
  44. * Construit le tableau de contraintes pour une condition (start, end).
  45. *
  46. * @param array<string, array<string, list<int>>> $contraints
  47. * @param array<string, list<int>> $newContraint
  48. *
  49. * @return array<string, array<string, int[]>>
  50. */
  51. protected function mergeConstraint(array $contraints, array $newContraint, string $key): array
  52. {
  53. if (array_key_exists($key, $newContraint)) {
  54. foreach ($newContraint[$key] as $dateKey => $arithmeticValue) {
  55. // Si la date à déjà des conditions
  56. if (array_key_exists($dateKey, $contraints[$key])) {
  57. // Si la conditions (<, >, =, ...) n'est pas encore appliquée à la date
  58. if (!in_array($arithmeticValue, $contraints[$key][$dateKey])) {
  59. $contraints[$key][$dateKey][] = $arithmeticValue;
  60. }
  61. } else {
  62. $contraints[$key][$dateKey] = [$arithmeticValue];
  63. }
  64. }
  65. }
  66. return $contraints;
  67. }
  68. /**
  69. * Nettoyage des contraintes (toutes celles supérieur à la condition cancel et les valeurs null isolées).
  70. *
  71. * @param array<string, array<string, list<int>>> $constraints
  72. *
  73. * @return array<string, array<string, list<int>>>
  74. *
  75. * @see DateTimeConstraintTest::testCleanConstraints()
  76. */
  77. protected function cleanConstraints(array $constraints): array
  78. {
  79. $constraints[self::START_KEY] = $this->filterConstraint($constraints, self::START_KEY);
  80. $constraints[self::START_KEY] = $this->clearNull($constraints, self::START_KEY);
  81. $constraints[self::END_KEY] = $this->filterConstraint($constraints, self::END_KEY);
  82. $constraints[self::END_KEY] = $this->clearNull($constraints, self::END_KEY);
  83. return $constraints;
  84. }
  85. /**
  86. * Pour chaque contraintes appliquées à une date on vérifie qu'on ne dépasse pas la valeur cancel : c'est à dire
  87. * la condition qui démontre que toutes les valeurs arithmétiques ont été choisies.
  88. *
  89. * @param array<string, array<string, list<int>>> $constraints
  90. *
  91. * @return array<string, list<int>>
  92. *
  93. * @see DateTimeConstraintTest::testFilterConstraint()
  94. */
  95. protected function filterConstraint(array $constraints, string $key): array
  96. {
  97. return array_filter($constraints[$key], function ($constraint) {
  98. return array_sum($constraint) < self::CANCEL_OPERATION;
  99. });
  100. }
  101. /**
  102. * On ne conserve pas les contraintes sur des conditions start et end si ces dernieres ne possède qu'une valeur null :
  103. * une valeur null doit obligatoirement s'appliquer avec un OR
  104. *
  105. * @param array<string, array<string, list<int>>> $constraints
  106. *
  107. * @return array<string, list<int>>
  108. *
  109. * @see DateTimeConstraintTest::testClearNull()
  110. */
  111. protected function clearNull(array $constraints, string $key): array
  112. {
  113. if (count($constraints[$key]) === 1 && array_key_exists(self::NULL_VALUE, $constraints[$key])) {
  114. $constraints[$key] = [];
  115. }
  116. return $constraints[$key];
  117. }
  118. }