PluginProbe
TablePress – Tables in WordPress made easy / 2.2
TablePress – Tables in WordPress made easy v2.2
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 2.4.4 All 44 releases
← All changes | classes/class-render.php +69 -139 trunk2.2 View file →
@@ -26,9 +26,9 @@
26 26 *
27 27 * @since 1.0.0
28 28 * @var array<string, mixed>
29 29 */
30 - protected array $table = array();
30 + protected $table = array();
31 31
32 32 /**
33 33 * Table options that influence the output result.
34 34 *
@@ -34,9 +34,9 @@
34 34 *
35 35 * @since 1.0.0
36 36 * @var array<string, mixed>
37 37 */
38 - protected array $render_options = array();
38 + protected $render_options = array();
39 39
40 40 /**
41 41 * Rendered HTML code of the table or PHP array.
42 42 *
@@ -50,9 +50,9 @@
50 50 *
51 51 * @since 1.0.0
52 52 * @var array<string, string>
53 53 */
54 - protected array $span_trigger = array(
54 + protected $span_trigger = array(
55 55 'colspan' => '#colspan#',
56 56 'rowspan' => '#rowspan#',
57 57 'span' => '#span#',
58 58 );
@@ -62,9 +62,9 @@
62 62 *
63 63 * @since 1.0.0
64 64 * @var int[]
65 65 */
66 - protected array $rowspan = array();
66 + protected $rowspan = array();
67 67
68 68 /**
69 69 * Buffer to store the counts of colspan per row, initialized in _render_table().
70 70 *
@@ -70,30 +70,25 @@
70 70 *
71 71 * @since 1.0.0
72 72 * @var int[]
73 73 */
74 - protected array $colspan = array();
74 + protected $colspan = array();
75 75
76 76 /**
77 - * Whether the table has connected cells (colspan or rowspan), set in _render_table().
78 - *
79 - * @since 3.0.0
80 - */
81 - protected bool $tbody_has_connected_cells = false;
82 -
83 - /**
84 77 * Index of the last row of the visible data in the table, set in _render_table().
85 78 *
86 79 * @since 1.0.0
80 + * @var int
87 81 */
88 - protected int $last_row_idx;
82 + protected $last_row_idx;
89 83
90 84 /**
91 85 * Index of the last column of the visible data in the table, set in _render_table().
92 86 *
93 87 * @since 1.0.0
88 + * @var int
94 89 */
95 - protected int $last_column_idx;
90 + protected $last_column_idx;
96 91
97 92 /**
98 93 * Class constructor.
99 94 *
@@ -355,9 +350,8 @@
355 350 $num_columns = ( $num_rows > 0 ) ? count( $this->table['data'][0] ) : 0;
356 351
357 352 // Check if there are rows and columns in the table (might not be the case after removing hidden rows/columns!).
358 353 if ( 0 === $num_rows || 0 === $num_columns ) {
359 - /* translators: %s: Table ID */
360 354 $this->output = sprintf( __( '<!-- The table with the ID %s is empty! -->', 'tablepress' ), $this->table['id'] );
361 355 return;
362 356 }
363 357
@@ -467,46 +461,30 @@
467 461 if ( $this->render_options['print_description'] && 'above' === $this->render_options['print_description_position'] ) {
468 462 $output .= $print_description_html;
469 463 }
470 464
471 - $thead = array();
472 - $tfoot = array();
465 + $thead = '';
466 + $tfoot = '';
473 467 $tbody = array();
474 468
475 469 $this->last_row_idx = $num_rows - 1;
476 470 $this->last_column_idx = $num_columns - 1;
477 -
478 471 // Loop through rows in reversed order, to search for rowspan trigger keyword.
479 - $row_idx = $this->last_row_idx;
480 -
481 - // Render the table footer rows, if there is at least one extra row.
482 - if ( $this->render_options['table_foot'] > 0 && $num_rows >= $this->render_options['table_head'] + $this->render_options['table_foot'] ) {
483 - $last_tbody_idx = $this->last_row_idx - $this->render_options['table_foot'];
484 - while ( $row_idx > $last_tbody_idx ) {
485 - $tfoot[] = $this->_render_row( $row_idx, 'th' );
486 - --$row_idx;
472 + for ( $row_idx = $this->last_row_idx; $row_idx >= 0; $row_idx-- ) {
473 + // Last row, need to check for footer (but only if at least two rows).
474 + if ( $this->last_row_idx === $row_idx && $this->render_options['table_foot'] && $num_rows > 1 ) {
475 + $tfoot = $this->_render_row( $row_idx, 'th' );
476 + continue;
487 477 }
488 - // Reverse rows because we looped through the rows in reverse order.
489 - $tfoot = array_reverse( $tfoot );
490 - }
491 -
492 - // Render the table body rows.
493 - $last_thead_idx = $this->render_options['table_head'] - 1;
494 - while ( $row_idx > $last_thead_idx ) {
478 + // First row, need to check for head (but only if at least two rows).
479 + if ( 0 === $row_idx && $this->render_options['table_head'] && $num_rows > 1 ) {
480 + $thead = $this->_render_row( $row_idx, 'th' );
481 + continue;
482 + }
483 + // Neither first nor last row (with respective head/foot enabled), so render as body row.
495 484 $tbody[] = $this->_render_row( $row_idx, 'td' );
496 - --$row_idx;
497 485 }
498 - // Reverse rows because we looped through the rows in reverse order.
499 - $tbody = array_reverse( $tbody );
500 486
501 - // Render the table header rows, if rows are left.
502 - while ( $row_idx > -1 ) {
503 - $thead[] = $this->_render_row( $row_idx, 'th' );
504 - --$row_idx;
505 - }
506 - // Reverse rows because we looped through the rows in reverse order.
507 - $thead = array_reverse( $thead );
508 -
509 487 // <caption> tag.
510 488 /**
511 489 * Filters the content for the HTML caption element of the table.
512 490 *
@@ -566,9 +544,9 @@
566 544 * @param string $table_id The current table ID.
567 545 * @param int $col_idx The number of the column.
568 546 */
569 547 $attributes = apply_filters( 'tablepress_colgroup_tag_attributes', $attributes, $this->table['id'], $col_idx + 1 );
570 - $colgroup .= "\t<col{$attributes} />\n";
548 + $colgroup .= "\t<col{$attributes}/>\n";
571 549 }
572 550 }
573 551 if ( ! empty( $colgroup ) ) {
574 552 $colgroup = "<colgroup>\n{$colgroup}</colgroup>\n";
@@ -573,36 +551,18 @@
573 551 if ( ! empty( $colgroup ) ) {
574 552 $colgroup = "<colgroup>\n{$colgroup}</colgroup>\n";
575 553 }
576 554
577 - /*
578 - * <thead>, <tfoot>, and <tbody> tags.
579 - */
580 -
555 + // <thead>, <tfoot>, and <tbody> tags.
581 556 if ( ! empty( $thead ) ) {
582 - $thead = "<thead>\n" . implode( '', $thead ) . "</thead>\n";
583 - } else {
584 - $thead = '';
557 + $thead = "<thead>\n{$thead}</thead>\n";
585 558 }
586 -
587 559 if ( ! empty( $tfoot ) ) {
588 - $tfoot = "<tfoot>\n" . implode( '', $tfoot ) . "</tfoot>\n";
589 - } else {
590 - $tfoot = '';
560 + $tfoot = "<tfoot>\n{$tfoot}</tfoot>\n";
591 561 }
592 -
593 - $tbody_classes = array();
594 - if ( $this->render_options['alternating_row_colors'] ) {
595 - $tbody_classes[] = 'row-striping';
596 - }
597 - if ( $this->render_options['row_hover'] ) {
598 - $tbody_classes[] = 'row-hover';
599 - }
600 - $tbody_class = implode( ' ', $tbody_classes );
601 - if ( '' !== $tbody_class ) {
602 - $tbody_class = ' class="' . esc_attr( $tbody_class ) . '"';
603 - }
604 -
562 + $tbody_class = ( $this->render_options['row_hover'] ) ? ' class="row-hover"' : '';
563 + // Reverse rows because we looped through the rows in reverse order.
564 + $tbody = array_reverse( $tbody );
605 565 $tbody = "<tbody{$tbody_class}>\n" . implode( '', $tbody ) . "</tbody>\n";
606 566
607 567 // Attributes for the table (HTML table element).
608 568 $table_attributes = array();
@@ -612,16 +572,9 @@
612 572 $table_attributes['id'] = $this->render_options['html_id'];
613 573 }
614 574
615 575 // "class" attribute.
616 - $css_classes = array(
617 - 'tablepress',
618 - "tablepress-id-{$this->table['id']}",
619 - $this->render_options['extra_css_classes'],
620 - );
621 - if ( $this->tbody_has_connected_cells ) {
622 - $css_classes[] = 'tbody-has-connected-cells';
623 - }
576 + $css_classes = array( 'tablepress', "tablepress-id-{$this->table['id']}", $this->render_options['extra_css_classes'] );
624 577 /**
625 578 * Filters the CSS classes that are given to the HTML table element.
626 579 *
627 580 * @since 1.0.0
@@ -633,11 +586,10 @@
633 586 // $css_classes might contain several classes in one array entry.
634 587 $css_classes = explode( ' ', implode( ' ', $css_classes ) );
635 588 $css_classes = array_map( array( 'TablePress', 'sanitize_css_class' ), $css_classes );
636 589 $css_classes = array_unique( $css_classes );
637 - $css_classes = array_filter( $css_classes ); // Remove empty entries.
638 - $css_classes = implode( ' ', $css_classes );
639 - if ( '' !== $css_classes ) {
590 + $css_classes = trim( implode( ' ', $css_classes ) );
591 + if ( ! empty( $css_classes ) ) {
640 592 $table_attributes['class'] = $css_classes;
641 593 }
642 594
643 595 // ARIA label attributes.
@@ -667,9 +619,9 @@
667 619
668 620 // Legacy support for attributes that are not encouraged in HTML5.
669 621 foreach ( array( 'cellspacing', 'cellpadding', 'border' ) as $attribute ) {
670 622 if ( false !== $this->render_options[ $attribute ] ) {
671 - $table_attributes[ $attribute ] = (string) absint( $this->render_options[ $attribute ] );
623 + $table_attributes[ $attribute ] = (int) $this->render_options[ $attribute ];
672 624 }
673 625 }
674 626
675 627 /**
@@ -683,26 +635,12 @@
683 635 */
684 636 $table_attributes = apply_filters( 'tablepress_table_tag_attributes', $table_attributes, $this->table, $this->render_options );
685 637 $table_attributes = $this->_attributes_array_to_string( $table_attributes );
686 638
687 - $table_html = "<table{$table_attributes}>\n";
688 - $table_html .= $caption . $colgroup . $thead . $tbody . $tfoot;
689 - $table_html .= '</table>';
639 + $output .= "\n<table{$table_attributes}>\n";
640 + $output .= $caption . $colgroup . $thead . $tbody . $tfoot;
641 + $output .= "</table>\n";
690 642
691 - /**
692 - * Filters the generated HTML code for the table, without HTML elements around it.
693 - *
694 - * @since 2.4.0
695 - *
696 - * @param string $output The generated HTML for the table, without HTML elements around it.
697 - * @param array<string, mixed> $table The current table.
698 - * @param array<string, mixed> $render_options The render options for the table, without HTML elements around it.
699 - */
700 - $table_html = apply_filters( 'tablepress_table_html', $table_html, $this->table, $this->render_options );
701 -
702 - $output .= "\n{$table_html}\n";
703 - unset( $table_html ); // Unset the potentially large variable to free up memory.
704 -
705 643 // name/description below table (HTML already generated above).
706 644 if ( $this->render_options['print_name'] && 'below' === $this->render_options['print_name_position'] ) {
707 645 $output .= $print_name_html;
708 646 }
@@ -710,15 +648,15 @@
710 648 $output .= $print_description_html;
711 649 }
712 650
713 651 /**
714 - * Filters the generated HTML code for the table and HTML elements around it.
652 + * Filters the generated HTML code for table.
715 653 *
716 654 * @since 1.0.0
717 655 *
718 - * @param string $output The generated HTML for the table and HTML elements around it.
656 + * @param string $output The generated HTML for the table.
719 657 * @param array<string, mixed> $table The current table.
720 - * @param array<string, mixed> $render_options The render options for the table and HTML elements around it.
658 + * @param array<string, mixed> $render_options The render options for the table.
721 659 */
722 660 $this->output = apply_filters( 'tablepress_table_output', $output, $this->table, $this->render_options );
723 661 }
724 662
@@ -739,10 +677,10 @@
739 677
740 678 if ( $this->span_trigger['rowspan'] === $cell_content ) { // There will be a rowspan.
741 679 if ( ! (
742 680 ( 0 === $row_idx ) // No rowspan inside first row.
743 - || ( $this->render_options['table_head'] === $row_idx ) // No rowspan into table head.
744 - || ( $this->last_row_idx - $this->render_options['table_foot'] + 1 === $row_idx ) // No rowspan out of table foot.
681 + || ( 1 === $row_idx && $this->render_options['table_head'] ) // No rowspan into table head.
682 + || ( $this->last_row_idx === $row_idx && $this->render_options['table_foot'] ) // No rowspan out of table foot.
745 683 ) ) {
746 684 // Increase counter for rowspan in this column.
747 685 ++$this->rowspan[ $col_idx ];
748 686 // Reset counter for colspan in this row, combined col- and rowspan might be happening.
@@ -766,10 +704,10 @@
766 704 $cell_content = '';
767 705 } elseif ( $this->span_trigger['span'] === $cell_content ) { // There will be a combined col- and rowspan.
768 706 if ( ! (
769 707 ( 0 === $row_idx ) // No rowspan inside first row.
770 - || ( $this->render_options['table_head'] === $row_idx ) // No rowspan into table head.
771 - || ( $this->last_row_idx - $this->render_options['table_foot'] + 1 === $row_idx ) // No rowspan out of table foot.
708 + || ( 1 === $row_idx && $this->render_options['table_head'] ) // No rowspan into table head.
709 + || ( $this->last_row_idx === $row_idx && $this->render_options['table_foot'] ) // No rowspan out of table foot.
772 710 ) && ! (
773 711 ( 0 === $col_idx ) // No colspan inside first column.
774 712 || ( 1 === $col_idx && $this->render_options['first_column_th'] ) // No colspan into first column head.
775 713 ) ) {
@@ -784,19 +722,11 @@
784 722
785 723 // "colspan" and "rowspan" attributes.
786 724 if ( $this->colspan[ $row_idx ] > 1 ) { // We have colspaned cells.
787 725 $tag_attributes['colspan'] = (string) $this->colspan[ $row_idx ];
788 - if ( ! $this->tbody_has_connected_cells && $row_idx > $this->render_options['table_head'] - 1 && $row_idx < $this->last_row_idx - $this->render_options['table_foot'] + 1 ) {
789 - // Set flag that there are connected cells in the tbody.
790 - $this->tbody_has_connected_cells = true;
791 - }
792 726 }
793 727 if ( $this->rowspan[ $col_idx ] > 1 ) { // We have rowspaned cells.
794 728 $tag_attributes['rowspan'] = (string) $this->rowspan[ $col_idx ];
795 - if ( ! $this->tbody_has_connected_cells && $row_idx > $this->render_options['table_head'] - 1 && $row_idx < $this->last_row_idx - $this->render_options['table_foot'] + 1 ) {
796 - // Set flag that there are connected cells in the tbody.
797 - $this->tbody_has_connected_cells = true;
798 - }
799 729 }
800 730
801 731 // "class" attribute.
802 732 $cell_class = 'column-' . ( $col_idx + 1 );
@@ -838,17 +768,13 @@
838 768 */
839 769 $tag_attributes = apply_filters( 'tablepress_cell_tag_attributes', $tag_attributes, $this->table['id'], $cell_content, $row_idx + 1, $col_idx + 1, $this->colspan[ $row_idx ], $this->rowspan[ $col_idx ] );
840 770 $tag_attributes = $this->_attributes_array_to_string( $tag_attributes );
841 771
842 - if ( '' === $cell_content ) {
843 - $cell_tag = 'td'; // For accessibility, empty cells should use `td` and not `th` tags.
844 - } elseif ( $this->render_options['first_column_th'] && 0 === $col_idx ) {
845 - $cell_tag = 'th'; // Non-empty cells in the first column should use `th` tags, if enabled.
846 - } else {
847 - $cell_tag = $tag; // Otherwise, use the tag that was passed in as the default for the row.
772 + if ( $this->render_options['first_column_th'] && 0 === $col_idx ) {
773 + $tag = 'th';
848 774 }
849 775
850 - $row_cells[] = "<{$cell_tag}{$tag_attributes}>{$cell_content}</{$cell_tag}>";
776 + $row_cells[] = "<{$tag}{$tag_attributes}>{$cell_content}</{$tag}>";
851 777 $this->colspan[ $row_idx ] = 1; // Reset.
852 778 $this->rowspan[ $col_idx ] = 1; // Reset.
853 779 }
854 780
@@ -856,8 +782,11 @@
856 782 $tr_attributes = array();
857 783
858 784 // "class" attribute.
859 785 $row_classes = 'row-' . ( $row_idx + 1 );
786 + if ( $this->render_options['alternating_row_colors'] ) {
787 + $row_classes .= ( 1 === ( $row_idx % 2 ) ) ? ' even' : ' odd';
788 + }
860 789 /**
861 790 * Filters the CSS classes that are given to a row (HTML tr element) of a table.
862 791 *
863 792 * @since 1.0.0
@@ -909,8 +838,10 @@
909 838
910 839 /**
911 840 * Possibly replace certain HTML entities and replace line breaks with HTML.
912 841 *
842 + * @TODO: Find a better solution than this function, e.g. something like wpautop().
843 + *
913 844 * @since 1.0.0
914 845 *
915 846 * @param string $text The string to process.
916 847 * @return string Processed string for output.
@@ -945,9 +876,8 @@
945 876 public function get_default_render_options(): array {
946 877 // Attention: Array keys have to be lowercase, otherwise they won't match the Shortcode attributes, which will be passed in lowercase by WP.
947 878 return array(
948 879 'alternating_row_colors' => null,
949 - 'block_preview' => false,
950 880 'border' => false,
951 881 'cache_table_output' => true,
952 882 'cellpadding' => false,
953 883 'cellspacing' => false,
@@ -953,9 +883,8 @@
953 883 'cellspacing' => false,
954 884 'column_widths' => '',
955 885 'convert_line_breaks' => true,
956 886 'datatables_custom_commands' => null,
957 - 'datatables_datetime' => '',
958 887 'datatables_filter' => null,
959 888 'datatables_info' => null,
960 889 'datatables_lengthchange' => null,
961 890 'datatables_locale' => get_locale(),
@@ -996,29 +925,30 @@
996 925 $tablepress_css = TablePress::load_class( 'TablePress_CSS', 'class-css.php', 'classes' );
997 926 $default_css_minified = $tablepress_css->load_default_css_from_file( $is_rtl );
998 927 if ( false === $default_css_minified ) {
999 928 $default_css_minified = '';
929 + } else {
930 + // Change relative URLs to web font files to absolute URLs, as combining the CSS files and saving to another directory breaks the relative URLs.
931 + $absolute_path = plugins_url( 'css/build/tablepress.', TABLEPRESS__FILE__ );
932 + // Make the absolute URL protocol-relative to prevent mixed content warnings.
933 + $absolute_path = str_replace( array( 'http:', 'https:' ), '', $absolute_path );
934 + $default_css_minified = str_replace( 'url(tablepress.', 'url(' . $absolute_path, $default_css_minified );
1000 935 }
1001 936
1002 937 $rtl_direction = $is_rtl ? "\ndirection: rtl;" : '';
1003 938
1004 939 return <<<CSS
1005 - <style>
1006 - /* iframe */
1007 - body {
1008 - margin: 10px;
1009 - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;{$rtl_direction}
1010 - }
1011 - p {
1012 - font-size: 13px;
1013 - }
1014 - .preview {
1015 - overflow-x: auto;
1016 - overflow-y: hidden;
1017 - scroll-behavior: smooth;
1018 - }
1019 - {$default_css_minified}
1020 - </style>
1021 - CSS;
940 +<style>
941 +/* iframe */
942 +body {
943 + margin: 10px;
944 + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;{$rtl_direction}
945 +}
946 +p {
947 + font-size: 13px;
948 +}
949 +{$default_css_minified}
950 +</style>
951 +CSS;
1022 952 }
1023 953
1024 954 } // class TablePress_Render