1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Apps\Controller\Console; |
4
|
|
|
|
5
|
|
|
use Ffcms\Console\App; |
6
|
|
|
use Ffcms\Core\Helper\FileSystem\Directory; |
7
|
|
|
use Ffcms\Core\Helper\FileSystem\File; |
8
|
|
|
use Ffcms\Core\Helper\Type\Arr; |
9
|
|
|
use Ffcms\Core\Helper\Type\Obj; |
10
|
|
|
use Ffcms\Core\Helper\Type\Str; |
11
|
|
|
use \Illuminate\Database\Capsule\Manager as Capsule; |
12
|
|
|
use Apps\Controller\Console\Db as DbController; |
13
|
|
|
|
14
|
|
|
class Main |
15
|
|
|
{ |
16
|
|
|
// dirs to create & chmod |
17
|
|
|
protected $installDirs = [ |
18
|
|
|
'/upload/user/', '/upload/gallery/', '/upload/images/', |
19
|
|
|
'/Private/Cache/', '/Private/Cache/HTMLPurifier/', '/Private/Sessions/', '/Private/Antivirus/', |
20
|
|
|
'/Private/Config/', '/Private/Config/Default.php', '/Private/Config/Routing.php' |
21
|
|
|
]; |
22
|
|
|
|
23
|
|
|
public function actionHelp() |
24
|
|
|
{ |
25
|
|
|
$text = "You are using FFCMS console application. \n"; |
26
|
|
|
$text .= "This application support next basic commands: \n\n"; |
27
|
|
|
$text .= "\t main/info - show info about CMS\n"; |
28
|
|
|
$text .= "\t main/install - install FFCMS from console line.\n"; |
29
|
|
|
$text .= "\t main/update - update package to current minor version if available.\n"; |
30
|
|
|
$text .= "\t main/chmod - update chmod for ffcms special folders. Can be used after project deployment.\n"; |
31
|
|
|
$text .= "\t main/buildperms - build and update permissions map for applications. \n"; |
32
|
|
|
$text .= "\t create/model workground/modelName - create model carcase default.\n"; |
33
|
|
|
$text .= "\t create/ar activeRecordName - create active record table and model.\n"; |
34
|
|
|
$text .= "\t create/controller workground/controllerName - create default controller carcase.\n"; |
35
|
|
|
$text .= "\t db/import activeRecordName - import to database single schema from ar model.\n"; |
36
|
|
|
$text .= "\t db/importAll - import all active record tables to database.\n"; |
37
|
|
|
return $text; |
38
|
|
|
} |
39
|
|
|
|
40
|
|
|
public function actionInfo() |
41
|
|
|
{ |
42
|
|
|
$text = "\nInformation about FFCMS package and environment: \n\n"; |
43
|
|
|
$text .= "\t PHP version: " . phpversion() . "\n"; |
44
|
|
|
$text .= "\t Dist path: " . root . "\n"; |
45
|
|
|
$text .= "\t Used version: " . App::$Properties->version['num'] . ' [build: ' . App::$Properties->version['date'] . "]\n\n"; |
46
|
|
|
$text .= "Information about FFCMS cmf packages: \n\n"; |
47
|
|
|
|
48
|
|
|
$composerInfo = File::read('/composer.lock'); |
49
|
|
|
if (false !== $composerInfo) { |
50
|
|
|
$jsonInfo = json_decode($composerInfo); |
51
|
|
|
foreach ($jsonInfo->packages as $item) { |
52
|
|
|
$text .= "\t Package: " . $item->name . ' => ' . $item->version . "\n"; |
53
|
|
|
} |
54
|
|
|
} else { |
55
|
|
|
$text .= "\t Composer is never be used - no information available."; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
return $text; |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Scan available permissions and write to cfg file |
63
|
|
|
* @return string |
64
|
|
|
*/ |
65
|
|
|
public function actionBuildperms() |
66
|
|
|
{ |
67
|
|
|
// default permissions |
68
|
|
|
$permissions = [ |
69
|
|
|
'global/write', |
70
|
|
|
'global/modify', |
71
|
|
|
'global/file', |
72
|
|
|
'global/all' |
73
|
|
|
]; |
74
|
|
|
|
75
|
|
|
// admin controllers |
76
|
|
|
$AdminAppControllers = '/Apps/Controller/Admin/'; |
77
|
|
|
|
78
|
|
|
// scan directory |
79
|
|
|
$scan = File::listFiles($AdminAppControllers, ['.php']); |
80
|
|
|
|
81
|
|
|
foreach ($scan as $file) { |
82
|
|
|
$className = Str::firstIn(Str::lastIn($file, DIRECTORY_SEPARATOR, true), '.'); |
83
|
|
|
// read as plain text |
84
|
|
|
$byte = File::read($file); |
85
|
|
|
preg_match_all('/public function action(\w*?)\(/', $byte, $matches); // matches[0] contains all methods ;) |
|
|
|
|
86
|
|
|
if (Obj::isArray($matches[1]) && count($matches[1]) > 0) { |
87
|
|
|
foreach ($matches[1] as $perm) { |
88
|
|
|
$permissions[] = 'Admin/' . $className . '/' . $perm; |
89
|
|
|
} |
90
|
|
|
} |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
// prepare save string |
94
|
|
|
$stringSave = "<?php \n\nreturn " . var_export($permissions, true) . ';'; |
95
|
|
|
File::write('/Private/Config/Permissions.php', $stringSave); |
96
|
|
|
|
97
|
|
|
return App::$Output->write('Permission mas is successful updated! Founded permissions: ' . count($permissions)); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Set chmod for system directories |
102
|
|
|
*/ |
103
|
|
|
public function actionChmod() |
104
|
|
|
{ |
105
|
|
|
$errors = false; |
106
|
|
|
foreach ($this->installDirs as $obj) { |
107
|
|
|
if (Directory::exist($obj)) { |
108
|
|
|
Directory::recursiveChmod($obj, 0777); |
109
|
|
|
} elseif (File::exist($obj)) { |
110
|
|
|
chmod(root . $obj, 0777); |
111
|
|
|
} else { |
112
|
|
|
$errors .= App::$Output->write('Filesystem object is not founded: ' . $obj); |
113
|
|
|
} |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
return $errors === false ? App::$Output->write('Chmods are successful changed') : $errors; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
public function actionInstall() |
120
|
|
|
{ |
121
|
|
|
$config = App::$Properties->get('database'); |
122
|
|
|
$newConfig = []; |
123
|
|
|
// creating default directory's |
124
|
|
|
foreach ($this->installDirs as $obj) { |
125
|
|
|
// looks like a directory |
126
|
|
|
if (!Str::contains('.', $obj)) { |
127
|
|
|
Directory::create($obj, 0777); |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
echo App::$Output->write('Upload and private directories are successful created!'); |
131
|
|
|
|
132
|
|
|
// set chmods |
133
|
|
|
echo $this->actionChmod(); |
134
|
|
|
|
135
|
|
|
// database config from input |
136
|
|
|
echo App::$Output->writeHeader('Database connection configuration'); |
137
|
|
|
echo 'Driver(default:' . $config['driver'] . '):'; |
138
|
|
|
$dbDriver = App::$Input->read(); |
139
|
|
|
if (Arr::in($dbDriver, ['mysql', 'pgsql', 'sqlite'])) { |
140
|
|
|
$newConfig['driver'] = $dbDriver; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
// for sqlite its would be a path |
144
|
|
|
echo 'Host(default:' . $config['host'] . '):'; |
145
|
|
|
$dbHost = App::$Input->read(); |
146
|
|
|
if (!Str::likeEmpty($dbHost)) { |
147
|
|
|
$newConfig['host'] = $dbHost; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
echo 'Database name(default:' . $config['database'] . '):'; |
151
|
|
|
$dbName = App::$Input->read(); |
152
|
|
|
if (!Str::likeEmpty($dbName)) { |
153
|
|
|
$newConfig['database'] = $dbName; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
echo 'User(default:' . $config['username'] . '):'; |
157
|
|
|
$dbUser = App::$Input->read(); |
158
|
|
|
if (!Str::likeEmpty($dbUser)) { |
159
|
|
|
$newConfig['username'] = $dbUser; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
echo 'Password(default:' . $config['password'] . '):'; |
163
|
|
|
$dbPwd = App::$Input->read(); |
164
|
|
|
if (!Str::likeEmpty($dbPwd)) { |
165
|
|
|
$newConfig['password'] = $dbPwd; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
echo 'Table prefix(default:' . $config['prefix'] . '):'; |
169
|
|
|
$dbPrefix = App::$Input->read(); |
170
|
|
|
if (!Str::likeEmpty($dbPrefix)) { |
171
|
|
|
$newConfig['prefix'] = $dbPrefix; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
// merge configs and add new connection to db pull |
175
|
|
|
$dbConfigs = Arr::merge($config, $newConfig); |
176
|
|
|
App::$Database->addConnection($dbConfigs, 'install'); |
177
|
|
|
|
178
|
|
|
try { |
179
|
|
|
App::$Database->connection('install')->getDatabaseName(); |
|
|
|
|
180
|
|
|
} catch (\Exception $e) { |
181
|
|
|
return 'Testing database connection is failed! Run installer again and pass tested connection data! Log: ' . $e->getMessage(); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
// autoload isn't work here |
185
|
|
|
include(root . '/Apps/Controller/Console/Db.php'); |
186
|
|
|
|
187
|
|
|
// import db data |
188
|
|
|
$dbController = new DbController(); |
189
|
|
|
echo $dbController->actionImportAll('install'); |
190
|
|
|
|
191
|
|
|
// set website send from email from input |
192
|
|
|
$emailConfig = App::$Properties->get('adminEmail'); |
193
|
|
|
echo 'Website sendFrom email(default: ' . $emailConfig . '):'; |
194
|
|
|
$email = App::$Input->read(); |
195
|
|
|
if (!Str::isEmail($email)) { |
196
|
|
|
$email = $emailConfig; |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
// generate other configuration data and security salt, key's and other |
200
|
|
|
echo App::$Output->writeHeader('Writing configurations'); |
201
|
|
|
$allCfg = App::$Properties->getAll('default'); |
202
|
|
|
$allCfg['database'] = $dbConfigs; |
203
|
|
|
$allCfg['adminEmail'] = $email; |
204
|
|
|
echo App::$Output->write('Generate password salt for BLOWFISH crypt'); |
205
|
|
|
$allCfg['passwordSalt'] = Str::randomLatinNumeric(mt_rand(21, 30)) . '$'; |
206
|
|
|
echo App::$Output->write('Generate security cookies for debug panel'); |
207
|
|
|
$allCfg['debug']['cookie']['key'] = 'fdebug_' . Str::randomLatinNumeric(mt_rand(8, 32)); |
208
|
|
|
$allCfg['debug']['cookie']['value'] = Str::randomLatinNumeric(mt_rand(32, 128)); |
209
|
|
|
|
210
|
|
|
// write config data |
211
|
|
|
$writeCfg = App::$Properties->writeConfig('default', $allCfg); |
|
|
|
|
212
|
|
|
if ($writeCfg !== true) { |
213
|
|
|
return 'File /Private/Config/Default.php is unavailable to write data!'; |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
return 'Configuration done! FFCMS 3 is successful installed! Visit your website. You can add administrator using command php console.php db/adduser'; |
217
|
|
|
} |
218
|
|
|
} |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.