Passed
Branch master (5b6d04)
by Michael
03:42
created

Utility   F

Complexity

Total Complexity 190

Size/Duplication

Total Lines 1348
Duplicated Lines 0 %

Importance

Changes 3
Bugs 2 Features 0
Metric Value
eloc 610
c 3
b 2
f 0
dl 0
loc 1348
rs 1.99
wmc 190

44 Methods

Rating   Name   Duplication   Size   Complexity  
A userIsAuthor() 0 3 3
A buildTableItemTitleRow() 0 18 1
A createFolder() 0 11 6
F createDir() 0 51 14
A recurseCopy() 0 14 5
A copyFile() 0 3 1
C uploadFile() 0 71 12
A userIsAdmin() 0 18 3
A getUploadDir() 0 15 4
A cpHeader() 0 14 1
A userIsModerator() 0 6 2
A getCurrentUrls() 0 24 3
C editCategory() 0 125 11
A setCookieVar() 0 6 2
A chmod() 0 3 1
A getCurrentPage() 0 5 1
A openCollapsableBar() 0 14 3
A makeUri() 0 17 4
A getPathStatus() 0 27 6
A moduleHome() 0 13 3
A createCategoryOptions() 0 19 4
B copyr() 0 32 10
A getCookieVar() 0 8 1
A closeCollapsableBar() 0 15 2
A getImageDir() 0 9 2
B getOrderBy() 0 19 7
A substr() 0 19 2
B mkdir() 0 24 7
A formatErrors() 0 8 2
A closeTags() 0 30 6
A createCategorySelect() 0 30 6
A truncateTagSafe() 0 18 4
A html2text() 0 51 1
A saveCategoryPermissions() 0 20 3
A getAllowedImagesTypes() 0 3 1
B addCategoryOption() 0 26 7
A tellAFriend() 0 9 2
A newFeatureTag() 0 5 1
B renderErrors() 0 23 7
B displayCategory() 0 46 6
A stringToInt() 0 9 2
D ratingBar() 0 77 13
A convertCharset() 0 16 4
A getEditors() 0 23 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
2
3
declare(strict_types=1);
4
5
namespace XoopsModules\Publisher;
6
7
/*
8
 You may not change or alter any portion of this comment or credits
9
 of supporting developers from this source code or any supporting source code
10
 which is considered copyrighted (c) material of the original comment or credit authors.
11
12
 This program is distributed in the hope that it will be useful,
13
 but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
 */
16
17
/**
18
 * PublisherUtil Class
19
 *
20
 * @copyright   XOOPS Project (https://xoops.org)
21
 * @license     http://www.fsf.org/copyleft/gpl.html GNU public license
22
 * @author      XOOPS Development Team
23
 * @since       1.03
24
 */
25
26
use Xmf\Request;
27
use XoopsModules\Publisher;
28
29
/**
30
 * Class Utility
31
 */
