Completed
Push — work-fleets ( a017ed...86976e )
by SuperNova.WS
06:16
created

PropertyHider::setProperties()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
3
/**
4
 * Class PropertyHider
5
 *
6
 * Hides properties from visibility
7
 */
8
class PropertyHider extends stdClass {
9
10
  /**
11
   * Property list
12
   *
13
   * @var array[]
14
   */
15
  protected static $_properties = array();
16
17
  /**
18
   * List of property names that was changed since last DB operation
19
   *
20
   * @var string[]
21
   */
22
  protected $propertiesChanged = array();
23
  /**
24
   * List of property names->$delta that was adjusted since last DB operation - and then need to be processed as Deltas
25
   *
26
   * @var string[]
27
   */
28
  protected $propertiesAdjusted = array();
29
30
  /**
31
   * @param array $properties
32
   */
33 1
  public static function setProperties($properties) {
34
    // TODO - reset internals??
35 1
    static::$_properties = $properties;
36 1
  }
37
38 1
  public static function getProperties() {
39 1
    return static::$_properties;
40
  }
41
42
  /**
43
   * PropertyHider constructor.
44
   */
45 1
  public function __construct() {
46 1
  }
47
48
//  protected function checkForGetSet($name, $left3) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
49
//    // If method is not getter or setter OR property name not exists in $_properties - raising exception
50
//    // Descendants can catch this Exception to make own __call magic
51
//    if ($left3 != 'get' && $left3 != 'set') {
52
//      throw new ExceptionNotGetterOrSetter('Magic call is not getter or setter ' . get_called_class() . '::' . $name, ERR_ERROR);
53
//    }
54
//  }
55
//
56
//  protected function checkForPropertyExists($name, $propertyName) {
57
//    if (empty(static::$_properties[$propertyName])) {
58
//      throw new ExceptionPropertyNotExists('Property ' . $propertyName . ' not exists when calling getter/setter ' . get_called_class() . '::' . $name, ERR_ERROR);
59
//    }
60
//  }
61
62
//  protected function checkForDoubleAdjust($name, $left3, $propertyName) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
63
//    if ($left3 == 'set' && array_key_exists($propertyName, $this->propertiesAdjusted)) {
64
//      throw new PropertyAccessException('Property ' . $propertyName . ' already was adjusted so no SET is possible until dbSave in ' . get_called_class() . '::' . $name, ERR_ERROR);
65
//    }
66
//  }
67
68
//  /**
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
69
//   * Handles getters and setters
70
//   *
71
//   * @param string $name
72
//   * @param array  $arguments
73
//   *
74
//   * @return mixed
75
//   * @throws ExceptionNotGetterOrSetter
76
//   * @throws ExceptionPropertyNotExists
77
//   * @throws PropertyAccessException
78
//   */
79
//  protected function callGetSet($name, $arguments) {
80
//    $this->checkForGetSet($name, $left3 = substr($name, 0, 3));
81
//    $this->checkForPropertyExists($name, $propertyName = lcfirst(substr($name, 3)));
82
//    // TODO check for read-only
83
//    $this->checkForDoubleAdjust($name, $left3, $propertyName);
84
//
85
//    $result = null;
86
//
87
//    // Now deciding - will we call a protected setter or will we work with protected property
88
//    if (method_exists($this, $name)) {
89
//      // If method exists - just calling it
90
//      $result = call_user_func_array(array($this, $name), $arguments);
91
//    } else {
92
//      // No getter/setter exists - works directly with protected property
93
//      if ($left3 === 'set') {
94
//        $this->{'_' . $propertyName} = $arguments[0];
95
//      } elseif ($left3 === 'get') {
96
//        $result = $this->{'_' . $propertyName};
97
//      }
98
//    }
99
//
100
//    if ($left3 === 'set') {
101
//      $this->propertiesChanged[$propertyName] = true;
102
//    }
103
//
104
//    return $result;
105
//  }
106
107
//  public function __call($name, $arguments) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
108
//    $this->callGetSet($name, $arguments);
109
//  }
110
111 5
  protected function checkPropertyExists($name) {
112 5
    if (!array_key_exists($name, static::$_properties)) {
113 2
      throw new ExceptionPropertyNotExists('Property [' . get_called_class() . '::' . $name . '] not exists when accessing via __get/__set', ERR_ERROR);
114
    }
115 3
  }
116
117 3
  protected function checkOverwriteAdjusted($name) {
118 3
    if (array_key_exists($name, $this->propertiesAdjusted)) {
119 1
      throw new PropertyAccessException('Property [' . get_called_class() . '::' . $name . '] already was adjusted so no SET is possible until dbSave', ERR_ERROR);
120
    }
121 2
  }
122
123
124
  /**
125
   * Getter with support of protected methods
126
   *
127
   * @param $name
128
   *
129
   * @return mixed
130
   * @throws ExceptionPropertyNotExists
131
   */
132 4 View Code Duplication
  public function __get($name) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
133 4
    $this->checkPropertyExists($name);
134
135 3
    $result = null;
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
136
    // Now deciding - will we call a protected setter or will we work with protected property
137 3
    if (method_exists($this, $methodName = 'get' . ucfirst($name))) {
138
      // If method exists - just calling it
139 2
      $result = call_user_func_array(array($this, $methodName), array());
140 3
    } elseif (property_exists($this, $propertyName = '_' . $name)) {
141
      // No getter exists - works directly with protected property
142 2
      $result = $this->$propertyName;
143 2
    } else {
144 1
      throw new ExceptionPropertyNotExists('Property [' . get_called_class() . '::' . $name . '] does not have getter/property to get', ERR_ERROR);
145
    }
146
147 2
    return $result;
148
  }
