|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace phpMyFAQ; |
|
4
|
|
|
|
|
5
|
|
|
/** |
|
6
|
|
|
* The Installer class installs phpMyFAQ. Classy. |
|
7
|
|
|
* |
|
8
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public License, |
|
9
|
|
|
* v. 2.0. If a copy of the MPL was not distributed with this file, You can |
|
10
|
|
|
* obtain one at http://mozilla.org/MPL/2.0/. |
|
11
|
|
|
* |
|
12
|
|
|
* @package phpMyFAQ |
|
13
|
|
|
* @author Florian Anderiasch <[email protected]> |
|
14
|
|
|
* @copyright 2012-2019 phpMyFAQ Team |
|
15
|
|
|
* @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0 |
|
16
|
|
|
* @link https://www.phpmyfaq.de |
|
17
|
|
|
* @since 2012-08-27 |
|
18
|
|
|
*/ |
|
19
|
|
|
|
|
20
|
|
|
use Composer\Autoload\ClassLoader; |
|
21
|
|
|
use Elasticsearch\ClientBuilder; |
|
22
|
|
|
use phpMyFAQ\Db\Driver; |
|
23
|
|
|
use phpMyFAQ\Instance\Database; |
|
24
|
|
|
use phpMyFAQ\Instance\Database\Stopwords; |
|
|
|
|
|
|
25
|
|
|
use phpMyFAQ\Instance\Elasticsearch; |
|
26
|
|
|
use phpMyFAQ\Instance\Setup; |
|
27
|
|
|
use phpMyFAQ\Instance\Master; |
|
28
|
|
|
|
|
29
|
|
|
if (!defined('IS_VALID_PHPMYFAQ')) { |
|
30
|
|
|
exit(); |
|
31
|
|
|
} |
|
32
|
|
|
|
|
33
|
|
|
/** |
|
34
|
|
|
* Class Installer. |
|
35
|
|
|
* |
|
36
|
|
|
* @package phpMyFAQ |
|
37
|
|
|
* @author Florian Anderiasch <[email protected]> |
|
38
|
|
|
* @copyright 2012-2019 phpMyFAQ Team |
|
39
|
|
|
* @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0 |
|
40
|
|
|
* @link https://www.phpmyfaq.de |
|
41
|
|
|
* @since 2012-08-27 |
|
42
|
|
|
*/ |
|
43
|
|
|
class Installer |
|
44
|
|
|
{ |
|
45
|
|
|
/** |
|
46
|
|
|
* System object. |
|
47
|
|
|
* |
|
48
|
|
|
* @var System |
|
49
|
|
|
*/ |
|
50
|
|
|
protected $system; |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* Array with user rights. |
|
54
|
|
|
* |
|
55
|
|
|
* @var array |
|
56
|
|
|
*/ |
|
57
|
|
|
protected $mainRights = [ |
|
58
|
|
|
[ |
|
59
|
|
|
'name' => 'add_user', |
|
60
|
|
|
'description' => 'Right to add user accounts', |
|
61
|
|
|
], |
|
62
|
|
|
[ |
|
63
|
|
|
'name' => 'edit_user', |
|
64
|
|
|
'description' => 'Right to edit user accounts', |
|
65
|
|
|
], |
|
66
|
|
|
[ |
|
67
|
|
|
'name' => 'delete_user', |
|
68
|
|
|
'description' => 'Right to delete user accounts', |
|
69
|
|
|
], |
|
70
|
|
|
//4 => "add_faq", |
|
71
|
|
|
[ |
|
72
|
|
|
'name' => 'add_faq', |
|
73
|
|
|
'description' => 'Right to add faq entries', |
|
74
|
|
|
], |
|
75
|
|
|
//5 => "edit_faq", |
|
76
|
|
|
[ |
|
77
|
|
|
'name' => 'edit_faq', |
|
78
|
|
|
'description' => 'Right to edit faq entries', |
|
79
|
|
|
], |
|
80
|
|
|
//6 => "delete_faq", |
|
81
|
|
|
[ |
|
82
|
|
|
'name' => 'delete_faq', |
|
83
|
|
|
'description' => 'Right to delete faq entries', |
|
84
|
|
|
], |
|
85
|
|
|
//7 => "viewlog", |
|
86
|
|
|
[ |
|
87
|
|
|
'name' => 'viewlog', |
|
88
|
|
|
'description' => 'Right to view logfiles', |
|
89
|
|
|
], |
|
90
|
|
|
//8 => "adminlog", |
|
91
|
|
|
[ |
|
92
|
|
|
'name' => 'adminlog', |
|
93
|
|
|
'description' => 'Right to view admin log', |
|
94
|
|
|
], |
|
95
|
|
|
//9 => "delcomment", |
|
96
|
|
|
[ |
|
97
|
|
|
'name' => 'delcomment', |
|
98
|
|
|
'description' => 'Right to delete comments', |
|
99
|
|
|
], |
|
100
|
|
|
//10 => "addnews", |
|
101
|
|
|
[ |
|
102
|
|
|
'name' => 'addnews', |
|
103
|
|
|
'description' => 'Right to add news', |
|
104
|
|
|
], |
|
105
|
|
|
//11 => "editnews", |
|
106
|
|
|
[ |
|
107
|
|
|
'name' => 'editnews', |
|
108
|
|
|
'description' => 'Right to edit news', |
|
109
|
|
|
], |
|
110
|
|
|
//12 => "delnews", |
|
111
|
|
|
[ |
|
112
|
|
|
'name' => 'delnews', |
|
113
|
|
|
'description' => 'Right to delete news', |
|
114
|
|
|
], |
|
115
|
|
|
//13 => "addcateg", |
|
116
|
|
|
[ |
|
117
|
|
|
'name' => 'addcateg', |
|
118
|
|
|
'description' => 'Right to add categories', |
|
119
|
|
|
], |
|
120
|
|
|
//14 => "editcateg", |
|
121
|
|
|
[ |
|
122
|
|
|
'name' => 'editcateg', |
|
123
|
|
|
'description' => 'Right to edit categories', |
|
124
|
|
|
], |
|
125
|
|
|
//15 => "delcateg", |
|
126
|
|
|
[ |
|
127
|
|
|
'name' => 'delcateg', |
|
128
|
|
|
'description' => 'Right to delete categories', |
|
129
|
|
|
], |
|
130
|
|
|
//16 => "passwd", |
|
131
|
|
|
[ |
|
132
|
|
|
'name' => 'passwd', |
|
133
|
|
|
'description' => 'Right to change passwords', |
|
134
|
|
|
], |
|
135
|
|
|
//17 => "editconfig", |
|
136
|
|
|
[ |
|
137
|
|
|
'name' => 'editconfig', |
|
138
|
|
|
'description' => 'Right to edit configuration', |
|
139
|
|
|
], |
|
140
|
|
|
//18 => "viewadminlink", |
|
141
|
|
|
[ |
|
142
|
|
|
'name' => 'viewadminlink', |
|
143
|
|
|
'description' => 'Right to see the link to the admin section' |
|
144
|
|
|
], |
|
145
|
|
|
//19 => "backup delatt", // Duplicate, removed with 2.7.3 |
|
146
|
|
|
//[ |
|
147
|
|
|
// 'name' => 'delatt', |
|
148
|
|
|
// 'description' => 'Right to delete attachments' |
|
149
|
|
|
//], |
|
150
|
|
|
//20 => "backup", |
|
151
|
|
|
[ |
|
152
|
|
|
'name' => 'backup', |
|
153
|
|
|
'description' => 'Right to save backups', |
|
154
|
|
|
], |
|
155
|
|
|
//21 => "restore", |
|
156
|
|
|
[ |
|
157
|
|
|
'name' => 'restore', |
|
158
|
|
|
'description' => 'Right to load backups', |
|
159
|
|
|
], |
|
160
|
|
|
//22 => "delquestion", |
|
161
|
|
|
[ |
|
162
|
|
|
'name' => 'delquestion', |
|
163
|
|
|
'description' => 'Right to delete questions', |
|
164
|
|
|
], |
|
165
|
|
|
//23 => 'addglossary', |
|
166
|
|
|
[ |
|
167
|
|
|
'name' => 'addglossary', |
|
168
|
|
|
'description' => 'Right to add glossary entries', |
|
169
|
|
|
], |
|
170
|
|
|
//24 => 'editglossary', |
|
171
|
|
|
[ |
|
172
|
|
|
'name' => 'editglossary', |
|
173
|
|
|
'description' => 'Right to edit glossary entries', |
|
174
|
|
|
], |
|
175
|
|
|
//25 => 'delglossary' |
|
176
|
|
|
[ |
|
177
|
|
|
'name' => 'delglossary', |
|
178
|
|
|
'description' => 'Right to delete glossary entries', |
|
179
|
|
|
], |
|
180
|
|
|
//26 => 'changebtrevs' |
|
181
|
|
|
[ |
|
182
|
|
|
'name' => 'changebtrevs', |
|
183
|
|
|
'description' => 'Right to edit revisions', |
|
184
|
|
|
], |
|
185
|
|
|
//27 => "addgroup", |
|
186
|
|
|
[ |
|
187
|
|
|
'name' => 'addgroup', |
|
188
|
|
|
'description' => 'Right to add group accounts', |
|
189
|
|
|
], |
|
190
|
|
|
//28 => "editgroup", |
|
191
|
|
|
[ |
|
192
|
|
|
'name' => 'editgroup', |
|
193
|
|
|
'description' => 'Right to edit group accounts', |
|
194
|
|
|
], |
|
195
|
|
|
//29 => "delgroup", |
|
196
|
|
|
[ |
|
197
|
|
|
'name' => 'delgroup', |
|
198
|
|
|
'description' => 'Right to delete group accounts', |
|
199
|
|
|
], |
|
200
|
|
|
//30 => "addtranslation", |
|
201
|
|
|
[ |
|
202
|
|
|
'name' => 'addtranslation', |
|
203
|
|
|
'description' => 'Right to add translation', |
|
204
|
|
|
], |
|
205
|
|
|
//31 => "edittranslation", |
|
206
|
|
|
[ |
|
207
|
|
|
'name' => 'edittranslation', |
|
208
|
|
|
'description' => 'Right to edit translations', |
|
209
|
|
|
], |
|
210
|
|
|
//32 => "deltranslation", |
|
211
|
|
|
[ |
|
212
|
|
|
'name' => 'deltranslation', |
|
213
|
|
|
'description' => 'Right to delete translations', |
|
214
|
|
|
], |
|
215
|
|
|
// 33 => 'approverec' |
|
216
|
|
|
[ |
|
217
|
|
|
'name' => 'approverec', |
|
218
|
|
|
'description' => 'Right to approve records', |
|
219
|
|
|
], |
|
220
|
|
|
// 34 => 'addattachment' |
|
221
|
|
|
[ |
|
222
|
|
|
'name' => 'addattachment', |
|
223
|
|
|
'description' => 'Right to add attachments', |
|
224
|
|
|
], |
|
225
|
|
|
// 35 => 'editattachment' |
|
226
|
|
|
[ |
|
227
|
|
|
'name' => 'editattachment', |
|
228
|
|
|
'description' => 'Right to edit attachments', |
|
229
|
|
|
], |
|
230
|
|
|
// 36 => 'delattachment' |
|
231
|
|
|
[ |
|
232
|
|
|
'name' => 'delattachment', |
|
233
|
|
|
'description' => 'Right to delete attachments', |
|
234
|
|
|
], |
|
235
|
|
|
// 37 => 'dlattachment' |
|
236
|
|
|
[ |
|
237
|
|
|
'name' => 'dlattachment', |
|
238
|
|
|
'description' => 'Right to download attachments', |
|
239
|
|
|
], |
|
240
|
|
|
// 38 => 'reports' |
|
241
|
|
|
[ |
|
242
|
|
|
'name' => 'reports', |
|
243
|
|
|
'description' => 'Right to generate reports', |
|
244
|
|
|
], |
|
245
|
|
|
// 39 => 'addfaq' |
|
246
|
|
|
[ |
|
247
|
|
|
'name' => 'addfaq', |
|
248
|
|
|
'description' => 'Right to add FAQs in frontend', |
|
249
|
|
|
], |
|
250
|
|
|
// 40 => 'addquestion' |
|
251
|
|
|
[ |
|
252
|
|
|
'name' => 'addquestion', |
|
253
|
|
|
'description' => 'Right to add questions in frontend', |
|
254
|
|
|
], |
|
255
|
|
|
// 41 => 'addcomment' |
|
256
|
|
|
[ |
|
257
|
|
|
'name' => 'addcomment', |
|
258
|
|
|
'description' => 'Right to add comments in frontend', |
|
259
|
|
|
], |
|
260
|
|
|
// 42 => 'editinstances' |
|
261
|
|
|
[ |
|
262
|
|
|
'name' => 'editinstances', |
|
263
|
|
|
'description' => 'Right to edit multi-site instances', |
|
264
|
|
|
], |
|
265
|
|
|
// 43 => 'addinstances' |
|
266
|
|
|
[ |
|
267
|
|
|
'name' => 'addinstances', |
|
268
|
|
|
'description' => 'Right to add multi-site instances', |
|
269
|
|
|
], |
|
270
|
|
|
// 44 => 'delinstances' |
|
271
|
|
|
[ |
|
272
|
|
|
'name' => 'delinstances', |
|
273
|
|
|
'description' => 'Right to delete multi-site instances', |
|
274
|
|
|
], |
|
275
|
|
|
[ |
|
276
|
|
|
'name' => 'export', |
|
277
|
|
|
'description' => 'Right to export the complete FAQ', |
|
278
|
|
|
], |
|
279
|
|
|
[ |
|
280
|
|
|
'name' => 'view_faqs', |
|
281
|
|
|
'description' => 'Right to view FAQs' |
|
282
|
|
|
], |
|
283
|
|
|
[ |
|
284
|
|
|
'name' => 'view_categories', |
|
285
|
|
|
'description' => 'Right to view categories' |
|
286
|
|
|
|
|
287
|
|
|
], |
|
288
|
|
|
[ |
|
289
|
|
|
'name' => 'view_sections', |
|
290
|
|
|
'description' => 'Right to view sections' |
|
291
|
|
|
|
|
292
|
|
|
], |
|
293
|
|
|
[ |
|
294
|
|
|
'name' => 'view_news', |
|
295
|
|
|
'description' => 'Right to view news' |
|
296
|
|
|
|
|
297
|
|
|
], |
|
298
|
|
|
[ |
|
299
|
|
|
'name' => 'add_section', |
|
300
|
|
|
'description' => 'Right to add sections' |
|
301
|
|
|
|
|
302
|
|
|
], |
|
303
|
|
|
[ |
|
304
|
|
|
'name' => 'edit_section', |
|
305
|
|
|
'description' => 'Right to edit sections' |
|
306
|
|
|
|
|
307
|
|
|
], |
|
308
|
|
|
[ |
|
309
|
|
|
'name' => 'delete_section', |
|
310
|
|
|
'description' => 'Right to delete sections' |
|
311
|
|
|
|
|
312
|
|
|
], |
|
313
|
|
|
[ |
|
314
|
|
|
'name' => 'administrate_sections', |
|
315
|
|
|
'description' => 'Right to administrate sections' |
|
316
|
|
|
|
|
317
|
|
|
], |
|
318
|
|
|
[ |
|
319
|
|
|
'name' => 'administrate_groups', |
|
320
|
|
|
'description' => 'Right to administrate groups' |
|
321
|
|
|
|
|
322
|
|
|
], |
|
323
|
|
|
]; |
|
324
|
|
|
|
|
325
|
|
|
/** |
|
326
|
|
|
* Configuration array. |
|
327
|
|
|
* |
|
328
|
|
|
* @var array |
|
329
|
|
|
*/ |
|
330
|
|
|
protected $_mainConfig = [ |
|
331
|
|
|
'main.currentVersion' => null, |
|
332
|
|
|
'main.currentApiVersion' => null, |
|
333
|
|
|
'main.language' => '__PHPMYFAQ_LANGUAGE__', |
|
334
|
|
|
'main.languageDetection' => 'true', |
|
335
|
|
|
'main.phpMyFAQToken' => null, |
|
336
|
|
|
'main.referenceURL' => '__PHPMYFAQ_REFERENCE_URL__', |
|
337
|
|
|
'main.administrationMail' => '[email protected]', |
|
338
|
|
|
'main.contactInformations' => '', |
|
339
|
|
|
'main.enableAdminLog' => 'true', |
|
340
|
|
|
'main.enableRewriteRules' => 'false', |
|
341
|
|
|
'main.enableUserTracking' => 'true', |
|
342
|
|
|
'main.metaDescription' => 'phpMyFAQ should be the answer for all questions in life', |
|
343
|
|
|
'main.metaKeywords' => '', |
|
344
|
|
|
'main.metaPublisher' => '__PHPMYFAQ_PUBLISHER__', |
|
345
|
|
|
'main.send2friendText' => '', |
|
346
|
|
|
'main.titleFAQ' => 'phpMyFAQ Codename Phobos', |
|
347
|
|
|
'main.urlValidateInterval' => '86400', |
|
348
|
|
|
'main.enableWysiwygEditor' => 'true', |
|
349
|
|
|
'main.enableWysiwygEditorFrontend' => 'false', |
|
350
|
|
|
'main.enableMarkdownEditor' => 'false', |
|
351
|
|
|
'main.templateSet' => 'default', |
|
352
|
|
|
'main.optionalMailAddress' => 'false', |
|
353
|
|
|
'main.dateFormat' => 'Y-m-d H:i', |
|
354
|
|
|
'main.maintenanceMode' => 'false', |
|
355
|
|
|
'main.enableGravatarSupport' => 'false', |
|
356
|
|
|
'main.enableRssFeeds' => 'true', |
|
357
|
|
|
'main.enableGzipCompression' => 'true', |
|
358
|
|
|
'main.enableLinkVerification' => 'true', |
|
359
|
|
|
'main.customPdfHeader' => '', |
|
360
|
|
|
'main.customPdfHFooter' => '', |
|
361
|
|
|
'main.enableSmartAnswering' => 'true', |
|
362
|
|
|
'main.enableCategoryRestrictions' => 'true', |
|
363
|
|
|
'main.enableSendToFriend' => 'true', |
|
364
|
|
|
'main.privacyURL' => '', |
|
365
|
|
|
'main.enableAutoUpdateHint' => 'true', |
|
366
|
|
|
|
|
367
|
|
|
'records.numberOfRecordsPerPage' => '10', |
|
368
|
|
|
'records.numberOfShownNewsEntries' => '3', |
|
369
|
|
|
'records.defaultActivation' => 'false', |
|
370
|
|
|
'records.defaultAllowComments' => 'false', |
|
371
|
|
|
'records.enableVisibilityQuestions' => 'false', |
|
372
|
|
|
'records.numberOfRelatedArticles' => '5', |
|
373
|
|
|
'records.orderby' => 'id', |
|
374
|
|
|
'records.sortby' => 'DESC', |
|
375
|
|
|
'records.orderingPopularFaqs' => 'visits', |
|
376
|
|
|
'records.disableAttachments' => 'true', |
|
377
|
|
|
'records.maxAttachmentSize' => '100000', |
|
378
|
|
|
'records.attachmentsPath' => 'attachments', |
|
379
|
|
|
'records.attachmentsStorageType' => '0', |
|
380
|
|
|
'records.enableAttachmentEncryption' => 'false', |
|
381
|
|
|
'records.defaultAttachmentEncKey' => '', |
|
382
|
|
|
'records.enableCloseQuestion' => 'false', |
|
383
|
|
|
'records.enableDeleteQuestion' => 'false', |
|
384
|
|
|
'records.autosaveActive' => 'false', |
|
385
|
|
|
'records.autosaveSecs' => '180', |
|
386
|
|
|
'records.randomSort' => 'false', |
|
387
|
|
|
'records.allowCommentsForGuests' => 'true', |
|
388
|
|
|
'records.allowQuestionsForGuests' => 'true', |
|
389
|
|
|
'records.allowNewFaqsForGuests' => 'true', |
|
390
|
|
|
'records.hideEmptyCategories' => 'false', |
|
391
|
|
|
'records.allowDownloadsForGuests' => 'false', |
|
392
|
|
|
'records.numberMaxStoredRevisions' => '10', |
|
393
|
|
|
'records.enableAutoRevisions' => 'false', |
|
394
|
|
|
|
|
395
|
|
|
'search.numberSearchTerms' => '10', |
|
396
|
|
|
'search.relevance' => 'thema,content,keywords', |
|
397
|
|
|
'search.enableRelevance' => 'false', |
|
398
|
|
|
'search.enableHighlighting' => 'true', |
|
399
|
|
|
'search.searchForSolutionId' => 'true', |
|
400
|
|
|
'search.enableElasticsearch' => 'false', |
|
401
|
|
|
|
|
402
|
|
|
'security.permLevel' => 'basic', |
|
403
|
|
|
'security.ipCheck' => 'false', |
|
404
|
|
|
'security.enableLoginOnly' => 'false', |
|
405
|
|
|
'security.bannedIPs' => '', |
|
406
|
|
|
'security.ssoSupport' => 'false', |
|
407
|
|
|
'security.ssoLogoutRedirect' => '', |
|
408
|
|
|
'security.useSslForLogins' => 'false', |
|
409
|
|
|
'security.useSslOnly' => 'false', |
|
410
|
|
|
'security.forcePasswordUpdate' => 'false', |
|
411
|
|
|
'security.enableRegistration' => 'true', |
|
412
|
|
|
|
|
413
|
|
|
'spam.checkBannedWords' => 'true', |
|
414
|
|
|
'spam.enableCaptchaCode' => null, |
|
415
|
|
|
'spam.enableSafeEmail' => 'true', |
|
416
|
|
|
'spam.manualActivation' => 'true', |
|
417
|
|
|
|
|
418
|
|
|
'socialnetworks.enableTwitterSupport' => 'false', |
|
419
|
|
|
'socialnetworks.twitterConsumerKey' => '', |
|
420
|
|
|
'socialnetworks.twitterConsumerSecret' => '', |
|
421
|
|
|
'socialnetworks.twitterAccessTokenKey' => '', |
|
422
|
|
|
'socialnetworks.twitterAccessTokenSecret' => '', |
|
423
|
|
|
'socialnetworks.enableFacebookSupport' => 'false', |
|
424
|
|
|
'socialnetworks.disableAll' => 'false', |
|
425
|
|
|
|
|
426
|
|
|
'seo.metaTagsHome' => 'index, follow', |
|
427
|
|
|
'seo.metaTagsFaqs' => 'index, follow', |
|
428
|
|
|
'seo.metaTagsCategories' => 'index, follow', |
|
429
|
|
|
'seo.metaTagsPages' => 'index, follow', |
|
430
|
|
|
'seo.metaTagsAdmin' => 'noindex, nofollow', |
|
431
|
|
|
'seo.enableXMLSitemap' => 'true', |
|
432
|
|
|
|
|
433
|
|
|
'mail.remoteSMTP' => 'false', |
|
434
|
|
|
'mail.remoteSMTPServer' => '', |
|
435
|
|
|
'mail.remoteSMTPUsername' => '', |
|
436
|
|
|
'mail.remoteSMTPPassword' => '', |
|
437
|
|
|
|
|
438
|
|
|
'ldap.ldapSupport' => 'false', |
|
439
|
|
|
'ldap.ldap_mapping.name' => 'cn', |
|
440
|
|
|
'ldap.ldap_mapping.username' => 'samAccountName', |
|
441
|
|
|
'ldap.ldap_mapping.mail' => 'mail', |
|
442
|
|
|
'ldap.ldap_mapping.memberOf' => '', |
|
443
|
|
|
'ldap.ldap_use_domain_prefix' => 'true', |
|
444
|
|
|
'ldap.ldap_options.LDAP_OPT_PROTOCOL_VERSION' => '3', |
|
445
|
|
|
'ldap.ldap_options.LDAP_OPT_REFERRALS' => '0', |
|
446
|
|
|
'ldap.ldap_use_memberOf' => 'false', |
|
447
|
|
|
'ldap.ldap_use_sasl' => 'false', |
|
448
|
|
|
'ldap.ldap_use_multiple_servers' => 'false', |
|
449
|
|
|
'ldap.ldap_use_anonymous_login' => 'false', |
|
450
|
|
|
'ldap.ldap_use_dynamic_login' => 'false', |
|
451
|
|
|
'ldap.ldap_dynamic_login_attribute' => 'uid' |
|
452
|
|
|
]; |
|
453
|
|
|
|
|
454
|
|
|
/** |
|
455
|
|
|
* Constructor. |
|
456
|
|
|
* |
|
457
|
|
|
*/ |
|
458
|
|
|
public function __construct() |
|
459
|
|
|
{ |
|
460
|
|
|
$this->system = new System(); |
|
461
|
|
|
$dynMainConfig = [ |
|
462
|
|
|
'main.currentVersion' => System::getVersion(), |
|
463
|
|
|
'main.currentApiVersion' => System::getApiVersion(), |
|
464
|
|
|
'main.phpMyFAQToken' => md5(uniqid(rand())), |
|
465
|
|
|
'spam.enableCaptchaCode' => (extension_loaded('gd') ? 'true' : 'false') |
|
466
|
|
|
]; |
|
467
|
|
|
$this->_mainConfig = array_merge($this->_mainConfig, $dynMainConfig); |
|
468
|
|
|
} |
|
469
|
|
|
|
|
470
|
|
|
/** |
|
471
|
|
|
* Check absolutely necessary stuff and die. |
|
472
|
|
|
*/ |
|
473
|
|
|
public function checkBasicStuff() |
|
474
|
|
|
{ |
|
475
|
|
|
if (!$this->checkMinimumPhpVersion()) { |
|
476
|
|
|
printf( |
|
477
|
|
|
'<p class="alert alert-danger">Sorry, but you need PHP %s or later!</p>', |
|
478
|
|
|
System::VERSION_MINIMUM_PHP |
|
479
|
|
|
); |
|
480
|
|
|
System::renderFooter(); |
|
481
|
|
|
} |
|
482
|
|
|
|
|
483
|
|
|
if (!function_exists('date_default_timezone_set')) { |
|
484
|
|
|
echo '<p class="alert alert-danger">Sorry, but setting a default timezone doesn\'t work in your environment!</p>'; |
|
485
|
|
|
System::renderFooter(); |
|
486
|
|
|
} |
|
487
|
|
|
|
|
488
|
|
View Code Duplication |
if (!$this->system->checkDatabase()) { |
|
489
|
|
|
echo '<p class="alert alert-danger">No supported database detected! Please install one of the following'. |
|
490
|
|
|
' database systems and enable the corresponding PHP extension in php.ini:</p>'; |
|
491
|
|
|
echo '<ul>'; |
|
492
|
|
|
foreach ($this->system->getSupportedDatabases() as $database) { |
|
493
|
|
|
printf(' <li>%s</li>', $database[1]); |
|
494
|
|
|
} |
|
495
|
|
|
echo '</ul>'; |
|
496
|
|
|
System::renderFooter(); |
|
497
|
|
|
} |
|
498
|
|
|
|
|
499
|
|
View Code Duplication |
if (!$this->system->checkRequiredExtensions()) { |
|
500
|
|
|
echo '<p class="alert alert-danger">The following extensions are missing! Please enable the PHP extension(s) in '. |
|
501
|
|
|
'php.ini.</p>'; |
|
502
|
|
|
echo '<ul>'; |
|
503
|
|
|
foreach ($this->system->getMissingExtensions() as $extension) { |
|
504
|
|
|
printf(' <li>ext/%s</li>', $extension); |
|
505
|
|
|
} |
|
506
|
|
|
echo '</ul>'; |
|
507
|
|
|
System::renderFooter(); |
|
508
|
|
|
} |
|
509
|
|
|
|
|
510
|
|
|
if (!$this->system->checkphpMyFAQInstallation()) { |
|
511
|
|
|
echo '<p class="alert alert-danger">The file <code>config/database.php</code> was detected. It seems'. |
|
512
|
|
|
' you\'re already running a version of phpMyFAQ. Please run the <a href="update.php">update script</a>.'. |
|
513
|
|
|
'</p>'; |
|
514
|
|
|
System::renderFooter(); |
|
515
|
|
|
} |
|
516
|
|
|
} |
|
517
|
|
|
|
|
518
|
|
|
/** |
|
519
|
|
|
* Checks for the minimum PHP requirement and if the database credentials file is readable. |
|
520
|
|
|
* |
|
521
|
|
|
* @param string $databaseType |
|
522
|
|
|
* |
|
523
|
|
|
* @return void |
|
524
|
|
|
*/ |
|
525
|
|
|
public function checkPreUpgrade(string $databaseType) |
|
526
|
|
|
{ |
|
527
|
|
|
if (!$this->checkMinimumPhpVersion()) { |
|
528
|
|
|
printf( |
|
529
|
|
|
'<p class="alert alert-danger">Sorry, but you need PHP %s or later!</p>', |
|
530
|
|
|
System::VERSION_MINIMUM_PHP |
|
531
|
|
|
); |
|
532
|
|
|
System::renderFooter(); |
|
533
|
|
|
} |
|
534
|
|
|
|
|
535
|
|
|
if (!is_readable(PMF_ROOT_DIR.'/inc/data.php') && !is_readable(PMF_ROOT_DIR.'/config/database.php')) { |
|
536
|
|
|
echo '<p class="alert alert-danger">It seems you never run a version of phpMyFAQ.<br>'. |
|
537
|
|
|
'Please use the <a href="setup.php">install script</a>.</p>'; |
|
538
|
|
|
System::renderFooter(); |
|
539
|
|
|
} |
|
540
|
|
|
|
|
541
|
|
|
if ('' !== $databaseType) { |
|
542
|
|
|
$databaseFound = false; |
|
543
|
|
|
foreach ($this->system->getSupportedDatabases() as $database => $values) { |
|
544
|
|
|
if ($database === $databaseType) { |
|
545
|
|
|
$databaseFound = true; |
|
546
|
|
|
break; |
|
547
|
|
|
} |
|
548
|
|
|
} |
|
549
|
|
|
if (!$databaseFound) { |
|
550
|
|
|
echo '<p class="alert alert-danger">It seems you\'re using an unsupported database version.<br>'. |
|
551
|
|
|
'We found '.ucfirst($database).'<br>'. |
|
|
|
|
|
|
552
|
|
|
'Please use the change the database type in <code>config/database.php</code>.</p>'; |
|
553
|
|
|
System::renderFooter(); |
|
554
|
|
|
} |
|
555
|
|
|
} |
|
556
|
|
|
} |
|
557
|
|
|
|
|
558
|
|
|
/** |
|
559
|
|
|
* Checks the minimum required PHP version, defined in System. |
|
560
|
|
|
* |
|
561
|
|
|
* @return bool |
|
562
|
|
|
*/ |
|
563
|
|
|
public function checkMinimumPhpVersion() |
|
564
|
|
|
{ |
|
565
|
|
|
if (version_compare(PHP_VERSION, System::VERSION_MINIMUM_PHP, '<')) { |
|
566
|
|
|
return false; |
|
567
|
|
|
} |
|
568
|
|
|
|
|
569
|
|
|
return true; |
|
570
|
|
|
} |
|
571
|
|
|
|
|
572
|
|
|
/** |
|
573
|
|
|
* Checks if the file permissions are okay. |
|
574
|
|
|
*/ |
|
575
|
|
|
public function checkFilesystemPermissions() |
|
576
|
|
|
{ |
|
577
|
|
|
$instanceSetup = new Setup(); |
|
578
|
|
|
$instanceSetup->setRootDir(PMF_ROOT_DIR); |
|
579
|
|
|
|
|
580
|
|
|
$dirs = ['/attachments', '/config', '/data', '/images']; |
|
581
|
|
|
$failedDirs = $instanceSetup->checkDirs($dirs); |
|
582
|
|
|
$numDirs = sizeof($failedDirs); |
|
583
|
|
|
|
|
584
|
|
|
if (1 <= $numDirs) { |
|
585
|
|
|
printf( |
|
586
|
|
|
'<p class="alert alert-danger">The following %s could not be created or %s not writable:</p><ul>', |
|
587
|
|
|
(1 < $numDirs) ? 'directories' : 'directory', |
|
588
|
|
|
(1 < $numDirs) ? 'are' : 'is' |
|
589
|
|
|
); |
|
590
|
|
|
foreach ($failedDirs as $dir) { |
|
591
|
|
|
echo "<li>$dir</li>\n"; |
|
592
|
|
|
} |
|
593
|
|
|
printf( |
|
594
|
|
|
'</ul><p class="alert alert-danger">Please create %s manually and/or change access to chmod 775 (or '. |
|
595
|
|
|
'greater if necessary).</p>', |
|
596
|
|
|
(1 < $numDirs) ? 'them' : 'it' |
|
597
|
|
|
); |
|
598
|
|
|
System::renderFooter(); |
|
599
|
|
|
} |
|
600
|
|
|
} |
|
601
|
|
|
|
|
602
|
|
|
/** |
|
603
|
|
|
* Checks some non critical settings and print some hints. |
|
604
|
|
|
* |
|
605
|
|
|
* @todo We should return an array of messages |
|
606
|
|
|
*/ |
|
607
|
|
|
public function checkNoncriticalSettings() |
|
608
|
|
|
{ |
|
609
|
|
|
if ((@ini_get('safe_mode') == 'On' || @ini_get('safe_mode') === 1)) { |
|
610
|
|
|
echo '<p class="alert alert-danger">The PHP safe mode is enabled. You may have problems when phpMyFAQ tries to write '. |
|
611
|
|
|
' in some directories.</p>'; |
|
612
|
|
|
} |
|
613
|
|
|
if (!extension_loaded('gd')) { |
|
614
|
|
|
echo '<p class="alert alert-danger">You don\'t have GD support enabled in your PHP installation. Please enable GD '. |
|
615
|
|
|
'support in your php.ini file otherwise you can\'t use Captchas for spam protection.</p>'; |
|
616
|
|
|
} |
|
617
|
|
|
if (!function_exists('imagettftext')) { |
|
618
|
|
|
echo '<p class="alert alert-danger">You don\'t have Freetype support enabled in the GD extension of your PHP '. |
|
619
|
|
|
'installation. Please enable Freetype support in GD extension otherwise the Captchas for spam '. |
|
620
|
|
|
'protection will be quite easy to break.</p>'; |
|
621
|
|
|
} |
|
622
|
|
|
if (!extension_loaded('curl') || !extension_loaded('openssl')) { |
|
623
|
|
|
echo '<p class="alert alert-danger">You don\'t have cURL and/or OpenSSL support enabled in your PHP installation. '. |
|
624
|
|
|
'Please enable cURL and/or OpenSSL support in your php.ini file otherwise you can\'t use the Twitter '. |
|
625
|
|
|
' support or Elasticsearch.</p>'; |
|
626
|
|
|
} |
|
627
|
|
|
if (!extension_loaded('fileinfo')) { |
|
628
|
|
|
echo '<p class="alert alert-danger">You don\'t have Fileinfo support enabled in your PHP installation. '. |
|
629
|
|
|
'Please enable Fileinfo support in your php.ini file otherwise you can\'t use our backup/restore '. |
|
630
|
|
|
'functionality.</p>'; |
|
631
|
|
|
} |
|
632
|
|
|
} |
|
633
|
|
|
|
|
634
|
|
|
/** |
|
635
|
|
|
* Checks if we can store data via sessions. If not, e.g. an user can't |
|
636
|
|
|
* login into the admin section. |
|
637
|
|
|
* |
|
638
|
|
|
* @return bool |
|
639
|
|
|
*/ |
|
640
|
|
|
public function checkSessionSettings() |
|
641
|
|
|
{ |
|
642
|
|
|
return true; |
|
643
|
|
|
} |
|
644
|
|
|
|
|
645
|
|
|
/** |
|
646
|
|
|
* Checks if phpMyFAQ database tables are available |
|
647
|
|
|
* @param Driver $database |
|
648
|
|
|
* @throws |
|
649
|
|
|
*/ |
|
650
|
|
|
public function checkAvailableDatabaseTables(Driver $database) |
|
651
|
|
|
{ |
|
652
|
|
|
$query = sprintf( |
|
653
|
|
|
'SELECT 1 FROM %s%s LIMIT 1', |
|
654
|
|
|
Db::getTablePrefix(), |
|
655
|
|
|
'faqconfig' |
|
656
|
|
|
); |
|
657
|
|
|
$result = $database->query($query); |
|
658
|
|
|
if ($database->numRows($result) === 0) { |
|
659
|
|
|
echo "<p class=\"alert alert-danger\"><strong>Error:</strong> Table faqconfig not found.</p>\n"; |
|
660
|
|
|
System::renderFooter(true); |
|
661
|
|
|
} |
|
662
|
|
|
} |
|
663
|
|
|
|
|
664
|
|
|
/** |
|
665
|
|
|
* Starts the installation. |
|
666
|
|
|
* |
|
667
|
|
|
* @param array $setup |
|
668
|
|
|
* @throws |
|
669
|
|
|
*/ |
|
670
|
|
|
public function startInstall(array $setup = null) |
|
671
|
|
|
{ |
|
672
|
|
|
$query = $uninst = $dbSetup = []; |
|
673
|
|
|
|
|
674
|
|
|
// Check table prefix |
|
675
|
|
|
$dbSetup['dbPrefix'] = Filter::filterInput(INPUT_POST, 'sqltblpre', FILTER_SANITIZE_STRING, ''); |
|
676
|
|
|
if ('' !== $dbSetup['dbPrefix']) { |
|
677
|
|
|
Db::setTablePrefix($dbSetup['dbPrefix']); |
|
678
|
|
|
} |
|
679
|
|
|
|
|
680
|
|
|
// Check database entries |
|
681
|
|
|
$dbSetup['dbType'] = Filter::filterInput(INPUT_POST, 'sql_type', FILTER_SANITIZE_STRING, $setup['dbType']); |
|
682
|
|
|
if (!is_null($dbSetup['dbType'])) { |
|
683
|
|
|
$dbSetup['dbType'] = trim($dbSetup['dbType']); |
|
684
|
|
|
if (!file_exists(PMF_SRC_DIR.'/phpMyFAQ/Instance/Database/'.ucfirst($dbSetup['dbType']).'.php')) { |
|
685
|
|
|
printf( |
|
686
|
|
|
'<p class="alert alert-danger"><strong>Error:</strong> Invalid server type: %s</p>', |
|
687
|
|
|
$dbSetup['dbType'] |
|
688
|
|
|
); |
|
689
|
|
|
System::renderFooter(true); |
|
690
|
|
|
} |
|
691
|
|
|
} else { |
|
692
|
|
|
echo "<p class=\"alert alert-danger\"><strong>Error:</strong> Please select a database type.</p>\n"; |
|
693
|
|
|
System::renderFooter(true); |
|
694
|
|
|
} |
|
695
|
|
|
|
|
696
|
|
|
$dbSetup['dbServer'] = Filter::filterInput(INPUT_POST, 'sql_server', FILTER_SANITIZE_STRING, ''); |
|
697
|
|
View Code Duplication |
if (is_null($dbSetup['dbServer']) && !System::isSqlite($dbSetup['dbType'])) { |
|
698
|
|
|
echo "<p class=\"alert alert-danger\"><strong>Error:</strong> Please add a database server.</p>\n"; |
|
699
|
|
|
System::renderFooter(true); |
|
700
|
|
|
} |
|
701
|
|
|
|
|
702
|
|
|
$dbSetup['dbUser'] = Filter::filterInput(INPUT_POST, 'sql_user', FILTER_SANITIZE_STRING, ''); |
|
703
|
|
View Code Duplication |
if (is_null($dbSetup['dbUser']) && !System::isSqlite($dbSetup['dbType'])) { |
|
704
|
|
|
echo "<p class=\"alert alert-danger\"><strong>Error:</strong> Please add a database username.</p>\n"; |
|
705
|
|
|
System::renderFooter(true); |
|
706
|
|
|
} |
|
707
|
|
|
|
|
708
|
|
|
$dbSetup['dbPassword'] = Filter::filterInput(INPUT_POST, 'sql_password', FILTER_UNSAFE_RAW, ''); |
|
709
|
|
|
if (is_null($dbSetup['dbPassword']) && !System::isSqlite($dbSetup['dbType'])) { |
|
710
|
|
|
// Password can be empty... |
|
711
|
|
|
$dbSetup['dbPassword'] = ''; |
|
712
|
|
|
} |
|
713
|
|
|
|
|
714
|
|
|
$dbSetup['dbDatabaseName'] = Filter::filterInput(INPUT_POST, 'sql_db', FILTER_SANITIZE_STRING); |
|
715
|
|
View Code Duplication |
if (is_null($dbSetup['dbDatabaseName']) && !System::isSqlite($dbSetup['dbType'])) { |
|
716
|
|
|
echo "<p class=\"alert alert-danger\"><strong>Error:</strong> Please add a database name.</p>\n"; |
|
717
|
|
|
System::renderFooter(true); |
|
718
|
|
|
} |
|
719
|
|
|
|
|
720
|
|
|
if (System::isSqlite($dbSetup['dbType'])) { |
|
721
|
|
|
$dbSetup['dbServer'] = Filter::filterInput( |
|
722
|
|
|
INPUT_POST, |
|
723
|
|
|
'sql_sqlitefile', |
|
724
|
|
|
FILTER_SANITIZE_STRING, |
|
725
|
|
|
$setup['dbServer'] |
|
726
|
|
|
); |
|
727
|
|
|
if (is_null($dbSetup['dbServer'])) { |
|
728
|
|
|
echo "<p class=\"alert alert-danger\"><strong>Error:</strong> Please add a SQLite database filename.</p>\n"; |
|
729
|
|
|
System::renderFooter(true); |
|
730
|
|
|
} |
|
731
|
|
|
} |
|
732
|
|
|
|
|
733
|
|
|
// check database connection |
|
734
|
|
|
Db::setTablePrefix($dbSetup['dbPrefix']); |
|
735
|
|
|
$db = Db::factory($dbSetup['dbType']); |
|
736
|
|
|
try { |
|
737
|
|
|
$db->connect($dbSetup['dbServer'], $dbSetup['dbUser'], $dbSetup['dbPassword'], $dbSetup['dbDatabaseName']); |
|
738
|
|
|
} catch (Exception $e) { |
|
739
|
|
|
printf("<p class=\"alert alert-danger\"><strong>DB Error:</strong> %s</p>\n", $e->getMessage()); |
|
740
|
|
|
} |
|
741
|
|
|
if (!$db) { |
|
742
|
|
|
System::renderFooter(true); |
|
743
|
|
|
} |
|
744
|
|
|
|
|
745
|
|
|
$configuration = new Configuration($db); |
|
746
|
|
|
|
|
747
|
|
|
// |
|
748
|
|
|
// Check LDAP if enabled |
|
749
|
|
|
// |
|
750
|
|
|
$ldapEnabled = Filter::filterInput(INPUT_POST, 'ldap_enabled', FILTER_SANITIZE_STRING); |
|
751
|
|
|
if (extension_loaded('ldap') && !is_null($ldapEnabled)) { |
|
752
|
|
|
$ldapSetup = []; |
|
753
|
|
|
|
|
754
|
|
|
// check LDAP entries |
|
755
|
|
|
$ldapSetup['ldapServer'] = Filter::filterInput(INPUT_POST, 'ldap_server', FILTER_SANITIZE_STRING); |
|
756
|
|
|
if (is_null($ldapSetup['ldapServer'])) { |
|
757
|
|
|
echo "<p class=\"alert alert-danger\"><strong>Error:</strong> Please add a LDAP server.</p>\n"; |
|
758
|
|
|
System::renderFooter(true); |
|
759
|
|
|
} |
|
760
|
|
|
|
|
761
|
|
|
$ldapSetup['ldapPort'] = Filter::filterInput(INPUT_POST, 'ldap_port', FILTER_VALIDATE_INT); |
|
762
|
|
|
if (is_null($ldapSetup['ldapPort'])) { |
|
763
|
|
|
echo "<p class=\"alert alert-danger\"><strong>Error:</strong> Please add a LDAP port.</p>\n"; |
|
764
|
|
|
System::renderFooter(true); |
|
765
|
|
|
} |
|
766
|
|
|
|
|
767
|
|
|
$ldapSetup['ldapBase'] = Filter::filterInput(INPUT_POST, 'ldap_base', FILTER_SANITIZE_STRING); |
|
768
|
|
|
if (is_null($ldapSetup['ldapBase'])) { |
|
769
|
|
|
echo "<p class=\"alert alert-danger\"><strong>Error:</strong> Please add a LDAP base search DN.</p>\n"; |
|
770
|
|
|
System::renderFooter(true); |
|
771
|
|
|
} |
|
772
|
|
|
|
|
773
|
|
|
// LDAP User and LDAP password are optional |
|
774
|
|
|
$ldapSetup['ldapUser'] = Filter::filterInput(INPUT_POST, 'ldap_user', FILTER_SANITIZE_STRING, ''); |
|
775
|
|
|
$ldapSetup['ldapPassword'] = Filter::filterInput(INPUT_POST, 'ldap_password', FILTER_SANITIZE_STRING, ''); |
|
776
|
|
|
|
|
777
|
|
|
// set LDAP Config to prevent DB query |
|
778
|
|
|
foreach ($this->_mainConfig as $configKey => $configValue) { |
|
779
|
|
|
if (strpos($configKey, 'ldap.') !== false) { |
|
780
|
|
|
$configuration->config[$configKey] = $configValue; |
|
781
|
|
|
} |
|
782
|
|
|
} |
|
783
|
|
|
|
|
784
|
|
|
// check LDAP connection |
|
785
|
|
|
$ldap = new Ldap($configuration); |
|
786
|
|
|
$ldap->connect( |
|
787
|
|
|
$ldapSetup['ldapServer'], |
|
788
|
|
|
$ldapSetup['ldapPort'], |
|
789
|
|
|
$ldapSetup['ldapBase'], |
|
790
|
|
|
$ldapSetup['ldapUser'], |
|
791
|
|
|
$ldapSetup['ldapPassword'] |
|
792
|
|
|
); |
|
793
|
|
|
if (!$ldap) { |
|
794
|
|
|
echo '<p class="alert alert-danger"><strong>LDAP Error:</strong> '.$ldap->error()."</p>\n"; |
|
795
|
|
|
System::renderFooter(true); |
|
796
|
|
|
} |
|
797
|
|
|
} |
|
798
|
|
|
|
|
799
|
|
|
// |
|
800
|
|
|
// Check Elasticsearch if enabled |
|
801
|
|
|
// |
|
802
|
|
|
$esEnabled = Filter::filterInput(INPUT_POST, 'elasticsearch_enabled', FILTER_SANITIZE_STRING); |
|
803
|
|
|
if (!is_null($esEnabled)) { |
|
804
|
|
|
$esSetup = []; |
|
805
|
|
|
$esHostFilter = [ |
|
806
|
|
|
'elasticsearch_server' => [ |
|
807
|
|
|
'filter' => FILTER_SANITIZE_STRING, |
|
808
|
|
|
'flags' => FILTER_REQUIRE_ARRAY |
|
809
|
|
|
] |
|
810
|
|
|
]; |
|
811
|
|
|
|
|
812
|
|
|
// ES hosts |
|
813
|
|
|
$esHosts = Filter::filterInputArray(INPUT_POST, $esHostFilter); |
|
814
|
|
|
if (is_null($esHosts)) { |
|
815
|
|
|
echo "<p class=\"alert alert-danger\"><strong>Error:</strong> Please add at least one Elasticsearch host.</p>\n"; |
|
816
|
|
|
System::renderFooter(true); |
|
817
|
|
|
} |
|
818
|
|
|
|
|
819
|
|
|
$esSetup['hosts'] = $esHosts['elasticsearch_server']; |
|
820
|
|
|
|
|
821
|
|
|
// ES Index name |
|
822
|
|
|
$esSetup['index'] = Filter::filterInput(INPUT_POST, 'elasticsearch_index', FILTER_SANITIZE_STRING); |
|
823
|
|
|
if (is_null($esSetup['index'])) { |
|
824
|
|
|
echo "<p class=\"alert alert-danger\"><strong>Error:</strong> Please add an Elasticsearch index name.</p>\n"; |
|
825
|
|
|
System::renderFooter(true); |
|
826
|
|
|
} |
|
827
|
|
|
|
|
828
|
|
|
$psr4Loader = new ClassLoader(); |
|
829
|
|
|
$psr4Loader->addPsr4('Elasticsearch\\', PMF_SRC_DIR.'/libs/elasticsearch/src/Elasticsearch'); |
|
830
|
|
|
$psr4Loader->addPsr4('GuzzleHttp\\Ring\\', PMF_SRC_DIR.'/libs/guzzlehttp/ringphp/src'); |
|
831
|
|
|
$psr4Loader->addPsr4('Monolog\\', PMF_SRC_DIR.'/libs/monolog/src/Monolog'); |
|
832
|
|
|
$psr4Loader->addPsr4('Psr\\', PMF_SRC_DIR.'/libs/psr/log/Psr'); |
|
833
|
|
|
$psr4Loader->addPsr4('React\\Promise\\', PMF_SRC_DIR.'/libs/react/promise/src'); |
|
834
|
|
|
$psr4Loader->register(); |
|
835
|
|
|
|
|
836
|
|
|
// check LDAP connection |
|
837
|
|
|
$esHosts = array_values($esHosts['elasticsearch_server']); |
|
838
|
|
|
$esClient = ClientBuilder::create() |
|
839
|
|
|
->setHosts($esHosts) |
|
840
|
|
|
->build(); |
|
841
|
|
|
|
|
842
|
|
|
if (!$esClient) { |
|
843
|
|
|
echo '<p class="alert alert-danger"><strong>Elasticsearch Error:</strong> No connection.</p>'; |
|
844
|
|
|
System::renderFooter(true); |
|
845
|
|
|
} |
|
846
|
|
|
} else { |
|
847
|
|
|
$esSetup = []; |
|
848
|
|
|
} |
|
849
|
|
|
|
|
850
|
|
|
// check loginname |
|
851
|
|
|
$loginname = Filter::filterInput(INPUT_POST, 'loginname', FILTER_SANITIZE_STRING, $setup['loginname']); |
|
852
|
|
|
if (is_null($loginname)) { |
|
853
|
|
|
echo '<p class="alert alert-danger"><strong>Error:</strong> Please add a loginname for your account.</p>'; |
|
854
|
|
|
System::renderFooter(true); |
|
855
|
|
|
} |
|
856
|
|
|
|
|
857
|
|
|
// check user entries |
|
858
|
|
|
$password = Filter::filterInput(INPUT_POST, 'password', FILTER_SANITIZE_STRING, $setup['password']); |
|
859
|
|
|
if (is_null($password)) { |
|
860
|
|
|
echo '<p class="alert alert-danger"><strong>Error:</strong> Please add a password for the your account.</p>'; |
|
861
|
|
|
System::renderFooter(true); |
|
862
|
|
|
} |
|
863
|
|
|
|
|
864
|
|
|
$password_retyped = Filter::filterInput( |
|
865
|
|
|
INPUT_POST, |
|
866
|
|
|
'password_retyped', |
|
867
|
|
|
FILTER_SANITIZE_STRING, |
|
868
|
|
|
$setup['password_retyped'] |
|
869
|
|
|
); |
|
870
|
|
|
if (is_null($password_retyped)) { |
|
871
|
|
|
echo '<p class="alert alert-danger"><strong>Error:</strong> Please add a retyped password.</p>'; |
|
872
|
|
|
System::renderFooter(true); |
|
873
|
|
|
} |
|
874
|
|
|
|
|
875
|
|
|
if (strlen($password) <= 5 || strlen($password_retyped) <= 5) { |
|
876
|
|
|
echo '<p class="alert alert-danger"><strong>Error:</strong> Your password and retyped password are too short.'. |
|
877
|
|
|
' Please set your password and your retyped password with a minimum of 6 characters.</p>'; |
|
878
|
|
|
System::renderFooter(true); |
|
879
|
|
|
} |
|
880
|
|
|
if ($password != $password_retyped) { |
|
881
|
|
|
echo '<p class="alert alert-danger"><strong>Error:</strong> Your password and retyped password are not equal.'. |
|
882
|
|
|
' Please check your password and your retyped password.</p>'; |
|
883
|
|
|
System::renderFooter(true); |
|
884
|
|
|
} |
|
885
|
|
|
|
|
886
|
|
|
$language = Filter::filterInput(INPUT_POST, 'language', FILTER_SANITIZE_STRING, 'en'); |
|
887
|
|
|
$realname = Filter::filterInput(INPUT_POST, 'realname', FILTER_SANITIZE_STRING, ''); |
|
888
|
|
|
$email = Filter::filterInput(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL, ''); |
|
889
|
|
|
$permLevel = Filter::filterInput(INPUT_POST, 'permLevel', FILTER_SANITIZE_STRING, 'basic'); |
|
890
|
|
|
|
|
891
|
|
|
$rootDir = isset($setup['rootDir']) ? $setup['rootDir'] : PMF_ROOT_DIR; |
|
892
|
|
|
|
|
893
|
|
|
$instanceSetup = new Setup(); |
|
894
|
|
|
$instanceSetup->setRootDir($rootDir); |
|
895
|
|
|
|
|
896
|
|
|
// Write the DB variables in database.php |
|
897
|
|
|
if (!$instanceSetup->createDatabaseFile($dbSetup)) { |
|
898
|
|
|
echo '<p class="alert alert-danger"><strong>Error:</strong> Setup cannot write to ./config/database.php.</p>'; |
|
899
|
|
|
$this->system->cleanInstallation(); |
|
900
|
|
|
System::renderFooter(true); |
|
901
|
|
|
} |
|
902
|
|
|
|
|
903
|
|
|
// check LDAP is enabled |
|
904
|
|
|
if (extension_loaded('ldap') && !is_null($ldapEnabled) && count($ldapSetup)) { |
|
905
|
|
|
if (!$instanceSetup->createLdapFile($ldapSetup, '')) { |
|
906
|
|
|
echo '<p class="alert alert-danger"><strong>Error:</strong> Setup cannot write to ./config/ldap.php.</p>'; |
|
907
|
|
|
$this->system->cleanInstallation(); |
|
908
|
|
|
System::renderFooter(true); |
|
909
|
|
|
} |
|
910
|
|
|
} |
|
911
|
|
|
|
|
912
|
|
|
// check if Elasticsearch is enabled |
|
913
|
|
View Code Duplication |
if (!is_null($esEnabled) && count($esSetup)) { |
|
914
|
|
|
if (!$instanceSetup->createElasticsearchFile($esSetup, '')) { |
|
915
|
|
|
echo '<p class="alert alert-danger"><strong>Error:</strong> Setup cannot write to ./config/elasticsearch.php.</p>'; |
|
916
|
|
|
$this->system->cleanInstallation(); |
|
917
|
|
|
System::renderFooter(true); |
|
918
|
|
|
} |
|
919
|
|
|
} |
|
920
|
|
|
|
|
921
|
|
|
// connect to the database using config/database.php |
|
922
|
|
|
require $rootDir.'/config/database.php'; |
|
923
|
|
|
try { |
|
924
|
|
|
$db = Db::factory($dbSetup['dbType']); |
|
925
|
|
|
} catch (Exception $exception) { |
|
926
|
|
|
printf("<p class=\"alert alert-danger\"><strong>DB Error:</strong> %s</p>\n", $exception->getMessage()); |
|
927
|
|
|
$this->system->cleanInstallation(); |
|
928
|
|
|
System::renderFooter(true); |
|
929
|
|
|
} |
|
930
|
|
|
|
|
931
|
|
|
$db->connect($DB['server'], $DB['user'], $DB['password'], $DB['db']); |
|
|
|
|
|
|
932
|
|
|
if (!$db) { |
|
933
|
|
|
printf("<p class=\"alert alert-danger\"><strong>DB Error:</strong> %s</p>\n", $db->error()); |
|
934
|
|
|
$this->system->cleanInstallation(); |
|
935
|
|
|
System::renderFooter(true); |
|
936
|
|
|
} |
|
937
|
|
|
try { |
|
938
|
|
|
$databaseInstaller = Database::factory($configuration, $dbSetup['dbType']); |
|
939
|
|
|
} catch (Exception $exception) { |
|
940
|
|
|
printf("<p class=\"alert alert-danger\"><strong>DB Error:</strong> %s</p>\n", $exception->getMessage()); |
|
941
|
|
|
$this->system->cleanInstallation(); |
|
942
|
|
|
System::renderFooter(true); |
|
943
|
|
|
} |
|
944
|
|
|
|
|
945
|
|
|
$databaseInstaller->createTables($dbSetup['dbPrefix']); |
|
946
|
|
|
|
|
947
|
|
|
$stopwords = new Stopwords($configuration); |
|
948
|
|
|
$stopwords->executeInsertQueries($dbSetup['dbPrefix']); |
|
949
|
|
|
|
|
950
|
|
|
$this->system->setDatabase($db); |
|
951
|
|
|
|
|
952
|
|
|
// Erase any table before starting creating the required ones |
|
953
|
|
|
if (!System::isSqlite($dbSetup['dbType'])) { |
|
954
|
|
|
$this->system->dropTables($uninst); |
|
955
|
|
|
} |
|
956
|
|
|
|
|
957
|
|
|
// Start creating the required tables |
|
958
|
|
|
$count = 0; |
|
959
|
|
|
foreach ($query as $executeQuery) { |
|
960
|
|
|
$result = @$db->query($executeQuery); |
|
961
|
|
|
if (!$result) { |
|
962
|
|
|
echo '<p class="alert alert-danger"><strong>Error:</strong> Please install your version of phpMyFAQ once again or send |
|
963
|
|
|
us a <a href=\"https://www.phpmyfaq.de\" target=\"_blank\">bug report</a>.</p>'; |
|
964
|
|
|
printf('<p class="alert alert-danger"><strong>DB error:</strong> %s</p>', $db->error()); |
|
965
|
|
|
printf('<code>%s</code>', htmlentities($executeQuery)); |
|
966
|
|
|
$this->system->dropTables($uninst); |
|
967
|
|
|
$this->system->cleanInstallation(); |
|
968
|
|
|
System::renderFooter(true); |
|
969
|
|
|
} |
|
970
|
|
|
usleep(1000); |
|
971
|
|
|
++$count; |
|
972
|
|
|
if (!($count%10)) { |
|
973
|
|
|
echo '| '; |
|
974
|
|
|
} |
|
975
|
|
|
} |
|
976
|
|
|
|
|
977
|
|
|
$link = new Link(null, $configuration); |
|
978
|
|
|
|
|
979
|
|
|
// add main configuration, add personal settings |
|
980
|
|
|
$this->_mainConfig['main.metaPublisher'] = $realname; |
|
981
|
|
|
$this->_mainConfig['main.administrationMail'] = $email; |
|
982
|
|
|
$this->_mainConfig['main.language'] = $language; |
|
983
|
|
|
$this->_mainConfig['security.permLevel'] = $permLevel; |
|
984
|
|
|
|
|
985
|
|
|
foreach ($this->_mainConfig as $name => $value) { |
|
986
|
|
|
$configuration->add($name, $value); |
|
987
|
|
|
} |
|
988
|
|
|
|
|
989
|
|
|
$configuration->update(['main.referenceURL' => $link->getSystemUri('/setup/index.php')]); |
|
990
|
|
|
$configuration->add('security.salt', md5($configuration->getDefaultUrl())); |
|
991
|
|
|
|
|
992
|
|
|
// add admin account and rights |
|
993
|
|
|
$admin = new User($configuration); |
|
994
|
|
View Code Duplication |
if (!$admin->createUser($loginname, $password, null, 1)) { |
|
995
|
|
|
printf( |
|
996
|
|
|
'<p class="alert alert-danger"><strong>Fatal installation error:</strong><br>'. |
|
997
|
|
|
"Couldn't create the admin user: %s</p>\n", |
|
998
|
|
|
$admin->error() |
|
999
|
|
|
); |
|
1000
|
|
|
$this->system->cleanInstallation(); |
|
1001
|
|
|
System::renderFooter(true); |
|
1002
|
|
|
} |
|
1003
|
|
|
$admin->setStatus('protected'); |
|
1004
|
|
|
$adminData = [ |
|
1005
|
|
|
'display_name' => $realname, |
|
1006
|
|
|
'email' => $email, |
|
1007
|
|
|
]; |
|
1008
|
|
|
$admin->setUserData($adminData); |
|
1009
|
|
|
|
|
1010
|
|
|
// add default rights |
|
1011
|
|
|
foreach ($this->mainRights as $right) { |
|
1012
|
|
|
$admin->perm->grantUserRight(1, $admin->perm->addRight($right)); |
|
1013
|
|
|
} |
|
1014
|
|
|
|
|
1015
|
|
|
// Add anonymous user account |
|
1016
|
|
|
$instanceSetup->createAnonymousUser($configuration); |
|
1017
|
|
|
|
|
1018
|
|
|
// Add master instance |
|
1019
|
|
|
$instanceData = [ |
|
1020
|
|
|
'url' => $link->getSystemUri($_SERVER['SCRIPT_NAME']), |
|
1021
|
|
|
'instance' => $link->getSystemRelativeUri('setup/index.php'), |
|
1022
|
|
|
'comment' => 'phpMyFAQ '.System::getVersion(), |
|
1023
|
|
|
]; |
|
1024
|
|
|
$faqInstance = new Instance($configuration); |
|
1025
|
|
|
$faqInstance->addInstance($instanceData); |
|
1026
|
|
|
|
|
1027
|
|
|
$faqInstanceMaster = new Master($configuration); |
|
1028
|
|
|
$faqInstanceMaster->createMaster($faqInstance); |
|
1029
|
|
|
|
|
1030
|
|
|
// connect to Elasticsearch if enabled |
|
1031
|
|
|
if (!is_null($esEnabled) && is_file($rootDir.'/config/elasticsearch.php')) { |
|
1032
|
|
|
require $rootDir.'/config/elasticsearch.php'; |
|
1033
|
|
|
|
|
1034
|
|
|
$configuration->setElasticsearchConfig($PMF_ES); |
|
|
|
|
|
|
1035
|
|
|
|
|
1036
|
|
|
$esClient = ClientBuilder::create() |
|
1037
|
|
|
->setHosts($PMF_ES['hosts']) |
|
1038
|
|
|
->build(); |
|
1039
|
|
|
|
|
1040
|
|
|
$configuration->setElasticsearch($esClient); |
|
1041
|
|
|
|
|
1042
|
|
|
$faqInstanceElasticsearch = new Elasticsearch($configuration); |
|
1043
|
|
|
$faqInstanceElasticsearch->createIndex(); |
|
1044
|
|
|
} |
|
1045
|
|
|
} |
|
1046
|
|
|
|
|
1047
|
|
|
/** |
|
1048
|
|
|
* Cleanup all files after an installation. |
|
1049
|
|
|
* |
|
1050
|
|
|
* @return void |
|
1051
|
|
|
*/ |
|
1052
|
|
|
public function cleanUpFiles() |
|
1053
|
|
|
{ |
|
1054
|
|
|
if (!DEBUG) { |
|
1055
|
|
|
// Remove 'index.php' file |
|
1056
|
|
|
if (@unlink(dirname($_SERVER['PATH_TRANSLATED']).'/index.php')) { |
|
1057
|
|
|
echo "<p class=\"alert alert-success\">The file <em>./setup/index.php</em> was deleted automatically.</p>\n"; |
|
1058
|
|
|
} else { |
|
1059
|
|
|
echo "<p class=\"alert alert-danger\">Please delete the file <em>./setup/index.php</em> manually.</p>\n"; |
|
1060
|
|
|
} |
|
1061
|
|
|
} |
|
1062
|
|
|
|
|
1063
|
|
|
} |
|
1064
|
|
|
} |
|
1065
|
|
|
|
Let’s assume that you have a directory layout like this:
. |-- OtherDir | |-- Bar.php | `-- Foo.php `-- SomeDir `-- Foo.phpand let’s assume the following content of
Bar.php:If both files
OtherDir/Foo.phpandSomeDir/Foo.phpare loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.phpHowever, as
OtherDir/Foo.phpdoes not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: