Issues (299)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

admin/faq.php (3 issues)

1
<?php declare(strict_types=1);
2
3
/**
4
 * Module: SmartFAQ
5
 * Author: The SmartFactory <www.smartfactory.ca>
6
 * Licence: GNU
7
 */
8
9
use Xmf\Module\Admin;
10
use Xmf\Request;
11
use XoopsModules\Smartfaq;
12
use XoopsModules\Smartfaq\Constants;
13
use XoopsModules\Smartfaq\Helper;
14
15
require_once __DIR__ . '/admin_header.php';
16
17
/** @var Smartfaq\Helper $helper */
18
$helper = Helper::getInstance();
19
20
// Creating the faq handler object
21
/** @var \XoopsModules\Smartfaq\FaqHandler $faqHandler */
22
$faqHandler = Helper::getInstance()->getHandler('Faq');
23
24
// Creating the category handler object
25
/** @var \XoopsModules\Smartfaq\CategoryHandler $categoryHandler */
26
$categoryHandler = Helper::getInstance()->getHandler('Category');
27
28
// Creating the answer handler object
29
/** @var \XoopsModules\Smartfaq\AnswerHandler $answerHandler */
30
$answerHandler = Helper::getInstance()->getHandler('Answer');
31
32
$op = Request::getCmd('op', '');
33
34
// Where shall we start?
35
$startfaq = Request::getInt('startfaq', 0, 'GET');
36
37
/**
38
 * @param bool $showmenu
39
 * @param int  $faqid
40
 * @param int  $answerid
41
 * @param bool $merge
42
 */
