Completed
Branch master (a93e21)
by Michael
02:18
created

Utility::renderErrors()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 14
nc 7
nop 2
dl 0
loc 25
rs 6.7272
c 0
b 0
f 0
1
<?php namespace Xoopsmodules\publisher;
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 35 and the first side effect is on line 27.

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
 * PublisherUtil Class
14
 *
15
 * @copyright   XOOPS Project (https://xoops.org)
16
 * @license     http://www.fsf.org/copyleft/gpl.html GNU public license
17
 * @author      XOOPS Development Team
18
 * @package     Publisher
19
 * @since       1.03
20
 *
21
 */
22
23
use Xmf\Request;
24
use Xoopsmodules\publisher;
25
use Xoopsmodules\publisher\common;
26
27
require_once __DIR__ . '/common/VersionChecks.php';
28
require_once __DIR__ . '/common/ServerStats.php';
29
require_once __DIR__ . '/common/FilesManagement.php';
30
31
32
/**
33
 * Class Utility
34
 */
35
class Utility
36
{
37
    use common\VersionChecks; //checkVerXoops, checkVerPhp Traits
38
39
    use common\ServerStats; // getServerStats Trait
40
41
    use common\FilesManagement; // Files Management Trait
42
43
    //--------------- Custom module methods -----------------------------
44
45
    /**
46
     * Function responsible for checking if a directory exists, we can also write in and create an index.html file
47
     *
48
     * @param string $folder The full path of the directory to check
49
     *
50
     * @return void
51
     */
52
    public static function createFolder($folder)
53
    {
54
        try {
55
            if (!file_exists($folder)) {
56
                if (!mkdir($folder) && !is_dir($folder)) {
57
                    throw new \RuntimeException(sprintf('Unable to create the %s directory', $folder));
58
                } else {
59
                    file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
60
                }
61
            }
62
        } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The class Xoopsmodules\publisher\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
63
            echo 'Caught exception: ', $e->getMessage(), "\n", '<br>';
64
        }
65
    }
66
67
    /**
68
     * @param $file
69
     * @param $folder
70
     * @return bool
71
     */
72
    public static function copyFile($file, $folder)
73
    {
74
        return copy($file, $folder);
75
        //        try {
76
        //            if (!is_dir($folder)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
77
        //                throw new \RuntimeException(sprintf('Unable to copy file as: %s ', $folder));
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
78
        //            } 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...
79
        //                return copy($file, $folder);
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
80
        //            }
81
        //        } catch (Exception $e) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
82
        //            echo 'Caught exception: ', $e->getMessage(), "\n", "<br>";
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

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

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

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

Loading history...
83
        //        }
84
        //        return false;
85
    }
86
87
    /**
88
     * @param $src
89
     * @param $dst
90
     */
91
    public static function recurseCopy($src, $dst)
92
    {
93
        $dir = opendir($src);
94
        //    @mkdir($dst);
95
        while (false !== ($file = readdir($dir))) {
96
            if (('.' !== $file) && ('..' !== $file)) {
97
                if (is_dir($src . '/' . $file)) {
98
                    self::recurseCopy($src . '/' . $file, $dst . '/' . $file);
99
                } else {
100
                    copy($src . '/' . $file, $dst . '/' . $file);
101
                }
102
            }
103
        }
104
        closedir($dir);
105
    }
106
107
    // auto create folders----------------------------------------
108
    //TODO rename this function? And exclude image folder?
109
    public static function createDir()
110
    {
111
        // auto crate folders
112
        //        $thePath = static::getUploadDir();
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...
113
114 View Code Duplication
        if (static::getPathStatus('root', true) < 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...
115
            $thePath = static::getUploadDir();
116
            $res     = static::mkdir($thePath);
117
            $msg     = $res ? _AM_PUBLISHER_DIRCREATED : _AM_PUBLISHER_DIRNOTCREATED;
0 ignored issues
show
Unused Code introduced by
$msg 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...
118
        }
119
120 View Code Duplication
        if (static::getPathStatus('images', true) < 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...
121
            $thePath = static::getImageDir();
122
            $res     = static::mkdir($thePath);
123
124
            if ($res) {
125
                $source = PUBLISHER_ROOT_PATH . '/assets/images/blank.png';
126
                $dest   = $thePath . 'blank.png';
127
                static::copyr($source, $dest);
128
            }
129
            $msg = $res ? _AM_PUBLISHER_DIRCREATED : _AM_PUBLISHER_DIRNOTCREATED;
0 ignored issues
show
Unused Code introduced by
$msg 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...
130
        }
131
132 View Code Duplication
        if (static::getPathStatus('images/category', true) < 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...
133
            $thePath = static::getImageDir('category');
134
            $res     = static::mkdir($thePath);
135
136
            if ($res) {
137
                $source = PUBLISHER_ROOT_PATH . '/assets/images/blank.png';
138
                $dest   = $thePath . 'blank.png';
139
                static::copyr($source, $dest);
140
            }
141
            $msg = $res ? _AM_PUBLISHER_DIRCREATED : _AM_PUBLISHER_DIRNOTCREATED;
0 ignored issues
show
Unused Code introduced by
$msg 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...
142
        }
143
144 View Code Duplication
        if (static::getPathStatus('images/item', true) < 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...
145
            $thePath = static::getImageDir('item');
146
            $res     = static::mkdir($thePath);
147
148
            if ($res) {
149
                $source = PUBLISHER_ROOT_PATH . '/assets/images/blank.png';
150
                $dest   = $thePath . 'blank.png';
151
                static::copyr($source, $dest);
152
            }
153
            $msg = $res ? _AM_PUBLISHER_DIRCREATED : _AM_PUBLISHER_DIRNOTCREATED;
0 ignored issues
show
Unused Code introduced by
$msg 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...
154
        }
155
156 View Code Duplication
        if (static::getPathStatus('content', true) < 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...
157
            $thePath = static::getUploadDir(true, 'content');
158
            $res     = static::mkdir($thePath);
159
            $msg     = $res ? _AM_PUBLISHER_DIRCREATED : _AM_PUBLISHER_DIRNOTCREATED;
0 ignored issues
show
Unused Code introduced by
$msg 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...
160
        }
161
    }
162
163
    public static function buildTableItemTitleRow()
164
    {
165
        echo "<table width='100%' cellspacing='1' cellpadding='3' border='0' class='outer'>";
166
        echo '<tr>';
167
        echo "<th width='40px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_ITEMID . '</strong></td>';
168
        echo "<th width='100px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_ITEMCAT . '</strong></td>';
169
        echo "<th class='bg3' align='center'><strong>" . _AM_PUBLISHER_TITLE . '</strong></td>';
170
        echo "<th width='100px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_CREATED . '</strong></td>';
171
172
        echo "<th width='50px' class='bg3' align='center'><strong>" . _CO_PUBLISHER_WEIGHT . '</strong></td>';
173
        echo "<th width='50px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_HITS . '</strong></td>';
174
        echo "<th width='60px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_RATE . '</strong></td>';
175
        echo "<th width='50px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_VOTES . '</strong></td>';
176
        echo "<th width='60px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_COMMENTS_COUNT . '</strong></td>';
177
178
        echo "<th width='90px' class='bg3' align='center'><strong>" . _CO_PUBLISHER_STATUS . '</strong></td>';
179
        echo "<th width='90px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_ACTION . '</strong></td>';
180
        echo '</tr>';
181
    }
182
183
    /**
184
     * @param \PublisherCategory $categoryObj
185
     * @param int               $level
186
     */
187
    public static function displayCategory(\PublisherCategory $categoryObj, $level = 0)
188
    {
189
        $helper = publisher\Helper::getInstance();
190
191
        $description = $categoryObj->description();
192
        if (!XOOPS_USE_MULTIBYTES) {
193
            if (strlen($description) >= 100) {
194
                $description = substr($description, 0, 100 - 1) . '...';
0 ignored issues
show
Unused Code introduced by
$description 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...
195
            }
196
        }
197
        $modify = "<a href='category.php?op=mod&amp;categoryid=" . $categoryObj->categoryid() . '&amp;parentid=' . $categoryObj->parentid() . "'><img src='" . PUBLISHER_URL . "/assets/images/links/edit.gif' title='" . _AM_PUBLISHER_EDITCOL . "' alt='" . _AM_PUBLISHER_EDITCOL . "'></a>";
198
        $delete = "<a href='category.php?op=del&amp;categoryid=" . $categoryObj->categoryid() . "'><img src='" . PUBLISHER_URL . "/assets/images/links/delete.png' title='" . _AM_PUBLISHER_DELETECOL . "' alt='" . _AM_PUBLISHER_DELETECOL . "'></a>";
199
200
        $spaces = '';
201
        for ($j = 0; $j < $level; ++$j) {
202
            $spaces .= '&nbsp;&nbsp;&nbsp;';
203
        }
204
205
        echo '<tr>';
206
        echo "<td class='even' align='center'>" . $categoryObj->categoryid() . '</td>';
207
        echo "<td class='even' align='left'>" . $spaces . "<a href='" . PUBLISHER_URL . '/category.php?categoryid=' . $categoryObj->categoryid() . "'><img src='" . PUBLISHER_URL . "/assets/images/links/subcat.gif' alt=''>&nbsp;" . $categoryObj->name() . '</a></td>';
208
        echo "<td class='even' align='center'>" . $categoryObj->weight() . '</td>';
209
        echo "<td class='even' align='center'> $modify $delete </td>";
210
        echo '</tr>';
211
        $subCategoriesObj = $helper->getHandler('category')->getCategories(0, 0, $categoryObj->categoryid());
212
        if (count($subCategoriesObj) > 0) {
213
            ++$level;
214
            foreach ($subCategoriesObj as $key => $thiscat) {
215
                self::displayCategory($thiscat, $level);
216
            }
217
            unset($key, $thiscat);
218
        }
219
        //        unset($categoryObj);
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% 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...
220
    }
221
222
    /**
223
     * @param bool $showmenu
224
     * @param int  $categoryId
225
     * @param int  $nbSubCats
226
     * @param null $categoryObj
227
     */
228
    public static function editCategory($showmenu = false, $categoryId = 0, $nbSubCats = 4, $categoryObj = null)
229
    {
230
        $helper = publisher\Helper::getInstance();
231
232
        // if there is a parameter, and the id exists, retrieve data: we're editing a category
233
        /* @var  $categoryObj PublisherCategory */
234
        if (0 != $categoryId) {
235
            // Creating the category object for the selected category
236
            $categoryObj = $helper->getHandler('category')->get($categoryId);
237
            if ($categoryObj->notLoaded()) {
238
                redirect_header('category.php', 1, _AM_PUBLISHER_NOCOLTOEDIT);
239
                //            exit();
240
            }
241
        } else {
242
            if (!$categoryObj) {
243
                $categoryObj = $helper->getHandler('category')->create();
244
            }
245
        }
246
247
        if (0 != $categoryId) {
248
            echo "<br>\n";
249
            static::openCollapsableBar('edittable', 'edittableicon', _AM_PUBLISHER_EDITCOL, _AM_PUBLISHER_CATEGORY_EDIT_INFO);
250
        } else {
251
            static::openCollapsableBar('createtable', 'createtableicon', _AM_PUBLISHER_CATEGORY_CREATE, _AM_PUBLISHER_CATEGORY_CREATE_INFO);
252
        }
253
254
        $sform = $categoryObj->getForm($nbSubCats);
255
        $sform->display();
256
257
        if (!$categoryId) {
258
            static::closeCollapsableBar('createtable', 'createtableicon');
259
        } else {
260
            static::closeCollapsableBar('edittable', 'edittableicon');
261
        }
262
263
        //Added by fx2024
264
        if ($categoryId) {
265
            $selCat = $categoryId;
266
267
            static::openCollapsableBar('subcatstable', 'subcatsicon', _AM_PUBLISHER_SUBCAT_CAT, _AM_PUBLISHER_SUBCAT_CAT_DSC);
268
            // Get the total number of sub-categories
269
            $categoriesObj = $helper->getHandler('category')->get($selCat);
270
            $totalsubs     = $helper->getHandler('category')->getCategoriesCount($selCat);
271
            // creating the categories objects that are published
272
            $subcatsObj    = $helper->getHandler('category')->getCategories(0, 0, $categoriesObj->categoryid());
273
            $totalSCOnPage = count($subcatsObj);
0 ignored issues
show
Unused Code introduced by
$totalSCOnPage 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...
274
            echo "<table width='100%' cellspacing=1 cellpadding=3 border=0 class = outer>";
275
            echo '<tr>';
276
            echo "<td width='60' class='bg3' align='left'><strong>" . _AM_PUBLISHER_CATID . '</strong></td>';
277
            echo "<td width='20%' class='bg3' align='left'><strong>" . _AM_PUBLISHER_CATCOLNAME . '</strong></td>';
278
            echo "<td class='bg3' align='left'><strong>" . _AM_PUBLISHER_SUBDESCRIPT . '</strong></td>';
279
            echo "<td width='60' class='bg3' align='right'><strong>" . _AM_PUBLISHER_ACTION . '</strong></td>';
280
            echo '</tr>';
281
            if ($totalsubs > 0) {
282
                foreach ($subcatsObj as $subcat) {
283
                    $modify = "<a href='category.php?op=mod&amp;categoryid=" . $subcat->categoryid() . "'><img src='" . XOOPS_URL . '/modules/' . $helper->getModule()->dirname() . "/assets/images/links/edit.gif' title='" . _AM_PUBLISHER_MODIFY . "' alt='" . _AM_PUBLISHER_MODIFY . "'></a>";
284
                    $delete = "<a href='category.php?op=del&amp;categoryid=" . $subcat->categoryid() . "'><img src='" . XOOPS_URL . '/modules/' . $helper->getModule()->dirname() . "/assets/images/links/delete.png' title='" . _AM_PUBLISHER_DELETE . "' alt='" . _AM_PUBLISHER_DELETE . "'></a>";
285
                    echo '<tr>';
286
                    echo "<td class='head' align='left'>" . $subcat->categoryid() . '</td>';
287
                    echo "<td class='even' align='left'><a href='" . XOOPS_URL . '/modules/' . $helper->getModule()->dirname() . '/category.php?categoryid=' . $subcat->categoryid() . '&amp;parentid=' . $subcat->parentid() . "'>" . $subcat->name() . '</a></td>';
288
                    echo "<td class='even' align='left'>" . $subcat->description() . '</td>';
289
                    echo "<td class='even' align='right'> {$modify} {$delete} </td>";
290
                    echo '</tr>';
291
                }
292
                //                unset($subcat);
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% 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...
293
            } else {
294
                echo '<tr>';
295
                echo "<td class='head' align='center' colspan= '7'>" . _AM_PUBLISHER_NOSUBCAT . '</td>';
296
                echo '</tr>';
297
            }
298
            echo "</table>\n";
299
            echo "<br>\n";
300
            static::closeCollapsableBar('subcatstable', 'subcatsicon');
301
302
            static::openCollapsableBar('bottomtable', 'bottomtableicon', _AM_PUBLISHER_CAT_ITEMS, _AM_PUBLISHER_CAT_ITEMS_DSC);
303
            $startitem = Request::getInt('startitem');
304
            // Get the total number of published ITEMS
305
            $totalitems = $helper->getHandler('item')->getItemsCount($selCat, [PublisherConstants::PUBLISHER_STATUS_PUBLISHED]);
306
            // creating the items objects that are published
307
            $itemsObj         = $helper->getHandler('item')->getAllPublished($helper->getConfig('idxcat_perpage'), $startitem, $selCat);
308
            $totalitemsOnPage = count($itemsObj);
309
            $allcats          = $helper->getHandler('category')->getObjects(null, true);
310
            echo "<table width='100%' cellspacing=1 cellpadding=3 border=0 class = outer>";
311
            echo '<tr>';
312
            echo "<td width='40' class='bg3' align='center'><strong>" . _AM_PUBLISHER_ITEMID . '</strong></td>';
313
            echo "<td width='20%' class='bg3' align='left'><strong>" . _AM_PUBLISHER_ITEMCOLNAME . '</strong></td>';
314
            echo "<td class='bg3' align='left'><strong>" . _AM_PUBLISHER_ITEMDESC . '</strong></td>';
315
            echo "<td width='90' class='bg3' align='center'><strong>" . _AM_PUBLISHER_CREATED . '</strong></td>';
316
            echo "<td width='60' class='bg3' align='center'><strong>" . _AM_PUBLISHER_ACTION . '</strong></td>';
317
            echo '</tr>';
318
            if ($totalitems > 0) {
319
                for ($i = 0; $i < $totalitemsOnPage; ++$i) {
320
                    $categoryObj = $allcats[$itemsObj[$i]->categoryid()];
321
                    $modify      = "<a href='item.php?op=mod&amp;itemid=" . $itemsObj[$i]->itemid() . "'><img src='" . XOOPS_URL . '/modules/' . $helper->getModule()->dirname() . "/assets/images/links/edit.gif' title='" . _AM_PUBLISHER_EDITITEM . "' alt='" . _AM_PUBLISHER_EDITITEM . "'></a>";
322
                    $delete      = "<a href='item.php?op=del&amp;itemid="
323
                                   . $itemsObj[$i]->itemid()
324
                                   . "'><img src='"
325
                                   . XOOPS_URL
326
                                   . '/modules/'
327
                                   . $helper->getModule()->dirname()
328
                                   . "/assets/images/links/delete.png' title='"
329
                                   . _AM_PUBLISHER_DELETEITEM
330
                                   . "' alt='"
331
                                   . _AM_PUBLISHER_DELETEITEM
332
                                   . "'></a>";
333
                    echo '<tr>';
334
                    echo "<td class='head' align='center'>" . $itemsObj[$i]->itemid() . '</td>';
335
                    echo "<td class='even' align='left'>" . $categoryObj->name() . '</td>';
336
                    echo "<td class='even' align='left'>" . $itemsObj[$i]->getitemLink() . '</td>';
337
                    echo "<td class='even' align='center'>" . $itemsObj[$i]->getDatesub('s') . '</td>';
338
                    echo "<td class='even' align='center'> $modify $delete </td>";
339
                    echo '</tr>';
340
                }
341
            } else {
342
                $itemid = -1;
0 ignored issues
show
Unused Code introduced by
$itemid 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...
343
                echo '<tr>';
344
                echo "<td class='head' align='center' colspan= '7'>" . _AM_PUBLISHER_NOITEMS . '</td>';
345
                echo '</tr>';
346
            }
347
            echo "</table>\n";
348
            echo "<br>\n";
349
            $parentid         = Request::getInt('parentid', 0, 'GET');
350
            $pagenavExtraArgs = "op=mod&categoryid=$selCat&parentid=$parentid";
351
            xoops_load('XoopsPageNav');
352
            $pagenav = new XoopsPageNav($totalitems, $helper->getConfig('idxcat_perpage'), $startitem, 'startitem', $pagenavExtraArgs);
353
            echo '<div style="text-align:right;">' . $pagenav->renderNav() . '</div>';
354
            echo "<input type='button' name='button' onclick=\"location='item.php?op=mod&categoryid=" . $selCat . "'\" value='" . _AM_PUBLISHER_CREATEITEM . "'>&nbsp;&nbsp;";
355
            echo '</div>';
356
        }
357
        //end of fx2024 code
358
    }
359
360
361
    //======================== FUNCTIONS =================================
362
363
    /**
364
     * Includes scripts in HTML header
365
     *
366
     * @return void
367
     */
368
    public static function cpHeader()
369
    {
370
        xoops_cp_header();
371
372
        //cannot use xoTheme, some conflit with admin gui
373
        echo '<link type="text/css" href="' . XOOPS_URL . '/modules/system/css/ui/' . xoops_getModuleOption('jquery_theme', 'system') . '/ui.all.css" rel="stylesheet">
374
    <link type="text/css" href="' . PUBLISHER_URL . '/assets/css/publisher.css" rel="stylesheet">
375
    <script type="text/javascript" src="' . PUBLISHER_URL . '/assets/js/funcs.js"></script>
376
    <script type="text/javascript" src="' . PUBLISHER_URL . '/assets/js/cookies.js"></script>
377
    <script type="text/javascript" src="' . XOOPS_URL . '/browse.php?Frameworks/jquery/jquery.js"></script>
378
    <!-- <script type="text/javascript" src="' . XOOPS_URL . '/browse.php?Frameworks/jquery/jquery-migrate-1.2.1.js"></script> -->
379
    <script type="text/javascript" src="' . XOOPS_URL . '/browse.php?Frameworks/jquery/plugins/jquery.ui.js"></script>
380
    <script type="text/javascript" src="' . PUBLISHER_URL . '/assets/js/ajaxupload.3.9.js"></script>
381
    <script type="text/javascript" src="' . PUBLISHER_URL . '/assets/js/publisher.js"></script>
382
    ';
383
    }
384
385
    /**
386
     * Default sorting for a given order
387
     *
388
     * @param  string $sort
389
     * @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...
390
     */
391
    public static function getOrderBy($sort)
392
    {
393
        if ('datesub' === $sort) {
394
            return 'DESC';
395
        } elseif ('counter' === $sort) {
396
            return 'DESC';
397
        } elseif ('weight' === $sort) {
398
            return 'ASC';
399
        } elseif ('votes' === $sort) {
400
            return 'DESC';
401
        } elseif ('rating' === $sort) {
402
            return 'DESC';
403
        } elseif ('comments' === $sort) {
404
            return 'DESC';
405
        }
406
407
        return null;
408
    }
409
410
    /**
411
     * @credits Thanks to Mithandir
412
     * @param  string $str
413
     * @param  int    $start
414
     * @param  int    $length
415
     * @param  string $trimMarker
416
     * @return string
417
     */
418
    public static function substr($str, $start, $length, $trimMarker = '...')
419
    {
420
        // if the string is empty, let's get out ;-)
421
        if ('' == $str) {
422
            return $str;
423
        }
424
425
        // reverse a string that is shortened with '' as trimmarker
426
        $reversedString = strrev(xoops_substr($str, $start, $length, ''));
427
428
        // find first space in reversed string
429
        $positionOfSpace = strpos($reversedString, ' ', 0);
430
431
        // truncate the original string to a length of $length
432
        // minus the position of the last space
433
        // plus the length of the $trimMarker
434
        $truncatedString = xoops_substr($str, $start, $length - $positionOfSpace + strlen($trimMarker), $trimMarker);
435
436
        return $truncatedString;
437
    }
438
439
    /**
440
     * @param  string $document
441
     * @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...
442
     */
443 View Code Duplication
    public static function html2text($document)
444
    {
445
        // PHP Manual:: function preg_replace
446
        // $document should contain an HTML document.
447
        // This will remove HTML tags, javascript sections
448
        // and white space. It will also convert some
449
        // common HTML entities to their text equivalent.
450
        // Credits : newbb2
451
        $search = [
452
            "'<script[^>]*?>.*?</script>'si", // Strip out javascript
453
            "'<img.*?>'si", // Strip out img tags
454
            "'<[\/\!]*?[^<>]*?>'si", // Strip out HTML tags
455
            "'([\r\n])[\s]+'", // Strip out white space
456
            "'&(quot|#34);'i", // Replace HTML entities
457
            "'&(amp|#38);'i",
458
            "'&(lt|#60);'i",
459
            "'&(gt|#62);'i",
460
            "'&(nbsp|#160);'i",
461
            "'&(iexcl|#161);'i",
462
            "'&(cent|#162);'i",
463
            "'&(pound|#163);'i",
464
            "'&(copy|#169);'i"
465
        ]; // evaluate as php
466
467
        $replace = [
468
            '',
469
            '',
470
            '',
471
            "\\1",
472
            '"',
473
            '&',
474
            '<',
475
            '>',
476
            ' ',
477
            chr(161),
478
            chr(162),
479
            chr(163),
480
            chr(169)
481
        ];
482
483
        $text = preg_replace($search, $replace, $document);
484
485
        preg_replace_callback('/&#(\d+);/', function ($matches) {
486
            return chr($matches[1]);
487
        }, $document);
488
489
        return $text;
490
        //<?php
491
    }
492
493
    /**
494
     * @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...
495
     */
496
    public static function getAllowedImagesTypes()
497
    {
498
        return ['jpg/jpeg', 'image/bmp', 'image/gif', 'image/jpeg', 'image/jpg', 'image/x-png', 'image/png', 'image/pjpeg'];
499
    }
500
501
    /**
502
     * @param  bool $withLink
503
     * @return string
504
     */
505
    public static function moduleHome($withLink = true)
506
    {
507
        $helper = publisher\Helper::getInstance();
508
509
        if (!$helper->getConfig('format_breadcrumb_modname')) {
510
            return '';
511
        }
512
513
        if (!$withLink) {
514
            return $helper->getModule()->getVar('name');
515
        } else {
516
            return '<a href="' . PUBLISHER_URL . '/">' . $helper->getModule()->getVar('name') . '</a>';
517
        }
518
    }
519
520
    /**
521
     * Copy a file, or a folder and its contents
522
     *
523
     * @author      Aidan Lister <[email protected]>
524
     * @version     1.0.0
525
     * @param  string $source The source
526
     * @param  string $dest   The destination
527
     * @return bool   Returns true on success, false on failure
528
     */
529
    public static function copyr($source, $dest)
530
    {
531
        // Simple copy for a file
532
        if (is_file($source)) {
533
            return copy($source, $dest);
534
        }
535
536
        // Make destination directory
537
        if (!is_dir($dest)) {
538
            mkdir($dest);
539
        }
540
541
        // Loop through the folder
542
        $dir = dir($source);
543
        while (false !== $entry = $dir->read()) {
544
            // Skip pointers
545
            if ('.' === $entry || '..' === $entry) {
546
                continue;
547
            }
548
549
            // Deep copy directories
550
            if (("$source/$entry" !== $dest) && is_dir("$source/$entry")) {
551
                static::copyr("$source/$entry", "$dest/$entry");
552
            } else {
553
                copy("$source/$entry", "$dest/$entry");
554
            }
555
        }
556
557
        // Clean up
558
        $dir->close();
559
560
        return true;
561
    }
562
563
    /**
564
     * .* @credits Thanks to the NewBB2 Development Team
565
     * @param  string $item
566
     * @param  bool   $getStatus
567
     * @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...
568
     */
569
    public static function &getPathStatus($item, $getStatus = false)
570
    {
571
        $path = '';
572
        if ('root' !== $item) {
573
            $path = $item;
574
        }
575
576
        $thePath = static::getUploadDir(true, $path);
577
578
        if (empty($thePath)) {
579
            return false;
580
        }
581
        if (is_writable($thePath)) {
582
            $pathCheckResult = 1;
583
            $pathStatus      = _AM_PUBLISHER_AVAILABLE;
584
        } elseif (!@is_dir($thePath)) {
585
            $pathCheckResult = -1;
586
            $pathStatus      = _AM_PUBLISHER_NOTAVAILABLE . " <a href='" . PUBLISHER_ADMIN_URL . "/index.php?op=createdir&amp;path={$item}'>" . _AM_PUBLISHER_CREATETHEDIR . '</a>';
587
        } else {
588
            $pathCheckResult = -2;
589
            $pathStatus      = _AM_PUBLISHER_NOTWRITABLE . " <a href='" . PUBLISHER_ADMIN_URL . "/index.php?op=setperm&amp;path={$item}'>" . _AM_PUBLISHER_SETMPERM . '</a>';
590
        }
591
        if (!$getStatus) {
592
            return $pathStatus;
593
        } else {
594
            return $pathCheckResult;
595
        }
596
    }
597
598
    /**
599
     * @credits Thanks to the NewBB2 Development Team
600
     * @param  string $target
601
     * @return bool
602
     */
603
    public static function mkdir($target)
604
    {
605
        // http://www.php.net/manual/en/function.mkdir.php
606
        // saint at corenova.com
607
        // bart at cdasites dot com
608
        if (empty($target) || is_dir($target)) {
609
            return true; // best case check first
610
        }
611
612
        if (file_exists($target) && !is_dir($target)) {
613
            return false;
614
        }
615
616
        if (static::mkdir(substr($target, 0, strrpos($target, '/')))) {
617
            if (!file_exists($target)) {
618
                $res = mkdir($target, 0777); // crawl back up & create dir tree
619
                static::chmod($target);
620
621
                return $res;
622
            }
623
        }
624
        $res = is_dir($target);
625
626
        return $res;
627
    }
628
629
    /**
630
     * @credits Thanks to the NewBB2 Development Team
631
     * @param  string $target
632
     * @param  int    $mode
633
     * @return bool
634
     */
635
    public static function chmod($target, $mode = 0777)
636
    {
637
        return @chmod($target, $mode);
638
    }
639
640
    /**
641
     * @param  bool   $hasPath
642
     * @param  string $item
643
     * @return string
644
     */
645
    public static function getUploadDir($hasPath = true, $item = '')
646
    {
647
        if ('' !== $item) {
648
            if ('root' === $item) {
649
                $item = '';
650
            } else {
651
                $item .= '/';
652
            }
653
        }
654
655
        if ($hasPath) {
656
            return PUBLISHER_UPLOAD_PATH . '/' . $item;
657
        } else {
658
            return PUBLISHER_UPLOAD_URL . '/' . $item;
659
        }
660
    }
661
662
    /**
663
     * @param  string $item
664
     * @param  bool   $hasPath
665
     * @return string
666
     */
667
    public static function getImageDir($item = '', $hasPath = true)
668
    {
669
        if ($item) {
670
            $item = "images/{$item}";
671
        } else {
672
            $item = 'images';
673
        }
674
675
        return static::getUploadDir($hasPath, $item);
676
    }
677
678
    /**
679
     * @param  array $errors
680
     * @return string
681
     */
682
    public static function formatErrors($errors = [])
683
    {
684
        $ret = '';
685
        foreach ($errors as $key => $value) {
686
            $ret .= '<br> - ' . $value;
687
        }
688
689
        return $ret;
690
    }
691
692
    /**
693
     * Checks if a user is admin of Publisher
694
     *
695
     * @return boolean
696
     */
697
    public static function userIsAdmin()
0 ignored issues
show
Coding Style introduced by
userIsAdmin 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...
698
    {
699
        $helper = publisher\Helper::getInstance();
700
701
        static $publisherIsAdmin;
702
703
        if (isset($publisherIsAdmin)) {
704
            return $publisherIsAdmin;
705
        }
706
707
        if (!$GLOBALS['xoopsUser']) {
708
            $publisherIsAdmin = false;
709
        } else {
710
            $publisherIsAdmin = $GLOBALS['xoopsUser']->isAdmin($helper->getModule()->getVar('mid'));
711
        }
712
713
        return $publisherIsAdmin;
714
    }
715
716
    /**
717
     * Check is current user is author of a given article
718
     *
719
     * @param  XoopsObject $itemObj
720
     * @return bool
721
     */
722
    public static function userIsAuthor($itemObj)
0 ignored issues
show
Coding Style introduced by
userIsAuthor 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...
723
    {
724
        return (is_object($GLOBALS['xoopsUser']) && is_object($itemObj) && ($GLOBALS['xoopsUser']->uid() == $itemObj->uid()));
725
    }
726
727
    /**
728
     * Check is current user is moderator of a given article
729
     *
730
     * @param  XoopsObject $itemObj
731
     * @return bool
732
     */
733
    public static function userIsModerator($itemObj)
734
    {
735
        $helper         = publisher\Helper::getInstance();
736
        $categoriesGranted = $helper->getHandler('permission')->getGrantedItems('category_moderation');
737
738
        return (is_object($itemObj) && in_array($itemObj->categoryid(), $categoriesGranted));
739
    }
740
741
    /**
742
     * Saves permissions for the selected category
743
     *
744
     * @param  array   $groups     : group with granted permission
745
     * @param  integer $categoryId : categoryid on which we are setting permissions
746
     * @param  string  $permName   : name of the permission
747
     * @return boolean : TRUE if the no errors occured
748
     */
749
    public static function saveCategoryPermissions($groups, $categoryId, $permName)
750
    {
751
        $helper = publisher\Helper::getInstance();
752
753
        $result = true;
754
755
        $moduleId = $helper->getModule()->getVar('mid');
756
        /* @var  $gpermHandler XoopsGroupPermHandler */
757
        $gpermHandler = xoops_getHandler('groupperm');
758
        // First, if the permissions are already there, delete them
759
        $gpermHandler->deleteByModule($moduleId, $permName, $categoryId);
760
761
        // Save the new permissions
762
        if (count($groups) > 0) {
763
            foreach ($groups as $groupId) {
764
                $gpermHandler->addRight($permName, $categoryId, $groupId, $moduleId);
765
            }
766
        }
767
768
        return $result;
769
    }
770
771
    /**
772
     * @param  string $tablename
773
     * @param  string $iconname
774
     * @param  string $tabletitle
775
     * @param  string $tabledsc
776
     * @param  bool   $open
777
     * @return void
778
     */
779
    public static function openCollapsableBar($tablename = '', $iconname = '', $tabletitle = '', $tabledsc = '', $open = true)
780
    {
781
        $image   = 'open12.gif';
782
        $display = 'none';
783
        if ($open) {
784
            $image   = 'close12.gif';
785
            $display = 'block';
786
        }
787
788
        echo "<h3 style=\"color: #2F5376; font-weight: bold; font-size: 14px; margin: 6px 0 0 0; \"><a href='javascript:;' onclick=\"toggle('" . $tablename . "'); toggleIcon('" . $iconname . "')\">";
789
        echo "<img id='" . $iconname . "' src='" . PUBLISHER_URL . '/assets/images/links/' . $image . "' alt=''></a>&nbsp;" . $tabletitle . '</h3>';
790
        echo "<div id='" . $tablename . "' style='display: " . $display . ";'>";
791
        if ('' != $tabledsc) {
792
            echo '<span style="color: #567; margin: 3px 0 12px 0; font-size: small; display: block; ">' . $tabledsc . '</span>';
793
        }
794
    }
795
796
    /**
797
     * @param  string $name
798
     * @param  string $icon
799
     * @return void
800
     */
801
    public static function closeCollapsableBar($name, $icon)
802
    {
803
        echo '</div>';
804
805
        $urls = static::getCurrentUrls();
806
        $path = $urls['phpself'];
807
808
        $cookieName = $path . '_publisher_collaps_' . $name;
809
        $cookieName = str_replace('.', '_', $cookieName);
810
        $cookie     = static::getCookieVar($cookieName, '');
811
812
        if ('none' === $cookie) {
813
            echo '
814
        <script type="text/javascript"><!--
815
        toggle("' . $name . '"); toggleIcon("' . $icon . '");
816
        //-->
817
        </script>
818
        ';
819
        }
820
    }
821
822
    /**
823
     * @param  string $name
824
     * @param  string $value
825
     * @param  int    $time
826
     * @return void
827
     */
828
    public static function setCookieVar($name, $value, $time = 0)
829
    {
830
        if (0 == $time) {
831
            $time = time() + 3600 * 24 * 365;
832
        }
833
        setcookie($name, $value, $time, '/');
834
    }
835
836
    /**
837
     * @param  string $name
838
     * @param  string $default
839
     * @return string
840
     */
841
    public static function getCookieVar($name, $default = '')
842
    {
843
        //    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...
844
        //        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...
845
        //    } 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...
846
        //        return $default;
847
        //    }
848
        return Request::getString('name', $default, 'COOKIE');
849
    }
850
851
    /**
852
     * @return array
853
     */
854
    public static function getCurrentUrls()
855
    {
856
        $http = false === strpos(XOOPS_URL, 'https://') ? 'http://' : 'https://';
857
        //    $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...
858
        //    $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...
859
        //    $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...
860
        $phpself     = Request::getString('PHP_SELF', '', 'SERVER');
861
        $httphost    = Request::getString('HTTP_HOST', '', 'SERVER');
862
        $querystring = Request::getString('QUERY_STRING', '', 'SERVER');
863
864
        if ('' != $querystring) {
865
            $querystring = '?' . $querystring;
866
        }
867
868
        $currenturl = $http . $httphost . $phpself . $querystring;
869
870
        $urls                = [];
871
        $urls['http']        = $http;
872
        $urls['httphost']    = $httphost;
873
        $urls['phpself']     = $phpself;
874
        $urls['querystring'] = $querystring;
875
        $urls['full']        = $currenturl;
876
877
        return $urls;
878
    }
879
880
    /**
881
     * @return string
882
     */
883
    public static function getCurrentPage()
884
    {
885
        $urls = static::getCurrentUrls();
886
887
        return $urls['full'];
888
    }
889
890
    /**
891
     * @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...
892
     * @param  int|array              $selectedid
0 ignored issues
show
Documentation introduced by
Consider making the type for parameter $selectedid a bit more specific; maybe use integer.
Loading history...
893
     * @param  int                    $level
894
     * @param  string                 $ret
895
     * @return string
896
     */
897
    public static function addCategoryOption(\PublisherCategory $categoryObj, $selectedid = 0, $level = 0, $ret = '')
898
    {
899
        $helper = publisher\Helper::getInstance();
900
901
        $spaces = '';
902
        for ($j = 0; $j < $level; ++$j) {
903
            $spaces .= '--';
904
        }
905
906
        $ret .= "<option value='" . $categoryObj->categoryid() . "'";
907
        if (is_array($selectedid) && in_array($categoryObj->categoryid(), $selectedid)) {
908
            $ret .= ' selected';
909
        } elseif ($categoryObj->categoryid() == $selectedid) {
910
            $ret .= ' selected';
911
        }
912
        $ret .= '>' . $spaces . $categoryObj->name() . "</option>\n";
913
914
        $subCategoriesObj = $helper->getHandler('category')->getCategories(0, 0, $categoryObj->categoryid());
915
        if (count($subCategoriesObj) > 0) {
916
            ++$level;
917
            foreach ($subCategoriesObj as $catID => $subCategoryObj) {
918
                $ret .= static::addCategoryOption($subCategoryObj, $selectedid, $level);
919
            }
920
        }
921
922
        return $ret;
923
    }
924
925
    /**
926
     * @param  int|array    $selectedid
0 ignored issues
show
Documentation introduced by
Consider making the type for parameter $selectedid a bit more specific; maybe use integer.
Loading history...
927
     * @param  int    $parentcategory
928
     * @param  bool   $allCatOption
929
     * @param  string $selectname
930
     * @return string
931
     */
932
    public static function createCategorySelect($selectedid = 0, $parentcategory = 0, $allCatOption = true, $selectname = 'options[0]')
933
    {
934
        $helper = publisher\Helper::getInstance();
935
936
        $selectedid = explode(',', $selectedid);
937
938
        $ret = "<select name='" . $selectname . "[]' multiple='multiple' size='10'>";
939
        if ($allCatOption) {
940
            $ret .= "<option value='0'";
941
            if (in_array(0, $selectedid)) {
942
                $ret .= ' selected';
943
            }
944
            $ret .= '>' . _MB_PUBLISHER_ALLCAT . '</option>';
945
        }
946
947
        // Creating category objects
948
        $categoriesObj = $helper->getHandler('category')->getCategories(0, 0, $parentcategory);
949
950 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...
951
            foreach ($categoriesObj as $catID => $categoryObj) {
952
                $ret .= static::addCategoryOption($categoryObj, $selectedid);
953
            }
954
        }
955
        $ret .= '</select>';
956
957
        return $ret;
958
    }
