Passed
Push — main ( c2190a...e8aeda )
by Dimitri
09:14 queued 01:02
created

XmlFormatter::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 2
eloc 3
c 1
b 1
f 0
nc 2
nop 0
dl 0
loc 8
ccs 2
cts 2
cp 1
crap 2
rs 10
1
<?php
2
3
/**
4
 * This file is part of Blitz PHP framework.
5
 *
6
 * (c) 2022 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace BlitzPHP\Formatter;
13
14
use BlitzPHP\Exceptions\FormatException;
15
use SimpleXMLElement;
16
17
/**
18
 * Formateur de données XML
19
 */
20
class XmlFormatter implements FormatterInterface
21
{
22
    public function __construct()
23
    {
24
        // SimpleXML est installé par défaut, mais il est préférable de vérifier, puis de fournir une solution de repli.
25
        if (! extension_loaded('simplexml')) {
26 6
            throw FormatException::missingExtension();
27
        }
28
29 6
        helper('inflector');
30
    }
31
32
    /**
33
     * {@inheritDoc}
34
     *
35
     * @return false|string Représentation XML d'une valeur
36
     *                      false en cas d'erreur de formattage
37
     */
38
    public function format($data)
39
    {
40 4
        $basenode  = 'xml';
41 4
        $structure = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><{$basenode} />");
42
43 4
        $this->arrayToXml((array) $data, $structure, $basenode);
44
45 4
        return $structure->asXML();
46
    }
47
48
    /**
49
     * {@inheritDoc}
50
     *
51
     * @param string $data Chaine XML
52
     */
53
    public function parse(string $data): array
54
    {
55 2
        $xml = @simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
56
57
        if ($xml === false) {
58 2
            return [];
59
        }
60
61 2
        $json = json_encode($xml);
62
63 2
        return json_decode($json, true);
64
    }
65
66
    /**
67
     * Une méthode récursive pour convertir un tableau en une chaîne XML valide.
68
     */
69
    protected function arrayToXml(array $data, SimpleXMLElement &$structure, string $basenode): void
70
    {
71
        foreach ($data as $key => $value) {
72
            // change false/true en 0/1
73
            if (is_bool($value)) {
74 2
                $value = (int) $value;
75
            }
76
77
            // pas de touches numériques dans notre xml s'il vous plait !
78
            if (is_numeric($key)) {
79
                // crée une clé de chaîne...
80 4
                $key = singular($basenode) !== $basenode ? singular($basenode) : 'item';
81
            }
82
83
            // remplace tout ce qui n'est pas alphanumérique
84 4
            $key = preg_replace('/[^a-z_\-0-9]/i', '', $key);
85
86
            if ($key === '_attributes' && (is_array($value) || is_object($value))) {
87 2
                $attributes = $value;
88
                if (is_object($attributes)) {
89 2
                    $attributes = get_object_vars($attributes);
90
                }
91
92
                foreach ($attributes as $attribute_name => $attribute_value) {
93 2
                    $structure->addAttribute($attribute_name, $attribute_value);
94
                }
95
            }
96
            // s'il y a un autre tableau trouvé appelez récursivement cette fonction
97
            elseif (is_array($value) || is_object($value)) {
98 4
                $node = $structure->addChild($key);
99
100
                // appel récursif
101 4
                $this->arrayToXml($value, $node, $key);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type object; however, parameter $data of BlitzPHP\Formatter\XmlFormatter::arrayToXml() does only seem to accept array, 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

101
                $this->arrayToXml(/** @scrutinizer ignore-type */ $value, $node, $key);
Loading history...
102
            } else {
103
                // ajouter un seul noeud
104 4
                $value = htmlspecialchars(html_entity_decode($value ?? '', ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8');
105
106 4
                $structure->addChild($key, $value);
107
            }
108
        }
109
    }
110
}
111