xhelp_admin_mkdir()   B
last analyzed

Complexity

Conditions 7
Paths 5

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 8
c 0
b 0
f 0
nc 5
nop 1
dl 0
loc 18
rs 8.8333
1
<?php declare(strict_types=1);
2
3
/*
4
 * You may not change or alter any portion of this comment or credits
5
 * of supporting developers from this source code or any supporting source code
6
 * which is considered copyrighted (c) material of the original comment or credit authors.
7
 *
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 */
12
13
/**
14
 * @copyright    {@link https://xoops.org/ XOOPS Project}
15
 * @license      {@link https://www.gnu.org/licenses/gpl-2.0.html GNU GPL 2 or later}
16
 * @author       Brian Wahoff <[email protected]>
17
 * @author       Eric Juden <[email protected]>
18
 * @author       XOOPS Development Team
19
 */
20
21
use XoopsModules\Xhelp;
22
23
//function xhelpAdminFooter()
24
//{
25
//    echo "<br><div class='center;'><a target='_BLANK' href='https://www.3dev.org'><img src='".XHELP_IMAGE_URL."/3Dev_xhelp.png'></a></div>";
26
//}
27
28
/**
29
 * Check the status of the supplied directory
30
 * Thanks to the NewBB2 Development Team and SmartFactory
31
 * @param string $path
32
 * @param bool   $getStatus
33
 * @return int|string
34
 */
35
function xhelp_admin_getPathStatus(string $path, bool $getStatus = false)
36
{
37
    if (empty($path)) {
38
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type integer|string.
Loading history...
39
    }
40
    $url_path = urlencode($path);
41
    if (@is_writable($path)) {
42
        $pathCheckResult = 1;
43
        $path_status     = _AM_XHELP_PATH_AVAILABLE;
44
    } elseif (@is_dir($path)) {
45
        $pathCheckResult = -2;
46
        $path_status     = _AM_XHELP_PATH_NOTWRITABLE . " [<a href=main.php?op=setperm&amp;path=$url_path>" . _AM_XHELP_TEXT_SETPERM . '</a>]';
47
    } else {
48
        $pathCheckResult = -1;
49
        $path_status     = _AM_XHELP_PATH_NOTAVAILABLE . " [<a href=main.php?op=createdir&amp;path=$url_path>" . _AM_XHELP_TEXT_CREATETHEDIR . '</a>]';
50
    }
51
    if (!$getStatus) {
52
        return $path_status;
53
    }
54
55
    return $pathCheckResult;
56
}
57
58
/**
59
 * Thanks to the NewBB2 Development Team and SmartFactory
60
 * @param string $target
61
 * @return bool
62
 */
63
function xhelp_admin_mkdir(string $target): bool
64
{
65
    // https://www.php.net/manual/en/function.mkdir.php
66
    // saint at corenova.com
67
    // bart at cdasites dot com
68
    if (empty($target) || is_dir($target)) {
69
        return true;
70
    } // best case check first
71
    if (is_dir($target) && !is_dir($target)) {
72
        return false;
73
    }
74
    if (xhelp_admin_mkdir(mb_substr($target, 0, mb_strrpos($target, '/')))) {
75
        if (!is_dir($target)) {
76
            return mkdir($target);
77
        }
78
    } // crawl back up & create dir tree
79
80
    return true;
81
}
82
83
/**
84
 * Thanks to the NewBB2 Development Team and SmartFactory
85
 * @param string $target
86
 * @param int    $mode
87
 * @return bool
88
 */
89
function xhelp_admin_chmod(string $target, int $mode = 0777): bool
90
{
91
    return @chmod($target, $mode);
92
}
93
94
/**
95
 * @param string $dirName
96
 * @param bool   $getResolved
97
 * @return string
98
 */
