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 | models/model-table.php +261 -183 2.0.4 → 3.4 View file →
@@ -7,8 +7,10 @@
7 7 * @author Tobias Bäthge
8 8 * @since 1.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 /**
@@ -24,38 +26,35 @@
24 26 /**
25 27 * Instance of the Post Type Model.
26 28 *
27 29 * @since 1.0.0
28 - * @var TablePress_Post_Model
29 30 */
30 - protected $model_post;
31 + protected \TablePress_Post_Model $model_post;
31 32
32 33 /**
33 34 * Name of the Post Meta Field for table options.
34 35 *
35 36 * @since 1.0.0
36 - * @var string
37 37 */
38 - protected $table_options_field_name = '_tablepress_table_options';
38 + protected string $table_options_field_name = '_tablepress_table_options';
39 39
40 40 /**
41 41 * Name of the Post Meta Field for table visibility.
42 42 *
43 43 * @since 1.0.0
44 - * @var string
45 44 */
46 - protected $table_visibility_field_name = '_tablepress_table_visibility';
45 + protected string $table_visibility_field_name = '_tablepress_table_visibility';
47 46
48 47 /**
49 48 * Default set of tables.
50 49 *
51 50 * @since 1.0.0
52 - * @var array $args {
53 - * @type int $last_id Last table ID that was given to a new table.
54 - * @type array $table_post Connections between table ID and post ID (key: table ID, value: post ID).
51 + * @var array{last_id: int, table_post: array<string, int>} {
52 + * @type int $last_id Last table ID that was given to a new table.
53 + * @type array<string, int> $table_post Connections between table ID and post ID (key: table ID, value: post ID).
55 54 * }
56 55 */
57 - protected $default_tables = array(
56 + protected array $default_tables = array(
58 57 'last_id' => 0,
59 58 'table_post' => array(),
60 59 );
61 60
@@ -62,11 +61,10 @@
62 61 /**
63 62 * Instance of WP_Option class for the list of tables.
64 63 *
65 64 * @since 1.0.0
66 - * @var TablePress_WP_Option
67 65 */
68 - protected $tables;
66 + protected \TablePress_WP_Option $tables;
69 67
70 68 /**
71 69 * Init the Table model by instantiating a Post model and loading the list of tables option.
72 70 *
@@ -87,11 +85,11 @@
87 85 * Get the tables option, which holds the connection between table ID and post ID.
88 86 *
89 87 * @since 1.0.0
90 88 *
91 - * @return array Current set of tables.
89 + * @return mixed[] Current set of tables.
92 90 */
93 - public function _debug_get_tables() {
91 + public function _debug_get_tables(): array {
94 92 return $this->tables->get();
95 93 }
96 94
97 95 /**
@@ -98,11 +96,11 @@
98 96 * Update the tables option, which holds the connection between table ID and post ID.
99 97 *
100 98 * @since 1.0.0
101 99 *
102 - * @param array $tables New set of tables.
100 + * @param mixed[] $tables New set of tables.
103 101 */
104 - public function _debug_update_tables( array $tables ) {
102 + public function _debug_update_tables( array $tables ): void {
105 103 $this->tables->update( $tables );
106 104 }
107 105
108 106 /**
@@ -109,16 +107,13 @@
109 107 * Convert a table to a post, which can be stored in the database.
110 108 *
111 109 * @since 1.0.0
112 110 *
113 - * @param array $table Table.
114 - * @param int $post_id Post ID of an existing table, or -1 for a new table.
115 - * @return array Post.
111 + * @param array<string, mixed> $table Table.
112 + * @param int $post_id Post ID of an existing table, or -1 for a new table.
113 + * @return array<string, mixed> Post.
116 114 */
117 - protected function _table_to_post( array $table, $post_id ) {
118 - // Run filters on content in each cell and other fields.
119 - $table = $this->filter_content( $table );
120 -
115 + protected function _table_to_post( array $table, int $post_id ): array {
121 116 // Sanitize each cell, table name, and table description, if the user is not allowed to work with unfiltered HTML.
122 117 if ( ! current_user_can( 'unfiltered_html' ) ) {
123 118 $table = $this->sanitize( $table );
124 119 }
@@ -146,16 +141,16 @@
146 141 *
147 142 * @param WP_Post $post Post.
148 143 * @param string $table_id Table ID.
149 144 * @param bool $load_data Whether the table data shall be loaded.
150 - * @return array Table.
145 + * @return array<string, mixed> Table.
151 146 */
152 - protected function _post_to_table( $post, $table_id, $load_data ) {
147 + protected function _post_to_table( WP_Post $post, string $table_id, bool $load_data ): array {
153 148 $table = array(
154 149 'id' => $table_id,
155 150 'name' => $post->post_title,
156 151 'description' => $post->post_excerpt,
157 - 'author' => $post->post_author,
152 + 'author' => (int) $post->post_author,
158 153 // 'created' => $post->post_date,
159 154 'last_modified' => $post->post_modified,
160 155 );
161 156
@@ -186,11 +181,11 @@
186 181 *
187 182 * @param string $table_id Table ID.
188 183 * @param bool $load_data Whether the table data shall be loaded.
189 184 * @param bool $load_options_visibility Whether the table options and table visibility shall be loaded.
190 - * @return array|WP_Error Table as an array on success, WP_Error on error.
185 + * @return array<string, mixed>|WP_Error Table as an array on success, WP_Error on error.
191 186 */
192 - public function load( $table_id, $load_data = true, $load_options_visibility = true ) {
187 + public function load( string $table_id, bool $load_data = true, bool $load_options_visibility = true ) /* : array|WP_Error */ {
193 188 if ( empty( $table_id ) ) {
194 189 return new WP_Error( 'table_load_empty_table_id' );
195 190 }
196 191
@@ -218,11 +213,11 @@
218 213 * @since 1.0.0
219 214 *
220 215 * @param bool $prime_meta_cache Optional. Whether the prime the post meta cache when loading the posts.
221 216 * @param bool $run_filter Optional. Whether to run a filter on the list of table IDs.
222 - * @return array Array of table IDs.
217 + * @return string[] Array of table IDs.
223 218 */
224 - public function load_all( $prime_meta_cache = true, $run_filter = true ) {
219 + public function load_all( bool $prime_meta_cache = true, bool $run_filter = true ): array {
225 220 $table_post = $this->tables->get( 'table_post' );
226 221 if ( empty( $table_post ) ) {
227 222 return array();
228 223 }
@@ -232,11 +227,13 @@
232 227
233 228 // This loop now uses the WP cache.
234 229 $table_ids = array();
235 230 foreach ( $table_post as $table_id => $post_id ) {
236 - $table_id = (string) $table_id;
231 + $table_id = (string) $table_id; // Ensure that the table ID is a string, as it comes from an array key where numeric strings are converted to integers.
232 +
237 233 // Load table without data and options to save memory.
238 234 $table = $this->load( $table_id, false, false );
235 +
239 236 // Skip tables that could not be loaded properly.
240 237 if ( ! is_wp_error( $table ) ) {
241 238 $table_ids[] = $table_id;
242 239 }
@@ -247,9 +244,9 @@
247 244 * Filters all table IDs that are loaded.
248 245 *
249 246 * @since 1.4.0
250 247 *
251 - * @param array $table_ids The table IDs that are loaded.
248 + * @param string[] $table_ids The table IDs that are loaded.
252 249 */
253 250 $table_ids = apply_filters( 'tablepress_load_all_tables', $table_ids );
254 251 }
255 252
@@ -260,12 +257,12 @@
260 257 * Sanitize the table to remove undesired HTML code using KSES.
261 258 *
262 259 * @since 1.8.0
263 260 *
264 - * @param array $table Table.
265 - * @return array Sanitized table.
261 + * @param array<string, mixed> $table Table.
262 + * @return array<string, mixed> Sanitized table.
266 263 */
267 - public function sanitize( array $table ) {
264 + public function sanitize( array $table ): array {
268 265 // Sanitize the table name and description.
269 266 $fields = array( 'name', 'description' );
270 267 foreach ( $fields as $field ) {
271 268 $table[ $field ] = wp_kses_post( $table[ $field ] );
@@ -273,9 +270,9 @@
273 270
274 271 // Sanitize each cell.
275 272 foreach ( $table['data'] as $row_idx => $row ) {
276 273 foreach ( $row as $column_idx => $cell_content ) {
277 - $table['data'][ $row_idx ][ $column_idx ] = wp_kses_post( $cell_content ); // Equals wp_filter_post_kses(), but without the unncessary slashes handling.
274 + $table['data'][ $row_idx ][ $column_idx ] = wp_kses_post( $cell_content ); // Equals wp_filter_post_kses(), but without the unnecessary slashes handling.
278 275 }
279 276 }
280 277
281 278 return $table;
@@ -281,59 +278,29 @@
281 278 return $table;
282 279 }
283 280
284 281 /**
285 - * Filter/modify the content of table cells and other fields, e.g. for security hardening.
286 - *
287 - * This is similar to the `sanitize()` method, but executed for all users.
288 - * In 1.10.0, adding `rel="noopener noreferrer"` to all HTML link elements like `<a target=` was added. See https://core.trac.wordpress.org/ticket/43187.
289 - * Since 1.13.0, and on WP 5.6, only `rel="noopener"` is added. See https://core.trac.wordpress.org/ticket/49558.
290 - *
291 - * @since 1.10.0
292 - *
293 - * @param array $table Table.
294 - * @return array Filtered/modified table.
295 - */
296 - public function filter_content( array $table ) {
297 - /**
298 - * Filters whether the contents of table cells and fields should be filtered/modified.
299 - *
300 - * @since 1.10.0
301 - *
302 - * @param bool $filter Whether to filter the content of table cells and other fields. Default true.
303 - */
304 - if ( ! apply_filters( 'tablepress_filter_table_cell_content', true ) ) {
305 - return $table;
306 - }
307 -
308 - // Filter the table name and description.
309 - $fields = array( 'name', 'description' );
310 - foreach ( $fields as $field ) {
311 - $table[ $field ] = wp_targeted_link_rel( $table[ $field ] );
312 - }
313 -
314 - foreach ( $table['data'] as $row_idx => $row ) {
315 - foreach ( $row as $column_idx => $cell_content ) {
316 - $table['data'][ $row_idx ][ $column_idx ] = wp_targeted_link_rel( $cell_content );
317 - }
318 - }
319 -
320 - return $table;
321 - }
322 -
323 - /**
324 282 * Save a table.
325 283 *
326 284 * @since 1.0.0
327 285 *
328 - * @param array $table Table (needs to have $table['id']!).
286 + * @param array<string, mixed> $table Table (needs to have $table['id']!).
329 287 * @return string|WP_Error WP_Error on error, string table ID on success.
330 288 */
331 - public function save( array $table ) {
289 + public function save( array $table ) /* : string|WP_Error */ {
332 290 if ( empty( $table['id'] ) ) {
333 291 return new WP_Error( 'table_save_empty_table_id' );
334 292 }
335 293
294 + /**
295 + * Fires before a table is saved.
296 + *
297 + * @since 3.1.0
298 + *
299 + * @param string $table_id ID of the table to be saved.
300 + */
301 + do_action( 'tablepress_event_pre_save_table', $table['id'] );
302 +
336 303 $post_id = $this->_get_post_id( $table['id'] );
337 304 if ( false === $post_id ) {
338 305 return new WP_Error( 'table_save_no_post_id_for_table_id', '', $table['id'] );
339 306 }
@@ -340,11 +307,11 @@
340 307
341 308 $post = $this->_table_to_post( $table, $post_id );
342 309 $new_post_id = $this->model_post->update( $post );
343 310 if ( is_wp_error( $new_post_id ) ) {
344 - // Add an error code to the existing WP_Error.
345 - $new_post_id->add( 'table_save_post_update', '', $post_id );
346 - return $new_post_id;
311 + $error = new WP_Error( 'table_save_post_update', '', $post_id );
312 + $error->merge_from( $new_post_id );
313 + return $error;
347 314 }
348 315 if ( $post_id !== $new_post_id ) {
349 316 return new WP_Error( 'table_save_new_post_id_does_not_match', '', $new_post_id );
350 317 }
@@ -370,9 +337,9 @@
370 337 * Fires after a table has been saved.
371 338 *
372 339 * @since 1.5.0
373 340 *
374 - * @param string $table_id ID of the added table.
341 + * @param string $table_id ID of the saved table.
375 342 */
376 343 do_action( 'tablepress_event_saved_table', $table['id'] );
377 344
378 345 return $table['id'];
@@ -382,20 +349,20 @@
382 349 * Add a new table.
383 350 *
384 351 * @since 1.0.0
385 352 *
386 - * @param array $table Table ($table['id'] is not necessary).
387 - * @param string $copy_or_add Optional. 'copy' if the table is copied, 'add' if it is a new table. Default 'add'.
353 + * @param array<string, mixed> $table Table ($table['id'] is not necessary).
354 + * @param string $copy_or_add Optional. 'copy' if the table is copied, 'add' if it is a new table. Default 'add'.
388 355 * @return string|WP_Error WP_Error on error, string table ID of the new table on success.
389 356 */
390 - public function add( array $table, $copy_or_add = 'add' ) {
357 + public function add( array $table, string $copy_or_add = 'add' ) /* : string|WP_Error */ {
391 358 $post_id = -1; // To insert table.
392 359 $post = $this->_table_to_post( $table, $post_id );
393 360 $new_post_id = $this->model_post->insert( $post );
394 361 if ( is_wp_error( $new_post_id ) ) {
395 - // Add an error code to the existing WP_Error.
396 - $new_post_id->add( 'table_add_post_insert', '' );
397 - return $new_post_id;
362 + $error = new WP_Error( 'table_add_post_insert', '' );
363 + $error->merge_from( $new_post_id );
364 + return $error;
398 365 }
399 366
400 367 $options_saved = $this->_add_table_options( $new_post_id, $table['options'] );
401 368 if ( ! $options_saved ) {
@@ -432,14 +399,14 @@
432 399 *
433 400 * @param string $table_id ID of the table to be copied.
434 401 * @return string|WP_Error WP_Error on error, string table ID of the new table on success.
435 402 */
436 - public function copy( $table_id ) {
403 + public function copy( string $table_id ) /* : string|WP_Error */ {
437 404 $table = $this->load( $table_id, true, true );
438 405 if ( is_wp_error( $table ) ) {
439 - // Add an error code to the existing WP_Error.
440 - $table->add( 'table_copy_table_load', '', $table_id );
441 - return $table;
406 + $error = new WP_Error( 'table_copy_table_load', '', $table_id );
407 + $error->merge_from( $table );
408 + return $error;
442 409 }
443 410
444 411 // Adjust name of copied table.
445 412 if ( '' === trim( $table['name'] ) ) {
@@ -449,19 +416,19 @@
449 416
450 417 // Merge this data into an empty table template.
451 418 $table = $this->prepare_table( $this->get_table_template(), $table, false );
452 419 if ( is_wp_error( $table ) ) {
453 - // Add an error code to the existing WP_Error.
454 - $table->add( 'table_copy_table_prepare', '', $table_id );
455 - return $table;
420 + $error = new WP_Error( 'table_copy_table_prepare', '', $table_id );
421 + $error->merge_from( $table );
422 + return $error;
456 423 }
457 424
458 425 // Add the copied table.
459 426 $new_table_id = $this->add( $table, 'copy' );
460 427 if ( is_wp_error( $new_table_id ) ) {
461 - // Add an error code to the existing WP_Error.
462 - $new_table_id->add( 'table_copy_table_add', '', $table_id );
463 - return $new_table_id;
428 + $error = new WP_Error( 'table_copy_table_add', '', $table_id );
429 + $error->merge_from( $new_table_id );
430 + return $error;
464 431 }
465 432
466 433 /**
467 434 * Fires after an existing table has been copied.
@@ -483,14 +450,25 @@
483 450 *
484 451 * @param string $table_id ID of the table to be deleted.
485 452 * @return bool|WP_Error WP_Error on error, true on success.
486 453 */
487 - public function delete( $table_id ) {
454 + public function delete( string $table_id ) /* : true|WP_Error */ {
488 455 if ( ! $this->table_exists( $table_id ) ) {
489 456 return new WP_Error( 'table_delete_table_does_not_exist', '', $table_id );
490 457 }
491 458
459 + /**
460 + * Fires before a table is deleted.
461 + *
462 + * @since 3.1.0
463 + *
464 + * @param string $table_id ID of the table to be deleted.
465 + */
466 + do_action( 'tablepress_event_pre_delete_table', $table_id );
467 +
492 468 $post_id = $this->_get_post_id( $table_id ); // No ! false check necessary, as this is covered by table_exists() check above.
469 +
470 + // @phpstan-ignore argument.type
493 471 $deleted = $this->model_post->delete( $post_id ); // Post Meta fields will be deleted automatically by that function.
494 472 if ( false === $deleted ) {
495 473 return new WP_Error( 'table_delete_post_could_not_be_deleted', '', $post_id );
496 474 }
@@ -519,9 +497,9 @@
519 497 * Delete all tables.
520 498 *
521 499 * @since 1.0.0
522 500 */
523 - public function delete_all() {
501 + public function delete_all(): void {
524 502 $tables = $this->tables->get();
525 503 if ( empty( $tables['table_post'] ) ) {
526 504 return;
527 505 }
@@ -526,11 +504,13 @@
526 504 return;
527 505 }
528 506
529 507 foreach ( $tables['table_post'] as $table_id => $post_id ) {
530 - $table_id = (string) $table_id;
508 + $table_id = (string) $table_id; // Ensure that the table ID is a string, as it comes from an array key where numeric strings are converted to integers.
509 +
531 510 $this->model_post->delete( $post_id ); // Post Meta fields will be deleted automatically by that function.
532 511 unset( $tables['table_post'][ $table_id ] );
512 +
533 513 // Invalidate table output caches that belong to this table.
534 514 $this->invalidate_table_output_cache( $table_id );
535 515 }
536 516
@@ -553,9 +533,9 @@
553 533 *
554 534 * @param string $table_id Table ID.
555 535 * @return bool Whether the table ID exists.
556 536 */
557 - public function table_exists( $table_id ) {
537 + public function table_exists( string $table_id ): bool {
558 538 $table_post = $this->tables->get( 'table_post' );
559 539 return isset( $table_post[ $table_id ] );
560 540 }
561 541
@@ -564,11 +544,11 @@
564 544 *
565 545 * @since 1.0.0
566 546 *
567 547 * @param bool $single_value Optional. Whether to return just the number of tables from the list, or also count in the database.
568 - * @return int|array Number of Tables (if $single_value), or array of Numbers from list/DB (if ! $single_value).
548 + * @return int|array{list: int, db: int} Number of Tables (if $single_value), or array of Numbers from list/DB (if ! $single_value).
569 549 */
570 - public function count_tables( $single_value = true ) {
550 + public function count_tables( bool $single_value = true ) /* : int|array */ {
571 551 $count_list = count( $this->tables->get( 'table_post' ) );
572 552 if ( $single_value ) {
573 553 return $count_list;
574 554 }
@@ -587,9 +567,9 @@
587 567 * @since 1.8.0 Renamed from _invalidate_table_output_cache to invalidate_table_output_cache and made public.
588 568 *
589 569 * @param string $table_id Table ID.
590 570 */
591 - public function invalidate_table_output_cache( $table_id ) {
571 + public function invalidate_table_output_cache( string $table_id ): void {
592 572 $caches_list_transient_name = 'tablepress_c_' . md5( $table_id );
593 573 $caches_list = get_transient( $caches_list_transient_name );
594 574 if ( false !== $caches_list ) {
595 575 $caches_list = (array) json_decode( $caches_list, true );
@@ -600,13 +580,13 @@
600 580 delete_transient( $caches_list_transient_name );
601 581 }
602 582
603 583 /**
604 - * Flush the caches of the plugins W3 Total Cache, WP Super Cache, Cachify, and Quick Cache.
584 + * Flush the caches of common caching plugins.
605 585 *
606 586 * @since 1.0.0
607 587 */
608 - public function _flush_caching_plugins_caches() {
588 + public function _flush_caching_plugins_caches(): void {
609 589 /**
610 590 * Filters whether the caches of common caching plugins shall be flushed.
611 591 *
612 592 * @since 1.0.0
@@ -648,15 +628,22 @@
648 628 foreach ( $cache_flush_hooks as $cache_flush_hook ) {
649 629 do_action( $cache_flush_hook );
650 630 }
651 631
632 + // Cloudflare APO.
633 + if ( class_exists( '\Cloudflare\APO\WordPress\Hooks' ) ) {
634 + $_cloudflare = new \Cloudflare\APO\WordPress\Hooks();
635 + if ( is_callable( array( $_cloudflare, 'purgeCacheEverything' ) ) ) {
636 + $_cloudflare->purgeCacheEverything();
637 + }
638 + }
652 639 // Kinsta.
653 640 if ( isset( $GLOBALS['kinsta_cache'] ) && ! empty( $GLOBALS['kinsta_cache']->kinsta_cache_purge ) && is_callable( array( $GLOBALS['kinsta_cache']->kinsta_cache_purge, 'purge_complete_caches' ) ) ) {
654 - $GLOBALS['kinsta_cache']->kinsta_cache_purge->purge_complete_caches();
641 + $GLOBALS['kinsta_cache']->kinsta_cache_purge->purge_complete_caches(); // @phpstan-ignore method.nonObject
655 642 }
656 643 // LiteSpeed Cache.
657 644 if ( is_callable( array( 'LiteSpeed_Cache_Tags', 'add_purge_tag' ) ) ) {
658 - LiteSpeed_Cache_Tags::add_purge_tag( '*' );
645 + LiteSpeed_Cache_Tags::add_purge_tag( '*' ); // @phpstan-ignore class.notFound
659 646 }
660 647 // Pagely.
661 648 if ( class_exists( 'PagelyCachePurge' ) ) {
662 649 $_pagely = new PagelyCachePurge();
@@ -663,25 +650,25 @@
663 650 if ( is_callable( array( $_pagely, 'purgeAll' ) ) ) {
664 651 $_pagely->purgeAll();
665 652 }
666 653 }
667 - // Pressidum.
654 + // Pressidium.
668 655 if ( is_callable( array( 'Ninukis_Plugin', 'get_instance' ) ) ) {
669 - $_pressidum = Ninukis_Plugin::get_instance();
656 + $_pressidum = Ninukis_Plugin::get_instance(); // @phpstan-ignore class.notFound
670 657 if ( is_callable( array( $_pressidum, 'purgeAllCaches' ) ) ) {
671 - $_pressidum->purgeAllCaches();
658 + $_pressidum->purgeAllCaches(); // @phpstan-ignore method.nonObject
672 659 }
673 660 }
674 661 // Savvii.
675 662 if ( defined( '\Savvii\CacheFlusherPlugin::NAME_DOMAINFLUSH_NOW' ) ) {
676 - $_savvii = new \Savvii\CacheFlusherPlugin();
663 + $_savvii = new \Savvii\CacheFlusherPlugin(); // @phpstan-ignore class.notFound
677 664 if ( is_callable( array( $_savvii, 'domainflush' ) ) ) {
678 - $_savvii->domainflush();
665 + $_savvii->domainflush(); // @phpstan-ignore class.notFound
679 666 }
680 667 }
681 668 // WP Fastest Cache.
682 - if ( isset( $GLOBALS['wp_fastest_cache'] ) && is_callable( $GLOBALS['wp_fastest_cache'], 'deleteCache' ) ) {
683 - $GLOBALS['wp_fastest_cache']->deleteCache();
669 + if ( isset( $GLOBALS['wp_fastest_cache'] ) && is_callable( array( $GLOBALS['wp_fastest_cache'], 'deleteCache' ) ) ) {
670 + $GLOBALS['wp_fastest_cache']->deleteCache( true ); // @phpstan-ignore method.nonObject
684 671 }
685 672 // WP-Optimize.
686 673 if ( function_exists( 'WP_Optimize' ) ) {
687 674 WP_Optimize()->get_page_cache()->purge();
@@ -695,9 +682,9 @@
695 682 *
696 683 * @param string $table_id Table ID.
697 684 * @return int|false Post ID on success, false on error.
698 685 */
699 - protected function _get_post_id( $table_id ) {
686 + protected function _get_post_id( string $table_id ) /* : int|false */ {
700 687 $table_post = $this->tables->get( 'table_post' );
701 688 if ( ! isset( $table_post[ $table_id ] ) ) {
702 689 return false;
703 690 }
@@ -711,9 +698,9 @@
711 698 *
712 699 * @param string $table_id Table ID.
713 700 * @param int $post_id Post ID.
714 701 */
715 - protected function _update_post_id( $table_id, $post_id ) {
702 + protected function _update_post_id( string $table_id, int $post_id ): void {
716 703 $tables = $this->tables->get();
717 704 $tables['table_post'][ $table_id ] = $post_id;
718 705 uksort( $tables['table_post'], 'strnatcasecmp' );
719 706 $this->tables->update( $tables );
@@ -725,9 +712,9 @@
725 712 * @since 1.0.0
726 713 *
727 714 * @param string $table_id Table ID.
728 715 */
729 - protected function _remove_post_id( $table_id ) {
716 + protected function _remove_post_id( string $table_id ): void {
730 717 $tables = $this->tables->get();
731 718 unset( $tables['table_post'][ $table_id ] );
732 719 $this->tables->update( $tables );
733 720 }
@@ -740,9 +727,9 @@
740 727 * @param string $old_id Old table ID.
741 728 * @param string $new_id New table ID.
742 729 * @return bool|WP_Error True on success, WP_Error on error.
743 730 */
744 - public function change_table_id( $old_id, $new_id ) {
731 + public function change_table_id( string $old_id, string $new_id ) /* : true|WP_Error */ {
745 732 $post_id = $this->_get_post_id( $old_id );
746 733 if ( false === $post_id ) {
747 734 return new WP_Error( 'table_change_id_no_post_id_for_table_id', '', $old_id );
748 735 }
@@ -778,9 +765,9 @@
778 765 * @since 1.0.0
779 766 *
780 767 * @return string Unused table ID (e.g. for a new table).
781 768 */
782 - protected function _get_new_table_id() {
769 + protected function _get_new_table_id(): string {
783 770 $tables = $this->tables->get();
784 771 // Need to check new ID candidate in a loop, because a higher ID might already be in use, if a table ID was changed manually.
785 772 do {
786 773 ++$tables['last_id'];
@@ -796,11 +783,11 @@
796 783 * Important: This scheme is versioned via TablePress::table_scheme_version; changes likely need a version update!
797 784 *
798 785 * @since 1.0.0
799 786 *
800 - * @return array Empty table.
787 + * @return array<string, mixed> Empty table.
801 788 */
802 - public function get_table_template() {
789 + public function get_table_template(): array {
803 790 // Attention: Array keys have to be lowercase, to make it possible to match them with Shortcode attributes!
804 791 $table = array(
805 792 'id' => false,
806 793 'name' => '',
@@ -809,10 +796,10 @@
809 796 'last_modified' => wp_date( 'Y-m-d H:i:s' ),
810 797 'author' => get_current_user_id(),
811 798 'options' => array(
812 799 'last_editor' => get_current_user_id(),
813 - 'table_head' => true,
814 - 'table_foot' => false,
800 + 'table_head' => 1,
801 + 'table_foot' => 0,
815 802 'alternating_row_colors' => true,
816 803 'row_hover' => true,
817 804 'print_name' => false,
818 805 'print_name_position' => 'above',
@@ -830,9 +817,9 @@
830 817 'datatables_scrollx' => false,
831 818 'datatables_custom_commands' => '',
832 819 ),
833 820 'visibility' => array(
834 - 'rows' => array( 1 ), // One visbile row.
821 + 'rows' => array( 1 ), // One visible row.
835 822 'columns' => array( 1 ), // One visible column.
836 823 ),
837 824 );
838 825 /**
@@ -839,9 +826,9 @@
839 826 * Filters the default template/structure of an empty table.
840 827 *
841 828 * @since 1.0.0
842 829 *
843 - * @param array $table Default template/structure of an empty table.
830 + * @param array<string, mixed> $table Default template/structure of an empty table.
844 831 */
845 832 return apply_filters( 'tablepress_table_template', $table );
846 833 }
847 834
@@ -851,14 +838,14 @@
851 838 * Performs consistency checks on data and visibility settings.
852 839 *
853 840 * @since 1.0.0
854 841 *
855 - * @param array $table Table to merge into.
856 - * @param array $new_table Table to merge.
857 - * @param bool $table_size_check Optional. Whether to check the number of rows and columns (e.g. not necessary for added or copied tables).
858 - * @return array|WP_Error Merged table on success, WP_Error on error.
842 + * @param array<string, mixed> $table Table to merge into.
843 + * @param array<string, mixed> $new_table Table to merge.
844 + * @param bool $table_size_check Optional. Whether to check the number of rows and columns (e.g. not necessary for added or copied tables).
845 + * @return array<string, mixed>|WP_Error Merged table on success, WP_Error on error.
859 846 */
860 - public function prepare_table( array $table, array $new_table, $table_size_check = true ) {
847 + public function prepare_table( array $table, array $new_table, bool $table_size_check = true ) /* : array|WP_Error */ {
861 848 // Table ID must be the same (if there was an ID already).
862 849 if ( false !== $table['id'] && $table['id'] !== $new_table['id'] ) {
863 850 return new WP_Error( 'table_prepare_no_id_match', '', $new_table['id'] );
864 851 }
@@ -899,9 +886,9 @@
899 886
900 887 // All checks were successful, replace original values with new ones.
901 888
902 889 // $table['id'] is either false (and remains false) or already equal to $new_table['id'].
903 - $table['new_id'] = isset( $new_table['new_id'] ) ? $new_table['new_id'] : $table['id'];
890 + $table['new_id'] = $new_table['new_id'] ?? $table['id'];
904 891 $table['name'] = $new_table['name'];
905 892 $table['description'] = $new_table['description'];
906 893 $table['data'] = $new_table['data'];
907 894 // Make sure that cells are stored as strings.
@@ -906,16 +893,12 @@
906 893 $table['data'] = $new_table['data'];
907 894 // Make sure that cells are stored as strings.
908 895 array_walk_recursive(
909 896 $table['data'],
910 - static function( &$cell_content, $col_idx ) {
897 + static function ( /* string|int|float|bool|null */ &$cell_content, int $col_idx ): void {
911 898 $cell_content = (string) $cell_content;
912 - }
899 + },
913 900 );
914 - // $table['author'] = get_current_user_id(); // We don't want this, as it would override the original author.
915 - // $table['created'] = wp_date( 'Y-m-d H:i:s' ); // We don't want this, as it would override the original datetime.
916 - $table['last_modified'] = wp_date( 'Y-m-d H:i:s' );
917 - $table['options']['last_editor'] = get_current_user_id();
918 901 // Table Options.
919 902 if ( isset( $new_table['options'] ) ) { // Options are for example not set for newly added tables.
920 903 // Specials check for certain options.
921 904 if ( isset( $new_table['options']['extra_css_classes'] ) ) {
@@ -929,8 +912,17 @@
929 912 if ( $new_table['options']['datatables_paginate_entries'] < 1 ) {
930 913 $new_table['options']['datatables_paginate_entries'] = 10; // Default value.
931 914 }
932 915 }
916 +
917 + // Backward compatibility: Convert boolean or numeric string "table_head" and "table_foot" options to integer.
918 + if ( isset( $new_table['options']['table_head'] ) ) {
919 + $new_table['options']['table_head'] = absint( $new_table['options']['table_head'] );
920 + }
921 + if ( isset( $new_table['options']['table_foot'] ) ) {
922 + $new_table['options']['table_foot'] = absint( $new_table['options']['table_foot'] );
923 + }
924 +
933 925 // Merge new options.
934 926 $default_table = $this->get_table_template();
935 927 $table['options'] = array_intersect_key( $table['options'], $default_table['options'] );
936 928 $new_table['options'] = array_intersect_key( $new_table['options'], $default_table['options'] );
@@ -939,8 +931,23 @@
939 931 // Table Visibility.
940 932 $table['visibility']['rows'] = $new_table['visibility']['rows'];
941 933 $table['visibility']['columns'] = $new_table['visibility']['columns'];
942 934
935 + // $table['author'] = get_current_user_id(); // We don't want this, as it would override the original author.
936 + // $table['created'] = wp_date( 'Y-m-d H:i:s' ); // We don't want this, as it would override the original datetime.
937 + $table['last_modified'] = wp_date( 'Y-m-d H:i:s' );
938 + $table['options']['last_editor'] = get_current_user_id();
939 +
940 + // Prevent issues if the "Custom Commands" field is not set, e.g. when non-admins have previously edited the table.
941 + if ( ! isset( $table['options']['datatables_custom_commands'] ) ) {
942 + $table['options']['datatables_custom_commands'] = '';
943 + }
944 +
945 + // Convert CSS classes and some DataTables 1.x parameters to the DataTables 2 variants.
946 + if ( '' !== $table['options']['datatables_custom_commands'] ) {
947 + $table['options']['datatables_custom_commands'] = TablePress::convert_datatables_api_data( $table['options']['datatables_custom_commands'] );
948 + }
949 +
943 950 return $table;
944 951 }
945 952
946 953 /**
@@ -947,15 +954,15 @@
947 954 * Save the table options of a table (in a post meta field of the table's post).
948 955 *
949 956 * @since 1.0.0
950 957 *
951 - * @param int $post_id Post ID.
952 - * @param array $options Table options.
958 + * @param int $post_id Post ID.
959 + * @param array<string, mixed> $options Table options.
953 960 * @return bool True on success, false on error.
954 961 */
955 - protected function _add_table_options( $post_id, array $options ) {
962 + protected function _add_table_options( int $post_id, array $options ): bool {
956 963 $options = wp_json_encode( $options, TABLEPRESS_JSON_OPTIONS );
957 - return $this->model_post->add_meta_field( $post_id, $this->table_options_field_name, $options );
964 + return $this->model_post->add_meta_field( $post_id, $this->table_options_field_name, $options ); // @phpstan-ignore argument.type
958 965 }
959 966
960 967 /**
961 968 * Update the table options of a table (in a post meta field in the table's post).
@@ -961,15 +968,15 @@
961 968 * Update the table options of a table (in a post meta field in the table's post).
962 969 *
963 970 * @since 1.0.0
964 971 *
965 - * @param int $post_id Post ID.
966 - * @param array $options Table options.
972 + * @param int $post_id Post ID.
973 + * @param array<string, mixed> $options Table options.
967 974 * @return bool True on success, false on error.
968 975 */
969 - protected function _update_table_options( $post_id, array $options ) {
976 + protected function _update_table_options( int $post_id, array $options ): bool {
970 977 $options = wp_json_encode( $options, TABLEPRESS_JSON_OPTIONS );
971 - return $this->model_post->update_meta_field( $post_id, $this->table_options_field_name, $options );
978 + return $this->model_post->update_meta_field( $post_id, $this->table_options_field_name, $options ); // @phpstan-ignore argument.type
972 979 }
973 980
974 981 /**
975 982 * Get the table options of a table (from a post meta field of the table's post).
@@ -976,16 +983,22 @@
976 983 *
977 984 * @since 1.0.0
978 985 *
979 986 * @param int $post_id Post ID.
980 - * @return array Table options on success, empty array on error.
987 + * @return array<string, mixed> Table options on success, empty array on error.
981 988 */
982 - protected function _get_table_options( $post_id ) {
989 + protected function _get_table_options( int $post_id ): array {
983 990 $options = $this->model_post->get_meta_field( $post_id, $this->table_options_field_name );
984 991 if ( empty( $options ) ) {
985 992 return array();
986 993 }
987 - return (array) json_decode( $options, true );
994 + $options = (array) json_decode( $options, true );
995 +
996 + // Backward compatibility: Convert boolean "table_head" and "table_foot" options to integer.
997 + $options['table_head'] = absint( $options['table_head'] );
998 + $options['table_foot'] = absint( $options['table_foot'] );
999 +
1000 + return $options;
988 1001 }
989 1002
990 1003 /**
991 1004 * Save the table visibility of a table (in a post meta field of the table's post).
@@ -991,15 +1004,15 @@
991 1004 * Save the table visibility of a table (in a post meta field of the table's post).
992 1005 *
993 1006 * @since 1.0.0
994 1007 *
995 - * @param int $post_id Post ID.
996 - * @param array $visibility Table visibility.
1008 + * @param int $post_id Post ID.
1009 + * @param array{rows: int[], columns: int[]} $visibility Table visibility.
997 1010 * @return bool True on success, false on error.
998 1011 */
999 - protected function _add_table_visibility( $post_id, array $visibility ) {
1012 + protected function _add_table_visibility( int $post_id, array $visibility ): bool {
1000 1013 $visibility = wp_json_encode( $visibility, TABLEPRESS_JSON_OPTIONS );
1001 - return $this->model_post->add_meta_field( $post_id, $this->table_visibility_field_name, $visibility );
1014 + return $this->model_post->add_meta_field( $post_id, $this->table_visibility_field_name, $visibility ); // @phpstan-ignore argument.type
1002 1015 }
1003 1016
1004 1017 /**
1005 1018 * Update the table visibility of a table (in a post meta field in the table's post).
@@ -1005,15 +1018,15 @@
1005 1018 * Update the table visibility of a table (in a post meta field in the table's post).
1006 1019 *
1007 1020 * @since 1.0.0
1008 1021 *
1009 - * @param int $post_id Post ID.
1010 - * @param array $visibility Table visibility.
1022 + * @param int $post_id Post ID.
1023 + * @param array{rows: int[], columns: int[]} $visibility Table visibility.
1011 1024 * @return bool True on success, false on error.
1012 1025 */
1013 - protected function _update_table_visibility( $post_id, array $visibility ) {
1026 + protected function _update_table_visibility( int $post_id, array $visibility ): bool {
1014 1027 $visibility = wp_json_encode( $visibility, TABLEPRESS_JSON_OPTIONS );
1015 - return $this->model_post->update_meta_field( $post_id, $this->table_visibility_field_name, $visibility );
1028 + return $this->model_post->update_meta_field( $post_id, $this->table_visibility_field_name, $visibility ); // @phpstan-ignore argument.type
1016 1029 }
1017 1030
1018 1031 /**
1019 1032 * Get the table visibility of a table (from a post meta field of the table's post).
@@ -1020,14 +1033,17 @@
1020 1033 *
1021 1034 * @since 1.0.0
1022 1035 *
1023 1036 * @param int $post_id Post ID.
1024 - * @return array Table visibility on success, empty array on error.
1037 + * @return array{rows: int[], columns: int[]} Table visibility on success, empty array on error.
1025 1038 */
1026 - protected function _get_table_visibility( $post_id ) {
1039 + protected function _get_table_visibility( int $post_id ): array {
1027 1040 $visibility = $this->model_post->get_meta_field( $post_id, $this->table_visibility_field_name );
1028 1041 if ( empty( $visibility ) ) {
1029 - return array();
1042 + return array(
1043 + 'rows' => array(),
1044 + 'columns' => array(),
1045 + );
1030 1046 }
1031 1047 return json_decode( $visibility, true );
1032 1048 }
1033 1049
@@ -1040,9 +1056,9 @@
1040 1056 * @since 2.0.0 Add optional $remove_old_options parameter.
1041 1057 *
1042 1058 * @param bool $remove_old_options Optional. Whether old table options should be removed from the database. Default true.
1043 1059 */
1044 - public function merge_table_options_defaults( $remove_old_options = true ) {
1060 + public function merge_table_options_defaults( bool $remove_old_options = true ): void {
1045 1061 $table_post = $this->tables->get( 'table_post' );
1046 1062 if ( empty( $table_post ) ) {
1047 1063 return;
1048 1064 }
@@ -1053,10 +1069,23 @@
1053 1069 // Get default Table with default Table Options.
1054 1070 $default_table = $this->get_table_template();
1055 1071
1056 1072 // Go through all tables (this loop now uses the WP cache).
1057 - foreach ( $table_post as $table_id => $post_id ) {
1073 + foreach ( $table_post as $post_id ) {
1058 1074 $table_options = $this->_get_table_options( $post_id );
1075 +
1076 + /**
1077 + * Filters the Table Options before they are merged with the default Table Options.
1078 + *
1079 + * @since 3.0.0
1080 + *
1081 + * @param array<string, mixed> $table_options Table Options.
1082 + * @param array<string, mixed> $default_table_options Default Table Options.
1083 + * @param bool $remove_old_options Whether old table options should be removed from the database.
1084 + * @param int $post_id Post ID of the table.
1085 + */
1086 + $table_options = apply_filters( 'tablepress_table_options_before_merge', $table_options, $default_table['options'], $remove_old_options, $post_id );
1087 +
1059 1088 if ( $remove_old_options ) {
1060 1089 // Remove old (i.e. no longer existing) Table Options.
1061 1090 $table_options = array_intersect_key( $table_options, $default_table['options'] );
1062 1091 }
@@ -1066,13 +1095,53 @@
1066 1095 }
1067 1096 }
1068 1097
1069 1098 /**
1099 + * Updates all tables' "Custom Commands" to use DataTables 2 variants instead of old DataTables 1.x CSS classes and parameters
1100 + *
1101 + * @since 3.0.0
1102 + */
1103 + public function update_custom_commands_datatables_tp30(): void {
1104 + $table_post = $this->tables->get( 'table_post' );
1105 + if ( empty( $table_post ) ) {
1106 + return;
1107 + }
1108 +
1109 + // Prime the meta cache with the table options of all tables.
1110 + update_meta_cache( 'post', array_values( $table_post ) );
1111 +
1112 + foreach ( $table_post as $table_id => $post_id ) {
1113 + $table_options = $this->_get_table_options( $post_id );
1114 +
1115 + // Fix tables where the "Custom Commands" entry is missing entirely.
1116 + if ( ! isset( $table_options['datatables_custom_commands'] ) ) {
1117 + $table_options['datatables_custom_commands'] = '';
1118 + $this->_update_table_options( $post_id, $table_options );
1119 + continue;
1120 + }
1121 +
1122 + // Nothing to do if there are no "Custom Commands".
1123 + if ( '' === $table_options['datatables_custom_commands'] ) {
1124 + continue;
1125 + }
1126 + // Run search/replace.
1127 + $old_custom_commands = $table_options['datatables_custom_commands'];
1128 + $table_options['datatables_custom_commands'] = TablePress::convert_datatables_api_data( $table_options['datatables_custom_commands'] );
1129 + // No need to save (which runs a DB query) if nothing was replaced in the "Custom Commands".
1130 + if ( $old_custom_commands === $table_options['datatables_custom_commands'] ) {
1131 + continue;
1132 + }
1133 +
1134 + $this->_update_table_options( $post_id, $table_options );
1135 + }
1136 + }
1137 +
1138 + /**
1070 1139 * Invalidate all table output caches, e.g. after a plugin update.
1071 1140 *
1072 1141 * @since 1.0.0
1073 1142 */
1074 - public function invalidate_table_output_caches() {
1143 + public function invalidate_table_output_caches(): void {
1075 1144 $table_post = $this->tables->get( 'table_post' );
1076 1145 if ( empty( $table_post ) ) {
1077 1146 return;
1078 1147 }
@@ -1077,8 +1146,9 @@
1077 1146 return;
1078 1147 }
1079 1148
1080 1149 foreach ( $table_post as $table_id => $post_id ) {
1150 + $table_id = (string) $table_id; // Ensure that the table ID is a string, as it comes from an array key where numeric strings are converted to integers.
1081 1151 $this->invalidate_table_output_cache( $table_id );
1082 1152 }
1083 1153 }
1084 1154
@@ -1089,11 +1159,11 @@
1089 1159 * @since 1.5.0
1090 1160 *
1091 1161 * @global wpdb $wpdb WordPress database abstraction object.
1092 1162 */
1093 - public function add_mime_type_to_posts() {
1163 + public function add_mime_type_to_posts(): void {
1094 1164 global $wpdb;
1095 - $wpdb->update( $wpdb->posts, array( 'post_mime_type' => 'application/json' ), array( 'post_type' => $this->model_post->get_post_type() ) );
1165 + $wpdb->update( $wpdb->posts, array( 'post_mime_type' => 'application/json' ), array( 'post_type' => $this->model_post->get_post_type() ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
1096 1166 }
1097 1167
1098 1168 /**
1099 1169 * Add a table ID for a post (table) that was imported through the WP WXR importer to the table ID to post ID map.
@@ -1099,14 +1169,14 @@
1099 1169 * Add a table ID for a post (table) that was imported through the WP WXR importer to the table ID to post ID map.
1100 1170 *
1101 1171 * @since 1.5.0
1102 1172 *
1103 - * @param int|WP_Error $post_id Post ID of the imported post on success. 0 or WP_Error on failure.
1104 - * @param int $original_post_id Original post ID that the post had on the site where it was exported from.
1105 - * @param array $postdata Post data that was imported into the database.
1106 - * @param array $post Original post data as it was exported.
1173 + * @param int|WP_Error $post_id Post ID of the imported post on success. 0 or WP_Error on failure.
1174 + * @param int $original_post_id Original post ID that the post had on the site where it was exported from.
1175 + * @param array<string, mixed> $postdata Post data that was imported into the database.
1176 + * @param array<string, mixed> $post Original post data as it was exported.
1107 1177 */
1108 - public function add_table_id_on_wp_import( $post_id, $original_post_id, array $postdata, array $post ) {
1178 + public function add_table_id_on_wp_import( /* int|WP_Error */ $post_id, int $original_post_id, array $postdata, array $post ): void {
1109 1179 // Bail if the post could not be imported or if the post is not a TablePress table.
1110 1180 if ( is_wp_error( $post_id ) || $this->model_post->get_post_type() !== $postdata['post_type'] ) {
1111 1181 return;
1112 1182 }
@@ -1125,9 +1195,9 @@
1125 1195
1126 1196 // Save the post ID for each of the table IDs.
1127 1197 $post_id_saved = false;
1128 1198 foreach ( $table_ids as $table_id ) {
1129 - $table_id = preg_replace( '/[^a-zA-Z0-9_-]/', '', $table_id );
1199 + $table_id = (string) preg_replace( '/[^a-zA-Z0-9_-]/', '', $table_id );
1130 1200 if ( '' === $table_id || $this->table_exists( $table_id ) ) {
1131 1201 continue;
1132 1202 }
1133 1203 $this->_update_post_id( $table_id, $post_id );
@@ -1145,14 +1215,14 @@
1145 1215 * Remove the `_tablepress_export_table_id` post meta field from the fields that are imported during a WP WXR import.
1146 1216 *
1147 1217 * @since 1.5.0
1148 1218 *
1149 - * @param array $postmeta Post meta fields for the post.
1150 - * @param int $post_id Post ID.
1151 - * @param array $post Post.
1152 - * @return array Modified post meta fields.
1219 + * @param array<string, mixed> $postmeta Post meta fields for the post.
1220 + * @param int $post_id Post ID.
1221 + * @param array<string, mixed> $post Post.
1222 + * @return array<string, mixed> Modified post meta fields.
1153 1223 */
1154 - public function prevent_table_id_post_meta_import_on_wp_import( array $postmeta, $post_id, array $post ) {
1224 + public function prevent_table_id_post_meta_import_on_wp_import( array $postmeta, int $post_id, array $post ): array {
1155 1225 // Bail if the post is not a TablePress table.
1156 1226 if ( $this->model_post->get_post_type() !== $post['post_type'] ) {
1157 1227 return $postmeta;
1158 1228 }
@@ -1177,10 +1247,11 @@
1177 1247 *
1178 1248 * @param bool $skip Whether to skip the current post meta. Default false.
1179 1249 * @param string $meta_key Current meta key.
1180 1250 * @param stdClass $meta Current meta object.
1251 + * @return bool Whether to skip the current post meta (unchanged $skip parameter).
1181 1252 */
1182 - public function add_table_id_to_wp_export( $skip, $meta_key, $meta ) {
1253 + public function add_table_id_to_wp_export( bool $skip, string $meta_key, stdClass $meta ): bool {
1183 1254 // Bail if the exporter doesn't process a TablePress table right now.
1184 1255 if ( $this->table_options_field_name !== $meta_key ) {
1185 1256 return $skip;
1186 1257 }
@@ -1195,17 +1266,24 @@
1195 1266 }
1196 1267
1197 1268 // Pretend that there is a `_tablepress_export_table_id` post meta field with the list of table IDs.
1198 1269 $key = '_tablepress_export_table_id';
1270 +
1271 + /**
1272 + * Load WP export functions.
1273 + */
1274 + require_once ABSPATH . 'wp-admin/includes/export.php';
1199 1275 $value = wxr_cdata( implode( ',', $table_ids ) );
1200 1276
1201 1277 // Hijack the filter and print extra XML code for our faked post meta field.
1278 + // phpcs:disable WordPress.Security.EscapeOutput.HeredocOutputNotEscaped
1202 1279 echo <<<WXR
1203 - <wp:postmeta>
1204 - <wp:meta_key>{$key}</wp:meta_key>
1205 - <wp:meta_value>{$value}</wp:meta_value>
1206 - </wp:postmeta>\n
1207 -WXR;
1280 + <wp:postmeta>
1281 + <wp:meta_key>{$key}</wp:meta_key>
1282 + <wp:meta_value>{$value}</wp:meta_value>
1283 + </wp:postmeta>\n
1284 + WXR;
1285 + // phpcs:enable
1208 1286
1209 1287 return $skip;
1210 1288 }
1211 1289
@@ -1213,9 +1291,9 @@
1213 1291 * Delete the WP_Option of the model.
1214 1292 *
1215 1293 * @since 1.0.0
1216 1294 */
1217 - public function destroy() {
1295 + public function destroy(): void {
1218 1296 $this->tables->delete();
1219 1297 }
1220 1298
1221 1299 } // class TablePress_Table_Model