959
960
    /**
961
     * @param  int  $selectedid
962
     * @param  int  $parentcategory
963
     * @param  bool $allCatOption
964
     * @return string
965
     */
966
    public static function createCategoryOptions($selectedid = 0, $parentcategory = 0, $allCatOption = true)
967
    {
968
        $helper = publisher\Helper::getInstance();
969
970
        $ret = '';
971
        if ($allCatOption) {
972
            $ret .= "<option value='0'";
973
            $ret .= '>' . _MB_PUBLISHER_ALLCAT . "</option>\n";
974
        }
975
976
        // Creating category objects
977
        $categoriesObj = $helper->getHandler('category')->getCategories(0, 0, $parentcategory);
978 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...
979
            foreach ($categoriesObj as $catID => $categoryObj) {
980
                $ret .= static::addCategoryOption($categoryObj, $selectedid);
981
            }
982
        }
983
984
        return $ret;
985
    }
986
987
    /**
988
     * @param  array  $errArray
989
     * @param  string $reseturl
990
     * @return void
991
     */
992
    public static function renderErrors(&$errArray, $reseturl = '')
993
    {
994
        if (is_array($errArray) && count($errArray) > 0) {
995
            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;">';
996
997
            echo '<h4 style="text-align:left;margin:0; padding-top:0;">' . _AM_PUBLISHER_MSG_SUBMISSION_ERR;
998
999
            if ($reseturl) {
1000
                echo ' <a href="' . $reseturl . '">[' . _AM_PUBLISHER_TEXT_SESSION_RESET . ']</a>';
1001
            }
1002
1003
            echo '</h4><ul>';
1004
1005
            foreach ($errArray as $key => $error) {
1006
                if (is_array($error)) {
1007
                    foreach ($error as $err) {
1008
                        echo '<li><a href="#' . $key . '" onclick="var e = xoopsGetElementById(\'' . $key . '\'); e.focus();">' . htmlspecialchars($err) . '</a></li>';
1009
                    }
1010
                } else {
1011
                    echo '<li><a href="#' . $key . '" onclick="var e = xoopsGetElementById(\'' . $key . '\'); e.focus();">' . htmlspecialchars($error) . '</a></li>';
1012
                }
1013
            }
1014
            echo '</ul></div><br>';
1015
        }
1016
    }