99
function xhelpDirsize(string $dirName = '.', bool $getResolved = false): string
100
{
101
    $helper = Xhelp\Helper::getInstance();
102
    $dir    = dir($dirName);
103
    $size   = 0;
104
105
    if ($getResolved) {
106
        /** @var \XoopsModules\Xhelp\TicketHandler $ticketHandler */
107
        $ticketHandler = $helper->getHandler('Ticket');
108
        /** @var \XoopsModules\Xhelp\FileHandler $fileHandler */
109
        $fileHandler = $helper->getHandler('File');
110
111
        $tickets = $ticketHandler->getObjectsByState(1);
112
113
        $aTickets = [];
114
        foreach ($tickets as $ticket) {
115
            $aTickets[$ticket->getVar('id')] = $ticket->getVar('id');
116
        }
117
118
        // Retrieve all unresolved ticket attachments
119
        $criteria = new \Criteria('ticketid', '(' . implode(',', $aTickets) . ')', 'IN');
120
        $files    = $fileHandler->getObjects($criteria);
121
        $aFiles   = [];
122
        foreach ($files as $f) {
123
            $aFiles[$f->getVar('id')] = $f->getVar('filename');
124
        }
125
    }
126
127
    while ($file = $dir->read()) {
128
        if ('.' !== $file && '..' !== $file) {
129
            if (is_dir($file)) {
130
                //                $size += dirsize($dirName . '/' . $file);
131
                $size += disk_total_space($dirName . '/' . $file);
132
            } else {
133
                if ($getResolved) {
134
                    if (!in_array($file, $aFiles)) {     // Skip unresolved files
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $aFiles does not seem to be defined for all execution paths leading up to this point.
Loading history...
135
                        $size += filesize($dirName . '/' . $file);
136
                    }
137
                } else {
138
                    $size += filesize($dirName . '/' . $file);
139
                }
140
            }
141
        }
142
    }
143
    $dir->close();
144
145
    return Xhelp\Utility::prettyBytes($size);
0 ignored issues
show
Bug introduced by
It seems like $size can also be of type double; however, parameter $bytes of XoopsModules\Xhelp\Utility::prettyBytes() does only seem to accept integer, 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

145
    return Xhelp\Utility::prettyBytes(/** @scrutinizer ignore-type */ $size);
Loading history...
146
}
147
148
/**
149
 * @param string $control
150
 * @return mixed
151
 */
152
function xhelpGetControlLabel(string $control)
153
{
154
    $controlArr = xhelpGetControl($control);
155
    if ($controlArr) {
156
        return $controlArr['label'];
157
    }
158
159
    return $control;
160
}
161
162
/**
163
 * @param string $control
164
 * @return bool|array
165
 */
166
function xhelpGetControl(string $control)
167
{
168
    $controls = xhelpGetControlArray();
169
170
    return $controls[$control] ?? false;
171
}
172
173
/**
174
 * @return array
175
 */
176
function &xhelpGetControlArray(): array
177
{
178
    $ret = [
179
        XHELP_CONTROL_TXTBOX   => [
180
            'label'        => _XHELP_CONTROL_DESC_TXTBOX,
181
            'needs_length' => true,
182
            'needs_values' => false,
183
        ],
184
        XHELP_CONTROL_TXTAREA  => [
185
            'label'        => _XHELP_CONTROL_DESC_TXTAREA,
186
            'needs_length' => true,
187
            'needs_values' => false,
188
        ],
189
        XHELP_CONTROL_SELECT   => [
190
            'label'        => _XHELP_CONTROL_DESC_SELECT,
191
            'needs_length' => true,
192
            'needs_values' => true,
193
        ],
194
        //Search issues?
195
        //XHELP_CONTROL_MULTISELECT => _XHELP_CONTROL_DESC_MULTISELECT,
196
        XHELP_CONTROL_YESNO    => [
197
            'label'        => _XHELP_CONTROL_DESC_YESNO,
198
            'needs_length' => false,
199
            'needs_values' => false,
200
        ],
201
        //Search issues?
202
        //XHELP_CONTROL_CHECKBOX => _XHELP_CONTROL_DESC_CHECKBOX,
203
        XHELP_CONTROL_RADIOBOX => [
204
            'label'        => _XHELP_CONTROL_DESC_RADIOBOX,
205
            'needs_length' => true,
206
            'needs_values' => true,
207
        ],
208
        XHELP_CONTROL_DATETIME => [
209
            'label'        => _XHELP_CONTROL_DESC_DATETIME,
210
            'needs_length' => false,
211
            'needs_values' => false,
212
        ],
213
        XHELP_CONTROL_FILE     => [
214
            'label'        => _XHELP_CONTROL_DESC_FILE,
215
            'needs_length' => false,
216
            'needs_values' => false,
217
        ],
218
    ];
219
220
    return $ret;
221
}
222
223
/**
224
 * @param array  $err_arr
225
 * @param string $reseturl
226
 */
