Completed
Push — master ( 16270d...f28230 )
by Michael
03:23
created

functions.php ➔ publisherHtml2text()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 47
Code Lines 33

Duplication

Lines 45
Ratio 95.74 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 33
c 1
b 0
f 0
nc 1
nop 1
dl 45
loc 47
rs 9.0303
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"
128
    ); // evaluate as php
129
130
    $replace = array(
131
        '',
132
        '',
133
        '',
134
        "\\1",
135
        "\"",
136
        '&',
137
        '<',
138
        '>',
139
        ' ',
140
        chr(161),
141
        chr(162),
142
        chr(163),
143
        chr(169),
144
        "chr(\\1)"
145
    );
146
147
    $text = preg_replace($search, $replace, $document);
148
149
    return $text;
150
    //<?php
151
}
152
153
/**
154
 * @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...
155
 */
156
function publisherGetAllowedImagesTypes()
157
{
158
    return array('jpg/jpeg', 'image/bmp', 'image/gif', 'image/jpeg', 'image/jpg', 'image/x-png', 'image/png', 'image/pjpeg');
159
}
160
161
/**
162
 * @param  bool $withLink
163
 * @return string
164
 */
165
function publisherModuleHome($withLink = true)
166
{
167
    $publisher = PublisherPublisher::getInstance();
168
169
    if (!$publisher->getConfig('format_breadcrumb_modname')) {
170
        return '';
171
    }
172
173
    if (!$withLink) {
174
        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...
175
    } else {
176
        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...
177
    }
178
}
179
180
/**
181
 * Copy a file, or a folder and its contents
182
 *
183
 * @author      Aidan Lister <[email protected]>
184
 * @version     1.0.0
185
 * @param  string $source The source
186
 * @param  string $dest   The destination
187
 * @return bool   Returns true on success, false on failure
188
 */
189
function publisherCopyr($source, $dest)
190
{
191
    // Simple copy for a file
192
    if (is_file($source)) {
193
        return copy($source, $dest);
194
    }
195
196
    // Make destination directory
197
    if (!is_dir($dest)) {
198
        mkdir($dest);
199
    }
200
201
    // Loop through the folder
202
    $dir = dir($source);
203
    while (false !== $entry = $dir->read()) {
204
        // Skip pointers
205
        if ($entry === '.' || $entry === '..') {
206
            continue;
207
        }
208
209
        // Deep copy directories
210
        if (($dest !== "$source/$entry") && is_dir("$source/$entry")) {
211
            publisherCopyr("$source/$entry", "$dest/$entry");
212
        } else {
213
            copy("$source/$entry", "$dest/$entry");
214
        }
215
    }
216
217
    // Clean up
218
    $dir->close();
219
220
    return true;
221
}
222
223
/**
224
 * .* @credits Thanks to the NewBB2 Development Team
225
 * @param  string $item
226
 * @param  bool   $getStatus
227
 * @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...
228
 */
229
function &publisherGetPathStatus($item, $getStatus = false)
230
{
231
    $path = '';
232
    if ('root' !== $item) {
233
        $path = $item;
234
    }
235
236
    $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...
237
238
    if (empty($thePath)) {
239
        return false;
240
    }
241
    if (is_writable($thePath)) {
242
        $pathCheckResult = 1;
243
        $pathStatus      = _AM_PUBLISHER_AVAILABLE;
244
    } elseif (!@is_dir($thePath)) {
245
        $pathCheckResult = -1;
246
        $pathStatus      = _AM_PUBLISHER_NOTAVAILABLE . " <a href='" . PUBLISHER_ADMIN_URL . "/index.php?op=createdir&amp;path={$item}'>" . _AM_PUBLISHER_CREATETHEDIR . '</a>';
247
    } else {
248
        $pathCheckResult = -2;
249
        $pathStatus      = _AM_PUBLISHER_NOTWRITABLE . " <a href='" . PUBLISHER_ADMIN_URL . "/index.php?op=setperm&amp;path={$item}'>" . _AM_PUBLISHER_SETMPERM . '</a>';
250
    }
251
    if (!$getStatus) {
252
        return $pathStatus;
253
    } else {
254
        return $pathCheckResult;
255
    }
256
}
257
258
/**
259
 * @credits Thanks to the NewBB2 Development Team
260
 * @param  string $target
261
 * @return bool
262
 */