1017
1018
    /**
1019
     * Generate publisher URL
1020
     *
1021
     * @param  string $page
1022
     * @param  array  $vars
1023
     * @param  bool   $encodeAmp
1024
     * @return string
1025
     *
1026
     * @credit : xHelp module, developped by 3Dev
1027
     */
1028
    public static function makeUri($page, $vars = [], $encodeAmp = true)
1029
    {
1030
        $joinStr = '';
1031
1032
        $amp = ($encodeAmp ? '&amp;' : '&');
1033
1034
        if (!count($vars)) {
1035
            return $page;
1036
        }
1037
1038
        $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...
1039
        foreach ($vars as $key => $value) {
1040
            $qs      .= $joinStr . $key . '=' . $value;
1041
            $joinStr = $amp;
1042
        }
1043
1044
        return $page . '?' . $qs;
1045
    }
1046
1047
    /**
1048
     * @param  string $subject
1049
     * @return string
1050
     */
1051
    public static function tellAFriend($subject = '')
1052
    {
1053
        if (false !== strpos($subject, '%')) {
1054
            $subject = rawurldecode($subject);
1055
        }
1056
1057
        $targetUri = XOOPS_URL . Request::getString('REQUEST_URI', '', 'SERVER');
1058
1059
        return XOOPS_URL . '/modules/tellafriend/index.php?target_uri=' . rawurlencode($targetUri) . '&amp;subject=' . rawurlencode($subject);
1060
    }