227
function xhelpRenderErrors(array $err_arr, string $reseturl = '')
228
{
229
    if ($err_arr && is_array($err_arr)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $err_arr of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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

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

Loading history...
230
        echo '<div id="readOnly" class="errorMsg" style="border:1px solid #D24D00; background:#FEFECC url(' . XHELP_IMAGE_URL . '/important-32.png) no-repeat 7px 50%;color:#333;padding-left:45px;">';
231
232
        echo '<h4 style="text-align:left;margin:0; padding-top:0;">' . _AM_XHELP_MSG_SUBMISSION_ERR;
233
234
        if ($reseturl) {
235
            echo ' <a href="' . $reseturl . '">[' . _AM_XHELP_TEXT_SESSION_RESET . ']</a>';
236
        }
237
238
        echo '</h4><ul>';
239
240
        foreach ($err_arr as $key => $error) {
241
            if (is_array($error)) {
242
                foreach ($error as $err) {
243
                    echo '<li><a href="#' . $key . '" onclick="var e = xoopsGetElementById(\'' . $key . '\'); e.focus();">' . htmlspecialchars($err, ENT_QUOTES | ENT_HTML5) . '</a></li>';
244
                }
245
            } else {
246
                echo '<li><a href="#' . $key . '" onclick="var e = xoopsGetElementById(\'' . $key . '\'); e.focus();">' . htmlspecialchars($error, ENT_QUOTES | ENT_HTML5) . '</a></li>';
247
            }
248
        }
249
        echo '</ul></div><br>';
250
    }
251
}
252
253
/**
254
 * @param string $string
255
 * @return string
256
 */
257
function removeAccents(string $string): string
258
{
259
    $chars['in']  = chr(128)
0 ignored issues
show
Comprehensibility Best Practice introduced by
$chars was never initialized. Although not strictly required by PHP, it is generally a good practice to add $chars = array(); before regardless.
Loading history...
260
                    . chr(131)
261
                    . chr(138)
262
                    . chr(142)
263
                    . chr(154)
264
                    . chr(158)
265
                    . chr(159)
266
                    . chr(162)
267
                    . chr(165)
268
                    . chr(181)
269
                    . chr(192)
270
                    . chr(193)
271
                    . chr(194)
272
                    . chr(195)
273
                    . chr(196)
274
                    . chr(197)
275
                    . chr(199)
276
                    . chr(200)
277
                    . chr(201)
278
                    . chr(202)
279
                    . chr(203)
280
                    . chr(204)
281
                    . chr(205)
282
                    . chr(206)
283
                    . chr(207)
284
                    . chr(
285
                        209
286
                    )
287
                    . chr(210)
288
                    . chr(211)
289
                    . chr(212)
290
                    . chr(213)
291
                    . chr(214)
292
                    . chr(216)
293
                    . chr(217)
294
                    . chr(218)
295
                    . chr(219)
296
                    . chr(220)
297
                    . chr(221)
298
                    . chr(224)
299
                    . chr(225)
300
                    . chr(226)
301
                    . chr(227)
302
                    . chr(228)
303
                    . chr(229)
304
                    . chr(231)
305
                    . chr(232)
306
                    . chr(233)
307
                    . chr(234)
308
                    . chr(235)
309
                    . chr(236)
310
                    . chr(237)
311
                    . chr(238)
312
                    . chr(239)
313
                    . chr(241)
314
                    . chr(242)
315
                    . chr(243)
316
                    . chr(244)
317
                    . chr(245)
318
                    . chr(246)
319
                    . chr(248)
320
                    . chr(249)
321
                    . chr(250)
322
                    . chr(251)
323
                    . chr(252)
324
                    . chr(253)
325
                    . chr(255);
326
    $chars['out'] = 'EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy';
327
    if (seemsUtf8($string)) {
328
        $invalid_latin_chars = [
329
            chr(197) . chr(146)            => 'OE',
330
            chr(197) . chr(147)            => 'oe',
331
            chr(197) . chr(160)            => 'S',
332
            chr(197) . chr(189)            => 'Z',
333
            chr(197) . chr(161)            => 's',
334
            chr(197) . chr(190)            => 'z',
335
            chr(226) . chr(130) . chr(172) => 'E',
336
        ];
337
        $string              = utf8_decode(strtr($string, $invalid_latin_chars));
338
    }
339
    $string              = strtr($string, $chars['in'], $chars['out']);
340
    $double_chars['in']  = [
0 ignored issues
show
Comprehensibility Best Practice introduced by
$double_chars was never initialized. Although not strictly required by PHP, it is generally a good practice to add $double_chars = array(); before regardless.
Loading history...
341
        chr(140),
342
        chr(156),
343
        chr(198),
344
        chr(208),
345
        chr(222),
346
        chr(223),
347
        chr(230),
348
        chr(240),
349
        chr(254),
350
    ];
351
    $double_chars['out'] = ['OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'];
352
    $string              = str_replace($double_chars['in'], $double_chars['out'], $string);
353
354
    return $string;
355
}
356
357
/**
358
 * @param array|string $str
359
 * @return bool
360
 */
