Completed
Push — master ( 53ea58...16270d )
by Michael
04:51
created

functions.php ➔ publisherRatingBar()   F

Complexity

Conditions 13
Paths 336

Size

Total Lines 76
Code Lines 54

Duplication

Lines 6
Ratio 7.89 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
eloc 54
c 1
b 0
f 0
nc 336
nop 1
dl 6
loc 76
rs 3.9627

How to fix   Long Method    Complexity   

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
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 30 and the first side effect is on line 23.

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
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
 */
11
12
/**
13
 * @copyright       The XUUPS Project http://sourceforge.net/projects/xuups/
14
 * @license         http://www.fsf.org/copyleft/gpl.html GNU public license
15
 * @package         Publisher
16
 * @since           1.0
17
 * @author          trabis <[email protected]>
18
 * @author          The SmartFactory <www.smartfactory.ca>
19
 */
20
21
// 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...
22
23
include_once __DIR__ . '/common.php';
24
25
/**
26
 * Includes scripts in HTML header
27
 *
28
 * @return void
29
 */
30
function publisherCpHeader()
31
{
32
    xoops_cp_header();
33
34
    //cannot use xoTheme, some conflit with admin gui
35
    echo '<link type="text/css" href="' . XOOPS_URL . '/modules/system/css/ui/' . xoops_getModuleOption('jquery_theme', 'system') . '/ui.all.css" rel="stylesheet" />
36
    <link type="text/css" href="' . PUBLISHER_URL . '/assets/css/publisher.css" rel="stylesheet" />
37
    <script type="text/javascript" src="' . PUBLISHER_URL . '/assets/js/funcs.js"></script>
38
    <script type="text/javascript" src="' . PUBLISHER_URL . '/assets/js/cookies.js"></script>
39
    <script type="text/javascript" src="' . XOOPS_URL . '/browse.php?Frameworks/jquery/jquery.js"></script>
40
    <!-- <script type="text/javascript" src="' . XOOPS_URL . '/browse.php?Frameworks/jquery/jquery-migrate-1.2.1.js"></script> -->
41
    <script type="text/javascript" src="' . XOOPS_URL . '/browse.php?Frameworks/jquery/plugins/jquery.ui.js"></script>
42
    <script type="text/javascript" src="' . PUBLISHER_URL . '/assets/js/ajaxupload.3.9.js"></script>
43
    <script type="text/javascript" src="' . PUBLISHER_URL . '/assets/js/publisher.js"></script>
44
    ';
45
}
46
47
/**
48
 * Default sorting for a given order
49
 *
50
 * @param  string $sort
51
 * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

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...
52
 */
53
function publisherGetOrderBy($sort)
54
{
55
    if ($sort === 'datesub') {
56
        return 'DESC';
57
    } elseif ($sort === 'counter') {
58
        return 'DESC';
59
    } elseif ($sort === 'weight') {
60
        return 'ASC';
61
    } elseif ($sort === 'votes') {
62
        return 'DESC';
63
    } elseif ($sort === 'rating') {
64
        return 'DESC';
65
    } elseif ($sort === 'comments') {
66
        return 'DESC';
67
    }
68
69
    return null;
70
}
71
72
/**
73
 * @credits Thanks to Mithandir
74
 * @param  string $str
75
 * @param  int    $start
76
 * @param  int    $length
77
 * @param  string $trimMarker
78
 * @return string
79
 */
80
function publisherSubstr($str, $start, $length, $trimMarker = '...')
81
{
82
    // if the string is empty, let's get out ;-)
83
    if ($str == '') {
84
        return $str;
85
    }
86
87
    // reverse a string that is shortened with '' as trimmarker
88
    $reversedString = strrev(xoops_substr($str, $start, $length, ''));
89
90
    // find first space in reversed string
91
    $positionOfSpace = strpos($reversedString, ' ', 0);
92
93
    // truncate the original string to a length of $length
94
    // minus the position of the last space
95
    // plus the length of the $trimMarker
96
    $truncatedString = xoops_substr($str, $start, $length - $positionOfSpace + strlen($trimMarker), $trimMarker);
97
98
    return $truncatedString;
99
}
100
101
/**
102
 * @param  string $document
103
 * @return mixed
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use string.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
104
 */
105 View Code Duplication
function publisherHtml2text($document)
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...
106
{
107
    // PHP Manual:: function preg_replace
108
    // $document should contain an HTML document.
109
    // This will remove HTML tags, javascript sections
110
    // and white space. It will also convert some
111
    // common HTML entities to their text equivalent.
112
    // Credits : newbb2
113
    $search = array(
114
        "'<script[^>]*?>.*?</script>'si", // Strip out javascript
115
        "'<img.*?/>'si", // Strip out img tags
116
        "'<[\/\!]*?[^<>]*?>'si", // Strip out HTML tags
117
        "'([\r\n])[\s]+'", // Strip out white space
118
        "'&(quot|#34);'i", // Replace HTML entities
119
        "'&(amp|#38);'i",
120
        "'&(lt|#60);'i",
121
        "'&(gt|#62);'i",
122
        "'&(nbsp|#160);'i",
123
        "'&(iexcl|#161);'i",
124
        "'&(cent|#162);'i",
125
        "'&(pound|#163);'i",
126
        "'&(copy|#169);'i",
127
        "'&#(\d+);'e"); // evaluate as php
128
129
    $replace = array(
130
        '',
131
        '',
132
        '',
133
        "\\1",
134
        "\"",
135
        '&',
136
        '<',
137
        '>',
138
        ' ',
139
        chr(161),
140
        chr(162),
141
        chr(163),
142
        chr(169),
143
        "chr(\\1)");
144
145
    $text = preg_replace($search, $replace, $document);
146
147
    return $text;
148
    //<?php
149
}
150
151
/**
152
 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use string[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
153
 */