1061
1062
    /**
1063
     * @param  bool        $another
1064
     * @param  bool        $withRedirect
1065
     * @param              $itemObj
1066
     * @return bool|string
1067
     */
1068
    public static function uploadFile($another = false, $withRedirect = true, &$itemObj)
0 ignored issues
show
Coding Style introduced by
uploadFile 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
uploadFile 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...
1069
    {
1070
        xoops_load('XoopsMediaUploader');
1071
//        require_once PUBLISHER_ROOT_PATH . '/class/uploader.php';
1072
1073
        //    global $publisherIsAdmin;
1074
        $helper = publisher\Helper::getInstance();
1075
1076
        $itemId  = Request::getInt('itemid', 0, 'POST');
1077
        $uid     = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->uid() : 0;
1078
        $session = PublisherSession::getInstance();
1079
        $session->set('publisher_file_filename', Request::getString('item_file_name', '', 'POST'));
1080
        $session->set('publisher_file_description', Request::getString('item_file_description', '', 'POST'));
1081
        $session->set('publisher_file_status', Request::getInt('item_file_status', 1, 'POST'));
1082
        $session->set('publisher_file_uid', $uid);
1083
        $session->set('publisher_file_itemid', $itemId);
1084
1085
        if (!is_object($itemObj)) {
1086
            $itemObj = $helper->getHandler('item')->get($itemId);
1087
        }
1088
1089
        $fileObj = $helper->getHandler('file')->create();
1090
        $fileObj->setVar('name', Request::getString('item_file_name', '', 'POST'));
1091
        $fileObj->setVar('description', Request::getString('item_file_description', '', 'POST'));
1092
        $fileObj->setVar('status', Request::getInt('item_file_status', 1, 'POST'));
1093
        $fileObj->setVar('uid', $uid);
1094
        $fileObj->setVar('itemid', $itemObj->getVar('itemid'));
1095
        $fileObj->setVar('datesub', time());
1096
1097
        // Get available mimetypes for file uploading
1098
        $allowedMimetypes = $helper->getHandler('mimetype')->getArrayByType();
1099
        // TODO : display the available mimetypes to the user
1100
        $errors = [];
1101
        if ($helper->getConfig('perm_upload') && is_uploaded_file($_FILES['item_upload_file']['tmp_name'])) {
1102
            if (!$ret = $fileObj->checkUpload('item_upload_file', $allowedMimetypes, $errors)) {
1103
                $errorstxt = implode('<br>', $errors);
1104
1105
                $message = sprintf(_CO_PUBLISHER_MESSAGE_FILE_ERROR, $errorstxt);
1106
                if ($withRedirect) {
1107
                    redirect_header('file.php?op=mod&itemid=' . $itemId, 5, $message);
1108
                } else {
1109
                    return $message;
1110
                }
1111
            }
1112
        }
1113
1114
        // Storing the file
1115
        if (!$fileObj->store($allowedMimetypes)) {
1116
            //        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...
1117
            //            redirect_header("file.php?op=mod&itemid=" . $fileObj->itemid(), 3, _CO_PUBLISHER_FILEUPLOAD_ERROR . static::formatErrors($fileObj->getErrors()));
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% 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...
1118
            //            exit;
1119
            //        }
1120
            try {
1121
                if ($withRedirect) {
1122
                    throw new RuntimeException(_CO_PUBLISHER_FILEUPLOAD_ERROR . static::formatErrors($fileObj->getErrors()));
1123
                }
1124
            } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The class Xoopsmodules\publisher\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
1125
                $helper->addLog($e);
1126
                redirect_header('file.php?op=mod&itemid=' . $fileObj->itemid(), 3, _CO_PUBLISHER_FILEUPLOAD_ERROR . static::formatErrors($fileObj->getErrors()));
1127
            }
1128
            //    } 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...
1129
            //        return _CO_PUBLISHER_FILEUPLOAD_ERROR . static::formatErrors($fileObj->getErrors());
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
1130
        }
