Passed
Push — master ( 2744eb...81ba93 )
by Michael
02:46
created

Answer::__construct()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 28
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 28
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 22
nc 4
nop 1
1
<?php namespace XoopsModules\Smartfaq;
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 20 and the first side effect is on line 12.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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
/** @var Smartfaq\Helper $helper */
12
$helper = Smartfaq\Helper::getInstance();
13
14
// defined('XOOPS_ROOT_PATH') || die('Restricted access');
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
15
16
17
/**
18
 * Class Answer
19
 */
20
class Answer extends \XoopsObject
0 ignored issues
show
Bug introduced by
The type XoopsObject was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
{
22
    public $attachment_array = [];
23
24
    /**
25
     * constructor
26
     * @param null $id
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $id is correct as it would always require null to be passed?
Loading history...
27
     */
28
    public function __construct($id = null)
29
    {
30
        $this->db = \XoopsDatabaseFactory::getDatabaseConnection();
0 ignored issues
show
Bug Best Practice introduced by
The property db does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Bug introduced by
The type XoopsDatabaseFactory was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
31
        $this->initVar('answerid', XOBJ_DTYPE_INT, null, false);
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Smartfaq\XOBJ_DTYPE_INT was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
32
        $this->initVar('status', XOBJ_DTYPE_INT, -1, false);
33
        $this->initVar('faqid', XOBJ_DTYPE_INT, null, false);
34
        $this->initVar('answer', XOBJ_DTYPE_TXTAREA, null, true);
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Smartfaq\XOBJ_DTYPE_TXTAREA was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
35
        $this->initVar('uid', XOBJ_DTYPE_INT, 0, false);
36
        $this->initVar('datesub', XOBJ_DTYPE_INT, null, false);
37
        $this->initVar('notifypub', XOBJ_DTYPE_INT, 0, false);
38
39
        $this->initVar('attachment', XOBJ_DTYPE_TXTAREA, '');
40
41
        $this->initVar('dohtml', XOBJ_DTYPE_INT, 1, false);
42
        $this->initVar('doxcode', XOBJ_DTYPE_INT, 1, false);
43
        $this->initVar('dosmiley', XOBJ_DTYPE_INT, 1, false);
44
        $this->initVar('doimage', XOBJ_DTYPE_INT, 0, false);
45
        $this->initVar('dobr', XOBJ_DTYPE_INT, 1, false);
46
47
        // for backward compatibility
48
        if (isset($id)) {
49
            if (is_array($id)) {
50
                $this->assignVars($id);
51
            } else {
52
                $answerHandler = new AnswerHandler($this->db);
53
                $answer        = $answerHandler->get($id);
54
                foreach ($answer->vars as $k => $v) {
55
                    $this->assignVar($k, $v['value']);
56
                }
57
            }
58
        }
59
    }
60
61
    // ////////////////////////////////////////////////////////////////////////////////////
62
    // attachment functions    TODO: there should be a file/attachment management class
63
    /**
64
     * @return array|mixed|null
65
     */
66
    public function getAttachment()
67
    {
68
        if (count($this->attachment_array)) {
69
            return $this->attachment_array;
70
        }
71
        $attachment = $this->getVar('attachment');
72
        if (empty($attachment)) {
73
            $this->attachment_array = null;
74
        } else {
75
            $this->attachment_array = @unserialize(base64_decode($attachment));
76
        }
77
78
        return $this->attachment_array;
79
    }
80
81
    /**
82
     * @param $attach_key
83
     * @return bool
84
     */
85
    public function incrementDownload($attach_key)
86
    {
87
        if (!$attach_key) {
88
            return false;
89
        }
90
        $this->attachment_array[(string)$attach_key]['num_download']++;
91
92
        return $this->attachment_array[(string)$attach_key]['num_download'];
93
    }
94
95
    /**
96
     * @return bool
97
     */
98
    public function saveAttachment()
99
    {
100
        $attachment_save = '';
101
        if (is_array($this->attachment_array) && count($this->attachment_array) > 0) {
102
            $attachment_save = base64_encode(serialize($this->attachment_array));
103
        }
104
        $this->setVar('attachment', $attachment_save);
105
        $sql = 'UPDATE ' . $GLOBALS['xoopsDB']->prefix('smartfaq_answers') . ' SET attachment=' . $GLOBALS['xoopsDB']->quoteString($attachment_save) . ' WHERE post_id = ' . $this->getVar('answerid');
106
        if (!$result = $GLOBALS['xoopsDB']->queryF($sql)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
107
            //xoops_error($GLOBALS["xoopsDB"]->error());
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% 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...
108
            return false;
109
        }
110
111
        return true;
112
    }
113
114
    /**
115
     * @param  null $attach_array
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $attach_array is correct as it would always require null to be passed?
Loading history...
116
     * @return bool
117
     */
118
    public function deleteAttachment($attach_array = null)
119
    {
120
        /** @var Smartfaq\Helper $helper */
121
        $helper = Smartfaq\Helper::getInstance();
122
123
        $attach_old = $this->getAttachment();
124
        if (!is_array($attach_old) || count($attach_old) < 1) {
125
            return true;
126
        }
127
        $this->attachment_array = [];
128
129
        if (null === $attach_array) {
130
            $attach_array = array_keys($attach_old);
131
        } // to delete all!
132
        if (!is_array($attach_array)) {
133
            $attach_array = [$attach_array];
134
        }
135
136
        foreach ($attach_old as $key => $attach) {
137
            if (in_array($key, $attach_array)) {
138
                @unlink(XOOPS_ROOT_PATH . '/' . $helper->getConfig('dir_attachments') . '/' . $attach['name_saved']);
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Smartfaq\XOOPS_ROOT_PATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for unlink(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

138
                /** @scrutinizer ignore-unhandled */ @unlink(XOOPS_ROOT_PATH . '/' . $helper->getConfig('dir_attachments') . '/' . $attach['name_saved']);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
139
                @unlink(XOOPS_ROOT_PATH . '/' . $helper->getConfig('dir_attachments') . '/thumbs/' . $attach['name_saved']); // delete thumbnails
140
                continue;
141
            }
142
            $this->attachment_array[$key] = $attach;
143
        }
144
        $attachment_save = '';
145
        if (is_array($this->attachment_array) && count($this->attachment_array) > 0) {
146
            $attachment_save = base64_encode(serialize($this->attachment_array));
147
        }
148
        $this->setVar('attachment', $attachment_save);
149
150
        return true;
151
    }
152
153
    /**
154
     * @param  string $name_saved
155
     * @param  string $name_display
156
     * @param  string $mimetype
157
     * @param  int    $num_download
158
     * @return bool
159
     */
160
    public function setAttachment($name_saved = '', $name_display = '', $mimetype = '', $num_download = 0)
161
    {
162
        static $counter = 0;
163
        $this->attachment_array = $this->getAttachment();
164
        if ($name_saved) {
165
            $key                          = (string)(time() + ($counter++));
166
            $this->attachment_array[$key] = [
167
                'name_saved'   => $name_saved,
168
                'name_display' => isset($name_display) ? $name_display : $name_saved,
169
                'mimetype'     => $mimetype,
170
                'num_download' => isset($num_download) ? (int)$num_download : 0
171
            ];
172
        }
173
        $attachment_save = null;
174
        if (is_array($this->attachment_array)) {
175
            $attachment_save = base64_encode(serialize($this->attachment_array));
176
        }
177
        $this->setVar('attachment', $attachment_save);
178
179
        return true;
180
    }
181
182
    /**
183
     * TODO: refactor
184
     * @param  bool $asSource
185
     * @return string
186
     */
187
    public function displayAttachment($asSource = false)
188
    {
189
        global $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...
190
        /** @var Smartfaq\Helper $helper */
191
        $helper = Smartfaq\Helper::getInstance();
192
193
        $post_attachment = '';
194
        $attachments     = $this->getAttachment();
195
        if (is_array($attachments) && count($attachments) > 0) {
196
            $iconHandler = sf_getIconHandler();
197
            $mime_path   = $iconHandler->getPath('mime');
198
            require_once XOOPS_ROOT_PATH . '/modules/' . $xoopsModule->getVar('dirname', 'n') . '/include/functions.image.php';
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Smartfaq\XOOPS_ROOT_PATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
199
            $image_extensions = ['jpg', 'jpeg', 'gif', 'png', 'bmp']; // need improve !!!
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% 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...
200
            $post_attachment  .= '<br><strong>' . _MD_ATTACHMENT . '</strong>:';
201
            $post_attachment  .= '<br><hr size="1" noshade="noshade"><br>';
202
            foreach ($attachments as $key => $att) {
203
                $file_extension = ltrim(strrchr($att['name_saved'], '.'), '.');
204
                $filetype       = $file_extension;
205
                if (file_exists(XOOPS_ROOT_PATH . '/' . $mime_path . '/' . $filetype . '.gif')) {
206
                    $icon_filetype = XOOPS_URL . '/' . $mime_path . '/' . $filetype . '.gif';
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Smartfaq\XOOPS_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
207
                } else {
208
                    $icon_filetype = XOOPS_URL . '/' . $mime_path . '/unknown.gif';
209
                }
210
                $file_size = @filesize(XOOPS_ROOT_PATH . '/' . $helper->getConfig('dir_attachments') . '/' . $att['name_saved']);
211
                $file_size = number_format($file_size / 1024, 2) . ' KB';
212
                if ($helper->getConfig('media_allowed') && in_array(strtolower($file_extension), $image_extensions)) {
213
                    $post_attachment .= '<br><img src="' . $icon_filetype . '" alt="' . $filetype . '"><strong>&nbsp; ' . $att['name_display'] . '</strong> <small>(' . $file_size . ')</small>';
214
                    $post_attachment .= '<br>' . sf_attachmentImage($att['name_saved']);
215
                    $isDisplayed     = true;
0 ignored issues
show
Unused Code introduced by
The assignment to $isDisplayed is dead and can be removed.
Loading history...
216
                } else {
217
                    global $xoopsUser;
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...
218
                    if (empty($helper->getConfig('show_userattach'))) {
219
                        $post_attachment .= '<a href="'
220
                                            . XOOPS_URL
221
                                            . '/modules/'
222
                                            . $xoopsModule->getVar('dirname', 'n')
223
                                            . '/dl_attachment.php?attachid='
224
                                            . $key
225
                                            . '&amp;post_id='
226
                                            . $this->getVar('post_id')
227
                                            . '"> <img src="'
228
                                            . $icon_filetype
229
                                            . '" alt="'
230
                                            . $filetype
231
                                            . '"> '
232
                                            . $att['name_display']
233
                                            . '</a> '
234
                                            . _MD_FILESIZE
235
                                            . ': '
236
                                            . $file_size
237
                                            . '; '
238
                                            . _MD_HITS
239
                                            . ': '
240
                                            . $att['num_download'];
241
                    } elseif ($xoopsUser && $xoopsUser->uid() > 0 && $xoopsUser->isActive()) {
242
                        $post_attachment .= '<a href="'
243
                                            . XOOPS_URL
244
                                            . '/modules/'
245
                                            . $xoopsModule->getVar('dirname', 'n')
246
                                            . '/dl_attachment.php?attachid='
247
                                            . $key
248
                                            . '&amp;post_id='
249
                                            . $this->getVar('post_id')
250
                                            . '"> <img src="'
251
                                            . $icon_filetype
252
                                            . '" alt="'
253
                                            . $filetype
254
                                            . '"> '
255
                                            . $att['name_display']
256
                                            . '</a> '
257
                                            . _MD_FILESIZE
258
                                            . ': '
259
                                            . $file_size
260
                                            . '; '
261
                                            . _MD_HITS
262
                                            . ': '
263
                                            . $att['num_download'];
264
                    } else {
265
                        $post_attachment .= _MD_NEWBB_SEENOTGUEST;
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Smartfaq\_MD_NEWBB_SEENOTGUEST was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
266
                    }
267
                }
268
                $post_attachment .= '<br>';
269
            }
270
        }
271
272
        return $post_attachment;
273
    }
274
    // attachment functions
275
    // ////////////////////////////////////////////////////////////////////////////////////
276
277
    /**
278
     * @param  bool $force
279
     * @return bool
280
     */
281
    public function store($force = true)
282
    {
283
        $answerHandler = new AnswerHandler($this->db);
284
285
        if (Constants::SF_AN_STATUS_APPROVED == $this->status()) {
286
            $criteria = new \CriteriaCompo(new \Criteria('faqid', $this->faqid()));
0 ignored issues
show
Bug introduced by
The type CriteriaCompo was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
The type Criteria was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
287
            $answerHandler->updateAll('status', Constants::SF_AN_STATUS_REJECTED, $criteria);
288
        }
289
290
        return $answerHandler->insert($this, $force);
291
    }
292
293
    /**
294
     * @return mixed
295
     */
296
    public function answerid()
297
    {
298
        return $this->getVar('answerid');
299
    }
300
301
    /**
302
     * @return mixed
303
     */
304
    public function faqid()
305
    {
306
        return $this->getVar('faqid');
307
    }
308
309
    /**
310
     * @param  string $format
311
     * @return mixed
312
     */
313
    public function answer($format = 'S')
314
    {
315
        return $this->getVar('answer', $format);
316
    }
317
318
    /**
319
     * @return mixed
320
     */
321
    public function uid()
322
    {
323
        return $this->getVar('uid');
324
    }
325
326
    /**
327
     * @param  string $dateFormat
328
     * @param  string $format
329
     * @return string
330
     */
331
    public function datesub($dateFormat = 'none', $format = 'S')
332
    {
333
        if ('none' === $dateFormat) {
334
            $smartModuleConfig = Smartfaq\Utility::getModuleConfig();
335
            $dateFormat        = $smartModuleConfig['dateformat'];
336
        }
337
338
        return formatTimestamp($this->getVar('datesub', $format), $dateFormat);
0 ignored issues
show
Bug introduced by
The function formatTimestamp was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

338
        return /** @scrutinizer ignore-call */ formatTimestamp($this->getVar('datesub', $format), $dateFormat);
Loading history...
339
    }
340
341
    /**
342
     * @return mixed
343
     */
344
    public function status()
345
    {
346
        return $this->getVar('status');
347
    }
348
349
    /**
350
     * @return bool
351
     */
352
    public function notLoaded()
353
    {
354
        return (-1 == $this->getVar('answerid'));
355
    }
356
357
    /**
358
     * @param array $notifications
359
     */
360
    public function sendNotifications($notifications = [])
361
    {
362
        $smartModule = Smartfaq\Utility::getModuleInfo();
363
364
        $myts                = \MyTextSanitizer::getInstance();
0 ignored issues
show
Bug introduced by
The type MyTextSanitizer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
365
        $notificationHandler = xoops_getHandler('notification');
0 ignored issues
show
Bug introduced by
The function xoops_getHandler was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

365
        $notificationHandler = /** @scrutinizer ignore-call */ xoops_getHandler('notification');
Loading history...
366
367
        $faqObj = new Smartfaq\Faq($this->faqid());
368
369
        $tags                  = [];
370
        $tags['MODULE_NAME']   = $myts->displayTarea($smartModule->getVar('name'));
371
        $tags['FAQ_NAME']      = $faqObj->question();
372
        $tags['FAQ_URL']       = XOOPS_URL . '/modules/' . $smartModule->getVar('dirname') . '/faq.php?faqid=' . $faqObj->faqid();
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Smartfaq\XOOPS_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
373
        $tags['CATEGORY_NAME'] = $faqObj->getCategoryName();
374
        $tags['CATEGORY_URL']  = XOOPS_URL . '/modules/' . $smartModule->getVar('dirname') . '/category.php?categoryid=' . $faqObj->categoryid();
375
        $tags['FAQ_QUESTION']  = $faqObj->question();
376
377
        // TODO : Not sure about the 'formpreview' ...
378
        $tags['FAQ_ANSWER'] = $this->answer('formpreview');
379
        $tags['DATESUB']    = $this->datesub();
380
381
        foreach ($notifications as $notification) {
382
            switch ($notification) {
383
                case Constants::SF_NOT_ANSWER_APPROVED:
384
                    // This notification is not working for PM, but is for email... and I don't understand why???
385
                    $notificationHandler->triggerEvent('faq', $this->answerid(), 'answer_approved', $tags);
386
                    break;
387
                case -1:
388
                default:
389
                    break;
390
            }
391
        }
392
    }
393
}
394