361
function seemsUtf8($str): bool
362
{ # by bmorel at ssi dot fr
363
    foreach ($str as $i => $iValue) {
364
        if (ord($iValue) < 0x80) {
365
            continue;
366
        } # 0bbbbbbb
367
        elseif (0xC0 == (ord($iValue) & 0xE0)) {
368
            $n = 1;
369
        } # 110bbbbb
370
        elseif (0xE0 == (ord($iValue) & 0xF0)) {
371
            $n = 2;
372
        } # 1110bbbb
373
        elseif (0xF0 == (ord($iValue) & 0xF8)) {
374
            $n = 3;
375
        } # 11110bbb
376
        elseif (0xF8 == (ord($iValue) & 0xFC)) {
377
            $n = 4;
378
        } # 111110bb
379
        elseif (0xFC == (ord($iValue) & 0xFE)) {
380
            $n = 5;
381
        } # 1111110b
382
        else {
383
            return false;
384
        } # Does not match any model
385
        for ($j = 0; $j < $n; ++$j) { # n bytes matching 10bbbbbb follow ?
386
            if ((++$i == mb_strlen($str)) || (0x80 != (ord($str[$i]) & 0xC0))) {
0 ignored issues
show
Bug introduced by
$str of type array is incompatible with the type string expected by parameter $string of mb_strlen(). ( Ignorable by Annotation )

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

386
            if ((++$i == mb_strlen(/** @scrutinizer ignore-type */ $str)) || (0x80 != (ord($str[$i]) & 0xC0))) {
Loading history...
387
                return false;
388
            }
389
        }
390
    }
391
392
    return true;
393
}
394
395
/**
396
 * @param string $field
397
 * @return string
398
 */
399
function sanitizeFieldName(string $field): string
400
{
401
    $field = removeAccents($field);
402
    $field = \mb_strtolower($field);
403
    $field = preg_replace('/&.+?;/', '', $field); // kill entities
404
    $field = preg_replace('/[^a-z0-9 _-]/', '', $field);
405
    $field = preg_replace('/\s+/', ' ', $field);
406
    $field = str_replace(' ', '-', $field);
407
    $field = preg_replace('|-+|', '-', $field);
408
    $field = trim($field, '-');
409
410
    return $field;
411
}
412
413
/**
414
 * @return bool
415
 */
416
function xhelpCreateDepartmentVisibility(): bool
417
{
418
    $helper = Xhelp\Helper::getInstance();
419
420
    /** @var \XoopsModules\Xhelp\DepartmentHandler $departmentHandler */
421
    $departmentHandler = $helper->getHandler('Department');
422
    /** @var \XoopsGroupHandler $groupHandler */
423
    $groupHandler = xoops_getHandler('group');
424
    /** @var \XoopsGroupPermHandler $grouppermHandler */
425
    $grouppermHandler = xoops_getHandler('groupperm');
426
    $xoopsModule      = Xhelp\Utility::getModule();
427
428
    $module_id = $xoopsModule->getVar('mid');
429
430
    // Get array of all departments
431
    $departments = $departmentHandler->getObjects(null, true);
432
433
    // Get array of groups
434
    $groups  = $groupHandler->getObjects(null, true);
435
    $aGroups = [];
436
    foreach ($groups as $group_id => $group) {
437
        $aGroups[$group_id] = $group->getVar('name');
438
    }
439
440
    foreach ($departments as $dept) {
441
        $deptID = $dept->getVar('id');
442
443
        // Remove old group permissions
444
        $criteria = new \CriteriaCompo(new \Criteria('gperm_modid', $module_id));
0 ignored issues
show
Bug introduced by
It seems like $module_id can also be of type array and array; however, parameter $value of Criteria::__construct() 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

444
        $criteria = new \CriteriaCompo(new \Criteria('gperm_modid', /** @scrutinizer ignore-type */ $module_id));
Loading history...
445
        $criteria->add(new \Criteria('gperm_itemid', $deptID));
446
        $criteria->add(new \Criteria('gperm_name', _XHELP_GROUP_PERM_DEPT));
447
        $grouppermHandler->deleteAll($criteria);
448
449
        foreach ($aGroups as $group => $group_name) {     // Add new group permissions
450
            $grouppermHandler->addRight(_XHELP_GROUP_PERM_DEPT, $deptID, $group, $module_id);
451
        }
452
        // Todo: Possibly add text saying, "Visibility for Department x set"
453
    }
454
455
    return true;
456
}
457