Issues (1369)

classes/Common/AccessLoggedAbstract.php (1 issue)

1
<?php
2
/**
3
 * Created by Gorlum 14.11.2018 0:43
4
 */
5
6
namespace Common;
7
8
9
use Exception;
10
11
abstract class AccessLoggedAbstract extends AccessMagic {
12
  const ACCESS_SET = null;
13
  const ACCESS_DELTA_INC = +1;
14
  const ACCESS_DELTA_DEC = -1;
15
16
  /**
17
   * Starting values of properties
18
   *
19
   * @var array $_startValues
20
   */
21
  protected $_startValues = [];
22
  /**
23
   * Changed values
24
   *
25
   * @var array $_changes
26
   */
27
  protected $_changes = [];
28
  /**
29
   * Increment/Decrement results AKA deltas
30
   *
31
   * @var array $_deltas
32
   */
33
  protected $_deltas = [];
34
35
  /**
36
   * Current operation: direct store or positive/negative delta which would be applied on next __set() call
37
   *
38
   * @var int|float $_currentOperation
39
   */
40
  protected $_currentOperation = self::ACCESS_SET;
41
42
  public function clear() {
43
    parent::clear();
44
    $this->accept();
45
  }
46
47
  /**
48
   * @param string $name
49
   *
50
   * @throws Exception
51
   */
52
  protected function blockChange($name) {
53
    if (array_key_exists($name, $this->_deltas)) {
54
      throw new Exception(get_called_class() . '::' . $name . ' already INCREMENTED/DECREMENTED - can not CHANGE', ERR_ERROR);
55
    }
56
  }
57
58
  /**
59
   * @param string $name
60
   *
61
   * @throws Exception
62
   */
63
  protected function blockDelta($name) {
64
    if (array_key_exists($name, $this->_changes)) {
65
      throw new Exception(get_called_class() . '::' . $name . ' already changed - can not use DELTA', ERR_ERROR);
66
    }
67
  }
68
69
//  /**
70
//   * Stub to pass call down
71
//   *
72
//   * @param string $name
73
//   * @param mixed  $value
74
//   */
75
//  public function __set($name, $value) {
76
//    parent::__set($name, $value);
77
//  }
78
79
//  /**
80
//   * Stub to pass call down
81
//   *
82
//   * @param string $name
83
//   *
84
//   * @return mixed
85
//   */
86
//  public function __get($name) {
87
//    return parent::__get($name);
88
//  }
89
90
//  public function __set($name, $value) {
91
//    if ($this->_currentOperation === self::ACCESS_SET) {
92
//      $this->valueSet($name, $value);
93
//    } else {
94
//      $this->valueDelta($name, $value);
95
//    }
96
//  }
97
98
  /**
99
   * @param string $name
100
   * @param $value
101
   *
102
   * @throws Exception
103
   */
104
  abstract protected function valueSet($name, $value);
105
106
  /**
107
   * @param string $name
108
   * @param mixed $value
109
   *
110
   * @throws Exception
111
   */
112
  abstract protected function valueDelta($name, $value);
113
114
115
    /**
116
   * Mark next set operation as delta increment
117
   *
118
   * @return $this
119
   */
120
  public function inc() {
121
    $this->_currentOperation = self::ACCESS_DELTA_INC;
122
123
    return $this;
124
  }
125
126
  /**
127
   * Mark next set operation as delta decrement
128
   *
129
   * @return $this
130
   */
131
  public function dec() {
132
    $this->_currentOperation = self::ACCESS_DELTA_DEC;
133
134
    return $this;
135
  }
136
137
  /**
138
   * Accepts changes
139
   *
140
   * Makes current values a start one and resets changes/deltas
141
   */
142
  public function accept() {
143
    $this->_startValues      = $this->values;
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->values can also be of type \ArrayObject. However, the property $_startValues is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
144
    $this->_currentOperation = self::ACCESS_SET;
145
    $this->_changes          = [];
146
    $this->_deltas           = [];
147
  }
148
149
  /**
150
   * Rolls changes back
151
   */
152
  public function reject() {
153
    $this->values            = $this->_startValues;
154
    $this->_currentOperation = self::ACCESS_SET;
155
    $this->_changes          = [];
156
    $this->_deltas           = [];
157
  }
158
159
  /**
160
   * Is container was changed?
161
   *
162
   * @return bool
163
   */
164
  public function isChanged() {
165
    return
166
      ! empty($this->_changes)
167
      ||
168
      ! empty($this->_deltas);
169
  }
170
171
  public function getChanges() {
172
    return $this->_changes;
173
  }
174
175
  public function getDeltas() {
176
    return $this->_deltas;
177
  }
178
179
}
180