Passed
Push — master ( 50c3b3...1e9e85 )
by Michael
04:45 queued 02:26
created

Utility::prettifyBytes()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 10
nc 4
nop 1
dl 0
loc 16
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
namespace XoopsModules\Tdmdownloads;
4
5
/*
6
 Utility Class Definition
7
8
 You may not change or alter any portion of this comment or credits of
9
 supporting developers from this source code or any supporting source code
10
 which is considered copyrighted (c) material of the original comment or credit
11
 authors.
12
13
 This program is distributed in the hope that it will be useful, but
14
 WITHOUT ANY WARRANTY; without even the implied warranty of
15
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
 */
17
18
/**
19
 * Class Utility
20
 */
21
class Utility
22
{
23
    use Common\VersionChecks; //checkVerXoops, checkVerPhp Traits
24
25
    use Common\ServerStats; // getServerStats Trait
26
27
    use Common\FilesManagement; // Files Management Trait
28
29
    /**
30
     * truncateHtml can truncate a string up to a number of characters while preserving whole words and HTML tags
31
     * www.gsdesign.ro/blog/cut-html-string-without-breaking-the-tags
32
     * www.cakephp.org
33
     *
34
     * @param string $text         String to truncate.
35
     * @param int    $length       Length of returned string, including ellipsis.
36
     * @param string $ending       Ending to be appended to the trimmed string.
37
     * @param bool   $exact        If false, $text will not be cut mid-word
38
     * @param bool   $considerHtml If true, HTML tags would be handled correctly
39
     *
40
     * @return string Trimmed string.
41
     */
42
    public static function truncateHtml($text, $length = 100, $ending = '...', $exact = false, $considerHtml = true)
43
    {
44
        $open_tags    = [];
45
        if ($considerHtml) {
46
            // if the plain text is shorter than the maximum length, return the whole text
47
            if (mb_strlen(preg_replace('/<.*?' . '>/', '', $text)) <= $length) {
48
                return $text;
49
            }
50
            // splits all html-tags to scanable lines
51
            preg_match_all('/(<.+?' . '>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
52
            $total_length = mb_strlen($ending);
53
            $truncate     = '';
54
            foreach ($lines as $line_matchings) {
55
                // if there is any html-tag in this line, handle it and add it (uncounted) to the output
56
                if (!empty($line_matchings[1])) {
57
                    // if it's an "empty element" with or without xhtml-conform closing slash
58
                    if (preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
59
                        // do nothing
60
                        // if tag is a closing tag
61
                    } elseif (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
62
                        // delete tag from $open_tags list
63
                        $pos = array_search($tag_matchings[1], $open_tags, true);
64
                        if (false !== $pos) {
65
                            unset($open_tags[$pos]);
66
                        }
67
                        // if tag is an opening tag
68
                    } elseif (preg_match('/^<\s*([^\s>!]+).*?' . '>$/s', $line_matchings[1], $tag_matchings)) {
69
                        // add tag to the beginning of $open_tags list
70
                        array_unshift($open_tags, mb_strtolower($tag_matchings[1]));
71
                    }
72
                    // add html-tag to $truncate'd text
73
                    $truncate .= $line_matchings[1];
74
                }
75
                // calculate the length of the plain text part of the line; handle entities as one character
76
                $content_length = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
77
                if ($total_length + $content_length > $length) {
78
                    // the number of characters which are left
79
                    $left            = $length - $total_length;
80
                    $entities_length = 0;
81
                    // search for html entities
82
                    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)) {
83
                        // calculate the real length of all entities in the legal range
84
                        foreach ($entities[0] as $entity) {
85
                            if ($left >= $entity[1] + 1 - $entities_length) {
86
                                $left--;
87
                                $entities_length += mb_strlen($entity[0]);
88
                            } else {
89
                                // no more characters left
90
                                break;
91
                            }
92
                        }
93
                    }
94
                    $truncate .= mb_substr($line_matchings[2], 0, $left + $entities_length);
95
                    // maximum lenght is reached, so get off the loop
96
                    break;
97
                }
98
                $truncate     .= $line_matchings[2];
99
                $total_length += $content_length;
100
101
                // if the maximum length is reached, get off the loop
102
                if ($total_length >= $length) {
103
                    break;
104
                }
105
            }
106
        } else {
107
            if (mb_strlen($text) <= $length) {
108
                return $text;
109
            }
110
            $truncate = mb_substr($text, 0, $length - mb_strlen($ending));
111
        }
112
        // if the words shouldn't be cut in the middle...
113
        if (!$exact) {
114
            // ...search the last occurance of a space...
115
            $spacepos = mb_strrpos($truncate, ' ');
116
            if (isset($spacepos)) {
117
                // ...and cut the text in this position
118
                $truncate = mb_substr($truncate, 0, $spacepos);
119
            }
120
        }
121
        // add the defined ending to the text
122
        $truncate .= $ending;
123
        if ($considerHtml) {
124
            // close all unclosed html-tags
125
            foreach ($open_tags as $tag) {
126
                $truncate .= '</' . $tag . '>';
127
            }
128
        }
129
130
        return $truncate;
131
    }