263
function publisherMkdir($target)
264
{
265
    // http://www.php.net/manual/en/function.mkdir.php
266
    // saint at corenova.com
267
    // bart at cdasites dot com
268
    if (empty($target) || is_dir($target)) {
269
        return true; // best case check first
270
    }
271
272
    if (file_exists($target) && !is_dir($target)) {
273
        return false;
274
    }
275
276
    if (publisherMkdir(substr($target, 0, strrpos($target, '/')))) {
277
        if (!file_exists($target)) {
278
            $res = mkdir($target, 0777); // crawl back up & create dir tree
279
            publisherChmod($target);
280
281
            return $res;
282
        }
283
    }
284
    $res = is_dir($target);
285
286
    return $res;
287
}
288
289
/**
290
 * @credits Thanks to the NewBB2 Development Team
291
 * @param  string $target
292
 * @param  int    $mode
293
 * @return bool
294
 */
295
function publisherChmod($target, $mode = 0777)
296
{
297
    return @chmod($target, $mode);
298
}
299
300
/**
301
 * @param  bool $hasPath
302
 * @param  bool $item
303
 * @return string
304
 */
305
function publisherGetUploadDir($hasPath = true, $item = false)
306
{
307
    if ($item) {
308
        if ($item === 'root') {
309
            $item = '';
310
        } else {
311
            $item .= '/';
312
        }
313
    } else {
314
        $item = '';
315
    }
316
317
    if ($hasPath) {
318
        return PUBLISHER_UPLOAD_PATH . '/' . $item;
319
    } else {
320
        return PUBLISHER_UPLOAD_URL . '/' . $item;
321
    }
322
}
323
324
/**
325
 * @param  string $item
326
 * @param  bool   $hasPath
327
 * @return string
328
 */
329
function publisherGetImageDir($item = '', $hasPath = true)
330
{
331
    if ($item) {
332
        $item = "images/{$item}";
333
    } else {
334
        $item = 'images';
335
    }
336
337
    return publisherGetUploadDir($hasPath, $item);
338
}
339
340
/**
341
 * @param  array $errors
342
 * @return string
343
 */
344
function publisherFormatErrors($errors = array())
345
{
346
    $ret = '';
347
    foreach ($errors as $key => $value) {
348
        $ret .= '<br> - ' . $value;
349
    }
350
351
    return $ret;
352
}
353
354
/**
355
 * Checks if a user is admin of Publisher
356
 *
357
 * @return boolean
358
 */
359
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...
360
{
361
    $publisher = PublisherPublisher::getInstance();
362
363
    static $publisherIsAdmin;
364
365
    if (isset($publisherIsAdmin)) {
366
        return $publisherIsAdmin;
367
    }
368
369
    if (!$GLOBALS['xoopsUser']) {
370
        $publisherIsAdmin = false;
371
    } else {
372
        $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...
373
    }
374
375
    return $publisherIsAdmin;
376
}
377
378
/**
379
 * Check is current user is author of a given article
380
 *
381
 * @param  object $itemObj
382
 * @return bool
383
 */
384
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...
385
{
386
    return (is_object($GLOBALS['xoopsUser']) && is_object($itemObj) && ($GLOBALS['xoopsUser']->uid() == $itemObj->uid()));
387
}
388
389
/**
390
 * Check is current user is moderator of a given article
391
 *
392
 * @param  object $itemObj
393
 * @return bool
394
 */
