1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Created by PhpStorm. |
4
|
|
|
* User: VITALYIEGOROV |
5
|
|
|
* Date: 09.12.15 |
6
|
|
|
* Time: 14:34 |
7
|
|
|
*/ |
8
|
|
|
namespace samsoncms\api; |
9
|
|
|
|
10
|
|
|
use samsonframework\orm\DatabaseInterface; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Entity classes generator. |
14
|
|
|
* @package samsoncms\api |
15
|
|
|
*/ |
16
|
|
|
class Generator |
17
|
|
|
{ |
18
|
|
|
/** @var DatabaseInterface */ |
19
|
|
|
protected $database; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Transliterate string to english. |
23
|
|
|
* |
24
|
|
|
* @param string $string Source string |
25
|
|
|
* @return string Transliterated string |
26
|
|
|
*/ |
27
|
|
|
protected function transliterated($string) |
28
|
|
|
{ |
29
|
|
|
return str_replace( |
30
|
|
|
' ', |
31
|
|
|
'', |
32
|
|
|
ucwords(iconv("UTF-8", "UTF-8//IGNORE", strtr($string, array( |
33
|
|
|
"'" => "", |
34
|
|
|
"`" => "", |
35
|
|
|
"-" => " ", |
36
|
|
|
"_" => " ", |
37
|
|
|
"а" => "a", "А" => "a", |
38
|
|
|
"б" => "b", "Б" => "b", |
39
|
|
|
"в" => "v", "В" => "v", |
40
|
|
|
"г" => "g", "Г" => "g", |
41
|
|
|
"д" => "d", "Д" => "d", |
42
|
|
|
"е" => "e", "Е" => "e", |
43
|
|
|
"ж" => "zh", "Ж" => "zh", |
44
|
|
|
"з" => "z", "З" => "z", |
45
|
|
|
"и" => "i", "И" => "i", |
46
|
|
|
"й" => "y", "Й" => "y", |
47
|
|
|
"к" => "k", "К" => "k", |
48
|
|
|
"л" => "l", "Л" => "l", |
49
|
|
|
"м" => "m", "М" => "m", |
50
|
|
|
"н" => "n", "Н" => "n", |
51
|
|
|
"о" => "o", "О" => "o", |
52
|
|
|
"п" => "p", "П" => "p", |
53
|
|
|
"р" => "r", "Р" => "r", |
54
|
|
|
"с" => "s", "С" => "s", |
55
|
|
|
"т" => "t", "Т" => "t", |
56
|
|
|
"у" => "u", "У" => "u", |
57
|
|
|
"ф" => "f", "Ф" => "f", |
58
|
|
|
"х" => "h", "Х" => "h", |
59
|
|
|
"ц" => "c", "Ц" => "c", |
60
|
|
|
"ч" => "ch", "Ч" => "ch", |
61
|
|
|
"ш" => "sh", "Ш" => "sh", |
62
|
|
|
"щ" => "sch", "Щ" => "sch", |
63
|
|
|
"ъ" => "", "Ъ" => "", |
64
|
|
|
"ы" => "y", "Ы" => "y", |
65
|
|
|
"ь" => "", "Ь" => "", |
66
|
|
|
"э" => "e", "Э" => "e", |
67
|
|
|
"ю" => "yu", "Ю" => "yu", |
68
|
|
|
"я" => "ya", "Я" => "ya", |
69
|
|
|
"і" => "i", "І" => "i", |
70
|
|
|
"ї" => "yi", "Ї" => "yi", |
71
|
|
|
"є" => "e", "Є" => "e" |
72
|
|
|
) |
73
|
|
|
) |
74
|
|
|
) |
75
|
|
|
) |
76
|
|
|
); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* Get class constant name by its value. |
81
|
|
|
* |
82
|
|
|
* @param string $value Constant value |
83
|
|
|
* @param string $className Class name |
84
|
|
|
* @return string Full constant name |
85
|
|
|
*/ |
86
|
|
|
protected function constantNameByValue($value, $className = Field::ENTITY) |
87
|
|
|
{ |
88
|
|
|
// Get array where class constants are values and their values are keys |
89
|
|
|
$nameByValue = array_flip((new \ReflectionClass($className))->getConstants()); |
90
|
|
|
|
91
|
|
|
// Try to find constant by its value |
92
|
|
|
if (isset($nameByValue[$value])) { |
93
|
|
|
// Return constant name |
94
|
|
|
return '\\' . $className . '::' . $nameByValue[$value]; |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* Create entity PHP class code. |
100
|
|
|
* |
101
|
|
|
* @param array $structureRow Collection of structure info |
102
|
|
|
* @return string Generated entitiy class code |
103
|
|
|
*/ |
104
|
|
View Code Duplication |
protected function createEntityClass($structureRow) |
|
|
|
|
105
|
|
|
{ |
106
|
|
|
$structureKey = ucfirst($this->transliterated($structureRow['Name'])); |
107
|
|
|
|
108
|
|
|
$class = "\n" . 'class ' . $structureKey . ' extends Entity'; |
109
|
|
|
$class .= "\n" . '{'; |
110
|
|
|
$class .= "\n\t" . '/** @var string Not transliterated entity name */'; |
111
|
|
|
$class .= "\n\t" . 'protected $identifier = "' . $structureRow['Name'] . '";'; |
112
|
|
|
|
113
|
|
|
// Get structure fields |
114
|
|
|
//$fieldMap = array(); |
115
|
|
|
$fields = array(); |
116
|
|
|
$fieldIDs = array(); |
117
|
|
|
|
118
|
|
|
// TODO: Optimize queries |
119
|
|
|
foreach ($this->database->fetch('SELECT * FROM `structurefield` WHERE `StructureID` = "' . $structureRow['StructureID'] . '" AND `Active` = "1"') as $fieldStructureRow) { |
120
|
|
|
foreach ($this->database->fetch('SELECT * FROM `field` WHERE `FieldID` = "' . $fieldStructureRow['FieldID'] . '"') as $fieldRow) { |
121
|
|
|
$type = str_replace( |
|
|
|
|
122
|
|
|
'\samsoncms\api\Field', |
123
|
|
|
'Field', |
124
|
|
|
$this->constantNameByValue($fieldRow['Type']) |
125
|
|
|
); |
126
|
|
|
$commentType = Field::$PHP_TYPE[$fieldRow['Type']]; |
127
|
|
|
$fieldName = lcfirst($this->transliterated($fieldRow['Name'])); |
128
|
|
|
|
129
|
|
|
$class .= "\n\t" . '/** @var ' . $commentType . ' Field #' . $fieldRow['FieldID'] . '*/'; |
130
|
|
|
$class .= "\n\t" . 'protected $' . $fieldName . ';'; |
131
|
|
|
|
132
|
|
|
// Store field metadata |
133
|
|
|
$fields[$fieldName][] = $fieldRow; |
134
|
|
|
$fieldIDs[] = $fieldRow['FieldID']; |
135
|
|
|
//$fieldMap[] = '"'.$fieldName.'" => array("Id" => "'.$fieldRow['FieldID'].'", "Type" => ' . $type . ', "Name" => "' . $fieldRow['Name'] . '")'; |
136
|
|
|
} |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
//$class .= "\n\t" . '/** @var array Entity additional fields metadata */'; |
140
|
|
|
//$class .= "\n\t" .'protected $fieldsData = array('."\n\t\t".implode(','."\n\t\t", $fieldMap)."\n\t".');'; |
141
|
|
|
$class .= "\n\t"; |
142
|
|
|
$class .= "\n\t" . '/** @var array Collection of additional fields identifiers */'; |
143
|
|
|
$class .= "\n\t" . 'protected static $fieldIDs = array(' . implode(',', $fieldIDs) . ');'; |
144
|
|
|
$class .= "\n\t" . '/** @var array Collection of navigation identifiers */'; |
145
|
|
|
$class .= "\n\t" . 'protected static $navigationIDs = array(' . $structureRow['StructureID'] . ');'; |
146
|
|
|
$class .= "\n" . '}'; |
147
|
|
|
|
148
|
|
|
// Replace tabs with spaces |
149
|
|
|
return str_replace("\t", ' ', $class); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* Create entity PHP class code. |
154
|
|
|
* |
155
|
|
|
* @param array $structureRow Collection of structure info |
156
|
|
|
* @return string Generated entitiy class code |
157
|
|
|
*/ |
158
|
|
View Code Duplication |
protected function createQueryClass($structureRow) |
|
|
|
|
159
|
|
|
{ |
160
|
|
|
$structureKey = ucfirst($this->transliterated($structureRow['Name'])); |
161
|
|
|
|
162
|
|
|
$class = "\n" . 'class ' . $structureKey . ' extends Base'; |
163
|
|
|
$class .= "\n" . '{'; |
164
|
|
|
$class .= "\n\t" . '/** @var string Not transliterated entity name */'; |
165
|
|
|
$class .= "\n\t" . 'protected $identifier = "' . $structureRow['Name'] . '";'; |
166
|
|
|
|
167
|
|
|
// Get structure fields |
168
|
|
|
//$fieldMap = array(); |
169
|
|
|
$fields = array(); |
170
|
|
|
$fieldIDs = array(); |
171
|
|
|
|
172
|
|
|
// TODO: Optimize queries |
173
|
|
|
foreach ($this->database->fetch('SELECT * FROM `structurefield` WHERE `StructureID` = "' . $structureRow['StructureID'] . '" AND `Active` = "1"') as $fieldStructureRow) { |
174
|
|
|
foreach ($this->database->fetch('SELECT * FROM `field` WHERE `FieldID` = "' . $fieldStructureRow['FieldID'] . '"') as $fieldRow) { |
175
|
|
|
$type = str_replace( |
|
|
|
|
176
|
|
|
'\samsoncms\api\Field', |
177
|
|
|
'Field', |
178
|
|
|
$this->constantNameByValue($fieldRow['Type']) |
179
|
|
|
); |
180
|
|
|
$commentType = Field::$PHP_TYPE[$fieldRow['Type']]; |
181
|
|
|
$fieldName = lcfirst($this->transliterated($fieldRow['Name'])); |
182
|
|
|
|
183
|
|
|
$class .= "\n\t" . '/** @var ' . $commentType . ' Field #' . $fieldRow['FieldID'] . '*/'; |
184
|
|
|
$class .= "\n\t" . 'protected $' . $fieldName . ';'; |
185
|
|
|
|
186
|
|
|
// Store field metadata |
187
|
|
|
$fields[$fieldName][] = $fieldRow; |
188
|
|
|
$fieldIDs[] = $fieldRow['FieldID']; |
189
|
|
|
//$fieldMap[] = '"'.$fieldName.'" => array("Id" => "'.$fieldRow['FieldID'].'", "Type" => ' . $type . ', "Name" => "' . $fieldRow['Name'] . '")'; |
190
|
|
|
} |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
//$class .= "\n\t" . '/** @var array Entity additional fields metadata */'; |
194
|
|
|
//$class .= "\n\t" .'protected $fieldsData = array('."\n\t\t".implode(','."\n\t\t", $fieldMap)."\n\t".');'; |
195
|
|
|
$class .= "\n\t"; |
196
|
|
|
$class .= "\n\t" . '/** @var array Collection of additional fields identifiers */'; |
197
|
|
|
$class .= "\n\t" . 'protected static $fieldIDs = array(' . implode(',', $fieldIDs) . ');'; |
198
|
|
|
$class .= "\n\t" . '/** @var array Collection of navigation identifiers */'; |
199
|
|
|
$class .= "\n\t" . 'protected static $navigationIDs = array(' . $structureRow['StructureID'] . ');'; |
200
|
|
|
$class .= "\n" . '}'; |
201
|
|
|
|
202
|
|
|
// Replace tabs with spaces |
203
|
|
|
return str_replace("\t", ' ', $class); |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
/** @return string Entity state hash */ |
207
|
|
|
public function entityHash() |
208
|
|
|
{ |
209
|
|
|
// Получим информацию о всех таблицах из БД |
210
|
|
|
return md5($this->database->fetch( |
211
|
|
|
'SELECT `TABLES`.`TABLE_NAME` as `TABLE_NAME` |
212
|
|
|
FROM `information_schema`.`TABLES` as `TABLES` |
213
|
|
|
WHERE `TABLES`.`TABLE_SCHEMA`="' . $this->database->database() . '";' |
214
|
|
|
)); |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
/** @return mixed Get collection of structures object */ |
218
|
|
|
protected function entityStructures() |
219
|
|
|
{ |
220
|
|
|
return $this->database->fetch(' |
221
|
|
|
SELECT * FROM `structure` |
222
|
|
|
WHERE `Active` = "1" AND `Type` = "0"' |
223
|
|
|
); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** @return string Generate entity classes */ |
227
|
|
|
public function createEntityClasses() |
228
|
|
|
{ |
229
|
|
|
$classes = "\n" . 'namespace ' . __NAMESPACE__ . ';'; |
230
|
|
|
$classes .= "\n"; |
231
|
|
|
$classes .= "\n" . 'use \samsoncms\api\Field;'; |
232
|
|
|
$classes .= "\n"; |
233
|
|
|
// Iterate all structures |
234
|
|
|
foreach ($this->entityStructures() as $structureRow) { |
235
|
|
|
$classes .= $this->createEntityClass($structureRow); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
return $classes; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* Generator constructor. |
243
|
|
|
* @param DatabaseInterface $database Database instance |
244
|
|
|
*/ |
245
|
|
|
public function __construct(DatabaseInterface $database) |
246
|
|
|
{ |
247
|
|
|
$this->database = $database; |
248
|
|
|
} |
249
|
|
|
} |
250
|
|
|
|
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.