132
133
    /**
134
     * @param \Xmf\Module\Helper $helper
135
     * @param array|null         $options
136
     * @return \XoopsFormDhtmlTextArea|\XoopsFormEditor
137
     */
138
    public static function getEditor($helper = null, $options = null)
139
    {
140
        /** @var \XoopsModules\Tdmdownloads\Helper $helper */
141
        if (null === $options) {
142
            $options           = [];
143
            $options['name']   = 'Editor';
144
            $options['value']  = 'Editor';
145
            $options['rows']   = 10;
146
            $options['cols']   = '100%';
147
            $options['width']  = '100%';
148
            $options['height'] = '400px';
149
        }
150
151
        $isAdmin = $helper->isUserAdmin();
152
153
        if (class_exists('XoopsFormEditor')) {
154
            if ($isAdmin) {
155
                $descEditor = new \XoopsFormEditor(ucfirst($options['name']), $helper->getConfig('editorAdmin'), $options, $nohtml = false, $onfailure = 'textarea');
156
            } else {
157
                $descEditor = new \XoopsFormEditor(ucfirst($options['name']), $helper->getConfig('editorUser'), $options, $nohtml = false, $onfailure = 'textarea');
158
            }
159
        } else {
160
            $descEditor = new \XoopsFormDhtmlTextArea(ucfirst($options['name']), $options['name'], $options['value'], '100%', '100%');
0 ignored issues
show
Bug introduced by
'100%' of type string is incompatible with the type integer expected by parameter $rows of XoopsFormDhtmlTextArea::__construct(). ( Ignorable by Annotation )

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

160
            $descEditor = new \XoopsFormDhtmlTextArea(ucfirst($options['name']), $options['name'], $options['value'], /** @scrutinizer ignore-type */ '100%', '100%');
Loading history...
Bug introduced by
'100%' of type string is incompatible with the type integer expected by parameter $cols of XoopsFormDhtmlTextArea::__construct(). ( Ignorable by Annotation )

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

160
            $descEditor = new \XoopsFormDhtmlTextArea(ucfirst($options['name']), $options['name'], $options['value'], '100%', /** @scrutinizer ignore-type */ '100%');
Loading history...
161
        }
162
163
        //        $form->addElement($descEditor);
164
165
        return $descEditor;
166
    }
167
168
    //--------------- Custom module methods -----------------------------
169
170
    /**
171
     * @param $permtype
172
     * @param $dirname
173
     * @return mixed
174
     */
175
    public function getItemIds($permtype, $dirname)
176
    {
177
        global $xoopsUser;
178
        static $permissions = [];
179
        if (is_array($permissions) && array_key_exists($permtype, $permissions)) {
180
            return $permissions[$permtype];
181
        }
182
        /** @var \XoopsModuleHandler $moduleHandler */
183
        $moduleHandler = xoops_getHandler('module');
184
        $tdmModule     = $moduleHandler->getByDirname($dirname);
185
        $groups        = is_object($xoopsUser) ? $xoopsUser->getGroups() : XOOPS_GROUP_ANONYMOUS;
186
187
        /** @var \XoopsGroupPermHandler $grouppermHandler */
188
        $grouppermHandler = xoops_getHandler('groupperm');
189
        $categories       = $grouppermHandler->getItemIds($permtype, $groups, $tdmModule->getVar('mid'));
190
191
        return $categories;
192
    }
193
194
    /**
195
     * retourne le nombre de téléchargements dans le catégories enfants d'une catégorie
196
     * @param \XoopsModules\Tdmdownloads\Tree        $mytree
197
     * @param                                        $categories
198
     * @param                                        $entries
199
     * @param                                        $cid
200
     * @return int
201
     */
202
    public function getNumbersOfEntries($mytree, $categories, $entries, $cid)
