PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
← All changes | libraries/html-parser.class.php +27 -23 2.0.4 → 3.4 View file →
@@ -7,8 +7,10 @@
7 7 * @author Tobias Bäthge
8 8 * @since 2.0.0
9 9 */
10 10
11 +declare(strict_types=1);
12 +
11 13 // Prohibit direct script loading.
12 14 defined( 'ABSPATH' ) || die( 'No direct script access allowed!' );
13 15
14 16 /**
@@ -26,11 +28,11 @@
26 28 *
27 29 * @since 2.0.0
28 30 *
29 31 * @param string $html Data to be parsed.
30 - * @return array|WP_Error Array with table data and options (current table head and foot row) on success, WP_Error on error.
32 + * @return array<string, mixed>|WP_Error Array with table data and options (current table head and foot row) on success, WP_Error on error.
31 33 */
32 - public static function parse( $html ) {
34 + public static function parse( string $html ) /* : array|WP_Error */ {
33 35 if ( false === stripos( $html, '<table' ) || false === stripos( $html, '</table>' ) ) {
34 36 return new WP_Error( 'table_import_html_no_table_found' );
35 37 }
36 38
@@ -40,9 +42,9 @@
40 42 /*
41 43 * Don't expand external entities, see https://websec.io/2012/08/27/Preventing-XXE-in-PHP.html.
42 44 * Silence warnings as the function is deprecated in PHP 8, but can be necessary with LIBXML_NOENT being defined, see https://core.trac.wordpress.org/changeset/50714.
43 45 */
44 - @libxml_disable_entity_loader( true ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
46 + @libxml_disable_entity_loader( true ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged,Generic.PHP.DeprecatedFunctions.Deprecated
45 47 }
46 48 // No warnings/errors raised, but stored internally.
47 49 libxml_use_internal_errors( true );
48 50 $dom = new DOMDocument( '1.0', 'UTF-8' );
@@ -47,10 +49,10 @@
47 49 libxml_use_internal_errors( true );
48 50 $dom = new DOMDocument( '1.0', 'UTF-8' );
49 51 // No strict checking for invalid HTML.
50 52 $dom->strictErrorChecking = false; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
51 - $dom->loadHTML( $full_html );
52 - if ( false === $dom ) {
53 + $result = $dom->loadHTML( $full_html );
54 + if ( ! $result ) {
53 55 return new WP_Error( 'table_import_html_dom_load_html_failed' );
54 56 }
55 57 $dom_tables = $dom->getElementsByTagName( 'table' );
56 58 if ( 0 === count( $dom_tables ) ) {
@@ -56,10 +58,10 @@
56 58 if ( 0 === count( $dom_tables ) ) {
57 59 return new WP_Error( 'table_import_html_dom_get_tables' );
58 60 }
59 61 libxml_clear_errors(); // Clear errors so that we only catch those inside the table in the next line.
60 - $table = simplexml_import_dom( $dom_tables->item( 0 ) );
61 - if ( false === $table ) {
62 + $table = simplexml_import_dom( $dom_tables->item( 0 ) ); // @phpstan-ignore argument.type
63 + if ( is_null( $table ) ) {
62 64 return new WP_Error( 'table_import_html_simplexml_import_dom_failed' );
63 65 }
64 66
65 67 $errors = libxml_get_errors();
@@ -64,19 +66,19 @@
64 66
65 67 $errors = libxml_get_errors();
66 68 libxml_clear_errors();
67 69 if ( ! empty( $errors ) ) {
68 - $output = '<strong>' . __( 'The imported file contains errors:', 'tablepress' ) . '</strong><br /><br />';
70 + $output = '<strong>' . __( 'The imported file contains errors:', 'tablepress' ) . '</strong><br><br>';
69 71 foreach ( $errors as $error ) {
70 72 switch ( $error->level ) {
71 73 case LIBXML_ERR_WARNING:
72 - $output .= "Warning {$error->code}: {$error->message} in line {$error->line}, column {$error->column}<br />";
74 + $output .= "Warning {$error->code}: {$error->message} in line {$error->line}, column {$error->column}<br>";
73 75 break;
74 76 case LIBXML_ERR_ERROR:
75 - $output .= "Error {$error->code}: {$error->message} in line {$error->line}, column {$error->column}<br />";
77 + $output .= "Error {$error->code}: {$error->message} in line {$error->line}, column {$error->column}<br>";
76 78 break;
77 79 case LIBXML_ERR_FATAL:
78 - $output .= "Fatal Error {$error->code}: {$error->message} in line {$error->line}, column {$error->column}<br />";
80 + $output .= "Fatal Error {$error->code}: {$error->message} in line {$error->line}, column {$error->column}<br>";
79 81 break;
80 82 }
81 83 }
82 84 wp_die( $output, 'Import Error', array( 'response' => 200, 'back_link' => true ) );
@@ -86,20 +88,22 @@
86 88 'data' => array(),
87 89 'options' => array(),
88 90 );
89 91 if ( isset( $table->thead ) ) {
90 - $html_table['data'] = array_merge( $html_table['data'], self::_import_html_rows( $table->thead[0]->tr ) );
91 - $html_table['options']['table_head'] = true;
92 + $head_rows = self::_import_html_rows( $table->thead[0]->tr ); // @phpstan-ignore property.nonObject
93 + $html_table['data'] = array_merge( $html_table['data'], $head_rows );
94 + $html_table['options']['table_head'] = count( $head_rows );
92 95 }
93 96 if ( isset( $table->tbody ) ) {
94 - $html_table['data'] = array_merge( $html_table['data'], self::_import_html_rows( $table->tbody[0]->tr ) );
97 + $html_table['data'] = array_merge( $html_table['data'], self::_import_html_rows( $table->tbody[0]->tr ) ); // @phpstan-ignore property.nonObject
95 98 }
96 99 if ( isset( $table->tr ) ) {
97 100 $html_table['data'] = array_merge( $html_table['data'], self::_import_html_rows( $table->tr ) );
98 101 }
99 102 if ( isset( $table->tfoot ) ) {
100 - $html_table['data'] = array_merge( $html_table['data'], self::_import_html_rows( $table->tfoot[0]->tr ) );
101 - $html_table['options']['table_foot'] = true;
103 + $foot_rows = self::_import_html_rows( $table->tfoot[0]->tr ); // @phpstan-ignore property.nonObject
104 + $html_table['data'] = array_merge( $html_table['data'], $foot_rows );
105 + $html_table['options']['table_foot'] = count( $foot_rows );
102 106 }
103 107
104 108 return $html_table;
105 109 }
@@ -109,11 +113,11 @@
109 113 *
110 114 * @since 2.0.0
111 115 *
112 116 * @param SimpleXMLElement $element XMLElement.
113 - * @return array SimpleXMLElement exported to an array.
117 + * @return array<int, array<int, string>> SimpleXMLElement exported to an array.
114 118 */
115 - protected static function _import_html_rows( $element ) {
119 + protected static function _import_html_rows( SimpleXMLElement $element ): array {
116 120 $rows = array(); // Container for the table data.
117 121 $rowspans = array(); // Container for information about rowspans in rows that follow the currently processed row.
118 122
119 123 $row_idx = 0;
@@ -118,9 +122,9 @@
118 122
119 123 $row_idx = 0;
120 124 foreach ( $element as $row ) {
121 125 // If all cells in a row should be merged with the cells in the row above, add the trigger word to each of them (should be very rare).
122 - while ( isset( $rowspans[ $row_idx ] ) && count( $rowspans[ $row_idx ] ) === count( $rows[ $row_idx - 1 ] ) ) {
126 + while ( isset( $rowspans[ $row_idx ] ) && count( $rowspans[ $row_idx ] ) === count( $rows[ $row_idx - 1 ] ) ) { // phpcs:ignore Squiz.PHP.DisallowSizeFunctionsInLoops.Found
123 127 $rows[] = $rowspans[ $row_idx ];
124 128 ++$row_idx;
125 129 }
126 130
@@ -132,15 +136,15 @@
132 136 $new_row[] = $rowspans[ $row_idx ][ $column_idx ];
133 137 ++$column_idx;
134 138 }
135 139
136 - $cell_xml = $cell->asXml();
140 + $cell_xml = $cell->asXML();
137 141
138 142 // Get content between <td>...</td>, or <th>...</th>, possibly with HTML.
139 - if ( 1 === preg_match( '#<t[d|h].*?>(.*)</t[d|h]>#is', $cell_xml, $matches ) ) {
143 + if ( false !== $cell_xml && 1 === preg_match( '#<t[d|h].*?>(.*)</t[d|h]>#is', $cell_xml, $matches ) ) {
140 144 /*
141 145 * Decode HTML entities again, as there might be some left especially in attributes of HTML tags in the cells,
142 - * see https://secure.php.net/manual/en/simplexmlelement.asxml.php#107137.
146 + * see https://www.php.net/manual/en/simplexmlelement.asxml.php#107137.
143 147 */
144 148 $new_row[] = html_entity_decode( $matches[1], ENT_NOQUOTES, 'UTF-8' );
145 149
146 150 // Search for colspan and rowspan attributes in the cell's HTML tag.
@@ -186,9 +190,9 @@
186 190 ++$row_idx;
187 191 }
188 192
189 193 // After the last data row: If all cells in a row should be merged with the cells in the row above, add the trigger word to each of them (should be very rare).
190 - while ( isset( $rowspans[ $row_idx ] ) && count( $rowspans[ $row_idx ] ) === count( $rows[ $row_idx - 1 ] ) ) {
194 + while ( isset( $rowspans[ $row_idx ] ) && count( $rowspans[ $row_idx ] ) === count( $rows[ $row_idx - 1 ] ) ) { // phpcs:ignore Squiz.PHP.DisallowSizeFunctionsInLoops.Found
191 195 $rows[] = $rowspans[ $row_idx ];
192 196 ++$row_idx;
193 197 }
194 198