154
function publisherGetAllowedImagesTypes()
155
{
156
    return array('jpg/jpeg', 'image/bmp', 'image/gif', 'image/jpeg', 'image/jpg', 'image/x-png', 'image/png', 'image/pjpeg');
157
}
158
159
/**
160
 * @param  bool $withLink
161
 * @return string
162
 */
163
function publisherModuleHome($withLink = true)
164
{
165
    $publisher = PublisherPublisher::getInstance();
166
167
    if (!$publisher->getConfig('format_breadcrumb_modname')) {
168
        return '';
169
    }
170
171
    if (!$withLink) {
172
        return $publisher->getModule()->getVar('name');
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $publisher->getModule() (of type null).

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

Loading history...
173
    } else {
174
        return '<a href="' . PUBLISHER_URL . '/">' . $publisher->getModule()->getVar('name') . '</a>';
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $publisher->getModule() (of type null).

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

Loading history...
175
    }
176
}
177
178
/**
179
 * Copy a file, or a folder and its contents
180
 *
181
 * @author      Aidan Lister <[email protected]>
182
 * @version     1.0.0
183
 * @param  string $source The source
184
 * @param  string $dest   The destination
185
 * @return bool   Returns true on success, false on failure
186
 */
187
function publisherCopyr($source, $dest)
188
{
189
    // Simple copy for a file
190
    if (is_file($source)) {
191
        return copy($source, $dest);
192
    }
193
194
    // Make destination directory
195
    if (!is_dir($dest)) {
196
        mkdir($dest);
197
    }
198
199
    // Loop through the folder
200
    $dir = dir($source);
201
    while (false !== $entry = $dir->read()) {
202
        // Skip pointers
203
        if ($entry === '.' || $entry === '..') {
204
            continue;
205
        }
206
207
        // Deep copy directories
208
        if (($dest !== "$source/$entry") && is_dir("$source/$entry")) {
209
            publisherCopyr("$source/$entry", "$dest/$entry");
210
        } else {
211
            copy("$source/$entry", "$dest/$entry");
212
        }
213
    }
214
215
    // Clean up
216
    $dir->close();
217
218
    return true;
219
}
220
221
/**
222
 * .* @credits Thanks to the NewBB2 Development Team
223
 * @param  string $item
224
 * @param  bool   $getStatus
225
 * @return bool|int|string
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use false|string|integer.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
226
 */
227
function &publisherGetPathStatus($item, $getStatus = false)
228
{
229
    $path = '';
230
    if ('root' !== $item) {
231
        $path = $item;
232
    }
233
234
    $thePath = publisherGetUploadDir(true, $path);
0 ignored issues
show
Documentation introduced by
$path is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
235
236
    if (empty($thePath)) {
237
        return false;
238
    }
239
    if (is_writable($thePath)) {
240
        $pathCheckResult = 1;
241
        $pathStatus      = _AM_PUBLISHER_AVAILABLE;
242
    } elseif (!@is_dir($thePath)) {
243
        $pathCheckResult = -1;
244
        $pathStatus      = _AM_PUBLISHER_NOTAVAILABLE . " <a href='" . PUBLISHER_ADMIN_URL . "/index.php?op=createdir&amp;path={$item}'>" . _AM_PUBLISHER_CREATETHEDIR . '</a>';
245
    } else {
246
        $pathCheckResult = -2;
247
        $pathStatus      = _AM_PUBLISHER_NOTWRITABLE . " <a href='" . PUBLISHER_ADMIN_URL . "/index.php?op=setperm&amp;path={$item}'>" . _AM_PUBLISHER_SETMPERM . '</a>';
248
    }
249
    if (!$getStatus) {
250
        return $pathStatus;
251
    } else {
252
        return $pathCheckResult;
253
    }
254
}
255
256
/**
257
 * @credits Thanks to the NewBB2 Development Team
258
 * @param  string $target
259
 * @return bool
260
 */
261
function publisherMkdir($target)
262
{
263
    // http://www.php.net/manual/en/function.mkdir.php
264
    // saint at corenova.com
265
    // bart at cdasites dot com
266
    if (empty($target) || is_dir($target)) {
267
        return true; // best case check first
268
    }
269
270
    if (file_exists($target) && !is_dir($target)) {
271
        return false;
272
    }
273
274
    if (publisherMkdir(substr($target, 0, strrpos($target, '/')))) {
275
        if (!file_exists($target)) {
276
            $res = mkdir($target, 0777); // crawl back up & create dir tree
277
            publisherChmod($target);
278
279
            return $res;
280
        }
281
    }
282
    $res = is_dir($target);
283
284
    return $res;
285
}
286
287
/**
288
 * @credits Thanks to the NewBB2 Development Team
289
 * @param  string $target
290
 * @param  int    $mode
291
 * @return bool
292
 */