203
    {
204
        $count     = 0;
205
        $child_arr = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $child_arr is dead and can be removed.
Loading history...
206
        if (in_array($cid, $categories, true)) {
207
            $child = $mytree->getAllChild($cid);
208
            foreach (array_keys($entries) as $i) {
209
                if ($entries[$i]->getVar('cid') == $cid) {
210
                    $count++;
211
                }
212
                foreach (array_keys($child) as $j) {
213
                    if ($entries[$i]->getVar('cid') == $j) {
214
                        $count++;
215
                    }
216
                }
217
            }
218
        }
219
220
        return $count;
221
    }
222
223
    /**
224
     * retourne une image "nouveau" ou "mise à jour"
225
     * @param $time
226
     * @param $status
227
     * @return string
228
     */
229
    public function getStatusImage($time, $status)
230
    {
231
        global $xoopsModuleConfig;
232
        $count     = 7;
233
        $new       = '';
234
        $startdate = (time() - (86400 * $count));
235
        if (1 == $xoopsModuleConfig['showupdated']) {
236
            if ($startdate < $time) {
237
                $language = $GLOBALS['xoopsConfig']['language'];
238
                if (!is_dir(XOOPS_ROOT_PATH . '/modules/tdmdownloads/language/' . $language . '/')) {
239
                    $language = 'english';
240
                }
241
                $img_path = XOOPS_ROOT_PATH . '/modules/tdmdownloads/language/' . $language . '/';
242
                $img_url  = XOOPS_URL . '/modules/tdmdownloads/language/' . $language . '/';
243
                if (1 == $status) {
244
                    if (is_readable($img_path . 'new.png')) {
245
                        $new = '&nbsp;<img src="' . $img_url . 'new.png" alt="' . _MD_TDMDOWNLOADS_INDEX_NEWTHISWEEK . '" title="' . _MD_TDMDOWNLOADS_INDEX_NEWTHISWEEK . '">';
246
                    } else {
247
                        $new = '&nbsp;<img src="' . XOOPS_URL . '/modules/tdmdownloads/language/english/new.png" alt="' . _MD_TDMDOWNLOADS_INDEX_NEWTHISWEEK . '" title="' . _MD_TDMDOWNLOADS_INDEX_NEWTHISWEEK . '">';
248
                    }
249
                } elseif (2 == $status) {
250
                    if (is_readable($img_path . 'updated.png')) {
251
                        $new = '&nbsp;<img src="' . $img_url . 'updated.png" alt="' . _MD_TDMDOWNLOADS_INDEX_UPTHISWEEK . '" title="' . _MD_TDMDOWNLOADS_INDEX_UPTHISWEEK . '">';
252
                    } else {
253
                        $new = '&nbsp;<img src="' . XOOPS_URL . '/modules/tdmdownloads/language/english/updated.png" alt="' . _MD_TDMDOWNLOADS_INDEX_UPTHISWEEK . '" title="' . _MD_TDMDOWNLOADS_INDEX_UPTHISWEEK . '">';
254
                    }
255
                }
256
            }
257
        }
258
259
        return $new;
260
    }
261
262
    /**
263
     * retourne une image "populaire"
264
     * @param $hits
265
     * @return string
266
     */
267
    public function getPopularImage($hits)
268
    {
269
        global $xoopsModuleConfig;
270
        $pop = '';
271
        if ($hits >= $xoopsModuleConfig['popular']) {
272
            $language = $GLOBALS['xoopsConfig']['language'];
273
            if (!is_dir(XOOPS_ROOT_PATH . '/modules/tdmdownloads/language/' . $language . '/')) {
274
                $language = 'english';
275
            }
276
            $img_path = XOOPS_ROOT_PATH . '/modules/tdmdownloads/language/' . $language . '/';
277
            $img_url  = XOOPS_URL . '/modules/tdmdownloads/language/' . $language . '/';
278
            if (is_readable($img_path . 'popular.png')) {
279
                $pop = '&nbsp;<img src="' . $img_url . 'popular.png" alt="' . _MD_TDMDOWNLOADS_INDEX_POPULAR . '" title="' . _MD_TDMDOWNLOADS_INDEX_POPULAR . '">';
280
            } else {
281
                $pop = '&nbsp;<img src ="' . XOOPS_URL . '/modules/tdmdownloads/language/english/popular.png" alt="' . _MD_TDMDOWNLOADS_INDEX_POPULAR . '" title="' . _MD_TDMDOWNLOADS_INDEX_POPULAR . '">';
282
            }
283
        }
284
285
        return $pop;
286
    }
287
288
    /**
289
     * @param int $size
290
     * @return string
291
     */
292
    public static function prettifyBytes($size)