1131
1132
        if ($withRedirect) {
1133
            $redirectPage = $another ? 'file.php' : 'item.php';
1134
            redirect_header($redirectPage . '?op=mod&itemid=' . $fileObj->itemid(), 2, _CO_PUBLISHER_FILEUPLOAD_SUCCESS);
1135
        } else {
1136
            return true;
1137
        }
1138
1139
        return null;
1140
    }
1141
1142
    /**
1143
     * @return string
1144
     */
1145
    public static function newFeatureTag()
1146
    {
1147
        $ret = '<span style="padding-right: 4px; font-weight: bold; color: red;">' . _CO_PUBLISHER_NEW_FEATURE . '</span>';
1148
1149
        return $ret;
1150
    }
1151
1152
    /**
1153
     * Smarty truncate_tagsafe modifier plugin
1154
     *
1155
     * Type:     modifier<br>
1156
     * Name:     truncate_tagsafe<br>
1157
     * Purpose:  Truncate a string to a certain length if necessary,
1158
     *           optionally splitting in the middle of a word, and
1159
     *           appending the $etc string or inserting $etc into the middle.
1160
     *           Makes sure no tags are left half-open or half-closed
1161
     *           (e.g. "Banana in a <a...")
1162
     * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
1163
     *           <amos dot robinson at gmail dot com>
1164
     * @param string
1165
     * @param integer
1166
     * @param string
1167
     * @param boolean
1168
     * @param boolean
1169
     * @return string
1170
     */