293
function publisherChmod($target, $mode = 0777)
294
{
295
    return @chmod($target, $mode);
296
}
297
298
/**
299
 * @param  bool $hasPath
300
 * @param  bool $item
301
 * @return string
302
 */
303
function publisherGetUploadDir($hasPath = true, $item = false)
304
{
305
    if ($item) {
306
        if ($item === 'root') {
307
            $item = '';
308
        } else {
309
            $item .= '/';
310
        }
311
    } else {
312
        $item = '';
313
    }
314
315
    if ($hasPath) {
316
        return PUBLISHER_UPLOAD_PATH . '/' . $item;
317
    } else {
318
        return PUBLISHER_UPLOAD_URL . '/' . $item;
319
    }
320
}
321
322
/**
323
 * @param  string $item
324
 * @param  bool   $hasPath
325
 * @return string
326
 */
327
function publisherGetImageDir($item = '', $hasPath = true)
328
{
329
    if ($item) {
330
        $item = "images/{$item}";
331
    } else {
332
        $item = 'images';
333
    }
334
335
    return publisherGetUploadDir($hasPath, $item);
336
}
337
338
/**
339
 * @param  array $errors
340
 * @return string
341
 */
342
function publisherFormatErrors($errors = array())
343
{
344
    $ret = '';
345
    foreach ($errors as $key => $value) {
346
        $ret .= '<br> - ' . $value;
347
    }
348
349
    return $ret;
350
}
351
352
/**
353
 * Checks if a user is admin of Publisher
354
 *
355
 * @return boolean
356
 */
357
function publisherUserIsAdmin()
0 ignored issues
show
Coding Style introduced by
publisherUserIsAdmin 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...
358
{
359
    $publisher = PublisherPublisher::getInstance();
360
361
    static $publisherIsAdmin;
362
363
    if (isset($publisherIsAdmin)) {
364
        return $publisherIsAdmin;
365
    }
366
367
    if (!$GLOBALS['xoopsUser']) {
368
        $publisherIsAdmin = false;
369
    } else {
370
        $publisherIsAdmin = $GLOBALS['xoopsUser']->isAdmin($publisher->getModule()->getVar('mid'));
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $publisher->getModule() (of type null).

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

Loading history...
371
    }
372
373
    return $publisherIsAdmin;
374
}
375
376
/**
377
 * Check is current user is author of a given article
378
 *
379
 * @param  object $itemObj
380
 * @return bool
381
 */
382
function publisherUserIsAuthor($itemObj)
0 ignored issues
show
Coding Style introduced by
publisherUserIsAuthor 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...
383
{
384
    return (is_object($GLOBALS['xoopsUser']) && is_object($itemObj) && ($GLOBALS['xoopsUser']->uid() == $itemObj->uid()));
385
}
386
387
/**
388
 * Check is current user is moderator of a given article
389
 *
390
 * @param  object $itemObj
391
 * @return bool
392
 */
393
function publisherUserIsModerator($itemObj)
394
{
395
    $publisher         = PublisherPublisher::getInstance();
396
    $categoriesGranted = $publisher->getHandler('permission')->getGrantedItems('category_moderation');
397
398
    return (is_object($itemObj) && in_array($itemObj->categoryid(), $categoriesGranted));
399
}
400
401
/**
402
 * Saves permissions for the selected category
403
 *
404
 * @param  array   $groups     : group with granted permission
405
 * @param  integer $categoryId : categoryid on which we are setting permissions
406
 * @param  string  $permName   : name of the permission
407
 * @return boolean : TRUE if the no errors occured
408
 */
409
function publisherSaveCategoryPermissions($groups, $categoryId, $permName)
410
{
411
    $publisher = PublisherPublisher::getInstance();
412
413
    $result = true;
414
415
    $moduleId     = $publisher->getModule()->getVar('mid');
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $publisher->getModule() (of type null).

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

Loading history...
416
    $gpermHandler = xoops_getHandler('groupperm');
417
    // First, if the permissions are already there, delete them
418
    $gpermHandler->deleteByModule($moduleId, $permName, $categoryId);
419
420
    // Save the new permissions
421
    if (count($groups) > 0) {
422
        foreach ($groups as $groupId) {
423
            $gpermHandler->addRight($permName, $categoryId, $groupId, $moduleId);
424
        }
425
    }
426
427
    return $result;
428
}
429
430
/**
431
 * @param  string $tablename
432
 * @param  string $iconname
433
 * @param  string $tabletitle
434
 * @param  string $tabledsc
435
 * @param  bool   $open
436
 * @return void
437
 */