32
class Utility extends Common\SysUtility
33
{
34
    //--------------- Custom module methods -----------------------------
35
    /**
36
     * Function responsible for checking if a directory exists, we can also write in and create an index.html file
37
     *
38
     * @param string $folder The full path of the directory to check
39
     */
40
    public static function createFolder($folder)
41
    {
42
        try {
43
            if (!\is_dir($folder)) {
44
                if (!\is_dir($folder) && !\mkdir($folder) && !\is_dir($folder)) {
45
                    throw new \RuntimeException(\sprintf('Unable to create the %s directory', $folder));
46
                }
47
                file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
48
            }
49
        } catch (\Throwable $e) {
50
            echo 'Caught exception: ', $e->getMessage(), "\n", '<br>';
51
        }
52
    }
53
54
    /**
55
     * @param $file
56
     * @param $folder
57
     * @return bool
58
     */
59
    public static function copyFile($file, $folder)
60
    {
61
        return \copy($file, $folder);
62
        //        try {
63
        //            if (!is_dir($folder)) {
64
        //                throw new \RuntimeException(sprintf('Unable to copy file as: %s ', $folder));
65
        //            } else {
66
        //                return copy($file, $folder);
67
        //            }
68
        //        } catch (\Exception $e) {
69
        //            echo 'Caught exception: ', $e->getMessage(), "\n", "<br>";
70
        //        }
71
        //        return false;
72
    }
73
74
    /**
75
     * @param $src
76
     * @param $dst
77
     */
78
    public static function recurseCopy($src, $dst)
79
    {
80
        $dir = \opendir($src);
81
        //    @mkdir($dst);
82
        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

82
        while (false !== ($file = \readdir(/** @scrutinizer ignore-type */ $dir))) {
Loading history...
83
            if (('.' !== $file) && ('..' !== $file)) {
84
                if (\is_dir($src . '/' . $file)) {
85
                    self::recurseCopy($src . '/' . $file, $dst . '/' . $file);
86
                } else {
87
                    \copy($src . '/' . $file, $dst . '/' . $file);
88
                }
89
            }
90
        }
91
        \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

91
        \closedir(/** @scrutinizer ignore-type */ $dir);
Loading history...
92
    }
93
94
    // auto create folders----------------------------------------
95
    //TODO rename this function? And exclude image folder?
96
    public static function createDir()
97
    {
98
        // auto crate folders
99
        //        $thePath = static::getUploadDir();
100
101
        if (static::getPathStatus('root', true) < 0) {
102
            $thePath = static::getUploadDir();
103
            $res     = static::mkdir($thePath);
104
            $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...
105
        }
106
107
        if (static::getPathStatus('images', true) < 0) {
108
            $thePath = static::getImageDir();
109
            $res     = static::mkdir($thePath);
110
111
            if ($res) {
112
                $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...
113
                $dest   = $thePath . 'blank.png';
114
                static::copyr($source, $dest);
115
            }
116
            $msg = $res ? \_AM_PUBLISHER_DIRCREATED : \_AM_PUBLISHER_DIRNOTCREATED;
117
        }
118
119
        if (static::getPathStatus('images/category', true) < 0) {
120
            $thePath = static::getImageDir('category');
121
            $res     = static::mkdir($thePath);
122
123
            if ($res) {
124
                $source = PUBLISHER_ROOT_PATH . '/assets/images/blank.png';
125
                $dest   = $thePath . 'blank.png';
126
                static::copyr($source, $dest);
127
            }
128
            $msg = $res ? \_AM_PUBLISHER_DIRCREATED : \_AM_PUBLISHER_DIRNOTCREATED;
129
        }
130
131
        if (static::getPathStatus('images/item', true) < 0) {
132
            $thePath = static::getImageDir('item');
133
            $res     = static::mkdir($thePath);
134
135
            if ($res) {
136
                $source = PUBLISHER_ROOT_PATH . '/assets/images/blank.png';
137
                $dest   = $thePath . 'blank.png';
138
                static::copyr($source, $dest);
139
            }
140
            $msg = $res ? \_AM_PUBLISHER_DIRCREATED : \_AM_PUBLISHER_DIRNOTCREATED;
141
        }
142
143
        if (static::getPathStatus('content', true) < 0) {
144
            $thePath = static::getUploadDir(true, 'content');
145
            $res     = static::mkdir($thePath);
146
            $msg     = $res ? \_AM_PUBLISHER_DIRCREATED : \_AM_PUBLISHER_DIRNOTCREATED;
147
        }
148
    }
149
150
    public static function buildTableItemTitleRow()
151
    {
152
        echo "<table width='100%' cellspacing='1' cellpadding='3' border='0' class='outer'>";
153
        echo '<tr>';
154
        echo "<th width='40px' class='bg3' align='center'><strong>" . \_AM_PUBLISHER_ITEMID . '</strong></td>';
155
        echo "<th width='100px' class='bg3' align='center'><strong>" . \_AM_PUBLISHER_ITEMCAT . '</strong></td>';
156
        echo "<th class='bg3' align='center'><strong>" . \_AM_PUBLISHER_TITLE . '</strong></td>';
157
        echo "<th width='100px' class='bg3' align='center'><strong>" . \_AM_PUBLISHER_CREATED . '</strong></td>';
158
159
        echo "<th width='50px' class='bg3' align='center'><strong>" . \_CO_PUBLISHER_WEIGHT . '</strong></td>';
160
        echo "<th width='50px' class='bg3' align='center'><strong>" . \_AM_PUBLISHER_HITS . '</strong></td>';
161
        echo "<th width='60px' class='bg3' align='center'><strong>" . \_AM_PUBLISHER_RATE . '</strong></td>';
162
        echo "<th width='50px' class='bg3' align='center'><strong>" . \_AM_PUBLISHER_VOTES . '</strong></td>';
163
        echo "<th width='60px' class='bg3' align='center'><strong>" . \_AM_PUBLISHER_COMMENTS_COUNT . '</strong></td>';
164
165
        echo "<th width='90px' class='bg3' align='center'><strong>" . \_CO_PUBLISHER_STATUS . '</strong></td>';
166
        echo "<th width='90px' class='bg3' align='center'><strong>" . \_AM_PUBLISHER_ACTION . '</strong></td>';
167
        echo '</tr>';
168
    }
169
170
    /**
171
     * @param Category $categoryObj
172
     * @param int      $level
173
     */
174
    public static function displayCategory(Category $categoryObj, $level = 0)
175
    {
176
        $helper = Helper::getInstance();
177
178
        $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

178
        /** @scrutinizer ignore-call */ 
179
        $description = $categoryObj->description();
Loading history...
179
        if (!XOOPS_USE_MULTIBYTES && !is_null($description)) {
180
            if (\mb_strlen($description) >= 100) {
0 ignored issues
show
Bug introduced by
It seems like $description can also be of type array and array; however, parameter $str of mb_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

180
            if (\mb_strlen(/** @scrutinizer ignore-type */ $description) >= 100) {
Loading history...
181
                $description = \mb_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 $str of mb_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

181
                $description = \mb_substr(/** @scrutinizer ignore-type */ $description, 0, 100 - 1) . '...';
Loading history...
182
            }
183
        }
184
        $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

184
        $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

184
        $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...
185
        $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>";
186
        $spaces = \str_repeat('&nbsp;', ($level * 3));
187
        /*
188
        $spaces = '';
189
        for ($j = 0; $j < $level; ++$j) {
190
            $spaces .= '&nbsp;&nbsp;&nbsp;';
191
        }
192
        */
193
        echo "<tr>\n"
194
             . "<td class='even center'>"
195
             . $categoryObj->categoryid()
196
             . "</td>\n"
197
             . "<td class='even left'>"
198
             . $spaces
199
             . "<a href='"
200
             . PUBLISHER_URL
201
             . '/category.php?categoryid='
202
             . $categoryObj->categoryid()
203
             . "'><img src='"
204
             . PUBLISHER_URL
205
             . "/assets/images/links/subcat.gif' alt=''>&nbsp;"
206
             . $categoryObj->name()
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

206
             . $categoryObj->/** @scrutinizer ignore-call */ name()
Loading history...
207
             . "</a></td>\n"
208
             . "<td class='even center'>"
209
             . $categoryObj->weight()
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

209
             . $categoryObj->/** @scrutinizer ignore-call */ weight()
Loading history...
210
             . "</td>\n"
211
             . "<td class='even center'> {$modify} {$delete} </td>\n"
212
             . "</tr>\n";
213
        $subCategoriesObj = $helper->getHandler('Category')->getCategories(0, 0, $categoryObj->categoryid());
214
        if (\count($subCategoriesObj) > 0) {
215
            ++$level;
216
            foreach ($subCategoriesObj as $thiscat) {
217
                self::displayCategory($thiscat, $level);
218
            }
219
            unset($key);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $key seems to be never defined.
Loading history...
220
        }
221
        //        unset($categoryObj);
222
    }
223
224
    /**
225
     * @param bool          $showmenu
226
     * @param int           $categoryId
227
     * @param int           $nbSubCats
228
     * @param Category|null $categoryObj
229
     */
230
    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

230
    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...
231
    {
232
        $helper = Helper::getInstance();
233
234
        // if there is a parameter, and the id exists, retrieve data: we're editing a category
235
        /** @var  Category $categoryObj */
236
        if (0 != $categoryId) {
237
            // Creating the category object for the selected category
238
            $categoryObj = $helper->getHandler('Category')->get($categoryId);
239
            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

239
            if ($categoryObj->/** @scrutinizer ignore-call */ notLoaded()) {
Loading history...
240
                \redirect_header('category.php', 1, \_AM_PUBLISHER_NOCOLTOEDIT);
241
            }
242
        } elseif (null === $categoryObj) {
243
            $categoryObj = $helper->getHandler('Category')->create();
244
        }
245
246
        if (0 != $categoryId) {
247
            echo "<br>\n";
248
            static::openCollapsableBar('edittable', 'edittableicon', \_AM_PUBLISHER_EDITCOL, \_AM_PUBLISHER_CATEGORY_EDIT_INFO);
249
        } else {
250
            static::openCollapsableBar('createtable', 'createtableicon', \_AM_PUBLISHER_CATEGORY_CREATE, \_AM_PUBLISHER_CATEGORY_CREATE_INFO);
251
        }
252
253
        $sform = $categoryObj->getForm($nbSubCats);
254
        $sform->display();
255
256
        if (!$categoryId) {
257
            static::closeCollapsableBar('createtable', 'createtableicon');
258
        } else {
259
            static::closeCollapsableBar('edittable', 'edittableicon');
260
        }
261
262
        //Added by fx2024
263
        if ($categoryId) {
264
            $selCat = $categoryId;
265
266
            static::openCollapsableBar('subcatstable', 'subcatsicon', \_AM_PUBLISHER_SUBCAT_CAT, \_AM_PUBLISHER_SUBCAT_CAT_DSC);
267
            // Get the total number of sub-categories
268
            $categoriesObj = $helper->getHandler('Category')->get($selCat);
269
            $totalsubs     = $helper->getHandler('Category')->getCategoriesCount($selCat);
270
            // creating the categories objects that are published
271
            $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

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

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

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

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

727
        return (\is_object($GLOBALS['xoopsUser']) && \is_object($itemObj) && ($GLOBALS['xoopsUser']->uid() == $itemObj->/** @scrutinizer ignore-call */ uid()));
Loading history...
728
    }
729
730
    /**
731
     * Check is current user is moderator of a given article
732
     *
733
     * @param \XoopsObject $itemObj
734
     * @return bool
735
     */
736
    public static function userIsModerator($itemObj)
737
    {
738
        $helper            = Helper::getInstance();
739
        $categoriesGranted = $helper->getHandler('Permission')->getGrantedItems('category_moderation');
740
741
        return (\is_object($itemObj) && \in_array($itemObj->categoryid(), $categoriesGranted, true));
742
    }
743
744
    /**
745
     * Saves permissions for the selected category
746
     *
747
     * @param null|array $groups     : group with granted permission
748
     * @param int        $categoryId : categoryid on which we are setting permissions
749
     * @param string     $permName   : name of the permission
750
     * @return bool : TRUE if the no errors occured
751
     */
752
    public static function saveCategoryPermissions($groups, $categoryId, $permName)
753
    {
754
        $helper = Helper::getInstance();
755
756
        $result = true;
757
758
        $moduleId = $helper->getModule()->getVar('mid');
759
        /** @var \XoopsGroupPermHandler $grouppermHandler */
760
        $grouppermHandler = \xoops_getHandler('groupperm');
761
        // First, if the permissions are already there, delete them
762
        $grouppermHandler->deleteByModule($moduleId, $permName, $categoryId);
763
764
        // Save the new permissions
765
        if (\count($groups) > 0) {
766
            foreach ($groups as $groupId) {
767
                $grouppermHandler->addRight($permName, $categoryId, $groupId, $moduleId);
768
            }
769
        }
770
771
        return $result;
772
    }
773
774
    /**
775
     * @param string $tablename
776
     * @param string $iconname
777
     * @param string $tabletitle
778
     * @param string $tabledsc
779
     * @param bool   $open
780
     */
781
    public static function openCollapsableBar($tablename = '', $iconname = '', $tabletitle = '', $tabledsc = '', $open = true)
782
    {
783
        $image   = 'open12.gif';
784
        $display = 'none';
785
        if ($open) {
786
            $image   = 'close12.gif';
787
            $display = 'block';
788
        }
789
790
        echo "<h3 style=\"color: #2F5376; font-weight: bold; font-size: 14px; margin: 6px 0 0 0; \"><a href='javascript:;' onclick=\"toggle('" . $tablename . "'); toggleIcon('" . $iconname . "')\">";
791
        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...
792
        echo "<div id='" . $tablename . "' style='display: " . $display . ";'>";
793
        if ('' != $tabledsc) {
794
            echo '<span style="color: #567; margin: 3px 0 12px 0; font-size: small; display: block; ">' . $tabledsc . '</span>';
795
        }
796
    }
797
798
    /**
799
     * @param string $name
800
     * @param string $icon
801
     */
802
    public static function closeCollapsableBar($name, $icon)
803
    {
804
        echo '</div>';
805
806
        $urls = static::getCurrentUrls();
807
        $path = $urls['phpself'];
808
809
        $cookieName = $path . '_publisher_collaps_' . $name;
810
        $cookieName = \str_replace('.', '_', $cookieName);
811
        $cookie     = static::getCookieVar($cookieName, '');
812
813
        if ('none' === $cookie) {
814
            echo '
815
        <script type="text/javascript"><!--
816
        toggle("' . $name . '"); toggleIcon("' . $icon . '");
817
        //-->
818
        </script>
819
        ';
820
        }
821
    }
822
823
    /**
824
     * @param string $name
825
     * @param string $value
826
     * @param int    $time
827
     */
828
    public static function setCookieVar($name, $value, $time = 0)
829
    {
830
        if (0 === $time) {
831
            $time = \time() + 3600 * 24 * 365;
832
        }
833
        setcookie($name, $value, $time, '/');
834
    }
835
836
    /**
837
     * @param string $name
838
     * @param string $default
839
     * @return string
840
     */
841
    public static function getCookieVar($name, $default = '')
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

841
    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...
842
    {
843
        //    if (isset($_COOKIE[$name]) && ($_COOKIE[$name] > '')) {
844
        //        return $_COOKIE[$name];
845
        //    } else {
846
        //        return $default;
847
        //    }
848
        return Request::getString('name', $default, 'COOKIE');
849
    }
850
851
    /**
852
     * @return array
853
     */
854
    public static function getCurrentUrls()
855
    {
856
        $http = false === \mb_strpos(XOOPS_URL, 'https://') ? 'http://' : 'https://';
857
        //    $phpself     = $_SERVER['SCRIPT_NAME'];
858
        //    $httphost    = $_SERVER['HTTP_HOST'];
859
        //    $querystring = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '';
860
        $phpself     = Request::getString('SCRIPT_NAME', '', 'SERVER');
861
        $httphost    = Request::getString('HTTP_HOST', '', 'SERVER');
862
        $querystring = Request::getString('QUERY_STRING', '', 'SERVER');
863
864
        if ('' != $querystring) {
865
            $querystring = '?' . $querystring;
866
        }
867
868
        $currenturl = $http . $httphost . $phpself . $querystring;
869
870
        $urls                = [];
871
        $urls['http']        = $http;
872
        $urls['httphost']    = $httphost;
873
        $urls['phpself']     = $phpself;
874
        $urls['querystring'] = $querystring;
875
        $urls['full']        = $currenturl;
876
877
        return $urls;
878
    }
879
880
    /**
881
     * @return string
882
     */
883
    public static function getCurrentPage()
884
    {
885
        $urls = static::getCurrentUrls();
886
887
        return $urls['full'];
888
    }
889
890
    /**
891
     * @param null|Category $categoryObj
892
     * @param int|array     $selectedId
893
     * @param int           $level
894
     * @param string        $ret
895
     * @return string
896
     */
897
    public static function addCategoryOption(Category $categoryObj, $selectedId = 0, $level = 0, $ret = '')
898
    {
899
        $helper = Helper::getInstance();
900
901
        $spaces = '';
902
        for ($j = 0; $j < $level; ++$j) {
903
            $spaces .= '--';
904
        }
905
906
        $ret .= "<option value='" . $categoryObj->categoryid() . "'";
907
        if (\is_array($selectedId) && \in_array($categoryObj->categoryid(), $selectedId, true)) {
908
            $ret .= ' selected';
909
        } elseif ($categoryObj->categoryid() == $selectedId) {
910
            $ret .= ' selected';
911
        }
912
        $ret .= '>' . $spaces . $categoryObj->name() . "</option>\n";
913
914
        $subCategoriesObj = $helper->getHandler('Category')->getCategories(0, 0, $categoryObj->categoryid());
915
        if (\count($subCategoriesObj) > 0) {
916
            ++$level;
917
            foreach ($subCategoriesObj as $catId => $subCategoryObj) {
918
                $ret .= static::addCategoryOption($subCategoryObj, $selectedId, $level);
919
            }
920
        }
921
922
        return $ret;
923
    }
924
925
    /**
926
     * @param int|array $selectedId
927
     * @param int       $parentcategory
928
     * @param bool      $allCatOption
929
     * @param string    $selectname
930
     * @param bool      $multiple
931
     * @return string
932
     */
933
    public static function createCategorySelect($selectedId = 0, $parentcategory = 0, $allCatOption = true, $selectname = 'options[1]', $multiple = true)
934
    {
935
        $helper = Helper::getInstance();
936
937
        $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

937
        $selectedId  = \explode(',', /** @scrutinizer ignore-type */ $selectedId);
Loading history...
938
        $selectedId  = \array_map('\intval', $selectedId);
939
        $selMultiple = '';
940
        if ($multiple) {
941
            $selMultiple = " multiple='multiple'";
942
        }
943
        $ret = "<select name='" . $selectname . "[]'" . $selMultiple . " size='10'>";
944
        if ($allCatOption) {
945
            $ret .= "<option value='0'";
946
            if (\in_array(0, $selectedId, true)) {
947
                $ret .= ' selected';
948
            }
949
            $ret .= '>' . \_MB_PUBLISHER_ALLCAT . '</option>';
950
        }
951
952
        // Creating category objects
953
        $categoriesObj = $helper->getHandler('Category')->getCategories(0, 0, $parentcategory);
954
955
        if (\count($categoriesObj) > 0) {
956
            foreach ($categoriesObj as $catId => $categoryObj) {
957
                $ret .= static::addCategoryOption($categoryObj, $selectedId);
958
            }
959
        }
960
        $ret .= '</select>';
961
962
        return $ret;
963
    }
964
965
    /**
966
     * @param int  $selectedId
967
     * @param int  $parentcategory
968
     * @param bool $allCatOption
969
     * @return string
970
     */
971
    public static function createCategoryOptions($selectedId = 0, $parentcategory = 0, $allCatOption = true)
972
    {
973
        $helper = Helper::getInstance();
974
975
        $ret = '';
976
        if ($allCatOption) {
977
            $ret .= "<option value='0'";
978
            $ret .= '>' . \_MB_PUBLISHER_ALLCAT . "</option>\n";
979
        }
980
981
        // Creating category objects
982
        $categoriesObj = $helper->getHandler('Category')->getCategories(0, 0, $parentcategory);
983
        if (\count($categoriesObj) > 0) {
984
            foreach ($categoriesObj as $catId => $categoryObj) {
985
                $ret .= static::addCategoryOption($categoryObj, $selectedId);
986
            }
987
        }
988
989
        return $ret;
990
    }
991
992
    /**
993
     * @param array  $errArray
994
     * @param string $reseturl
995
     */
996
    public static function renderErrors($errArray, $reseturl = '')
997
    {
998
        if ($errArray && \is_array($errArray)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $errArray of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
999
            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...
1000
1001
            echo '<h4 style="text-align:left;margin:0; padding-top:0;">' . \_AM_PUBLISHER_MSG_SUBMISSION_ERR;
1002
1003
            if ($reseturl) {
1004
                echo ' <a href="' . $reseturl . '">[' . \_AM_PUBLISHER_TEXT_SESSION_RESET . ']</a>';
1005
            }
1006
1007
            echo '</h4><ul>';
1008
1009
            foreach ($errArray as $key => $error) {
1010
                if (\is_array($error)) {
1011
                    foreach ($error as $err) {
1012
                        echo '<li><a href="#' . $key . '" onclick="var e = xoopsGetElementById(\'' . $key . '\'); e.focus();">' . \htmlspecialchars($err, \ENT_QUOTES | \ENT_HTML5) . '</a></li>';
1013
                    }
1014
                } else {
1015
                    echo '<li><a href="#' . $key . '" onclick="var e = xoopsGetElementById(\'' . $key . '\'); e.focus();">' . \htmlspecialchars($error, \ENT_QUOTES | \ENT_HTML5) . '</a></li>';
1016
                }
1017
            }
1018
            echo '</ul></div><br>';
1019
        }
1020
    }
1021
1022
    /**
1023
     * Generate publisher URL
1024
     *
1025
     * @param string $page
1026
     * @param array  $vars
1027
     * @param bool   $encodeAmp
1028
     * @return string
1029
     *
1030
     * @credit : xHelp module, developped by 3Dev
1031
     */
1032
    public static function makeUri($page, $vars = [], $encodeAmp = true)
1033
    {
1034
        $joinStr = '';
1035
1036
        $amp = ($encodeAmp ? '&amp;' : '&');
1037
1038
        if (!\count($vars)) {
1039
            return $page;
1040
        }
1041
1042
        $qs = '';
1043
        foreach ($vars as $key => $value) {
1044
            $qs      .= $joinStr . $key . '=' . $value;
1045
            $joinStr = $amp;
1046
        }
1047
1048
        return $page . '?' . $qs;
1049
    }
1050
1051
    /**
1052
     * @param string $subject
1053
     * @return string
1054
     */
1055
    public static function tellAFriend($subject = '')
1056
    {
1057
        if (false !== \mb_strpos($subject, '%')) {
1058
            $subject = \rawurldecode($subject);
1059
        }
1060
1061
        $targetUri = XOOPS_URL . Request::getString('REQUEST_URI', '', 'SERVER');
1062
1063
        return XOOPS_URL . '/modules/tellafriend/index.php?target_uri=' . \rawurlencode($targetUri) . '&amp;subject=' . \rawurlencode($subject);
1064
    }
1065
1066
    /**
1067
     * @param bool $another
1068
     * @param bool $withRedirect
1069
     * @param Item $itemObj
1070
     * @return bool|string
1071
     */
1072
    public static function uploadFile($another, $withRedirect, &$itemObj)
1073
    {
1074
        \xoops_load('XoopsMediaUploader');
1075
        //        require_once PUBLISHER_ROOT_PATH . '/class/uploader.php';
1076
1077
        //    global $publisherIsAdmin;
1078
        $helper = Helper::getInstance();
1079
1080
        $itemId  = Request::getInt('itemid', 0, 'POST');
1081
        $uid     = \is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->uid() : 0;
1082
        $session = Session::getInstance();
1083
        $session->set('publisher_file_filename', Request::getString('item_file_name', '', 'POST'));
1084
        $session->set('publisher_file_description', Request::getString('item_file_description', '', 'POST'));
1085
        $session->set('publisher_file_status', Request::getInt('item_file_status', 1, 'POST'));
1086
        $session->set('publisher_file_uid', $uid);
1087
        $session->set('publisher_file_itemid', $itemId);
1088
1089
        if (!\is_object($itemObj)) {
1090
            $itemObj = $helper->getHandler('Item')->get($itemId);
1091
        }
1092
1093
        $fileObj = $helper->getHandler('File')->create();
1094
        $fileObj->setVar('name', Request::getString('item_file_name', '', 'POST'));
1095
        $fileObj->setVar('description', Request::getString('item_file_description', '', 'POST'));
1096
        $fileObj->setVar('status', Request::getInt('item_file_status', 1, 'POST'));
1097
        $fileObj->setVar('uid', $uid);
1098
        $fileObj->setVar('itemid', $itemObj->getVar('itemid'));
1099
        $fileObj->setVar('datesub', \time());
1100
1101
        // Get available mimetypes for file uploading
1102
        $allowedMimetypes = $helper->getHandler('Mimetype')->getArrayByType();
1103
        // TODO : display the available mimetypes to the user
1104
        $errors = [];
1105
        if ($helper->getConfig('perm_upload') && \is_uploaded_file($_FILES['item_upload_file']['tmp_name'])) {
1106
            if (!$ret = $fileObj->checkUpload('item_upload_file', $allowedMimetypes, $errors)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $ret is dead and can be removed.
Loading history...
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

1106
            if (!$ret = $fileObj->/** @scrutinizer ignore-call */ checkUpload('item_upload_file', $allowedMimetypes, $errors)) {
Loading history...
1107
                $errorstxt = \implode('<br>', $errors);
1108
1109
                $message = \sprintf(\_CO_PUBLISHER_MESSAGE_FILE_ERROR, $errorstxt);
1110
                if ($withRedirect) {
1111
                    \redirect_header('file.php?op=mod&itemid=' . $itemId, 5, $message);
1112
                } else {
1113
                    return $message;
1114
                }
1115
            }
1116
        }
1117
1118
        // Storing the file
1119
        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

1119
        if (!$fileObj->/** @scrutinizer ignore-call */ store($allowedMimetypes)) {
Loading history...
1120
            //        if ($withRedirect) {
1121
            //            redirect_header("file.php?op=mod&itemid=" . $fileObj->itemid(), 3, _CO_PUBLISHER_FILEUPLOAD_ERROR . static::formatErrors($fileObj->getErrors()));
1122
            //        }
1123
            try {
1124
                if ($withRedirect) {
1125
                    throw new \RuntimeException(\_CO_PUBLISHER_FILEUPLOAD_ERROR . static::formatErrors($fileObj->getErrors()));
1126
                }
1127
            } catch (\Throwable $e) {
1128
                $helper->addLog($e);
1129
                \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

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