Completed
Push — master ( 6c5294...348995 )
by Michael
02:27
created

functions.php ➔ faqAccessGranted()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 33
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

Loading history...
2
3
/**
4
 * Module: SmartFAQ
5
 * Author: The SmartFactory <www.smartfactory.ca>
6
 * Licence: GNU
7
 */
8
// defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined');
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
9
10
include_once XOOPS_ROOT_PATH . '/modules/smartfaq/class/category.php';
11
include_once XOOPS_ROOT_PATH . '/modules/smartfaq/class/faq.php';
12
include_once XOOPS_ROOT_PATH . '/modules/smartfaq/class/answer.php';
13
14
/**
15
 * @return mixed|null
16
 */
17
function sf_getModuleInfo()
18
{
19
    static $smartModule;
20 View Code Duplication
    if (!isset($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...
21
        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...
22
        if (isset($xoopsModule) && is_object($xoopsModule) && $xoopsModule->getVar('dirname') === 'smartfaq') {
23
            $smartModule = $xoopsModule;
24
        } else {
25
            $hModule     = xoops_getHandler('module');
26
            $smartModule = $hModule->getByDirname('smartfaq');
27
        }
28
    }
29
30
    return $smartModule;
31
}
32
33
/**
34
 * @return mixed
35
 */
36
function sf_getModuleConfig()
37
{
38
    static $smartConfig;
39
    if (!$smartConfig) {
40
        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...
41 View Code Duplication
        if (isset($xoopsModule) && is_object($xoopsModule) && $xoopsModule->getVar('dirname') === 'smartfaq') {
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...
42
            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...
43
            $smartConfig = $xoopsModuleConfig;
44
        } else {
45
            $smartModule = sf_getModuleInfo();
46
            $hModConfig  = xoops_getHandler('config');
47
            $smartConfig = $hModConfig->getConfigsByCat(0, $smartModule->getVar('mid'));
48
        }
49
    }
50
51
    return $smartConfig;
52
}
53
54
/**
55
 * @return string
56
 */
57
function sf_getHelpPath()
58
{
59
    $smartConfig = sf_getModuleConfig();
60
    switch ($smartConfig['helppath_select']) {
61
        case 'docs.xoops.org' :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

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

Loading history...
62
            return 'http://docs.xoops.org/help/sfaqh/index.htm';
63
            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...
64
65
        case 'inside' :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

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

Loading history...
66
            return XOOPS_URL . '/modules/smartfaq/doc/';
67
            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...
68
69
        case 'custom' :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

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

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