438
function publisherOpenCollapsableBar($tablename = '', $iconname = '', $tabletitle = '', $tabledsc = '', $open = true)
439
{
440
    $image   = 'open12.gif';
441
    $display = 'none';
442
    if ($open) {
443
        $image   = 'close12.gif';
444
        $display = 'block';
445
    }
446
447
    echo "<h3 style=\"color: #2F5376; font-weight: bold; font-size: 14px; margin: 6px 0 0 0; \"><a href='javascript:;' onclick=\"toggle('" . $tablename . "'); toggleIcon('" . $iconname . "')\">";
448
    echo "<img id='" . $iconname . "' src='" . PUBLISHER_URL . '/assets/images/links/' . $image . "' alt='' /></a>&nbsp;" . $tabletitle . '</h3>';
449
    echo "<div id='" . $tablename . "' style='display: " . $display . ";'>";
450
    if ($tabledsc != '') {
451
        echo "<span style=\"color: #567; margin: 3px 0 12px 0; font-size: small; display: block; \">" . $tabledsc . '</span>';
452
    }
453
}
454
455
/**
456
 * @param  string $name
457
 * @param  string $icon
458
 * @return void
459
 */
460
function publisherCloseCollapsableBar($name, $icon)
461
{
462
    echo '</div>';
463
464
    $urls = publisherGetCurrentUrls();
465
    $path = $urls['phpself'];
466
467
    $cookieName = $path . '_publisher_collaps_' . $name;
468
    $cookieName = str_replace('.', '_', $cookieName);
469
    $cookie     = publisherGetCookieVar($cookieName, '');
470
471
    if ($cookie === 'none') {
472
        echo '
473
        <script type="text/javascript"><!--
474
        toggle("' . $name . '"); toggleIcon("' . $icon . '");
475
        //-->
476
        </script>
477
        ';
478
    }
479
}
480
481
/**
482
 * @param  string $name
483
 * @param  string $value
484
 * @param  int    $time
485
 * @return void
486
 */
487
function publisherSetCookieVar($name, $value, $time = 0)
488
{
489
    if ($time == 0) {
490
        $time = time() + 3600 * 24 * 365;
491
    }
492
    setcookie($name, $value, $time, '/');
493
}
494
495
/**
496
 * @param  string $name
497
 * @param  string $default
498
 * @return string
499
 */
500
function publisherGetCookieVar($name, $default = '')
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
501
{
502
    //    if (isset($_COOKIE[$name]) && ($_COOKIE[$name] > '')) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
71% 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...
503
    //        return $_COOKIE[$name];
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% 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...
504
    //    } 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...
505
    //        return $default;
506
    //    }
507
    return XoopsRequest::getString('name', $default, 'COOKIE');
508
}
509
510
/**
511
 * @return array
512
 */
513
function publisherGetCurrentUrls()
514
{
515
    $http = strpos(XOOPS_URL, 'https://') === false ? 'http://' : 'https://';
516
    //    $phpself     = $_SERVER['PHP_SELF'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
517
    //    $httphost    = $_SERVER['HTTP_HOST'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
518
    //    $querystring = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '';
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...
519
    $phpself     = XoopsRequest::getString('PHP_SELF', '', 'SERVER');
520
    $httphost    = XoopsRequest::getString('HTTP_HOST', '', 'SERVER');
521
    $querystring = XoopsRequest::getString('QUERY_STRING', '', 'SERVER');
522
523
    if ($querystring != '') {
524
        $querystring = '?' . $querystring;
525
    }
526
527
    $currenturl = $http . $httphost . $phpself . $querystring;
528
529
    $urls                = array();
530
    $urls['http']        = $http;
531
    $urls['httphost']    = $httphost;
532
    $urls['phpself']     = $phpself;
533
    $urls['querystring'] = $querystring;
534
    $urls['full']        = $currenturl;
535
536
    return $urls;
537
}
538
539
/**
540
 * @return string
541
 */
542
function publisherGetCurrentPage()
543
{
544
    $urls = publisherGetCurrentUrls();
545
546
    return $urls['full'];
547
}
548
549
/**
550
 * @param  null|PublisherCategory $categoryObj
0 ignored issues
show
Documentation introduced by
Consider making the type for parameter $categoryObj a bit more specific; maybe use PublisherCategory.
Loading history...
551
 * @param  int                    $selectedid
552
 * @param  int                    $level
553
 * @param  string                 $ret
554
 * @return string
555
 */
556
function publisherAddCategoryOption(PublisherCategory $categoryObj, $selectedid = 0, $level = 0, $ret = '')
557
{
558
    $publisher = PublisherPublisher::getInstance();
559
560
    $spaces = '';
561
    for ($j = 0; $j < $level; ++$j) {
562
        $spaces .= '--';
563
    }
564
565
    $ret .= "<option value='" . $categoryObj->categoryid() . "'";
566
    if (is_array($selectedid) && in_array($categoryObj->categoryid(), $selectedid)) {
567
        $ret .= " selected='selected'";
568
    } elseif ($categoryObj->categoryid() == $selectedid) {
569
        $ret .= " selected='selected'";
570
    }
571
    $ret .= '>' . $spaces . $categoryObj->name() . "</option>\n";
572
573
    $subCategoriesObj = $publisher->getHandler('category')->getCategories(0, 0, $categoryObj->categoryid());
574
    if (count($subCategoriesObj) > 0) {
575
        ++$level;
576
        foreach ($subCategoriesObj as $catID => $subCategoryObj) {
577
            $ret .= publisherAddCategoryOption($subCategoryObj, $selectedid, $level);
0 ignored issues
show
Bug introduced by
It seems like $selectedid can also be of type array; however, publisherAddCategoryOption() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
578
        }
579
    }
580
581
    return $ret;
582
}
583
584
/**
585
 * @param  int    $selectedid
586
 * @param  int    $parentcategory
587
 * @param  bool   $allCatOption
588
 * @param  string $selectname
589
 * @return string
590
 */
