Passed
Branch master (7e303a)
by Michael
02:15
created

Utility::uploadFile()   C

Complexity

Conditions 12
Paths 112

Size

Total Lines 74
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 42
nc 112
nop 3
dl 0
loc 74
rs 6.8666
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace XoopsModules\Publisher;
4
5
/*
6
 You may not change or alter any portion of this comment or credits
7
 of supporting developers from this source code or any supporting source code
8
 which is considered copyrighted (c) material of the original comment or credit authors.
9
10
 This program is distributed in the hope that it will be useful,
11
 but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
15
/**
16
 * PublisherUtil Class
17
 *
18
 * @copyright   XOOPS Project (https://xoops.org)
19
 * @license     http://www.fsf.org/copyleft/gpl.html GNU public license
20
 * @author      XOOPS Development Team
21
 * @package     Publisher
22
 * @since       1.03
23
 *
24
 */
25
26
use Xmf\Request;
27
use XoopsModules\Publisher;
28
use XoopsModules\Publisher\Common;
29
use XoopsModules\Publisher\Constants;
30
31
/**
32
 * Class Utility
33
 */
34
class Utility
35
{
36
    use Common\VersionChecks; //checkVerXoops, checkVerPhp Traits
37
38
    use Common\ServerStats; // getServerStats Trait
39
40
    use Common\FilesManagement; // Files Management Trait
41
42
    //--------------- Custom module methods -----------------------------
43
44
    /**
45
     * Function responsible for checking if a directory exists, we can also write in and create an index.html file
46
     *
47
     * @param string $folder The full path of the directory to check
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
                }
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)) {
74
        //                throw new \RuntimeException(sprintf('Unable to copy file as: %s ', $folder));
75
        //            } else {
76
        //                return copy($file, $folder);
77
        //            }
78
        //        } catch (\Exception $e) {
79
        //            echo 'Caught exception: ', $e->getMessage(), "\n", "<br>";
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();
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
        /** @var Publisher\Helper $helper */
187
        $helper = Publisher\Helper::getInstance();
188
189
        $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

189
        /** @scrutinizer ignore-call */ 
190
        $description = $categoryObj->description();
Loading history...
190
        if (!XOOPS_USE_MULTIBYTES) {
191
            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

191
            if (mb_strlen(/** @scrutinizer ignore-type */ $description) >= 100) {
Loading history...
192
                $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

192
                $description = mb_substr(/** @scrutinizer ignore-type */ $description, 0, 100 - 1) . '...';
Loading history...
193
            }
194
        }
195
        $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 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

195
        $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...
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

195
        $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...
196
        $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>";
197
198
        $spaces = '';
199
        for ($j = 0; $j < $level; ++$j) {
200
            $spaces .= '&nbsp;&nbsp;&nbsp;';
201
        }
202
203
        echo '<tr>';
204
        echo "<td class='even' align='center'>" . $categoryObj->categoryid() . '</td>';
205
        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

205
        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...
206
        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

206
        echo "<td class='even' align='center'>" . $categoryObj->/** @scrutinizer ignore-call */ weight() . '</td>';
Loading history...
207
        echo "<td class='even' align='center'> $modify $delete </td>";
208
        echo '</tr>';
209
        $subCategoriesObj = $helper->getHandler('Category')->getCategories(0, 0, $categoryObj->categoryid());
0 ignored issues
show
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

209
        $subCategoriesObj = $helper->getHandler('Category')->/** @scrutinizer ignore-call */ getCategories(0, 0, $categoryObj->categoryid());
Loading history...
210
        if (count($subCategoriesObj) > 0) {
211
            ++$level;
212
            foreach ($subCategoriesObj as $key => $thiscat) {
213
                self::displayCategory($thiscat, $level);
214
            }
215
            unset($key);
216
        }
217
        //        unset($categoryObj);
218
    }