395
function publisherUserIsModerator($itemObj)
396
{
397
    $publisher         = PublisherPublisher::getInstance();
398
    $categoriesGranted = $publisher->getHandler('permission')->getGrantedItems('category_moderation');
399
400
    return (is_object($itemObj) && in_array($itemObj->categoryid(), $categoriesGranted));
401
}
402
403
/**
404
 * Saves permissions for the selected category
405
 *
406
 * @param  array   $groups     : group with granted permission
407
 * @param  integer $categoryId : categoryid on which we are setting permissions
408
 * @param  string  $permName   : name of the permission
409
 * @return boolean : TRUE if the no errors occured
410
 */
411
function publisherSaveCategoryPermissions($groups, $categoryId, $permName)
412
{
413
    $publisher = PublisherPublisher::getInstance();
414
415
    $result = true;
416
417
    $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...
418
    $gpermHandler = xoops_getHandler('groupperm');
419
    // First, if the permissions are already there, delete them
420
    $gpermHandler->deleteByModule($moduleId, $permName, $categoryId);
421
422
    // Save the new permissions
423
    if (count($groups) > 0) {
424
        foreach ($groups as $groupId) {
425
            $gpermHandler->addRight($permName, $categoryId, $groupId, $moduleId);
426
        }
427
    }
428
429
    return $result;
430
}
431
432
/**
433
 * @param  string $tablename
434
 * @param  string $iconname
435
 * @param  string $tabletitle
436
 * @param  string $tabledsc
437
 * @param  bool   $open
438
 * @return void
439
 */
440
function publisherOpenCollapsableBar($tablename = '', $iconname = '', $tabletitle = '', $tabledsc = '', $open = true)
441
{
442
    $image   = 'open12.gif';
443
    $display = 'none';
444
    if ($open) {
445
        $image   = 'close12.gif';
446
        $display = 'block';
447
    }
448
449
    echo "<h3 style=\"color: #2F5376; font-weight: bold; font-size: 14px; margin: 6px 0 0 0; \"><a href='javascript:;' onclick=\"toggle('" . $tablename . "'); toggleIcon('" . $iconname . "')\">";
450
    echo "<img id='" . $iconname . "' src='" . PUBLISHER_URL . '/assets/images/links/' . $image . "' alt='' /></a>&nbsp;" . $tabletitle . '</h3>';
451
    echo "<div id='" . $tablename . "' style='display: " . $display . ";'>";
452
    if ($tabledsc != '') {
453
        echo "<span style=\"color: #567; margin: 3px 0 12px 0; font-size: small; display: block; \">" . $tabledsc . '</span>';
454
    }
455
}
456
457
/**
458
 * @param  string $name
459
 * @param  string $icon
460
 * @return void
461
 */
462
function publisherCloseCollapsableBar($name, $icon)
463
{
464
    echo '</div>';
465
466
    $urls = publisherGetCurrentUrls();
467
    $path = $urls['phpself'];
468
469
    $cookieName = $path . '_publisher_collaps_' . $name;
470
    $cookieName = str_replace('.', '_', $cookieName);
471
    $cookie     = publisherGetCookieVar($cookieName, '');
472
473
    if ($cookie === 'none') {
474
        echo '
475
        <script type="text/javascript"><!--
476
        toggle("' . $name . '"); toggleIcon("' . $icon . '");
477
        //-->
478
        </script>
479
        ';
480
    }
481
}
482
483
/**
484
 * @param  string $name
485
 * @param  string $value
486
 * @param  int    $time
487
 * @return void
488
 */
489
function publisherSetCookieVar($name, $value, $time = 0)
490
{
491
    if ($time == 0) {
492
        $time = time() + 3600 * 24 * 365;
493
    }
494
    setcookie($name, $value, $time, '/');
495
}
496
497
/**
498
 * @param  string $name
499
 * @param  string $default
500
 * @return string
501
 */
502
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...
503
{
504
    //    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...
505
    //        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...
506
    //    } 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...
507
    //        return $default;
508
    //    }
509
    return XoopsRequest::getString('name', $default, 'COOKIE');
510
}
511
512
/**
513
 * @return array
514
 */