591
function publisherCreateCategorySelect($selectedid = 0, $parentcategory = 0, $allCatOption = true, $selectname = 'options[0]')
592
{
593
    $publisher = PublisherPublisher::getInstance();
594
595
    $selectedid = explode(',', $selectedid);
596
597
    $ret = "<select name='" . $selectname . "[]' multiple='multiple' size='10'>";
598
    if ($allCatOption) {
599
        $ret .= "<option value='0'";
600
        if (in_array(0, $selectedid)) {
601
            $ret .= " selected='selected'";
602
        }
603
        $ret .= '>' . _MB_PUBLISHER_ALLCAT . '</option>';
604
    }
605
606
    // Creating category objects
607
    $categoriesObj = $publisher->getHandler('category')->getCategories(0, 0, $parentcategory);
608
609 View Code Duplication
    if (count($categoriesObj) > 0) {
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...
610
        foreach ($categoriesObj as $catID => $categoryObj) {
611
            $ret .= publisherAddCategoryOption($categoryObj, $selectedid);
0 ignored issues
show
Documentation introduced by
$selectedid is of type array, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
612
        }
613
    }
614
    $ret .= '</select>';
615
616
    return $ret;
617
}
618
619
/**
620
 * @param  int  $selectedid
621
 * @param  int  $parentcategory
622
 * @param  bool $allCatOption
623
 * @return string
624
 */
625
function publisherCreateCategoryOptions($selectedid = 0, $parentcategory = 0, $allCatOption = true)
626
{
627
    $publisher = PublisherPublisher::getInstance();
628
629
    $ret = '';
630
    if ($allCatOption) {
631
        $ret .= "<option value='0'";
632
        $ret .= '>' . _MB_PUBLISHER_ALLCAT . "</option>\n";
633
    }
634
635
    // Creating category objects
636
    $categoriesObj = $publisher->getHandler('category')->getCategories(0, 0, $parentcategory);
637 View Code Duplication
    if (count($categoriesObj) > 0) {
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...
638
        foreach ($categoriesObj as $catID => $categoryObj) {
639
            $ret .= publisherAddCategoryOption($categoryObj, $selectedid);
640
        }
641
    }
642
643
    return $ret;
644
}
645
646
/**
647
 * @param  array  $errArray
648
 * @param  string $reseturl
649
 * @return void
650
 */
651
function publisherRenderErrors(&$errArray, $reseturl = '')
652
{
653
    if (is_array($errArray) && count($errArray) > 0) {
654
        echo '<div id="readOnly" class="errorMsg" style="border:1px solid #D24D00; background:#FEFECC url(' . PUBLISHER_URL . '/assets/images/important-32.png) no-repeat 7px 50%;color:#333;padding-left:45px;">';
655
656
        echo '<h4 style="text-align:left;margin:0; padding-top:0;">' . _AM_PUBLISHER_MSG_SUBMISSION_ERR;
657
658
        if ($reseturl) {
659
            echo ' <a href="' . $reseturl . '">[' . _AM_PUBLISHER_TEXT_SESSION_RESET . ']</a>';
660
        }
661
662
        echo '</h4><ul>';
663
664
        foreach ($errArray as $key => $error) {
665
            if (is_array($error)) {
666
                foreach ($error as $err) {
667
                    echo '<li><a href="#' . $key . '" onclick="var e = xoopsGetElementById(\'' . $key . '\'); e.focus();">' . htmlspecialchars($err) . '</a></li>';
668
                }
669
            } else {
670
                echo '<li><a href="#' . $key . '" onclick="var e = xoopsGetElementById(\'' . $key . '\'); e.focus();">' . htmlspecialchars($error) . '</a></li>';
671
            }
672
        }
673
        echo '</ul></div><br>';
674
    }
675
}
676
677
/**
678
 * Generate publisher URL
679
 *
680
 * @param  string $page
681
 * @param  array  $vars
682
 * @param  bool   $encodeAmp
683
 * @return string
684
 *
685
 * @credit : xHelp module, developped by 3Dev
686
 */
687
function publisherMakeUri($page, $vars = array(), $encodeAmp = true)
688
{
689
    $joinStr = '';
690
691
    $amp = ($encodeAmp ? '&amp;' : '&');
692
693
    if (!count($vars)) {
694
        return $page;
695
    }
696
697
    $qs = '';
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $qs. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
698
    foreach ($vars as $key => $value) {
699
        $qs .= $joinStr . $key . '=' . $value;
700
        $joinStr = $amp;
701
    }
702
703
    return $page . '?' . $qs;
704
}
705
706
/**
707
 * @param  string $subject
708
 * @return string
709
 */