1171
    public static function truncateTagSafe($string, $length = 80, $etc = '...', $breakWords = false)
1172
    {
1173
        if (0 == $length) {
1174
            return '';
1175
        }
1176
1177
        if (strlen($string) > $length) {
1178
            $length -= strlen($etc);
1179
            if (!$breakWords) {
1180
                $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length + 1));
1181
                $string = preg_replace('/<[^>]*$/', '', $string);
1182
                $string = static::closeTags($string);
1183
            }
1184
1185
            return $string . $etc;
1186
        } else {
1187
            return $string;
1188
        }
1189
    }
1190
1191
    /**
1192
     * @author   Monte Ohrt <monte at ohrt dot com>, modified by Amos Robinson
1193
     *           <amos dot robinson at gmail dot com>
1194
     * @param  string $string
1195
     * @return string
1196
     */
1197
    public static function closeTags($string)
1198
    {
1199
        // match opened tags
1200
        if (preg_match_all('/<([a-z\:\-]+)[^\/]>/', $string, $startTags)) {
1201
            $startTags = $startTags[1];
1202
            // match closed tags
1203
            if (preg_match_all('/<\/([a-z]+)>/', $string, $endTags)) {
1204
                $completeTags = [];
1205
                $endTags      = $endTags[1];
1206
1207
                foreach ($startTags as $key => $val) {
1208
                    $posb = array_search($val, $endTags);
1209
                    if (is_int($posb)) {
1210
                        unset($endTags[$posb]);
1211
                    } else {
1212
                        $completeTags[] = $val;
1213
                    }
1214
                }
1215
            } else {
1216
                $completeTags = $startTags;
1217
            }
1218
1219
            $completeTags = array_reverse($completeTags);
1220
            $elementCount = count($completeTags);
1221
            for ($i = 0; $i < $elementCount; ++$i) {
1222
                $string .= '</' . $completeTags[$i] . '>';
1223
            }
1224
        }
1225
1226
        return $string;
1227
    }
