Passed
Branch master (99165a)
by Michael
04:26
created

SysUtility::getEditor()   A

Complexity

Conditions 5
Paths 12

Size

Total Lines 32
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

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

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
179
        }
180
181
        $isAdmin = $helper->isUserAdmin();
182
183
        if (\class_exists('XoopsFormEditor')) {
184
            if ($isAdmin) {
185
                $descEditor = new \XoopsFormEditor(\ucfirst($options['name']), $helper->getConfig('editorAdmin'), $options, $nohtml = false, $onfailure = 'textarea');
186
            } else {
187
                $descEditor = new \XoopsFormEditor(\ucfirst($options['name']), $helper->getConfig('editorUser'), $options, $nohtml = false, $onfailure = 'textarea');
188
            }
189
        } else {
190
            $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

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

190
            $descEditor = new \XoopsFormDhtmlTextArea(\ucfirst($options['name']), $options['name'], $options['value'], '100%', /** @scrutinizer ignore-type */ '100%');
Loading history...
191
        }
192
193
        //        $form->addElement($descEditor);
194
195
        return $descEditor;
196
    }
197
198
    /**
199
     * @param $fieldname
200
     * @param $table
201
     *
202
     * @return bool
203
     */
204
    public function fieldExists($fieldname, $table)
205
    {
206
        global $xoopsDB;
207
        $result = $xoopsDB->queryF("SHOW COLUMNS FROM   $table LIKE '$fieldname'");
208
209
        return ($xoopsDB->getRowsNum($result) > 0);
210
    }
211
}
212