149
150
  /**
151
   * Real setter function
152
   *
153
   * @param string $name
154
   * @param mixed  $value
155
   *
156
   * @return mixed|null
157
   * @throws ExceptionPropertyNotExists
158
   */
159 4 View Code Duplication
  protected function ___set($name, $value) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
160 4
    $result = null;
161
    // Now deciding - will we call a protected setter or will we work with protected property
162 4
    if (method_exists($this, $methodName = 'set' . ucfirst($name))) {
163
      // If method exists - just calling it
164
      // TODO - should return TRUE if value changed or FALSE otherwise
165 2
      $result = call_user_func_array(array($this, $methodName), array($value));
166 4
    } elseif (property_exists($this, $propertyName = '_' . $name)) {
167
      // No setter exists - works directly with protected property
168 3
      $this->$propertyName = $value;
169 3
    } else {
170 1
      throw new ExceptionPropertyNotExists('Property [' . get_called_class() . '::' . $name . '] does not have setter/property to set', ERR_ERROR);
171
    }
172
173
    // TODO - should be primed only if value changed
174 3
    $this->propertiesChanged[$name] = true;
175
176 3
    return $result;
177
  }
178
179
  /**
180
   * Setter wrapper with support of protected properties/methods
181
   *
182
   * @param string $name
183
   * @param mixed  $value
184
   *
185
   * @return mixed|null
186
   * @throws ExceptionPropertyNotExists
187
   */
188
  // TODO - сеттер должен параллельно изменять значение db_row - for now...
189
  // TODO - Проверка, а действительно ли данные были изменены?? Понадобится определение типов - разные типы сравниваются по-разному
190 4
  public function __set($name, $value) {
191 4
    $this->checkPropertyExists($name);
192 3
    $this->checkOverwriteAdjusted($name);
193
194 2
    $result = $this->___set($name, $value);
195
196 1
    return $result;
197
  }
198
199
  /**
200
   * Adjust property value with $diff
201
   * Adjusted values put into DB with UPDATE query
202
   * Adjuster callback adjXXX() should return new value which will be propagated via ___set()
203
   *
204
   * @param string $name
205
   * @param mixed  $diff
206
   *
207
   * @return mixed
208
   */
209 1
  public function __adjust($name, $diff) {
210 1
    $this->checkPropertyExists($name);
211
212
    // Now deciding - will we call a protected setter or will we work with protected property
213 1
    if (method_exists($this, $methodName = 'adj' . ucfirst($name))) {
214
      // If method exists - just calling it
215
      // TODO - should return TRUE if value changed or FALSE otherwise
216 1
      $newValue = call_user_func_array(array($this, $methodName), array($diff));
217 1
    } else {
218
      // No adjuster exists - works directly with protected property
219
      // TODO - property type checks
220 1
      $newValue = $this->$name + $diff;
221
    }
222
223 1
    $this->___set($name, $newValue);
224
225 1
    if (!array_key_exists($name, $this->propertiesAdjusted)) {
226 1
      $this->propertiesAdjusted[$name] = null;
227 1
    }
228
229 1
    $this->propertiesAdjusted[$name] += $diff;
230
231 1
    return $this->$name;
232
  }
233
234
}
235