Passed
Push — master ( 82b95d...638320 )
by Michael
04:10 queued 11s
created

SysUtility::prepareFolder()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
dl 0
loc 9
rs 10
c 1
b 0
f 0
cc 4
nc 4
nop 1
1
<?php
2
3
namespace XoopsModules\Extcal\Common;
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
 *
20
 * @license      https://www.fsf.org/copyleft/gpl.html GNU public license
21
 * @copyright    https://xoops.org 2000-2020 &copy; XOOPS Project
22
 * @author       ZySpec <[email protected]>
23
 * @author       Mamba <[email protected]>
24
 */
25
26
use MyTextSanitizer;
27
use XoopsFormDhtmlTextArea;
28
use XoopsFormTextArea;
29
use XoopsModules\Extcal;
30
use XoopsModules\Extcal\Helper;
31
32
/**
33
 * Class SysUtility
34
 */
35
class SysUtility
36
{
37
    use VersionChecks; //checkVerXoops, checkVerPhp Traits
0 ignored issues
show
introduced by
The trait XoopsModules\Extcal\Common\VersionChecks requires some properties which are not provided by XoopsModules\Extcal\Common\SysUtility: $tag_name, $prerelease
Loading history...
38
39
    use ServerStats; // getServerStats Trait
40
41
    use FilesManagement; // Files Management Trait
42
43
    /**
44
     * truncateHtml can truncate a string up to a number of characters while preserving whole words and HTML tags
45
     * www.gsdesign.ro/blog/cut-html-string-without-breaking-the-tags
46
     * www.cakephp.org
47
     *
48
     * @param string $text         String to truncate.
49
     * @param int    $length       Length of returned string, including ellipsis.
50
     * @param string $ending       Ending to be appended to the trimmed string.
51
     * @param bool   $exact        If false, $text will not be cut mid-word
52
     * @param bool   $considerHtml If true, HTML tags would be handled correctly
53
     *
54
     * @return string Trimmed string.
55
     */
56
    public static function truncateHtml($text, $length = 100, $ending = '...', $exact = false, $considerHtml = true)
57
    {
58
        if ($considerHtml) {
59
            // if the plain text is shorter than the maximum length, return the whole text
60
            if (mb_strlen(\preg_replace('/<.*?' . '>/', '', $text)) <= $length) {
61
                return $text;
62
            }
63
            // splits all html-tags to scanable lines
64
            \preg_match_all('/(<.+?' . '>)?([^<>]*)/s', $text, $lines, \PREG_SET_ORDER);
65
            $total_length = mb_strlen($ending);
66
            $open_tags    = [];
67
            $truncate     = '';
68
            foreach ($lines as $line_matchings) {
69
                // if there is any html-tag in this line, handle it and add it (uncounted) to the output
70
                if (!empty($line_matchings[1])) {
71
                    // if it's an "empty element" with or without xhtml-conform closing slash
72
                    if (\preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
73
                        // do nothing
74
                        // if tag is a closing tag
75
                    } elseif (\preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
76
                        // delete tag from $open_tags list
77
                        $pos = \array_search($tag_matchings[1], $open_tags, true);
78
                        if (false !== $pos) {
79
                            unset($open_tags[$pos]);
80
                        }
81
                        // if tag is an opening tag
82
                    } elseif (\preg_match('/^<\s*([^\s>!]+).*?' . '>$/s', $line_matchings[1], $tag_matchings)) {
83
                        // add tag to the beginning of $open_tags list
84
                        \array_unshift($open_tags, mb_strtolower($tag_matchings[1]));
85
                    }
86
                    // add html-tag to $truncate'd text
87
                    $truncate .= $line_matchings[1];
88
                }
89
                // calculate the length of the plain text part of the line; handle entities as one character
90
                $content_length = mb_strlen(\preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
91
                if ($total_length + $content_length > $length) {
92
                    // the number of characters which are left
93
                    $left            = $length - $total_length;
94
                    $entities_length = 0;
95
                    // search for html entities
96
                    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)) {
97
                        // calculate the real length of all entities in the legal range
98
                        foreach ($entities[0] as $entity) {
99
                            if ($left >= $entity[1] + 1 - $entities_length) {
100
                                $left--;
101
                                $entities_length += mb_strlen($entity[0]);
102
                            } else {
103
                                // no more characters left
104
                                break;
105
                            }
106
                        }
107
                    }
108
                    $truncate .= mb_substr($line_matchings[2], 0, $left + $entities_length);
109
                    // maximum lenght is reached, so get off the loop
110
                    break;
111
                }
112
                $truncate     .= $line_matchings[2];
113
                $total_length += $content_length;
114
115
                // if the maximum length is reached, get off the loop
116
                if ($total_length >= $length) {
117
                    break;
118
                }
119
            }
120
        } else {
121
            if (mb_strlen($text) <= $length) {
122
                return $text;
123
            }
124
            $truncate = mb_substr($text, 0, $length - mb_strlen($ending));
125
        }
126
        // if the words shouldn't be cut in the middle...
127
        if (!$exact) {
128
            // ...search the last occurance of a space...
129
            $spacepos = mb_strrpos($truncate, ' ');
130
            if (isset($spacepos)) {
131
                // ...and cut the text in this position
132
                $truncate = mb_substr($truncate, 0, $spacepos);
133
            }
134
        }
135
        // add the defined ending to the text
136
        $truncate .= $ending;
137
        if ($considerHtml) {
138
            // close all unclosed html-tags
139
            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...
140
                $truncate .= '</' . $tag . '>';
141
            }
142
        }
