Completed
Pull Request — master (#348)
by
unknown
13:49
created

HTMLConverter::createRecordRow()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 4
dl 0
loc 11
ccs 0
cts 0
cp 0
crap 6
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * League.Csv (https://csv.thephpleague.com)
5
 *
6
 * (c) Ignace Nyamagana Butera <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace League\Csv;
15
16
use DOMDocument;
17
use DOMElement;
18
use DOMException;
19
use Traversable;
20
use function preg_match;
21
22
/**
23
 * Converts tabular data into an HTML Table string.
24
 */
25
class HTMLConverter
26
{
27
    /**
28
     * table class attribute value.
29
     *
30
     * @var string
31
     */
32
    protected $class_name = 'table-csv-data';
33
34
    /**
35
     * table id attribute value.
36
     *
37
     * @var string
38
     */
39
    protected $id_value = '';
40
41
    /**
42
     * @var XMLConverter
43
     */
44
    protected $xml_converter;
45
46
    /**
47 6
     * New Instance.
48
     */
49 6
    public function __construct()
50 6
    {
51 6
        $this->xml_converter = (new XMLConverter())
52 6
            ->rootElement('table')
53
            ->recordElement('tr')
54 6
            ->fieldElement('td')
55
        ;
56
    }
57
58
    /**
59
     * Convert an Record collection into a DOMDocument.
60
     *
61 3
     * @param array|Traversable $records      The tabular data collection
62
     * @param array             $headerRecord An optional array of headers to output to the table using `<thead>` and `<th>` elements
63 3
     * @param array             $footerRecord An optional array of footers to output to the table using `<tfoot>` and `<th>` elements
64 3
     *
65 3
     * @return string
66
     */
67 3
    public function convert($records, array $headerRecord = [], array $footerRecord = []): string
68
    {
69
        // If we do not want to add any headers or records, then we can default entirely to the XML converter
70
        if ([] === $headerRecord && [] === $footerRecord) {
71
            /** @var DOMDocument $doc */
72
            $doc = $this->xml_converter->convert($records);
73
74
            /** @var DOMElement $table */
75 6
            $table = $doc->getElementsByTagName('table')->item(0);
76
            $table = $this->styleTableElement($table);
77 6
78 3
            return $doc->saveHTML($table);
79
        };
80 3
81 3
        $doc = new DOMDocument('1.0');
82 3
83
        $thead = $this->createRecordRow('thead', 'th', $headerRecord, $doc);
84 3
        $tfoot = $this->createRecordRow('tfoot', 'th', $footerRecord, $doc);
85
        $tbody = $this->xml_converter->rootElement('tbody')->import($records, $doc);
0 ignored issues
show
Documentation introduced by
$records is of type array|object<Traversable>, but the function expects a object<League\Csv\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
86
        $table = $doc->createElement('table');
87
        $table = $this->styleTableElement($table);
88
89
        $table = $this->styleTableElement($table);
90 3
        $table->appendChild($thead);
91
        $table->appendChild($tbody);
92 3
        $table->appendChild($tfoot);
93 3
94
        $doc->appendChild($table);
95 3
96
        return $doc->saveHTML();
97
    }
98
99
    /**
100
     * HTML table class name setter.
101 3
     *
102
     * @throws DOMException if the id_value contains any type of whitespace
103 3
     */
104 3
    public function table(string $class_name, string $id_value = ''): self
105
    {
106 3
        if (preg_match(",\s,", $id_value)) {
107
            throw new DOMException("the id attribute's value must not contain whitespace (spaces, tabs etc.)");
108
        }
109
        $clone = clone $this;
110
        $clone->class_name = $class_name;
111
        $clone->id_value = $id_value;
112
113
        return $clone;
114
    }
115
116
    /**
117
     * HTML tr record offset attribute setter.
118
     */
119
    public function tr(string $record_offset_attribute_name): self
120
    {
121
        $clone = clone $this;
122
        $clone->xml_converter = $this->xml_converter->recordElement('tr', $record_offset_attribute_name);
123
124
        return $clone;
125
    }
126
127
    /**
128
     * HTML td field name attribute setter.
129
     */
130
    public function td(string $fieldname_attribute_name): self
131
    {
132
        $clone = clone $this;
133
        $clone->xml_converter = $this->xml_converter->fieldElement('td', $fieldname_attribute_name);
134
135
        return $clone;
136
    }
137
138
    /**
139
     * Create a DOMElement representing a single record of data
140
     *
141
     * @param string $rowTagName
142
     * @param string $elementTagName
143
     * @param array $record
144
     * @param DOMDocument $doc
145
     *
146
     * @return DOMElement
147
     */
148
    private function createRecordRow(string $rowTagName, string $elementTagName, array $record, DOMDocument $doc)
149
    {
150
        $node = $this->xml_converter->rootElement($rowTagName)->fieldElement($elementTagName)->import([$record], $doc);
0 ignored issues
show
Documentation introduced by
array($record) is of type array<integer,array,{"0":"array"}>, but the function expects a object<League\Csv\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
151
152
        /** @var DOMElement $element */
153
        foreach ($node->getElementsByTagName($elementTagName) as $element) {
154
            $element->setAttribute('scope', 'col');
155
        }
156
157
        return $node;
158
    }
159
160
    /**
161
     * Style the table dom element
162
     *
163
     * @param DOMElement $table_element
164
     *
165
     * @return DOMElement
166
     */
167
    private function styleTableElement(DOMElement $table_element)
168
    {
169
        $table_element->setAttribute('class', $this->class_name);
170
        $table_element->setAttribute('id', $this->id_value);
171
        return $table_element;
172
    }
173
}
174