515
function publisherGetCurrentUrls()
516
{
517
    $http = strpos(XOOPS_URL, 'https://') === false ? 'http://' : 'https://';
518
    //    $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...
519
    //    $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...
520
    //    $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...
521
    $phpself     = XoopsRequest::getString('PHP_SELF', '', 'SERVER');
522
    $httphost    = XoopsRequest::getString('HTTP_HOST', '', 'SERVER');
523
    $querystring = XoopsRequest::getString('QUERY_STRING', '', 'SERVER');
524
525
    if ($querystring != '') {
526
        $querystring = '?' . $querystring;
527
    }
528
529
    $currenturl = $http . $httphost . $phpself . $querystring;
530
531
    $urls                = array();
532
    $urls['http']        = $http;
533
    $urls['httphost']    = $httphost;
534
    $urls['phpself']     = $phpself;
535
    $urls['querystring'] = $querystring;
536
    $urls['full']        = $currenturl;
537
538
    return $urls;
539
}
540
541
/**
542
 * @return string
543
 */
544
function publisherGetCurrentPage()
545
{
546
    $urls = publisherGetCurrentUrls();
547
548
    return $urls['full'];
549
}
550
551
/**
552
 * @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...
553
 * @param  int                    $selectedid
554
 * @param  int                    $level
555
 * @param  string                 $ret
556
 * @return string
557
 */
558
function publisherAddCategoryOption(PublisherCategory $categoryObj, $selectedid = 0, $level = 0, $ret = '')
559
{
560
    $publisher = PublisherPublisher::getInstance();
561
562
    $spaces = '';
563
    for ($j = 0; $j < $level; ++$j) {
564
        $spaces .= '--';
565
    }
566
567
    $ret .= "<option value='" . $categoryObj->categoryid() . "'";
568
    if (is_array($selectedid) && in_array($categoryObj->categoryid(), $selectedid)) {
569
        $ret .= " selected='selected'";
570
    } elseif ($categoryObj->categoryid() == $selectedid) {
571
        $ret .= " selected='selected'";
572
    }
573
    $ret .= '>' . $spaces . $categoryObj->name() . "</option>\n";
574
575
    $subCategoriesObj = $publisher->getHandler('category')->getCategories(0, 0, $categoryObj->categoryid());
576
    if (count($subCategoriesObj) > 0) {
577
        ++$level;
578
        foreach ($subCategoriesObj as $catID => $subCategoryObj) {
579
            $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...
580
        }
581
    }
582
583
    return $ret;
584
}
585
586
/**
587
 * @param  int    $selectedid
588
 * @param  int    $parentcategory
589
 * @param  bool   $allCatOption
590
 * @param  string $selectname
591
 * @return string
592
 */
593
function publisherCreateCategorySelect($selectedid = 0, $parentcategory = 0, $allCatOption = true, $selectname = 'options[0]')
594
{
595
    $publisher = PublisherPublisher::getInstance();
596
597
    $selectedid = explode(',', $selectedid);
598
599
    $ret = "<select name='" . $selectname . "[]' multiple='multiple' size='10'>";
600
    if ($allCatOption) {
601
        $ret .= "<option value='0'";
602
        if (in_array(0, $selectedid)) {
603
            $ret .= " selected='selected'";
604
        }
605
        $ret .= '>' . _MB_PUBLISHER_ALLCAT . '</option>';
606
    }
607
608
    // Creating category objects
609
    $categoriesObj = $publisher->getHandler('category')->getCategories(0, 0, $parentcategory);
610
611 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...
612
        foreach ($categoriesObj as $catID => $categoryObj) {
613
            $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...
614
        }
615
    }
616
    $ret .= '</select>';
617
618
    return $ret;
619
}
620
621
/**
622
 * @param  int  $selectedid
623
 * @param  int  $parentcategory
624
 * @param  bool $allCatOption
625
 * @return string
626
 */