1228
1229
    /**
1230
     * @param  int $itemId
1231
     * @return string
1232
     */
1233
    public static function ratingBar($itemId)
0 ignored issues
show
Coding Style introduced by
ratingBar 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...
1234
    {
1235
        $helper       = publisher\Helper::getInstance();
1236
        $ratingUnitWidth = 30;
1237
        $units           = 5;
1238
1239
        $criteria   = new \Criteria('itemid', $itemId);
1240
        $ratingObjs = $helper->getHandler('rating')->getObjects($criteria);
1241
        unset($criteria);
1242
1243
        $uid           = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getVar('uid') : 0;
1244
        $count         = count($ratingObjs);
1245
        $currentRating = 0;
1246
        $voted         = false;
1247
        $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...
1248
        $rating1       = $rating2 = $ratingWidth = 0;
1249
1250 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...
1251
            $currentRating += $ratingObj->getVar('rate');
1252
            if ($ratingObj->getVar('ip') == $ip || ($uid > 0 && $uid == $ratingObj->getVar('uid'))) {
1253
                $voted = true;
1254
            }
1255
        }
1256
1257
        $tense = 1 == $count ? _MD_PUBLISHER_VOTE_VOTE : _MD_PUBLISHER_VOTE_VOTES; //plural form votes/vote
1258
1259
        // now draw the rating bar
1260
        if (0 != $count) {
1261
            $ratingWidth = number_format($currentRating / $count, 2) * $ratingUnitWidth;
1262
            $rating1     = number_format($currentRating / $count, 1);
1263
            $rating2     = number_format($currentRating / $count, 2);
1264
        }
