1 | <?php |
||
31 | class CMS extends CompressableService |
||
32 | { |
||
33 | /** Database entity name for relations between material and navigation */ |
||
34 | const MATERIAL_NAVIGATION_RELATION_ENTITY = '\samson\activerecord\structurematerial'; |
||
35 | /** Database entity name for relations between material and images */ |
||
36 | const MATERIAL_IMAGES_RELATION_ENTITY = GalleryField::class; |
||
37 | /** Database entity name for relations between additional fields and navigation */ |
||
38 | const FIELD_NAVIGATION_RELATION_ENTITY = '\samson\activerecord\structurefield'; |
||
39 | /** Database entity name for relations between material and additional fields values */ |
||
40 | const MATERIAL_FIELD_RELATION_ENTITY = MaterialField::class; |
||
41 | |||
42 | /** Identifier */ |
||
43 | protected $id = 'cmsapi2'; |
||
44 | |||
45 | /** @var \samsonframework\orm\DatabaseInterface */ |
||
46 | protected $database; |
||
47 | |||
48 | /** @var array[string] Collection of generated queries */ |
||
49 | protected $queries; |
||
50 | |||
51 | /** @var string Database table names prefix */ |
||
52 | public $tablePrefix = ''; |
||
53 | |||
54 | /** |
||
55 | * CMS constructor. |
||
56 | * |
||
57 | * @param string $path |
||
58 | * @param ResourcesInterface $resources |
||
59 | * @param SystemInterface $system |
||
60 | */ |
||
61 | public function __construct($path, ResourcesInterface $resources, SystemInterface $system) |
||
62 | { |
||
63 | // TODO: This should changed to normal DI |
||
64 | $this->database = db(); |
||
65 | |||
66 | parent::__construct($path, $resources, $system); |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * Module initialization. |
||
71 | * |
||
72 | * @param array $params Initialization parameters |
||
73 | * @return boolean|null Initialization result |
||
74 | */ |
||
75 | public function init(array $params = array()) |
||
76 | { |
||
77 | $this->rewriteEntityLocale(); |
||
78 | } |
||
79 | |||
80 | public function beforeCompress(& $obj = null, array & $code = null) |
||
81 | { |
||
82 | |||
83 | } |
||
84 | |||
85 | public function afterCompress(& $obj = null, array & $code = null) |
||
86 | { |
||
87 | // Iterate through generated php code |
||
88 | $files = array(); |
||
89 | foreach (\samson\core\File::dir($this->cache_path, 'php', '', $files, 1) as $file) { |
||
90 | // No namespace for global function file |
||
91 | $ns = strpos($file, 'func') === false ? __NAMESPACE__ : ''; |
||
92 | |||
93 | // Compress generated php code |
||
94 | $obj->compress_php($file, $this, $code, $ns); |
||
95 | } |
||
96 | } |
||
97 | |||
98 | /** |
||
99 | * Entity additional fields localization support. |
||
100 | */ |
||
101 | protected function rewriteEntityLocale() |
||
102 | { |
||
103 | // Iterate all generated entity classes |
||
104 | foreach (get_declared_classes() as $entityClass) { |
||
105 | if (is_subclass_of($entityClass, '\samsoncms\api\Entity')) { |
||
106 | // Insert current application locale |
||
107 | str_replace('@locale', locale(), $entityClass::$_sql_select); |
||
108 | } |
||
109 | } |
||
110 | } |
||
111 | |||
112 | //[PHPCOMPRESSOR(remove,start)] |
||
113 | /** |
||
114 | * Read SQL file with variables placeholders pasting |
||
115 | * @param string $filePath SQL file for reading |
||
116 | * @param string $prefix Prefix for addition |
||
117 | * @return array Collection of SQL command texts |
||
118 | */ |
||
119 | public function readSQL($filePath, $prefix = '') |
||
120 | { |
||
121 | $sql = ''; |
||
122 | |||
123 | // Build path to SQL folder |
||
124 | if (file_exists($filePath)) { |
||
125 | // Replace prefix |
||
126 | $sql = str_replace('@prefix', $prefix, file_get_contents($filePath)); |
||
127 | } |
||
128 | |||
129 | // Split queries |
||
130 | $sqlCommands = explode(';', str_replace("\n", '', $sql)); |
||
131 | |||
132 | // Always return array |
||
133 | return array_filter(is_array($sqlCommands) ? $sqlCommands : array($sqlCommands)); |
||
134 | } |
||
135 | |||
136 | /** |
||
137 | * @see ModuleConnector::prepare() |
||
138 | */ |
||
139 | public function prepare() |
||
140 | { |
||
141 | // Create cms_version |
||
142 | $this->database->execute(' |
||
143 | CREATE TABLE IF NOT EXISTS `cms_version` ( |
||
144 | `version` varchar(15) NOT NULL DEFAULT \'30\' |
||
145 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;' |
||
146 | ); |
||
147 | |||
148 | // Perform this migration and execute only once |
||
149 | if ($this->migrator() != 40) { |
||
150 | // Perform SQL table creation |
||
151 | $path = __DIR__ . '/../sql/'; |
||
152 | foreach (array_slice(scandir($path), 2) as $file) { |
||
153 | trace('Performing database script ['.$file.']'); |
||
154 | foreach ($this->readSQL($path . $file, $this->tablePrefix) as $sql) { |
||
155 | $this->database->execute($sql); |
||
156 | } |
||
157 | } |
||
158 | $this->migrator(40); |
||
159 | } |
||
160 | |||
161 | // Initiate migration mechanism |
||
162 | $this->database->migration(get_class($this), array($this, 'migrator')); |
||
163 | |||
164 | // Define permanent table relations |
||
165 | new TableRelation('material', 'user', 'UserID', 0, 'user_id'); |
||
166 | new TableRelation('material', 'gallery', 'MaterialID', TableRelation::T_ONE_TO_MANY); |
||
167 | new TableRelation('material', 'materialfield', 'MaterialID', TableRelation::T_ONE_TO_MANY); |
||
168 | new TableRelation('material', 'field', 'materialfield.FieldID', TableRelation::T_ONE_TO_MANY); |
||
169 | new TableRelation('material', 'structurematerial', 'MaterialID', TableRelation::T_ONE_TO_MANY); |
||
170 | new TableRelation('material', 'structure', 'structurematerial.StructureID', TableRelation::T_ONE_TO_MANY); |
||
171 | new TableRelation('materialfield', 'field', 'FieldID'); |
||
172 | new TableRelation('materialfield', 'material', 'MaterialID'); |
||
173 | new TableRelation('structurematerial', 'structure', 'StructureID'); |
||
174 | new TableRelation('structurematerial', 'materialfield', 'MaterialID', TableRelation::T_ONE_TO_MANY); |
||
175 | new TableRelation('structurematerial', 'material', 'MaterialID', TableRelation::T_ONE_TO_MANY); |
||
176 | new TableRelation('structure', 'material', 'structurematerial.MaterialID', TableRelation::T_ONE_TO_MANY, null, 'manymaterials'); |
||
177 | new TableRelation('structure', 'gallery', 'structurematerial.MaterialID', TableRelation::T_ONE_TO_MANY, null, 'manymaterials'); |
||
178 | /*new TableRelation( 'structure', 'material', 'MaterialID' );*/ |
||
179 | new TableRelation('structure', 'user', 'UserID', 0, 'user_id'); |
||
180 | new TableRelation('structure', 'materialfield', 'material.MaterialID', TableRelation::T_ONE_TO_MANY, 'MaterialID', '_mf'); |
||
181 | new TableRelation('structure', 'structurematerial', 'StructureID', TableRelation::T_ONE_TO_MANY); |
||
182 | //new TableRelation('related_materials', 'material', 'first_material', TableRelation::T_ONE_TO_MANY, 'MaterialID'); |
||
183 | //new TableRelation('related_materials', 'materialfield', 'first_material', TableRelation::T_ONE_TO_MANY, 'MaterialID'); |
||
184 | new TableRelation('field', 'structurefield', 'FieldID'); |
||
185 | new TableRelation('field', 'structure', 'structurefield.StructureID'); |
||
186 | new TableRelation('structurefield', 'field', 'FieldID'); |
||
187 | new TableRelation('structurefield', 'materialfield', 'FieldID'); |
||
188 | new TableRelation('structurefield', 'material', 'materialfield.MaterialID'); |
||
189 | new TableRelation('structure', 'structure_relation', 'StructureID', TableRelation::T_ONE_TO_MANY, 'parent_id', 'children_relations'); |
||
190 | new TableRelation('structure', 'structure', 'children_relations.child_id', TableRelation::T_ONE_TO_MANY, 'StructureID', 'children'); |
||
191 | new TableRelation('structure', 'structure_relation', 'StructureID', TableRelation::T_ONE_TO_MANY, 'child_id', 'parents_relations'); |
||
192 | new TableRelation('structure', 'structure', 'parents_relations.parent_id', TableRelation::T_ONE_TO_MANY, 'StructureID', 'parents'); |
||
193 | new TableRelation('structurematerial', 'structure_relation', 'StructureID', TableRelation::T_ONE_TO_MANY, 'parent_id'); |
||
194 | new TableRelation('groupright', 'right', 'RightID', TableRelation::T_ONE_TO_MANY); |
||
195 | |||
196 | // TODO: Should be removed |
||
197 | m('activerecord')->relations(); |
||
198 | |||
199 | // Create module cache folder if not exists |
||
200 | if (!file_exists($this->cache_path)) { |
||
201 | @mkdir($this->cache_path, 0777, true); |
||
202 | } |
||
203 | |||
204 | // Create database analyzer |
||
205 | $generator = new Virtual($this->database); |
||
206 | // Analyze database structure and get entities metadata |
||
207 | foreach ($generator->analyze() as $metadata) { |
||
208 | // Create entity generated class names |
||
209 | $entityFile = $this->cache_path.$metadata->entity.'.php'; |
||
210 | $queryFile = $this->cache_path.$metadata->entity.'Query.php'; |
||
211 | $collectionFile = $this->cache_path.$metadata->entity.'Collection.php'; |
||
212 | |||
213 | // Create entity query class generator |
||
214 | $entityGenerator = new Entity(new Generator(__NAMESPACE__.'\\generated'), $metadata); |
||
215 | // Create entity query class generator |
||
216 | $queryGenerator = new Query(new Generator(__NAMESPACE__.'\\generated'), $metadata); |
||
217 | // Create entity query collection class generator |
||
218 | $collectionGenerator = new Collection(new Generator(__NAMESPACE__.'\\generated'), $metadata); |
||
219 | |||
220 | // Create entity query class files |
||
221 | file_put_contents($entityFile, '<?php' . $entityGenerator->generate()); |
||
222 | file_put_contents($queryFile, '<?php' . $queryGenerator->generate()); |
||
223 | file_put_contents($collectionFile, '<?php' . $collectionGenerator->generate()); |
||
224 | |||
225 | // Require files |
||
226 | require($entityFile); |
||
227 | require($queryFile); |
||
228 | require($collectionFile); |
||
229 | } |
||
230 | |||
231 | // Create database analyzer |
||
232 | $generator = new \samsoncms\api\generator\analyzer\Gallery($this->database); |
||
233 | // Analyze database structure and get entities metadata |
||
234 | foreach ($generator->analyze() as $metadata) { |
||
235 | // Create entity generated class names |
||
236 | $entityFile = $this->cache_path.$metadata->entity.'.php'; |
||
237 | |||
238 | // Create entity query class generator |
||
239 | $entityGenerator = new Gallery(new Generator(__NAMESPACE__.'\\generated'), $metadata); |
||
240 | |||
241 | // Create entity query class files |
||
242 | file_put_contents($entityFile, '<?php' . $entityGenerator->generate()); |
||
243 | |||
244 | // Require files |
||
245 | require($entityFile); |
||
246 | } |
||
247 | |||
248 | // // Generate entities classes file |
||
249 | // $generatorApi = new GeneratorApi($this->database); |
||
250 | // //$queryGenerator = new Query($this->database); |
||
251 | // |
||
252 | // // Create cache file |
||
253 | // $file = md5($generatorApi->entityHash()).'.php'; |
||
254 | // if ($this->cache_refresh($file)) { |
||
255 | // file_put_contents($file, '<?php ' . $generatorApi->createEntityClasses()); |
||
256 | // } |
||
257 | // |
||
258 | // // Include entities file |
||
259 | // require($file); |
||
260 | |||
261 | return parent::prepare(); |
||
262 | } |
||
263 | |||
264 | /** |
||
265 | * Handler for CMSAPI database version manipulating |
||
266 | * @param string $toVersion Version to switch to |
||
267 | * @return string Current database version |
||
268 | */ |
||
269 | public function migrator($toVersion = null) |
||
289 | //[PHPCOMPRESSOR(remove,end)] |
||
290 | } |
||
291 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.