Completed
Push — master ( 454ebd...de22fe )
by Michael
03:58
created

submit.php (18 issues)

Upgrade to new PHP Analysis Engine

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
 * Module: SmartFAQ
5
 * Author: The SmartFactory <www.smartfactory.ca>
6
 * Licence: GNU
7
 */
8
9
use XoopsModules\Smartfaq;
10
use XoopsModules\Smartfaq\Constants;
11
12
require_once __DIR__ . '/header.php';
13
14
global $xoopsUser, $xoopsConfig, $xoopsModuleConfig, $xoopsModule;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
15
16
// Creating the category handler object
17
/** @var \XoopsModules\Smartfaq\CategoryHandler $categoryHandler */
18
$categoryHandler = \XoopsModules\Smartfaq\Helper::getInstance()->getHandler('Category');
19
20
// Creating the FAQ handler object
21
/** @var \XoopsModules\Smartfaq\FaqHandler $faqHandler */
22
$faqHandler = \XoopsModules\Smartfaq\Helper::getInstance()->getHandler('Faq');
23
24
// Creating the answer handler object
25
/** @var \XoopsModules\Smartfaq\AnswerHandler $answerHandler */
26
$answerHandler = \XoopsModules\Smartfaq\Helper::getInstance()->getHandler('Answer');
27
28
// Get the total number of categories
29
$totalCategories = count($categoryHandler->getCategories());
30
31
if (0 == $totalCategories) {
32
    redirect_header('index.php', 1, _AM_SF_NOCOLEXISTS);
33
}
34
35
// Find if the user is admin of the module
36
$isAdmin = Smartfaq\Utility::userIsAdmin();
37
// If the user is not admin AND we don't allow user submission, exit
38 View Code Duplication
if (!($isAdmin
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
39
      || (isset($xoopsModuleConfig['allowsubmit']) && 1 == $xoopsModuleConfig['allowsubmit']
40
          && (is_object($xoopsUser)
41
              || (isset($xoopsModuleConfig['anonpost'])
42
                  && 1 == $xoopsModuleConfig['anonpost']))))) {
43
    redirect_header('index.php', 1, _NOPERM);
44
}
45
46
$op = 'form';
47
48
if (isset($_POST['post'])) {
49
    $op = 'post';
50
} elseif (isset($_POST['preview'])) {
51
    $op = 'preview';
52
}
53
54
switch ($op) {
55
    case 'preview':
0 ignored issues
show
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
56
57
        global $xoopsUser, $xoopsConfig, $xoopsModule, $xoopsModuleConfig, $xoopsDB;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
58
59
        $faqObj      = $faqHandler->create();
60
        $answerObj   = $answerHandler->create();
61
        $categoryObj = $categoryHandler->get($_POST['categoryid']);
62
63 View Code Duplication
        if (!$xoopsUser) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
64
            if (1 == $xoopsModuleConfig['anonpost']) {
65
                $uid = 0;
66
            } else {
67
                redirect_header('index.php', 3, _NOPERM);
68
            }
69
        } else {
70
            $uid = $xoopsUser->uid();
0 ignored issues
show
The method uid cannot be called on $xoopsUser (of type integer|double|string|array|boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
71
        }
72
73
        $notifypub = isset($_POST['notifypub']) ? $_POST['notifypub'] : 0;
74
75
        // Putting the values about the FAQ in the FAQ object
76
        $faqObj->setVar('categoryid', $_POST['categoryid']);
77
        $faqObj->setVar('uid', $uid);
78
        $faqObj->setVar('question', $_POST['question']);
79
        $faqObj->setVar('howdoi', $_POST['howdoi']);
80
        $faqObj->setVar('diduno', $_POST['diduno']);
81
        $faqObj->setVar('datesub', time());
82
83
        // Putting the values in the answer object
84
        $answerObj->setVar('status', Constants::SF_AN_STATUS_APPROVED);
85
        $answerObj->setVar('faqid', $faqObj->faqid());
86
        $answerObj->setVar('answer', $_POST['answer']);
87
        $answerObj->setVar('uid', $uid);
88
89
        global $xoopsUser, $myts;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
90
91
        $GLOBALS['xoopsOption']['template_main'] = 'smartfaq_submit.tpl';
92
        require_once XOOPS_ROOT_PATH . '/header.php';
93
        require_once __DIR__ . '/footer.php';
94
95
        $name = $xoopsUser ? ucwords($xoopsUser->getVar('uname')) : 'Anonymous';
0 ignored issues
show
The method getVar cannot be called on $xoopsUser (of type integer|double|string|array|boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
96
97
        $moduleName          =& $myts->displayTarea($xoopsModule->getVar('name'));
98
        $faq                 = $faqObj->toArray(null, $categoryObj, false);
99
        $faq['categoryPath'] = $categoryObj->getCategoryPath(true);
100
        $faq['answer']       = $answerObj->answer();
101
        $faq['who_when']     = $faqObj->getWhoAndWhen();
102
103
        $faq['comments'] = -1;
104
        $xoopsTpl->assign('faq', $faq);
105
        $xoopsTpl->assign('op', 'preview');
106
        $xoopsTpl->assign('whereInSection', $moduleName);
107
        $xoopsTpl->assign('lang_submit', _MD_SF_SUB_SNEWNAME);
108
109
        $xoopsTpl->assign('lang_intro_title', sprintf(_MD_SF_SUB_SNEWNAME, ucwords($xoopsModule->name())));
110
        $xoopsTpl->assign('lang_intro_text', _MD_SF_GOODDAY . "<b>$name</b>, " . _MD_SF_SUB_INTRO);
111
112
        require_once __DIR__ . '/include/submit.inc.php';
113
114
        require_once XOOPS_ROOT_PATH . '/footer.php';
115
116
        exit();
117
        break;
118
119
    case 'post':
0 ignored issues
show
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
120
121
        global $xoopsUser, $xoopsConfig, $xoopsModule, $xoopsModuleConfig, $xoopsDB;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
122
123
        $newFaqObj    = $faqHandler->create();
124
        $newAnswerObj = $answerHandler->create();
125
126 View Code Duplication
        if (!$xoopsUser) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
127
            if (1 == $xoopsModuleConfig['anonpost']) {
128
                $uid = 0;
129
            } else {
130
                redirect_header('index.php', 3, _NOPERM);
131
            }
132
        } else {
133
            $uid = $xoopsUser->uid();
0 ignored issues
show
The method uid cannot be called on $xoopsUser (of type integer|double|string|array|boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
134
        }
135
136
        $notifypub = isset($_POST['notifypub']) ? $_POST['notifypub'] : 0;
137
138
        // Putting the values about the FAQ in the FAQ object
139
        $newFaqObj->setVar('categoryid', $_POST['categoryid']);
140
        $newFaqObj->setVar('uid', $uid);
141
        $newFaqObj->setVar('question', $_POST['question']);
142
        $newFaqObj->setVar('howdoi', $_POST['howdoi']);
143
        $newFaqObj->setVar('diduno', $_POST['diduno']);
144
        $newFaqObj->setVar('notifypub', $notifypub);
145
        //$newFaqObj->setVar('modulelink', $_POST['modulelink']);
0 ignored issues
show
Unused Code Comprehensibility introduced by
85% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
146
        //$newFaqObj->setVar('contextpage', $_POST['contextpage']);
0 ignored issues
show
Unused Code Comprehensibility introduced by
85% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
147
148
        // Setting the status of the FAQ
149
150
        // if user is admin, FAQ are automatically published
151
        $isAdmin = Smartfaq\Utility::userIsAdmin();
152
        if ($isAdmin) {
153
            $newFaqObj->setVar('status', Constants::SF_STATUS_PUBLISHED);
154
        } elseif (1 == $xoopsModuleConfig['autoapprove_submitted_faq']) {
155
            $newFaqObj->setVar('status', Constants::SF_STATUS_PUBLISHED);
156
        } else {
157
            $newFaqObj->setVar('status', Constants::SF_STATUS_SUBMITTED);
158
        }
159
160
        // Storing the FAQ object in the database
161
        if (!$newFaqObj->store()) {
162
            redirect_header('javascript:history.go(-1)', 2, _MD_SF_SUBMIT_ERROR);
163
        }
164
165
        // Putting the values in the answer object
166
        $newAnswerObj->setVar('status', Constants::SF_AN_STATUS_APPROVED);
167
        $newAnswerObj->setVar('faqid', $newFaqObj->faqid());
168
        $newAnswerObj->setVar('answer', $_POST['answer']);
169
        $newAnswerObj->setVar('uid', $uid);
170
171
        //====================================================================================
172
        //TODO post Attachment
173
        $attachments_tmp = [];
174
        if (!empty($_POST['attachments_tmp'])) {
175
            $attachments_tmp = unserialize(base64_decode($_POST['attachments_tmp']));
176
            if (isset($_POST['delete_tmp']) && count($_POST['delete_tmp'])) {
177
                foreach ($_POST['delete_tmp'] as $key) {
178
                    unlink(XOOPS_ROOT_PATH . '/' . $xoopsModuleConfig['dir_attachments'] . '/' . $attachments_tmp[$key][0]);
179
                    unset($attachments_tmp[$key]);
180
                }
181
            }
182
        }
183
        if (count($attachments_tmp)) {
184
            foreach ($attachments_tmp as $key => $attach) {
185
                if (rename(XOOPS_CACHE_PATH . '/' . $attachments_tmp[$key][0], XOOPS_ROOT_PATH . '/' . $xoopsModuleConfig['dir_attachments'] . '/' . $attachments_tmp[$key][0])) {
186
                    $post_obj->setAttachment($attach[0], $attach[1], $attach[2]);
187
                }
188
            }
189
        }
190
        $error_upload = '';
191
192
        if (isset($_FILES['userfile']['name']) && '' != $_FILES['userfile']['name']
193
            && $topicHandler->getPermission($forum_obj, $topic_status, 'attach')) {
194
            require_once XOOPS_ROOT_PATH . '/modules/' . $xoopsModule->getVar('dirname', 'n') . '/class/uploader.php';
195
            $maxfilesize = $forum_obj->getVar('attach_maxkb') * 1024;
196
            $uploaddir   = XOOPS_CACHE_PATH;
197
198
            $uploader = new Smartfaq\Uploader($uploaddir, $newAnswerObj->getVar('attach_ext'), (int)$maxfilesize, (int)$xoopsModuleConfig['max_img_width'], (int)$xoopsModuleConfig['max_img_height']);
199
200
            if ($_FILES['userfile']['error'] > 0) {
201
                switch ($_FILES['userfile']['error']) {
202
                    case 1:
203
                        $error_message[] = _MD_NEWBB_MAXUPLOADFILEINI;
204
                        break;
205
                    case 2:
206
                        $error_message[] = sprintf(_MD_NEWBB_MAXKB, $forum_obj->getVar('attach_maxkb'));
207
                        break;
208
                    default:
209
                        $error_message[] = _MD_NEWBB_UPLOAD_ERRNODEF;
210
                        break;
211
                }
212
            } else {
213
                $uploader->setCheckMediaTypeByExt();
214
215
                if ($uploader->fetchMedia($_POST['xoops_upload_file'][0])) {
216
                    $prefix = is_object($xoopsUser) ? (string)$xoopsUser->uid() . '_' : 'newbb_';
217
                    $uploader->setPrefix($prefix);
218
                    if (!$uploader->upload()) {
219
                        $error_message[] = $error_upload =& $uploader->getErrors();
220
                    } else {
221
                        if (is_file($uploader->getSavedDestination())) {
222
                            if (rename(XOOPS_CACHE_PATH . '/' . $uploader->getSavedFileName(), XOOPS_ROOT_PATH . '/' . $xoopsModuleConfig['dir_attachments'] . '/' . $uploader->getSavedFileName())) {
223
                                $post_obj->setAttachment($uploader->getSavedFileName(), $uploader->getMediaName(), $uploader->getMediaType());
224
                            }
225
                        }
226
                    }
227
                } else {
228
                    $error_message[] = $error_upload =& $uploader->getErrors();
229
                }
230
            }
231
        }
232
233
        //====================================================
234
235
        // Storing the answer object in the database
236
        if (!$newAnswerObj->store()) {
237
            redirect_header('javascript:history.go(-1)', 2, _MD_SF_SUBMIT_ERROR);
238
        }
239
240
        // Get the cateopry object related to that FAQ
241
        $categoryObj = $newFaqObj->category();
242
243
        // If autoapprove_submitted_faq
244
        if ($isAdmin) {
245
            // We do not not subscribe user to notification on publish since we publish it right away
246
247
            // Send notifications
248
            $newFaqObj->sendNotifications([Constants::SF_NOT_FAQ_PUBLISHED]);
249
250
            $redirect_msg = _MD_SF_SUBMIT_FROM_ADMIN;
251
        } elseif (1 == $xoopsModuleConfig['autoapprove_submitted_faq']) {
252
            // We do not not subscribe user to notification on publish since we publish it right away
253
254
            // Send notifications
255
            $newFaqObj->sendNotifications([Constants::SF_NOT_FAQ_PUBLISHED]);
256
257
            $redirect_msg = _MD_SF_QNA_RECEIVED_AND_PUBLISHED;
258 View Code Duplication
        } else {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
259
            // Subscribe the user to On Published notification, if requested
260
            if (1 == $notifypub) {
261
                require_once XOOPS_ROOT_PATH . '/include/notification_constants.php';
262
                $notificationHandler = xoops_getHandler('notification');
263
                $notificationHandler->subscribe('faq', $newFaqObj->faqid(), 'approved', XOOPS_NOTIFICATION_MODE_SENDONCETHENDELETE);
264
            }
265
            // Send notifications
266
            $newFaqObj->sendNotifications([Constants::SF_NOT_FAQ_SUBMITTED]);
267
268
            $redirect_msg = _MD_SF_QNA_RECEIVED_NEED_APPROVAL;
269
        }
270
271
        redirect_header('index.php', 2, $redirect_msg);
272
        break;
273
274
    case 'form':
275
    default:
0 ignored issues
show
The default body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a default statement must start on the line immediately following the statement.

switch ($expr) {
    default:
        doSomething(); //right
        break;
}


switch ($expr) {
    default:

        doSomething(); //wrong
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
276
277
        global $xoopsUser, $myts;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
278
279
        $faqObj      = $faqHandler->create();
280
        $answerObj   = $answerHandler->create();
281
        $categoryObj = $categoryHandler->create();
282
283
        $GLOBALS['xoopsOption']['template_main'] = 'smartfaq_submit.html';
284
        require_once XOOPS_ROOT_PATH . '/header.php';
285
        require_once __DIR__ . '/footer.php';
286
287
        $name       = $xoopsUser ? ucwords($xoopsUser->getVar('uname')) : 'Anonymous';
0 ignored issues
show
The method getVar cannot be called on $xoopsUser (of type integer|double|string|array|boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
288
        $notifypub  = 1;
289
        $moduleName =& $myts->displayTarea($xoopsModule->getVar('name'));
290
        $xoopsTpl->assign('whereInSection', $moduleName);
291
        $xoopsTpl->assign('lang_submit', _MD_SF_SUB_SNEWNAME);
292
293
        $xoopsTpl->assign('lang_intro_title', sprintf(_MD_SF_SUB_SNEWNAME, ucwords($xoopsModule->name())));
294
        $xoopsTpl->assign('lang_intro_text', _MD_SF_GOODDAY . "<b>$name</b>, " . _MD_SF_SUB_INTRO);
295
296
        require_once __DIR__ . '/include/submit.inc.php';
297
298
        require_once XOOPS_ROOT_PATH . '/footer.php';
299
        break;
300
}
301