Licitator 1.0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
6.2 KiB

5 years ago
  1. <?php
  2. namespace Zitec\RuleEngineBundle\Conditions;
  3. /**
  4. * Starter kit class for declaring conditions for a single-value parameter.
  5. */
  6. abstract class AbstractValueCondition implements ConditionInterface
  7. {
  8. /**
  9. * Use this operator when you want to
  10. * check that the parameter value is among a given set of values.
  11. */
  12. protected const VALUE_IN = 'valueIn';
  13. /**
  14. * Use this operator when you want to
  15. * check that the parameter value is NOT among a given set of values.
  16. */
  17. protected const VALUE_NOT_IN = 'valueNotIn';
  18. /**
  19. * Use this operator when you want to
  20. * check that the parameter value is in a given numeric interval.
  21. */
  22. protected const INTERVAL = 'valueInterval';
  23. /**
  24. * Use this operator when you want to
  25. * check that the parameter value and configured value are equal.
  26. */
  27. protected const EQUALS = 'valueEqual';
  28. /**
  29. * Use this operator when you want to
  30. * check that the parameter value is greater than the configured value.
  31. */
  32. protected const GREATER = 'valueGreater';
  33. /**
  34. * Use this operator when you want to
  35. * compare that the parameter value is smaller than the configured value.
  36. */
  37. protected const SMALLER = 'valueSmaller';
  38. /**
  39. * Use this operator when you want to
  40. * compare the parameter value with another single-value parameter's value.
  41. */
  42. protected const EQUALS_PARAM = 'valueEqParam';
  43. /**
  44. * @var string
  45. */
  46. protected $name;
  47. /**
  48. * @var string
  49. */
  50. protected $label;
  51. /**
  52. * @var string
  53. */
  54. protected $description;
  55. /**
  56. * @return string
  57. */
  58. public function getName(): string
  59. {
  60. return $this->name;
  61. }
  62. /**
  63. * @return string
  64. */
  65. public function getLabel(): string
  66. {
  67. return $this->label;
  68. }
  69. /**
  70. * @return array
  71. */
  72. public function getDefinitions(): array
  73. {
  74. return [
  75. 'name' => $this->name,
  76. 'label' => $this->label,
  77. 'description' => $this->description,
  78. 'operators' => $this->getOperatorDefinitions(),
  79. ];
  80. }
  81. /**
  82. * {@inheritdoc}
  83. *
  84. * Example implementation can be found in the CurrentDate parameter implementation.
  85. *
  86. * @return array
  87. */
  88. abstract protected function getOperatorDefinitions(): array;
  89. /**
  90. * @param string $parameterName
  91. * @param string $operator
  92. * @param mixed $value
  93. * @return string
  94. */
  95. public function getExpression(string $parameterName, string $operator, $value): string
  96. {
  97. if (is_null($value)) {
  98. throw new \UnexpectedValueException(
  99. sprintf('NULL value received for condition %s and operator $s', $this->name, $operator)
  100. );
  101. }
  102. $operators = $this->getOperatorDefinitions();
  103. foreach ($operators as $definition) {
  104. if ($operator == $definition['name'] && isset($definition['value_transform'])) {
  105. $value = call_user_func($definition['value_transform'], $value);
  106. break;
  107. }
  108. }
  109. switch ($operator) {
  110. case $this::VALUE_IN:
  111. if (!is_array($value)) {
  112. throw new \UnexpectedValueException('The value for the %s operator has to be an array.', $operator);
  113. }
  114. $formattedValue = implode("','", $value);
  115. return "$parameterName in ['$formattedValue']";
  116. case $this::VALUE_NOT_IN:
  117. if (!is_array($value)) {
  118. throw new \UnexpectedValueException('The value for the %s operator has to be an array.', $operator);
  119. }
  120. $formattedValue = implode("','", $value);
  121. return "$parameterName not in ['$formattedValue']";
  122. case $this::INTERVAL:
  123. if (!isset($value['from']) || !isset($value['to']) || $value['to'] < $value['from']) {
  124. throw new \UnexpectedValueException(
  125. 'The value for the %s operator is not a valid interval.',
  126. $operator
  127. );
  128. }
  129. $start = $value['from'];
  130. $end = $value['to'];
  131. return "$parameterName >= $start and $parameterName <= $end";
  132. case $this::EQUALS:
  133. return "$parameterName == '$value'";
  134. case $this::GREATER:
  135. return "$parameterName > $value";
  136. case $this::SMALLER:
  137. return "$parameterName < $value";
  138. case $this::EQUALS_PARAM:
  139. return "$parameterName == $value";
  140. }
  141. throw new \DomainException(sprintf('Unrecognized operator %s', $operator));
  142. }
  143. /**
  144. * @param mixed $value
  145. * @return bool
  146. */
  147. public function validateParameterValue($value): bool
  148. {
  149. return is_string($value);
  150. }
  151. /**
  152. * @param string $operator
  153. * @param $value
  154. * @return string
  155. */
  156. public function getDisplayValue(string $operator, $value): string
  157. {
  158. $operatorLabel = '';
  159. $operators = $this->getOperatorDefinitions();
  160. foreach ($operators as $definition) {
  161. if ($operator == $definition['name']) {
  162. $operatorLabel = $definition['label'];
  163. if (isset($definition['value_view_transform'])) {
  164. $value = call_user_func($definition['value_view_transform'], $value);
  165. }
  166. break;
  167. }
  168. }
  169. switch ($operator) {
  170. case $this::VALUE_IN:
  171. case $this::VALUE_NOT_IN:
  172. $formattedValue = implode(',', $value);
  173. break;
  174. case $this::INTERVAL:
  175. $start = $value['from'];
  176. $end = $value['to'];
  177. $formattedValue = "$start and $end";
  178. break;
  179. case $this::EQUALS:
  180. case $this::GREATER:
  181. case $this::SMALLER:
  182. case $this::EQUALS_PARAM:
  183. $formattedValue = $value;
  184. break;
  185. default:
  186. $formattedValue = '';
  187. break;
  188. }
  189. return $this->label . ': ' . $operatorLabel . ' ' . $formattedValue;
  190. }
  191. }