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

Utility::overrideFaqsPermissions()   B

Complexity

Conditions 5
Paths 2

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 15
nc 2
nop 2
dl 0
loc 28
rs 8.439
c 0
b 0
f 0
1
<?php namespace XoopsModules\Smartfaq;
2
3
use Xmf\Request;
4
use XoopsModules\Smartfaq;
5
use XoopsModules\Smartfaq\Common;
6
7
/**
8
 * Class Utility
9
 */
10
class Utility
11
{
12
    use Common\VersionChecks; //checkVerXoops, checkVerPhp Traits
13
14
    use Common\ServerStats; // getServerStats Trait
15
16
    use Common\FilesManagement; // Files Management Trait
17
18
    //--------------- Custom module methods -----------------------------
19
20
21
22
    /**
23
     * @return mixed|null
24
     */
25
    public static function getModuleInfo()
26
    {
27
        static $smartModule;
28 View Code Duplication
        if (null === $smartModule) {
0 ignored issues
show
Duplication introduced by
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...
29
            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...
30
            if (null !== $xoopsModule && is_object($xoopsModule) && 'smartfaq' === $xoopsModule->getVar('dirname')) {
31
                $smartModule = $xoopsModule;
32
            } else {
33
                $hModule     = xoops_getHandler('module');
34
                $smartModule = $hModule->getByDirname('smartfaq');
35
            }
36
        }
37
38
        return $smartModule;
39
    }
40
41
    /**
42
     * @return mixed
43
     */
44
    public static function getModuleConfig()
45
    {
46
        static $smartConfig;
47
        if (!$smartConfig) {
48
            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...
49 View Code Duplication
            if (null !== $xoopsModule && is_object($xoopsModule) && 'smartfaq' === $xoopsModule->getVar('dirname')) {
0 ignored issues
show
Duplication introduced by
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...
50
                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...
51
                $smartConfig = $xoopsModuleConfig;
52
            } else {
53
                $smartModule = self::getModuleInfo();
54
                $hModConfig  = xoops_getHandler('config');
55
                $smartConfig = $hModConfig->getConfigsByCat(0, $smartModule->getVar('mid'));
56
            }
57
        }
58
59
        return $smartConfig;
60
    }
61
62
    /**
63
     * @return string
64
     */
65
    public static function getHelpPath()
66
    {
67
        $smartConfig = self::getModuleConfig();
68
        switch ($smartConfig['helppath_select']) {
69
            case 'docs.xoops.org':
70
                return 'http://docs.xoops.org/help/sfaqh/index.htm';
71
                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...
72
73
            case 'inside':
74
                return XOOPS_URL . '/modules/smartfaq/doc/';
75
                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...
76
77
            case 'custom':
78
                return $smartConfig['helppath_custom'];
79
                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...
80
        }
81
    }
82
83
    /**
84
     * @param  array $errors
85
     * @return string
86
     */
87
    public static function formatErrors($errors = [])
88
    {
89
        $ret = '';
90
        foreach ($errors as $key => $value) {
91
            $ret .= '<br> - ' . $value;
92
        }
93
94
        return $ret;
95
    }
96
97
    /**
98
     * @param         $categoryObj
99
     * @param  int    $selectedid
100
     * @param  int    $level
101
     * @param  string $ret
102
     * @return string
103
     */
104
    public static function addCategoryOption($categoryObj, $selectedid = 0, $level = 0, $ret = '')
105
    {
106
        // Creating the category handler object
107
        /** @var Smartfaq\CategoryHandler $categoryHandler */
108
        $categoryHandler = Smartfaq\Helper::getInstance()->getHandler('Category');
109
110
        $spaces = '';
111
        for ($j = 0; $j < $level; ++$j) {
112
            $spaces .= '--';
113
        }
114
115
        $ret .= "<option value='" . $categoryObj->categoryid() . "'";
116
        if ($selectedid == $categoryObj->categoryid()) {
117
            $ret .= ' selected';
118
        }
119
        $ret .= '>' . $spaces . $categoryObj->name() . "</option>\n";
120
121
        $subCategoriesObj =& $categoryHandler->getCategories(0, 0, $categoryObj->categoryid());
122
        if (count($subCategoriesObj) > 0) {
123
            ++$level;
124
            foreach ($subCategoriesObj as $catID => $subCategoryObj) {
125
                $ret .= self::addCategoryOption($subCategoryObj, $selectedid, $level);
126
            }
127
        }
128
129
        return $ret;
130
    }
131
132
    /**
133
     * @param  int  $selectedid
134
     * @param  int  $parentcategory
135
     * @param  bool $allCatOption
136
     * @return string
137
     */
138
    public static function createCategorySelect($selectedid = 0, $parentcategory = 0, $allCatOption = true)
139
    {
140
        $ret = '' . _MB_SF_SELECTCAT . "&nbsp;<select name='options[]'>";
141
        if ($allCatOption) {
142
            $ret .= "<option value='0'";
143
            $ret .= '>' . _MB_SF_ALLCAT . "</option>\n";
144
        }
145
146
        // Creating the category handler object
147
        $categoryHandler = Smartfaq\Helper::getInstance()->getHandler('Category');
148
149
        // Creating category objects
150
        $categoriesObj = $categoryHandler->getCategories(0, 0, $parentcategory);
151
152
        if (count($categoriesObj) > 0) {
153
            foreach ($categoriesObj as $catID => $categoryObj) {
154
                $ret .= self::addCategoryOption($categoryObj, $selectedid);
155
            }
156
        }
157
        $ret .= "</select>\n";
158
159
        return $ret;
160
    }
161
162
    /**
163
     * @return array
164
     */
165
    public static function getStatusArray()
166
    {
167
        $result = [
168
            '1' => _AM_SF_STATUS1,
169
            '2' => _AM_SF_STATUS2,
170
            '3' => _AM_SF_STATUS3,
171
            '4' => _AM_SF_STATUS4,
172
            '5' => _AM_SF_STATUS5,
173
            '6' => _AM_SF_STATUS6,
174
            '7' => _AM_SF_STATUS7,
175
            '8' => _AM_SF_STATUS8
176
        ];
177
178
        return $result;
179
    }
180
181
    /**
182
     * @return bool
183
     */
184
    public static function getModerator()
185
    {
186
        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...
187
188
        if (!$xoopsUser) {
189
            $result = false;
190
        } else {
191
            /** @var \XoopsModules\Smartfaq\PermissionHandler $smartPermHandler */
192
            $smartPermHandler = \XoopsModules\Smartfaq\Helper::getInstance()->getHandler('Permission');
193
194
            $categories = $smartPermHandler->getPermissions('moderation');
195
            if (0 == count($categories)) {
196
                $result = false;
197
            } else {
198
                $result = true;
199
            }
200
        }
201
202
        return $result;
203
    }
204
205
    /**
206
     * @return string
207
     */
208
    public static function modFooter()
209
    {
210
        $smartModule = self::getModuleInfo();
211
212
        $modfootertxt = 'Module ' . $smartModule->getInfo('name') . ' - Version ' . $smartModule->getInfo('version') . '';
213
214
        $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>";
215
216
        return $modfooter;
217
    }
218
219
    /**
220
     * Checks if a user is admin of Smartfaq
221
     *
222
     * self::userIsAdmin()
223
     *
224
     * @return boolean : array with userids and uname
225
     */
226
    public static function userIsAdmin()
227
    {
228
        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...
229
230
        $result = false;
231
232
        $smartModule = self::getModuleInfo();
233
        $module_id   = $smartModule->getVar('mid');
234
235
        if (!empty($xoopsUser)) {
236
            $groups =& $xoopsUser->getGroups();
237
            $result = in_array(XOOPS_GROUP_ADMIN, $groups) || $xoopsUser->isAdmin($module_id);
238
        }
239
240
        return $result;
241
    }
242
243
    /**
244
     * Checks if a user has access to a selected faq. If no item permissions are
245
     * set, access permission is denied. The user needs to have necessary category
246
     * permission as well.
247
     *
248
     * self::faqAccessGranted()
249
     *
250
     * @param $faqObj
251
     * @return int : -1 if no access, 0 if partialview and 1 if full access
252
     * @internal param int $faqid : faqid on which we are setting permissions
253
     * @internal param $integer $ categoryid : categoryid of the faq
254
     */
255
256
    // TODO : Move this function to Smartfaq\Faq class
257
    public static function faqAccessGranted($faqObj)
258
    {
259
        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...
260
261
        if (self::userIsAdmin()) {
262
            $result = 1;
263
        } else {
264
            $result = -1;
265
266
            $groups = $xoopsUser ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
267
268
            $gpermHandler = xoops_getHandler('groupperm');
269
            $smartModule  = self::getModuleInfo();
270
            $module_id    = $smartModule->getVar('mid');
271
272
            // Do we have access to the parent category
273
            if ($gpermHandler->checkRight('category_read', $faqObj->categoryid(), $groups, $module_id)) {
274
                // Do we have access to the faq?
275
                if ($gpermHandler->checkRight('item_read', $faqObj->faqid(), $groups, $module_id)) {
276
                    $result = 1;
277
                } else { // No we don't !
278
                    // Check to see if we have partial view access
279
                    if (!is_object($xoopsUser) && $faqObj->partialView()) {
280
                        return 0;
281
                    }
282
                }
283
            } else { // No we don't !
284
                $result = false;
285
            }
286
        }
287
288
        return $result;
289
    }
290
291
    /**
292
     * Override FAQs permissions of a category by the category read permissions
293
     *
294
     *   self::overrideFaqsPermissions()
295
     *
296
     * @param  array   $groups     : group with granted permission
297
     * @param  integer $categoryid :
298
     * @return boolean|array : TRUE if the no errors occured
299
     */
300
    public static function overrideFaqsPermissions($groups, $categoryid)
0 ignored issues
show
Coding Style introduced by
overrideFaqsPermissions 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...
301
    {
302
        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...
303
304
        $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...
305
        $smartModule = self::getModuleInfo();
306
        $module_id   = $smartModule->getVar('mid');
307
308
        $gpermHandler = xoops_getHandler('groupperm');
309
310
        $sql    = 'SELECT faqid FROM ' . $xoopsDB->prefix('smartfaq_faq') . " WHERE categoryid = '$categoryid' ";
311
        $result = $xoopsDB->queryF($sql);
312
313
        if ($GLOBALS['xoopsDB']->getRowsNum($result) > 0) {
314
            while (list($faqid) = $xoopsDB->fetchRow($result)) {
315
                // First, if the permissions are already there, delete them
316
                $gpermHandler->deleteByModule($module_id, 'item_read', $faqid);
317
                // Save the new permissions
318
                if (count($groups) > 0) {
319
                    foreach ($groups as $group_id) {
320
                        $gpermHandler->addRight('item_read', $faqid, $group_id, $module_id);
321
                    }
322
                }
323
            }
324
        }
325
326
        return $result;
327
    }
328
329
    /**
330
     * Saves permissions for the selected faq
331
     *
332
     *   self::saveItemPermissions()
333
     *
334
     * @param  array   $groups : group with granted permission
335
     * @param  integer $itemID : faqid on which we are setting permissions
336
     * @return boolean : TRUE if the no errors occured
337
     */
338 View Code Duplication
    public static function 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...
339
    {
340
        $result      = true;
341
        $smartModule = self::getModuleInfo();
342
        $module_id   = $smartModule->getVar('mid');
343
344
        $gpermHandler = xoops_getHandler('groupperm');
345
        // First, if the permissions are already there, delete them
346
        $gpermHandler->deleteByModule($module_id, 'item_read', $itemID);
347
        // Save the new permissions
348
        if (count($groups) > 0) {
349
            foreach ($groups as $group_id) {
350
                $gpermHandler->addRight('item_read', $itemID, $group_id, $module_id);
351
            }
352
        }
353
354
        return $result;
355
    }
356
357
    /**
358
     * Saves permissions for the selected category
359
     *
360
     *   self::saveCategoryPermissions()
361
     *
362
     * @param  array   $groups     : group with granted permission
363
     * @param  integer $categoryid : categoryid on which we are setting permissions
364
     * @param  string  $perm_name  : name of the permission
365
     * @return boolean : TRUE if the no errors occured
366
     */
367
368 View Code Duplication
    public static function saveCategoryPermissions($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...
369
    {
370
        $result      = true;
371
        $smartModule = self::getModuleInfo();
372
        $module_id   = $smartModule->getVar('mid');
373
374
        $gpermHandler = xoops_getHandler('groupperm');
375
        // First, if the permissions are already there, delete them
376
        $gpermHandler->deleteByModule($module_id, $perm_name, $categoryid);
377
        // Save the new permissions
378
        if (count($groups) > 0) {
379
            foreach ($groups as $group_id) {
380
                $gpermHandler->addRight($perm_name, $categoryid, $group_id, $module_id);
381
            }
382
        }
383
384
        return $result;
385
    }
386
387
    /**
388
     * Saves permissions for the selected category
389
     *
390
     *   self::saveModerators()
391
     *
392
     * @param  array   $moderators : moderators uids
393
     * @param  integer $categoryid : categoryid on which we are setting permissions
394
     * @return boolean : TRUE if the no errors occured
395
     */
396
397 View Code Duplication
    public static function 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...
398
    {
399
        $result      = true;
400
        $smartModule = self::getModuleInfo();
401
        $module_id   = $smartModule->getVar('mid');
402
403
        $gpermHandler = xoops_getHandler('groupperm');
404
        // First, if the permissions are already there, delete them
405
        $gpermHandler->deleteByModule($module_id, 'category_moderation', $categoryid);
406
        // Save the new permissions
407
        if (count($moderators) > 0) {
408
            foreach ($moderators as $uid) {
409
                $gpermHandler->addRight('category_moderation', $categoryid, $uid, $module_id);
410
            }
411
        }
412
413
        return $result;
414
    }
415
416
    /**
417
     * @param  int $faqid
418
     * @return array
419
     */
420
    public static function retrieveFaqByID($faqid = 0)
421
    {
422
        $ret = [];
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...
423
        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...
424
425
        $result = $xoopsDB->queryF('SELECT * FROM ' . $xoopsDB->prefix('smartfaq_faq') . " WHERE faqid = '$faqid'");
426
        $ret    = $xoopsDB->fetchArray($result);
427
428
        return $ret;
429
    }
430
431
    /**
432
     * self::getAdminLinks()
433
     *
434
     * @param  integer $faqid
435
     * @param  bool    $open
436
     * @return string
437
     */
438
439
    // TODO : Move this to the Smartfaq\Faq class
440
    public static function getAdminLinks($faqid = 0, $open = false)
441
    {
442
        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...
443
        $adminLinks = '';
444
        $modulePath = XOOPS_URL . '/modules/' . $xoopsModule->dirname() . '/';
445
        $page       = $open ? 'question.php' : 'faq.php';
446
        if ($xoopsUser && $xoopsUser->isAdmin($xoopsModule->getVar('mid'))) {
447
            // Edit button
448
            $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>";
449
            $adminLinks .= ' ';
450
            // Delete button
451
            $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>";
452
            $adminLinks .= ' ';
453
        }
454
        // Print button
455
        $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>";
456
        $adminLinks .= ' ';
457
        // Email button
458
        $maillink   = 'mailto:?subject=' . sprintf(_MD_SF_INTARTICLE, $xoopsConfig['sitename']) . '&amp;body=' . sprintf(_MD_SF_INTARTFOUND, $xoopsConfig['sitename']) . ':  ' . $modulePath . 'faq.php?faqid=' . $faqid;
459
        $adminLinks .= '<a href="' . $maillink . "\"><img src='" . $modulePath . "assets/images/links/friend.gif' title='" . _MD_SF_MAIL . "' alt='" . _MD_SF_MAIL . "'></a>";
460
        $adminLinks .= ' ';
461
        // Submit New Answer button
462
        if ($xoopsModuleConfig['allownewanswer'] && (is_object($xoopsUser) || $xoopsModuleConfig['anonpost'])) {
463
            $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>";
464
            $adminLinks .= ' ';
465
        }
466
467
        return $adminLinks;
468
    }
469
470
    /**
471
     * self::getLinkedUnameFromId()
472
     *
473
     * @param  integer $userid Userid of poster etc
474
     * @param  integer $name   :  0 Use Usenamer 1 Use realname
475
     * @param  array   $users
476
     * @return string
477
     */
478
    public static function getLinkedUnameFromId($userid = 0, $name = 0, $users = [])
0 ignored issues
show
Coding Style introduced by
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...
479
    {
480
        if (!is_numeric($userid)) {
481
            return $userid;
482
        }
483
484
        $userid = (int)$userid;
485
        if ($userid > 0) {
486
            if ($users == []) {
487
                //fetching users
488
                $memberHandler = xoops_getHandler('member');
489
                $user          = $memberHandler->getUser($userid);
490
            } else {
491
                if (!isset($users[$userid])) {
492
                    return $GLOBALS['xoopsConfig']['anonymous'];
493
                }
494
                $user =& $users[$userid];
495
            }
496
497
            if (is_object($user)) {
498
                $ts       = \MyTextSanitizer::getInstance();
499
                $username = $user->getVar('uname');
500
                $fullname = '';
501
502
                $fullname2 = $user->getVar('name');
503
504
                if ($name && !empty($fullname2)) {
505
                    $fullname = $user->getVar('name');
506
                }
507
                if (!empty($fullname)) {
508
                    $linkeduser = "$fullname [<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $userid . "'>" . $ts->htmlSpecialChars($username) . '</a>]';
509
                } else {
510
                    $linkeduser = "<a href='" . XOOPS_URL . '/userinfo.php?uid=' . $userid . "'>" . ucwords($ts->htmlSpecialChars($username)) . '</a>';
511
                }
512
513
                return $linkeduser;
514
            }
515
        }
516
517
        return $GLOBALS['xoopsConfig']['anonymous'];
518
    }
519
520
    /**
521
     * @param  string $url
522
     * @return mixed|string
523
     */
524
    public static function getXoopslink($url = '')
525
    {
526
        $xurl = $url;
527
        if (strlen($xurl) > 0) {
528
            if ($xurl[0] = '/') {
529
                $xurl = str_replace('/', '', $xurl);
530
            }
531
            $xurl = str_replace('{SITE_URL}', XOOPS_URL, $xurl);
532
        }
533
534
        //        $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...
535
536
        return $xurl;
537
    }
538
539
    /**
540
     * @param string $tablename
541
     * @param string $iconname
542
     */
543
    public static function collapsableBar($tablename = '', $iconname = '')
544
    {
545
        ?>
546
        <script type="text/javascript"><!--
547
            function goto_URL(object) {
548
                window.location.href = object.options[object.selectedIndex].value;
549
            }
550
551
            function toggle(id) {
552
                if (document.getElementById) {
553
                    obj = document.getElementById(id);
554
                }
555
                if (document.all) {
556
                    obj = document.all[id];
557
                }
558
                if (document.layers) {
559
                    obj = document.layers[id];
560
                }
561
                if (obj) {
562
                    if (obj.style.display === "none") {
563
                        obj.style.display = "";
564
                    } else {
565
                        obj.style.display = "none";
566
                    }
567
                }
568
569
                return false;
570
            }
571
572
            var iconClose = new Image();
573
            iconClose.src = '../assets/images/icon/close12.gif';
574
            var iconOpen = new Image();
575
            iconOpen.src = '../assets/images/icon/open12.gif';
576
577
            function toggleIcon(iconName) {
578
                if (document.images[iconName].src == window.iconOpen.src) {
579
                    document.images[iconName].src = window.iconClose.src;
580
                }
581
                elseif(document.images[iconName].src == window.iconClose.src)
582
                {
583
                    document.images[iconName].src = window.iconOpen.src;
584
                }
585
586
                return;
587
            }
588
589
            //-->
590
        </script>
591
        <?php
592
        echo "<h3 style=\"color: #2F5376; margin: 6px 0 0 0; \"><a href='#' onClick=\"toggle('" . $tablename . "'); toggleIcon('" . $iconname . "');\">";
593
    }
594
595
    /**
596
     * @param       $name
597
     * @param  bool $optional
598
     * @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...
599
     */
600
    public static function getHandler($name, $optional = false)
0 ignored issues
show
Coding Style introduced by
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...
601
    {
602
        static $handlers;
603
        $name = strtolower(trim($name));
604
        if (!isset($handlers[$name])) {
605
            if (file_exists($hnd_file = XOOPS_ROOT_PATH . '/modules/smartfaq/class/' . $name . '.php')) {
606
                require_once $hnd_file;
607
            }
608
            $class = 'sf' . ucfirst($name) . 'Handler';
609
            if (class_exists($class)) {
610
                $handlers[$name] = new $class($GLOBALS['xoopsDB']);
611
            }
612
        }
613
        if (!$optional && !isset($handlers[$name])) {
614
            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...
615
        }
616
        $false = false;
617
618
        return isset($handlers[$name]) ? $handlers[$name] : $false;
619
    }
620
}
621