219
220
    /**
221
     * @param bool $showmenu
222
     * @param int  $categoryId
223
     * @param int  $nbSubCats
224
     * @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...
225
     */
226
    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

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

236
            if ($categoryObj->/** @scrutinizer ignore-call */ notLoaded()) {
Loading history...
237
                redirect_header('category.php', 1, _AM_PUBLISHER_NOCOLTOEDIT);
238
                //            exit();
239
            }
240
        } else {
241
            if (!$categoryObj) {
0 ignored issues
show
introduced by
$categoryObj is of type XoopsModules\Publisher\Category, thus it always evaluated to true. If $categoryObj can have other possible types, add them to class/Utility.php:232
Loading history...
242
                $categoryObj = $helper->getHandler('Category')->create();
243
            }
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);
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

253
        /** @scrutinizer ignore-call */ 
254
        $sform = $categoryObj->getForm($nbSubCats);
Loading history...
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);
0 ignored issues
show
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

269
            $totalsubs     = $helper->getHandler('Category')->/** @scrutinizer ignore-call */ getCategoriesCount($selCat);
Loading history...
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
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

304
            $totalitems = $helper->getHandler('Item')->/** @scrutinizer ignore-call */ getItemsCount($selCat, [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);
0 ignored issues
show
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

306
            $itemsObj         = $helper->getHandler('Item')->/** @scrutinizer ignore-call */ getAllPublished($helper->getConfig('idxcat_perpage'), $startitem, $selCat);
Loading history...
307
            $totalitemsOnPage = count($itemsObj);
308
            $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

308
            $allcats          = $helper->getHandler('Category')->/** @scrutinizer ignore-call */ getObjects(null, true);
Loading history...
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=" . $itemsObj[$i]->itemid() . "'><img src='" . XOOPS_URL . '/modules/' . $helper->getModule()->dirname() . "/assets/images/links/delete.png' title='" . _AM_PUBLISHER_DELETEITEM . "' alt='" . _AM_PUBLISHER_DELETEITEM . "'></a>";
322
                    echo '<tr>';
323
                    echo "<td class='head' align='center'>" . $itemsObj[$i]->itemid() . '</td>';
324
                    echo "<td class='even' align='left'>" . $categoryObj->name() . '</td>';
325
                    echo "<td class='even' align='left'>" . $itemsObj[$i]->getitemLink() . '</td>';
326
                    echo "<td class='even' align='center'>" . $itemsObj[$i]->getDatesub('s') . '</td>';
327
                    echo "<td class='even' align='center'> $modify $delete </td>";
328
                    echo '</tr>';
329
                }
330
            } else {
331
                $itemid = -1;
0 ignored issues
show
Unused Code introduced by
The assignment to $itemid is dead and can be removed.
Loading history...
332
                echo '<tr>';
333
                echo "<td class='head' align='center' colspan= '7'>" . _AM_PUBLISHER_NOITEMS . '</td>';
334
                echo '</tr>';
335
            }
336
            echo "</table>\n";
337
            echo "<br>\n";
338
            $parentid         = Request::getInt('parentid', 0, 'GET');
339
            $pagenavExtraArgs = "op=mod&categoryid=$selCat&parentid=$parentid";
340
            xoops_load('XoopsPageNav');
341
            $pagenav = new \XoopsPageNav($totalitems, $helper->getConfig('idxcat_perpage'), $startitem, 'startitem', $pagenavExtraArgs);
342
            echo '<div style="text-align:right;">' . $pagenav->renderNav() . '</div>';
343
            echo "<input type='button' name='button' onclick=\"location='item.php?op=mod&categoryid=" . $selCat . "'\" value='" . _AM_PUBLISHER_CREATEITEM . "'>&nbsp;&nbsp;";
344
            echo '</div>';
345
        }
346
        //end of fx2024 code
347
    }
348
349
350
    //======================== FUNCTIONS =================================
351
352
    /**
353
     * Includes scripts in HTML header
354
     */