627
function publisherCreateCategoryOptions($selectedid = 0, $parentcategory = 0, $allCatOption = true)
628
{
629
    $publisher = PublisherPublisher::getInstance();
630
631
    $ret = '';
632
    if ($allCatOption) {
633
        $ret .= "<option value='0'";
634
        $ret .= '>' . _MB_PUBLISHER_ALLCAT . "</option>\n";
635
    }
636
637
    // Creating category objects
638
    $categoriesObj = $publisher->getHandler('category')->getCategories(0, 0, $parentcategory);
639 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...
640
        foreach ($categoriesObj as $catID => $categoryObj) {
641
            $ret .= publisherAddCategoryOption($categoryObj, $selectedid);
642
        }
643
    }
644
645
    return $ret;
646
}
647
648
/**
649
 * @param  array  $errArray
650
 * @param  string $reseturl
651
 * @return void
652
 */
653
function publisherRenderErrors(&$errArray, $reseturl = '')
654
{
655
    if (is_array($errArray) && count($errArray) > 0) {
656
        echo '<div id="readOnly" class="errorMsg" style="border:1px solid #D24D00; background:#FEFECC url(' .
657
             PUBLISHER_URL .
658
             '/assets/images/important-32.png) no-repeat 7px 50%;color:#333;padding-left:45px;">';
659
660
        echo '<h4 style="text-align:left;margin:0; padding-top:0;">' . _AM_PUBLISHER_MSG_SUBMISSION_ERR;
661
662
        if ($reseturl) {
663
            echo ' <a href="' . $reseturl . '">[' . _AM_PUBLISHER_TEXT_SESSION_RESET . ']</a>';
664
        }
665
666
        echo '</h4><ul>';
667
668
        foreach ($errArray as $key => $error) {
669
            if (is_array($error)) {
670
                foreach ($error as $err) {
671
                    echo '<li><a href="#' . $key . '" onclick="var e = xoopsGetElementById(\'' . $key . '\'); e.focus();">' . htmlspecialchars($err) . '</a></li>';
672
                }
673
            } else {
674
                echo '<li><a href="#' . $key . '" onclick="var e = xoopsGetElementById(\'' . $key . '\'); e.focus();">' . htmlspecialchars($error) . '</a></li>';
675
            }
676
        }
677
        echo '</ul></div><br>';
678
    }
679
}
680
681
/**
682
 * Generate publisher URL
683
 *
684
 * @param  string $page
685
 * @param  array  $vars
686
 * @param  bool   $encodeAmp
687
 * @return string
688
 *
689
 * @credit : xHelp module, developped by 3Dev
690
 */
691
function publisherMakeUri($page, $vars = array(), $encodeAmp = true)
692
{
693
    $joinStr = '';
694
695
    $amp = ($encodeAmp ? '&amp;' : '&');
696
697
    if (!count($vars)) {
698
        return $page;
699
    }
700
701
    $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...
702
    foreach ($vars as $key => $value) {
703
        $qs .= $joinStr . $key . '=' . $value;
704
        $joinStr = $amp;
705
    }
706
707
    return $page . '?' . $qs;
708
}
709
710
/**
711
 * @param  string $subject
712
 * @return string
713
 */
714
function publisherTellAFriend($subject = '')
715
{
716
    if (false !== strpos($subject, '%')) {
717
        $subject = rawurldecode($subject);
718
    }
719
720
    $targetUri = XOOPS_URL . XoopsRequest::getString('REQUEST_URI', '', 'SERVER');
721
722
    return XOOPS_URL . '/modules/tellafriend/index.php?target_uri=' . rawurlencode($targetUri) . '&amp;subject=' . rawurlencode($subject);
723
}
724
725
/**
726
 * @param  bool        $another
727
 * @param  bool        $withRedirect
728
 * @param              $itemObj
729
 * @return bool|string
730
 */