710
function publisherTellAFriend($subject = '')
711
{
712
    if (false !== strpos($subject, '%')) {
713
        $subject = rawurldecode($subject);
714
    }
715
716
    $targetUri = XOOPS_URL . XoopsRequest::getString('REQUEST_URI', '', 'SERVER');
717
718
    return XOOPS_URL . '/modules/tellafriend/index.php?target_uri=' . rawurlencode($targetUri) . '&amp;subject=' . rawurlencode($subject);
719
}
720
721
/**
722
 * @param  bool        $another
723
 * @param  bool        $withRedirect
724
 * @param              $itemObj
725
 * @return bool|string
726
 */
727
function publisherUploadFile($another = false, $withRedirect = true, &$itemObj)
0 ignored issues
show
Coding Style introduced by
publisherUploadFile 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...
Coding Style introduced by
publisherUploadFile uses the super-global variable $_FILES 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...
728
{
729
    include_once PUBLISHER_ROOT_PATH . '/class/uploader.php';
730
731
    //    global $publisherIsAdmin;
732
    $publisher = PublisherPublisher::getInstance();
733
734
    $itemId  = XoopsRequest::getInt('itemid', 0, 'POST');
735
    $uid     = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->uid() : 0;
736
    $session = PublisherSession::getInstance();
737
    $session->set('publisher_file_filename', XoopsRequest::getString('item_file_name', '', 'POST'));
738
    $session->set('publisher_file_description', XoopsRequest::getString('item_file_description', '', 'POST'));
739
    $session->set('publisher_file_status', XoopsRequest::getInt('item_file_status', 1, 'POST'));
740
    $session->set('publisher_file_uid', $uid);
741
    $session->set('publisher_file_itemid', $itemId);
742
743
    if (!is_object($itemObj)) {
744
        $itemObj = $publisher->getHandler('item')->get($itemId);
745
    }
746
747
    $fileObj = $publisher->getHandler('file')->create();
748
    $fileObj->setVar('name', XoopsRequest::getString('item_file_name', '', 'POST'));
749
    $fileObj->setVar('description', XoopsRequest::getString('item_file_description', '', 'POST'));
750
    $fileObj->setVar('status', XoopsRequest::getInt('item_file_status', 1, 'POST'));
751
    $fileObj->setVar('uid', $uid);
752
    $fileObj->setVar('itemid', $itemObj->getVar('itemid'));
753
    $fileObj->setVar('datesub', time());
754
755
    // Get available mimetypes for file uploading
756
    $allowedMimetypes = $publisher->getHandler('mimetype')->getArrayByType();
757
    // TODO : display the available mimetypes to the user
758
    $errors = array();
759
    if ($publisher->getConfig('perm_upload') && is_uploaded_file($_FILES['item_upload_file']['tmp_name'])) {
760
        if (!$ret = $fileObj->checkUpload('item_upload_file', $allowedMimetypes, $errors)) {
761
            $errorstxt = implode('<br>', $errors);
762
763
            $message = sprintf(_CO_PUBLISHER_MESSAGE_FILE_ERROR, $errorstxt);
764
            if ($withRedirect) {
765
                redirect_header('file.php?op=mod&itemid=' . $itemId, 5, $message);
766
            } else {
767
                return $message;
768
            }
769
        }
770
    }
771
772
    // Storing the file
773
    if (!$fileObj->store($allowedMimetypes)) {
774
        //        if ($withRedirect) {
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...
775
        //            redirect_header("file.php?op=mod&itemid=" . $fileObj->itemid(), 3, _CO_PUBLISHER_FILEUPLOAD_ERROR . publisherFormatErrors($fileObj->getErrors()));
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% 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...
776
        //            exit;
777
        //        }
778
        try {
779
            if ($withRedirect) {
780
                throw new Exception(_CO_PUBLISHER_FILEUPLOAD_ERROR . publisherFormatErrors($fileObj->getErrors()));
781
            }
782
        } catch (Exception $e) {
783
            redirect_header('file.php?op=mod&itemid=' . $fileObj->itemid(), 3, _CO_PUBLISHER_FILEUPLOAD_ERROR . publisherFormatErrors($fileObj->getErrors()));
784
        }
785
        //    } 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...
786
        //        return _CO_PUBLISHER_FILEUPLOAD_ERROR . publisherFormatErrors($fileObj->getErrors());
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...
787
    }
788
789
    if ($withRedirect) {
790
        $redirectPage = $another ? 'file.php' : 'item.php';
791
        redirect_header($redirectPage . '?op=mod&itemid=' . $fileObj->itemid(), 2, _CO_PUBLISHER_FILEUPLOAD_SUCCESS);
792
    } else {
793
        return true;
794
    }
795
796
    return null;
797
}
798
799
/**
800
 * @return string
801
 */
