1
|
|
|
<?php |
|
|
|
|
2
|
|
|
namespace samsoncms\api; |
3
|
|
|
|
4
|
|
|
// Backward compatibility |
5
|
|
|
require('generated/Material.php'); |
6
|
|
|
require('generated/Field.php'); |
7
|
|
|
require('generated/MaterialField.php'); |
8
|
|
|
require('generated/Structure.php'); |
9
|
|
|
require('generated/StructureField.php'); |
10
|
|
|
|
11
|
|
|
use samson\activerecord\structurematerial; |
12
|
|
|
use samson\activerecord\TableRelation; |
13
|
|
|
use samson\core\CompressableService; |
14
|
|
|
use samson\activerecord\dbMySQLConnector; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* SamsonCMS API |
18
|
|
|
* @package samsoncms\api |
19
|
|
|
*/ |
20
|
|
|
class CMS extends CompressableService |
21
|
|
|
{ |
22
|
|
|
/** Database entity name for relations between material and navigation */ |
23
|
|
|
const MATERIAL_NAVIGATION_RELATION_ENTITY = '\samson\activerecord\structurematerial'; |
24
|
|
|
/** Database entity name for relations between material and images */ |
25
|
|
|
const MATERIAL_IMAGES_RELATION_ENTITY = '\samson\activerecord\gallery'; |
26
|
|
|
/** Database entity name for relations between additional fields and navigation */ |
27
|
|
|
const FIELD_NAVIGATION_RELATION_ENTITY = '\samson\activerecord\structurefield'; |
28
|
|
|
/** Database entity name for relations between material and additional fields values */ |
29
|
|
|
const MATERIAL_FIELD_RELATION_ENTITY = MaterialField::ENTITY; |
30
|
|
|
|
31
|
|
|
/** Identifier */ |
32
|
|
|
protected $id = 'cmsapi2'; |
33
|
|
|
|
34
|
|
|
/** @var \samsonframework\orm\DatabaseInterface */ |
35
|
|
|
protected $database; |
36
|
|
|
|
37
|
|
|
/** @var string Database table names prefix */ |
38
|
|
|
public $tablePrefix = ''; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* CMS constructor. |
42
|
|
|
* @param null|string $path |
43
|
|
|
* @param null|string $vid |
44
|
|
|
* @param mixed|null $resources |
45
|
|
|
*/ |
46
|
|
|
public function __construct($path, $vid, $resources) |
47
|
|
|
{ |
48
|
|
|
// TODO: This should changed to normal DI |
49
|
|
|
$this->database = db(); |
50
|
|
|
|
51
|
|
|
parent::__construct($path, $vid, $resources); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
|
55
|
|
|
public function beforeCompress(& $obj = null, array & $code = null) |
56
|
|
|
{ |
57
|
|
|
|
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
public function afterCompress(& $obj = null, array & $code = null) |
61
|
|
|
{ |
62
|
|
|
// Iterate through generated php code |
63
|
|
|
$files = array(); |
64
|
|
|
foreach (\samson\core\File::dir($this->cache_path, 'php', '', $files, 1) as $file) { |
65
|
|
|
// No namespace for global function file |
66
|
|
|
$ns = strpos($file, 'func') === false ? __NAMESPACE__ : ''; |
67
|
|
|
|
68
|
|
|
// Compress generated php code |
69
|
|
|
$obj->compress_php($file, $this, $code, $ns); |
70
|
|
|
} |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
//[PHPCOMPRESSOR(remove,start)] |
74
|
|
|
/** |
75
|
|
|
* Read SQL file with variables placeholders pasting |
76
|
|
|
* @param string $filePath SQL file for reading |
77
|
|
|
* @param string $prefix Prefix for addition |
78
|
|
|
* @return string SQL command text |
79
|
|
|
*/ |
80
|
|
|
public function readSQL($filePath, $prefix = '') |
81
|
|
|
{ |
82
|
|
|
$sql = ''; |
83
|
|
|
|
84
|
|
|
// Build path to SQL folder |
85
|
|
|
if (file_exists($filePath)) { |
86
|
|
|
// Replace prefix |
87
|
|
|
$sql = str_replace('@prefix', $prefix, file_get_contents($filePath)); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
return $sql; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* @see ModuleConnector::prepare() |
95
|
|
|
*/ |
96
|
|
|
public function prepare() |
97
|
|
|
{ |
98
|
|
|
// Perform this migration and execute only once |
99
|
|
|
if ($this->migrator() != 40) { |
100
|
|
|
// Perform SQL table creation |
101
|
|
|
$path = __DIR__ . '/../sql/'; |
102
|
|
|
foreach (array_slice(scandir($path), 2) as $file) { |
103
|
|
|
$this->database->execute($this->readSQL($path . $file, $this->tablePrefix)); |
104
|
|
|
} |
105
|
|
|
$this->migrator(40); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
// Initiate migration mechanism |
109
|
|
|
$this->database->migration(get_class($this), array($this, 'migrator')); |
|
|
|
|
110
|
|
|
|
111
|
|
|
// Define permanent table relations |
112
|
|
|
new TableRelation('material', 'user', 'UserID', 0, 'user_id'); |
113
|
|
|
new TableRelation('material', 'gallery', 'MaterialID', TableRelation::T_ONE_TO_MANY); |
114
|
|
|
new TableRelation('material', 'materialfield', 'MaterialID', TableRelation::T_ONE_TO_MANY); |
115
|
|
|
new TableRelation('material', 'field', 'materialfield.FieldID', TableRelation::T_ONE_TO_MANY); |
116
|
|
|
new TableRelation('material', 'structurematerial', 'MaterialID', TableRelation::T_ONE_TO_MANY); |
117
|
|
|
new TableRelation('material', 'structure', 'structurematerial.StructureID', TableRelation::T_ONE_TO_MANY); |
118
|
|
|
new TableRelation('materialfield', 'field', 'FieldID'); |
119
|
|
|
new TableRelation('materialfield', 'material', 'MaterialID'); |
120
|
|
|
new TableRelation('structurematerial', 'structure', 'StructureID'); |
121
|
|
|
new TableRelation('structurematerial', 'materialfield', 'MaterialID', TableRelation::T_ONE_TO_MANY); |
122
|
|
|
new TableRelation('structurematerial', 'material', 'MaterialID', TableRelation::T_ONE_TO_MANY); |
123
|
|
|
new TableRelation('structure', 'material', 'structurematerial.MaterialID', TableRelation::T_ONE_TO_MANY, null, 'manymaterials'); |
124
|
|
|
new TableRelation('structure', 'gallery', 'structurematerial.MaterialID', TableRelation::T_ONE_TO_MANY, null, 'manymaterials'); |
125
|
|
|
/*new TableRelation( 'structure', 'material', 'MaterialID' );*/ |
126
|
|
|
new TableRelation('structure', 'user', 'UserID', 0, 'user_id'); |
127
|
|
|
new TableRelation('structure', 'materialfield', 'material.MaterialID', TableRelation::T_ONE_TO_MANY, 'MaterialID', '_mf'); |
128
|
|
|
new TableRelation('structure', 'structurematerial', 'StructureID', TableRelation::T_ONE_TO_MANY); |
129
|
|
|
new TableRelation('related_materials', 'material', 'first_material', TableRelation::T_ONE_TO_MANY, 'MaterialID'); |
130
|
|
|
new TableRelation('related_materials', 'materialfield', 'first_material', TableRelation::T_ONE_TO_MANY, 'MaterialID'); |
131
|
|
|
new TableRelation('field', 'structurefield', 'FieldID'); |
132
|
|
|
new TableRelation('field', 'structure', 'structurefield.StructureID'); |
133
|
|
|
new TableRelation('structurefield', 'field', 'FieldID'); |
134
|
|
|
new TableRelation('structurefield', 'materialfield', 'FieldID'); |
135
|
|
|
new TableRelation('structurefield', 'material', 'materialfield.MaterialID'); |
136
|
|
|
new TableRelation('structure', 'structure_relation', 'StructureID', TableRelation::T_ONE_TO_MANY, 'parent_id', 'children_relations'); |
137
|
|
|
new TableRelation('structure', 'structure', 'children_relations.child_id', TableRelation::T_ONE_TO_MANY, 'StructureID', 'children'); |
138
|
|
|
new TableRelation('structure', 'structure_relation', 'StructureID', TableRelation::T_ONE_TO_MANY, 'child_id', 'parents_relations'); |
139
|
|
|
new TableRelation('structure', 'structure', 'parents_relations.parent_id', TableRelation::T_ONE_TO_MANY, 'StructureID', 'parents'); |
140
|
|
|
new TableRelation('structurematerial', 'structure_relation', 'StructureID', TableRelation::T_ONE_TO_MANY, 'parent_id'); |
141
|
|
|
new TableRelation('groupright', 'right', 'RightID', TableRelation::T_ONE_TO_MANY); |
142
|
|
|
|
143
|
|
|
m('activerecord')->relations(); |
144
|
|
|
|
145
|
|
|
// Generate entities classes file |
146
|
|
|
$generator = new Generator($this->database); |
147
|
|
|
$file = md5($generator->entityHash()).'.php'; |
148
|
|
|
if ($this->cache_refresh($file)) { |
149
|
|
|
|
150
|
|
|
} |
151
|
|
|
file_put_contents($file, '<?php '.$generator->createEntityClasses()); |
152
|
|
|
|
153
|
|
|
// Include entities file |
154
|
|
|
require($file); |
155
|
|
|
|
156
|
|
|
return parent::prepare(); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* Handler for CMSAPI database version manipulating |
161
|
|
|
* @param string $toVersion Version to switch to |
162
|
|
|
* @return string Current database version |
163
|
|
|
*/ |
164
|
|
|
public function migrator($toVersion = null) |
165
|
|
|
{ |
166
|
|
|
// If something passed - change database version to it |
167
|
|
|
if (func_num_args()) { |
168
|
|
|
// Save current version to special db table |
169
|
|
|
$this->database->execute( |
170
|
|
|
"ALTER TABLE `" . dbMySQLConnector::$prefix . "cms_version` |
171
|
|
|
CHANGE `version` `version` VARCHAR( 15 ) CHARACTER SET utf8 |
172
|
|
|
COLLATE utf8_general_ci NOT NULL DEFAULT '" . $toVersion . "';" |
173
|
|
|
); |
174
|
|
|
die('Database successfully migrated to [' . $toVersion . ']'); |
175
|
|
|
} else { // Return current database version |
176
|
|
|
$version_row = $this->database->fetch('SHOW COLUMNS FROM `' . dbMySQLConnector::$prefix . 'cms_version`'); |
177
|
|
|
if (isset($version_row[0]['Default'])) { |
178
|
|
|
return $version_row[0]['Default']; |
179
|
|
|
} else { |
180
|
|
|
return 0; |
181
|
|
|
} |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
//[PHPCOMPRESSOR(remove,end)] |
185
|
|
|
} |
186
|
|
|
|
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.