731
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...
732
{
733
    include_once PUBLISHER_ROOT_PATH . '/class/uploader.php';
734
735
    //    global $publisherIsAdmin;
736
    $publisher = PublisherPublisher::getInstance();
737
738
    $itemId  = XoopsRequest::getInt('itemid', 0, 'POST');
739
    $uid     = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->uid() : 0;
740
    $session = PublisherSession::getInstance();
741
    $session->set('publisher_file_filename', XoopsRequest::getString('item_file_name', '', 'POST'));
742
    $session->set('publisher_file_description', XoopsRequest::getString('item_file_description', '', 'POST'));
743
    $session->set('publisher_file_status', XoopsRequest::getInt('item_file_status', 1, 'POST'));
744
    $session->set('publisher_file_uid', $uid);
745
    $session->set('publisher_file_itemid', $itemId);
746
747
    if (!is_object($itemObj)) {
748
        $itemObj = $publisher->getHandler('item')->get($itemId);
749
    }
750
751
    $fileObj = $publisher->getHandler('file')->create();
752
    $fileObj->setVar('name', XoopsRequest::getString('item_file_name', '', 'POST'));
753
    $fileObj->setVar('description', XoopsRequest::getString('item_file_description', '', 'POST'));
754
    $fileObj->setVar('status', XoopsRequest::getInt('item_file_status', 1, 'POST'));
755
    $fileObj->setVar('uid', $uid);
756
    $fileObj->setVar('itemid', $itemObj->getVar('itemid'));
757
    $fileObj->setVar('datesub', time());
758
759
    // Get available mimetypes for file uploading
760
    $allowedMimetypes = $publisher->getHandler('mimetype')->getArrayByType();
761
    // TODO : display the available mimetypes to the user
762
    $errors = array();
763
    if ($publisher->getConfig('perm_upload') && is_uploaded_file($_FILES['item_upload_file']['tmp_name'])) {
764
        if (!$ret = $fileObj->checkUpload('item_upload_file', $allowedMimetypes, $errors)) {
765
            $errorstxt = implode('<br>', $errors);
766
767
            $message = sprintf(_CO_PUBLISHER_MESSAGE_FILE_ERROR, $errorstxt);
768
            if ($withRedirect) {
769
                redirect_header('file.php?op=mod&itemid=' . $itemId, 5, $message);
770
            } else {
771
                return $message;
772
            }
773
        }
774
    }
775
776
    // Storing the file
777
    if (!$fileObj->store($allowedMimetypes)) {
778
        //        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...
779
        //            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...
780
        //            exit;
781
        //        }
782
        try {
783
            if ($withRedirect) {
784
                throw new Exception(_CO_PUBLISHER_FILEUPLOAD_ERROR . publisherFormatErrors($fileObj->getErrors()));
785
            }
786
        } catch (Exception $e) {
787
            redirect_header('file.php?op=mod&itemid=' . $fileObj->itemid(), 3, _CO_PUBLISHER_FILEUPLOAD_ERROR . publisherFormatErrors($fileObj->getErrors()));
788
        }
789
        //    } 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...
790
        //        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...
791
    }
792
793
    if ($withRedirect) {
794
        $redirectPage = $another ? 'file.php' : 'item.php';
795
        redirect_header($redirectPage . '?op=mod&itemid=' . $fileObj->itemid(), 2, _CO_PUBLISHER_FILEUPLOAD_SUCCESS);
796
    } else {
797
        return true;
798
    }
799
800
    return null;
801
}
802
803
/**
804
 * @return string
805
 */
806
function publisherNewFeatureTag()
807
{
808
    $ret = '<span style="padding-right: 4px; font-weight: bold; color: red;">' . _CO_PUBLISHER_NEW_FEATURE . '</span>';
809
810
    return $ret;
811
}
812
813
/**
814
 * Smarty truncate_tagsafe modifier plugin
815
 *
816
 * Type:     modifier<br>
817
 * Name:     truncate_tagsafe<br>
818
 * Purpose:  Truncate a string to a certain length if necessary,
819
 *           optionally splitting in the middle of a word, and
820
 *           appending the $etc string or inserting $etc into the middle.
821
 *           Makes sure no tags are left half-open or half-closed
822
 *           (e.g. "Banana in a <a...")
823
 * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
824
 *           <amos dot robinson at gmail dot com>
825
 * @param string
826
 * @param integer
827
 * @param string
828
 * @param boolean
829
 * @param boolean
830
 * @return string
831
 */
