1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
4
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
5
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
6
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
7
|
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
8
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
9
|
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
10
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
11
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
12
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
13
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
14
|
|
|
* |
15
|
|
|
* This software consists of voluntary contributions made by many individuals |
16
|
|
|
* and is licensed under the MIT license. For more information, see |
17
|
|
|
* <http://www.doctrine-project.org>. |
18
|
|
|
*/ |
19
|
|
|
|
20
|
|
|
|
21
|
|
|
namespace Onurb\Doctrine\ORMMetadataGrapher\YumlMetadataGrapher; |
22
|
|
|
|
23
|
|
|
use Doctrine\Common\Persistence\Mapping\ClassMetadata; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Utility to generate yUML compatible strings from metadata graphs |
27
|
|
|
* |
28
|
|
|
* @license MIT |
29
|
|
|
* @link http://www.doctrine-project.org/ |
30
|
|
|
* @author Marco Pivetta <[email protected]> |
31
|
|
|
* @author Bruno Heron <<[email protected]> |
32
|
|
|
*/ |
33
|
|
|
class ClassStore implements ClassStoreInterface |
34
|
|
|
{ |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Indexed array of ClassMetadata and options |
38
|
|
|
* |
39
|
|
|
* @var array |
40
|
|
|
*/ |
41
|
|
|
private $indexedClasses = array(); |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* store metadata in an associated array to get classes |
45
|
|
|
* faster into $this->getClassByName() |
46
|
|
|
* |
47
|
|
|
* @param ClassMetadata[] $metadata |
48
|
|
|
*/ |
49
|
8 |
|
public function __construct($metadata) |
50
|
|
|
{ |
51
|
8 |
|
$this->indexClasses($metadata); |
52
|
8 |
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Retrieve a class metadata instance by name from the given array |
56
|
|
|
* |
57
|
|
|
* @param string $className |
58
|
|
|
* |
59
|
|
|
* @return ClassMetadata|null |
60
|
|
|
*/ |
61
|
3 |
|
public function getClassByName($className) |
62
|
|
|
{ |
63
|
3 |
|
$classMap = $this->getClassMap($this->splitClassName($className)) . "[\"__class\"]"; |
64
|
3 |
|
$return = null; |
65
|
|
|
|
66
|
|
|
eval( |
|
|
|
|
67
|
3 |
|
"if (isset(\$this->indexedClasses$classMap)) {" |
68
|
3 |
|
. " \$return = \$this->indexedClasses$classMap;" |
69
|
3 |
|
. "}" |
70
|
3 |
|
); |
71
|
|
|
|
72
|
3 |
|
return $return; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Retrieve a class metadata's parent class metadata |
77
|
|
|
* |
78
|
|
|
* @param ClassMetadata $class |
79
|
|
|
* |
80
|
|
|
* @return ClassMetadata|null |
81
|
|
|
*/ |
82
|
1 |
|
public function getParent(ClassMetadata $class) |
83
|
|
|
{ |
84
|
1 |
|
$className = $class->getName(); |
85
|
1 |
|
if (!class_exists($className) || (!$parent = get_parent_class($className))) { |
86
|
1 |
|
return null; |
87
|
|
|
} |
88
|
|
|
|
89
|
1 |
|
return $this->getClassByName($parent); |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* @return array |
94
|
|
|
*/ |
95
|
1 |
|
public function getIndexedClasses() |
96
|
|
|
{ |
97
|
1 |
|
return $this->indexedClasses; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* @param string $className |
102
|
|
|
* @return string |
103
|
|
|
*/ |
104
|
2 |
|
public function getClassColor($className) |
105
|
|
|
{ |
106
|
2 |
|
$splitName = $this->splitClassName($className); |
107
|
2 |
|
$color = null; |
108
|
|
|
|
109
|
|
|
do { |
110
|
2 |
|
$colorMap = $this->getClassMap($splitName) . "[\"__color\"]"; |
111
|
|
|
|
112
|
|
|
eval( |
|
|
|
|
113
|
2 |
|
"if (isset(\$this->indexedClasses$colorMap)) {" |
114
|
2 |
|
. "\$color = \$this->indexedClasses$colorMap;" |
115
|
2 |
|
. "}" |
116
|
2 |
|
); |
117
|
|
|
|
118
|
2 |
|
unset($splitName[count($splitName) - 1]); |
119
|
2 |
|
} while (null === $color && !empty($splitName)); |
120
|
|
|
|
121
|
2 |
|
return $color; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* @param array $colors |
126
|
|
|
*/ |
127
|
3 |
|
public function storeColors($colors) |
128
|
|
|
{ |
129
|
3 |
|
foreach ($colors as $namespace => $color) { |
130
|
3 |
|
$this->storeColor($namespace, $color); |
131
|
3 |
|
} |
132
|
3 |
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* @param array $classSplit |
136
|
|
|
* @return string |
137
|
|
|
*/ |
138
|
8 |
|
private function getClassMap($classSplit) |
139
|
|
|
{ |
140
|
8 |
|
return "[\"" . implode("\"][\"", $classSplit) . "\"]"; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* @param ClassMetadata[] $metadata |
145
|
|
|
*/ |
146
|
8 |
|
private function indexClasses($metadata) |
147
|
|
|
{ |
148
|
8 |
|
foreach ($metadata as $class) { |
149
|
8 |
|
$this->indexClass($class); |
150
|
8 |
|
} |
151
|
|
|
|
152
|
8 |
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* @param ClassMetadata $class |
156
|
|
|
*/ |
157
|
8 |
|
private function indexClass(ClassMetadata $class) |
158
|
|
|
{ |
159
|
8 |
|
$this->checkIndexAlreadyExists($class->getName()); |
160
|
|
|
|
161
|
8 |
|
$classMap = $this->getClassMap($this->splitClassName($class->getName())) . "[\"__class\"]"; |
162
|
|
|
|
163
|
|
|
eval( |
|
|
|
|
164
|
8 |
|
"\$this->indexedClasses$classMap = \$class;" |
165
|
8 |
|
); |
166
|
8 |
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* @param string $className |
170
|
|
|
* @return array |
171
|
|
|
*/ |
172
|
8 |
|
private function splitClassName($className) |
173
|
|
|
{ |
174
|
8 |
|
return explode('\\', $className); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* @param string $className |
179
|
|
|
*/ |
180
|
8 |
|
private function checkIndexAlreadyExists($className) |
181
|
|
|
{ |
182
|
8 |
|
$namespaces = $this->splitClassName($className); |
183
|
|
|
|
184
|
8 |
|
$tmpArrayMap = ""; |
185
|
|
|
|
186
|
8 |
|
foreach ($namespaces as $namespace) { |
187
|
8 |
|
$tmpArrayMap .="[\"$namespace\"]"; |
188
|
8 |
|
eval("if (!isset(\$this->indexedClasses$tmpArrayMap)) " |
|
|
|
|
189
|
8 |
|
. "{\$this->indexedClasses$tmpArrayMap = array(\"__class\" => null, \"__color\" => null);}"); |
190
|
8 |
|
} |
191
|
8 |
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* @param string $namespace |
195
|
|
|
* @param string $color |
196
|
|
|
*/ |
197
|
3 |
|
private function storeColor($namespace, $color) |
198
|
|
|
{ |
199
|
3 |
|
$this->checkIndexAlreadyExists($namespace); |
200
|
|
|
|
201
|
3 |
|
$colorMap = $this->getClassMap($this->splitClassName($namespace)) . "[\"__color\"]"; |
202
|
|
|
|
203
|
|
|
eval( |
|
|
|
|
204
|
3 |
|
"\$this->indexedClasses$colorMap = \"$color\";" |
205
|
3 |
|
); |
206
|
3 |
|
} |
207
|
|
|
} |
208
|
|
|
|
On one hand,
eval
might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM,eval
prevents some optimization that they perform.