43
function editfaq($showmenu = false, $faqid = -1, $answerid = -1, $merge = false): void
44
{
45
    global $answerHandler, $faqHandler, $categoryHandler, $xoopsUser, $xoopsConfig, $xoopsDB, $modify, $xoopsModule, $XOOPS_URL, $myts;
46
    /** @var Smartfaq\Helper $helper */
47
    $helper = Helper::getInstance();
48
49
    require_once XOOPS_ROOT_PATH . '/class/xoopsformloader.php';
50
    // If there is a parameter, and the id exists, retrieve data: we're editing a faq
51
    if (-1 != $faqid) {
52
        // Creating the FAQ object
53
        $faqObj = new Smartfaq\Faq($faqid);
0 ignored issues
show
It seems like $faqid can also be of type integer; however, parameter $id of XoopsModules\Smartfaq\Faq::__construct() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

53
        $faqObj = new Smartfaq\Faq(/** @scrutinizer ignore-type */ $faqid);
Loading history...
54
55
        if ($faqObj->notLoaded()) {
56
            redirect_header('faq.php', 1, _AM_SF_NOFAQSELECTED);
57
        }
58
59
        if (-1 == $answerid) {
60
            // Creating the object for the official answer
61
            $answerObj = $faqObj->answer();
62
            if (!$answerObj) {
63
                $answerObj = $answerHandler->create();
64
            }
65
        } else {
66
            $answerObj         = new Smartfaq\Answer($answerid);
67
            $originalAnswerObj = $faqObj->answer();
68
        }
69
70
        switch ($faqObj->status()) {
71
            case Constants::SF_STATUS_ASKED:
72
                $breadcrumb_action1   = _AM_SF_ASKED;
73
                $breadcrumb_action2   = _AM_SF_APPROVING;
74
                $collapsableBar_title = _AM_SF_ASKED_TITLE;
75
                $collapsableBar_info  = _AM_SF_ASKED_TITLE_INFO;
76
                $button_caption       = _AM_SF_PUBLISHED;
77
                $an_status            = Constants::SF_AN_STATUS_APPROVED;
78
                $answerObj->setVar('uid', $xoopsUser->getVar('uid'));
79
                break;
80
            case Constants::SF_STATUS_ANSWERED:
81
                $breadcrumb_action1   = _AM_SF_ANSWERED;
82
                $breadcrumb_action2   = _AM_SF_APPROVING;
83
                $collapsableBar_title = _AM_SF_ANSWERED_TITLE;
84
                $collapsableBar_info  = _AM_SF_ANSWERED_TITLE_INFO;
85
                $button_caption       = _AM_SF_APPROVE;
86
                $an_status            = Constants::SF_AN_STATUS_PROPOSED;
87
                break;
88
            case Constants::SF_STATUS_SUBMITTED:
89
                $breadcrumb_action1   = _AM_SF_SUBMITTED;
90
                $breadcrumb_action2   = _AM_SF_APPROVING;
91
                $collapsableBar_title = _AM_SF_SUBMITTED_TITLE;
92
                $collapsableBar_info  = _AM_SF_SUBMITTED_INFO;
93
                $button_caption       = _AM_SF_APPROVE;
94
                $an_status            = Constants::SF_AN_STATUS_PROPOSED;
95
                break;
96
            case Constants::SF_STATUS_PUBLISHED:
97
                $breadcrumb_action1   = _AM_SF_PUBLISHED;
98
                $breadcrumb_action2   = _AM_SF_EDITING;
99
                $collapsableBar_title = _AM_SF_PUBLISHEDEDITING;
100
                $collapsableBar_info  = _AM_SF_PUBLISHEDEDITING_INFO;
101
                $button_caption       = _AM_SF_MODIFY;
102
                $an_status            = Constants::SF_AN_STATUS_APPROVED;
103
                break;
104
            case Constants::SF_STATUS_OFFLINE:
105
                $breadcrumb_action1   = _AM_SF_OFFLINE;
106
                $breadcrumb_action2   = _AM_SF_EDITING;
107
                $collapsableBar_title = _AM_SF_OFFLINEEDITING;
108
                $collapsableBar_info  = _AM_SF_OFFLINEEDITING_INFO;
109
                $button_caption       = _AM_SF_MODIFY;
110
                $an_status            = Constants::SF_AN_STATUS_APPROVED;
111
                break;
112
            case Constants::SF_STATUS_OPENED:
113
                $breadcrumb_action1   = _AM_SF_OPEN_QUESTIONS;
114
                $breadcrumb_action2   = _AM_SF_ANSWERING;
115
                $collapsableBar_title = _AM_SF_OPEN_QUESTION_ANSWERING;
116
                $collapsableBar_info  = _AM_SF_OPEN_QUESTION_ANSWERING_INFO;
117
                $button_caption       = _AM_SF_PUBLISH;
118
                $an_status            = Constants::SF_AN_STATUS_NOTSET;
119
                $answerObj->setVar('uid', $xoopsUser->getVar('uid'));
120
                break;
121
            case Constants::SF_STATUS_NEW_ANSWER:
122
                $breadcrumb_action1   = _AM_SF_PUBLISHED;
123
                $breadcrumb_action2   = _AM_SF_EDITING;
124
                $collapsableBar_title = _AM_SF_NEW_ANSWER_EDITING;
125
                $collapsableBar_info  = _AM_SF_NEW_ANSWER_EDITING_INFO;
126
                $button_caption       = _AM_SF_PUBLISH;
127
                $an_status            = Constants::SF_AN_STATUS_NOTSET;
128
                break;
129
            case 'default':
130
            default:
131
                break;
132
        }
133
134
        /*      if (!$answerObj) {
135
                    redirect_header("faq.php", 2, _AM_SF_ANSWERNOTFOUND);
136
                }       */
137
138
        // Creating the category of this FAQ
139
        $categoryObj = $faqObj->category();
140
141
        echo "<br>\n";
142
        Smartfaq\Utility::collapsableBar('bottomtable', 'bottomtableicon');
143
        echo "<img id='bottomtableicon' src=" . XOOPS_URL . '/modules/' . $xoopsModule->dirname() . "/assets/images/icon/close12.gif alt=''></a>&nbsp;" . $collapsableBar_title . '</h3>';
144
        echo "<div id='bottomtable'>";
145
        echo '<span style="color: #567; margin: 3px 0 12px 0; font-size: small; display: block; ">' . $collapsableBar_info . '</span>';
146
    } else {
147
        // there's no parameter, so we're adding a faq
148
        $faqObj = $faqHandler->create();
149
        $faqObj->setVar('uid', $xoopsUser->getVar('uid'));
150
        $categoryObj = $categoryHandler->create();
151
        $answerObj   = $answerHandler->create();
152
        $answerObj->setVar('uid', $xoopsUser->getVar('uid'));
153
154
        $breadcrumb_action1 = _AM_SF_SMARTFAQS;
155
        $breadcrumb_action2 = _AM_SF_CREATINGNEW;
156
        $button_caption     = _AM_SF_CREATE;
157
158
        Smartfaq\Utility::collapsableBar('bottomtable', 'bottomtableicon');
159
        echo "<img id='bottomtableicon' src=" . XOOPS_URL . '/modules/' . $xoopsModule->dirname() . "/assets/images/icon/close12.gif alt=''></a>&nbsp;" . _AM_SF_CREATESMARTFAQ . '</h3>';
160
        echo "<div id='bottomtable'>";
161
    }
162
    $sform = new \XoopsThemeForm(_AM_SF_SMARTFAQ, 'op', xoops_getenv('SCRIPT_NAME'), 'post', true);
163
    $sform->setExtra('enctype="multipart/form-data"');
164
165
    // faq requester
166
    $sform->addElement(new \XoopsFormLabel(_AM_SF_REQUESTED_BY, Smartfaq\Utility::getLinkedUnameFromId($faqObj->uid(), $helper->getConfig('userealname'))));
167
168
    // faq answered by
169
    $sform->addElement(new \XoopsFormLabel(_AM_SF_ANSWERED_BY, Smartfaq\Utility::getLinkedUnameFromId($answerObj->uid(), $helper->getConfig('userealname'))));
170
171
    // CATEGORY
172
    /*
173
    * Get information for pulldown menu using XoopsTree.
174
    * First var is the database table
175
    * Second var is the unique field ID for the categories
176
    * Last one is not set as we do not have sub menus in Smartfaq
177
    */
178
179
    $mytree = new Smartfaq\Tree($xoopsDB->prefix('smartfaq_categories'), 'categoryid', 'parentid');
180
    ob_start();
181
    $mytree->makeMySelBox('name', 'weight', $categoryObj->categoryid());
182
    $sform->addElement(new \XoopsFormLabel(_AM_SF_CATEGORY_FAQ, ob_get_clean()));
183
184
    // faq QUESTION
185
    $sform->addElement(new \XoopsFormTextArea(_AM_SF_QUESTION, 'question', $faqObj->question(0, 'e'), 7, 60));
186
187
    // ANSWER
188
    if ($merge) {
189
        $theanswer = $originalAnswerObj->answer('e') . "\n\n" . sprintf(_AM_SF_NEW_CONTRIBUTION, Smartfaq\Utility::getLinkedUnameFromId($answerObj->uid(), $helper->getConfig('userealname')), $answerObj->datesub(), $answerObj->answer('e'));
190
    } else {
191
        $theanswer = $answerObj->answer('e');
192
    }
193
194
    //$sform->addElement(new \XoopsFormDhtmlTextArea(_AM_SF_ANSWER_FAQ, 'answer', $theanswer, 15, 60), true);
195
196
    $editorTray = new \XoopsFormElementTray(_AM_SF_ANSWER_FAQ, '<br>');
197
    if (class_exists('XoopsFormEditor')) {
198
        $options['name']   = 'answer';
199
        $options['value']  = $theanswer;
200
        $options['rows']   = 5;
201
        $options['cols']   = '100%';
202
        $options['width']  = '100%';
203
        $options['height'] = '200px';
204
        $answerEditor      = new \XoopsFormEditor('', $helper->getConfig('form_editorOptions'), $options, $nohtml = false, $onfailure = 'textarea');
205
        $editorTray->addElement($answerEditor, true);
206
    } else {
207
        $answerEditor = new \XoopsFormDhtmlTextArea(_AM_SF_ANSWER_FAQ, 'answer', $theanswer, '100%', '100%');
0 ignored issues
show
'100%' of type string is incompatible with the type integer expected by parameter $cols of XoopsFormDhtmlTextArea::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

207
        $answerEditor = new \XoopsFormDhtmlTextArea(_AM_SF_ANSWER_FAQ, 'answer', $theanswer, '100%', /** @scrutinizer ignore-type */ '100%');
Loading history...
'100%' of type string is incompatible with the type integer expected by parameter $rows of XoopsFormDhtmlTextArea::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

207
        $answerEditor = new \XoopsFormDhtmlTextArea(_AM_SF_ANSWER_FAQ, 'answer', $theanswer, /** @scrutinizer ignore-type */ '100%', '100%');
Loading history...
208
        $editorTray->addElement($answerEditor, true);
209
    }
210
211
    $sform->addElement($editorTray);
212
213
    // HOW DO I
214
    $sform->addElement(new \XoopsFormText(_AM_SF_HOWDOI_FAQ, 'howdoi', 50, 255, $faqObj->howdoi('e')), false);
215
216
    // DIDUNO
217
    $sform->addElement(new \XoopsFormTextArea(_AM_SF_DIDUNO_FAQ, 'diduno', $faqObj->diduno('e'), 3, 60));
218
219
    // CONTEXT MODULE LINK
220
    // Retrieve the list of module currently installed. The key value is the dirname
221
    /** @var \XoopsModuleHandler $moduleHandler */
222
    $moduleHandler           = xoops_getHandler('module');
223
    $modules_array           = $moduleHandler->getList(null, true);
224
    $modulelink_select_array = ['url' => _AM_SF_SPECIFIC_URL_SELECT];
225
    $modulelink_select_array = array_merge($modules_array, $modulelink_select_array);
226
    $modulelink_select_array = array_merge(['None' => _AM_SF_NONE, 'All' => _AM_SF_ALL], $modulelink_select_array);
227
228
    $modulelink_select = new \XoopsFormSelect('', 'modulelink', $faqObj->modulelink());
229
    $modulelink_select->addOptionArray($modulelink_select_array);
230
    $modulelink_tray = new \XoopsFormElementTray(_AM_SF_CONTEXTMODULELINK_FAQ, '&nbsp;');
231
    $modulelink_tray->addElement($modulelink_select);
232
    $sform->addElement($modulelink_tray);
233
234
    // SPECIFICURL
235
    $sform->addElement(new \XoopsFormText(_AM_SF_SPECIFIC_URL, 'contextpage', 50, 60, $faqObj->contextpage()), false);
236
237
    // EXACT URL?
238
    $excaturl_radio = new \XoopsFormRadioYN(_AM_SF_EXACTURL, 'exacturl', $faqObj->exacturl(), ' ' . _AM_SF_YES, ' ' . _AM_SF_NO);
239
    $sform->addElement($excaturl_radio);
240
    // WEIGHT
241
    $sform->addElement(new \XoopsFormText(_AM_SF_WEIGHT, 'weight', 5, 5, $faqObj->weight()), true);
242
243
    // COMMENTS
244
    // Code to allow comments
245
    $addcomments_radio = new \XoopsFormRadioYN(_AM_SF_ALLOWCOMMENTS, 'cancomment', $faqObj->cancomment(), ' ' . _AM_SF_YES, ' ' . _AM_SF_NO);
246
    $sform->addElement($addcomments_radio);
247
248
    // PER ITEM PERMISSIONS
249
    /** @var \XoopsMemberHandler $memberHandler */
250
    $memberHandler   = xoops_getHandler('member');
251
    $group_list      = $memberHandler->getGroupList();
252
    $groups_checkbox = new \XoopsFormCheckBox(_AM_SF_PERMISSIONS_FAQ, 'groups[]', $faqObj->getGroups_read());
253
    foreach ($group_list as $group_id => $group_name) {
254
        if (XOOPS_GROUP_ADMIN != $group_id) {
255
            $groups_checkbox->addOption($group_id, $group_name);
256
        }
257
    }
258
    $sform->addElement($groups_checkbox);
259
260
    $partial_view = new \XoopsFormRadioYN(_AM_SF_PARTIALVIEW, 'partialview', $faqObj->partialview(), ' ' . _AM_SF_YES, ' ' . _AM_SF_NO);
261
    $sform->addElement($partial_view);
262
263
    // VARIOUS OPTIONS
264
    $options_tray = new \XoopsFormElementTray(_AM_SF_OPTIONS, '<br>');
265
266
    $html_checkbox = new \XoopsFormCheckBox('', 'html', $faqObj->html());
267
    $html_checkbox->addOption(1, _AM_SF_DOHTML);
268
    $options_tray->addElement($html_checkbox);
269
270
    $smiley_checkbox = new \XoopsFormCheckBox('', 'smiley', $faqObj->smiley());
271
    $smiley_checkbox->addOption(1, _AM_SF_DOSMILEY);
272
    $options_tray->addElement($smiley_checkbox);
273
274
    $xcodes_checkbox = new \XoopsFormCheckBox('', 'xcodes', $faqObj->xcodes());
275
    $xcodes_checkbox->addOption(1, _AM_SF_DOXCODE);
276
    $options_tray->addElement($xcodes_checkbox);
277
278
    $sform->addElement($options_tray);
279
280
    // OFFLINE
281
    if (Constants::SF_STATUS_OFFLINE == $faqObj->status()) {
282
        // Back OnLine
283
        $offline_radio = new \XoopsFormRadioYN(_AM_SF_OFFLINE_FIELD, 'offline', 1, ' ' . _AM_SF_YES, ' ' . _AM_SF_NO);
284
        $sform->addElement($offline_radio);
285
    }
286
287
    // faq ID
288
    $sform->addElement(new \XoopsFormHidden('faqid', $faqObj->faqid()));
289
290
    // requester id
291
    $sform->addElement(new \XoopsFormHidden('requester_uid', $faqObj->uid()));
292
293
    // answerer id
294
    $sform->addElement(new \XoopsFormHidden('answerer_uid', $answerObj->uid()));
295
296
    // ANSWER ID
297
    $sform->addElement(new \XoopsFormHidden('answerid', $answerObj->answerid()));
298
299
    $buttonTray = new \XoopsFormElementTray('', '');
300
    $hidden     = new \XoopsFormHidden('op', 'addfaq');
301
    $buttonTray->addElement($hidden);
302
303
    $sform->addElement(new \XoopsFormHidden('status', $faqObj->status()));
304
305
    // Setting the FAQ Status
306
    /*  $status_select = new \XoopsFormSelect('', 'status', $status);
307
    $status_select->addOptionArray(Smartfaq\Utility::getStatusArray());
308
    $status_tray = new \XoopsFormElementTray(_AM_SF_STATUS_EXP , '&nbsp;');
309
    $status_tray->addElement($status_select);
310
    $sform->addElement($status_tray);
311
    */
312
    if ($faqid) {
313
        // else, we're editing an existing faq
314
        // $buttonTray -> addElement( new \XoopsFormButton( '', 'mod', _AM_SF_MODIFY, 'submit' ) );
315
        $butt_create = new \XoopsFormButton('', '', $button_caption, 'submit');
316
        $butt_create->setExtra('onclick="this.form.elements.op.value=\'addfaq\'"');
317
        $buttonTray->addElement($butt_create);
318
319
        $butt_cancel = new \XoopsFormButton('', '', _AM_SF_CANCEL, 'button');
320
        $butt_cancel->setExtra('onclick="history.go(-1)"');
321
        $buttonTray->addElement($butt_cancel);
322
    } else {
323
        // there's no faqid? Then it's a new faq
324
        // $buttonTray -> addElement( new \XoopsFormButton( '', 'mod', _AM_SF_CREATE, 'submit' ) );
325
        $butt_create = new \XoopsFormButton('', '', _AM_SF_CREATE, 'submit');
326
        $butt_create->setExtra('onclick="this.form.elements.op.value=\'addfaq\'"');
327
        $buttonTray->addElement($butt_create);
328
329
        $butt_clear = new \XoopsFormButton('', '', _AM_SF_CLEAR, 'reset');
330
        $buttonTray->addElement($butt_clear);
331
332
        $butt_cancel = new \XoopsFormButton('', '', _AM_SF_CANCEL, 'button');
333
        $butt_cancel->setExtra('onclick="history.go(-1)"');
334
        $buttonTray->addElement($butt_cancel);
335
    }
336
337
    $sform->addElement($buttonTray);
338
    $sform->display();
339
    echo '</div>';
340
    unset($hidden);
341
}
342
343
/* -- Available operations -- */
344
switch ($op) {
345
    case 'merge':
346
        $faqid    = $_GET['faqid'] ?? -1;
347
        $answerid = $_GET['answerid'] ?? -1;
348
        if (-1 == $faqid) {
349
            $totalcategories = $categoryHandler->getCategoriesCount(-1);
350
            if (0 == $totalcategories) {
351
                redirect_header('category.php?op=mod', 3, _AM_SF_NEED_CATEGORY_FAQ);
352
            }
353
        }
354
355
        xoops_cp_header();
356
        require_once XOOPS_ROOT_PATH . '/class/xoopsformloader.php';
357
358
        editfaq(true, $faqid, $answerid, true);
359
        break;
360
    case 'mod':
361
        global $xoopsUser, $xoopsConfig, $xoopsDB, $xoopsModule, $modify, $myts;
362
        $faqid    = $_GET['faqid'] ?? -1;
363
        $answerid = $_GET['answerid'] ?? -1;
364
        if (-1 == $faqid) {
365
            $totalcategories = $categoryHandler->getCategoriesCount(-1);
366
            if (0 == $totalcategories) {
367
                redirect_header('category.php?op=mod', 3, _AM_SF_NEED_CATEGORY_FAQ);
368
            }
369
        }
370
371
        $adminObject = Admin::getInstance();
372
        xoops_cp_header();
373
374
        $adminObject->displayNavigation(basename(__FILE__));
375
        require_once XOOPS_ROOT_PATH . '/class/xoopsformloader.php';
376
377
        editfaq(true, $faqid, $answerid);
378
        break;
379
    case 'addfaq':
380
        global $xoopsUser;
381
382
        $faqid        = Request::getInt('faqid', -1, 'POST');
383
        $requesterUid = Request::getInt('requester_uid', 0, 'POST');
384
        $answererUid  = Request::getInt('answerer_uid', 0, 'POST');
385
386
        // Creating the FAQ and answer objects
387
        if (-1 != $faqid) {
388
            $faqObj    = new Smartfaq\Faq($faqid);
389
            $answerObj = $faqObj->answer();
390
            // If the FAQ does not have an answer, then it's an answered opened question
391
            if (!$answerObj) {
392
                echo 'error in faq.php...200412111827';
393
            }
394
        } else {
395
            $faqObj    = $faqHandler->create();
396
            $answerObj = $answerHandler->create();
397
        }
398
399
        // Putting the values in the FAQ object
400
        //        if (Request::hasVar('groups', 'POST')) {
401
        //            $faqObj->setGroups_read($_POST['groups']);
402
        //        } else {
403
        //            $faqObj->setGroups_read();
404
        //        }
405
406
        if (Request::hasVar('groups', 'POST')) {
407
            $faqObj->setGroups_read(Request::getArray('groups', [], 'POST'));
408
        } else {
409
            $faqObj->setGroups_read();
410
        }
411
412
        $faqObj->setVar('categoryid', Request::getInt('categoryid', 0, 'POST'));
413
        $faqObj->setVar('question', Request::getString('question', '', 'POST'));
414
        $faqObj->setVar('howdoi', Request::getString('howdoi', '', 'POST'));
415
        $faqObj->setVar('diduno', Request::getString('diduno', '', 'POST'));
416
417
        $faqObj->setVar('status', Request::getInt('status', Constants::SF_STATUS_ASKED, 'POST'));
418
419
        // If this SmartFAQ is offline and the user set this option to No
420
        $offline = Request::getInt('offline', 1, 'POST');
421
        if ((0 == $offline) && (Constants::SF_STATUS_OFFLINE == $faqObj->status())) {
422
            $faqObj->setVar('status', Constants::SF_STATUS_PUBLISHED);
423
        }
424
        $faqObj->setVar('weight', Request::getInt('weight', $faqObj->weight(), 'POST'));
425
        $faqObj->setVar('html', Request::getInt('html', 0, 'POST'));
426
        $faqObj->setVar('smiley', Request::getInt('smiley', 0, 'POST'));
427
        $faqObj->setVar('xcodes', Request::getInt('xcodes', 0, 'POST'));
428
        $faqObj->setVar('cancomment', Request::getInt('cancomment', 0, 'POST'));
429
        $faqObj->setVar('modulelink', Request::getString('modulelink', '', 'POST'));
430
        $faqObj->setVar('contextpage', Request::getString('contextpage', '', 'POST'));
431
        $faqObj->setVar('exacturl', Request::getString('exacturl', '', 'POST'));
432
        $faqObj->setVar('partialview', Request::getInt('partialview', 0, 'POST'));
433
        $faqObj->setVar('uid', $requesterUid);
434
435
        switch ($faqObj->status()) {
436
            case Constants::SF_STATUS_ASKED:
437
                $redirect_msg = _AM_SF_ASKED_APPROVE_SUCCESS;
438
                $error_msg    = _AM_SF_ARTNOTUPDATED;
439
                // Setting the new status
440
                $status    = Constants::SF_STATUS_PUBLISHED;
441
                $an_status = Constants::SF_AN_STATUS_APPROVED;
442
                $notifToDo = [Constants::SF_NOT_FAQ_PUBLISHED];
443
                break;
444
            case Constants::SF_STATUS_ANSWERED:
445
                $redirect_msg = _AM_SF_ANSWERED_APPROVE_SUCCESS;
446
                $error_msg    = _AM_SF_ARTNOTUPDATED;
447
                // Setting the new status
448
                $status    = Constants::SF_STATUS_PUBLISHED;
449
                $an_status = Constants::SF_AN_STATUS_APPROVED;
450
                $notifToDo = [Constants::SF_NOT_FAQ_PUBLISHED];
451
                break;
452
            case Constants::SF_STATUS_SUBMITTED:
453
                $redirect_msg = _AM_SF_SUBMITTED_APPROVE_SUCCESS;
454
                $error_msg    = _AM_SF_ARTNOTUPDATED;
455
                // Setting the new status
456
                $status    = Constants::SF_STATUS_PUBLISHED;
457
                $an_status = Constants::SF_AN_STATUS_APPROVED;
458
                $notifToDo = [Constants::SF_NOT_FAQ_PUBLISHED];
459
                break;
460
            case Constants::SF_STATUS_PUBLISHED:
461
                $redirect_msg = _AM_SF_PUBLISHED_MOD_SUCCESS;
462
                $error_msg    = _AM_SF_ARTNOTUPDATED;
463
                // Setting the new status
464
                $status    = Constants::SF_STATUS_PUBLISHED;
465
                $an_status = Constants::SF_AN_STATUS_APPROVED;
466
                break;
467
            case Constants::SF_STATUS_OPENED:
468
                $redirect_msg = _AM_SF_OPENED_ANSWERING_SUCCESS;
469
                $error_msg    = _AM_SF_ARTNOTUPDATED;
470
                // Setting the new status
471
                $status    = Constants::SF_STATUS_PUBLISHED;
472
                $an_status = Constants::SF_AN_STATUS_APPROVED;
473
                $notifToDo = [Constants::SF_NOT_FAQ_PUBLISHED];
474
                break;
475
            case Constants::SF_STATUS_NEW_ANSWER:
476
                $redirect_msg = _AM_SF_FAQ_NEW_ANSWER_PUBLISHED;
477
                $error_msg    = _AM_SF_ARTNOTUPDATED;
478
                // Setting the new status
479
                $status    = Constants::SF_STATUS_PUBLISHED;
480
                $an_status = Constants::SF_AN_STATUS_APPROVED;
481
                //$notifToDo = array(Constants::SF_NOT_FAQ_PUBLISHED);
482
                break;
483
            case Constants::SF_STATUS_OFFLINE:
484
                break;
485
            case 'default':
486
            default:
487
                $redirect_msg = _AM_SF_SUBMITTED_APPROVE_SUCCESS;
488
                $error_msg    = _AM_SF_ARTNOTCREATED;
489
                // Setting the new status
490
                $status    = Constants::SF_STATUS_PUBLISHED;
491
                $an_status = Constants::SF_AN_STATUS_APPROVED;
492
                $notifToDo = [Constants::SF_NOT_FAQ_PUBLISHED];
493
                break;
494
        }
495
        $faqObj->setVar('status', $status);
496
497
        // Puting the info in the answer object
498
        $answerObj->setVar('answer', $_POST['answer']);
499
        $answerObj->setVar('status', $an_status);
500
        $answerObj->setVar('uid', $answererUid);
501
502
        // Storing the FAQ
503
        if (!$faqObj->store()) {
504
            redirect_header('<script>javascript:history.go(-1)</script>', 3, $error_msg . Smartfaq\Utility::formatErrors($faqObj->getErrors()));
505
        }
506
507
        // Storing the answer
508
        $answerObj->setVar('faqid', $faqObj->faqid());
509
        if (!$answerObj->store()) {
510
            redirect_header('<script>javascript:history.go(-1)</script>', 3, $error_msg . Smartfaq\Utility::formatErrors($answerObj->getErrors()));
511
        }
512
513
        // Send notifications
514
        if (!empty($notifToDo)) {
515
            $faqObj->sendNotifications($notifToDo);
516
        }
517
518
        redirect_header('faq.php', 2, $redirect_msg);
519
        break;
520
    case 'del':
521
        global $xoopsUser, $xoopsConfig, $xoopsDB, $_GET;
522
523
        $module_id = $xoopsModule->getVar('mid');
524
        /** @var \XoopsGroupPermHandler $grouppermHandler */
525
        $grouppermHandler = xoops_getHandler('groupperm');
526
527
        $faqid = Request::getInt('faqid', 0, 'POST');
528
        $faqid = Request::getInt('faqid', $faqid, 'GET');
529
530
        $faqObj = new Smartfaq\Faq($faqid);
531
532
        $confirm  = Request::getInt('confirm', 0, 'POST');
533
        $question = Request::getString('question', '', 'POST');
534
535
        if ($confirm) {
536
            if (!$faqHandler->delete($faqObj)) {
537
                redirect_header('faq.php', 2, _AM_SF_FAQ_DELETE_ERROR . Smartfaq\Utility::formatErrors($faqObj->getErrors()));
538
            }
539
540
            redirect_header('faq.php', 2, sprintf(_AM_SF_ARTISDELETED, $faqObj->question()));
541
        } else {
542
            // no confirm: show deletion condition
543
            $faqid = Request::getInt('faqid', 0, 'POST');
544
            xoops_cp_header();
545
            xoops_confirm(
546
                [
547
                    'op'      => 'del',
548
                    'faqid'   => $faqObj->faqid(),
549
                    'confirm' => 1,
550
                    'name'    => $faqObj->question(),
551
                ],
552
                'faq.php',
553
                _AM_SF_DELETETHISARTICLE . " <br>'" . $faqObj->question() . "'. <br> <br>",
554
                _AM_SF_DELETE
555
            );
556
            xoops_cp_footer();
557
        }
558
559
        exit();
560
    case 'default':
561
    default:
562
        $adminObject = Admin::getInstance();
563
        xoops_cp_header();
564
565
        $adminObject->displayNavigation(basename(__FILE__));
566
567
        require_once XOOPS_ROOT_PATH . '/class/xoopsformloader.php';
568
        require_once XOOPS_ROOT_PATH . '/class/pagenav.php';
569
570
        require_once XOOPS_ROOT_PATH . '/modules/smartfaq/include/displayfaqs.php';
571
572
        $totalcategories = $categoryHandler->getCategoriesCount(-1);
573
        if ($totalcategories > 0) {
574
            editfaq();
575
        }
576
577
        break;
578
}
579
580
require_once __DIR__ . '/admin_footer.php';
581