DataModel.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <?php
  2. namespace ForkBB\Models;
  3. use ForkBB\Models\Model;
  4. class DataModel extends Model
  5. {
  6. /**
  7. * Массив флагов измененных свойств модели
  8. * @var array
  9. */
  10. protected $zModFlags = [];
  11. /**
  12. * Массив состояний отслеживания изменений в свойствах модели
  13. * @var array
  14. */
  15. protected $zTrackFlags = [];
  16. /**
  17. * Устанавливает значения для свойств
  18. * Сбрасывает вычисленные свойства
  19. * Флаги модификации свойст сброшены
  20. *
  21. * @param array $attrs
  22. *
  23. * @return Model
  24. */
  25. public function setAttrs(array $attrs): Model
  26. {
  27. $this->zModFlags = [];
  28. $this->zTrackFlags = [];
  29. return parent::setAttrs($attrs);
  30. }
  31. /**
  32. * Перезаписывает свойства модели
  33. * Флаги модификации свойств сбрасываются/устанавливаются в зависимости от второго параметра
  34. *
  35. * @param array $attrs
  36. * @param bool $setFlags
  37. *
  38. * @return DataModel
  39. */
  40. public function replAttrs(array $attrs, bool $setFlags = false): DataModel
  41. {
  42. foreach ($attrs as $name => $value) {
  43. $this->__set($name, $value);
  44. if (! $setFlags) {
  45. unset($this->zModFlags[$name]);
  46. }
  47. }
  48. return $this;
  49. }
  50. /**
  51. * Возвращает значения свойств в массиве
  52. *
  53. * @return array
  54. */
  55. public function getAttrs(): array
  56. {
  57. return $this->zAttrs; //????
  58. }
  59. /**
  60. * Возвращает массив имен измененных свойств модели
  61. *
  62. * @return array
  63. */
  64. public function getModified(): array
  65. {
  66. return \array_keys($this->zModFlags);
  67. }
  68. /**
  69. * Возвращает модифицировано ли свойство модели
  70. */
  71. public function isModified(string $name): bool
  72. {
  73. return ! empty($this->zModFlags[$name]);
  74. }
  75. /**
  76. * Обнуляет массив флагов измененных свойств модели
  77. */
  78. public function resModified(): void
  79. {
  80. $this->zModFlags = [];
  81. $this->zTrackFlags = [];
  82. }
  83. /**
  84. * Устанавливает значение для свойства
  85. *
  86. * @param string $name
  87. * @param mixed $value
  88. */
  89. public function __set(string $name, $value): void
  90. {
  91. // без отслеживания
  92. if (0 === \strpos($name, '__')) {
  93. $track = null;
  94. $name = \substr($name, 2);
  95. // с отслеживанием
  96. } else {
  97. $track = false;
  98. if (\array_key_exists($name, $this->zAttrs)) {
  99. $track = true;
  100. $old = $this->zAttrs[$name];
  101. // fix
  102. if (
  103. \is_int($value)
  104. && \is_numeric($old)
  105. && \is_int(0 + $old)
  106. ) {
  107. $old = (int) $old;
  108. }
  109. }
  110. }
  111. $this->zTrackFlags[$name] = $track;
  112. parent::__set($name, $value);
  113. unset($this->zTrackFlags[$name]);
  114. if (null === $track) {
  115. return;
  116. }
  117. if (
  118. (
  119. ! $track
  120. && \array_key_exists($name, $this->zAttrs)
  121. )
  122. || (
  123. $track
  124. && $old !== $this->zAttrs[$name]
  125. )
  126. ) {
  127. $this->zModFlags[$name] = true;
  128. }
  129. }
  130. /**
  131. * Возвращает значение свойства
  132. *
  133. * @param string $name
  134. *
  135. * @return mixed
  136. */
  137. public function __get(string $name)
  138. {
  139. // без вычисления
  140. if (0 === \strpos($name, '__')) {
  141. return $this->getAttr(\substr($name, 2));
  142. // с вычислениями
  143. } else {
  144. return parent::__get($name);
  145. }
  146. }
  147. }