355
    public static function cpHeader()
356
    {
357
        xoops_cp_header();
358
359
        //cannot use xoTheme, some conflit with admin gui
360
        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

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

712
        return (is_object($GLOBALS['xoopsUser']) && is_object($itemObj) && ($GLOBALS['xoopsUser']->uid() == $itemObj->/** @scrutinizer ignore-call */ uid()));
Loading history...
713
    }
714
715
    /**
716
     * Check is current user is moderator of a given article
717
     *
718
     * @param  \XoopsObject $itemObj
719
     * @return bool
720
     */
721
    public static function userIsModerator($itemObj)
722
    {
723
        /** @var Publisher\Helper $helper */
724
        $helper            = Publisher\Helper::getInstance();
725
        $categoriesGranted = $helper->getHandler('Permission')->getGrantedItems('category_moderation');
0 ignored issues
show
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

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

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

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

1088
        $allowedMimetypes = $helper->getHandler('Mimetype')->/** @scrutinizer ignore-call */ getArrayByType();
Loading history...
1089
        // TODO : display the available mimetypes to the user
1090
        $errors = [];
1091
        if ($helper->getConfig('perm_upload') && is_uploaded_file($_FILES['item_upload_file']['tmp_name'])) {
1092
            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

1092
            if (!$ret = $fileObj->/** @scrutinizer ignore-call */ checkUpload('item_upload_file', $allowedMimetypes, $errors)) {
Loading history...
1093
                $errorstxt = implode('<br>', $errors);
1094
1095
                $message = sprintf(_CO_PUBLISHER_MESSAGE_FILE_ERROR, $errorstxt);
1096
                if ($withRedirect) {
1097
                    redirect_header('file.php?op=mod&itemid=' . $itemId, 5, $message);
1098
                } else {
1099
                    return $message;
1100
                }
1101
            }
1102
        }
1103
1104
        // Storing the file
1105
        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

1105
        if (!$fileObj->/** @scrutinizer ignore-call */ store($allowedMimetypes)) {
Loading history...
1106
            //        if ($withRedirect) {
1107
            //            redirect_header("file.php?op=mod&itemid=" . $fileObj->itemid(), 3, _CO_PUBLISHER_FILEUPLOAD_ERROR . static::formatErrors($fileObj->getErrors()));
1108
            //            exit;
1109
            //        }
1110
            try {
1111
                if ($withRedirect) {
1112
                    throw new \RuntimeException(_CO_PUBLISHER_FILEUPLOAD_ERROR . static::formatErrors($fileObj->getErrors()));
1113
                }
1114
            }
1115
            catch (\Exception $e) {
1116
                $helper->addLog($e);
1117
                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

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

1 path for user data to reach this point

  1. Read from $_FILES, and $_FILES[$media_name] is assigned to $media_name
    in XoopsCore25/htdocs/class/uploader.php on line 209
  2. $media_name['size'] is assigned to property XoopsMediaUploader::$mediaSize
    in XoopsCore25/htdocs/class/uploader.php on line 216
  3. Read from property XoopsMediaUploader::$mediaSize, and Data is passed through sprintf(), and XoopsMediaUploader::setErrors() is called
    in XoopsCore25/htdocs/class/uploader.php on line 470
  4. Enters via parameter $error
    in XoopsCore25/htdocs/class/uploader.php on line 599
  5. Data is passed through trim(), and trim($error) is assigned to property XoopsMediaUploader::$errors
    in XoopsCore25/htdocs/class/uploader.php on line 601
  6. Read from property XoopsMediaUploader::$errors, and $this->errors is returned
    in XoopsCore25/htdocs/class/uploader.php on line 613
  7. Data is passed through implode(), and implode('<br>', $uploader->getErrors(false)) is assigned to $error
    in include/ajax_upload.php on line 72
  8. Utility::convertCharset() is called
    in include/ajax_upload.php on line 103
  9. Enters via parameter $item
    in class/Utility.php on line 1350

Preventing Object Injection Attacks

If you pass raw user-data to unserialize() for example, this can be used to create an object of any class that is available in your local filesystem. For an attacker, classes that have magic methods like __destruct or __wakeup are particularly interesting in such a case, as they can be exploited very easily.

We recommend to not pass user data to such a function. In case of unserialize, better use JSON to transfer data.

General Strategies to prevent injection

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

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

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

$sanitized = (integer) $tainted;
Loading history...
1357
            foreach ($unserialize as $key => $value) {
1358
                $unserialize[$key] = @iconv('windows-1256', 'UTF-8', $value);
1359
            }
1360
            $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 1357. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
1361
1362
            return $serialize;
1363
        }
1364
        return @iconv('windows-1256', 'UTF-8', $item);
1365
    }
1366
1367
    /**
1368
     * Verifies XOOPS version meets minimum requirements for this module
1369
     * @static
1370
     * @param \XoopsModule $module
1371
     *
1372
     * @param null|string  $requiredVer
1373
     * @return bool true if meets requirements, false if not
1374
     */
1375
    public static function checkVerXoops(\XoopsModule $module = null, $requiredVer = null)
1376
    {
1377
        $moduleDirName = basename(dirname(__DIR__));
1378
        if (null === $module) {
1379
            $module = \XoopsModule::getByDirname($moduleDirName);
1380
        }
1381
        xoops_loadLanguage('admin', $moduleDirName);
1382
1383
        //check for minimum XOOPS version
1384
        $currentVer = mb_substr(XOOPS_VERSION, 6); // get the numeric part of string
1385
        if (null === $requiredVer) {
1386
            $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

1386
            $requiredVer = '' . /** @scrutinizer ignore-type */ $module->getInfo('min_xoops'); //making sure it's a string
Loading history...
1387
        }
1388
        $success = true;
1389
1390
        if (version_compare($currentVer, $requiredVer, '<')) {
1391
            $success = false;
1392
            $module->setErrors(sprintf(_AM_PUBLISHER_ERROR_BAD_XOOPS, $requiredVer, $currentVer));
1393
        }
1394
1395
        return $success;
1396
    }
1397
1398
    /**
1399
     * Verifies PHP version meets minimum requirements for this module
1400
     * @static
1401
     * @param \XoopsModule $module
1402
     *
1403
     * @return bool true if meets requirements, false if not
1404
     */
1405
    public static function checkVerPhp(\XoopsModule $module)
1406
    {
1407
        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

1407
        xoops_loadLanguage('admin', /** @scrutinizer ignore-type */ $module->dirname());
Loading history...
1408
        // check for minimum PHP version
1409
        $success = true;
1410
        $verNum  = PHP_VERSION;
1411
        $reqVer  = $module->getInfo('min_php');
1412
        if (false !== $reqVer && '' !== $reqVer) {
1413
            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

1413
            if (version_compare($verNum, /** @scrutinizer ignore-type */ $reqVer, '<')) {
Loading history...
1414
                $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

1414
                $module->setErrors(sprintf(_AM_PUBLISHER_ERROR_BAD_PHP, /** @scrutinizer ignore-type */ $reqVer, $verNum));
Loading history...
1415
                $success = false;
1416
            }
1417
        }
1418
1419
        return $success;
1420
    }
1421
1422
    /**
1423
     * truncateHtml can truncate a string up to a number of characters while preserving whole words and HTML tags
1424
     * www.gsdesign.ro/blog/cut-html-string-without-breaking-the-tags
1425
     * www.cakephp.org
1426
     *
1427
     * @param string $text         String to truncate.
1428
     * @param int    $length       Length of returned string, including ellipsis.
1429
     * @param string $ending       Ending to be appended to the trimmed string.
1430
     * @param bool   $exact        If false, $text will not be cut mid-word
1431
     * @param bool   $considerHtml If true, HTML tags would be handled correctly
1432
     *
1433
     * @return string Trimmed string.
1434
     */
1435
    public static function truncateHtml($text, $length = 100, $ending = '...', $exact = false, $considerHtml = true)
1436
    {
1437
        if ($considerHtml) {
1438
            // if the plain text is shorter than the maximum length, return the whole text
1439
            if (mb_strlen(preg_replace('/<.*?' . '>/', '', $text)) <= $length) {
1440
                return $text;
1441
            }
1442
            // splits all html-tags to scanable lines
1443
            preg_match_all('/(<.+?' . '>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
1444
            $total_length = mb_strlen($ending);
1445
            $open_tags    = [];
1446
            $truncate     = '';
1447
            foreach ($lines as $line_matchings) {
1448
                // if there is any html-tag in this line, handle it and add it (uncounted) to the output
1449
                if (!empty($line_matchings[1])) {
1450
                    // if it's an "empty element" with or without xhtml-conform closing slash
1451
                    if (preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
1452
                        // do nothing
1453
                        // if tag is a closing tag
1454
                    } elseif (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
1455
                        // delete tag from $open_tags list
1456
                        $pos = array_search($tag_matchings[1], $open_tags);
1457
                        if (false !== $pos) {
1458
                            unset($open_tags[$pos]);
1459
                        }
1460
                        // if tag is an opening tag
1461
                    } elseif (preg_match('/^<\s*([^\s>!]+).*?' . '>$/s', $line_matchings[1], $tag_matchings)) {
1462
                        // add tag to the beginning of $open_tags list
1463
                        array_unshift($open_tags, mb_strtolower($tag_matchings[1]));
1464
                    }
1465
                    // add html-tag to $truncate'd text
1466
                    $truncate .= $line_matchings[1];
1467
                }
1468
                // calculate the length of the plain text part of the line; handle entities as one character
1469
                $content_length = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
1470
                if ($total_length + $content_length > $length) {
1471
                    // the number of characters which are left
1472
                    $left            = $length - $total_length;
1473
                    $entities_length = 0;
1474
                    // search for html entities
1475
                    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)) {
1476
                        // calculate the real length of all entities in the legal range
1477
                        foreach ($entities[0] as $entity) {
1478
                            if ($entity[1] + 1 - $entities_length <= $left) {
1479
                                $left--;
1480
                                $entities_length += mb_strlen($entity[0]);
1481
                            } else {
1482
                                // no more characters left
1483
                                break;
1484
                            }
1485
                        }
1486
                    }
1487
                    $truncate .= mb_substr($line_matchings[2], 0, $left + $entities_length);
1488
                    // maximum lenght is reached, so get off the loop
1489
                    break;
1490
                }
1491
                $truncate     .= $line_matchings[2];
1492
                $total_length += $content_length;
1493
1494
                // if the maximum length is reached, get off the loop
1495
                if ($total_length >= $length) {
1496
                    break;
1497
                }
1498
            }
1499
        } else {
1500
            if (mb_strlen($text) <= $length) {
1501
                return $text;
1502
            }
1503
            $truncate = mb_substr($text, 0, $length - mb_strlen($ending));
1504
        }
1505
        // if the words shouldn't be cut in the middle...
1506
        if (!$exact) {
1507
            // ...search the last occurance of a space...
1508
            $spacepos = mb_strrpos($truncate, ' ');
1509
            if (isset($spacepos)) {
1510
                // ...and cut the text in this position
1511
                $truncate = mb_substr($truncate, 0, $spacepos);
1512
            }
1513
        }
1514
        // add the defined ending to the text
1515
        $truncate .= $ending;
1516
        if ($considerHtml) {
1517
            // close all unclosed html-tags
1518
            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...
1519
                $truncate .= '</' . $tag . '>';
1520
            }
1521
        }
1522
1523
        return $truncate;
1524
    }
1525
}
1526