832
function publisherTruncateTagSafe($string, $length = 80, $etc = '...', $breakWords = false)
833
{
834
    if ($length == 0) {
835
        return '';
836
    }
837
838
    if (strlen($string) > $length) {
839
        $length -= strlen($etc);
840
        if (!$breakWords) {
841
            $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length + 1));
842
            $string = preg_replace('/<[^>]*$/', '', $string);
843
            $string = publisherCloseTags($string);
844
        }
845
846
        return $string . $etc;
847
    } else {
848
        return $string;
849
    }
850
}
851
852
/**
853
 * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
854
 *           <amos dot robinson at gmail dot com>
855
 * @param  string $string
856
 * @return string
857
 */
858
function publisherCloseTags($string)
859
{
860
    // match opened tags
861
    if (preg_match_all('/<([a-z\:\-]+)[^\/]>/', $string, $startTags)) {
862
        $startTags = $startTags[1];
863
        // match closed tags
864
        if (preg_match_all('/<\/([a-z]+)>/', $string, $endTags)) {
865
            $completeTags = array();
866
            $endTags      = $endTags[1];
867
868
            foreach ($startTags as $key => $val) {
869
                $posb = array_search($val, $endTags);
870
                if (is_int($posb)) {
871
                    unset($endTags[$posb]);
872
                } else {
873
                    $completeTags[] = $val;
874
                }
875
            }
876
        } else {
877
            $completeTags = $startTags;
878
        }
879
880
        $completeTags = array_reverse($completeTags);
881
        $elementCount = count($completeTags);
882
        for ($i = 0; $i < $elementCount; ++$i) {
883
            $string .= '</' . $completeTags[$i] . '>';
884
        }
885
    }
886
887
    return $string;
888
}
889
890
/**
891
 * @param  int $itemId
892
 * @return string
893
 */
894
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...
895
{
896
    $publisher       = PublisherPublisher::getInstance();
897
    $ratingUnitWidth = 30;
898
    $units           = 5;
899
900
    $criteria   = new Criteria('itemid', $itemId);
901
    $ratingObjs = $publisher->getHandler('rating')->getObjects($criteria);
902
    unset($criteria);
903
904
    $uid           = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getVar('uid') : 0;
905
    $count         = count($ratingObjs);
906
    $currentRating = 0;
907
    $voted         = false;
908
    $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...
909
    $rating1       = $rating2 = $ratingWidth = 0;
910
911 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...
912
        $currentRating += $ratingObj->getVar('rate');
913
        if ($ratingObj->getVar('ip') == $ip || ($uid > 0 && $uid == $ratingObj->getVar('uid'))) {
914
            $voted = true;
915
        }
916
    }
917
918
    $tense = $count == 1 ? _MD_PUBLISHER_VOTE_VOTE : _MD_PUBLISHER_VOTE_VOTES; //plural form votes/vote
919
920
    // now draw the rating bar
921
    if ($count != 0) {
922
        $ratingWidth = number_format($currentRating / $count, 2) * $ratingUnitWidth;
923
        $rating1     = number_format($currentRating / $count, 1);
924
        $rating2     = number_format($currentRating / $count, 2);
925
    }
926
    $groups       = $GLOBALS['xoopsUser'] ? $GLOBALS['xoopsUser']->getGroups() : XOOPS_GROUP_ANONYMOUS;
927
    $gpermHandler = $publisher->getHandler('groupperm');
928
929
    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...
930
        $staticRater = array();
931
        $staticRater[] .= "\n" . '<div class="publisher_ratingblock">';
932
        $staticRater[] .= '<div id="unit_long' . $itemId . '">';
933
        $staticRater[] .= '<div id="unit_ul' . $itemId . '" class="publisher_unit-rating" style="width:' . $ratingUnitWidth * $units . 'px;">';
