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:
and let’s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are 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.php
However, as
OtherDir/Foo.php
does 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: