XMLBuild   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 48.89%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 3
dl 0
loc 135
ccs 22
cts 45
cp 0.4889
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A indentLines() 0 15 2
A startTag() 0 8 2
A attributes() 0 9 2
A attributeValue() 0 9 1
A wrapTag() 0 12 2
A readerNode() 0 15 3
A numericEntitiesSingleByte() 0 10 2
1
<?php
2
3
namespace Thruster\Component\XMLIterator;
4
5
use Traversable;
6
7
/**
8
 * Class XMLBuild
9
 *
10
 * @package Thruster\Component\XMLIterator
11
 * @author  Aurimas Niekis <[email protected]>
12
 */
13
abstract class XMLBuild
14
{
15
    /**
16
     * indentLines()
17
     *
18
     * this will add a line-separator at the end of the last line because if it was
19
     * empty it is not any longer and deserves one.
20
     *
21
     * @param string $lines
22
     * @param string $indent (optional)
23
     *
24
     * @return string
25
     */
26
    public static function indentLines($lines, $indent = '  ')
27
    {
28
        $lineSeparator = "\n";
29
        $buffer        = '';
30
        $line          = strtok($lines, $lineSeparator);
31
32
        while ($line) {
33
            $buffer .= $indent . $line . $lineSeparator;
34
            $line = strtok($lineSeparator);
35
        }
36
37
        strtok(null, null);
38
39
        return $buffer;
40
    }
41
42
    /**
43
     * @param string            $name
44
     * @param array|Traversable $attributes attributeName => attributeValue string pairs
45
     * @param bool              $emptyTag   create an empty element tag (commonly known as short tags)
46
     *
47
     * @return string
48
     */
49 1
    public static function startTag($name, $attributes, $emptyTag = false)
50
    {
51 1
        $buffer = '<' . $name;
52 1
        $buffer .= static::attributes($attributes);
53 1
        $buffer .= $emptyTag ? '/>' : '>';
54
55 1
        return $buffer;
56
    }
57
58
    /**
59
     * @param array|Traversable $attributes attributeName => attributeValue string pairs
60
     *
61
     * @return string
62
     */
63 1
    public static function attributes($attributes)
64
    {
65 1
        $buffer = '';
66 1
        foreach ($attributes as $name => $value) {
67 1
            $buffer .= ' ' . $name . '="' . static::attributeValue($value) . '"';
68
        }
69
70 1
        return $buffer;
71
    }
72
73
    /**
74
     * @param string $value
75
     *
76
     * @see XMLBuild::numericEntitiesSingleByte
77
     *
78
     * @return string
79
     */
80 1
    public static function attributeValue($value)
81
    {
82 1
        $buffer = $value;
83
        // REC-xml/#AVNormalize - preserve
84
        // REC-xml/#sec-line-ends - preserve
85 1
        $buffer = preg_replace_callback('~\r\n|\r(?!\n)|\t~', ['self', 'numericEntitiesSingleByte'], $buffer);
86
87 1
        return htmlspecialchars($buffer, ENT_QUOTES, 'UTF-8', false);
88
    }
89
90
    /**
91
     * @param string            $name
92
     * @param array|Traversable $attributes attributeName => attributeValue string pairs
93
     * @param string            $innerXML
94
     *
95
     * @return string
96
     */
97 1
    public static function wrapTag($name, $attributes, $innerXML)
98
    {
99 1
        if (!strlen($innerXML)) {
100 1
            return XMLBuild::startTag($name, $attributes, true);
101
        }
102
103
        return
104
            XMLBuild::startTag($name, $attributes)
105
            . "\n"
106
            . XMLBuild::indentLines($innerXML)
107
            . "</$name>";
108
    }
109
110
    /**
111
     * @param XMLReader $reader
112
     *
113
     * @return string
114
     */
115
    public static function readerNode(XMLReader $reader)
116
    {
117
        switch ($reader->nodeType) {
118
            case XMLREADER::NONE:
119
                return '%(0)%';
120
            case XMLReader::ELEMENT:
121
                return XMLBuild::startTag($reader->name, new AttributeIterator($reader));
122
            default:
123
                $node         = new Node($reader);
124
                $nodeTypeName = $node->getNodeTypeName();
125
                $nodeType     = $reader->nodeType;
126
127
                return sprintf('%%%s (%d)%%', $nodeTypeName, $nodeType);
128
        }
129
    }
130
131
    /**
132
     * @param array $matches
133
     *
134
     * @return string
135
     * @see attributeValue()
136
     */
137 1
    private static function numericEntitiesSingleByte($matches)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
138
    {
139 1
        $buffer = str_split($matches[0]);
140
141 1
        foreach ($buffer as &$char) {
142 1
            $char = sprintf('&#%d;', ord($char));
143
        }
144
145 1
        return implode('', $buffer);
146
    }
147
}
148