1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* PHP: Nelson Martell Library file |
4
|
|
|
* |
5
|
|
|
* Content: |
6
|
|
|
* - Class definition: [NelsonMartell] Object |
7
|
|
|
* |
8
|
|
|
* Copyright © 2014-2017 Nelson Martell (http://nelson6e65.github.io) |
9
|
|
|
* |
10
|
|
|
* Licensed under The MIT License (MIT) |
11
|
|
|
* For full copyright and license information, please see the LICENSE |
12
|
|
|
* Redistributions of files must retain the above copyright notice. |
13
|
|
|
* |
14
|
|
|
* @copyright 2014-2017 Nelson Martell |
15
|
|
|
* @link http://nelson6e65.github.io/php_nml/ |
16
|
|
|
* @since v0.1.1 |
17
|
|
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License (MIT) |
18
|
|
|
* */ |
19
|
|
|
|
20
|
|
|
namespace NelsonMartell; |
21
|
|
|
|
22
|
|
|
use \BadMethodCallException; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* Base class that encapsulates strict properties and other basic features. |
26
|
|
|
* |
27
|
|
|
* |
28
|
|
|
* @author Nelson Martell <[email protected]> |
29
|
|
|
* @see PropertiesHandler |
30
|
|
|
* */ |
31
|
|
|
class Object implements IComparer, IStrictPropertiesContainer, IConvertibleToString |
32
|
|
|
{ |
33
|
|
|
use PropertiesHandler; |
34
|
|
|
|
35
|
257 |
|
public function __construct() |
36
|
|
|
{ |
37
|
257 |
|
} |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Convierte esta instancia en su representación de cadena. |
41
|
|
|
* Para modificar el funcionamiento de esta función, debe reemplazarse |
42
|
|
|
* la función ObjectClass::toString() |
43
|
|
|
* |
44
|
|
|
* @return string |
45
|
|
|
* @see Object::toString() |
46
|
|
|
* */ |
47
|
35 |
|
final public function __toString() |
48
|
|
|
{ |
49
|
|
|
//$args = null; |
|
|
|
|
50
|
|
|
//list($args) = func_get_args(); |
|
|
|
|
51
|
35 |
|
return $this->toString(); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Convierte la instancia actual en su representación de cadena. |
56
|
|
|
* |
57
|
|
|
* @return string |
58
|
|
|
* */ |
59
|
|
|
public function toString() |
60
|
|
|
{ |
61
|
|
|
$type = typeof($this); |
62
|
|
|
|
63
|
|
|
if (defined('CODE_ANALYSIS')) { |
64
|
|
|
if ($type->Name != 'NelsonMartell\Object') { |
65
|
|
|
$args = [ |
66
|
|
|
'access' => 'public', |
67
|
|
|
'base_class' => __CLASS__, |
68
|
|
|
'class' => $type->Name, |
69
|
|
|
'function' => __FUNCTION__, |
70
|
|
|
]; |
71
|
|
|
|
72
|
|
|
$msg = msg('Using default "{base_class}::{function}" ({access}) method.', $args); |
|
|
|
|
73
|
|
|
$msg .= msg( |
74
|
|
|
' You can replace (override) its behavior by creating "{class}::{function}" ({access}) method.', |
75
|
|
|
$args |
76
|
|
|
); |
77
|
|
|
|
78
|
|
|
trigger_error($msg, E_USER_NOTICE); |
79
|
|
|
} |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
return '{ '.$type.' }'; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
public function equals($other) |
86
|
|
|
{ |
87
|
|
|
if (defined('CODE_ANALYSIS')) { |
88
|
|
|
if ($this instanceof IEquatable) { |
89
|
|
|
$type = typeof($this); |
90
|
|
|
|
91
|
|
|
$args = [ |
92
|
|
|
'access' => 'public', |
93
|
|
|
'base_class' => __CLASS__, |
94
|
|
|
'class' => $type->Name, |
95
|
|
|
'function' => __FUNCTION__, |
96
|
|
|
]; |
97
|
|
|
|
98
|
|
|
$msg = msg( |
99
|
|
|
'You implemented IEquatable, but using default "{base_class}::{function}" ({access}) method.', |
100
|
|
|
$args |
101
|
|
|
); |
102
|
|
|
|
103
|
|
|
$msg .= msg( |
104
|
|
|
' You can replace (override) its behavior by creating "{class}::{function}" ({access}) method.', |
105
|
|
|
$args |
106
|
|
|
); |
107
|
|
|
|
108
|
|
|
trigger_error($msg, E_USER_NOTICE); |
109
|
|
|
} |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
return $this == $other; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Determina la posición relativa del objeto de la izquierda con respecto al de la derecha. |
117
|
|
|
* |
118
|
|
|
* Compatible with, strings, integers, boolean, arrays and classes implementing ``IComparable`` interface. |
119
|
|
|
* |
120
|
|
|
* Puede usarse como segundo argumento en la función de ordenamiento de |
121
|
|
|
* arrays 'usort'. |
122
|
|
|
* |
123
|
|
|
* Notes: |
124
|
|
|
* - Comparison is made in natural way if they are of the same type. If not, is used the PHP standard |
125
|
|
|
* comparison. |
126
|
|
|
* - If ``$left`` and ``$right`` are arrays, comparison is made by first by 'key' (as strings) and then by |
127
|
|
|
* 'values' (using this method recursively). |
128
|
|
|
* |
129
|
|
|
* # Override |
130
|
|
|
* You can override this method to implement a contextual sorting behaviour for ``usort()`` function. |
131
|
|
|
* If you only need to compare instances of your class with other objects, implement |
132
|
|
|
* ``NelsonMartell\IComparable`` instead. |
133
|
|
|
* |
134
|
|
|
* @param mixed $left Left object. |
135
|
|
|
* @param mixed $right Right object. |
136
|
|
|
* |
137
|
|
|
* @return integer|null |
138
|
|
|
* Returns: |
139
|
|
|
* - ``= 0`` if $left is considered equivalent to $other; |
140
|
|
|
* - ``> 0`` if $left is considered greater than $other; |
141
|
|
|
* - ``< 0`` if $left is considered less than $other; |
142
|
|
|
* - ``null`` if $left can't be compared to $other . |
143
|
|
|
* @see IComparer::compare() |
144
|
|
|
* @see IComparable::compareTo() |
145
|
|
|
* @see \strnatcmp() |
146
|
|
|
* @see \usort() |
147
|
|
|
* */ |
148
|
41 |
|
public static function compare($left, $right) |
149
|
|
|
{ |
150
|
41 |
|
$r = null; |
|
|
|
|
151
|
|
|
|
152
|
41 |
|
if ($left instanceof IComparable) { |
153
|
7 |
|
$r = $left->compareTo($right); |
154
|
36 |
|
} elseif ($right instanceof IComparable) { |
155
|
13 |
|
$r = $right->compareTo($left); |
156
|
|
|
|
157
|
13 |
|
if ($r !== null) { |
158
|
12 |
|
$r *= -1; // Invert result |
159
|
|
|
} |
160
|
|
|
} else { |
161
|
27 |
|
$ltype = typeof($left); |
162
|
27 |
|
$rtype = typeof($right); |
163
|
|
|
|
164
|
|
|
// If they are of the same type. |
165
|
27 |
|
if ($ltype->Name === $rtype->Name) { |
166
|
27 |
|
switch ($ltype->Name) { |
167
|
27 |
|
case 'string': |
168
|
12 |
|
$r = strnatcmp($left, $right); |
169
|
12 |
|
break; |
170
|
|
|
|
171
|
19 |
|
case 'boolean': |
172
|
1 |
|
$r = (int) $left - (int) $right; |
173
|
1 |
|
break; |
174
|
|
|
|
175
|
19 |
|
case 'integer': |
176
|
9 |
|
$r = $left - $right; |
177
|
9 |
|
break; |
178
|
|
|
|
179
|
10 |
|
case 'float': |
180
|
10 |
|
case 'double': |
181
|
|
|
$r = (int) ceil($left - $right); |
182
|
|
|
break; |
183
|
|
|
|
184
|
10 |
|
case 'array': |
185
|
8 |
|
$r = count($left) - count($right); |
186
|
|
|
|
187
|
8 |
|
if ($r === 0) { |
188
|
4 |
|
reset($left); |
189
|
4 |
|
reset($right); |
190
|
|
|
|
191
|
|
|
do { |
192
|
4 |
|
$lKey = key($left); |
|
|
|
|
193
|
4 |
|
$lValue = current($left); |
194
|
4 |
|
$rKey = key($right); |
|
|
|
|
195
|
4 |
|
$rValue = current($right); |
196
|
|
|
|
197
|
4 |
|
$r = static::compare((string) $lKey, (string) $rKey); |
198
|
|
|
|
199
|
4 |
|
if ($r === 0) { |
200
|
|
|
// Recursive call to compare values |
201
|
3 |
|
$r = static::compare($lValue, $rValue); |
202
|
|
|
} |
203
|
4 |
|
} while (each($left) && each($right) && $r === 0); |
204
|
|
|
} |
205
|
8 |
|
break; |
206
|
|
|
|
207
|
|
|
default: |
208
|
2 |
|
if ($left == $right) { |
209
|
1 |
|
$r = 0; |
210
|
|
|
} else { |
211
|
27 |
|
$r = ($left > $right) ? +1 : -1; |
212
|
|
|
} |
213
|
|
|
} |
214
|
|
|
} else { |
215
|
|
|
if ($left == $right) { |
216
|
|
|
$r = 0; |
217
|
|
|
} elseif ($left > $right) { |
218
|
|
|
$r = 1; |
219
|
|
|
} elseif ($left < $right) { |
220
|
|
|
$r = -1; |
221
|
|
|
} else { |
222
|
|
|
// If can't determinate, retuns null |
223
|
|
|
$r = null; |
224
|
|
|
} |
225
|
|
|
} |
226
|
|
|
} |
227
|
|
|
|
228
|
41 |
|
return $r; |
229
|
|
|
} |
230
|
|
|
} |
231
|
|
|
|
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.