songlist_toXml()   C
last analyzed

Complexity

Conditions 13
Paths 18

Size

Total Lines 41
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
eloc 29
c 1
b 0
f 0
nc 18
nop 5
dl 0
loc 41
rs 6.6166

How to fix   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 declare(strict_types=1);
2
3
use Xmf\Request;
4
use XoopsModules\Songlist\Form\SelectAlbumForm;
5
use XoopsModules\Songlist\Form\SelectArtistForm;
6
use XoopsModules\Songlist\Form\SelectCategoryForm;
7
use XoopsModules\Songlist\Form\SelectGenreForm;
8
use XoopsModules\Songlist\Form\SelectSongForm;
9
use XoopsModules\Songlist\Form\SelectVoiceForm;
10
11
if (!function_exists('songlist_getToken')) {
12
    /**
13
     * @return mixed
14
     */
15
    function songlist_getToken()
16
    {
17
        $sql    = 'SELECT md5(rand()/rand()*rand()/rand()*rand()*rand()/rand()*rand()) as `salt`';
18
        $result = $GLOBALS['xoopsDB']->queryF($sql);
19
        [$salt] = $GLOBALS['xoopsDB']->fetchRow($result);
20
21
        return $salt;
22
    }
23
}
24
25
if (!function_exists('ucword')) {
26
    /**
27
     * @param $string
28
     * @return string
29
     */
30
    function ucword($string): string
31
    {
32
        $ret = [];
33
        foreach (explode(' ', \mb_strtolower($string)) as $part) {
34
            $ret[] = ucfirst($part);
35
        }
36
37
        return implode(' ', $ret);
38
    }
39
}
40
41
if (!function_exists('songlist_getIPData')) {
42
    /**
43
     * @param bool|string $ip
44
     * @return array
45
     */
46
    function songlist_getIPData($ip = false): array
47
    {
48
        $ret = [];
49
        if (is_object($GLOBALS['xoopsUser'])) {
50
            $ret['uid']   = $GLOBALS['xoopsUser']->getVar('uid');
51
            $ret['uname'] = $GLOBALS['xoopsUser']->getVar('uname');
52
            $ret['email'] = $GLOBALS['xoopsUser']->getVar('email');
53
        } else {
54
            $ret['uid']   = 0;
55
            $ret['uname'] = ($_REQUEST['uname'] ?? '');
56
            $ret['email'] = ($_REQUEST['email'] ?? '');
57
        }
58
        $ret['agent'] = $_SERVER['HTTP_USER_AGENT'];
59
        if ($ip) {
60
            $ret['is_proxied']   = false;
61
            $ret['network-addy'] = @gethostbyaddr($ip);
0 ignored issues
show
Bug introduced by
It seems like $ip can also be of type true; however, parameter $ip of gethostbyaddr() 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

61
            $ret['network-addy'] = @gethostbyaddr(/** @scrutinizer ignore-type */ $ip);
Loading history...
62
            $ret['long']         = @ip2long($ip);
0 ignored issues
show
Bug introduced by
It seems like $ip can also be of type true; however, parameter $ip of ip2long() 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

62
            $ret['long']         = @ip2long(/** @scrutinizer ignore-type */ $ip);
Loading history...
63
            if (is_ipv6($ip)) {
0 ignored issues
show
Bug introduced by
It seems like $ip can also be of type true; however, parameter $ip of is_ipv6() 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

63
            if (is_ipv6(/** @scrutinizer ignore-type */ $ip)) {
Loading history...
64
                $ret['ip6'] = true;
65
                $ret['ip4'] = false;
66
            } else {
67
                $ret['ip4'] = true;
68
                $ret['ip6'] = false;
69
            }
70
            $ret['ip'] = $ip;
71
        } elseif (Request::hasVar('HTTP_X_FORWARDED_FOR', 'SERVER')) {
72
                $ip                  = $_SERVER['HTTP_X_FORWARDED_FOR'];
73
                $ret['is_proxied']   = true;
74
                $proxy_ip            = $_SERVER['REMOTE_ADDR'];
75
                $ret['network-addy'] = @gethostbyaddr($ip);
76
                $ret['long']         = @ip2long($ip);
77
                if (is_ipv6($ip)) {
78
                    $ret['ip6']       = true;
79
                    $ret['proxy-ip6'] = true;
80
                    $ret['ip4']       = false;
81
                    $ret['proxy-ip4'] = false;
82
                } else {
83
                    $ret['ip4']       = true;
84
                    $ret['proxy-ip4'] = true;
85
                    $ret['ip6']       = false;
86
                    $ret['proxy-ip6'] = false;
87
                }
88
                $ret['ip']       = $ip;
89
                $ret['proxy-ip'] = $proxy_ip;
90
            } else {
91
                $ret['is_proxied']   = false;
92
                $ip                  = $_SERVER['REMOTE_ADDR'];
93
                $ret['network-addy'] = @gethostbyaddr($ip);
94
                $ret['long']         = @ip2long($ip);
95
                if (is_ipv6($ip)) {
96
                    $ret['ip6'] = true;
97
                    $ret['ip4'] = false;
98
                } else {
99
                    $ret['ip4'] = true;
100
                    $ret['ip6'] = false;
101
                }
102
                $ret['ip'] = $ip;
103
        }
104
        $ret['made'] = time();
105
106
        return $ret;
107
    }
108
}
109
110
if (!function_exists('is_ipv6')) {
111
    /**
112
     * @param string $ip
113
     * @return bool
114
     */
115
    function is_ipv6($ip = ''): bool
116
    {
117
        if ('' == $ip) {
118
            return false;
119
        }
120
121
        if (mb_substr_count($ip, ':') > 0) {
122
            return true;
123
        }
124
125
        return false;
126
    }
127
}
128
129
if (!function_exists('songlist_getFilterElement')) {
130
    /**
131
     * @param        $filter
132
     * @param        $field
133
     * @param string $sort
134
     * @param string $op
135
     * @param string $fct
136
     * @return bool|\XoopsModules\Songlist\Form\SelectAlbumForm|\XoopsModules\Songlist\Form\SelectArtistForm|\XoopsModules\Songlist\Form\SelectCategoryForm|\XoopsModules\Songlist\Form\SelectGenreForm|\XoopsModules\Songlist\Form\SelectVoiceForm
137
     */
138
    function songlist_getFilterElement($filter, $field, $sort = 'created', $op = '', $fct = '')
0 ignored issues
show
Unused Code introduced by
The parameter $fct 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

138
    function songlist_getFilterElement($filter, $field, $sort = 'created', $op = '', /** @scrutinizer ignore-unused */ $fct = '')

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...
139
    {
140
        $components = songlist_getFilterURLComponents($filter, $field, $sort);
141
        $ele        = false;
142
        require_once __DIR__ . '/songlist.object.php';
143
        switch ($field) {
144
            case 'gid':
145
                if ('genre' !== $op) {
146
                    $ele = new SelectGenreForm('', 'filter_' . $field . '', $components['value'], 1, false);
147
                    $ele->setExtra(
148
                        'onchange="window.open(\''
149
                        . $_SERVER['SCRIPT_NAME']
150
                        . '?'
151
                        . $components['extra']
152
                        . '&filter='
153
                        . $components['filter']
154
                        . (!empty($components['filter']) ? '|' : '')
155
                        . $field
156
                        . ',\'+this.options[this.selectedIndex].value'
157
                        . (!empty($components['operator']) ? '+\','
158
                                                             . $components['operator']
159
                                                             . '\'' : '')
160
                        . ',\'_self\')"'
161
                    );
162
                }
163
                break;
164
            case 'vcid':
165
                if ('voice' !== $op) {
166
                    $ele = new SelectVoiceForm('', 'filter_' . $field . '', $components['value'], 1, false);
167
                    $ele->setExtra(
168
                        'onchange="window.open(\''
169
                        . $_SERVER['SCRIPT_NAME']
170
                        . '?'
171
                        . $components['extra']
172
                        . '&filter='
173
                        . $components['filter']
174
                        . (!empty($components['filter']) ? '|' : '')
175
                        . $field
176
                        . ',\'+this.options[this.selectedIndex].value'
177
                        . (!empty($components['operator']) ? '+\','
178
                                                             . $components['operator']
179
                                                             . '\'' : '')
180
                        . ',\'_self\')"'
181
                    );
182
                }
183
                break;
184
            case 'cid':
185
                if ('category' !== $op) {
186
                    $ele = new SelectCategoryForm('', 'filter_' . $field . '', $components['value'], 1, false);
187
                    $ele->setExtra(
188
                        'onchange="window.open(\''
189
                        . $_SERVER['SCRIPT_NAME']
190
                        . '?'
191
                        . $components['extra']
192
                        . '&filter='
193
                        . $components['filter']
194
                        . (!empty($components['filter']) ? '|' : '')
195
                        . $field
196
                        . ',\'+this.options[this.selectedIndex].value'
197
                        . (!empty($components['operator']) ? '+\','
198
                                                             . $components['operator']
199
                                                             . '\'' : '')
200
                        . ',\'_self\')"'
201
                    );
202
                }
203
                break;
204
            case 'pid':
205
                $ele = new SelectCategoryForm('', 'filter_' . $field . '', $components['value'], 1, false);
206
                $ele->setExtra(
207
                    'onchange="window.open(\''
208
                    . $_SERVER['SCRIPT_NAME']
209
                    . '?'
210
                    . $components['extra']
211
                    . '&filter='
212
                    . $components['filter']
213
                    . (!empty($components['filter']) ? '|' : '')
214
                    . $field
215
                    . ',\'+this.options[this.selectedIndex].value'
216
                    . (!empty($components['operator']) ? '+\','
217
                                                         . $components['operator']
218
                                                         . '\'' : '')
219
                    . ',\'_self\')"'
220
                );
221
                break;
222
            case 'abid':
223
                if ('albums' !== $op) {
224
                    $ele = new SelectAlbumForm('', 'filter_' . $field . '', $components['value'], 1, false);
225
                    $ele->setExtra(
226
                        'onchange="window.open(\''
227
                        . $_SERVER['SCRIPT_NAME']
228
                        . '?'
229
                        . $components['extra']
230
                        . '&filter='
231
                        . $components['filter']
232
                        . (!empty($components['filter']) ? '|' : '')
233
                        . $field
234
                        . ',\'+this.options[this.selectedIndex].value'
235
                        . (!empty($components['operator']) ? '+\','
236
                                                             . $components['operator']
237
                                                             . '\'' : '')
238
                        . ',\'_self\')"'
239
                    );
240
                }
241
                break;
242
            case 'aid':
243
                if ('artists' !== $op) {
244
                    $ele = new SelectArtistForm('', 'filter_' . $field . '', $components['value'], 1, false);
245
                    $ele->setExtra(
246
                        'onchange="window.open(\''
247
                        . $_SERVER['SCRIPT_NAME']
248
                        . '?'
249
                        . $components['extra']
250
                        . '&filter='
251
                        . $components['filter']
252
                        . (!empty($components['filter']) ? '|' : '')
253
                        . $field
254
                        . ',\'+this.options[this.selectedIndex].value'
255
                        . (!empty($components['operator']) ? '+\','
256
                                                             . $components['operator']
257
                                                             . '\'' : '')
258
                        . ',\'_self\')"'
259
                    );
260
                }
261
                break;
262
            case 'sid':
263
                if ('songs' !== $op) {
264
                    $ele = new SelectSongForm('', 'filter_' . $field . '', $components['value'], 1, false);
265
                    $ele->setExtra(
266
                        'onchange="window.open(\''
267
                        . $_SERVER['SCRIPT_NAME']
268
                        . '?'
269
                        . $components['extra']
270
                        . '&filter='
271
                        . $components['filter']
272
                        . (!empty($components['filter']) ? '|' : '')
273
                        . $field
274
                        . ',\'+this.options[this.selectedIndex].value'
275
                        . (!empty($components['operator']) ? '+\','
276
                                                             . $components['operator']
277
                                                             . '\'' : '')
278
                        . ',\'_self\')"'
279
                    );
280
                }
281
                break;
282
            case 'name':
283
            case 'title':
284
            case 'artists':
285
            case 'albums':
286
            case 'songs':
287
            case 'hits':
288
            case 'rank':
289
            case 'votes':
290
            case 'description':
291
            case 'lyrics':
292
            case 'songid':
293
            case 'tags':
294
                $ele = new \XoopsFormElementTray('');
295
                $ele->addElement(new \XoopsFormText('', 'filter_' . $field . '', 11, 40, $components['value']));
296
                $button = new \XoopsFormButton('', 'button_' . $field . '', '[+]');
297
                $button->setExtra(
298
                    'onclick="window.open(\''
299
                    . $_SERVER['SCRIPT_NAME']
300
                    . '?'
301
                    . $components['extra']
302
                    . '&filter='
303
                    . $components['filter']
304
                    . (!empty($components['filter']) ? '|' : '')
305
                    . $field
306
                    . ',\'+$(\'#filter_'
307
                    . $field
308
                    . '\').val()'
309
                    . (!empty($components['operator']) ? '+\','
310
                                                         . $components['operator']
311
                                                         . '\'' : '')
312
                    . ',\'_self\')"'
313
                );
314
                $ele->addElement($button);
315
                break;
316
        }
317
318
        return $ele;
319
    }
320
}
321
322
if (!function_exists('songlist_getFilterURLComponents')) {
323
    /**
324
     * @param        $filter
325
     * @param        $field
326
     * @param string $sort
327
     * @return array
328
     */
329
    function songlist_getFilterURLComponents($filter, $field, $sort = 'created'): array
330
    {
331
        $parts     = explode('|', $filter);
332
        $ret       = [];
333
        $value     = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $value is dead and can be removed.
Loading history...
334
        $ele_value = '';
335
        $operator  = '';
336
        foreach ($parts as $part) {
337
            $var = explode(',', $part);
338
            if (count($var) > 1) {
339
                if ($var[0] == $field) {
340
                    $ele_value = $var[1];
341
                    if (isset($var[2])) {
342
                        $operator = $var[2];
343
                    }
344
                } elseif (1 != $var[0]) {
345
                    $ret[] = implode(',', $var);
346
                }
347
            }
348
        }
349
        $pagenav          = [];
350
        $pagenav['op']    = $_REQUEST['op'] ?? 'videos';
351
        $pagenav['fct']   = $_REQUEST['fct'] ?? 'list';
352
        $pagenav['limit'] = Request::getInt('limit', 30, 'REQUEST');
353
        $pagenav['start'] = 0;
354
        $pagenav['order'] = !empty($_REQUEST['order']) ? $_REQUEST['order'] : 'DESC';
355
        $pagenav['sort']  = !empty($_REQUEST['sort']) ? '' . $_REQUEST['sort'] . '' : $sort;
356
        $retb             = [];
357
        foreach ($pagenav as $key => $value) {
358
            $retb[] = "$key=$value";
359
        }
360
361
        return ['value' => $ele_value, 'field' => $field, 'operator' => $operator, 'filter' => implode('|', $ret), 'extra' => implode('&', $retb)];
362
    }
363
}
364
365
if (!function_exists('songlist_obj2array')) {
366
    /**
367
     * @param $objects
368
     * @return array
369
     */
370
    function songlist_obj2array($objects): array
371
    {
372
        $ret = [];
373
        foreach ((array)$objects as $key => $value) {
374
            if (is_a($value, 'stdClass')) {
375
                $ret[$key] = songlist_obj2array($value);
376
            } elseif (is_array($value)) {
377
                $ret[$key] = songlist_obj2array($value);
378
            } else {
379
                $ret[$key] = $value;
380
            }
381
        }
382
383
        return $ret;
384
    }
385
}
386
387
if (!function_exists('songlist_shortenurl')) {
388
    /**
389
     * @param $url
390
     * @return mixed
391
     */
392
    function songlist_shortenurl($url)
393
    {
394
        /** @var \XoopsModuleHandler $moduleHandler */
395
        $moduleHandler = xoops_getHandler('module');
396
        /** @var \XoopsConfigHandler $configHandler */
397
        $configHandler                   = xoops_getHandler('config');
398
        $GLOBALS['songlistModule']       = $moduleHandler->getByDirname('songlist');
399
        $GLOBALS['songlistModuleConfig'] = $configHandler->getConfigList($GLOBALS['songlistModule']->getVar('mid'));
400
401
        if (!empty($GLOBALS['songlistModuleConfig']['bitly_username']) && !empty($GLOBALS['songlistModuleConfig']['bitly_apikey'])) {
402
            $source_url = $GLOBALS['songlistModuleConfig']['bitly_apiurl'] . '/shorten?login=' . $GLOBALS['songlistModuleConfig']['bitly_username'] . '&apiKey=' . $GLOBALS['songlistModuleConfig']['bitly_apikey'] . '&format=json&longUrl=' . urlencode($url);
403
            $cookies    = XOOPS_ROOT_PATH . '/uploads/songlist_' . md5($GLOBALS['songlistModuleConfig']['bitly_apikey']) . '.cookie';
404
            if (!$ch = curl_init($source_url)) {
405
                return $url;
406
            }
407
            curl_setopt($ch, CURLOPT_COOKIEJAR, $cookies);
408
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
409
            curl_setopt($ch, CURLOPT_USERAGENT, $GLOBALS['songlistModuleConfig']['user_agent']);
410
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $GLOBALS['songlistModuleConfig']['curl_connect_timeout']);
411
            curl_setopt($ch, CURLOPT_TIMEOUT, $GLOBALS['songlistModuleConfig']['curl_timeout']);
412
            $data = curl_exec($ch);
413
            curl_close($ch);
414
            $result                = songlist_object2array(json_decode($data));
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type true; however, parameter $json of json_decode() 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

414
            $result                = songlist_object2array(json_decode(/** @scrutinizer ignore-type */ $data));
Loading history...
Bug introduced by
The function songlist_object2array was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

414
            $result                = /** @scrutinizer ignore-call */ songlist_object2array(json_decode($data));
Loading history...
415
            $result['status_code'] = 200;
416
            if ($result['status_code']) {
417
                if (!empty($result['data']['url'])) {
418
                    return $result['data']['url'];
419
                }
420
421
                return $url;
422
            }
423
424
            return $url;
425
        }
426
427
        return $url;
428
    }
429
}
430
431
if (!function_exists('songlist_xml2array')) {
432
    /**
433
     * @param        $contents
434
     * @param int    $get_attributes
435
     * @param string $priority
436
     * @return array|void
437
     */
438
    function songlist_xml2array($contents, $get_attributes = 1, $priority = 'tag')
439
    {
440
        if (!$contents) {
441
            return [];
442
        }
443
444
        if (!function_exists('xml_parser_create')) {
445
            return [];
446
        }
447
448
        //Get the XML parser of PHP - PHP must have this module for the parser to work
449
        $parser = xml_parser_create('');
450
        xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8'); # https://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss
451
        xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
452
        xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
453
        xml_parse_into_struct($parser, trim($contents), $xml_values);
454
        xml_parser_free($parser);
455
456
        if (!$xml_values) {
457
            return;
458
        }//Hmm...
459
460
        //Initializations
461
        $xml_array   = [];
462
        $parents     = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $parents is dead and can be removed.
Loading history...
463
        $opened_tags = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $opened_tags is dead and can be removed.
Loading history...
464
        $arr         = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $arr is dead and can be removed.
Loading history...
465
466
        $current = &$xml_array; //Refference
467
468
        //Go through the tags.
469
        $repeated_tag_index = []; //Multiple tags with same name will be turned into an array
470
        foreach ($xml_values as $data) {
471
            unset($attributes, $value); //Remove existing values, or there will be trouble
472
473
            //This command will extract these variables into the foreach scope
474
            // tag(string), type(string), level(int), attributes(array).
475
            extract($data); //We could use the array by itself, but this cooler.
476
477
            $result          = [];
478
            $attributes_data = [];
479
480
            if (isset($value)) {
481
                if ('tag' === $priority) {
482
                    $result = $value;
483
                } else {
484
                    $result['value'] = $value;
485
                } //Put the value in a assoc array if we are in the 'Attribute' mode
486
            }
487
488
            //Set the attributes too.
489
            if (isset($attributes) and $get_attributes) {
490
                foreach ($attributes as $attr => $val) {
491
                    if ('tag' === $priority) {
492
                        $attributes_data[$attr] = $val;
493
                    } else {
494
                        $result['attr'][$attr] = $val;
495
                    } //Set all the attributes in a array called 'attr'
496
                }
497
            }
498
499
            //See tag status and do the needed.
500
            if ('open' === $type) {//The starting of the tag '<tag>'
501
                $parent[$level - 1] = &$current;
502
                if (!is_array($current) or (!array_key_exists($tag, $current))) { //Insert New tag
503
                    $current[$tag] = $result;
504
                    if ($attributes_data) {
505
                        $current[$tag . '_attr'] = $attributes_data;
506
                    }
507
                    $repeated_tag_index[$tag . '_' . $level] = 1;
508
509
                    $current = &$current[$tag];
510
                } else { //There was another element with the same tag name
511
                    if (isset($current[$tag][0])) {//If there is a 0th element it is already an array
512
                        $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
513
                        $repeated_tag_index[$tag . '_' . $level]++;
514
                    } else {//This section will make the value an array if multiple tags with the same name appear together
515
                        $current[$tag]                           = [$current[$tag], $result]; //This will combine the existing item and the new item together to make an array
516
                        $repeated_tag_index[$tag . '_' . $level] = 2;
517
518
                        if (isset($current[$tag . '_attr'])) { //The attribute of the last(0th) tag must be moved as well
519
                            $current[$tag]['0_attr'] = $current[$tag . '_attr'];
520
                            unset($current[$tag . '_attr']);
521
                        }
522
                    }
523
                    $last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
524
                    $current         = &$current[$tag][$last_item_index];
525
                }
526
            } elseif ('complete' === $type) { //Tags that ends in 1 line '<tag>'
527
                //See if the key is already taken.
528
                if (isset($current[$tag])) { //If taken, put all things inside a list(array)
529
                    if (isset($current[$tag][0]) and is_array($current[$tag])) {//If it is already an array...
530
                        // ...push the new element into that array.
531
                        $current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
532
533
                        if ('tag' === $priority and $get_attributes and $attributes_data) {
534
                            $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
535
                        }
536
                        $repeated_tag_index[$tag . '_' . $level]++;
537
                    } else { //If it is not an array...
538
                        $current[$tag]                           = [$current[$tag], $result]; //...Make it an array using using the existing value and the new value
539
                        $repeated_tag_index[$tag . '_' . $level] = 1;
540
                        if ('tag' === $priority and $get_attributes) {
541
                            if (isset($current[$tag . '_attr'])) { //The attribute of the last(0th) tag must be moved as well
542
                                $current[$tag]['0_attr'] = $current[$tag . '_attr'];
543
                                unset($current[$tag . '_attr']);
544
                            }
545
546
                            if ($attributes_data) {
547
                                $current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
548
                            }
549
                        }
550
                        $repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
551
                    }
552
                } else { //New Key
553
                    $current[$tag]                           = $result;
554
                    $repeated_tag_index[$tag . '_' . $level] = 1;
555
                    if ('tag' === $priority and $attributes_data) {
556
                        $current[$tag . '_attr'] = $attributes_data;
557
                    }
558
                }
559
            } elseif ('close' === $type) { //End of tag '</tag>'
560
                $current = &$parent[$level - 1];
561
            }
562
        }
563
564
        return $xml_array;
565
    }
566
}
567
568
if (!function_exists('songlist_toXml')) {
569
    /**
570
     * @param $array
571
     * @param $name
572
     * @param $standalone
573
     * @param $beginning
574
     * @param $nested
575
     * @return string
576
     */
577
    function songlist_toXml($array, $name, $standalone, $beginning, $nested): string
578
    {
579
        $output = '';
580
        if ($beginning) {
581
            if ($standalone) {
582
                header('content-type:text/xml;charset=' . _CHARSET);
583
            }
584
            $output .= '<' . '?' . 'xml version="1.0" encoding="' . _CHARSET . '"' . '?' . '>' . "\n";
585
            $output .= '<' . $name . '>' . "\n";
586
            $nested = 0;
587
        }
588
589
        if (is_array($array)) {
590
            foreach ($array as $key => $value) {
591
                ++$nested;
592
                if (is_array($value)) {
593
                    $output .= str_repeat("\t", (int)$nested) . '<' . (is_string($key) ? $key : $name . '_' . $key) . '>' . "\n";
594
                    ++$nested;
595
                    $output .= songlist_toXml($value, $name, false, false, $nested);
596
                    $nested--;
597
                    $output .= str_repeat("\t", (int)$nested) . '</' . (is_string($key) ? $key : $name . '_' . $key) . '>' . "\n";
598
                } elseif ('' != $value) {
599
                        ++$nested;
600
                        $output .= str_repeat("\t", (int)$nested) . '  <' . (is_string($key) ? $key : $name . '_' . $key) . '>' . trim($value) . '</' . (is_string($key) ? $key : $name . '_' . $key) . '>' . "\n";
601
                        $nested--;
602
                }
603
                $nested--;
604
            }
605
        } elseif ('' != $array) {
606
            ++$nested;
607
            $output .= str_repeat("\t", (int)$nested) . trim($array) . "\n";
608
            $nested--;
609
        }
610
611
        if ($beginning) {
612
            $output .= '</' . $name . '>';
613
614
            return $output;
615
        }
616
617
        return $output;
618
    }
619
}
620