802
function publisherNewFeatureTag()
803
{
804
    $ret = '<span style="padding-right: 4px; font-weight: bold; color: red;">' . _CO_PUBLISHER_NEW_FEATURE . '</span>';
805
806
    return $ret;
807
}
808
809
/**
810
 * Smarty truncate_tagsafe modifier plugin
811
 *
812
 * Type:     modifier<br>
813
 * Name:     truncate_tagsafe<br>
814
 * Purpose:  Truncate a string to a certain length if necessary,
815
 *           optionally splitting in the middle of a word, and
816
 *           appending the $etc string or inserting $etc into the middle.
817
 *           Makes sure no tags are left half-open or half-closed
818
 *           (e.g. "Banana in a <a...")
819
 * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
820
 *           <amos dot robinson at gmail dot com>
821
 * @param string
822
 * @param integer
823
 * @param string
824
 * @param boolean
825
 * @param boolean
826
 * @return string
827
 */
828
function publisherTruncateTagSafe($string, $length = 80, $etc = '...', $breakWords = false)
829
{
830
    if ($length == 0) {
831
        return '';
832
    }
833
834
    if (strlen($string) > $length) {
835
        $length -= strlen($etc);
836
        if (!$breakWords) {
837
            $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length + 1));
838
            $string = preg_replace('/<[^>]*$/', '', $string);
839
            $string = publisherCloseTags($string);
840
        }
841
842
        return $string . $etc;
843
    } else {
844
        return $string;
845
    }
846
}
847
848
/**
849
 * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
850
 *           <amos dot robinson at gmail dot com>
851
 * @param  string $string
852
 * @return string
853
 */
854
function publisherCloseTags($string)
855
{
856
    // match opened tags
857
    if (preg_match_all('/<([a-z\:\-]+)[^\/]>/', $string, $startTags)) {
858
        $startTags = $startTags[1];
859
        // match closed tags
860
        if (preg_match_all('/<\/([a-z]+)>/', $string, $endTags)) {
861
            $completeTags = array();
862
            $endTags      = $endTags[1];
863
864
            foreach ($startTags as $key => $val) {
865
                $posb = array_search($val, $endTags);
866
                if (is_int($posb)) {
867
                    unset($endTags[$posb]);
868
                } else {
869
                    $completeTags[] = $val;
870
                }
871
            }
872
        } else {
873
            $completeTags = $startTags;
874
        }
875
876
        $completeTags = array_reverse($completeTags);
877
        $elementCount = count($completeTags);
878
        for ($i = 0; $i < $elementCount; ++$i) {
879
            $string .= '</' . $completeTags[$i] . '>';
880
        }
881
    }
882
883
    return $string;
884
}
885
886
/**
887
 * @param  int $itemId
888
 * @return string
889
 */