293
    {
294
        if ($size > 0) {
295
            $mb = 1024 * 1024;
296
            if ($size > $mb) {
297
                $mysize = sprintf('%01.2f', $size / $mb) . ' MB';
298
            } elseif ($size >= 1024) {
299
                $mysize = sprintf('%01.2f', $size / 1024) . ' KB';
300
            } else {
301
                $mysize = sprintf(_AM_TDMDOWNLOADS_NUMBYTES, $size);
302
            }
303
304
            return $mysize;
305
        }
306
307
        return '';
308
    }
309
310
    /**
311
     * @param        $global
312
     * @param        $key
313
     * @param string $default
314
     * @param string $type
315
     * @return mixed|string
316
     */
317
    public static function cleanVars(&$global, $key, $default = '', $type = 'int')
318
    {
319
        switch ($type) {
320
            case 'string':
321
                $ret = isset($global[$key]) ? filter_var($global[$key], FILTER_SANITIZE_MAGIC_QUOTES) : $default;
322
                break;
323
            case 'int':
324
            default:
325
                $ret = isset($global[$key]) ? filter_var($global[$key], FILTER_SANITIZE_NUMBER_INT) : $default;
326
                break;
327
        }
328
        if (false === $ret) {
329
            return $default;
330
        }
331
332
        return $ret;
333
    }
334
335
    /**
336
     * @param        $mytree
337
     * @param        $key
338
     * @param        $category_array
339
     * @param        $title
340
     * @param string $prefix
341
     * @return string
342
     */
343
    public function getPathTree($mytree, $key, $category_array, $title, $prefix = '')
344
    {
345
        $categoryParent = $mytree->getAllParent($key);
346
        $categoryParent = array_reverse($categoryParent);
347
        $path            = '';
348
        foreach (array_keys($categoryParent) as $j) {
349
            $path .= $categoryParent[$j]->getVar($title) . $prefix;
350
        }
351
        if (array_key_exists($key, $category_array)) {
352
            $firstCategory = $category_array[$key]->getVar($title);
353
        } else {
354
            $firstCategory = '';
355
        }
356
        $path .= $firstCategory;
357
358
        return $path;
359
    }
360
361
    /**
362
     * @param \XoopsModules\Tdmdownloads\Tree $mytree
363
     * @param                                 $key
364
     * @param                                 $category_array
365
     * @param                                 $title
366
     * @param string                          $prefix
367
     * @param bool                            $link
368
     * @param string                          $order
369
     * @param bool                            $lasturl
370
     * @return string
371
     */
372
    public function getPathTreeUrl($mytree, $key, $category_array, $title, $prefix = '', $link = false, $order = 'ASC', $lasturl = false)
373
    {
374
        global $xoopsModule;
375
        $categoryParent = $mytree->getAllParent($key);
376
        if ('ASC' === $order) {
377
            $categoryParent = array_reverse($categoryParent);
378
            if (true === $link) {
379
                $path = '<a href="index.php">' . $xoopsModule->name() . '</a>' . $prefix;
380
            } else {
381
                $path = $xoopsModule->name() . $prefix;
382
            }
383
        } else {
384
            if (array_key_exists($key, $category_array)) {
385
                $firstCategory = $category_array[$key]->getVar($title);
386
            } else {
387
                $firstCategory = '';
388
            }
389
            $path = $firstCategory . $prefix;
390
        }
391
        foreach (array_keys($categoryParent) as $j) {
392
            if (true === $link) {
393
                $path .= '<a href="viewcat.php?cid=' . $categoryParent[$j]->getVar('cat_cid') . '">' . $categoryParent[$j]->getVar($title) . '</a>' . $prefix;
394
            } else {
395
                $path .= $categoryParent[$j]->getVar($title) . $prefix;
396
            }
397
        }
398
        if ('ASC' === $order) {
399
            if (array_key_exists($key, $category_array)) {
400
                if (true === $lasturl) {
401
                    $firstCategory = '<a href="viewcat.php?cid=' . $category_array[$key]->getVar('cat_cid') . '">' . $category_array[$key]->getVar($title) . '</a>';
402
                } else {
403
                    $firstCategory = $category_array[$key]->getVar($title);
404
                }
405
            } else {
406
                $firstCategory = '';
407
            }
408
            $path .= $firstCategory;
409
        } else {
410
            if (true === $link) {
411
                $path .= '<a href="index.php">' . $xoopsModule->name() . '</a>';
412
            } else {
413
                $path .= $xoopsModule->name();
414
            }
415
        }
416
417
        return $path;
418
    }
419
}
420