This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * The Ajax Service Layer. |
||
5 | * |
||
6 | * This Source Code Form is subject to the terms of the Mozilla Public License, |
||
7 | * v. 2.0. If a copy of the MPL was not distributed with this file, You can |
||
8 | * obtain one at http://mozilla.org/MPL/2.0/. |
||
9 | * |
||
10 | * @package phpMyFAQ |
||
11 | * @author Thorsten Rinne <[email protected]> |
||
12 | * @copyright 2010-2019 phpMyFAQ Team |
||
13 | * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0 |
||
14 | * @link https://www.phpmyfaq.de |
||
15 | * @since 2010-09-15 |
||
16 | */ |
||
17 | |||
18 | define('IS_VALID_PHPMYFAQ', null); |
||
19 | |||
20 | use phpMyFAQ\Captcha; |
||
21 | use phpMyFAQ\Category; |
||
22 | use phpMyFAQ\Comment; |
||
23 | use phpMyFAQ\Faq; |
||
24 | use phpMyFAQ\Filter; |
||
25 | use phpMyFAQ\Helper\HttpHelper; |
||
26 | use phpMyFAQ\Helper\FaqHelper; |
||
27 | use phpMyFAQ\Language; |
||
28 | use phpMyFAQ\Language\Plurals; |
||
29 | use phpMyFAQ\Link; |
||
30 | use phpMyFAQ\Mail; |
||
31 | use phpMyFAQ\Network; |
||
32 | use phpMyFAQ\News; |
||
33 | use phpMyFAQ\Rating; |
||
34 | use phpMyFAQ\Search; |
||
35 | use phpMyFAQ\Search\Resultset; |
||
36 | use phpMyFAQ\Session; |
||
37 | use phpMyFAQ\Stopwords; |
||
38 | use phpMyFAQ\Strings; |
||
39 | use phpMyFAQ\User; |
||
40 | use phpMyFAQ\User\CurrentUser; |
||
41 | use phpMyFAQ\Utils; |
||
42 | use phpMyFAQ\Visits; |
||
43 | |||
44 | // |
||
45 | // Bootstrapping |
||
46 | // |
||
47 | require 'src/Bootstrap.php'; |
||
48 | |||
49 | $action = Filter::filterInput(INPUT_GET, 'action', FILTER_SANITIZE_STRING); |
||
50 | $ajaxLang = Filter::filterInput(INPUT_POST, 'lang', FILTER_SANITIZE_STRING); |
||
51 | $code = Filter::filterInput(INPUT_POST, 'captcha', FILTER_SANITIZE_STRING); |
||
52 | $currentToken = Filter::filterInput(INPUT_POST, 'csrf', FILTER_SANITIZE_STRING); |
||
53 | |||
54 | $Language = new Language($faqConfig); |
||
55 | $languageCode = $Language->setLanguage($faqConfig->get('main.languageDetection'), $faqConfig->get('main.language')); |
||
56 | require_once 'lang/language_en.php'; |
||
57 | $faqConfig->setLanguage($Language); |
||
58 | |||
59 | View Code Duplication | if (Language::isASupportedLanguage($ajaxLang)) { |
|
60 | $languageCode = trim($ajaxLang); |
||
61 | require_once 'lang/language_'.$languageCode.'.php'; |
||
62 | } else { |
||
63 | $languageCode = 'en'; |
||
64 | require_once 'lang/language_en.php'; |
||
65 | } |
||
66 | |||
67 | // |
||
68 | // Load plurals support for selected language |
||
69 | // |
||
70 | $plr = new Plurals($PMF_LANG); |
||
71 | |||
72 | // |
||
73 | // Initalizing static string wrapper |
||
74 | // |
||
75 | Strings::init($languageCode); |
||
76 | |||
77 | // |
||
78 | // Check captcha |
||
79 | // |
||
80 | $captcha = new Captcha($faqConfig); |
||
81 | $captcha->setSessionId( |
||
82 | Filter::filterInput(INPUT_COOKIE, Session::PMF_COOKIE_NAME_SESSIONID, FILTER_VALIDATE_INT) |
||
83 | ); |
||
84 | |||
85 | // |
||
86 | // Send headers |
||
87 | // |
||
88 | $http = new HttpHelper(); |
||
89 | $http->setContentType('application/json'); |
||
90 | |||
91 | // |
||
92 | // Set session |
||
93 | // |
||
94 | $faqSession = new Session($faqConfig); |
||
95 | $network = new Network($faqConfig); |
||
96 | $stopWords = new Stopwords($faqConfig); |
||
97 | |||
98 | if (!$network->checkIp($_SERVER['REMOTE_ADDR'])) { |
||
99 | $message = array('error' => $PMF_LANG['err_bannedIP']); |
||
100 | } |
||
101 | |||
102 | // |
||
103 | // Check, if user is logged in |
||
104 | // |
||
105 | $user = CurrentUser::getFromCookie($faqConfig); |
||
106 | if (!$user instanceof CurrentUser) { |
||
107 | $user = CurrentUser::getFromSession($faqConfig); |
||
108 | } |
||
109 | if ($user instanceof CurrentUser) { |
||
110 | $isLoggedIn = true; |
||
111 | } else { |
||
112 | $isLoggedIn = false; |
||
113 | } |
||
114 | |||
115 | if ('savevoting' !== $action && 'saveuserdata' !== $action && 'changepassword' !== $action && |
||
116 | !$captcha->checkCaptchaCode($code) && !$isLoggedIn) { |
||
117 | $message = ['error' => $PMF_LANG['msgCaptcha']]; |
||
118 | } |
||
119 | |||
120 | // |
||
121 | // Check if logged in if FAQ is completely secured |
||
122 | // |
||
123 | if (false === $isLoggedIn && $faqConfig->get('security.enableLoginOnly') && |
||
124 | 'changepassword' !== $action && 'saveregistration' !== $action) { |
||
125 | $message = ['error' => $PMF_LANG['ad_msg_noauth']]; |
||
126 | } |
||
127 | |||
128 | if (isset($message['error'])) { |
||
129 | $http->sendJsonWithHeaders($message); |
||
130 | exit(); |
||
131 | } |
||
132 | |||
133 | // Save user generated content |
||
134 | switch ($action) { |
||
135 | |||
136 | // Comments |
||
137 | case 'savecomment': |
||
138 | |||
139 | View Code Duplication | if (!$faqConfig->get('records.allowCommentsForGuests') && |
|
140 | !$user->perm->checkRight($user->getUserId(), 'addcomment')) { |
||
141 | $message = array('error' => $PMF_LANG['err_NotAuth']); |
||
142 | break; |
||
143 | } |
||
144 | |||
145 | $faq = new Faq($faqConfig); |
||
146 | $oComment = new Comment($faqConfig); |
||
147 | $category = new Category($faqConfig); |
||
148 | $type = Filter::filterInput(INPUT_POST, 'type', FILTER_SANITIZE_STRING); |
||
149 | $faqId = Filter::filterInput(INPUT_POST, 'id', FILTER_VALIDATE_INT, 0); |
||
150 | $newsId = Filter::filterInput(INPUT_POST, 'newsid', FILTER_VALIDATE_INT); |
||
151 | $username = Filter::filterInput(INPUT_POST, 'user', FILTER_SANITIZE_STRING); |
||
152 | $mail = Filter::filterInput(INPUT_POST, 'mail', FILTER_VALIDATE_EMAIL); |
||
153 | $comment = Filter::filterInput(INPUT_POST, 'comment_text', FILTER_SANITIZE_SPECIAL_CHARS); |
||
154 | |||
155 | switch ($type) { |
||
156 | case 'news': |
||
157 | $id = $newsId; |
||
158 | break; |
||
159 | case 'faq'; |
||
160 | $id = $faqId; |
||
161 | break; |
||
162 | } |
||
163 | |||
164 | // If e-mail address is set to optional |
||
165 | if (!$faqConfig->get('main.optionalMailAddress') && is_null($mail)) { |
||
166 | $mail = $faqConfig->get('main.administrationMail'); |
||
167 | } |
||
168 | |||
169 | // Check display name and e-mail address for not logged in users |
||
170 | if (false === $isLoggedIn) { |
||
171 | $user = new User($faqConfig); |
||
172 | if (true === $user->checkDisplayName($username) && true === $user->checkMailAddress($mail)) { |
||
173 | echo json_encode(array('error' => $PMF_LANG['err_SaveComment'])); |
||
174 | break; |
||
175 | } |
||
176 | } |
||
177 | |||
178 | if (!is_null($username) && !empty($username) && !empty($mail) && !is_null($mail) && !is_null($comment) && |
||
179 | !empty($comment) && $stopWords->checkBannedWord($comment) && !$faq->commentDisabled($id, $languageCode, $type)) { |
||
180 | try { |
||
181 | $faqSession->userTracking('save_comment', $id); |
||
182 | } catch (Exception $e) { |
||
183 | // @todo handle the exception |
||
184 | } |
||
185 | |||
186 | $commentData = [ |
||
187 | 'record_id' => $id, |
||
188 | 'type' => $type, |
||
189 | 'username' => $username, |
||
190 | 'usermail' => $mail, |
||
191 | 'comment' => nl2br($comment), |
||
192 | 'date' => $_SERVER['REQUEST_TIME'], |
||
193 | 'helped' => '', |
||
194 | ]; |
||
195 | |||
196 | if ($oComment->addComment($commentData)) { |
||
197 | $emailTo = $faqConfig->get('main.administrationMail'); |
||
198 | $urlToContent = ''; |
||
199 | if ('faq' == $type) { |
||
200 | $faq->getRecord($id); |
||
201 | if ($faq->faqRecord['email'] != '') { |
||
202 | $emailTo = $faq->faqRecord['email']; |
||
203 | } |
||
204 | $faqUrl = sprintf( |
||
205 | '%s?action=faq&cat=%d&id=%d&artlang=%s', |
||
206 | $faqConfig->getDefaultUrl(), |
||
207 | $category->getCategoryIdFromFaq($faq->faqRecord['id']), |
||
208 | $faq->faqRecord['id'], |
||
209 | $faq->faqRecord['lang'] |
||
210 | ); |
||
211 | |||
212 | $oLink = new Link($faqUrl, $faqConfig); |
||
213 | $oLink->itemTitle = $faq->faqRecord['title']; |
||
214 | $urlToContent = $oLink->toString(); |
||
215 | } else { |
||
216 | $oNews = new News($faqConfig); |
||
217 | $news = $oNews->getNewsEntry($id); |
||
218 | if ($news['authorEmail'] != '') { |
||
219 | $emailTo = $news['authorEmail']; |
||
220 | } |
||
221 | $link = sprintf('%s?action=news&newsid=%d&newslang=%s', |
||
222 | $faqConfig->getDefaultUrl(), |
||
223 | $news['id'], |
||
224 | $news['lang'] |
||
225 | ); |
||
226 | $oLink = new Link($link, $faqConfig); |
||
227 | $oLink->itemTitle = $news['header']; |
||
228 | $urlToContent = $oLink->toString(); |
||
229 | } |
||
230 | |||
231 | $commentMail = |
||
232 | 'User: '.$commentData['username'].', mailto:'.$commentData['usermail']."\n". |
||
233 | 'New comment posted on: '.$urlToContent. |
||
234 | "\n\n". |
||
235 | wordwrap($comment, 72); |
||
236 | |||
237 | $send = []; |
||
238 | $mail = new Mail($faqConfig); |
||
239 | $mail->setReplyTo($commentData['usermail'], $commentData['username']); |
||
240 | $mail->addTo($emailTo); |
||
241 | |||
242 | $send[$emailTo] = 1; |
||
243 | $send[$faqConfig->get('main.administrationMail')] = 1; |
||
244 | |||
245 | // Let the category owner get a copy of the message |
||
246 | $category = new Category($faqConfig); |
||
247 | $categories = $category->getCategoryIdsFromFaq($faq->faqRecord['id']); |
||
248 | foreach ($categories as $_category) { |
||
249 | $userId = $category->getOwner($_category); |
||
250 | $catUser = new User($faqConfig); |
||
251 | $catUser->getUserById($userId); |
||
252 | $catOwnerEmail = $catUser->getUserData('email'); |
||
253 | |||
254 | if ($catOwnerEmail !== '') { |
||
255 | if (!isset($send[$catOwnerEmail]) && $catOwnerEmail !== $emailTo) { |
||
256 | $mail->addCc($catOwnerEmail); |
||
257 | $send[$catOwnerEmail] = 1; |
||
258 | } |
||
259 | } |
||
260 | } |
||
261 | |||
262 | $mail->subject = '%sitename%'; |
||
263 | $mail->message = strip_tags($commentMail); |
||
264 | $result = $mail->send(); |
||
265 | unset($mail); |
||
266 | |||
267 | $message = array('success' => $PMF_LANG['msgCommentThanks']); |
||
268 | } else { |
||
269 | try { |
||
270 | $faqSession->userTracking('error_save_comment', $id); |
||
271 | } catch (Exception $e) { |
||
272 | // @todo handle the exception |
||
273 | } |
||
274 | $message = array('error' => $PMF_LANG['err_SaveComment']); |
||
275 | } |
||
276 | } else { |
||
277 | $message = array('error' => 'Please add your name, your e-mail address and a comment!'); |
||
278 | } |
||
279 | break; |
||
280 | |||
281 | case 'savefaq': |
||
282 | |||
283 | View Code Duplication | if (!$faqConfig->get('records.allowNewFaqsForGuests') && |
|
284 | !$user->perm->checkRight($user->getUserId(), 'addfaq')) { |
||
285 | $message = array('error' => $PMF_LANG['err_NotAuth']); |
||
286 | break; |
||
287 | } |
||
288 | |||
289 | $faq = new Faq($faqConfig); |
||
290 | $category = new Category($faqConfig); |
||
291 | $author = Filter::filterInput(INPUT_POST, 'name', FILTER_SANITIZE_STRING); |
||
292 | $email = Filter::filterInput(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); |
||
293 | $faqId = Filter::filterInput(INPUT_POST, 'faqid', FILTER_VALIDATE_INT); |
||
294 | $faqLanguage = Filter::filterInput(INPUT_POST, 'faqlanguage', FILTER_SANITIZE_STRING); |
||
295 | $question = Filter::filterInput(INPUT_POST, 'question', FILTER_SANITIZE_STRIPPED); |
||
296 | if ($faqConfig->get('main.enableWysiwygEditorFrontend')) { |
||
297 | $answer = Filter::filterInput(INPUT_POST, 'answer', FILTER_SANITIZE_SPECIAL_CHARS); |
||
298 | $answer = html_entity_decode($answer); |
||
299 | } else { |
||
300 | $answer = Filter::filterInput(INPUT_POST, 'answer', FILTER_SANITIZE_STRIPPED); |
||
301 | $answer = nl2br($answer); |
||
302 | } |
||
303 | $translatedAnswer = Filter::filterInput(INPUT_POST, 'translated_answer', FILTER_SANITIZE_STRING); |
||
304 | $contentLink = Filter::filterInput(INPUT_POST, 'contentlink', FILTER_SANITIZE_STRING); |
||
305 | $contentLink = Filter::filterVar($contentLink, FILTER_VALIDATE_URL); |
||
306 | $keywords = Filter::filterInput(INPUT_POST, 'keywords', FILTER_SANITIZE_STRIPPED); |
||
307 | $categories = Filter::filterInputArray( |
||
308 | INPUT_POST, |
||
309 | array( |
||
310 | 'rubrik' => array( |
||
311 | 'filter' => FILTER_VALIDATE_INT, |
||
312 | 'flags' => FILTER_REQUIRE_ARRAY, |
||
313 | ), |
||
314 | ) |
||
315 | ); |
||
316 | |||
317 | // Check on translation |
||
318 | if (empty($answer) && !is_null($translatedAnswer)) { |
||
319 | $answer = $translatedAnswer; |
||
320 | } |
||
321 | |||
322 | if (!is_null($author) && !empty($author) && !is_null($email) && !empty($email) && |
||
323 | !is_null($question) && !empty($question) && $stopWords->checkBannedWord(strip_tags($question)) && |
||
324 | !is_null($answer) && !empty($answer) && $stopWords->checkBannedWord(strip_tags($answer)) && |
||
325 | ((is_null($faqId) && !is_null($categories['rubrik'])) || (!is_null($faqId) && !is_null($faqLanguage) && |
||
326 | Language::isASupportedLanguage($faqLanguage)))) { |
||
327 | $isNew = true; |
||
328 | if (!is_null($faqId)) { |
||
329 | $isNew = false; |
||
330 | try { |
||
331 | $faqSession->userTracking('save_new_translation_entry', 0); |
||
332 | } catch (Exception $e) { |
||
333 | // @todo handle the exception |
||
334 | } |
||
335 | } else { |
||
336 | try { |
||
337 | $faqSession->userTracking('save_new_entry', 0); |
||
338 | } catch (Exception $e) { |
||
339 | // @todo handle the exception |
||
340 | } |
||
341 | } |
||
342 | |||
343 | $isTranslation = false; |
||
344 | if (!is_null($faqLanguage)) { |
||
345 | $isTranslation = true; |
||
346 | $newLanguage = $faqLanguage; |
||
347 | } |
||
348 | |||
349 | if (Strings::substr($contentLink, 7) != '') { |
||
350 | $answer = sprintf( |
||
351 | '%s<br /><div id="newFAQContentLink">%s<a href="http://%s" target="_blank">%s</a></div>', |
||
352 | $answer, |
||
353 | $PMF_LANG['msgInfo'], |
||
354 | Strings::substr($contentLink, 7), |
||
355 | $contentLink |
||
356 | ); |
||
357 | } |
||
358 | |||
359 | $autoActivate = $faqConfig->get('records.defaultActivation'); |
||
360 | |||
361 | $newData = [ |
||
362 | 'lang' => ($isTranslation === true ? $newLanguage : $languageCode), |
||
363 | 'thema' => $question, |
||
364 | 'active' => ($autoActivate ? FAQ_SQL_ACTIVE_YES : FAQ_SQL_ACTIVE_NO), |
||
365 | 'sticky' => 0, |
||
366 | 'content' => $answer, |
||
367 | 'keywords' => $keywords, |
||
368 | 'author' => $author, |
||
369 | 'email' => $email, |
||
370 | 'comment' => 'y', |
||
371 | 'date' => date('YmdHis'), |
||
372 | 'dateStart' => '00000000000000', |
||
373 | 'dateEnd' => '99991231235959', |
||
374 | 'linkState' => '', |
||
375 | 'linkDateCheck' => 0 |
||
376 | ]; |
||
377 | |||
378 | if ($isNew) { |
||
379 | $categories = $categories['rubrik']; |
||
380 | } else { |
||
381 | $newData['id'] = $faqId; |
||
382 | $categories = $category->getCategoryIdsFromFaq($newData['id']); |
||
383 | } |
||
384 | |||
385 | $recordId = $faq->addRecord($newData, $isNew); |
||
386 | |||
387 | $faq->addCategoryRelations($categories, $recordId, $newData['lang']); |
||
388 | |||
389 | $openQuestionId = Filter::filterInput(INPUT_POST, 'openQuestionID', FILTER_VALIDATE_INT); |
||
390 | View Code Duplication | if ($openQuestionId) { |
|
391 | if ($faqConfig->get('records.enableDeleteQuestion')) { |
||
392 | $faq->deleteQuestion($openQuestionId); |
||
393 | } else { // adds this faq record id to the related open question |
||
394 | $faq->updateQuestionAnswer($openQuestionId, $recordId, $categories[0]); |
||
395 | } |
||
396 | } |
||
397 | |||
398 | // Activate visits |
||
399 | $visits = new Visits($faqConfig); |
||
400 | $visits->logViews($recordId); |
||
401 | |||
402 | // Set permissions |
||
403 | $userPermissions = $category->getPermissions('user', $categories); |
||
404 | // Add user permissions |
||
405 | $faq->addPermission('user', $recordId, $userPermissions); |
||
406 | $category->addPermission('user', $categories, $userPermissions); |
||
407 | // Add group permission |
||
408 | if ($faqConfig->get('security.permLevel') !== 'basic') { |
||
409 | $groupPermissions = $category->getPermissions('group', $categories); |
||
410 | $faq->addPermission('group', $recordId, $groupPermissions); |
||
411 | $category->addPermission('group', $categories, $groupPermissions); |
||
412 | } |
||
413 | |||
414 | // Let the PMF Administrator and the Entity Owner to be informed by email of this new entry |
||
415 | $send = []; |
||
416 | $mail = new Mail($faqConfig); |
||
417 | $mail->setReplyTo($email, $author); |
||
418 | $mail->addTo($faqConfig->get('main.administrationMail')); |
||
419 | $send[$faqConfig->get('main.administrationMail')] = 1; |
||
420 | |||
421 | foreach ($categories as $_category) { |
||
422 | $userId = $category->getOwner($_category); |
||
423 | $groupId = $category->getModeratorGroupId($_category); |
||
424 | |||
425 | // @todo Move this code to Entityhp |
||
426 | $oUser = new User($faqConfig); |
||
427 | $oUser->getUserById($userId); |
||
428 | $catOwnerEmail = $oUser->getUserData('email'); |
||
429 | |||
430 | // Avoid to send multiple emails to the same owner |
||
431 | if (!empty($catOwnerEmail) && !isset($send[$catOwnerEmail])) { |
||
432 | $mail->addCc($catOwnerEmail); |
||
433 | $send[$catOwnerEmail] = 1; |
||
434 | } |
||
435 | |||
436 | if ($groupId > 0) { |
||
437 | $moderators = $oUser->perm->getGroupMembers($groupId); |
||
0 ignored issues
–
show
|
|||
438 | foreach ($moderators as $moderator) { |
||
439 | $oUser->getUserById($moderator); |
||
440 | $moderatorEmail = $oUser->getUserData('email'); |
||
441 | |||
442 | // Avoid to send multiple emails to the same moderator |
||
443 | if (!empty($moderatorEmail) && !isset($send[$moderatorEmail])) { |
||
444 | $mail->addCc($moderatorEmail); |
||
445 | $send[$moderatorEmail] = 1; |
||
446 | } |
||
447 | } |
||
448 | } |
||
449 | } |
||
450 | |||
451 | $mail->subject = '%sitename%'; |
||
452 | |||
453 | // @todo let the email contains the faq article both as plain text and as HTML |
||
454 | $mail->message = html_entity_decode( |
||
455 | $PMF_LANG['msgMailCheck'])."\n\n". |
||
456 | $faqConfig->get('main.titleFAQ').': '. |
||
457 | $faqConfig->getDefaultUrl().'admin/?action=editentry&id='.$recordId.'&lang='.$faqLanguage; |
||
458 | $result = $mail->send(); |
||
459 | unset($mail); |
||
460 | |||
461 | $message = [ |
||
462 | 'success' => ($isNew ? $PMF_LANG['msgNewContentThanks'] : $PMF_LANG['msgNewTranslationThanks']), |
||
463 | ]; |
||
464 | } else { |
||
465 | $message = [ |
||
466 | 'error' => $PMF_LANG['err_SaveEntries'] |
||
467 | ]; |
||
468 | } |
||
469 | |||
470 | break; |
||
471 | |||
472 | case 'savequestion': |
||
473 | |||
474 | View Code Duplication | if (!$faqConfig->get('records.allowQuestionsForGuests') && |
|
475 | !$user->perm->checkRight($user->getUserId(), 'addquestion')) { |
||
476 | $message = ['error' => $PMF_LANG['err_NotAuth']]; |
||
477 | break; |
||
478 | } |
||
479 | |||
480 | $faq = new Faq($faqConfig); |
||
481 | $cat = new Category($faqConfig); |
||
482 | $categories = $cat->getAllCategories(); |
||
483 | $author = Filter::filterInput(INPUT_POST, 'name', FILTER_SANITIZE_STRING); |
||
484 | $email = Filter::filterInput(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); |
||
485 | $ucategory = Filter::filterInput(INPUT_POST, 'category', FILTER_VALIDATE_INT); |
||
486 | $question = Filter::filterInput(INPUT_POST, 'question', FILTER_SANITIZE_STRIPPED); |
||
487 | $save = Filter::filterInput(INPUT_POST, 'save', FILTER_VALIDATE_INT, 0); |
||
488 | |||
489 | // If e-mail address is set to optional |
||
490 | if (!$faqConfig->get('main.optionalMailAddress') && is_null($email)) { |
||
491 | $email = $faqConfig->get('main.administrationMail'); |
||
492 | } |
||
493 | |||
494 | // If smart answering is disabled, save question immediately |
||
495 | if (false === $faqConfig->get('main.enableSmartAnswering')) { |
||
496 | $save = true; |
||
497 | } |
||
498 | |||
499 | if (!is_null($author) && !empty($author) && !is_null($email) && !empty($email) && |
||
500 | !is_null($question) && !empty($question) && $stopWords->checkBannedWord(Strings::htmlspecialchars($question))) { |
||
501 | if ($faqConfig->get('records.enableVisibilityQuestions')) { |
||
502 | $visibility = 'N'; |
||
503 | } else { |
||
504 | $visibility = 'Y'; |
||
505 | } |
||
506 | |||
507 | $questionData = [ |
||
508 | 'username' => $author, |
||
509 | 'email' => $email, |
||
510 | 'category_id' => $ucategory, |
||
511 | 'question' => $question, |
||
512 | 'is_visible' => $visibility |
||
513 | ]; |
||
514 | |||
515 | if (false === (boolean)$save) { |
||
516 | |||
517 | $cleanQuestion = $stopWords->clean($question); |
||
518 | |||
519 | $user = new CurrentUser($faqConfig); |
||
520 | $faqSearch = new Search($faqConfig); |
||
521 | $faqSearch->setCategory(new Category($faqConfig)); |
||
522 | $faqSearch->setCategoryId($ucategory); |
||
523 | $faqSearchResult = new Resultset($user, $faq, $faqConfig); |
||
524 | $searchResult = []; |
||
525 | $mergedResult = []; |
||
526 | |||
527 | foreach ($cleanQuestion as $word) { |
||
528 | if (!empty($word)) { |
||
529 | $searchResult[] = $faqSearch->search($word, false); |
||
530 | } |
||
531 | } |
||
532 | foreach ($searchResult as $resultSet) { |
||
533 | foreach ($resultSet as $result) { |
||
534 | $mergedResult[] = $result; |
||
535 | } |
||
536 | } |
||
537 | $faqSearchResult->reviewResultset($mergedResult); |
||
538 | |||
539 | if (0 < $faqSearchResult->getNumberOfResults()) { |
||
540 | $response = sprintf( |
||
541 | '<p>%s</p>', |
||
542 | $plr->GetMsg('plmsgSearchAmount', $faqSearchResult->getNumberOfResults()) |
||
543 | ); |
||
544 | |||
545 | $response .= '<ul>'; |
||
546 | |||
547 | $faqHelper = new FaqHelper($faqConfig); |
||
548 | foreach ($faqSearchResult->getResultset() as $result) { |
||
549 | $url = sprintf( |
||
550 | '%sindex.php?action=faq&cat=%d&id=%d&artlang=%s', |
||
551 | $faqConfig->getDefaultUrl(), |
||
552 | $result->category_id, |
||
553 | $result->id, |
||
554 | $result->lang |
||
555 | ); |
||
556 | $oLink = new Link($url, $faqConfig); |
||
557 | $oLink->text = Utils::chopString($result->question, 15); |
||
558 | $oLink->itemTitle = $result->question; |
||
559 | |||
560 | $response .= sprintf( |
||
561 | '<li>%s<br /><div class="searchpreview">%s...</div></li>', |
||
562 | $oLink->toHtmlAnchor(), |
||
563 | $faqHelper->renderAnswerPreview($result->answer, 10) |
||
564 | ); |
||
565 | } |
||
566 | $response .= '</ul>'; |
||
567 | |||
568 | $message = array('result' => $response); |
||
569 | View Code Duplication | } else { |
|
570 | |||
571 | $faq->addQuestion($questionData); |
||
572 | |||
573 | $questionMail = 'User: '.$questionData['username']. |
||
574 | ', mailto:'.$questionData['email']."\n".$PMF_LANG['msgCategory']. |
||
575 | ': '.$categories[$questionData['category_id']]['name']."\n\n". |
||
576 | wordwrap($question, 72)."\n\n". |
||
577 | $faqConfig->getDefaultUrl().'admin/'; |
||
578 | |||
579 | $userId = $cat->getOwner($questionData['category_id']); |
||
580 | $oUser = new User($faqConfig); |
||
581 | $oUser->getUserById($userId); |
||
582 | |||
583 | $userEmail = $oUser->getUserData('email'); |
||
584 | $mainAdminEmail = $faqConfig->get('main.administrationMail'); |
||
585 | |||
586 | $mail = new Mail($faqConfig); |
||
587 | $mail->setReplyTo($questionData['email'], $questionData['username']); |
||
588 | $mail->addTo($mainAdminEmail); |
||
589 | // Let the category owner get a copy of the message |
||
590 | if (!empty($userEmail) && $mainAdminEmail != $userEmail) { |
||
591 | $mail->addCc($userEmail); |
||
592 | } |
||
593 | $mail->subject = '%sitename%'; |
||
594 | $mail->message = $questionMail; |
||
595 | $mail->send(); |
||
596 | unset($mail); |
||
597 | |||
598 | $message = array('success' => $PMF_LANG['msgAskThx4Mail']); |
||
599 | } |
||
600 | View Code Duplication | } else { |
|
601 | $faq->addQuestion($questionData); |
||
602 | |||
603 | $questionMail = 'User: '.$questionData['username']. |
||
604 | ', mailto:'.$questionData['email']."\n".$PMF_LANG['msgCategory']. |
||
605 | ': '.$categories[$questionData['category_id']]['name']."\n\n". |
||
606 | wordwrap($question, 72)."\n\n". |
||
607 | $faqConfig->getDefaultUrl().'admin/'; |
||
608 | |||
609 | $userId = $cat->getOwner($questionData['category_id']); |
||
610 | $oUser = new User($faqConfig); |
||
611 | $oUser->getUserById($userId); |
||
612 | |||
613 | $userEmail = $oUser->getUserData('email'); |
||
614 | $mainAdminEmail = $faqConfig->get('main.administrationMail'); |
||
615 | |||
616 | $mail = new Mail($faqConfig); |
||
617 | $mail->setReplyTo($questionData['email'], $questionData['username']); |
||
618 | $mail->addTo($mainAdminEmail); |
||
619 | // Let the category owner get a copy of the message |
||
620 | if (!empty($userEmail) && $mainAdminEmail != $userEmail) { |
||
621 | $mail->addCc($userEmail); |
||
622 | } |
||
623 | $mail->subject = '%sitename%'; |
||
624 | $mail->message = $questionMail; |
||
625 | $mail->send(); |
||
626 | unset($mail); |
||
627 | |||
628 | $message = array('success' => $PMF_LANG['msgAskThx4Mail']); |
||
629 | } |
||
630 | } else { |
||
631 | $message = array('error' => $PMF_LANG['err_SaveQuestion']); |
||
632 | } |
||
633 | |||
634 | break; |
||
635 | |||
636 | case 'saveregistration': |
||
637 | |||
638 | $realname = Filter::filterInput(INPUT_POST, 'realname', FILTER_SANITIZE_STRING); |
||
639 | $loginName = Filter::filterInput(INPUT_POST, 'name', FILTER_SANITIZE_STRING); |
||
640 | $email = Filter::filterInput(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); |
||
641 | |||
642 | if (!is_null($loginName) && !empty($loginName) && !is_null($email) && !empty($email) && |
||
643 | !is_null($realname) && !empty($realname)) { |
||
644 | $message = []; |
||
645 | $user = new User($faqConfig); |
||
646 | |||
647 | // Create user account (login and password) |
||
648 | // Note: password be automatically generated and sent by email as soon if admin switch user to "active" |
||
649 | if (!$user->createUser($loginName, null)) { |
||
650 | $message = array('error' => $user->error()); |
||
651 | } else { |
||
652 | $user->userdata->set( |
||
653 | array('display_name', 'email'), |
||
654 | array($realname, $email) |
||
655 | ); |
||
656 | // set user status |
||
657 | $user->setStatus('blocked'); |
||
658 | |||
659 | if (!$faqConfig->get('spam.manualActivation')) { |
||
660 | $isNowActive = $user->activateUser(); |
||
661 | } else { |
||
662 | $isNowActive = false; |
||
663 | } |
||
664 | |||
665 | if ($isNowActive) { |
||
666 | $adminMessage = 'This user has been automatically activated, you can still'. |
||
667 | ' modify the users permissions or decline membership by visiting the admin section'; |
||
668 | } else { |
||
669 | $adminMessage = 'To activate this user please use'; |
||
670 | } |
||
671 | |||
672 | $text = sprintf( |
||
673 | "New user has been registrated:\n\nName: %s\nLogin name: %s\n\n". |
||
674 | '%s the administration interface at %s.', |
||
675 | $realname, |
||
676 | $loginName, |
||
677 | $adminMessage, |
||
678 | $faqConfig->getDefaultUrl() |
||
679 | ); |
||
680 | |||
681 | $mail = new Mail($faqConfig); |
||
682 | $mail->setReplyTo($email, $realname); |
||
683 | $mail->addTo($faqConfig->get('main.administrationMail')); |
||
684 | $mail->subject = Utils::resolveMarkers($PMF_LANG['emailRegSubject'], $faqConfig); |
||
685 | $mail->message = $text; |
||
686 | $result = $mail->send(); |
||
687 | unset($mail); |
||
688 | |||
689 | $message = array( |
||
690 | 'success' => trim($PMF_LANG['successMessage']). |
||
691 | ' '. |
||
692 | trim($PMF_LANG['msgRegThankYou']), |
||
693 | ); |
||
694 | } |
||
695 | } else { |
||
696 | $message = array('error' => $PMF_LANG['err_sendMail']); |
||
697 | } |
||
698 | break; |
||
699 | |||
700 | case 'savevoting': |
||
701 | |||
702 | $faq = new Faq($faqConfig); |
||
703 | $rating = new Rating($faqConfig); |
||
704 | $type = Filter::filterInput(INPUT_POST, 'type', FILTER_SANITIZE_STRING, 'faq'); |
||
705 | $recordId = Filter::filterInput(INPUT_POST, 'id', FILTER_VALIDATE_INT, 0); |
||
706 | $vote = Filter::filterInput(INPUT_POST, 'vote', FILTER_VALIDATE_INT); |
||
707 | $userIp = Filter::filterVar($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP); |
||
708 | |||
709 | if (isset($vote) && $rating->check($recordId, $userIp) && $vote > 0 && $vote < 6) { |
||
710 | try { |
||
711 | $faqSession->userTracking('save_voting', $recordId); |
||
712 | } catch (Exception $e) { |
||
713 | // @todo handle the exception |
||
714 | } |
||
715 | |||
716 | $votingData = array( |
||
717 | 'record_id' => $recordId, |
||
718 | 'vote' => $vote, |
||
719 | 'user_ip' => $userIp,); |
||
720 | |||
721 | if (!$rating->getNumberOfVotings($recordId)) { |
||
722 | $rating->addVoting($votingData); |
||
723 | } else { |
||
724 | $rating->update($votingData); |
||
725 | } |
||
726 | $message = array( |
||
727 | 'success' => $PMF_LANG['msgVoteThanks'], |
||
728 | 'rating' => $rating->getVotingResult($recordId), |
||
729 | ); |
||
730 | } elseif (!$rating->check($recordId, $userIp)) { |
||
731 | try { |
||
732 | $faqSession->userTracking('error_save_voting', $recordId); |
||
733 | } catch (Exception $e) { |
||
734 | // @todo handle the exception |
||
735 | } |
||
736 | $message = array('error' => $PMF_LANG['err_VoteTooMuch']); |
||
737 | } else { |
||
738 | try { |
||
739 | $faqSession->userTracking('error_save_voting', $recordId); |
||
740 | } catch (Exception $e) { |
||
741 | // @todo handle the exception |
||
742 | } |
||
743 | $message = array('error' => $PMF_LANG['err_noVote']); |
||
744 | } |
||
745 | |||
746 | break; |
||
747 | |||
748 | // Send user generated mails |
||
749 | case 'sendcontact': |
||
750 | |||
751 | $author = Filter::filterInput(INPUT_POST, 'name', FILTER_SANITIZE_STRING); |
||
752 | $email = Filter::filterInput(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); |
||
753 | $question = Filter::filterInput(INPUT_POST, 'question', FILTER_SANITIZE_STRIPPED); |
||
754 | |||
755 | // If e-mail address is set to optional |
||
756 | if (!$faqConfig->get('main.optionalMailAddress') && is_null($email)) { |
||
757 | $email = $faqConfig->get('main.administrationMail'); |
||
758 | } |
||
759 | |||
760 | View Code Duplication | if (!is_null($author) && !empty($author) && !is_null($email) && !empty($email) && !is_null($question) && |
|
761 | !empty($question) && $stopWords->checkBannedWord(Strings::htmlspecialchars($question))) { |
||
762 | $question = sprintf( |
||
763 | "%s %s\n%s %s\n\n %s", |
||
764 | $PMF_LANG['msgNewContentName'], |
||
765 | $author, |
||
766 | $PMF_LANG['msgNewContentMail'], |
||
767 | $email, |
||
768 | $question |
||
769 | ); |
||
770 | |||
771 | $mail = new Mail($faqConfig); |
||
772 | $mail->setReplyTo($email, $author); |
||
773 | $mail->addTo($faqConfig->get('main.administrationMail')); |
||
774 | $mail->subject = 'Feedback: %sitename%'; |
||
775 | $mail->message = $question; |
||
776 | $result = $mail->send(); |
||
777 | unset($mail); |
||
778 | |||
779 | $message = array('success' => $PMF_LANG['msgMailContact']); |
||
780 | } else { |
||
781 | $message = array('error' => $PMF_LANG['err_sendMail']); |
||
782 | } |
||
783 | break; |
||
784 | |||
785 | // Send mails to friends |
||
786 | case 'sendtofriends': |
||
787 | |||
788 | $author = Filter::filterInput(INPUT_POST, 'name', FILTER_SANITIZE_STRING); |
||
789 | $email = Filter::filterInput(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); |
||
790 | $link = Filter::filterInput(INPUT_POST, 'link', FILTER_VALIDATE_URL); |
||
791 | $attached = Filter::filterInput(INPUT_POST, 'message', FILTER_SANITIZE_STRIPPED); |
||
792 | $mailto = Filter::filterInputArray(INPUT_POST, |
||
793 | array('mailto' => array('filter' => FILTER_VALIDATE_EMAIL, |
||
794 | 'flags' => FILTER_REQUIRE_ARRAY | FILTER_NULL_ON_FAILURE, |
||
795 | ), |
||
796 | ) |
||
797 | ); |
||
798 | |||
799 | if (!is_null($author) && !empty($author) && !is_null($email) && !empty($email) && |
||
800 | is_array($mailto) && !empty($mailto['mailto'][0]) && |
||
801 | $stopWords->checkBannedWord(Strings::htmlspecialchars($attached))) { |
||
802 | foreach ($mailto['mailto'] as $recipient) { |
||
803 | $recipient = trim(strip_tags($recipient)); |
||
804 | if (!empty($recipient)) { |
||
805 | $mail = new Mail($faqConfig); |
||
806 | $mail->setReplyTo($email, $author); |
||
807 | $mail->addTo($recipient); |
||
808 | $mail->subject = $PMF_LANG['msgS2FMailSubject'].$author; |
||
809 | $mail->message = sprintf("%s\r\n\r\n%s\r\n%s\r\n\r\n%s", |
||
810 | $faqConfig->get('main.send2friendText'), |
||
811 | $PMF_LANG['msgS2FText2'], |
||
812 | $link, |
||
813 | $attached); |
||
814 | |||
815 | // Send the email |
||
816 | $result = $mail->send(); |
||
817 | unset($mail); |
||
818 | usleep(250); |
||
819 | } |
||
820 | } |
||
821 | |||
822 | $message = array('success' => $PMF_LANG['msgS2FThx']); |
||
823 | } else { |
||
824 | $message = array('error' => $PMF_LANG['err_sendMail']); |
||
825 | } |
||
826 | break; |
||
827 | |||
828 | // Save user data from UCP |
||
829 | case 'saveuserdata': |
||
830 | |||
831 | if (!isset($_SESSION['phpmyfaq_csrf_token']) || $_SESSION['phpmyfaq_csrf_token'] !== $currentToken) { |
||
832 | $message = array('error' => $PMF_LANG['ad_msg_noauth']); |
||
833 | break; |
||
834 | } |
||
835 | |||
836 | $userId = Filter::filterInput(INPUT_POST, 'userid', FILTER_VALIDATE_INT); |
||
837 | $author = Filter::filterInput(INPUT_POST, 'name', FILTER_SANITIZE_STRING); |
||
838 | $email = Filter::filterInput(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); |
||
839 | $password = Filter::filterInput(INPUT_POST, 'password', FILTER_SANITIZE_STRING); |
||
840 | $confirm = Filter::filterInput(INPUT_POST, 'password_confirm', FILTER_SANITIZE_STRING); |
||
841 | |||
842 | $user = CurrentUser::getFromSession($faqConfig); |
||
843 | |||
844 | if ($userId !== $user->getUserId()) { |
||
845 | $message = array('error' => 'User ID mismatch!'); |
||
846 | break; |
||
847 | } |
||
848 | |||
849 | if ($password !== $confirm) { |
||
850 | $message = array('error' => $PMF_LANG['ad_user_error_passwordsDontMatch']); |
||
851 | break; |
||
852 | } |
||
853 | |||
854 | $userData = array( |
||
855 | 'display_name' => $author, |
||
856 | 'email' => $email,); |
||
857 | $success = $user->setUserData($userData); |
||
858 | |||
859 | if (0 !== strlen($password) && 0 !== strlen($confirm)) { |
||
860 | foreach ($user->getAuthContainer() as $author => $auth) { |
||
861 | if ($auth->setReadOnly()) { |
||
862 | continue; |
||
863 | } |
||
864 | if (!$auth->changePassword($user->getLogin(), $password)) { |
||
865 | $message = array('error' => $auth->error()); |
||
866 | $success = false; |
||
867 | } else { |
||
868 | $success = true; |
||
869 | } |
||
870 | } |
||
871 | } |
||
872 | |||
873 | if ($success) { |
||
874 | $message = array('success' => $PMF_LANG['ad_entry_savedsuc']); |
||
875 | } else { |
||
876 | $message = array('error' => $PMF_LANG['ad_entry_savedfail']); |
||
877 | } |
||
878 | break; |
||
879 | |||
880 | case 'changepassword': |
||
881 | |||
882 | $username = Filter::filterInput(INPUT_POST, 'username', FILTER_SANITIZE_STRING); |
||
883 | $email = Filter::filterInput(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); |
||
884 | |||
885 | if (!is_null($username) && !is_null($email)) { |
||
886 | $user = new CurrentUser($faqConfig); |
||
887 | $loginExist = $user->getUserByLogin($username); |
||
888 | |||
889 | if ($loginExist && ($email == $user->getUserData('email'))) { |
||
890 | $consonants = array( |
||
891 | 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z', |
||
892 | ); |
||
893 | $vowels = array( |
||
894 | 'a', 'e', 'i', 'o', 'u', |
||
895 | ); |
||
896 | $newPassword = ''; |
||
897 | for ($i = 1; $i <= 4; ++$i) { |
||
898 | $newPassword .= $consonants[Utils::createRandomNumber(0, 19)]; |
||
899 | $newPassword .= $vowels[Utils::createRandomNumber(0, 4)]; |
||
900 | } |
||
901 | $user->changePassword($newPassword); |
||
902 | $text = $PMF_LANG['lostpwd_text_1']."\nUsername: ".$username."\nNew Password: ".$newPassword."\n\n".$PMF_LANG['lostpwd_text_2']; |
||
903 | |||
904 | $mail = new Mail($faqConfig); |
||
905 | $mail->addTo($email); |
||
906 | $mail->subject = '[%sitename%] Username / password request'; |
||
907 | $mail->message = $text; |
||
908 | $result = $mail->send(); |
||
909 | unset($mail); |
||
910 | // Trust that the email has been sent |
||
911 | $message = array('success' => $PMF_LANG['lostpwd_mail_okay']); |
||
912 | } else { |
||
913 | $message = array('error' => $PMF_LANG['lostpwd_err_1']); |
||
914 | } |
||
915 | } else { |
||
916 | $message = array('error' => $PMF_LANG['lostpwd_err_2']); |
||
917 | } |
||
918 | break; |
||
919 | |||
920 | case 'request-removal': |
||
921 | |||
922 | $author = Filter::filterInput(INPUT_POST, 'name', FILTER_SANITIZE_STRING); |
||
923 | $loginName = Filter::filterInput(INPUT_POST, 'loginname', FILTER_SANITIZE_STRING); |
||
924 | $email = Filter::filterInput(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); |
||
925 | $question = Filter::filterInput(INPUT_POST, 'question', FILTER_SANITIZE_STRIPPED); |
||
926 | |||
927 | // If e-mail address is set to optional |
||
928 | if (!$faqConfig->get('main.optionalMailAddress') && is_null($email)) { |
||
929 | $email = $faqConfig->get('main.administrationMail'); |
||
930 | } |
||
931 | |||
932 | View Code Duplication | if (!is_null($author) && !empty($author) && !is_null($email) && !empty($email) && !is_null($question) && |
|
933 | !empty($question) && $stopWords->checkBannedWord(Strings::htmlspecialchars($question))) { |
||
934 | $question = sprintf( |
||
935 | "%s %s\n%s %s\n%s %s\n\n %s", |
||
936 | $PMF_LANG['ad_user_loginname'], |
||
937 | $loginName, |
||
938 | $PMF_LANG['msgNewContentName'], |
||
939 | $author, |
||
940 | $PMF_LANG['msgNewContentMail'], |
||
941 | $email, |
||
942 | $question |
||
943 | ); |
||
944 | |||
945 | $mail = new Mail($faqConfig); |
||
946 | $mail->setReplyTo($email, $author); |
||
947 | $mail->addTo($faqConfig->get('main.administrationMail')); |
||
948 | $mail->subject = 'Remove User Request: %sitename%'; |
||
949 | $mail->message = $question; |
||
950 | $result = $mail->send(); |
||
951 | unset($mail); |
||
952 | |||
953 | $message = ['success' => $PMF_LANG['msgMailContact']]; |
||
954 | } else { |
||
955 | $message = ['error' => $PMF_LANG['err_sendMail']]; |
||
956 | } |
||
957 | break; |
||
958 | } |
||
959 | |||
960 | $http->sendJsonWithHeaders($message); |
||
961 |
It seems like the method you are trying to call exists only in some of the possible types.
Let’s take a look at an example:
Available Fixes
Add an additional type-check:
Only allow a single type to be passed if the variable comes from a parameter: