Completed
Push — master ( bb1ebf...0d7d1b )
by Michael
02:07
created

SmartfaqUtility::sf_collapsableBar()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 51
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 2
dl 0
loc 51
rs 9.4109
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Class MyalbumUtil
5
 */
6
class SmartfaqUtility extends XoopsObject
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
7
{
8
    /**
9
     * Function responsible for checking if a directory exists, we can also write in and create an index.html file
10
     *
11
     * @param string $folder The full path of the directory to check
12
     *
13
     * @return void
14
     */
15
    public static function createFolder($folder)
16
    {
17
        //        try {
18
        //            if (!mkdir($folder) && !is_dir($folder)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% 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...
19
        //                throw new \RuntimeException(sprintf('Unable to create the %s directory', $folder));
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% 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...
20
        //            } else {
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
21
        //                file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% 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...
22
        //            }
23
        //        }
24
        //        catch (Exception $e) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
25
        //            echo 'Caught exception: ', $e->getMessage(), "\n", '<br>';
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
26
        //        }
27
        try {
28
            if (!file_exists($folder)) {
29
                if (!mkdir($folder) && !is_dir($folder)) {
30
                    throw new \RuntimeException(sprintf('Unable to create the %s directory', $folder));
31
                } else {
32
                    file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
33
                }
34
            }
35
        } catch (Exception $e) {
36
            echo 'Caught exception: ', $e->getMessage(), "\n", '<br>';
37
        }
38
    }
39
40
    /**
41
     * @param $file
42
     * @param $folder
43
     * @return bool
44
     */
45
    public static function copyFile($file, $folder)
46
    {
47
        return copy($file, $folder);
48
        //        try {
49
        //            if (!is_dir($folder)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
50
        //                throw new \RuntimeException(sprintf('Unable to copy file as: %s ', $folder));
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% 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...
51
        //            } else {
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
52
        //                return copy($file, $folder);
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% 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...
53
        //            }
54
        //        } catch (Exception $e) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
55
        //            echo 'Caught exception: ', $e->getMessage(), "\n", "<br>";
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
56
        //        }
57
        //        return false;
58
    }
59
60
    /**
61
     * @param $src
62
     * @param $dst
63
     */
64
    public static function recurseCopy($src, $dst)
65
    {
66
        $dir = opendir($src);
67
        //    @mkdir($dst);
68
        while (false !== ($file = readdir($dir))) {
69
            if (($file !== '.') && ($file !== '..')) {
70
                if (is_dir($src . '/' . $file)) {
71
                    self::recurseCopy($src . '/' . $file, $dst . '/' . $file);
72
                } else {
73
                    copy($src . '/' . $file, $dst . '/' . $file);
74
                }
75
            }
76
        }
77
        closedir($dir);
78
    }
79
80
    /**
81
     *
82
     * Verifies XOOPS version meets minimum requirements for this module
83
     * @static
84
     * @param XoopsModule $module
0 ignored issues
show
Documentation introduced by
Should the type for parameter $module not be null|XoopsModule?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
85
     *
86
     * @param null|string $requiredVer
87
     * @return bool true if meets requirements, false if not
88
     */
89
    public static function checkVerXoops(XoopsModule $module = null, $requiredVer = null)
90
    {
91
        $moduleDirName = basename(dirname(__DIR__));
92
        if (null === $module) {
93
            $module = XoopsModule::getByDirname($moduleDirName);
94
        }
95
        xoops_loadLanguage('admin', $moduleDirName);
96
        //check for minimum XOOPS version
97
        $currentVer = substr(XOOPS_VERSION, 6); // get the numeric part of string
98
        $currArray  = explode('.', $currentVer);
99
        if (null === $requiredVer) {
100
            $requiredVer = '' . $module->getInfo('min_xoops'); //making sure it's a string
101
        }
102
        $reqArray = explode('.', $requiredVer);
103
        $success  = true;
104
        foreach ($reqArray as $k => $v) {
105
            if (isset($currArray[$k])) {
106
                if ($currArray[$k] > $v) {
107
                    break;
108
                } elseif ($currArray[$k] == $v) {
109
                    continue;
110
                } else {
111
                    $success = false;
112
                    break;
113
                }
114
            } else {
115
                if ((int)$v > 0) { // handles versions like x.x.x.0_RC2
116
                    $success = false;
117
                    break;
118
                }
119
            }
120
        }
121
122
        if (!$success) {
123
            $module->setErrors(sprintf(_AM_SF_ERROR_BAD_XOOPS, $requiredVer, $currentVer));
124
        }
125
126
        return $success;
127
    }
128
129
    /**
130
     *
131
     * Verifies PHP version meets minimum requirements for this module
132
     * @static
133
     * @param XoopsModule $module
134
     *
135
     * @return bool true if meets requirements, false if not
136
     */
137
    public static function checkVerPhp(XoopsModule $module)
138
    {
139
        xoops_loadLanguage('admin', $module->dirname());
140
        // check for minimum PHP version
141
        $success = true;
142
        $verNum  = PHP_VERSION;
143
        $reqVer  = $module->getInfo('min_php');
144
        if (false !== $reqVer && '' !== $reqVer) {
145
            if (version_compare($verNum, $reqVer, '<')) {
146
                $module->setErrors(sprintf(_AM_SF_ERROR_BAD_PHP, $reqVer, $verNum));
147
                $success = false;
148
            }
149
        }
150
151
        return $success;
152
    }
153
154
    /**
155
     * @return mixed|null
156
     */
157
    public static function sf_getModuleInfo()
158
    {
159
        static $smartModule;
160
        if (!isset($smartModule)) {
161
            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...
162
            if (isset($xoopsModule) && is_object($xoopsModule) && $xoopsModule->getVar('dirname') === 'smartfaq') {
163
                $smartModule = $xoopsModule;
164
            } else {
165
                $hModule     = xoops_getHandler('module');
166
                $smartModule = $hModule->getByDirname('smartfaq');
167
            }
168
        }
169
170
        return $smartModule;
171
    }
172
173
    /**
174
     * @return mixed
175
     */
176 View Code Duplication
    public static function sf_getModuleConfig()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
177
    {
178
        static $smartConfig;
179
        if (!$smartConfig) {
180
            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...
181
            if (isset($xoopsModule) && is_object($xoopsModule) && $xoopsModule->getVar('dirname') === 'smartfaq') {
182
                global $xoopsModuleConfig;
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...
183
                $smartConfig = $xoopsModuleConfig;
184
            } else {
185
                $smartModule = sf_getModuleInfo();
186
                $hModConfig  = xoops_getHandler('config');
187
                $smartConfig = $hModConfig->getConfigsByCat(0, $smartModule->getVar('mid'));
188
            }
189
        }
190
191
        return $smartConfig;
192
    }
193
194
    /**
195
     * @return string
196
     */
197 View Code Duplication
    public static function sf_getHelpPath()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
198
    {
199
        $smartConfig = sf_getModuleConfig();
200
        switch ($smartConfig['helppath_select']) {
201
            case 'docs.xoops.org':
202
                return 'http://docs.xoops.org/help/sfaqh/index.htm';
203
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
204
205
            case 'inside':
206
                return XOOPS_URL . '/modules/smartfaq/doc/';
207
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
208
209
            case 'custom':
210
                return $smartConfig['helppath_custom'];
211
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
212
        }
213
    }
214
215
    /**
216
     * @param  array $errors
217
     * @return string
218
     */
219
    public static function sf_formatErrors($errors = array())
220
    {
221
        $ret = '';
222
        foreach ($errors as $key => $value) {
223
            $ret .= '<br> - ' . $value;
224
        }
225
226
        return $ret;
227
    }
228
229
    /**
230
     * @param         $categoryObj
231
     * @param  int    $selectedid
232
     * @param  int    $level
233
     * @param  string $ret
234
     * @return string
235
     */
236 View Code Duplication
    public static function sf_addCategoryOption($categoryObj, $selectedid = 0, $level = 0, $ret = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
237
    {
238
        // Creating the category handler object
239
        $categoryHandler = sf_gethandler('category');
240
241
        $spaces = '';
242
        for ($j = 0; $j < $level; ++$j) {
243
            $spaces .= '--';
244
        }
245
246
        $ret .= "<option value='" . $categoryObj->categoryid() . "'";
247
        if ($selectedid == $categoryObj->categoryid()) {
248
            $ret .= ' selected';
249
        }
250
        $ret .= '>' . $spaces . $categoryObj->name() . "</option>\n";
251
252
        $subCategoriesObj = $categoryHandler->getCategories(0, 0, $categoryObj->categoryid());
253
        if (count($subCategoriesObj) > 0) {
254
            ++$level;
255
            foreach ($subCategoriesObj as $catID => $subCategoryObj) {
256
                $ret .= sf_addCategoryOption($subCategoryObj, $selectedid, $level);
257
            }
258
        }
259
260
        return $ret;
261
    }
262
263
    /**
264
     * @param  int  $selectedid
265
     * @param  int  $parentcategory
266
     * @param  bool $allCatOption
267
     * @return string
268
     */
269 View Code Duplication
    public static function sf_createCategorySelect($selectedid = 0, $parentcategory = 0, $allCatOption = true)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
270
    {
271
        $ret = '' . _MB_SF_SELECTCAT . "&nbsp;<select name='options[]'>";
272
        if ($allCatOption) {
273
            $ret .= "<option value='0'";
274
            $ret .= '>' . _MB_SF_ALLCAT . "</option>\n";
275
        }
276
277
        // Creating the category handler object
278
        $categoryHandler = sf_gethandler('category');
279
280
        // Creating category objects
281
        $categoriesObj = $categoryHandler->getCategories(0, 0, $parentcategory);
282
283
        if (count($categoriesObj) > 0) {
284
            foreach ($categoriesObj as $catID => $categoryObj) {
285
                $ret .= sf_addCategoryOption($categoryObj, $selectedid);
286
            }
287
        }
288
        $ret .= "</select>\n";
289
290
        return $ret;
291
    }
292
293
    /**
294
     * @return array
295
     */
296 View Code Duplication
    public static function sf_getStatusArray()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
297
    {
298
        $result = array(
299
            '1' => _AM_SF_STATUS1,
300
            '2' => _AM_SF_STATUS2,
301
            '3' => _AM_SF_STATUS3,
302
            '4' => _AM_SF_STATUS4,
303
            '5' => _AM_SF_STATUS5,
304
            '6' => _AM_SF_STATUS6,
305
            '7' => _AM_SF_STATUS7,
306
            '8' => _AM_SF_STATUS8
307
        );
308
309
        return $result;
310
    }
311
312
    /**
313
     * @return bool
314
     */
315 View Code Duplication
    public static function sf_moderator()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
316
    {
317
        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...
318
319
        if (!$xoopsUser) {
320
            $result = false;
321
        } else {
322
            $smartPermHandler = xoops_getModuleHandler('permission', 'smartfaq');
323
324
            $categories = $smartPermHandler->getPermissions('moderation');
325
            if (count($categories) == 0) {
326
                $result = false;
327
            } else {
328
                $result = true;
329
            }
330
        }
331
332
        return $result;
333
    }
334
335
    /**
336
     * @return string
337
     */
338 View Code Duplication
    public static function sf_modFooter()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
339
    {
340
        $smartModule = sf_getModuleInfo();
341
342
        $modfootertxt = 'Module ' . $smartModule->getInfo('name') . ' - Version ' . $smartModule->getInfo('version') . '';
343
344
        $modfooter = "<a href='" . $smartModule->getInfo('support_site_url') . "' target='_blank'><img src='" . XOOPS_URL . "/modules/smartfaq/assets/images/sfcssbutton.gif' title='" . $modfootertxt . "' alt='" . $modfootertxt . "'></a>";
345
346
        return $modfooter;
347
    }
348
349
    /**
350
     * Checks if a user is admin of Smartfaq
351
     *
352
     * sf_userIsAdmin()
353
     *
354
     * @return boolean : array with userids and uname
355
     */
356 View Code Duplication
    public static function sf_userIsAdmin()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
357
    {
358
        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...
359
360
        $result = false;
361
362
        $smartModule = sf_getModuleInfo();
363
        $module_id   = $smartModule->getVar('mid');
364
365
        if (!empty($xoopsUser)) {
366
            $groups = $xoopsUser->getGroups();
367
            $result = in_array(XOOPS_GROUP_ADMIN, $groups) || $xoopsUser->isAdmin($module_id);
368
        }
369
370
        return $result;
371
    }
372
373
    /**
374
     * Checks if a user has access to a selected faq. If no item permissions are
375
     * set, access permission is denied. The user needs to have necessary category
376
     * permission as well.
377
     *
378
     * faqAccessGranted()
379
     *
380
     * @param $faqObj
381
     * @return int : -1 if no access, 0 if partialview and 1 if full access
382
     * @internal param int $faqid : faqid on which we are setting permissions
383
     * @internal param $integer $ categoryid : categoryid of the faq
384
     */
385
386
    // TODO : Move this function to sfFaq class
387 View Code Duplication
    public static function faqAccessGranted($faqObj)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
388
    {
389
        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...
390
391
        if (sf_userIsAdmin()) {
392
            $result = 1;
393
        } else {
394
            $result = -1;
395
396
            $groups = $xoopsUser ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
397
398
            $gpermHandler = xoops_getHandler('groupperm');
399
            $smartModule  = sf_getModuleInfo();
400
            $module_id    = $smartModule->getVar('mid');
401
402
            // Do we have access to the parent category
403
            if ($gpermHandler->checkRight('category_read', $faqObj->categoryid(), $groups, $module_id)) {
404
                // Do we have access to the faq?
405
                if ($gpermHandler->checkRight('item_read', $faqObj->faqid(), $groups, $module_id)) {
406
                    $result = 1;
407
                } else { // No we don't !
408
                    // Check to see if we have partial view access
409
                    if (!is_object($xoopsUser) && $faqObj->partialView()) {
410
                        return 0;
411
                    }
412
                }
413
            } else { // No we don't !
414
                $result = false;
415
            }
416
        }
417
418
        return $result;
419
    }
420
421
    /**
422
     * Override FAQs permissions of a category by the category read permissions
423
     *
424
     *   sf_overrideFaqsPermissions()
425
     *
426
     * @param  array   $groups     : group with granted permission
427
     * @param  integer $categoryid :
428
     * @return boolean|array : TRUE if the no errors occured
429
     */
430 View Code Duplication
    public static function sf_overrideFaqsPermissions($groups, $categoryid)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
431
    {
432
        global $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...
433
434
        $result      = true;
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
435
        $smartModule = sf_getModuleInfo();
436
        $module_id   = $smartModule->getVar('mid');
437
438
        $gpermHandler = xoops_getHandler('groupperm');
439
440
        $sql    = 'SELECT faqid FROM ' . $xoopsDB->prefix('smartfaq_faq') . " WHERE categoryid = '$categoryid' ";
441
        $result = $xoopsDB->queryF($sql);
442
443
        if (count($result) > 0) {
444
            while (list($faqid) = $xoopsDB->fetchrow($result)) {
445
                // First, if the permissions are already there, delete them
446
                $gpermHandler->deleteByModule($module_id, 'item_read', $faqid);
447
                // Save the new permissions
448
                if (count($groups) > 0) {
449
                    foreach ($groups as $group_id) {
450
                        $gpermHandler->addRight('item_read', $faqid, $group_id, $module_id);
451
                    }
452
                }
453
            }
454
        }
455
456
        return $result;
457
    }
458
459
    /**
460
     * Saves permissions for the selected faq
461
     *
462
     *   sf_saveItemPermissions()
463
     *
464
     * @param  array   $groups : group with granted permission
465
     * @param  integer $itemID : faqid on which we are setting permissions
466
     * @return boolean : TRUE if the no errors occured
467
     */
468 View Code Duplication
    public static function sf_saveItemPermissions($groups, $itemID)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
469
    {
470
        $result      = true;
471
        $smartModule = sf_getModuleInfo();
472
        $module_id   = $smartModule->getVar('mid');
473
474
        $gpermHandler = xoops_getHandler('groupperm');
475
        // First, if the permissions are already there, delete them
476
        $gpermHandler->deleteByModule($module_id, 'item_read', $itemID);
477
        // Save the new permissions
478
        if (count($groups) > 0) {
479
            foreach ($groups as $group_id) {
480
                $gpermHandler->addRight('item_read', $itemID, $group_id, $module_id);
481
            }
482
        }
483
484
        return $result;
485
    }
486
487
    /**
488
     * Saves permissions for the selected category
489
     *
490
     *   sf_saveCategory_Permissions()
491
     *
492
     * @param  array   $groups     : group with granted permission
493
     * @param  integer $categoryid : categoryid on which we are setting permissions
494
     * @param  string  $perm_name  : name of the permission
495
     * @return boolean : TRUE if the no errors occured
496
     */
497
498 View Code Duplication
    public static function sf_saveCategory_Permissions($groups, $categoryid, $perm_name)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
499
    {
500
        $result      = true;
501
        $smartModule = sf_getModuleInfo();
502
        $module_id   = $smartModule->getVar('mid');
503
504
        $gpermHandler = xoops_getHandler('groupperm');
505
        // First, if the permissions are already there, delete them
506
        $gpermHandler->deleteByModule($module_id, $perm_name, $categoryid);
507
        // Save the new permissions
508
        if (count($groups) > 0) {
509
            foreach ($groups as $group_id) {
510
                $gpermHandler->addRight($perm_name, $categoryid, $group_id, $module_id);
511
            }
512
        }
513
514
        return $result;
515
    }
516
517
    /**
518
     * Saves permissions for the selected category
519
     *
520
     *   sf_saveModerators()
521
     *
522
     * @param  array   $moderators : moderators uids
523
     * @param  integer $categoryid : categoryid on which we are setting permissions
524
     * @return boolean : TRUE if the no errors occured
525
     */
526
527 View Code Duplication
    public static function sf_saveModerators($moderators, $categoryid)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
528
    {
529
        $result      = true;
530
        $smartModule = sf_getModuleInfo();
531
        $module_id   = $smartModule->getVar('mid');
532
533
        $gpermHandler = xoops_getHandler('groupperm');
534
        // First, if the permissions are already there, delete them
535
        $gpermHandler->deleteByModule($module_id, 'category_moderation', $categoryid);
536
        // Save the new permissions
537
        if (count($moderators) > 0) {
538
            foreach ($moderators as $uid) {
539
                $gpermHandler->addRight('category_moderation', $categoryid, $uid, $module_id);
540
            }
541
        }
542
543
        return $result;
544
    }
545
546
    /**
547
     * @param  int $faqid
548
     * @return array
549
     */
550 View Code Duplication
    public static function sf_retrieveFaqByID($faqid = 0)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
551
    {
552
        $ret = array();
0 ignored issues
show
Unused Code introduced by
$ret is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
553
        global $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...
554
555
        $result = $xoopsDB->queryF('SELECT * FROM ' . $xoopsDB->prefix('smartfaq_faq') . " WHERE faqid = '$faqid'");
556
        $ret    = $xoopsDB->fetcharray($result);
557
558
        return $ret;
559
    }
560
561
    /**
562
     * sf_getAdminLinks()
563
     *
564
     * @param  integer $faqid
565
     * @param  bool    $open
566
     * @return string
567
     */
568
569
    // TODO : Move this to the sfFaq class
570 View Code Duplication
    public static function sf_getAdminLinks($faqid = 0, $open = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
571
    {
572
        global $xoopsUser, $xoopsModule, $xoopsModuleConfig, $xoopsConfig;
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...
573
        $adminLinks = '';
574
        $modulePath = XOOPS_URL . '/modules/' . $xoopsModule->dirname() . '/';
575
        $page       = $open ? 'question.php' : 'faq.php';
576
        if ($xoopsUser && $xoopsUser->isAdmin($xoopsModule->getVar('mid'))) {
577
            // Edit button
578
            $adminLinks .= "<a href='" . $modulePath . "admin/$page?op=mod&amp;faqid=" . $faqid . "'><img src='" . $modulePath . "assets/images/links/edit.gif'" . " title='" . _MD_SF_EDIT . "' alt='" . _MD_SF_EDIT . "'></a>";
579
            $adminLinks .= ' ';
580
            // Delete button
581
            $adminLinks .= "<a href='" . $modulePath . "admin/$page?op=del&amp;faqid=" . $faqid . "'><img src='" . $modulePath . "assets/images/links/delete.gif'" . " title='" . _MD_SF_DELETE . "' alt='" . _MD_SF_DELETE . "'></a>";
582
            $adminLinks .= ' ';
583
        }
584
        // Print button
585
        $adminLinks .= "<a href='" . $modulePath . 'print.php?faqid=' . $faqid . "'><img src='" . $modulePath . "assets/images/links/print.gif' title='" . _MD_SF_PRINT . "' alt='" . _MD_SF_PRINT . "'></a>";
586
        $adminLinks .= ' ';
587
        // Email button
588
        $maillink   = 'mailto:?subject=' . sprintf(_MD_SF_INTARTICLE, $xoopsConfig['sitename']) . '&amp;body=' . sprintf(_MD_SF_INTARTFOUND, $xoopsConfig['sitename']) . ':  ' . $modulePath . 'faq.php?faqid=' . $faqid;
589
        $adminLinks .= '<a href="' . $maillink . "\"><img src='" . $modulePath . "assets/images/links/friend.gif' title='" . _MD_SF_MAIL . "' alt='" . _MD_SF_MAIL . "'></a>";
590
        $adminLinks .= ' ';
591
        // Submit New Answer button
592
        if ($xoopsModuleConfig['allownewanswer'] && (is_object($xoopsUser) || $xoopsModuleConfig['anonpost'])) {
593
            $adminLinks .= "<a href='" . $modulePath . 'answer.php?faqid=' . $faqid . "'><img src='" . $modulePath . "assets/images/links/newanswer.gif' title='" . _MD_SF_SUBMITANSWER . "' alt='" . _MD_SF_SUBMITANSWER . "'></a>";
594
            $adminLinks .= ' ';
595
        }
596
597
        return $adminLinks;
598
    }
599
600
    /**
601
     * sf_getLinkedUnameFromId()
602
     *
603
     * @param  integer $userid Userid of poster etc
604
     * @param  integer $name   :  0 Use Usenamer 1 Use realname
605
     * @param  array   $users
606
     * @return string
607
     */
608 View Code Duplication
    public static function sf_getLinkedUnameFromId($userid = 0, $name = 0, $users = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
Coding Style introduced by
sf_getLinkedUnameFromId uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
609
    {
610
        if (!is_numeric($userid)) {
611
            return $userid;
612
        }
613
614
        $userid = (int)$userid;
615
        if ($userid > 0) {
616
            if ($users == array()) {
617
                //fetching users
618
                $memberHandler = xoops_getHandler('member');
619
                $user          = $memberHandler->getUser($userid);
620
            } else {
621
                if (!isset($users[$userid])) {
622
                    return $GLOBALS['xoopsConfig']['anonymous'];
623
                }
624
                $user =& $users[$userid];
625
            }
626
627
            if (is_object($user)) {
628
                $ts       = MyTextSanitizer::getInstance();
629
                $username = $user->getVar('uname');
630
                $fullname = '';
631
632
                $fullname2 = $user->getVar('name');
633
634
                if ($name && !empty($fullname2)) {
635
                    $fullname = $user->getVar('name');
636
                }
637
                if (!empty($fullname)) {
638
                    $linkeduser = "$fullname [<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $userid . "'>" . $ts->htmlSpecialChars($username) . '</a>]';
639
                } else {
640
                    $linkeduser = "<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $userid . "'>" . ucwords($ts->htmlSpecialChars($username)) . '</a>';
641
                }
642
643
                return $linkeduser;
644
            }
645
        }
646
647
        return $GLOBALS['xoopsConfig']['anonymous'];
648
    }
649
650
    /**
651
     * @param  string $url
652
     * @return mixed|string
653
     */
654 View Code Duplication
    public static function sf_getxoopslink($url = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
655
    {
656
        $xurl = $url;
657
        if (strlen($xurl) > 0) {
658
            if ($xurl[0] = '/') {
659
                $xurl = str_replace('/', '', $xurl);
660
            }
661
            $xurl = str_replace('{SITE_URL}', XOOPS_URL, $xurl);
662
        }
663
664
        //        $xurl = $url;
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% 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...
665
666
        return $xurl;
667
    }
668
669
    /**
670
     * @param string $tablename
671
     * @param string $iconname
672
     */
673
    public static function sf_collapsableBar($tablename = '', $iconname = '')
674
    {
675
        ?>
676
        <script type="text/javascript"><!--
677
            function goto_URL(object) {
678
                window.location.href = object.options[object.selectedIndex].value;
679
            }
680
681
            function toggle(id) {
682
                if (document.getElementById) {
683
                    obj = document.getElementById(id);
684
                }
685
                if (document.all) {
686
                    obj = document.all[id];
687
                }
688
                if (document.layers) {
689
                    obj = document.layers[id];
690
                }
691
                if (obj) {
692
                    if (obj.style.display === "none") {
693
                        obj.style.display = "";
694
                    } else {
695
                        obj.style.display = "none";
696
                    }
697
                }
698
699
                return false;
700
            }
701
702
            var iconClose = new Image();
703
            iconClose.src = '../assets/images/icon/close12.gif';
704
            var iconOpen = new Image();
705
            iconOpen.src = '../assets/images/icon/open12.gif';
706
707
            function toggleIcon(iconName) {
708
                if (document.images[iconName].src == window.iconOpen.src) {
709
                    document.images[iconName].src = window.iconClose.src;
710
                }
711
                elseif(document.images[iconName].src == window.iconClose.src)
712
                {
713
                    document.images[iconName].src = window.iconOpen.src;
714
                }
715
716
                return;
717
            }
718
719
            //-->
720
        </script>
721
        <?php
722
        echo "<h3 style=\"color: #2F5376; margin: 6px 0 0 0; \"><a href='#' onClick=\"toggle('" . $tablename . "'); toggleIcon('" . $iconname . "');\">";
723
    }
724
725
    /**
726
     * @param       $name
727
     * @param  bool $optional
728
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be object|false?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
729
     */
730 View Code Duplication
    public static function sf_gethandler($name, $optional = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
Coding Style introduced by
sf_gethandler uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
731
    {
732
        static $handlers;
733
        $name = strtolower(trim($name));
734
        if (!isset($handlers[$name])) {
735
            if (file_exists($hnd_file = XOOPS_ROOT_PATH . '/modules/smartfaq/class/' . $name . '.php')) {
736
                require_once $hnd_file;
737
            }
738
            $class = 'sf' . ucfirst($name) . 'Handler';
739
            if (class_exists($class)) {
740
                $handlers[$name] = new $class($GLOBALS['xoopsDB']);
741
            }
742
        }
743
        if (!$optional && !isset($handlers[$name])) {
744
            trigger_error('Class <b>' . $class . '</b> does not exist<br>Handler Name: ' . $name, E_USER_ERROR);
0 ignored issues
show
Bug introduced by
The variable $class does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
745
        }
746
        $false = false;
747
748
        return isset($handlers[$name]) ? $handlers[$name] : $false;
749
    }
750
}
751