Passed
Branch master (95688a)
by Michael
11:53 queued 05:49
created

Utility   F

Complexity

Total Complexity 214

Size/Duplication

Total Lines 1503
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1503
rs 0.6314
c 0
b 0
f 0
wmc 214

47 Methods

Rating   Name   Duplication   Size   Complexity  
C uploadFile() 0 72 12
A userIsAdmin() 0 18 3
A getUploadDir() 0 14 4
A cpHeader() 0 14 1
A checkVerXoops() 0 21 4
A stringToInt() 0 9 2
A userIsModerator() 0 6 2
B getCurrentUrls() 0 24 3
A buildTableItemTitleRow() 0 18 1
C editCategory() 0 128 11
A setCookieVar() 0 6 2
A chmod() 0 3 1
B createFolder() 0 12 6
D ratingBar() 0 75 13
F createDir() 0 51 14
A checkVerPhp() 0 15 4
A getCurrentPage() 0 5 1
A openCollapsableBar() 0 14 3
A makeUri() 0 17 4
B recurseCopy() 0 14 5
B displayCategory() 0 31 6
A convertCharset() 0 15 4
B getPathStatus() 0 26 6
A moduleHome() 0 12 3
A createCategoryOptions() 0 19 4
C copyr() 0 32 8
A getCookieVar() 0 8 1
A closeCollapsableBar() 0 15 2
A getImageDir() 0 9 2
B getOrderBy() 0 17 7
A substr() 0 19 2
C mkdir() 0 24 7
A formatErrors() 0 8 2
B closeTags() 0 30 6
A copyFile() 0 3 1
B createCategorySelect() 0 26 5
A truncateTagSafe() 0 17 4
A html2text() 0 47 1
A saveCategoryPermissions() 0 20 3
D truncateHtml() 0 90 19
A getAllowedImagesTypes() 0 3 1
C addCategoryOption() 0 26 7
A userIsAuthor() 0 3 3
A tellAFriend() 0 9 2
A newFeatureTag() 0 5 1
C renderErrors() 0 23 7
B getEditors() 0 22 4

How to fix   Complexity   

Complex Class

Complex classes like Utility often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Utility, and based on these observations, apply Extract Interface, too.

1
<?php namespace XoopsModules\Publisher;
2
3
/*
4
 You may not change or alter any portion of this comment or credits
5
 of supporting developers from this source code or any supporting source code
6
 which is considered copyrighted (c) material of the original comment or credit authors.
7
8
 This program is distributed in the hope that it will be useful,
9
 but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 */
12
13
/**
14
 * PublisherUtil Class
15
 *
16
 * @copyright   XOOPS Project (https://xoops.org)
17
 * @license     http://www.fsf.org/copyleft/gpl.html GNU public license
18
 * @author      XOOPS Development Team
19
 * @package     Publisher
20
 * @since       1.03
21
 *
22
 */
23
24
use Xmf\Request;
25
use XoopsModules\Publisher;
26
use XoopsModules\Publisher\Common;
27
use XoopsModules\Publisher\Constants;
28
29
/**
30
 * Class Utility
31
 */