1265
        $groups = $GLOBALS['xoopsUser'] ? $GLOBALS['xoopsUser']->getGroups() : XOOPS_GROUP_ANONYMOUS;
1266
        /* @var $gpermHandler XoopsGroupPermHandler */
1267
        $gpermHandler = $helper->getHandler('groupperm');
1268
1269
        if (!$gpermHandler->checkRight('global', \PublisherConstants::PUBLISHER_RATE, $groups, $helper->getModule()->getVar('mid'))) {
1270
            $staticRater   = [];
1271
            $staticRater[] .= "\n" . '<div class="publisher_ratingblock">';
1272
            $staticRater[] .= '<div id="unit_long' . $itemId . '">';
1273
            $staticRater[] .= '<div id="unit_ul' . $itemId . '" class="publisher_unit-rating" style="width:' . $ratingUnitWidth * $units . 'px;">';
1274
            $staticRater[] .= '<div class="publisher_current-rating" style="width:' . $ratingWidth . 'px;">' . _MD_PUBLISHER_VOTE_RATING . ' ' . $rating2 . '/' . $units . '</div>';
1275
            $staticRater[] .= '</div>';
1276
            $staticRater[] .= '<div class="publisher_static">' . _MD_PUBLISHER_VOTE_RATING . ': <strong> ' . $rating1 . '</strong>/' . $units . ' (' . $count . ' ' . $tense . ') <br><em>' . _MD_PUBLISHER_VOTE_DISABLE . '</em></div>';
1277
            $staticRater[] .= '</div>';
1278
            $staticRater[] .= '</div>' . "\n\n";
1279
1280
            return implode("\n", $staticRater);
1281
        } else {
1282
            $rater = '';
1283
            $rater .= '<div class="publisher_ratingblock">';
1284
            $rater .= '<div id="unit_long' . $itemId . '">';
1285
            $rater .= '<div id="unit_ul' . $itemId . '" class="publisher_unit-rating" style="width:' . $ratingUnitWidth * $units . 'px;">';
1286
            $rater .= '<div class="publisher_current-rating" style="width:' . $ratingWidth . 'px;">' . _MD_PUBLISHER_VOTE_RATING . ' ' . $rating2 . '/' . $units . '</div>';
1287
1288
            for ($ncount = 1; $ncount <= $units; ++$ncount) { // loop from 1 to the number of units
1289
                if (!$voted) { // if the user hasn't yet voted, draw the voting stars
1290
                    $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>';
1291
                }
1292
            }
1293
1294
            $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...
1295
            $rater  .= '  </div>';
1296
            $rater  .= '  <div';
1297
1298
            if ($voted) {
1299
                $rater .= ' class="publisher_voted"';
1300
            }
1301
1302
            $rater .= '>' . _MD_PUBLISHER_VOTE_RATING . ': <strong> ' . $rating1 . '</strong>/' . $units . ' (' . $count . ' ' . $tense . ')';
1303
            $rater .= '  </div>';
1304
            $rater .= '</div>';
1305
            $rater .= '</div>';
1306
1307
            return $rater;
1308
        }
1309
    }
1310
1311
    /**
1312
     * @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...
1313
     * @return array
1314
     */
1315
    public static function getEditors($allowedEditors = null)
1316
    {
1317
        $ret    = [];
1318
        $nohtml = false;
0 ignored issues
show
Unused Code introduced by
$nohtml 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...
1319
        xoops_load('XoopsEditorHandler');
1320
        $editorHandler = \XoopsEditorHandler::getInstance();
1321
        $editors       = array_flip($editorHandler->getList());//$editorHandler->getList($nohtml);
0 ignored issues
show
Unused Code Comprehensibility introduced by
86% 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...
1322
        foreach ($editors as $name => $title) {
1323
            $key = static::stringToInt($name);
1324
            if (is_array($allowedEditors)) {
1325
                //for submit page
1326
                if (in_array($key, $allowedEditors)) {
1327
                    $ret[] = $name;
1328
                }
1329
            } else {
1330
                //for admin permissions page
1331
                $ret[$key]['name']  = $name;
1332
                $ret[$key]['title'] = $title;
1333
            }
1334
        }
1335
1336
        return $ret;
1337
    }
1338
1339
    /**
1340
     * @param  string $string
1341
     * @param  int    $length
1342
     * @return int
1343
     */
1344
    public static function stringToInt($string = '', $length = 5)
1345
    {
1346
        $final  = '';
1347
        $substring = substr(md5($string), $length);
1348
        for ($i = 0; $i < $length; ++$i) {
1349
            $final .= (int)$substring[$i];
1350
        }
1351
1352
        return (int)$final;
1353
    }
1354
1355
    /**
1356
     * @param  string $item
1357
     * @return string
1358
     */
1359
    public static function convertCharset($item)
1360
    {
1361
        if (_CHARSET !== 'windows-1256') {
1362
            return utf8_encode($item);
1363
        }
1364
1365
        if ($unserialize == unserialize($item)) {
1366
            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...
1367
                $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...
1368
            }
1369
            $serialize = serialize($unserialize);
1370
1371
            return $serialize;
1372
        } else {
1373
            return @iconv('windows-1256', 'UTF-8', $item);
1374
        }
1375
    }
1376
1377
    /**
1378
     *
1379
     * Verifies XOOPS version meets minimum requirements for this module
1380
     * @static
1381
     * @param \XoopsModule $module
0 ignored issues
show
Documentation introduced by
Should the type for parameter $module not be null|\XoopsModule?

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

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

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

Loading history...
1382
     *
1383
     * @param null|string $requiredVer
1384
     * @return bool true if meets requirements, false if not
1385
     */
1386
    public static function checkVerXoops(\XoopsModule $module = null, $requiredVer = null)
1387
    {
1388
        $moduleDirName = basename(dirname(__DIR__));
1389
        if (null === $module) {
1390
            $module = \XoopsModule::getByDirname($moduleDirName);
1391
        }
1392
        xoops_loadLanguage('admin', $moduleDirName);
1393
1394
        //check for minimum XOOPS version
1395
        $currentVer = substr(XOOPS_VERSION, 6); // get the numeric part of string
1396
        if (null === $requiredVer) {
1397
            $requiredVer = '' . $module->getInfo('min_xoops'); //making sure it's a string
1398
        }
1399
        $success     = true;
1400
1401
        if (version_compare($currentVer, $requiredVer, '<')) {
1402
            $success     = false;
1403
            $module->setErrors(sprintf(_AM_PUBLISHER_ERROR_BAD_XOOPS, $requiredVer, $currentVer));
1404
        }
1405
1406
        return $success;
1407
    }
1408
1409
    /**
1410
     *
1411
     * Verifies PHP version meets minimum requirements for this module
1412
     * @static
1413
     * @param XoopsModule $module
1414
     *
1415
     * @return bool true if meets requirements, false if not
1416
     */
1417
    public static function checkVerPhp(XoopsModule $module)
1418
    {
1419
        xoops_loadLanguage('admin', $module->dirname());
1420
        // check for minimum PHP version
1421
        $success = true;
1422
        $verNum  = PHP_VERSION;
1423
        $reqVer  = $module->getInfo('min_php');
1424
        if (false !== $reqVer && '' !== $reqVer) {
1425
            if (version_compare($verNum, $reqVer, '<')) {
1426
                $module->setErrors(sprintf(_AM_PUBLISHER_ERROR_BAD_PHP, $reqVer, $verNum));
1427
                $success = false;
1428
            }
1429
        }
1430
1431
        return $success;
1432
    }
1433
}
1434