1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Phossa Project |
4
|
|
|
* |
5
|
|
|
* PHP version 5.4 |
6
|
|
|
* |
7
|
|
|
* @category Library |
8
|
|
|
* @package Phossa2\Shared |
9
|
|
|
* @copyright Copyright (c) 2016 phossa.com |
10
|
|
|
* @license http://mit-license.org/ MIT License |
11
|
|
|
* @link http://www.phossa.com/ |
12
|
|
|
*/ |
13
|
|
|
/*# declare(strict_types=1); */ |
14
|
|
|
|
15
|
|
|
namespace Phossa2\Shared\Reference; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* ReferenceTrait |
19
|
|
|
* |
20
|
|
|
* Provides reference & dereference methods |
21
|
|
|
* |
22
|
|
|
* @package Phossa2\Shared |
23
|
|
|
* @author Hong Zhang <[email protected]> |
24
|
|
|
* @see ReferenceInterface |
25
|
|
|
* @version 2.0.4 |
26
|
|
|
* @since 2.0.4 added |
27
|
|
|
*/ |
28
|
|
|
trait ReferenceTrait |
29
|
|
|
{ |
30
|
|
|
/** |
31
|
|
|
* refernece start chars |
32
|
|
|
* |
33
|
|
|
* @var string |
34
|
|
|
* @access protected |
35
|
|
|
*/ |
36
|
|
|
protected $ref_start = '${'; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* reference ending chars |
40
|
|
|
* |
41
|
|
|
* @var string |
42
|
|
|
* @access protected |
43
|
|
|
*/ |
44
|
|
|
protected $ref_end = '}'; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* pattern to match |
48
|
|
|
* |
49
|
|
|
* @var string |
50
|
|
|
* @access protected |
51
|
|
|
*/ |
52
|
|
|
protected $ref_pattern; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* unresolved reference |
56
|
|
|
* |
57
|
|
|
* @var array |
58
|
|
|
* @access protected |
59
|
|
|
*/ |
60
|
|
|
protected $unresolved = []; |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* {@inheritDoc} |
64
|
|
|
*/ |
65
|
|
|
public function setReference( |
66
|
|
|
/*# string */ $start, |
67
|
|
|
/*# string */ $end |
68
|
|
|
) { |
69
|
|
|
$this->ref_start = $start; |
70
|
|
|
$this->ref_end = $end; |
71
|
|
|
|
72
|
|
|
// build pattern |
73
|
|
|
$s = preg_quote($start); |
74
|
|
|
$e = preg_quote($end); |
75
|
|
|
$this->ref_pattern = sprintf( |
76
|
|
|
"~(%s((?:(?!%s|%s).)+?)%s)~", $s, $s, $e, $e |
77
|
|
|
); |
78
|
|
|
|
79
|
|
|
return $this; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* {@inheritDoc} |
84
|
|
|
*/ |
85
|
|
|
public function hasReference( |
86
|
|
|
/*# string */ $subject, |
87
|
|
|
array &$matched |
88
|
|
|
)/*# : bool */ { |
89
|
|
|
$m = []; |
90
|
|
|
if (is_string($subject) && |
91
|
|
|
false !== strpos($subject, $this->ref_start) && |
92
|
|
|
preg_match($this->ref_pattern, $subject, $m) |
93
|
|
|
) { |
94
|
|
|
$matched[$m[1]] = $m[2]; |
95
|
|
|
return true; |
96
|
|
|
} |
97
|
|
|
return false; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* {@inheritDoc} |
102
|
|
|
*/ |
103
|
|
|
public function deReference(/*# string */ $subject) |
104
|
|
|
{ |
105
|
|
|
$loop = 0; |
106
|
|
|
$matched = []; |
107
|
|
|
while ($this->hasReference($subject, $matched)) { |
108
|
|
|
// resolving |
109
|
|
|
$val = $this->resolveReference($matched[1]); |
110
|
|
|
|
111
|
|
|
// loop found |
112
|
|
|
if ($loop++ > 10) { |
|
|
|
|
113
|
|
|
// throw exception |
114
|
|
|
|
115
|
|
|
// matched whole target |
116
|
|
|
} elseif ($matched[0] === $subject) { |
117
|
|
|
return $val; |
118
|
|
|
|
119
|
|
|
// partial matched |
120
|
|
|
} elseif (is_string($val)) { |
121
|
|
|
$subject = str_replace($matched[0], $val, $subject); |
122
|
|
|
|
123
|
|
|
// malformed target |
124
|
|
|
} else { |
|
|
|
|
125
|
|
|
// throw exception |
126
|
|
|
} |
127
|
|
|
} |
128
|
|
|
return $subject; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Resolve the reference $name |
133
|
|
|
* |
134
|
|
|
* @param string $name |
135
|
|
|
* @return mixed |
136
|
|
|
* @access protected |
137
|
|
|
*/ |
138
|
|
|
protected function resolveReference(/*# string */ $name) |
139
|
|
|
{ |
140
|
|
|
$val = $this->getReference($name); |
141
|
|
|
|
142
|
|
|
// not found |
143
|
|
|
if (is_null($val)) { |
144
|
|
|
$this->unresolved[$name] = true; |
145
|
|
|
return $this->resolveUnknown($name); |
146
|
|
|
|
147
|
|
|
// found it |
148
|
|
|
} else { |
149
|
|
|
return $val; |
150
|
|
|
} |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* For unknown reference $name, NEED OVERLOAD |
155
|
|
|
* |
156
|
|
|
* @param string $name |
157
|
|
|
* @return mixed |
158
|
|
|
* @access protected |
159
|
|
|
*/ |
160
|
|
|
protected function resolveUnknown(/*# string */ $name) |
|
|
|
|
161
|
|
|
{ |
162
|
|
|
return ''; |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* The real resolving method. return NULL for unknown reference |
167
|
|
|
* |
168
|
|
|
* @param string $name |
169
|
|
|
* @return mixed |
170
|
|
|
* @access protected |
171
|
|
|
*/ |
172
|
|
|
abstract protected function getReference(/*# string */ $name); |
173
|
|
|
} |
174
|
|
|
|
This check looks for the bodies of
if
statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.These
if
bodies can be removed. If you have an empty if but statements in theelse
branch, consider inverting the condition.could be turned into
This is much more concise to read.