32
class Utility
33
{
34
    use Common\VersionChecks; //checkVerXoops, checkVerPhp Traits
35
36
    use Common\ServerStats; // getServerStats Trait
37
38
    use Common\FilesManagement; // Files Management Trait
39
40
    //--------------- Custom module methods -----------------------------
41
42
    /**
43
     * Function responsible for checking if a directory exists, we can also write in and create an index.html file
44
     *
45
     * @param string $folder The full path of the directory to check
46
     *
47
     * @return void
48
     */
49
    public static function createFolder($folder)
50
    {
51
        try {
52
            if (!file_exists($folder)) {
53
                if (!is_dir($folder) && !mkdir($folder) && !is_dir($folder)) {
54
                    throw new \RuntimeException(sprintf('Unable to create the %s directory', $folder));
55
                } else {
56
                    file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
57
                }
58
            }
59
        } catch (\Exception $e) {
60
            echo 'Caught exception: ', $e->getMessage(), "\n", '<br>';
61
        }
62
    }
63
64
    /**
65
     * @param $file
66
     * @param $folder
67
     * @return bool
68
     */
69
    public static function copyFile($file, $folder)
70
    {
71
        return copy($file, $folder);
72
        //        try {
73
        //            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...
74
        //                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...
75
        //            } 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...
76
        //                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...
77
        //            }
78
        //        } 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...
79
        //            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...
80
        //        }
81
        //        return false;
82
    }
83
84
    /**
85
     * @param $src
86
     * @param $dst
87
     */
88
    public static function recurseCopy($src, $dst)
89
    {
90
        $dir = opendir($src);
91
        //    @mkdir($dst);
92
        while (false !== ($file = readdir($dir))) {
0 ignored issues
show
Bug introduced by
It seems like $dir can also be of type false; however, parameter $dir_handle of readdir() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

92
        while (false !== ($file = readdir(/** @scrutinizer ignore-type */ $dir))) {
Loading history...
93
            if (('.' !== $file) && ('..' !== $file)) {
94
                if (is_dir($src . '/' . $file)) {
95
                    self::recurseCopy($src . '/' . $file, $dst . '/' . $file);
96
                } else {
97
                    copy($src . '/' . $file, $dst . '/' . $file);
98
                }
99
            }
100
        }
101
        closedir($dir);
0 ignored issues
show
Bug introduced by
It seems like $dir can also be of type false; however, parameter $dir_handle of closedir() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

101
        closedir(/** @scrutinizer ignore-type */ $dir);
Loading history...
102
    }
103
104
    // auto create folders----------------------------------------
105
    //TODO rename this function? And exclude image folder?
106
    public static function createDir()
107
    {
108
        // auto crate folders
109
        //        $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...
110
111
        if (static::getPathStatus('root', true) < 0) {
112
            $thePath = static::getUploadDir();
113
            $res     = static::mkdir($thePath);
114
            $msg     = $res ? _AM_PUBLISHER_DIRCREATED : _AM_PUBLISHER_DIRNOTCREATED;
0 ignored issues
show
Unused Code introduced by
The assignment to $msg is dead and can be removed.
Loading history...
115
        }
116
117
        if (static::getPathStatus('images', true) < 0) {
118
            $thePath = static::getImageDir();
119
            $res     = static::mkdir($thePath);
120
121
            if ($res) {
122
                $source = PUBLISHER_ROOT_PATH . '/assets/images/blank.png';
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Publisher\PUBLISHER_ROOT_PATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
123
                $dest   = $thePath . 'blank.png';
124
                static::copyr($source, $dest);
125
            }
126
            $msg = $res ? _AM_PUBLISHER_DIRCREATED : _AM_PUBLISHER_DIRNOTCREATED;
127
        }
128
129
        if (static::getPathStatus('images/category', true) < 0) {
130
            $thePath = static::getImageDir('category');
131
            $res     = static::mkdir($thePath);
132
133
            if ($res) {
134
                $source = PUBLISHER_ROOT_PATH . '/assets/images/blank.png';
135
                $dest   = $thePath . 'blank.png';
136
                static::copyr($source, $dest);
137
            }
138
            $msg = $res ? _AM_PUBLISHER_DIRCREATED : _AM_PUBLISHER_DIRNOTCREATED;
139
        }
140
141
        if (static::getPathStatus('images/item', true) < 0) {
142
            $thePath = static::getImageDir('item');
143
            $res     = static::mkdir($thePath);
144
145
            if ($res) {
146
                $source = PUBLISHER_ROOT_PATH . '/assets/images/blank.png';
147
                $dest   = $thePath . 'blank.png';
148
                static::copyr($source, $dest);
149
            }
150
            $msg = $res ? _AM_PUBLISHER_DIRCREATED : _AM_PUBLISHER_DIRNOTCREATED;
151
        }
152
153
        if (static::getPathStatus('content', true) < 0) {
154
            $thePath = static::getUploadDir(true, 'content');
155
            $res     = static::mkdir($thePath);
156
            $msg     = $res ? _AM_PUBLISHER_DIRCREATED : _AM_PUBLISHER_DIRNOTCREATED;
157
        }
158
    }
159
160
    public static function buildTableItemTitleRow()
161
    {
162
        echo "<table width='100%' cellspacing='1' cellpadding='3' border='0' class='outer'>";
163
        echo '<tr>';
164
        echo "<th width='40px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_ITEMID . '</strong></td>';
165
        echo "<th width='100px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_ITEMCAT . '</strong></td>';
166
        echo "<th class='bg3' align='center'><strong>" . _AM_PUBLISHER_TITLE . '</strong></td>';
167
        echo "<th width='100px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_CREATED . '</strong></td>';
168
169
        echo "<th width='50px' class='bg3' align='center'><strong>" . _CO_PUBLISHER_WEIGHT . '</strong></td>';
170
        echo "<th width='50px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_HITS . '</strong></td>';
171
        echo "<th width='60px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_RATE . '</strong></td>';
172
        echo "<th width='50px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_VOTES . '</strong></td>';
173
        echo "<th width='60px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_COMMENTS_COUNT . '</strong></td>';
174
175
        echo "<th width='90px' class='bg3' align='center'><strong>" . _CO_PUBLISHER_STATUS . '</strong></td>';
176
        echo "<th width='90px' class='bg3' align='center'><strong>" . _AM_PUBLISHER_ACTION . '</strong></td>';
177
        echo '</tr>';
178
    }
179
180
    /**
181
     * @param Publisher\Category $categoryObj
182
     * @param int               $level
183
     */
184
    public static function displayCategory(Publisher\Category $categoryObj, $level = 0)
185
    {
186
        $helper = Publisher\Helper::getInstance();
187
188
        $description = $categoryObj->description();
0 ignored issues
show
Bug introduced by
The method description() does not exist on XoopsModules\Publisher\Category. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

188
        /** @scrutinizer ignore-call */ 
189
        $description = $categoryObj->description();
Loading history...
189
        if (!XOOPS_USE_MULTIBYTES) {
190
            if (strlen($description) >= 100) {
0 ignored issues
show
Bug introduced by
It seems like $description can also be of type array and array; however, parameter $string of strlen() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

190
            if (strlen(/** @scrutinizer ignore-type */ $description) >= 100) {
Loading history...
191
                $description = substr($description, 0, 100 - 1) . '...';
0 ignored issues
show
Unused Code introduced by
The assignment to $description is dead and can be removed.
Loading history...
Bug introduced by
It seems like $description can also be of type array and array; however, parameter $string of substr() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

191
                $description = substr(/** @scrutinizer ignore-type */ $description, 0, 100 - 1) . '...';
Loading history...
192
            }
193
        }
194
        $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>";
0 ignored issues
show
Bug introduced by
The method parentid() does not exist on XoopsModules\Publisher\Category. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

194
        $modify = "<a href='category.php?op=mod&amp;categoryid=" . $categoryObj->categoryid() . '&amp;parentid=' . $categoryObj->/** @scrutinizer ignore-call */ parentid() . "'><img src='" . PUBLISHER_URL . "/assets/images/links/edit.gif' title='" . _AM_PUBLISHER_EDITCOL . "' alt='" . _AM_PUBLISHER_EDITCOL . "'></a>";
Loading history...
Bug introduced by
The constant XoopsModules\Publisher\PUBLISHER_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
Bug introduced by
The method categoryid() does not exist on XoopsModules\Publisher\Category. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

194
        $modify = "<a href='category.php?op=mod&amp;categoryid=" . $categoryObj->/** @scrutinizer ignore-call */ categoryid() . '&amp;parentid=' . $categoryObj->parentid() . "'><img src='" . PUBLISHER_URL . "/assets/images/links/edit.gif' title='" . _AM_PUBLISHER_EDITCOL . "' alt='" . _AM_PUBLISHER_EDITCOL . "'></a>";
Loading history...
195
        $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>";
196
197
        $spaces = '';
198
        for ($j = 0; $j < $level; ++$j) {
199
            $spaces .= '&nbsp;&nbsp;&nbsp;';
200
        }
201
202
        echo '<tr>';
203
        echo "<td class='even' align='center'>" . $categoryObj->categoryid() . '</td>';
204
        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>';
0 ignored issues
show
Bug introduced by
The method name() does not exist on XoopsModules\Publisher\Category. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

204
        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->/** @scrutinizer ignore-call */ name() . '</a></td>';
Loading history...
205
        echo "<td class='even' align='center'>" . $categoryObj->weight() . '</td>';
0 ignored issues
show
Bug introduced by
The method weight() does not exist on XoopsModules\Publisher\Category. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

205
        echo "<td class='even' align='center'>" . $categoryObj->/** @scrutinizer ignore-call */ weight() . '</td>';
Loading history...
206
        echo "<td class='even' align='center'> $modify $delete </td>";
207
        echo '</tr>';
208
        $subCategoriesObj = $helper->getHandler('Category')->getCategories(0, 0, $categoryObj->categoryid());
0 ignored issues
show
Bug introduced by
The method getCategories() does not exist on XoopsPersistableObjectHandler. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

208
        $subCategoriesObj = $helper->getHandler('Category')->/** @scrutinizer ignore-call */ getCategories(0, 0, $categoryObj->categoryid());
Loading history...
Bug introduced by
The method getCategories() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

208
        $subCategoriesObj = $helper->getHandler('Category')->/** @scrutinizer ignore-call */ getCategories(0, 0, $categoryObj->categoryid());
Loading history...
209
        if (count($subCategoriesObj) > 0) {
210
            ++$level;
211
            foreach ($subCategoriesObj as $key => $thiscat) {
212
                self::displayCategory($thiscat, $level);
213
            }
214
            unset($key);
215
        }
216
        //        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...
217
    }
218
219
    /**
220
     * @param bool $showmenu
221
     * @param int  $categoryId
222
     * @param int  $nbSubCats
223
     * @param null $categoryObj
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $categoryObj is correct as it would always require null to be passed?
Loading history...
224
     */
225
    public static function editCategory($showmenu = false, $categoryId = 0, $nbSubCats = 4, $categoryObj = null)
0 ignored issues
show
Unused Code introduced by
The parameter $showmenu is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

225
    public static function editCategory(/** @scrutinizer ignore-unused */ $showmenu = false, $categoryId = 0, $nbSubCats = 4, $categoryObj = null)

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

Loading history...
226
    {
227
        $helper = Publisher\Helper::getInstance();
228
229
        // if there is a parameter, and the id exists, retrieve data: we're editing a category
230
        /* @var  $categoryObj Publisher\Category */
231
        if (0 != $categoryId) {
232
            // Creating the category object for the selected category
233
            $categoryObj = $helper->getHandler('Category')->get($categoryId);
234
            if ($categoryObj->notLoaded()) {
0 ignored issues
show
Bug introduced by
The method notLoaded() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Publisher\Item or XoopsModules\Publisher\File or XoopsModules\Publisher\Category. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

234
            if ($categoryObj->/** @scrutinizer ignore-call */ notLoaded()) {
Loading history...
235
                redirect_header('category.php', 1, _AM_PUBLISHER_NOCOLTOEDIT);
236
                //            exit();
237
            }
238
        } else {
239
            if (!$categoryObj) {
0 ignored issues
show
introduced by
$categoryObj is of type XoopsModules\Publisher\Category, thus it always evaluated to true.
Loading history...
240
                $categoryObj = $helper->getHandler('Category')->create();
241
            }
242
        }
243
244
        if (0 != $categoryId) {
245
            echo "<br>\n";
246
            static::openCollapsableBar('edittable', 'edittableicon', _AM_PUBLISHER_EDITCOL, _AM_PUBLISHER_CATEGORY_EDIT_INFO);
247
        } else {
248
            static::openCollapsableBar('createtable', 'createtableicon', _AM_PUBLISHER_CATEGORY_CREATE, _AM_PUBLISHER_CATEGORY_CREATE_INFO);
249
        }
250
251
        $sform = $categoryObj->getForm($nbSubCats);
0 ignored issues
show
Bug introduced by
The method getForm() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as SystemSmilies or SystemBanner or SystemBannerclient or XoopsModules\Publisher\Item or ProfileCategory or SystemUserrank or XoopsModules\Publisher\File or XoopsModules\Publisher\Category or SystemGroup or SystemBlock or SystemAvatar or SystemUsers. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

251
        /** @scrutinizer ignore-call */ 
252
        $sform = $categoryObj->getForm($nbSubCats);
Loading history...
252
        $sform->display();
253
254
        if (!$categoryId) {
255
            static::closeCollapsableBar('createtable', 'createtableicon');
256
        } else {
257
            static::closeCollapsableBar('edittable', 'edittableicon');
258
        }
259
260
        //Added by fx2024
261
        if ($categoryId) {
262
            $selCat = $categoryId;
263
264
            static::openCollapsableBar('subcatstable', 'subcatsicon', _AM_PUBLISHER_SUBCAT_CAT, _AM_PUBLISHER_SUBCAT_CAT_DSC);
265
            // Get the total number of sub-categories
266
            $categoriesObj = $helper->getHandler('Category')->get($selCat);
267
            $totalsubs     = $helper->getHandler('Category')->getCategoriesCount($selCat);
0 ignored issues
show
Bug introduced by
The method getCategoriesCount() does not exist on XoopsPersistableObjectHandler. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

267
            $totalsubs     = $helper->getHandler('Category')->/** @scrutinizer ignore-call */ getCategoriesCount($selCat);
Loading history...
Bug introduced by
The method getCategoriesCount() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

267
            $totalsubs     = $helper->getHandler('Category')->/** @scrutinizer ignore-call */ getCategoriesCount($selCat);
Loading history...
268
            // creating the categories objects that are published
269
            $subcatsObj    = $helper->getHandler('Category')->getCategories(0, 0, $categoriesObj->categoryid());
0 ignored issues
show
Bug introduced by
The method categoryid() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Publisher\Item or XoopsModules\Publisher\File or XoopsModules\Publisher\Category. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

269
            $subcatsObj    = $helper->getHandler('Category')->getCategories(0, 0, $categoriesObj->/** @scrutinizer ignore-call */ categoryid());
Loading history...
270
            $totalSCOnPage = count($subcatsObj);
0 ignored issues
show
Unused Code introduced by
The assignment to $totalSCOnPage is dead and can be removed.
Loading history...
271
            echo "<table width='100%' cellspacing=1 cellpadding=3 border=0 class = outer>";
272
            echo '<tr>';
273
            echo "<td width='60' class='bg3' align='left'><strong>" . _AM_PUBLISHER_CATID . '</strong></td>';
274
            echo "<td width='20%' class='bg3' align='left'><strong>" . _AM_PUBLISHER_CATCOLNAME . '</strong></td>';
275
            echo "<td class='bg3' align='left'><strong>" . _AM_PUBLISHER_SUBDESCRIPT . '</strong></td>';
276
            echo "<td width='60' class='bg3' align='right'><strong>" . _AM_PUBLISHER_ACTION . '</strong></td>';
277
            echo '</tr>';
278
            if ($totalsubs > 0) {
279
                foreach ($subcatsObj as $subcat) {
280
                    $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>";
281
                    $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>";
282
                    echo '<tr>';
283
                    echo "<td class='head' align='left'>" . $subcat->categoryid() . '</td>';
284
                    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>';
285
                    echo "<td class='even' align='left'>" . $subcat->description() . '</td>';
286
                    echo "<td class='even' align='right'> {$modify} {$delete} </td>";
287
                    echo '</tr>';
288
                }
289
                //                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...
290
            } else {
291
                echo '<tr>';
292
                echo "<td class='head' align='center' colspan= '7'>" . _AM_PUBLISHER_NOSUBCAT . '</td>';
293
                echo '</tr>';
294
            }
295
            echo "</table>\n";
296
            echo "<br>\n";
297
            static::closeCollapsableBar('subcatstable', 'subcatsicon');
298
299
            static::openCollapsableBar('bottomtable', 'bottomtableicon', _AM_PUBLISHER_CAT_ITEMS, _AM_PUBLISHER_CAT_ITEMS_DSC);
300
            $startitem = Request::getInt('startitem');
301
            // Get the total number of published ITEMS
302
            $totalitems = $helper->getHandler('Item')->getItemsCount($selCat, [Constants::PUBLISHER_STATUS_PUBLISHED]);
0 ignored issues
show
Bug introduced by
The method getItemsCount() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

302
            $totalitems = $helper->getHandler('Item')->/** @scrutinizer ignore-call */ getItemsCount($selCat, [Constants::PUBLISHER_STATUS_PUBLISHED]);
Loading history...
Bug introduced by
The method getItemsCount() does not exist on XoopsPersistableObjectHandler. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

302
            $totalitems = $helper->getHandler('Item')->/** @scrutinizer ignore-call */ getItemsCount($selCat, [Constants::PUBLISHER_STATUS_PUBLISHED]);
Loading history...
303
            // creating the items objects that are published
304
            $itemsObj         = $helper->getHandler('Item')->getAllPublished($helper->getConfig('idxcat_perpage'), $startitem, $selCat);
0 ignored issues
show
Bug introduced by
The method getAllPublished() does not exist on XoopsPersistableObjectHandler. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

304
            $itemsObj         = $helper->getHandler('Item')->/** @scrutinizer ignore-call */ getAllPublished($helper->getConfig('idxcat_perpage'), $startitem, $selCat);
Loading history...
Bug introduced by
The method getAllPublished() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

304
            $itemsObj         = $helper->getHandler('Item')->/** @scrutinizer ignore-call */ getAllPublished($helper->getConfig('idxcat_perpage'), $startitem, $selCat);
Loading history...
305
            $totalitemsOnPage = count($itemsObj);
306
            $allcats          = $helper->getHandler('Category')->getObjects(null, true);
0 ignored issues
show
Bug introduced by
The method getObjects() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of said class. However, the method does not exist in XoopsRankHandler or XoUserHandler or XoopsModules\Publisher\PermissionHandler. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

306
            $allcats          = $helper->getHandler('Category')->/** @scrutinizer ignore-call */ getObjects(null, true);
Loading history...
307
            echo "<table width='100%' cellspacing=1 cellpadding=3 border=0 class = outer>";
308
            echo '<tr>';
309
            echo "<td width='40' class='bg3' align='center'><strong>" . _AM_PUBLISHER_ITEMID . '</strong></td>';
310
            echo "<td width='20%' class='bg3' align='left'><strong>" . _AM_PUBLISHER_ITEMCOLNAME . '</strong></td>';
311
            echo "<td class='bg3' align='left'><strong>" . _AM_PUBLISHER_ITEMDESC . '</strong></td>';
312
            echo "<td width='90' class='bg3' align='center'><strong>" . _AM_PUBLISHER_CREATED . '</strong></td>';
313
            echo "<td width='60' class='bg3' align='center'><strong>" . _AM_PUBLISHER_ACTION . '</strong></td>';
314
            echo '</tr>';
315
            if ($totalitems > 0) {
316
                for ($i = 0; $i < $totalitemsOnPage; ++$i) {
317
                    $categoryObj = $allcats[$itemsObj[$i]->categoryid()];
318
                    $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>";
319
                    $delete      = "<a href='item.php?op=del&amp;itemid="
320
                                   . $itemsObj[$i]->itemid()
321
                                   . "'><img src='"
322
                                   . XOOPS_URL
323
                                   . '/modules/'
324
                                   . $helper->getModule()->dirname()
325
                                   . "/assets/images/links/delete.png' title='"
326
                                   . _AM_PUBLISHER_DELETEITEM
327
                                   . "' alt='"
328
                                   . _AM_PUBLISHER_DELETEITEM
329
                                   . "'></a>";
330
                    echo '<tr>';
331
                    echo "<td class='head' align='center'>" . $itemsObj[$i]->itemid() . '</td>';
332
                    echo "<td class='even' align='left'>" . $categoryObj->name() . '</td>';
333
                    echo "<td class='even' align='left'>" . $itemsObj[$i]->getitemLink() . '</td>';
334
                    echo "<td class='even' align='center'>" . $itemsObj[$i]->getDatesub('s') . '</td>';
335
                    echo "<td class='even' align='center'> $modify $delete </td>";
336
                    echo '</tr>';
337
                }
338
            } else {
339
                $itemid = -1;
0 ignored issues
show
Unused Code introduced by
The assignment to $itemid is dead and can be removed.
Loading history...
340
                echo '<tr>';
341
                echo "<td class='head' align='center' colspan= '7'>" . _AM_PUBLISHER_NOITEMS . '</td>';
342
                echo '</tr>';
343
            }
344
            echo "</table>\n";
345
            echo "<br>\n";
346
            $parentid         = Request::getInt('parentid', 0, 'GET');
347
            $pagenavExtraArgs = "op=mod&categoryid=$selCat&parentid=$parentid";
348
            xoops_load('XoopsPageNav');
349
            $pagenav = new \XoopsPageNav($totalitems, $helper->getConfig('idxcat_perpage'), $startitem, 'startitem', $pagenavExtraArgs);
350
            echo '<div style="text-align:right;">' . $pagenav->renderNav() . '</div>';
351
            echo "<input type='button' name='button' onclick=\"location='item.php?op=mod&categoryid=" . $selCat . "'\" value='" . _AM_PUBLISHER_CREATEITEM . "'>&nbsp;&nbsp;";
352
            echo '</div>';
353
        }
354
        //end of fx2024 code
355
    }
356
357
358
    //======================== FUNCTIONS =================================
359
360
    /**
361
     * Includes scripts in HTML header
362
     *
363
     * @return void
364
     */
365
    public static function cpHeader()
366
    {
367
        xoops_cp_header();
368
369
        //cannot use xoTheme, some conflit with admin gui
370
        echo '<link type="text/css" href="' . XOOPS_URL . '/modules/system/css/ui/' . xoops_getModuleOption('jquery_theme', 'system') . '/ui.all.css" rel="stylesheet">
0 ignored issues
show
Deprecated Code introduced by
The function xoops_getModuleOption() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

370
        echo '<link type="text/css" href="' . XOOPS_URL . '/modules/system/css/ui/' . /** @scrutinizer ignore-deprecated */ xoops_getModuleOption('jquery_theme', 'system') . '/ui.all.css" rel="stylesheet">
Loading history...
371
    <link type="text/css" href="' . PUBLISHER_URL . '/assets/css/publisher.css" rel="stylesheet">
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Publisher\PUBLISHER_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
372
    <script type="text/javascript" src="' . PUBLISHER_URL . '/assets/js/funcs.js"></script>
373
    <script type="text/javascript" src="' . PUBLISHER_URL . '/assets/js/cookies.js"></script>
374
    <script type="text/javascript" src="' . XOOPS_URL . '/browse.php?Frameworks/jquery/jquery.js"></script>
375
    <!-- <script type="text/javascript" src="' . XOOPS_URL . '/browse.php?Frameworks/jquery/jquery-migrate-1.2.1.js"></script> -->
376
    <script type="text/javascript" src="' . XOOPS_URL . '/browse.php?Frameworks/jquery/plugins/jquery.ui.js"></script>
377
    <script type="text/javascript" src="' . PUBLISHER_URL . '/assets/js/ajaxupload.3.9.js"></script>
378
    <script type="text/javascript" src="' . PUBLISHER_URL . '/assets/js/publisher.js"></script>
379
    ';
380
    }
381
382
    /**
383
     * Default sorting for a given order
384
     *
385
     * @param  string $sort
386
     * @return string
387
     */
388
    public static function getOrderBy($sort)
389
    {
390
        if ('datesub' === $sort) {
391
            return 'DESC';
392
        } elseif ('counter' === $sort) {
393
            return 'DESC';
394
        } elseif ('weight' === $sort) {
395
            return 'ASC';
396
        } elseif ('votes' === $sort) {
397
            return 'DESC';
398
        } elseif ('rating' === $sort) {
399
            return 'DESC';
400
        } elseif ('comments' === $sort) {
401
            return 'DESC';
402
        }
403
404
        return null;
405
    }
406
407
    /**
408
     * @credits Thanks to Mithandir
409
     * @param  string $str
410
     * @param  int    $start
411
     * @param  int    $length
412
     * @param  string $trimMarker
413
     * @return string
414
     */
415
    public static function substr($str, $start, $length, $trimMarker = '...')
416
    {
417
        // if the string is empty, let's get out ;-)
418
        if ('' == $str) {
419
            return $str;
420
        }
421
422
        // reverse a string that is shortened with '' as trimmarker
423
        $reversedString = strrev(xoops_substr($str, $start, $length, ''));
424
425
        // find first space in reversed string
426
        $positionOfSpace = strpos($reversedString, ' ', 0);
427
428
        // truncate the original string to a length of $length
429
        // minus the position of the last space
430
        // plus the length of the $trimMarker
431
        $truncatedString = xoops_substr($str, $start, $length - $positionOfSpace + strlen($trimMarker), $trimMarker);
432
433
        return $truncatedString;
434
    }
435
436
    /**
437
     * @param  string $document
438
     * @return mixed
439
     */
440
    public static function html2text($document)
441
    {
442
        // PHP Manual:: function preg_replace
443
        // $document should contain an HTML document.
444
        // This will remove HTML tags, javascript sections
445
        // and white space. It will also convert some
446
        // common HTML entities to their text equivalent.
447
        // Credits : newbb2
448
        $search = [
449
            "'<script[^>]*?>.*?</script>'si", // Strip out javascript
450
            "'<img.*?>'si", // Strip out img tags
451
            "'<[\/\!]*?[^<>]*?>'si", // Strip out HTML tags
452
            "'([\r\n])[\s]+'", // Strip out white space
453
            "'&(quot|#34);'i", // Replace HTML entities
454
            "'&(amp|#38);'i",
455
            "'&(lt|#60);'i",
456
            "'&(gt|#62);'i",
457
            "'&(nbsp|#160);'i",
458
            "'&(iexcl|#161);'i",
459
            "'&(cent|#162);'i",
460
            "'&(pound|#163);'i",
461
            "'&(copy|#169);'i"
462
        ]; // evaluate as php
463
464
        $replace = [
465
            '',
466
            '',
467
            '',
468
            "\\1",
469
            '"',
470
            '&',
471
            '<',
472
            '>',
473
            ' ',
474
            chr(161),
475
            chr(162),
476
            chr(163),
477
            chr(169)
478
        ];
479
480
        $text = preg_replace($search, $replace, $document);
481
482
        preg_replace_callback('/&#(\d+);/', function ($matches) {
483
            return chr($matches[1]);
484
        }, $document);
485
486
        return $text;
487
        //<?php
488
    }
489
490
    /**
491
     * @return array
492
     */
493
    public static function getAllowedImagesTypes()
494
    {
495
        return ['jpg/jpeg', 'image/bmp', 'image/gif', 'image/jpeg', 'image/jpg', 'image/x-png', 'image/png', 'image/pjpeg'];
496
    }
497
498
    /**
499
     * @param  bool $withLink
500
     * @return string
501
     */
502
    public static function moduleHome($withLink = true)
503
    {
504
        $helper = Publisher\Helper::getInstance();
505
506
        if (!$helper->getConfig('format_breadcrumb_modname')) {
507
            return '';
508
        }
509
510
        if (!$withLink) {
511
            return $helper->getModule()->getVar('name');
512
        } else {
513
            return '<a href="' . PUBLISHER_URL . '/">' . $helper->getModule()->getVar('name') . '</a>';
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Publisher\PUBLISHER_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
514
        }
515
    }
516
517
    /**
518
     * Copy a file, or a folder and its contents
519
     *
520
     * @author      Aidan Lister <[email protected]>
521
     * @version     1.0.0
522
     * @param  string $source The source
523
     * @param  string $dest   The destination
524
     * @return bool   Returns true on success, false on failure
525
     */
526
    public static function copyr($source, $dest)
527
    {
528
        // Simple copy for a file
529
        if (is_file($source)) {
530
            return copy($source, $dest);
531
        }
532
533
        // Make destination directory
534
        if (!is_dir($dest)) {
535
            mkdir($dest);
536
        }
537
538
        // Loop through the folder
539
        $dir = dir($source);
540
        while (false !== $entry = $dir->read()) {
541
            // Skip pointers
542
            if ('.' === $entry || '..' === $entry) {
543
                continue;
544
            }
545
546
            // Deep copy directories
547
            if (("$source/$entry" !== $dest) && is_dir("$source/$entry")) {
548
                static::copyr("$source/$entry", "$dest/$entry");
549
            } else {
550
                copy("$source/$entry", "$dest/$entry");
551
            }
552
        }
553
554
        // Clean up
555
        $dir->close();
556
557
        return true;
558
    }
559
560
    /**
561
     * .* @credits Thanks to the NewBB2 Development Team
562
     * @param  string $item
563
     * @param  bool   $getStatus
564
     * @return bool|int|string
565
     */
566
    public static function &getPathStatus($item, $getStatus = false)
567
    {
568
        $path = '';
569
        if ('root' !== $item) {
570
            $path = $item;
571
        }
572
573
        $thePath = static::getUploadDir(true, $path);
574
575
        if (empty($thePath)) {
576
            return false;
577
        }
578
        if (is_writable($thePath)) {
579
            $pathCheckResult = 1;
580
            $pathStatus      = _AM_PUBLISHER_AVAILABLE;
581
        } elseif (!@is_dir($thePath)) {
582
            $pathCheckResult = -1;
583
            $pathStatus      = _AM_PUBLISHER_NOTAVAILABLE . " <a href='" . PUBLISHER_ADMIN_URL . "/index.php?op=createdir&amp;path={$item}'>" . _AM_PUBLISHER_CREATETHEDIR . '</a>';
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Publisher\PUBLISHER_ADMIN_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
584
        } else {
585
            $pathCheckResult = -2;
586
            $pathStatus      = _AM_PUBLISHER_NOTWRITABLE . " <a href='" . PUBLISHER_ADMIN_URL . "/index.php?op=setperm&amp;path={$item}'>" . _AM_PUBLISHER_SETMPERM . '</a>';
587
        }
588
        if (!$getStatus) {
589
            return $pathStatus;
590
        } else {
591
            return $pathCheckResult;
592
        }
593
    }
594
595
    /**
596
     * @credits Thanks to the NewBB2 Development Team
597
     * @param  string $target
598
     * @return bool
599
     */
600
    public static function mkdir($target)
601
    {
602
        // http://www.php.net/manual/en/function.mkdir.php
603
        // saint at corenova.com
604
        // bart at cdasites dot com
605
        if (empty($target) || is_dir($target)) {
606
            return true; // best case check first
607
        }
608
609
        if (file_exists($target) && !is_dir($target)) {
610
            return false;
611
        }
612
613
        if (static::mkdir(substr($target, 0, strrpos($target, '/')))) {
614
            if (!file_exists($target)) {
615
                $res = mkdir($target, 0777); // crawl back up & create dir tree
616
                static::chmod($target);
617
618
                return $res;
619
            }
620
        }
621
        $res = is_dir($target);
622
623
        return $res;
624
    }
625
626
    /**
627
     * @credits Thanks to the NewBB2 Development Team
628
     * @param  string $target
629
     * @param  int    $mode
630
     * @return bool
631
     */
632
    public static function chmod($target, $mode = 0777)
633
    {
634
        return @chmod($target, $mode);
635
    }
636
637
    /**
638
     * @param  bool   $hasPath
639
     * @param  string $item
640
     * @return string
641
     */
642
    public static function getUploadDir($hasPath = true, $item = '')
643
    {
644
        if ('' !== $item) {
645
            if ('root' === $item) {
646
                $item = '';
647
            } else {
648
                $item .= '/';
649
            }
650
        }
651
652
        if ($hasPath) {
653
            return PUBLISHER_UPLOAD_PATH . '/' . $item;
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Publisher\PUBLISHER_UPLOAD_PATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
654
        } else {
655
            return PUBLISHER_UPLOAD_URL . '/' . $item;
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Publisher\PUBLISHER_UPLOAD_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
656
        }
657
    }
658
659
    /**
660
     * @param  string $item
661
     * @param  bool   $hasPath
662
     * @return string
663
     */
664
    public static function getImageDir($item = '', $hasPath = true)
665
    {
666
        if ($item) {
667
            $item = "images/{$item}";
668
        } else {
669
            $item = 'images';
670
        }
671
672
        return static::getUploadDir($hasPath, $item);
673
    }
674
675
    /**
676
     * @param  array $errors
677
     * @return string
678
     */
679
    public static function formatErrors($errors = [])
680
    {
681
        $ret = '';
682
        foreach ($errors as $key => $value) {
683
            $ret .= '<br> - ' . $value;
684
        }
685
686
        return $ret;
687
    }
688
689
    /**
690
     * Checks if a user is admin of Publisher
691
     *
692
     * @return boolean
693
     */
694
    public static function userIsAdmin()
695
    {
696
        /** @var Publisher\Helper $helper */
697
        $helper = Publisher\Helper::getInstance();
698
699
        static $publisherIsAdmin;
700
701
        if (null !== $publisherIsAdmin) {
702
            return $publisherIsAdmin;
703
        }
704
705
        if (!$GLOBALS['xoopsUser']) {
706
            $publisherIsAdmin = false;
707
        } else {
708
            $publisherIsAdmin = $GLOBALS['xoopsUser']->isAdmin($helper->getModule()->getVar('mid'));
709
        }
710
711
        return $publisherIsAdmin;
712
    }
713
714
    /**
715
     * Check is current user is author of a given article
716
     *
717
     * @param  XoopsObject $itemObj
0 ignored issues
show
Bug introduced by
The type XoopsModules\Publisher\XoopsObject was not found. Did you mean XoopsObject? If so, make sure to prefix the type with \.
Loading history...
718
     * @return bool
719
     */
720
    public static function userIsAuthor($itemObj)
721
    {
722
        return (is_object($GLOBALS['xoopsUser']) && is_object($itemObj) && ($GLOBALS['xoopsUser']->uid() == $itemObj->uid()));
723
    }
724
725
    /**
726
     * Check is current user is moderator of a given article
727
     *
728
     * @param  XoopsObject $itemObj
729
     * @return bool
730
     */
731
    public static function userIsModerator($itemObj)
732
    {
733
        $helper         = Publisher\Helper::getInstance();
734
        $categoriesGranted = $helper->getHandler('Permission')->getGrantedItems('category_moderation');
0 ignored issues
show
Bug introduced by
The method getGrantedItems() does not exist on XoopsPersistableObjectHandler. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

734
        $categoriesGranted = $helper->getHandler('Permission')->/** @scrutinizer ignore-call */ getGrantedItems('category_moderation');
Loading history...
Bug introduced by
The method getGrantedItems() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler or XoopsModules\Publisher\PermissionHandler. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

734
        $categoriesGranted = $helper->getHandler('Permission')->/** @scrutinizer ignore-call */ getGrantedItems('category_moderation');
Loading history...
735
736
        return (is_object($itemObj) && in_array($itemObj->categoryid(), $categoriesGranted));
737
    }
738
739
    /**
740
     * Saves permissions for the selected category
741
     *
742
     * @param  null|array   $groups     : group with granted permission
743
     * @param  integer $categoryId : categoryid on which we are setting permissions
744
     * @param  string  $permName   : name of the permission
745
     * @return boolean : TRUE if the no errors occured
746
     */
747
    public static function saveCategoryPermissions($groups, $categoryId, $permName)
748
    {
749
        $helper = Publisher\Helper::getInstance();
750
751
        $result = true;
752
753
        $moduleId = $helper->getModule()->getVar('mid');
754
        /* @var  $grouppermHandler XoopsGroupPermHandler */
755
        $grouppermHandler = xoops_getHandler('groupperm');
756
        // First, if the permissions are already there, delete them
757
        $grouppermHandler->deleteByModule($moduleId, $permName, $categoryId);
758
759
        // Save the new permissions
760
        if (count($groups) > 0) {
761
            foreach ($groups as $groupId) {
762
                $grouppermHandler->addRight($permName, $categoryId, $groupId, $moduleId);
763
            }
764
        }
765
766
        return $result;
767
    }
768
769
    /**
770
     * @param  string $tablename
771
     * @param  string $iconname
772
     * @param  string $tabletitle
773
     * @param  string $tabledsc
774
     * @param  bool   $open
775
     * @return void
776
     */
777
    public static function openCollapsableBar($tablename = '', $iconname = '', $tabletitle = '', $tabledsc = '', $open = true)
778
    {
779
        $image   = 'open12.gif';
780
        $display = 'none';
781
        if ($open) {
782
            $image   = 'close12.gif';
783
            $display = 'block';
784
        }
785
786
        echo "<h3 style=\"color: #2F5376; font-weight: bold; font-size: 14px; margin: 6px 0 0 0; \"><a href='javascript:;' onclick=\"toggle('" . $tablename . "'); toggleIcon('" . $iconname . "')\">";
787
        echo "<img id='" . $iconname . "' src='" . PUBLISHER_URL . '/assets/images/links/' . $image . "' alt=''></a>&nbsp;" . $tabletitle . '</h3>';
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Publisher\PUBLISHER_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
788
        echo "<div id='" . $tablename . "' style='display: " . $display . ";'>";
789
        if ('' != $tabledsc) {
790
            echo '<span style="color: #567; margin: 3px 0 12px 0; font-size: small; display: block; ">' . $tabledsc . '</span>';
791
        }
792
    }
793
794
    /**
795
     * @param  string $name
796
     * @param  string $icon
797
     * @return void
798
     */
799
    public static function closeCollapsableBar($name, $icon)
800
    {
801
        echo '</div>';
802
803
        $urls = static::getCurrentUrls();
804
        $path = $urls['phpself'];
805
806
        $cookieName = $path . '_publisher_collaps_' . $name;
807
        $cookieName = str_replace('.', '_', $cookieName);
808
        $cookie     = static::getCookieVar($cookieName, '');
809
810
        if ('none' === $cookie) {
811
            echo '
812
        <script type="text/javascript"><!--
813
        toggle("' . $name . '"); toggleIcon("' . $icon . '");
814
        //-->
815
        </script>
816
        ';
817
        }
818
    }
819
820
    /**
821
     * @param  string $name
822
     * @param  string $value
823
     * @param  int    $time
824
     * @return void
825
     */
826
    public static function setCookieVar($name, $value, $time = 0)
827
    {
828
        if (0 === $time) {
829
            $time = time() + 3600 * 24 * 365;
830
        }
831
        setcookie($name, $value, $time, '/');
832
    }
833
834
    /**
835
     * @param  string $name
836
     * @param  string $default
837
     * @return string
838
     */
839
    public static function getCookieVar($name, $default = '')
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

839
    public static function getCookieVar(/** @scrutinizer ignore-unused */ $name, $default = '')

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

Loading history...
840
    {
841
        //    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...
842
        //        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...
843
        //    } 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...
844
        //        return $default;
845
        //    }
846
        return Request::getString('name', $default, 'COOKIE');
847
    }
848
849
    /**
850
     * @return array
851
     */
852
    public static function getCurrentUrls()
853
    {
854
        $http = false === strpos(XOOPS_URL, 'https://') ? 'http://' : 'https://';
855
        //    $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...
856
        //    $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...
857
        //    $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...
858
        $phpself     = Request::getString('PHP_SELF', '', 'SERVER');
859
        $httphost    = Request::getString('HTTP_HOST', '', 'SERVER');
860
        $querystring = Request::getString('QUERY_STRING', '', 'SERVER');
861
862
        if ('' != $querystring) {
863
            $querystring = '?' . $querystring;
864
        }
865
866
        $currenturl = $http . $httphost . $phpself . $querystring;
867
868
        $urls                = [];
869
        $urls['http']        = $http;
870
        $urls['httphost']    = $httphost;
871
        $urls['phpself']     = $phpself;
872
        $urls['querystring'] = $querystring;
873
        $urls['full']        = $currenturl;
874
875
        return $urls;
876
    }
877
878
    /**
879
     * @return string
880
     */
881
    public static function getCurrentPage()
882
    {
883
        $urls = static::getCurrentUrls();
884
885
        return $urls['full'];
886
    }
887
888
    /**
889
     * @param  null|Publisher\Category $categoryObj
890
     * @param  int|array              $selectedid
891
     * @param  int                    $level
892
     * @param  string                 $ret
893
     * @return string
894
     */
895
    public static function addCategoryOption(Publisher\Category $categoryObj, $selectedid = 0, $level = 0, $ret = '')
896
    {
897
        $helper = Publisher\Helper::getInstance();
898
899
        $spaces = '';
900
        for ($j = 0; $j < $level; ++$j) {
901
            $spaces .= '--';
902
        }
903
904
        $ret .= "<option value='" . $categoryObj->categoryid() . "'";
905
        if (is_array($selectedid) && in_array($categoryObj->categoryid(), $selectedid)) {
906
            $ret .= ' selected';
907
        } elseif ($categoryObj->categoryid() == $selectedid) {
908
            $ret .= ' selected';
909
        }
910
        $ret .= '>' . $spaces . $categoryObj->name() . "</option>\n";
911
912
        $subCategoriesObj = $helper->getHandler('Category')->getCategories(0, 0, $categoryObj->categoryid());
913
        if (count($subCategoriesObj) > 0) {
914
            ++$level;
915
            foreach ($subCategoriesObj as $catID => $subCategoryObj) {
916
                $ret .= static::addCategoryOption($subCategoryObj, $selectedid, $level);
917
            }
918
        }
919
920
        return $ret;
921
    }
922
923
    /**
924
     * @param  int|array    $selectedid
925
     * @param  int    $parentcategory
926
     * @param  bool   $allCatOption
927
     * @param  string $selectname
928
     * @return string
929
     */
930
    public static function createCategorySelect($selectedid = 0, $parentcategory = 0, $allCatOption = true, $selectname = 'options[0]')
931
    {
932
        $helper = Publisher\Helper::getInstance();
933
934
        $selectedid = explode(',', $selectedid);
0 ignored issues
show
Bug introduced by
It seems like $selectedid can also be of type array; however, parameter $string of explode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

934
        $selectedid = explode(',', /** @scrutinizer ignore-type */ $selectedid);
Loading history...
935
936
        $ret = "<select name='" . $selectname . "[]' multiple='multiple' size='10'>";
937
        if ($allCatOption) {
938
            $ret .= "<option value='0'";
939
            if (in_array(0, $selectedid)) {
940
                $ret .= ' selected';
941
            }
942
            $ret .= '>' . _MB_PUBLISHER_ALLCAT . '</option>';
943
        }
944
945
        // Creating category objects
946
        $categoriesObj = $helper->getHandler('Category')->getCategories(0, 0, $parentcategory);
947
948
        if (count($categoriesObj) > 0) {
949
            foreach ($categoriesObj as $catID => $categoryObj) {
950
                $ret .= static::addCategoryOption($categoryObj, $selectedid);
951
            }
952
        }
953
        $ret .= '</select>';
954
955
        return $ret;
956
    }
957
958
    /**
959
     * @param  int  $selectedid
960
     * @param  int  $parentcategory
961
     * @param  bool $allCatOption
962
     * @return string
963
     */
964
    public static function createCategoryOptions($selectedid = 0, $parentcategory = 0, $allCatOption = true)
965
    {
966
        $helper = Publisher\Helper::getInstance();
967
968
        $ret = '';
969
        if ($allCatOption) {
970
            $ret .= "<option value='0'";
971
            $ret .= '>' . _MB_PUBLISHER_ALLCAT . "</option>\n";
972
        }
973
974
        // Creating category objects
975
        $categoriesObj = $helper->getHandler('Category')->getCategories(0, 0, $parentcategory);
976
        if (count($categoriesObj) > 0) {
977
            foreach ($categoriesObj as $catID => $categoryObj) {
978
                $ret .= static::addCategoryOption($categoryObj, $selectedid);
979
            }
980
        }
981
982
        return $ret;
983
    }
984
985
    /**
986
     * @param  array  $errArray
987
     * @param  string $reseturl
988
     * @return void
989
     */
990
    public static function renderErrors(&$errArray, $reseturl = '')
991
    {
992
        if (is_array($errArray) && count($errArray) > 0) {
993
            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;">';
0 ignored issues
show
Bug introduced by
The constant XoopsModules\Publisher\PUBLISHER_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
994
995
            echo '<h4 style="text-align:left;margin:0; padding-top:0;">' . _AM_PUBLISHER_MSG_SUBMISSION_ERR;
996
997
            if ($reseturl) {
998
                echo ' <a href="' . $reseturl . '">[' . _AM_PUBLISHER_TEXT_SESSION_RESET . ']</a>';
999
            }
1000
1001
            echo '</h4><ul>';
1002
1003
            foreach ($errArray as $key => $error) {
1004
                if (is_array($error)) {
1005
                    foreach ($error as $err) {
1006
                        echo '<li><a href="#' . $key . '" onclick="var e = xoopsGetElementById(\'' . $key . '\'); e.focus();">' . htmlspecialchars($err, ENT_QUOTES | ENT_HTML5) . '</a></li>';
1007
                    }
1008
                } else {
1009
                    echo '<li><a href="#' . $key . '" onclick="var e = xoopsGetElementById(\'' . $key . '\'); e.focus();">' . htmlspecialchars($error, ENT_QUOTES | ENT_HTML5) . '</a></li>';
1010
                }
1011
            }
1012
            echo '</ul></div><br>';
1013
        }
1014
    }
1015
1016
    /**
1017
     * Generate publisher URL
1018
     *
1019
     * @param  string $page
1020
     * @param  array  $vars
1021
     * @param  bool   $encodeAmp
1022
     * @return string
1023
     *
1024
     * @credit : xHelp module, developped by 3Dev
1025
     */
1026
    public static function makeUri($page, $vars = [], $encodeAmp = true)
1027
    {
1028
        $joinStr = '';
1029
1030
        $amp = ($encodeAmp ? '&amp;' : '&');
1031
1032
        if (!count($vars)) {
1033
            return $page;
1034
        }
1035
1036
        $qs = '';
1037
        foreach ($vars as $key => $value) {
1038
            $qs      .= $joinStr . $key . '=' . $value;
1039
            $joinStr = $amp;
1040
        }
1041
1042
        return $page . '?' . $qs;
1043
    }
1044
1045
    /**
1046
     * @param  string $subject
1047
     * @return string
1048
     */
1049
    public static function tellAFriend($subject = '')
1050
    {
1051
        if (false !== strpos($subject, '%')) {
1052
            $subject = rawurldecode($subject);
1053
        }
1054
1055
        $targetUri = XOOPS_URL . Request::getString('REQUEST_URI', '', 'SERVER');
1056
1057
        return XOOPS_URL . '/modules/tellafriend/index.php?target_uri=' . rawurlencode($targetUri) . '&amp;subject=' . rawurlencode($subject);
1058
    }
1059
1060
    /**
1061
     * @param  bool        $another
1062
     * @param  bool        $withRedirect
1063
     * @param              $itemObj
1064
     * @return bool|string
1065
     */
1066
    public static function uploadFile($another = false, $withRedirect = true, &$itemObj)
1067
    {
1068
        xoops_load('XoopsMediaUploader');
1069
//        require_once PUBLISHER_ROOT_PATH . '/class/uploader.php';
1070
1071
        //    global $publisherIsAdmin;
1072
        $helper = Publisher\Helper::getInstance();
1073
1074
        $itemId  = Request::getInt('itemid', 0, 'POST');
1075
        $uid     = is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->uid() : 0;
1076
        $session = Session::getInstance();
1077
        $session->set('publisher_file_filename', Request::getString('item_file_name', '', 'POST'));
1078
        $session->set('publisher_file_description', Request::getString('item_file_description', '', 'POST'));
1079
        $session->set('publisher_file_status', Request::getInt('item_file_status', 1, 'POST'));
1080
        $session->set('publisher_file_uid', $uid);
1081
        $session->set('publisher_file_itemid', $itemId);
1082
1083
        if (!is_object($itemObj)) {
1084
            $itemObj = $helper->getHandler('Item')->get($itemId);
1085
        }
1086
1087
        $fileObj = $helper->getHandler('File')->create();
1088
        $fileObj->setVar('name', Request::getString('item_file_name', '', 'POST'));
1089
        $fileObj->setVar('description', Request::getString('item_file_description', '', 'POST'));
1090
        $fileObj->setVar('status', Request::getInt('item_file_status', 1, 'POST'));
1091
        $fileObj->setVar('uid', $uid);
1092
        $fileObj->setVar('itemid', $itemObj->getVar('itemid'));
1093
        $fileObj->setVar('datesub', time());
1094
1095
        // Get available mimetypes for file uploading
1096
        $allowedMimetypes = $helper->getHandler('Mimetype')->getArrayByType();
0 ignored issues
show
Bug introduced by
The method getArrayByType() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1096
        $allowedMimetypes = $helper->getHandler('Mimetype')->/** @scrutinizer ignore-call */ getArrayByType();
Loading history...
Bug introduced by
The method getArrayByType() does not exist on XoopsPersistableObjectHandler. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1096
        $allowedMimetypes = $helper->getHandler('Mimetype')->/** @scrutinizer ignore-call */ getArrayByType();
Loading history...
1097
        // TODO : display the available mimetypes to the user
1098
        $errors = [];
1099
        if ($helper->getConfig('perm_upload') && is_uploaded_file($_FILES['item_upload_file']['tmp_name'])) {
1100
            if (!$ret = $fileObj->checkUpload('item_upload_file', $allowedMimetypes, $errors)) {
0 ignored issues
show
Bug introduced by
The method checkUpload() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Publisher\Item or XoopsModules\Publisher\File or XoopsModules\Publisher\Category. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1100
            if (!$ret = $fileObj->/** @scrutinizer ignore-call */ checkUpload('item_upload_file', $allowedMimetypes, $errors)) {
Loading history...
Unused Code introduced by
The assignment to $ret is dead and can be removed.
Loading history...
1101
                $errorstxt = implode('<br>', $errors);
1102
1103
                $message = sprintf(_CO_PUBLISHER_MESSAGE_FILE_ERROR, $errorstxt);
1104
                if ($withRedirect) {
1105
                    redirect_header('file.php?op=mod&itemid=' . $itemId, 5, $message);
1106
                } else {
1107
                    return $message;
1108
                }
1109
            }
1110
        }
1111
1112
        // Storing the file
1113
        if (!$fileObj->store($allowedMimetypes)) {
0 ignored issues
show
Bug introduced by
The method store() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsComments or XoopsModules\Publisher\Item or XoopsModules\Publisher\File or XoopsModules\Publisher\Category. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1113
        if (!$fileObj->/** @scrutinizer ignore-call */ store($allowedMimetypes)) {
Loading history...
1114
            //        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...
1115
            //            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...
1116
            //            exit;
1117
            //        }
1118
            try {
1119
                if ($withRedirect) {
1120
                    throw new RuntimeException(_CO_PUBLISHER_FILEUPLOAD_ERROR . static::formatErrors($fileObj->getErrors()));
0 ignored issues
show
Bug introduced by
The type XoopsModules\Publisher\RuntimeException was not found. Did you mean RuntimeException? If so, make sure to prefix the type with \.
Loading history...
1121
                }
1122
            } catch (\Exception $e) {
1123
                $helper->addLog($e);
1124
                redirect_header('file.php?op=mod&itemid=' . $fileObj->itemid(), 3, _CO_PUBLISHER_FILEUPLOAD_ERROR . static::formatErrors($fileObj->getErrors()));
0 ignored issues
show
Bug introduced by
The method itemid() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Publisher\Item or XoopsModules\Publisher\File or XoopsModules\Publisher\Category. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

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

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1395
            $requiredVer = '' . /** @scrutinizer ignore-type */ $module->getInfo('min_xoops'); //making sure it's a string
Loading history...
1396
        }
1397
        $success     = true;
1398
1399
        if (version_compare($currentVer, $requiredVer, '<')) {
1400
            $success     = false;
1401
            $module->setErrors(sprintf(_AM_PUBLISHER_ERROR_BAD_XOOPS, $requiredVer, $currentVer));
1402
        }
1403
1404
        return $success;
1405
    }
1406
1407
    /**
1408
     *
1409
     * Verifies PHP version meets minimum requirements for this module
1410
     * @static
1411
     * @param \XoopsModule $module
1412
     *
1413
     * @return bool true if meets requirements, false if not
1414
     */
1415
    public static function checkVerPhp(\XoopsModule $module)
1416
    {
1417
        xoops_loadLanguage('admin', $module->dirname());
0 ignored issues
show
Bug introduced by
It seems like $module->dirname() can also be of type array and array; however, parameter $domain of xoops_loadLanguage() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1417
        xoops_loadLanguage('admin', /** @scrutinizer ignore-type */ $module->dirname());
Loading history...
1418
        // check for minimum PHP version
1419
        $success = true;
1420
        $verNum  = PHP_VERSION;
1421
        $reqVer  = $module->getInfo('min_php');
1422
        if (false !== $reqVer && '' !== $reqVer) {
1423
            if (version_compare($verNum, $reqVer, '<')) {
0 ignored issues
show
Bug introduced by
It seems like $reqVer can also be of type array; however, parameter $version2 of version_compare() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1423
            if (version_compare($verNum, /** @scrutinizer ignore-type */ $reqVer, '<')) {
Loading history...
1424
                $module->setErrors(sprintf(_AM_PUBLISHER_ERROR_BAD_PHP, $reqVer, $verNum));
0 ignored issues
show
Bug introduced by
It seems like $reqVer can also be of type array; however, parameter $args of sprintf() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

1424
                $module->setErrors(sprintf(_AM_PUBLISHER_ERROR_BAD_PHP, /** @scrutinizer ignore-type */ $reqVer, $verNum));
Loading history...
1425
                $success = false;
1426
            }
1427
        }
1428
1429
        return $success;
1430
    }
1431
1432
    /**
1433
     * truncateHtml can truncate a string up to a number of characters while preserving whole words and HTML tags
1434
     * www.gsdesign.ro/blog/cut-html-string-without-breaking-the-tags
1435
     * www.cakephp.org
1436
     *
1437
     * @param string  $text         String to truncate.
1438
     * @param integer $length       Length of returned string, including ellipsis.
1439
     * @param string  $ending       Ending to be appended to the trimmed string.
1440
     * @param boolean $exact        If false, $text will not be cut mid-word
1441
     * @param boolean $considerHtml If true, HTML tags would be handled correctly
1442
     *
1443
     * @return string Trimmed string.
1444
     */
1445
    public static function truncateHtml($text, $length = 100, $ending = '...', $exact = false, $considerHtml = true)
1446
    {
1447
        if ($considerHtml) {
1448
            // if the plain text is shorter than the maximum length, return the whole text
1449
            if (strlen(preg_replace('/<.*?' . '>/', '', $text)) <= $length) {
1450
                return $text;
1451
            }
1452
            // splits all html-tags to scanable lines
1453
            preg_match_all('/(<.+?' . '>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
1454
            $total_length = strlen($ending);
1455
            $open_tags    = [];
1456
            $truncate     = '';
1457
            foreach ($lines as $line_matchings) {
1458
                // if there is any html-tag in this line, handle it and add it (uncounted) to the output
1459
                if (!empty($line_matchings[1])) {
1460
                    // if it's an "empty element" with or without xhtml-conform closing slash
1461
                    if (preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
1462
                        // do nothing
1463
                        // if tag is a closing tag
1464
                    } elseif (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
1465
                        // delete tag from $open_tags list
1466
                        $pos = array_search($tag_matchings[1], $open_tags);
1467
                        if (false !== $pos) {
1468
                            unset($open_tags[$pos]);
1469
                        }
1470
                        // if tag is an opening tag
1471
                    } elseif (preg_match('/^<\s*([^\s>!]+).*?' . '>$/s', $line_matchings[1], $tag_matchings)) {
1472
                        // add tag to the beginning of $open_tags list
1473
                        array_unshift($open_tags, strtolower($tag_matchings[1]));
1474
                    }
1475
                    // add html-tag to $truncate'd text
1476
                    $truncate .= $line_matchings[1];
1477
                }
1478
                // calculate the length of the plain text part of the line; handle entities as one character
1479
                $content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
1480
                if ($total_length + $content_length > $length) {
1481
                    // the number of characters which are left
1482
                    $left            = $length - $total_length;
1483
                    $entities_length = 0;
1484
                    // search for html entities
1485
                    if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', $line_matchings[2], $entities, PREG_OFFSET_CAPTURE)) {
1486
                        // calculate the real length of all entities in the legal range
1487
                        foreach ($entities[0] as $entity) {
1488
                            if ($entity[1] + 1 - $entities_length <= $left) {
1489
                                $left--;
1490
                                $entities_length += strlen($entity[0]);
1491
                            } else {
1492
                                // no more characters left
1493
                                break;
1494
                            }
1495
                        }
1496
                    }
1497
                    $truncate .= substr($line_matchings[2], 0, $left + $entities_length);
1498
                    // maximum lenght is reached, so get off the loop
1499
                    break;
1500
                } else {
1501
                    $truncate     .= $line_matchings[2];
1502
                    $total_length += $content_length;
1503
                }
1504
                // if the maximum length is reached, get off the loop
1505
                if ($total_length >= $length) {
1506
                    break;
1507
                }
1508
            }
1509
        } else {
1510
            if (strlen($text) <= $length) {
1511
                return $text;
1512
            } else {
1513
                $truncate = substr($text, 0, $length - strlen($ending));
1514
            }
1515
        }
1516
        // if the words shouldn't be cut in the middle...
1517
        if (!$exact) {
1518
            // ...search the last occurance of a space...
1519
            $spacepos = strrpos($truncate, ' ');
1520
            if (isset($spacepos)) {
1521
                // ...and cut the text in this position
1522
                $truncate = substr($truncate, 0, $spacepos);
1523
            }
1524
        }
1525
        // add the defined ending to the text
1526
        $truncate .= $ending;
1527
        if ($considerHtml) {
1528
            // close all unclosed html-tags
1529
            foreach ($open_tags as $tag) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $open_tags does not seem to be defined for all execution paths leading up to this point.
Loading history...
1530
                $truncate .= '</' . $tag . '>';
1531
            }
1532
        }
1533
1534
        return $truncate;
1535
    }
1536
}
1537