AbstractUnit.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. namespace App\Yr\Forecast\Tabular\Time;
  3. /**
  4. * Time-object entity should inherit this
  5. */
  6. abstract class AbstractUnit implements DiffInterface {
  7. const DEFAULT_VARIANCE = 2;
  8. private $value = 0;
  9. private $unit;
  10. /**
  11. * @param float The value
  12. * @param float The unit
  13. */
  14. public function __construct(float $value, string $unit) {
  15. $this->value = $value;
  16. $this->unit = $unit;
  17. }
  18. private function canOperate(AbstractUnit $with, bool $throw = false): bool {
  19. if ($with instanceof $this || $with instanceof CustomUnit)
  20. return true;
  21. if ($this instanceof CustomUnit && $with instanceof AbstractUnit)
  22. return true;
  23. if ($throw)
  24. throw new \InvalidArgumentException(sprintf(
  25. "Invalid type <%s>, expected of type \"%s\" or \"%s\"",
  26. get_class($with), get_class($this), CustomUnit::class
  27. ));
  28. return false;
  29. }
  30. protected function transformClass(CustomUnit $cu): self {
  31. return unserialize(preg_replace(
  32. '/^O:\d+:"[^"]++"/',
  33. sprintf('O:%d:"%s"', strlen(static::class), static::class),
  34. serialize($cu)
  35. ));
  36. }
  37. /**
  38. * Addition method
  39. *
  40. * @param AbstractUnit $with Unit to add with
  41. * @thows \InvalidArgumentException
  42. * */
  43. public function add(AbstractUnit $with): self {
  44. $this->canOperate($with, true);
  45. return $this->transformClass(
  46. new CustomUnit($this->getValue() + $with->getValue(), $with->getUnit())
  47. );
  48. }
  49. /**
  50. * Multiplication method
  51. *
  52. * @param AbstractUnit $with Unit to multiply with
  53. * @thows \InvalidArgumentException
  54. * */
  55. public function mul(AbstractUnit $with): self {
  56. $this->canOperate($with, true);
  57. return $this->transformClass(
  58. new CustomUnit($this->getValue() * $with->getValue(), $with->getUnit())
  59. );
  60. }
  61. /**
  62. * Divide method
  63. *
  64. * @param AbstractUnit $with Unit to divide with
  65. * @thows \InvalidArgumentException
  66. * */
  67. public function div(AbstractUnit $with): self {
  68. $this->canOperate($with, true);
  69. return $this->transformClass(
  70. new CustomUnit($this->getValue() / $with->getValue(), $with->getUnit())
  71. );
  72. }
  73. /**
  74. * Get the value
  75. *
  76. * @return float
  77. */
  78. public function getValue(): float {
  79. return $this->value;
  80. }
  81. /**
  82. * Return the unit (e.g «degree»)
  83. *
  84. * @return string
  85. */
  86. public function getUnit(): string {
  87. return $this->unit;
  88. }
  89. /**
  90. * {@inheritDoc}
  91. */
  92. public function diff(DiffInterface $d): int {
  93. if ($d instanceof $this)
  94. return $this->value - $d->getValue();
  95. return 0;
  96. }
  97. public function __toString(): string {
  98. return sprintf(
  99. "%s: %f %s", basename(str_replace(
  100. '\\', DIRECTORY_SEPARATOR, get_class($this)
  101. )), $this->value, $this->unit);
  102. }
  103. }