890
function publisherRatingBar($itemId)
0 ignored issues
show
Coding Style introduced by
publisherRatingBar 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...
891
{
892
    $publisher       = PublisherPublisher::getInstance();
893
    $ratingUnitWidth = 30;
894
    $units           = 5;
895
896
    $criteria   = new Criteria('itemid', $itemId);
897
    $ratingObjs = $publisher->getHandler('rating')->getObjects($criteria);
898
    unset($criteria);
899
900
    $uid           = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getVar('uid') : 0;
901
    $count         = count($ratingObjs);
902
    $currentRating = 0;
903
    $voted         = false;
904
    $ip            = getenv('REMOTE_ADDR');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $ip. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
905
    $rating1       = $rating2 = $ratingWidth = 0;
906
907 View Code Duplication
    foreach ($ratingObjs as $ratingObj) {
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...
908
        $currentRating += $ratingObj->getVar('rate');
909
        if ($ratingObj->getVar('ip') == $ip || ($uid > 0 && $uid == $ratingObj->getVar('uid'))) {
910
            $voted = true;
911
        }
912
    }
913
914
    $tense = $count == 1 ? _MD_PUBLISHER_VOTE_VOTE : _MD_PUBLISHER_VOTE_VOTES; //plural form votes/vote
915
916
    // now draw the rating bar
917
    if ($count != 0) {
918
        $ratingWidth = number_format($currentRating / $count, 2) * $ratingUnitWidth;
919
        $rating1     = number_format($currentRating / $count, 1);
920
        $rating2     = number_format($currentRating / $count, 2);
921
    }
922
    $groups       = $GLOBALS['xoopsUser'] ? $GLOBALS['xoopsUser']->getGroups() : XOOPS_GROUP_ANONYMOUS;
923
    $gpermHandler = $publisher->getHandler('groupperm');
924
925
    if (!$gpermHandler->checkRight('global', PublisherConstants::PUBLISHER_RATE, $groups, $publisher->getModule()->getVar('mid'))) {
0 ignored issues
show
Bug introduced by
The method getVar cannot be called on $publisher->getModule() (of type null).

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

Loading history...
926
        $staticRater = array();
927
        $staticRater[] .= "\n" . '<div class="publisher_ratingblock">';
928
        $staticRater[] .= '<div id="unit_long' . $itemId . '">';
929
        $staticRater[] .= '<div id="unit_ul' . $itemId . '" class="publisher_unit-rating" style="width:' . $ratingUnitWidth * $units . 'px;">';
930
        $staticRater[] .= '<div class="publisher_current-rating" style="width:' . $ratingWidth . 'px;">' . _MD_PUBLISHER_VOTE_RATING . ' ' . $rating2 . '/' . $units . '</div>';
931
        $staticRater[] .= '</div>';
932
        $staticRater[] .= '<div class="publisher_static">' . _MD_PUBLISHER_VOTE_RATING . ': <strong> ' . $rating1 . '</strong>/' . $units . ' (' . $count . ' ' . $tense . ') <br><em>' . _MD_PUBLISHER_VOTE_DISABLE . '</em></div>';
933
        $staticRater[] .= '</div>';
934
        $staticRater[] .= '</div>' . "\n\n";
935
936
        return implode("\n", $staticRater);
937
    } else {
938
        $rater = '';
939
        $rater .= '<div class="publisher_ratingblock">';
940
        $rater .= '<div id="unit_long' . $itemId . '">';
941
        $rater .= '<div id="unit_ul' . $itemId . '" class="publisher_unit-rating" style="width:' . $ratingUnitWidth * $units . 'px;">';
942
        $rater .= '<div class="publisher_current-rating" style="width:' . $ratingWidth . 'px;">' . _MD_PUBLISHER_VOTE_RATING . ' ' . $rating2 . '/' . $units . '</div>';
943
944
        for ($ncount = 1; $ncount <= $units; ++$ncount) { // loop from 1 to the number of units
945
            if (!$voted) { // if the user hasn't yet voted, draw the voting stars
946
                $rater .= '<div><a href="' . PUBLISHER_URL . '/rate.php?itemid=' . $itemId . '&amp;rating=' . $ncount . '" title="' . $ncount . ' ' . _MD_PUBLISHER_VOTE_OUTOF . ' ' . $units . '" class="publisher_r' . $ncount . '-unit rater" rel="nofollow">' . $ncount . '</a></div>';
947
            }
948
        }
949
950
        $ncount = 0; // resets the count
0 ignored issues
show
Unused Code introduced by
$ncount 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...
951
        $rater .= '  </div>';
952
        $rater .= '  <div';
953
954
        if ($voted) {
955
            $rater .= ' class="publisher_voted"';
956
        }
957
958
        $rater .= '>' . _MD_PUBLISHER_VOTE_RATING . ': <strong> ' . $rating1 . '</strong>/' . $units . ' (' . $count . ' ' . $tense . ')';
959
        $rater .= '  </div>';
960
        $rater .= '</div>';
961
        $rater .= '</div>';
962
963
        return $rater;
964
    }
965
}
966
967
/**
968
 * @param  array $allowedEditors
0 ignored issues
show
Documentation introduced by
Should the type for parameter $allowedEditors not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

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. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

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

Loading history...
969
 * @return array
970
 */
971
function publisherGetEditors($allowedEditors = null)
972
{
973
    $ret    = array();
974
    $nohtml = false;
975
    xoops_load('XoopsEditorHandler');
976
    $editorHandler = XoopsEditorHandler::getInstance();
977
    $editors       = $editorHandler->getList($nohtml);
978
    foreach ($editors as $name => $title) {
979
        $key = publisherStringToInt($name);
980
        if (is_array($allowedEditors)) {
981
            //for submit page
982
            if (in_array($key, $allowedEditors)) {
983
                $ret[] = $name;
984
            }
985
        } else {
986
            //for admin permissions page
987
            $ret[$key]['name']  = $name;
988
            $ret[$key]['title'] = $title;
989
        }
990
    }
991
992
    return $ret;
993
}
994
995
/**
996
 * @param  string $string
997
 * @param  int    $length
998
 * @return int
999
 */
1000
function publisherStringToInt($string = '', $length = 5)
1001
{
1002
    $final  = '';
1003
    $string = substr(md5($string), $length);
1004
    for ($i = 0; $i < $length; ++$i) {
1005
        $final .= (int)$string[$i];
1006
    }
1007
1008
    return (int)$final;
1009
}
1010
1011
/**
1012
 * @param  string $item
1013
 * @return string
1014
 */
1015
function publisherConvertCharset($item)
1016
{
1017
    if (_CHARSET !== 'windows-1256') {
1018
        return utf8_encode($item);
1019
    }
1020
1021
    if ($unserialize == unserialize($item)) {
0 ignored issues
show
Security Object Injection introduced by
$item can contain request data and is used in unserialized context(s) leading to a potential security vulnerability.

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
1022
        foreach ($unserialize as $key => $value) {
0 ignored issues
show
Bug introduced by
The variable $unserialize 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...
1023
            $unserialize[$key] = @iconv('windows-1256', 'UTF-8', $value);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$unserialize was never initialized. Although not strictly required by PHP, it is generally a good practice to add $unserialize = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1024
        }
1025
        $serialize = serialize($unserialize);
1026
1027
        return $serialize;
1028
    } else {
1029
        return @iconv('windows-1256', 'UTF-8', $item);
1030
    }
1031
}
1032