143
144
        return $truncate;
145
    }
146
147
    /**
148
     * @param \Xmf\Module\Helper $helper
149
     * @param array|null         $options
150
     * @return \XoopsFormDhtmlTextArea|\XoopsFormEditor
151
     */
152
    public static function getEditor($helper = null, $options = null)
153
    {
154
        /** @var Helper $helper */
155
        if (null === $options) {
156
            $options           = [];
157
            $options['name']   = 'Editor';
158
            $options['value']  = 'Editor';
159
            $options['rows']   = 10;
160
            $options['cols']   = '100%';
161
            $options['width']  = '100%';
162
            $options['height'] = '400px';
163
        }
164
165
        if (null === $helper) {
166
            $helper = Helper::getInstance();
167
        }
168
169
        $isAdmin = $helper->isUserAdmin();
170
171
        if (\class_exists('XoopsFormEditor')) {
172
            if ($isAdmin) {
173
                $descEditor = new \XoopsFormEditor(\ucfirst($options['name']), $helper->getConfig('editorAdmin'), $options, $nohtml = false, $onfailure = 'textarea');
174
            } else {
175
                $descEditor = new \XoopsFormEditor(\ucfirst($options['name']), $helper->getConfig('editorUser'), $options, $nohtml = false, $onfailure = 'textarea');
176
            }
177
        } else {
178
            $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 $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

178
            $descEditor = new \XoopsFormDhtmlTextArea(\ucfirst($options['name']), $options['name'], $options['value'], '100%', /** @scrutinizer ignore-type */ '100%');
Loading history...
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

178
            $descEditor = new \XoopsFormDhtmlTextArea(\ucfirst($options['name']), $options['name'], $options['value'], /** @scrutinizer ignore-type */ '100%', '100%');
Loading history...
179
        }
180
181
        //        $form->addElement($descEditor);
182
183
        return $descEditor;
184
    }
185
186
    /**
187
     * @param $fieldname
188
     * @param $table
189
     *
190
     * @return bool
191
     */
192
    public function fieldExists($fieldname, $table)
193
    {
194
        global $xoopsDB;
195
        $result = $xoopsDB->queryF("SHOW COLUMNS FROM   $table LIKE '$fieldname'");
196
197
        return ($xoopsDB->getRowsNum($result) > 0);
198
    }
199
200
    /**
201
     * Function responsible for checking if a directory exists, we can also write in and create an index.html file
202
     *
203
     * @param string $folder The full path of the directory to check
204
     */
205
    public static function prepareFolder($folder)
206
    {
207
        try {
208
            if (!@\mkdir($folder) && !\is_dir($folder)) {
209
                throw new \RuntimeException(\sprintf('Unable to create the %s directory', $folder));
210
            }
211
            file_put_contents($folder . '/index.html', '<script>history.go(-1);</script>');
212
        } catch (\Exception $e) {
213
            echo 'Caught exception: ', $e->getMessage(), "\n", '<br>';
214
        }
215
    }
216
}
217