Passed
Push — main ( 97d8d6...d31f66 )
by Stefan
11:26
created

XMLHelper::getFormatedXMLError()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 9
nc 4
nop 1
dl 0
loc 12
rs 9.9666
c 1
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace SKien\Formgenerator;
5
6
/**
7
 * Trait containing some Helper to generate the Form from XML-File
8
 * @package Formgenerator
9
 * @author Stefanius <[email protected]>
10
 * @copyright MIT License - see the LICENSE file for details
11
 */
12
trait XMLHelper
13
{
14
    /**
15
     * Get the string value of named attrib or return default value, if attrib not exist
16
     * @param \DOMElement $oXMLElement
17
     * @param string $strName
18
     * @param string $strDefault
19
     * @return string|null
20
     */
21
    static protected function getAttribString(\DOMElement $oXMLElement, string $strName, ?string $strDefault = null) : ?string
22
    {
23
        if (!$oXMLElement->hasAttribute($strName)) {
24
            return $strDefault;
25
        }
26
        return $oXMLElement->getAttribute($strName);
27
    }
28
29
    /**
30
     * Get the integer value of named attrib or return default value, if attrib not exist
31
     * @param \DOMElement $oXMLElement
32
     * @param string $strName
33
     * @param int $iDefault
34
     * @return int|null
35
     */
36
    static protected function getAttribInt(\DOMElement $oXMLElement, string $strName, ?int $iDefault = null) : ?int
37
    {
38
        if (!$oXMLElement->hasAttribute($strName)) {
39
            return $iDefault;
40
        }
41
        return intval($oXMLElement->getAttribute($strName));
42
    }
43
44
    /**
45
     * Get an array of string values of the named attrib.
46
     * The attrib must contain a list spearated by whitespace(s).
47
     * @param \DOMElement $oXMLElement
48
     * @param string $strName
49
     * @return array|null
50
     */
51
    static protected function getAttribStringArray(\DOMElement $oXMLElement, string $strName) : ?array
52
    {
53
        $aValues = null;
54
        $strArray = $oXMLElement->getAttribute($strName);
55
        if (strlen($strArray) > 0) {
56
            // to make it validateable by XSD-schema, we use a whitespace-separated list since
57
            // there is no way to define the delimiter for xs:list in XSD...
58
             $aValues = array_map('trim', preg_split('/\s+/', trim($strArray)));
59
        }
60
        return $aValues;
61
    }
62
63
    /**
64
     * Get an array of integer values of the named attrib.
65
     * The attrib must contain a list spearated by comma.
66
     * @param \DOMElement $oXMLElement
67
     * @param string $strName
68
     * @return array|null
69
     */
70
    static protected function getAttribIntArray(\DOMElement $oXMLElement, string $strName) : ?array
71
    {
72
        $aValues = null;
73
        $strArray = $oXMLElement->getAttribute($strName);
74
        if (strlen($strArray) > 0) {
75
            $aValues = array_map('intval', explode(',', $strArray));
76
        }
77
        return $aValues;
78
    }
79
80
    /**
81
     * Get the flags specified by the named attrib.
82
     * The attrib must contain a list of FormFlag - constants spearated by any whitespace(s).
83
     * @param \DOMElement $oXMLElement
84
     * @return int
85
     */
86
    static protected function getAttribFlags(\DOMElement $oXMLElement) : int
87
    {
88
        $wFlags = 0;
89
        $strFlags = $oXMLElement->getAttribute('flags');
90
        if (strlen($strFlags) > 0) {
91
            // to make it validateable by XSD-schema, we use a whitespace-separated list since
92
            // there is no way to define the delimiter for xs:list in XSD...
93
            $aFlags = array_map('trim', preg_split('/\s+/', trim($strFlags)));
94
            foreach ($aFlags as $strFlag) {
95
                $strConstName = __NAMESPACE__ . '\FormFlags::' . strtoupper($strFlag);
96
                if (defined($strConstName)) {
97
                    $wFlags += constant($strConstName);
98
                } else {
99
                    trigger_error('Unknown Constant [' . $strConstName . '] for the FormFlag property!', E_USER_WARNING);
100
                }
101
            }
102
        }
103
        return $wFlags;
104
    }
105
106
    /**
107
     * Read all known attributes that don't need any further processing.
108
     * @param \DOMElement $oXMLElement
109
     */
110
    public function readElementAttributes(\DOMElement $oXMLElement, ?array $aAttributes) : array
111
    {
112
        $aAttributesToRead = [
113
            'onclick',
114
            'ondblclick',
115
            'onchange',
116
            'oninput',
117
            'onfocus',
118
            'onblur',
119
            'onkeydown',
120
            'onkeypress',
121
            'onkeyup',
122
            'title',
123
            'placeholder',
124
            'maxlength',
125
        ];
126
        if ($aAttributes == null) {
127
            $aAttributes = array();
128
        }
129
        foreach ($aAttributesToRead as $strAttribute) {
130
            if (($strValue = self::getAttribString($oXMLElement, $strAttribute)) !== null) {
131
                $aAttributes[$strAttribute] = $strValue;
132
            }
133
        }
134
        return $aAttributes;
135
    }
136
137
    /**
138
     * Get the child with the given tag name.
139
     * The given parent must only contain one chuld with this name!
140
     * @param string $strName
141
     * @return \DOMElement|null
142
     */
143
    public function getXMLChild(\DOMElement $oXMLElement, string $strName) : ?\DOMElement
144
    {
145
        $oList = $oXMLElement->getElementsByTagName($strName);
146
        if ($oList->count() === 1) {
147
            if ($oList->item(0) instanceof \DOMElement) {
148
                return $oList->item(0);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $oList->item(0) could return the type DOMNode which includes types incompatible with the type-hinted return DOMElement|null. Consider adding an additional type-check to rule them out.
Loading history...
149
            }
150
        }
151
        return null;
152
    }
153
154
    /**
155
     * Get formated list of detailed XML error.
156
     * this method only works, if <i><b>libxml_use_internal_errors(true);</b></i> is called
157
     * before parsing the xml and/or validating the xml against XSD file.
158
     * @param bool $bPlainText
159
     * @return string
160
     */
161
    public function getFormatedXMLError(bool $bPlainText) : string
162
    {
163
        $errors = libxml_get_errors();
164
        $aLevel = [LIBXML_ERR_WARNING => 'Warning ', LIBXML_ERR_ERROR => 'Error ', LIBXML_ERR_FATAL => 'Fatal Error '];
165
        $strCR = ($bPlainText ? PHP_EOL : '<br/>');
166
        $strErrorMsg = '';
167
        foreach ($errors as $error) {
168
            $strErrorMsg .= $strCR . $aLevel[$error->level] . $error->code;
169
            $strErrorMsg .= ' (Line ' . $error->line . ', Col ' . $error->column . ') ';
170
            $strErrorMsg .= trim($error->message);
171
        }
172
        return $strErrorMsg;
173
    }
174
}
175