934
        $staticRater[] .= '<div class="publisher_current-rating" style="width:' . $ratingWidth . 'px;">' . _MD_PUBLISHER_VOTE_RATING . ' ' . $rating2 . '/' . $units . '</div>';
935
        $staticRater[] .= '</div>';
936
        $staticRater[] .= '<div class="publisher_static">' . _MD_PUBLISHER_VOTE_RATING . ': <strong> ' . $rating1 . '</strong>/' . $units . ' (' . $count . ' ' . $tense . ') <br><em>' . _MD_PUBLISHER_VOTE_DISABLE . '</em></div>';
937
        $staticRater[] .= '</div>';
938
        $staticRater[] .= '</div>' . "\n\n";
939
940
        return implode("\n", $staticRater);
941
    } else {
942
        $rater = '';
943
        $rater .= '<div class="publisher_ratingblock">';
944
        $rater .= '<div id="unit_long' . $itemId . '">';
945
        $rater .= '<div id="unit_ul' . $itemId . '" class="publisher_unit-rating" style="width:' . $ratingUnitWidth * $units . 'px;">';
946
        $rater .= '<div class="publisher_current-rating" style="width:' . $ratingWidth . 'px;">' . _MD_PUBLISHER_VOTE_RATING . ' ' . $rating2 . '/' . $units . '</div>';
947
948
        for ($ncount = 1; $ncount <= $units; ++$ncount) { // loop from 1 to the number of units
949
            if (!$voted) { // if the user hasn't yet voted, draw the voting stars
950
                $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>';
951
            }
952
        }
953
954
        $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...
955
        $rater .= '  </div>';
956
        $rater .= '  <div';
957
958
        if ($voted) {
959
            $rater .= ' class="publisher_voted"';
960
        }
961
962
        $rater .= '>' . _MD_PUBLISHER_VOTE_RATING . ': <strong> ' . $rating1 . '</strong>/' . $units . ' (' . $count . ' ' . $tense . ')';
963
        $rater .= '  </div>';
964
        $rater .= '</div>';
965
        $rater .= '</div>';
966
967
        return $rater;
968
    }
969
}
970
971
/**
972
 * @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...
973
 * @return array
974
 */
975
function publisherGetEditors($allowedEditors = null)
976
{
977
    $ret    = array();
978
    $nohtml = false;
979
    xoops_load('XoopsEditorHandler');
980
    $editorHandler = XoopsEditorHandler::getInstance();
981
    $editors       = $editorHandler->getList($nohtml);
982
    foreach ($editors as $name => $title) {
983
        $key = publisherStringToInt($name);
984
        if (is_array($allowedEditors)) {
985
            //for submit page
986
            if (in_array($key, $allowedEditors)) {
987
                $ret[] = $name;
988
            }
989
        } else {
990
            //for admin permissions page
991
            $ret[$key]['name']  = $name;
992
            $ret[$key]['title'] = $title;
993
        }
994
    }
995
996
    return $ret;
997
}
998
999
/**
1000
 * @param  string $string
1001
 * @param  int    $length
1002
 * @return int
1003
 */
1004
function publisherStringToInt($string = '', $length = 5)
1005
{
1006
    $final  = '';
1007
    $string = substr(md5($string), $length);
1008
    for ($i = 0; $i < $length; ++$i) {
1009
        $final .= (int)$string[$i];
1010
    }
1011
1012
    return (int)$final;
1013
}
1014
1015
/**
1016
 * @param  string $item
1017
 * @return string
1018
 */
1019
function publisherConvertCharset($item)
1020
{
1021
    if (_CHARSET !== 'windows-1256') {
1022
        return utf8_encode($item);
1023
    }
1024
1025
    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...
1026
        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...
1027
            $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...
1028
        }
1029
        $serialize = serialize($unserialize);
1030
1031
        return $serialize;
1032
    } else {
1033
        return @iconv('windows-1256', 'UTF-8', $item);
1034
    }
1035
}
1036