| @@ -7,13 +7,16 @@ | ||
| 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 | /** |
| 15 | 17 | * List Tables View class |
| 18 | + * | |
| 16 | 19 | * @package TablePress |
| 17 | 20 | * @subpackage Views |
| 18 | 21 | * @author Tobias Bäthge |
| 19 | 22 | * @since 1.0.0 |
| @@ -23,11 +26,10 @@ | ||
| 23 | 26 | /** |
| 24 | 27 | * Object for the All Tables List Table. |
| 25 | 28 | * |
| 26 | 29 | * @since 1.0.0 |
| 27 | - * @var TablePress_All_Tables_List_Table | |
| 28 | 30 | */ |
| 29 | - protected $wp_list_table; | |
| 31 | + protected \TablePress_All_Tables_List_Table $wp_list_table; | |
| 30 | 32 | |
| 31 | 33 | /** |
| 32 | 34 | * Set up the view with data and do things that are specific for this view. |
| 33 | 35 | * |
| @@ -32,93 +34,276 @@ | ||
| 32 | 34 | * Set up the view with data and do things that are specific for this view. |
| 33 | 35 | * |
| 34 | 36 | * @since 1.0.0 |
| 35 | 37 | * |
| 36 | - * @param string $action Action for this view. | |
| 37 | - * @param array $data Data for this view. | |
| 38 | + * @param string $action Action for this view. | |
| 39 | + * @param array<string, mixed> $data Data for this view. | |
| 38 | 40 | */ |
| 39 | - public function setup( $action, array $data ) { | |
| 41 | + #[\Override] | |
| 42 | + public function setup( /* string */ $action, array $data ) /* : void */ { | |
| 43 | + // Don't use type hints in the method declaration to prevent PHP errors, as the method is inherited. | |
| 44 | + | |
| 40 | 45 | parent::setup( $action, $data ); |
| 41 | 46 | |
| 42 | - add_thickbox(); | |
| 43 | - $this->admin_page->enqueue_script( 'list', array( 'jquery-core' ), array( | |
| 44 | - 'list' => array( | |
| 45 | - 'shortcode_popup' => __( 'To embed this table into a post or page, use this Shortcode:', 'tablepress' ), | |
| 46 | - 'donation-message-already-donated' => __( 'Thank you very much! Your donation is highly appreciated. You just contributed to the further development of TablePress!', 'tablepress' ), | |
| 47 | - 'donation-message-maybe-later' => sprintf( __( 'No problem! I still hope you enjoy the benefits that TablePress adds to your site. If you should change your mind, you’ll always find the “Donate” button on the <a href="%s">TablePress website</a>.', 'tablepress' ), 'https://tablepress.org/' ), | |
| 48 | - ), | |
| 49 | - ) ); | |
| 47 | + TablePress::enqueue_script( 'list' ); | |
| 50 | 48 | |
| 51 | - if ( $data['messages']['first_visit'] ) { | |
| 52 | - $this->add_header_message( | |
| 53 | - '<strong><em>' . __( 'Welcome!', 'tablepress' ) . '</em></strong><br />' | |
| 54 | - . __( 'Thank you for using TablePress for the first time!', 'tablepress' ) . ' ' | |
| 55 | - . sprintf( __( 'If you encounter any questions or problems, please visit the <a href="%1$s">FAQ</a>, the <a href="%2$s">documentation</a>, and the <a href="%3$s">Support</a> section on the <a href="%4$s">plugin website</a>.', 'tablepress' ), 'https://tablepress.org/faq/', 'https://tablepress.org/documentation/', 'https://tablepress.org/support/', 'https://tablepress.org/' ) . '<br /><br />' | |
| 56 | - . $this->ajax_link( array( 'action' => 'hide_message', 'item' => 'first_visit', 'return' => 'list' ), __( 'Hide this message', 'tablepress' ) ), | |
| 57 | - 'notice-info not-dismissible' | |
| 49 | + $milestone_period_ended = ( strtotime( '2026-10-10' ) < strtotime( 'today' ) ); | |
| 50 | + | |
| 51 | + if ( $data['messages']['superseded_extensions'] ) { | |
| 52 | + $superseded_extensions = array( | |
| 53 | + 'tablepress-advanced-access-rights/tablepress-advanced-access-rights.php' => array( | |
| 54 | + 'name' => 'TablePress Extension: Advanced Access Rights', | |
| 55 | + 'compatible' => true, | |
| 56 | + ), | |
| 57 | + 'tablepress-auto-export-tables/tablepress-auto-export-tables.php' => array( | |
| 58 | + 'name' => 'TablePress Extension: Automatic Table Export', | |
| 59 | + 'compatible' => true, | |
| 60 | + ), | |
| 61 | + 'tablepress-cell-highlighting/tablepress-cell-highlighting.php' => array( | |
| 62 | + 'name' => 'TablePress Extension: Cell Highlighting', | |
| 63 | + 'compatible' => true, | |
| 64 | + ), | |
| 65 | + 'tablepress-datatables-alphabetsearch/tablepress-datatables-alphabetsearch.php' => array( | |
| 66 | + 'name' => 'TablePress Extension: DataTables AlphabetSearch', | |
| 67 | + 'compatible' => false, | |
| 68 | + ), | |
| 69 | + 'tablepress-datatables-buttons/tablepress-datatables-buttons.php' => array( | |
| 70 | + 'name' => 'TablePress Extension: DataTables Buttons', | |
| 71 | + 'compatible' => true, | |
| 72 | + ), | |
| 73 | + 'tablepress-datatables-column-filter-widgets/tablepress-datatables-column-filter-widgets.php' => array( | |
| 74 | + 'name' => 'TablePress Extension: DataTables ColumnFilterWidgets', | |
| 75 | + 'compatible' => false, | |
| 76 | + ), | |
| 77 | + 'tablepress-datatables-columnfilter/tablepress-datatables-columnfilter.php' => array( | |
| 78 | + 'name' => 'TablePress Extension: DataTables Column Filter', | |
| 79 | + 'compatible' => false, | |
| 80 | + ), | |
| 81 | + 'tablepress-datatables-counter-column/tablepress-datatables-counter-column.php' => array( | |
| 82 | + 'name' => 'TablePress Extension: DataTables Counter Column', | |
| 83 | + 'compatible' => true, | |
| 84 | + ), | |
| 85 | + 'tablepress-datatables-fixedcolumns/tablepress-datatables-fixedcolumns.php' => array( | |
| 86 | + 'name' => 'TablePress Extension: DataTables FixedColumns', | |
| 87 | + 'compatible' => false, | |
| 88 | + ), | |
| 89 | + 'tablepress-datatables-fixedheader/tablepress-datatables-fixedheader.php' => array( | |
| 90 | + 'name' => 'TablePress Extension: DataTables FixedHeader', | |
| 91 | + 'compatible' => true, | |
| 92 | + ), | |
| 93 | + 'tablepress-datatables-inverted-filter/tablepress-datatables-inverted-filter.php' => array( | |
| 94 | + 'name' => 'TablePress Extension: DataTables Inverted Filter', | |
| 95 | + 'compatible' => false, | |
| 96 | + ), | |
| 97 | + 'tablepress-datatables-row-details/tablepress-datatables-row-details.php' => array( | |
| 98 | + 'name' => 'TablePress Extension: DataTables Row Details', | |
| 99 | + 'compatible' => false, | |
| 100 | + ), | |
| 101 | + 'tablepress-datatables-rowgroup/tablepress-datatables-rowgroup.php' => array( | |
| 102 | + 'name' => 'TablePress Extension: DataTables RowGroup', | |
| 103 | + 'compatible' => false, | |
| 104 | + ), | |
| 105 | + 'tablepress-responsive-tables/tablepress-responsive-tables.php' => array( | |
| 106 | + 'name' => 'TablePress Extension: Responsive Tables', | |
| 107 | + 'compatible' => false, | |
| 108 | + ), | |
| 109 | + 'tablepress-row-filter/tablepress-row-filter.php' => array( | |
| 110 | + 'name' => 'TablePress Extension: Row Filtering', | |
| 111 | + 'compatible' => true, | |
| 112 | + ), | |
| 113 | + 'tablepress-row-highlighting/tablepress-row-highlighting.php' => array( | |
| 114 | + 'name' => 'TablePress Extension: Row Highlighting', | |
| 115 | + 'compatible' => true, | |
| 116 | + ), | |
| 117 | + 'tablepress-table-auto-update/tablepress-table-auto-update.php' => array( | |
| 118 | + 'name' => 'TablePress Extension: Table Auto Update', | |
| 119 | + 'compatible' => true, | |
| 120 | + ), | |
| 121 | + 'tablepress-table-column-order/tablepress-table-column-order.php' => array( | |
| 122 | + 'name' => 'TablePress Extension: Table Column Order', | |
| 123 | + 'compatible' => true, | |
| 124 | + ), | |
| 58 | 125 | ); |
| 126 | + | |
| 127 | + $active_compatible_superseded_extensions = array(); | |
| 128 | + $active_incompatible_superseded_extensions = array(); | |
| 129 | + foreach ( $superseded_extensions as $plugin => $extension ) { | |
| 130 | + if ( is_plugin_active( $plugin ) ) { | |
| 131 | + if ( $extension['compatible'] ) { | |
| 132 | + $active_compatible_superseded_extensions[] = $extension['name']; | |
| 133 | + } else { | |
| 134 | + $active_incompatible_superseded_extensions[] = $extension['name']; | |
| 135 | + } | |
| 136 | + } | |
| 137 | + } | |
| 138 | + | |
| 139 | + /* | |
| 140 | + * If no superseded extensions are used, hide the message, to prevent running the checks on every load of the view. | |
| 141 | + * This leaves a small risk of an Extension being activated later, but that's acceptable as they are no longer publicly available. | |
| 142 | + */ | |
| 143 | + if ( empty( $active_incompatible_superseded_extensions ) && ( empty( $active_compatible_superseded_extensions ) || ! tb_tp_fs()->is_free_plan() ) ) { | |
| 144 | + TablePress::$model_options->update( 'message_superseded_extensions', false ); | |
| 145 | + } | |
| 146 | + | |
| 147 | + $message = ''; | |
| 148 | + | |
| 149 | + $notice_css_classes = 'not-dismissible'; | |
| 150 | + | |
| 151 | + if ( ! empty( $active_incompatible_superseded_extensions ) ) { | |
| 152 | + $notice_css_classes .= ' is-error notice-error'; | |
| 153 | + | |
| 154 | + $message .= '<p style="font-size:16px;">' . __( 'You are using <strong>TablePress Extension plugins</strong> on this website that have been retired many years ago.', 'tablepress' ) . '<br>' . __( 'For technical reasons, some or all features of these outdated plugins <strong>do no longer work</strong>:', 'tablepress' ) . '</p>'; | |
| 155 | + $message .= '<ul style="list-style:disc;margin:0.5em 1em;font-size:16px;">'; | |
| 156 | + foreach ( $active_incompatible_superseded_extensions as $extension ) { | |
| 157 | + $message .= '<li>' . esc_html( $extension ) . '</li>'; | |
| 158 | + } | |
| 159 | + $message .= '</ul>'; | |
| 160 | + $message .= '<p style="font-size:16px;"><strong>' . __( 'Keeping them activated can lead to errors on your website.', 'tablepress' ) . '</strong></p>'; | |
| 161 | + | |
| 162 | + if ( tb_tp_fs()->is_free_plan() ) { | |
| 163 | + $message .= '<p style="font-size:16px;"><strong>' . sprintf( __( 'To continue using these features, <a href="%s">upgrade to a TablePress Premium license plan</a>!', 'tablepress' ), 'https://tablepress.org/upgrade-extensions/?utm_source=plugin&utm_medium=textlink&utm_content=superseded-extensions-message' ) . '</strong><br>' | |
| 164 | + . __( 'TablePress Pro and TablePress Max come with updated and heavily improved versions of these features and include direct priority email support.', 'tablepress' ) . '</p>'; | |
| 165 | + } | |
| 166 | + | |
| 167 | + if ( ! empty( $active_compatible_superseded_extensions ) && tb_tp_fs()->is_free_plan() ) { | |
| 168 | + $message .= '<p style="margin-top:1em;font-size:14px;">' . __( 'In addition, these TablePress Extension plugins have been retired and might become incompatible in the future as well:', 'tablepress' ) . '</strong></p>'; | |
| 169 | + $message .= '<ul style="list-style:disc;margin:0.5em 1em;font-size:14px;">'; | |
| 170 | + foreach ( $active_compatible_superseded_extensions as $extension ) { | |
| 171 | + $message .= '<li>' . esc_html( $extension ) . '</li>'; | |
| 172 | + } | |
| 173 | + $message .= '</ul>'; | |
| 174 | + } | |
| 175 | + } elseif ( ! empty( $active_compatible_superseded_extensions ) && tb_tp_fs()->is_free_plan() ) { | |
| 176 | + $notice_css_classes .= ' is-warning notice-warning'; | |
| 177 | + | |
| 178 | + $message .= '<p style="font-size:14px;"><strong>' . __( 'You are using TablePress Extension plugins on this website that have been retired and will no longer receive updates or support:', 'tablepress' ) . '</strong></p>'; | |
| 179 | + $message .= '<ul style="list-style:disc;margin:0.5em 1em;">'; | |
| 180 | + foreach ( $active_compatible_superseded_extensions as $extension ) { | |
| 181 | + $message .= '<li>' . esc_html( $extension ) . '</li>'; | |
| 182 | + } | |
| 183 | + $message .= '</ul>'; | |
| 184 | + $message .= '<p style="font-size:14px;"><strong>' . __( 'It is possible that these become incompatible with TablePress or WordPress in the future!', 'tablepress' ) . '</strong></p>'; | |
| 185 | + $message .= '<p style="margin-top:1em;font-size:14px;">' . sprintf( __( 'However, their features were heavily improved and are now part of the up-to-date <a href="%s">TablePress Premium versions</a>!', 'tablepress' ), 'https://tablepress.org/upgrade-extensions/?utm_source=plugin&utm_medium=textlink&utm_content=superseded-extensions-message' ) . '</p>'; | |
| 186 | + } | |
| 187 | + | |
| 188 | + if ( '' !== $message ) { | |
| 189 | + if ( tb_tp_fs()->is_free_plan() ) { | |
| 190 | + $message .= '<p style="font-size:16px;margin-top:1.5em;"><strong>' . __( 'Upgrade to a TablePress Premium license plan now and get:', 'tablepress' ) . '</strong></p>'; | |
| 191 | + $message .= '<ul style="list-style:disc;margin:0.5em 1em;font-size:16px;">'; | |
| 192 | + $message .= '<li>' . __( 'Updated and heavily improved versions of these features!', 'tablepress' ) . '</li>'; | |
| 193 | + $message .= '<li>' . __( 'Direct integration into the user interface!', 'tablepress' ) . '</li>'; | |
| 194 | + $message .= '<li>' . __( 'Regular updates that ensure compatibility with WordPress!', 'tablepress' ) . '</li>'; | |
| 195 | + $message .= '<li>' . __( 'Priority email support!', 'tablepress' ) . '</li>'; | |
| 196 | + $message .= '</ul>'; | |
| 197 | + $message .= '<p style="font-size:16px;"><strong>' . sprintf( __( 'And the best: %s', 'tablepress' ), sprintf( __( 'Use the promo code %1$s during the checkout process for a special offer!', 'tablepress' ), '<code>UPGRADE</code>' ) ) . '</strong></p>'; | |
| 198 | + $message .= '<p style="margin-top:2em;">' . sprintf( '<a href="%s" class="components-button is-primary" style="font-size:14px;margin-right:3em;background:linear-gradient(135deg,#00d184 0%%,#0791e3 100%%);border:none;font-weight:bold;">%s<span class="dashicons dashicons-arrow-right-alt" style="vertical-align:middle;margin:0 0 4px 4px"></span></a>', 'https://tablepress.org/upgrade-extensions/?utm_source=plugin&utm_medium=button&utm_content=superseded-extensions-message', __( 'Upgrade to a TablePress Premium version now!', 'tablepress' ) ); | |
| 199 | + } | |
| 200 | + $message .= $this->ajax_link( array( 'action' => 'hide_message', 'item' => 'superseded_extensions', 'return' => 'list' ), __( 'Hide this message', 'tablepress' ) ) . '</p>'; | |
| 201 | + | |
| 202 | + $title = '<em>' . __( 'Important Notice!', 'tablepress' ) . '</em>'; | |
| 203 | + | |
| 204 | + $this->add_header_message( $message, $notice_css_classes, $title ); | |
| 205 | + } | |
| 59 | 206 | } |
| 60 | 207 | |
| 61 | - if ( $data['messages']['wp_table_reloaded_warning'] ) { | |
| 62 | - $this->add_header_message( | |
| 63 | - '<strong><em>' . __( 'Attention!', 'tablepress' ) . '</em></strong><br />' | |
| 64 | - . __( 'You have activated the plugin WP-Table Reloaded, which can not be used together with TablePress.', 'tablepress' ) . '<br />' | |
| 65 | - . __( 'It is strongly recommended that you switch from WP-Table Reloaded to TablePress, which not only fixes many problems, but also has more and better features than WP-Table Reloaded.', 'tablepress' ) . '<br />' | |
| 66 | - . sprintf( __( 'Please follow the <a href="%s">migration guide</a> to move your tables and then deactivate WP-Table Reloaded!', 'tablepress' ), 'https://tablepress.org/migration-from-wp-table-reloaded/' ) . '<br />' | |
| 67 | - . '<a href="' . TablePress::url( array( 'action' => 'import' ) ) . '" class="button button-primary button-large" style="color:#ffffff;margin-top:5px;">' . __( 'Import your tables from WP-Table Reloaded', 'tablepress' ) . '</a>', | |
| 68 | - 'notice-error not-dismissible' | |
| 69 | - ); | |
| 208 | + if ( $data['messages']['first_visit'] && ( ! $data['messages']['plugin_update'] || $milestone_period_ended ) ) { | |
| 209 | + $message = '<p style="font-size:14px;"><strong>' . __( 'Thank you for choosing TablePress, the most popular table plugin for WordPress!', 'tablepress' ) . '</strong></p>'; | |
| 210 | + /* translators: %1$s: URL to FAQ, %2$s: URL to Documentation, %3$s: URL to Support, %4$s: URL to plugin website */ | |
| 211 | + $message .= '<p>' . sprintf( __( 'If you encounter any questions or problems, please visit the <a href="%1$s">FAQ</a>, the <a href="%2$s">Documentation</a>, and the <a href="%3$s">Support</a> section on the <a href="%4$s">plugin website</a>.', 'tablepress' ), 'https://tablepress.org/faq/', 'https://tablepress.org/documentation/', 'https://tablepress.org/support/', 'https://tablepress.org/' ) . '</p>'; | |
| 212 | + | |
| 213 | + if ( tb_tp_fs()->is_free_plan() ) { | |
| 214 | + $message .= '<p style="font-size:14px;"><strong>' . sprintf( __( 'More great features for you and your site’s visitors and priority email support are available with a Premium license plan of TablePress. <a href="%s">Go check them out!</a>', 'tablepress' ), 'https://tablepress.org/premium/?utm_source=plugin&utm_medium=textlink&utm_content=first-visit-message' ) . '</strong></p>'; | |
| 215 | + } | |
| 216 | + | |
| 217 | + $message .= '<p style="margin-top:1em;">' . $this->ajax_link( array( 'action' => 'hide_message', 'item' => 'first_visit', 'return' => 'list' ), __( 'Hide this message', 'tablepress' ) ) . '</p>'; | |
| 218 | + | |
| 219 | + $title = '<em>' . __( 'Welcome!', 'tablepress' ) . '</em>'; | |
| 220 | + | |
| 221 | + $this->add_header_message( $message, 'notice-info not-dismissible', $title ); | |
| 70 | 222 | } |
| 71 | 223 | |
| 72 | - if ( $data['messages']['donation_message'] ) { | |
| 73 | - $this->add_header_message( | |
| 74 | - '<img alt="' . esc_attr__( 'Tobias Bäthge, developer of TablePress', 'tablepress' ) . '" src="https://secure.gravatar.com/avatar/50f1cff2e27a1f522b18ce229c057bc5?s=110" height="110" width="110" style="float:left;margin:1px 10px 40px 0;" />' | |
| 75 | - . __( 'Hi, my name is Tobias, I’m the developer of the TablePress plugin.', 'tablepress' ) . '<br /><br />' | |
| 76 | - . __( 'Thanks for using it! You’ve installed TablePress over a month ago.', 'tablepress' ) . ' ' | |
| 77 | - . sprintf( _n( 'If everything works and you are satisfied with the results of managing your %s table, isn’t that worth a coffee or two?', 'If everything works and you are satisfied with the results of managing your %s tables, isn’t that worth a coffee or two?', $data['table_count'], 'tablepress' ), esc_html( $data['table_count'] ) ) . '<br />' | |
| 78 | - . sprintf( __( '<a href="%s">Donations</a> help me to continue user support and development of this <em>free</em> software — things for which I spend countless hours of my free time! Thank you very much!', 'tablepress' ), 'https://tablepress.org/donate/' ) . '<br /><br />' | |
| 79 | - . __( 'Sincerely, Tobias', 'tablepress' ) . '<br /><br />' | |
| 80 | - . sprintf( '<a href="%s" target="_blank"><strong>%s</strong></a>', 'https://tablepress.org/donate/', __( 'Sure, I’ll buy you a coffee and support TablePress!', 'tablepress' ) ) . ' · ' | |
| 81 | - . $this->ajax_link( array( 'action' => 'hide_message', 'item' => 'donation_nag', 'return' => 'list', 'target' => 'already-donated' ), __( 'I already donated.', 'tablepress' ) ) . ' · ' | |
| 82 | - . $this->ajax_link( array( 'action' => 'hide_message', 'item' => 'donation_nag', 'return' => 'list', 'target' => 'maybe-later' ), __( 'No, thanks. Don’t ask again.', 'tablepress' ) ), | |
| 83 | - 'notice-success not-dismissible' | |
| 84 | - ); | |
| 224 | + if ( $data['messages']['donation_nag'] && ( ! $data['messages']['plugin_update'] || $milestone_period_ended ) ) { | |
| 225 | + $message = '<p style="font-size:14px;"><img alt="' . esc_attr__( 'Tobias Bäthge, developer of TablePress', 'tablepress' ) . '" src="https://secure.gravatar.com/avatar/50f1cff2e27a1f522b18ce229c057bc5?s=250" height="125" width="125" style="float:left;margin:2px 15px 30px 0;border-radius:5px;">' | |
| 226 | + . __( 'Hi, my name is Tobias, I’m the developer of the TablePress plugin.', 'tablepress' ) . '</p>'; | |
| 227 | + $message .= '<p style="font-size:14px;">' . __( 'Thank you for using it!', 'tablepress' ) . ' '; | |
| 228 | + if ( $data['table_count'] > 0 ) { | |
| 229 | + /* translators: %s: Number of tables */ | |
| 230 | + $message .= sprintf( _n( 'I hope that everything works and that you are satisfied with the results of managing your %s table.', 'I hope that everything works and that you are satisfied with the results of managing your %s tables.', $data['table_count'], 'tablepress' ), $data['table_count'] ); | |
| 231 | + } else { | |
| 232 | + /* translators: %s: URL to TablePress website */ | |
| 233 | + $message .= sprintf( __( 'It looks like you haven’t added a table yet. If you need help to get started, please find more information in the FAQ and Documentation on the <a href="%s">TablePress website</a>.', 'tablepress' ), 'https://tablepress.org/' ); | |
| 234 | + } | |
| 235 | + $message .= '</p>'; | |
| 236 | + $message .= '<p style="font-size:14px;"><strong>' . sprintf( __( 'I would like to invite you to check out the <a href="%s">Premium versions of TablePress</a>.', 'tablepress' ), 'https://tablepress.org/premium/?utm_source=plugin&utm_medium=textlink&utm_content=upgrade-message' ) . '<br>' | |
| 237 | + . __( 'The available Pro and Max plans offer user support and many exciting and helpful features for your tables.', 'tablepress' ) . '</strong></p>'; | |
| 238 | + $message .= '<p style="font-size:14px;">' . __( 'Sincerely, Tobias', 'tablepress' ) . '</p>'; | |
| 239 | + $message .= '<p style="margin-top:1em;">' . sprintf( '<a href="%s" class="components-button is-primary" style="font-size:14px;margin-right:3em;color:#ffffff;">%s<span class="dashicons dashicons-arrow-right-alt" style="margin-inline:8px 0"></span></a>', 'https://tablepress.org/premium/?utm_source=plugin&utm_medium=button&utm_content=upgrade-message', __( 'Tell me more about the Premium features', 'tablepress' ) ) | |
| 240 | + . $this->ajax_link( array( 'action' => 'hide_message', 'item' => 'donation_nag', 'return' => 'list' ), __( 'Hide this message', 'tablepress' ) ) . '</p>'; | |
| 241 | + | |
| 242 | + $title = '<em>' . __( 'TablePress has more to offer!', 'tablepress' ) . '</em>'; | |
| 243 | + | |
| 244 | + $this->add_header_message( $message, 'notice-success not-dismissible', $title ); | |
| 85 | 245 | } |
| 86 | 246 | |
| 87 | - if ( $data['messages']['plugin_update_message'] ) { | |
| 88 | - $this->add_header_message( | |
| 89 | - '<strong><em>' . sprintf( __( 'Thank you for updating to TablePress %s!', 'tablepress' ), TablePress::version ) . '</em></strong><br />' | |
| 90 | - . sprintf( __( 'Please read the <a href="%s">release announcement</a> for more information.', 'tablepress' ), 'https://tablepress.org/news/' ) . ' ' | |
| 91 | - . sprintf( __( 'If you like the new features and enhancements, <a href="%s">giving a donation</a> towards the further support and development of TablePress is recommended. Thank you!', 'tablepress' ), 'https://tablepress.org/donate/' ) | |
| 92 | - . '<br /><br />' | |
| 93 | - . $this->ajax_link( array( 'action' => 'hide_message', 'item' => 'plugin_update', 'return' => 'list' ), __( 'Hide this message', 'tablepress' ) ), | |
| 94 | - 'notice-info not-dismissible' | |
| 95 | - ); | |
| 247 | + if ( $data['messages']['plugin_update'] ) { | |
| 248 | + if ( $milestone_period_ended ) { | |
| 249 | + $message = '<p>' . sprintf( __( 'To find out more about what’s new, please read the <a href="%s"><strong>release announcement</strong></a>.', 'tablepress' ), 'https://tablepress.org/news/?utm_source=plugin&utm_medium=textlink&utm_content=plugin-update-message' ) . '</p>'; | |
| 250 | + | |
| 251 | + if ( tb_tp_fs()->is_free_plan() ) { | |
| 252 | + $message .= '<p><strong>' . sprintf( __( 'More great features and priority email support are available with a Premium license plan. <a href="%s">Check them out!</a>', 'tablepress' ), 'https://tablepress.org/premium/?utm_source=plugin&utm_medium=textlink&utm_content=plugin-update-message' ) . '</strong></p>'; | |
| 253 | + } | |
| 254 | + | |
| 255 | + $title = '<em>' . sprintf( __( 'Thank you for updating to TablePress %s!', 'tablepress' ), TablePress::version ) . '</em>'; | |
| 256 | + $class = 'notice-info not-dismissible'; | |
| 257 | + } else { | |
| 258 | + $texts_german = in_array( get_user_locale(), array( 'de_DE', 'de_AT', 'de_CH' ), true ); | |
| 259 | + if ( $texts_german ) { | |
| 260 | + $message = '<p style="font-size:16px;">Wir feiern <strong>25 Millionen Downloads</strong> von TablePress aus dem WordPress-Pluginverzeichnis!<br>Mach mit und <strong>spare 25 %</strong> beim Upgrade auf TablePress Pro oder TablePress Max!</p>'; | |
| 261 | + } else { | |
| 262 | + $message = '<p style="font-size:16px;">We’re celebrating <strong>25 million downloads</strong> of TablePress from the WordPress Plugin Directory!<br>Join us and <strong>get 25% off</strong> your TablePress Pro or TablePress Max upgrade!</p>'; | |
| 263 | + } | |
| 264 | + $url = 'https://tablepress.org/premium/?utm_source=plugin&utm_medium=notice&utm_campaign=upgrade-message340&utm_content=button'; | |
| 265 | + $message .= '<p style="margin-top:1em;margin-bottom:24px;">' . sprintf( '<a href="%s" class="components-button is-primary" target="_blank"><span>%s</span><span class="dashicons dashicons-arrow-right-alt" style="margin-inline:8px 0"></span></a>', $url, $texts_german ? 'Spare jetzt 25 %' : 'Get 25% off now' ) . '</p>'; | |
| 266 | + | |
| 267 | + $filename = $texts_german ? 'admin/img/dl-25-period.svg' : 'admin/img/dl-25-comma.svg'; | |
| 268 | + $message .= sprintf( '<img src="%1$s" alt="%2$s">', plugins_url( $filename, TABLEPRESS__FILE__ ), $texts_german ? 'Grafik mit einer Tabelle mit „Downloads“ in der Kopfzeile und der Zahl 25.000.000 im Tabellenkörper' : 'Graphic with a table with “Downloads” in the header and the number 25,000,000 in the body' ); | |
| 269 | + | |
| 270 | + $title = ''; | |
| 271 | + $class = 'notice-milestone not-dismissible'; | |
| 272 | + } | |
| 273 | + | |
| 274 | + $message .= '<p style="margin-top:1em;">' . $this->ajax_link( array( 'action' => 'hide_message', 'item' => 'plugin_update', 'return' => 'list' ), __( 'Hide this message', 'tablepress' ) ) . '</p>'; | |
| 275 | + | |
| 276 | + $this->add_header_message( $message, $class, $title ); | |
| 96 | 277 | } |
| 97 | 278 | |
| 98 | 279 | $this->process_action_messages( array( |
| 99 | - 'success_delete' => _n( 'The table was deleted successfully.', 'The tables were deleted successfully.', 1, 'tablepress' ), | |
| 100 | - 'success_delete_plural' => _n( 'The table was deleted successfully.', 'The tables were deleted successfully.', 2, 'tablepress' ), | |
| 101 | - 'error_delete' => __( 'Error: The table could not be deleted.', 'tablepress' ), | |
| 102 | - 'error_save' => __( 'Error: The table could not be saved.', 'tablepress' ), | |
| 103 | - 'success_copy' => _n( 'The table was copied successfully.', 'The tables were copied successfully.', 1, 'tablepress' ) . ( ( false !== $data['table_id'] ) ? ' ' . sprintf( __( 'The copied table has the table ID “%s”.', 'tablepress' ), esc_html( $data['table_id'] ) ) : '' ), | |
| 104 | - 'success_copy_plural' => _n( 'The table was copied successfully.', 'The tables were copied successfully.', 2, 'tablepress' ), | |
| 105 | - 'error_copy' => __( 'Error: The table could not be copied.', 'tablepress' ), | |
| 106 | - 'error_no_table' => __( 'Error: You did not specify a valid table ID.', 'tablepress' ), | |
| 107 | - 'error_load_table' => __( 'Error: This table could not be loaded!', 'tablepress' ), | |
| 108 | - 'error_bulk_action_invalid' => __( 'Error: This bulk action is invalid!', 'tablepress' ), | |
| 109 | - 'error_no_selection' => __( 'Error: You did not select any tables!', 'tablepress' ), | |
| 110 | - 'error_delete_not_all_tables' => __( 'Notice: Not all selected tables could be deleted!', 'tablepress' ), | |
| 111 | - 'error_copy_not_all_tables' => __( 'Notice: Not all selected tables could be copied!', 'tablepress' ), | |
| 112 | - 'success_import' => __( 'The tables were imported successfully.', 'tablepress' ), | |
| 113 | - 'success_import_wp_table_reloaded' => __( 'The tables were imported successfully from WP-Table Reloaded.', 'tablepress' ), | |
| 280 | + 'success_delete' => _n( 'The table was deleted successfully.', 'The tables were deleted successfully.', 1, 'tablepress' ), | |
| 281 | + 'success_delete_plural' => _n( 'The table was deleted successfully.', 'The tables were deleted successfully.', 2, 'tablepress' ), | |
| 282 | + 'error_delete' => __( 'Error: The table could not be deleted.', 'tablepress' ), | |
| 283 | + 'success_copy' => _n( 'The table was copied successfully.', 'The tables were copied successfully.', 1, 'tablepress' ) | |
| 284 | + . ( ( false !== $data['table_id'] ) | |
| 285 | + ? ' ' . ( current_user_can( 'tablepress_edit_table', $data['table_id'] ) | |
| 286 | + ? sprintf( __( 'You can now <a href="%1$s">edit the copied table</a>, which has the table ID “%2$s”.', 'tablepress' ), esc_url( TablePress::url( array( 'action' => 'edit', 'table_id' => $data['table_id'] ) ) ), esc_html( $data['table_id'] ) ) | |
| 287 | + : sprintf( __( 'The copied table has the table ID “%s”.', 'tablepress' ), esc_html( $data['table_id'] ) ) ) | |
| 288 | + : '' | |
| 289 | + ), | |
| 290 | + 'success_copy_plural' => _n( 'The table was copied successfully.', 'The tables were copied successfully.', 2, 'tablepress' ), | |
| 291 | + 'error_copy' => __( 'Error: The table could not be copied.', 'tablepress' ), | |
| 292 | + 'error_no_table' => __( 'Error: You did not specify a valid table ID.', 'tablepress' ), | |
| 293 | + 'error_load_table' => __( 'Error: This table could not be loaded!', 'tablepress' ), | |
| 294 | + 'error_bulk_action_invalid' => __( 'Error: This bulk action is invalid!', 'tablepress' ), | |
| 295 | + 'error_no_selection' => __( 'Error: You did not select any tables!', 'tablepress' ), | |
| 296 | + 'error_delete_not_all_tables' => __( 'Notice: Not all selected tables could be deleted!', 'tablepress' ), | |
| 297 | + 'error_copy_not_all_tables' => __( 'Notice: Not all selected tables could be copied!', 'tablepress' ), | |
| 298 | + 'success_import' => __( 'The tables were imported successfully.', 'tablepress' ), | |
| 114 | 299 | ) ); |
| 115 | 300 | |
| 116 | 301 | $this->add_text_box( 'head', array( $this, 'textbox_head' ), 'normal' ); |
| 117 | 302 | $this->add_text_box( 'tables-list', array( $this, 'textbox_tables_list' ), 'normal' ); |
| 118 | 303 | |
| 119 | - add_screen_option( 'per_page', array( 'label' => __( 'Tables', 'tablepress' ), 'default' => 20 ) ); // Admin_Controller contains function to allow changes to this in the Screen Options to be saved | |
| 120 | - $this->wp_list_table = new TablePress_All_Tables_List_Table(); | |
| 304 | + add_screen_option( 'per_page', array( 'label' => __( 'Tables', 'tablepress' ), 'default' => 20 ) ); // Admin_Controller contains function to allow changes to this in the Screen Options to be saved. | |
| 305 | + $this->wp_list_table = TablePress::load_class( 'TablePress_All_Tables_List_Table', 'class-all-tables-list-table.php', 'views' ); | |
| 121 | 306 | $this->wp_list_table->set_items( $this->data['table_ids'] ); |
| 122 | 307 | $this->wp_list_table->prepare_items(); |
| 123 | 308 | |
| 124 | 309 | // Cleanup Request URI string, which WP_List_Table uses to generate the sort URLs. |
| @@ -129,20 +314,26 @@ | ||
| 129 | 314 | * Render the current view (in this view: without form tag). |
| 130 | 315 | * |
| 131 | 316 | * @since 1.0.0 |
| 132 | 317 | */ |
| 133 | - public function render() { | |
| 318 | + #[\Override] | |
| 319 | + public function render(): void { | |
| 134 | 320 | ?> |
| 135 | 321 | <div id="tablepress-page" class="wrap"> |
| 136 | 322 | <?php |
| 137 | 323 | $this->print_nav_tab_menu(); |
| 138 | - // Print all header messages. | |
| 139 | - foreach ( $this->header_messages as $message ) { | |
| 140 | - echo $message; | |
| 141 | - } | |
| 324 | + ?> | |
| 325 | + <div id="tablepress-body"> | |
| 326 | + <hr class="wp-header-end"> | |
| 327 | + <script>document.querySelectorAll('.notice:has(~#tablepress-page)').forEach(e=>document.querySelector('.wp-header-end').after(e));</script> | |
| 328 | + <?php | |
| 329 | + // Print all header messages. | |
| 330 | + foreach ( $this->header_messages as $message ) { | |
| 331 | + echo $message; | |
| 332 | + } | |
| 142 | 333 | |
| 143 | - // For this screen, this is done in textbox_tables_list(), to get the fields into the correct <form>: | |
| 144 | - // $this->do_text_boxes( 'header' ); | |
| 334 | + // For this screen, this is done in textbox_tables_list(), to get the fields into the correct <form>: | |
| 335 | + // $this->do_text_boxes( 'header' );. | |
| 145 | 336 | ?> |
| 146 | 337 | <div id="poststuff"> |
| 147 | 338 | <div id="post-body" class="metabox-holder columns-<?php echo ( isset( $GLOBALS['screen_layout_columns'] ) && ( 2 === $GLOBALS['screen_layout_columns'] ) ) ? '2' : '1'; ?>"> |
| 148 | 339 | <div id="postbox-container-2" class="postbox-container"> |
| @@ -164,11 +355,12 @@ | ||
| 164 | 355 | $this->do_meta_boxes( 'side' ); |
| 165 | 356 | ?> |
| 166 | 357 | </div> |
| 167 | 358 | </div> |
| 168 | - <br class="clear" /> | |
| 359 | + <br class="clear"> | |
| 169 | 360 | </div> |
| 170 | 361 | </div> |
| 362 | + </div> | |
| 171 | 363 | <?php |
| 172 | 364 | } |
| 173 | 365 | |
| 174 | 366 | /** |
| @@ -175,25 +367,26 @@ | ||
| 175 | 367 | * Print the screen head text. |
| 176 | 368 | * |
| 177 | 369 | * @since 1.0.0 |
| 178 | 370 | * |
| 179 | - * @param array $data Data for this screen. | |
| 180 | - * @param array $box Information about the text box. | |
| 371 | + * @param array<string, mixed> $data Data for this screen. | |
| 372 | + * @param array<string, mixed> $box Information about the text box. | |
| 181 | 373 | */ |
| 182 | - public function textbox_head( array $data, array $box ) { | |
| 183 | - ?> | |
| 184 | - <p> | |
| 185 | - <?php _e( 'This is a list of your tables.', 'tablepress' ); ?> | |
| 186 | - <?php _e( 'Click the corresponding links within the list to edit, copy, delete, or preview a table.', 'tablepress' ); ?> | |
| 187 | - </p> | |
| 188 | - <p> | |
| 189 | - <label class="screen-reader-only" for="table-shortcode-inline"><?php esc_html_e( 'Shortcode text for editor', 'tablepress' ); ?></label> | |
| 190 | - | |
| 191 | - <?php printf( __( 'To insert a table into a page, post, or text widget, copy its Shortcode %s and paste it at the desired place in the editor.', 'tablepress' ), '<input type="text" class="table-shortcode table-shortcode-inline" id="table-shortcode-inline" value="' . esc_attr( '[' . TablePress::$shortcode . ' id=<ID> /]' ) . '" readonly="readonly" />' ); ?> | |
| 192 | - <?php _e( 'Each table has a unique ID that needs to be adjusted in that Shortcode.', 'tablepress' ); ?> | |
| 193 | - <?php printf( __( 'You can also click the “%s” button in the editor toolbar to select and insert a table.', 'tablepress' ), __( 'Table', 'tablepress' ) ); ?> | |
| 194 | - </p> | |
| 195 | - <?php | |
| 374 | + public function textbox_head( array $data, array $box ): void { | |
| 375 | + echo '<p>'; | |
| 376 | + _e( 'This is a list of your tables.', 'tablepress' ); | |
| 377 | + echo ' '; | |
| 378 | + // Show the instructions string depending on whether the Block Editor is used on the site or not. | |
| 379 | + if ( 'block' === $data['site_used_editor'] ) { | |
| 380 | + printf( __( 'To insert a table into a post or page, add a “%1$s” block in the block editor and select the desired table.', 'tablepress' ), __( 'TablePress table', 'tablepress' ) ); | |
| 381 | + } elseif ( 'elementor' === $data['site_used_editor'] ) { | |
| 382 | + printf( __( 'To insert a table into a post or page, add a “%1$s” widget in the Elementor editor and select the desired table.', 'tablepress' ), __( 'TablePress table', 'tablepress' ) ); | |
| 383 | + } else { | |
| 384 | + _e( 'To insert a table into a post or page, paste its Shortcode at the desired place in the editor.', 'tablepress' ); | |
| 385 | + echo ' '; | |
| 386 | + _e( 'Each table has a unique ID that needs to be adjusted in that Shortcode.', 'tablepress' ); | |
| 387 | + } | |
| 388 | + echo '</p>'; | |
| 196 | 389 | } |
| 197 | 390 | |
| 198 | 391 | /** |
| 199 | 392 | * Print the content of the "All Tables" text box. |
| @@ -199,32 +392,33 @@ | ||
| 199 | 392 | * Print the content of the "All Tables" text box. |
| 200 | 393 | * |
| 201 | 394 | * @since 1.0.0 |
| 202 | 395 | * |
| 203 | - * @param array $data Data for this screen. | |
| 204 | - * @param array $box Information about the text box. | |
| 396 | + * @param array<string, mixed> $data Data for this screen. | |
| 397 | + * @param array<string, mixed> $box Information about the text box. | |
| 205 | 398 | */ |
| 206 | - public function textbox_tables_list( array $data, array $box ) { | |
| 399 | + public function textbox_tables_list( array $data, array $box ): void { | |
| 207 | 400 | if ( ! empty( $_GET['s'] ) ) { |
| 208 | 401 | printf( '<span class="subtitle">' . __( 'Search results for “%s”', 'tablepress' ) . '</span>', esc_html( wp_unslash( $_GET['s'] ) ) ); |
| 209 | 402 | } |
| 210 | - ?> | |
| 211 | -<form method="get" action=""> | |
| 212 | - <?php | |
| 213 | - if ( isset( $_GET['page'] ) ) { | |
| 214 | - echo '<input type="hidden" name="page" value="' . esc_attr( $_GET['page'] ) . '" />' . "\n"; | |
| 215 | - } | |
| 216 | - $this->wp_list_table->search_box( __( 'Search Tables', 'tablepress' ), 'tables_search' ); | |
| 217 | - ?> | |
| 403 | + ?> | |
| 404 | +<form method="get"> | |
| 405 | + <?php | |
| 406 | + if ( isset( $_GET['page'] ) ) { | |
| 407 | + echo '<input type="hidden" name="page" value="' . esc_attr( $_GET['page'] ) . '">' . "\n"; | |
| 408 | + } | |
| 409 | + $this->wp_list_table->search_box( __( 'Search Tables', 'tablepress' ), 'tables_search' ); | |
| 410 | + ?> | |
| 218 | 411 | </form> |
| 219 | 412 | <form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post"> |
| 220 | - <?php | |
| 413 | + <?php | |
| 221 | 414 | // This prints the nonce and action fields for this screen (done here instead of render(), due to moved <form>). |
| 222 | 415 | $this->do_text_boxes( 'header' ); |
| 223 | 416 | $this->wp_list_table->display(); |
| 224 | - ?> | |
| 417 | + ?> | |
| 225 | 418 | </form> |
| 226 | - <?php | |
| 419 | +<div id="tablepress-list-screen"></div> | |
| 420 | + <?php | |
| 227 | 421 | } |
| 228 | 422 | |
| 229 | 423 | /** |
| 230 | 424 | * Create HTML code for an AJAXified link. |
| @@ -230,556 +424,21 @@ | ||
| 230 | 424 | * Create HTML code for an AJAXified link. |
| 231 | 425 | * |
| 232 | 426 | * @since 1.0.0 |
| 233 | 427 | * |
| 234 | - * @param array $params Parameters for the URL. | |
| 235 | - * @param string $text Text for the link. | |
| 428 | + * @param array<string, mixed> $params Parameters for the URL. | |
| 429 | + * @param string $text Text for the link. | |
| 236 | 430 | * @return string HTML code for the link. |
| 237 | 431 | */ |
| 238 | - protected function ajax_link( array $params = array( 'action' => 'list', 'item' => '' ), $text ) { | |
| 432 | + protected function ajax_link( array $params, string $text ): string { | |
| 433 | + $class = 'ajax-link'; | |
| 434 | + if ( ! empty( $params['class'] ) ) { | |
| 435 | + $class .= ' ' . esc_attr( $params['class'] ); | |
| 436 | + } | |
| 239 | 437 | $url = TablePress::url( $params, true, 'admin-post.php' ); |
| 240 | 438 | $action = esc_attr( $params['action'] ); |
| 241 | 439 | $item = esc_attr( $params['item'] ); |
| 242 | - $target = isset( $params['target'] ) ? esc_attr( $params['target'] ) : ''; | |
| 243 | - return "<a class=\"ajax-link\" href=\"{$url}\" data-action=\"{$action}\" data-item=\"{$item}\" data-target=\"{$target}\">{$text}</a>"; | |
| 440 | + $target = esc_attr( $params['target'] ?? '' ); | |
| 441 | + return "<a class=\"{$class}\" href=\"{$url}\" data-action=\"{$action}\" data-item=\"{$item}\" data-target=\"{$target}\">{$text}</a>"; | |
| 244 | 442 | } |
| 245 | 443 | |
| 246 | 444 | } // class TablePress_List_View |
| 247 | - | |
| 248 | -/** | |
| 249 | - * TablePress All Tables List Table Class | |
| 250 | - * @package TablePress | |
| 251 | - * @subpackage Views | |
| 252 | - * @author Tobias Bäthge | |
| 253 | - * @link https://codex.wordpress.org/Class_Reference/WP_List_Table | |
| 254 | - * @since 1.0.0 | |
| 255 | - */ | |
| 256 | -class TablePress_All_Tables_List_Table extends WP_List_Table { | |
| 257 | - | |
| 258 | - /** | |
| 259 | - * Number of items of the initial data set (before sort, search, and pagination). | |
| 260 | - * | |
| 261 | - * @since 1.0.0 | |
| 262 | - * @var int | |
| 263 | - */ | |
| 264 | - protected $items_count = 0; | |
| 265 | - | |
| 266 | - /** | |
| 267 | - * Initialize the List Table. | |
| 268 | - * | |
| 269 | - * @since 1.0.0 | |
| 270 | - */ | |
| 271 | - public function __construct() { | |
| 272 | - $screen = get_current_screen(); | |
| 273 | - | |
| 274 | - // Hide "Last Modified By" column by default. | |
| 275 | - if ( false === get_user_option( 'manage' . $screen->id . 'columnshidden' ) ) { | |
| 276 | - update_user_option( get_current_user_id(), 'manage' . $screen->id . 'columnshidden', array( 'table_last_modified_by' ), true ); | |
| 277 | - } | |
| 278 | - | |
| 279 | - parent::__construct( array( | |
| 280 | - 'singular' => 'tablepress-table', // Singular name of the listed records. | |
| 281 | - 'plural' => 'tablepress-all-tables', // Plural name of the listed records. | |
| 282 | - 'ajax' => false, // Does this list table support AJAX? | |
| 283 | - 'screen' => $screen, // WP_Screen object. | |
| 284 | - ) ); | |
| 285 | - } | |
| 286 | - | |
| 287 | - /** | |
| 288 | - * Set the data items (here: tables) that are to be displayed by the List Tables, and their original count. | |
| 289 | - * | |
| 290 | - * @since 1.0.0 | |
| 291 | - * | |
| 292 | - * @param array $items Tables to be displayed in the List Table. | |
| 293 | - */ | |
| 294 | - public function set_items( array $items ) { | |
| 295 | - $this->items = $items; | |
| 296 | - $this->items_count = count( $items ); | |
| 297 | - } | |
| 298 | - | |
| 299 | - /** | |
| 300 | - * Check whether the user has permissions for certain AJAX actions. | |
| 301 | - * (not used, but must be implemented in this child class) | |
| 302 | - * | |
| 303 | - * @since 1.0.0 | |
| 304 | - * | |
| 305 | - * @return bool true (Default value). | |
| 306 | - */ | |
| 307 | - public function ajax_user_can() { | |
| 308 | - return true; | |
| 309 | - } | |
| 310 | - | |
| 311 | - /** | |
| 312 | - * Get a list of columns in this List Table. | |
| 313 | - * | |
| 314 | - * Format: 'internal-name' => 'Column Title'. | |
| 315 | - * | |
| 316 | - * @since 1.0.0 | |
| 317 | - * | |
| 318 | - * @return array List of columns in this List Table. | |
| 319 | - */ | |
| 320 | - public function get_columns() { | |
| 321 | - $columns = array( | |
| 322 | - 'cb' => $this->has_items() ? '<input type="checkbox" />' : '', // Checkbox for "Select all", but only if there are items in the table. | |
| 323 | - // "name" is special in WP, which is why we prefix every entry here, to be safe! | |
| 324 | - 'table_id' => __( 'ID', 'tablepress' ), | |
| 325 | - 'table_name' => __( 'Table Name', 'tablepress' ), | |
| 326 | - 'table_description' => __( 'Description', 'tablepress' ), | |
| 327 | - 'table_author' => __( 'Author', 'tablepress' ), | |
| 328 | - 'table_last_modified_by' => __( 'Last Modified By', 'tablepress' ), | |
| 329 | - 'table_last_modified' => __( 'Last Modified', 'tablepress' ), | |
| 330 | - ); | |
| 331 | - return $columns; | |
| 332 | - } | |
| 333 | - | |
| 334 | - /** | |
| 335 | - * Get a list of columns that are sortable. | |
| 336 | - * | |
| 337 | - * Format: 'internal-name' => array( $field for $item[ $field ], true for already sorted ). | |
| 338 | - * | |
| 339 | - * @since 1.0.0 | |
| 340 | - * | |
| 341 | - * @return array List of sortable columns in this List Table. | |
| 342 | - */ | |
| 343 | - protected function get_sortable_columns() { | |
| 344 | - // No sorting on the Empty List placeholder. | |
| 345 | - if ( ! $this->has_items() ) { | |
| 346 | - return array(); | |
| 347 | - } | |
| 348 | - | |
| 349 | - $sortable_columns = array( | |
| 350 | - 'table_id' => array( 'id', true ), // true means its already sorted | |
| 351 | - 'table_name' => array( 'name', false ), | |
| 352 | - 'table_description' => array( 'description', false ), | |
| 353 | - 'table_author' => array( 'author', false ), | |
| 354 | - 'table_last_modified_by' => array( 'last_modified_by', false ), | |
| 355 | - 'table_last_modified' => array( 'last_modified', false ), | |
| 356 | - ); | |
| 357 | - return $sortable_columns; | |
| 358 | - } | |
| 359 | - | |
| 360 | - /** | |
| 361 | - * Gets the name of the default primary column. | |
| 362 | - * | |
| 363 | - * @since 1.7.0 | |
| 364 | - * | |
| 365 | - * @return string Name of the default primary column, in this case, the table name. | |
| 366 | - */ | |
| 367 | - protected function get_default_primary_column_name() { | |
| 368 | - return 'table_name'; | |
| 369 | - } | |
| 370 | - | |
| 371 | - /** | |
| 372 | - * Render a cell in the "cb" column. | |
| 373 | - * | |
| 374 | - * @since 1.0.0 | |
| 375 | - * | |
| 376 | - * @param array $item Data item for the current row. | |
| 377 | - * @return string HTML content of the cell. | |
| 378 | - */ | |
| 379 | - protected function column_cb( /* array */ $item ) { // No `array` type hint to prevent a Strict Standards notice, as the method is inherited. | |
| 380 | - $user_can_copy_table = current_user_can( 'tablepress_copy_table', $item['id'] ); | |
| 381 | - $user_can_delete_table = current_user_can( 'tablepress_delete_table', $item['id'] ); | |
| 382 | - $user_can_export_table = current_user_can( 'tablepress_export_table', $item['id'] ); | |
| 383 | - | |
| 384 | - if ( $user_can_copy_table || $user_can_delete_table || $user_can_export_table ) { | |
| 385 | - return sprintf( | |
| 386 | - '<label><span class="screen-reader-text">%1$s</span><input type="checkbox" name="table[]" value="%2$s" /></label>', | |
| 387 | - esc_html__( 'Bulk action selector', 'tablepress' ), | |
| 388 | - esc_attr( $item['id'] ) | |
| 389 | - ); | |
| 390 | - } else { | |
| 391 | - return ''; | |
| 392 | - } | |
| 393 | - } | |
| 394 | - | |
| 395 | - /** | |
| 396 | - * Render a cell in the "table_id" column. | |
| 397 | - * | |
| 398 | - * @since 1.0.0 | |
| 399 | - * | |
| 400 | - * @param array $item Data item for the current row. | |
| 401 | - * @return string HTML content of the cell. | |
| 402 | - */ | |
| 403 | - protected function column_table_id( array $item ) { | |
| 404 | - return esc_html( $item['id'] ); | |
| 405 | - } | |
| 406 | - | |
| 407 | - /** | |
| 408 | - * Render a cell in the "table_name" column. | |
| 409 | - * | |
| 410 | - * @since 1.0.0 | |
| 411 | - * | |
| 412 | - * @param array $item Data item for the current row. | |
| 413 | - * @return string HTML content of the cell. | |
| 414 | - */ | |
| 415 | - protected function column_table_name( array $item ) { | |
| 416 | - $user_can_edit_table = current_user_can( 'tablepress_edit_table', $item['id'] ); | |
| 417 | - $user_can_copy_table = current_user_can( 'tablepress_copy_table', $item['id'] ); | |
| 418 | - $user_can_export_table = current_user_can( 'tablepress_export_table', $item['id'] ); | |
| 419 | - $user_can_delete_table = current_user_can( 'tablepress_delete_table', $item['id'] ); | |
| 420 | - $user_can_preview_table = current_user_can( 'tablepress_preview_table', $item['id'] ); | |
| 421 | - | |
| 422 | - $edit_url = TablePress::url( array( 'action' => 'edit', 'table_id' => $item['id'] ) ); | |
| 423 | - $copy_url = TablePress::url( array( 'action' => 'copy_table', 'item' => $item['id'], 'return' => 'list', 'return_item' => $item['id'] ), true, 'admin-post.php' ); | |
| 424 | - $export_url = TablePress::url( array( 'action' => 'export', 'table_id' => $item['id'] ) ); | |
| 425 | - $delete_url = TablePress::url( array( 'action' => 'delete_table', 'item' => $item['id'], 'return' => 'list', 'return_item' => $item['id'] ), true, 'admin-post.php' ); | |
| 426 | - $preview_url = TablePress::url( array( 'action' => 'preview_table', 'item' => $item['id'], 'return' => 'list', 'return_item' => $item['id'] ), true, 'admin-post.php' ); | |
| 427 | - | |
| 428 | - if ( '' === trim( $item['name'] ) ) { | |
| 429 | - $item['name'] = __( '(no name)', 'tablepress' ); | |
| 430 | - } | |
| 431 | - | |
| 432 | - if ( $user_can_edit_table ) { | |
| 433 | - $row_text = '<strong><a title="' . esc_attr( sprintf( __( 'Edit “%s”', 'tablepress' ), esc_attr( $item['name'] ) ) ) . '" class="row-title" href="' . $edit_url . '">' . esc_html( $item['name'] ) . '</a></strong>'; | |
| 434 | - } else { | |
| 435 | - $row_text = '<strong>' . esc_html( $item['name'] ) . '</strong>'; | |
| 436 | - } | |
| 437 | - | |
| 438 | - $row_actions = array(); | |
| 439 | - if ( $user_can_edit_table ) { | |
| 440 | - $row_actions['edit'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $edit_url, esc_attr( sprintf( __( 'Edit “%s”', 'tablepress' ), $item['name'] ) ), __( 'Edit', 'tablepress' ) ); | |
| 441 | - } | |
| 442 | - $row_actions['shortcode hide-if-no-js'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', '#', esc_attr( '[' . TablePress::$shortcode . " id={$item['id']} /]" ), __( 'Show Shortcode', 'tablepress' ) ); | |
| 443 | - if ( $user_can_copy_table ) { | |
| 444 | - $row_actions['copy'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $copy_url, esc_attr( sprintf( __( 'Copy “%s”', 'tablepress' ), $item['name'] ) ), __( 'Copy', 'tablepress' ) ); | |
| 445 | - } | |
| 446 | - if ( $user_can_export_table ) { | |
| 447 | - $row_actions['export'] = sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', $export_url, esc_attr( sprintf( __( 'Export “%s”', 'tablepress' ), $item['name'] ) ), _x( 'Export', 'row action', 'tablepress' ) ); | |
| 448 | - } | |
| 449 | - if ( $user_can_delete_table ) { | |
| 450 | - $row_actions['delete'] = sprintf( '<a href="%1$s" title="%2$s" class="delete-link">%3$s</a>', $delete_url, esc_attr( sprintf( __( 'Delete “%s”', 'tablepress' ), $item['name'] ) ), __( 'Delete', 'tablepress' ) ); | |
| 451 | - } | |
| 452 | - if ( $user_can_preview_table ) { | |
| 453 | - $row_actions['table-preview'] = sprintf( '<a href="%1$s" title="%2$s" target="_blank">%3$s</a>', $preview_url, esc_attr( sprintf( __( 'Show a preview of “%s”', 'tablepress' ), $item['name'] ) ), __( 'Preview', 'tablepress' ) ); | |
| 454 | - } | |
| 455 | - | |
| 456 | - return $row_text . $this->row_actions( $row_actions ); | |
| 457 | - } | |
| 458 | - | |
| 459 | - /** | |
| 460 | - * Render a cell in the "table_description" column. | |
| 461 | - * | |
| 462 | - * @since 1.0.0 | |
| 463 | - * | |
| 464 | - * @param array $item Data item for the current row. | |
| 465 | - * @return string HTML content of the cell. | |
| 466 | - */ | |
| 467 | - protected function column_table_description( array $item ) { | |
| 468 | - if ( '' === trim( $item['description'] ) ) { | |
| 469 | - $item['description'] = __( '(no description)', 'tablepress' ); | |
| 470 | - } | |
| 471 | - return esc_html( $item['description'] ); | |
| 472 | - } | |
| 473 | - | |
| 474 | - /** | |
| 475 | - * Render a cell in the "table_author" column. | |
| 476 | - * | |
| 477 | - * @since 1.0.0 | |
| 478 | - * | |
| 479 | - * @param array $item Data item for the current row. | |
| 480 | - * @return string HTML content of the cell. | |
| 481 | - */ | |
| 482 | - protected function column_table_author( array $item ) { | |
| 483 | - return TablePress::get_user_display_name( $item['author'] ); | |
| 484 | - } | |
| 485 | - | |
| 486 | - /** | |
| 487 | - * Render a cell in the "last_modified_by" column. | |
| 488 | - * | |
| 489 | - * @since 1.0.0 | |
| 490 | - * | |
| 491 | - * @param array $item Data item for the current row. | |
| 492 | - * @return string HTML content of the cell. | |
| 493 | - */ | |
| 494 | - protected function column_table_last_modified_by( array $item ) { | |
| 495 | - return TablePress::get_user_display_name( $item['options']['last_editor'] ); | |
| 496 | - } | |
| 497 | - | |
| 498 | - /** | |
| 499 | - * Render a cell in the "table_last_modified" column. | |
| 500 | - * | |
| 501 | - * @since 1.0.0 | |
| 502 | - * | |
| 503 | - * @param array $item Data item for the current row. | |
| 504 | - * @return string HTML content of the cell. | |
| 505 | - */ | |
| 506 | - protected function column_table_last_modified( array $item ) { | |
| 507 | - $modified_timestamp = strtotime( $item['last_modified'] ); | |
| 508 | - $current_timestamp = current_time( 'timestamp' ); | |
| 509 | - $time_diff = $current_timestamp - $modified_timestamp; | |
| 510 | - // Time difference is only shown up to one day. | |
| 511 | - if ( $time_diff >= 0 && $time_diff < DAY_IN_SECONDS ) { | |
| 512 | - $time_diff = sprintf( __( '%s ago', 'tablepress' ), human_time_diff( $modified_timestamp, $current_timestamp ) ); | |
| 513 | - } else { | |
| 514 | - $time_diff = TablePress::format_datetime( $item['last_modified'], 'mysql', '<br />' ); | |
| 515 | - } | |
| 516 | - | |
| 517 | - $readable_time = TablePress::format_datetime( $item['last_modified'], 'mysql', ' ' ); | |
| 518 | - return '<abbr title="' . esc_attr( $readable_time ) . '">' . $time_diff . '</abbr>'; | |
| 519 | - } | |
| 520 | - | |
| 521 | - /** | |
| 522 | - * Handles output for the default column. | |
| 523 | - * | |
| 524 | - * @since 1.8.0 | |
| 525 | - * | |
| 526 | - * @param array $item Data item for the current row. | |
| 527 | - * @param string $column_name Current column name. | |
| 528 | - */ | |
| 529 | - protected function column_default( /* array */ $item, $column_name ) { // No `array` type hint to prevent a Strict Standards notice, as the method is inherited. | |
| 530 | - /** | |
| 531 | - * Fires inside each custom column of the TablePress list table. | |
| 532 | - * | |
| 533 | - * @since 1.8.0 | |
| 534 | - * | |
| 535 | - * @param array $column_name Current column name. | |
| 536 | - * @param string $item Data item for the current row. | |
| 537 | - */ | |
| 538 | - do_action( 'manage_tablepress_list_custom_column', $column_name, $item ); | |
| 539 | - } | |
| 540 | - | |
| 541 | - /** | |
| 542 | - * Get a list (name => title) bulk actions that are available. | |
| 543 | - * | |
| 544 | - * @since 1.0.0 | |
| 545 | - * | |
| 546 | - * @return array Bulk actions for this table. | |
| 547 | - */ | |
| 548 | - protected function get_bulk_actions() { | |
| 549 | - $bulk_actions = array(); | |
| 550 | - | |
| 551 | - if ( current_user_can( 'tablepress_copy_tables' ) ) { | |
| 552 | - $bulk_actions['copy'] = _x( 'Copy', 'bulk action', 'tablepress' ); | |
| 553 | - } | |
| 554 | - if ( current_user_can( 'tablepress_export_tables' ) ) { | |
| 555 | - $bulk_actions['export'] = _x( 'Export', 'bulk action', 'tablepress' ); | |
| 556 | - } | |
| 557 | - if ( current_user_can( 'tablepress_delete_tables' ) ) { | |
| 558 | - $bulk_actions['delete'] = _x( 'Delete', 'bulk action', 'tablepress' ); | |
| 559 | - } | |
| 560 | - | |
| 561 | - return $bulk_actions; | |
| 562 | - } | |
| 563 | - | |
| 564 | - /** | |
| 565 | - * Render the bulk actions dropdown. | |
| 566 | - * | |
| 567 | - * In comparison with parent class, this has modified HTML (especially no field named "action" as that's being used already)! | |
| 568 | - * | |
| 569 | - * @since 1.0.0 | |
| 570 | - * | |
| 571 | - * @param string $which The location of the bulk actions: 'top' or 'bottom'. | |
| 572 | - * This is designated as optional for backwards-compatibility. | |
| 573 | - */ | |
| 574 | - protected function bulk_actions( $which = '' ) { | |
| 575 | - if ( is_null( $this->_actions ) ) { | |
| 576 | - $no_new_actions = $this->_actions = $this->get_bulk_actions(); | |
| 577 | - /** This filter is documented in the WordPress function WP_List_Table::bulk_actions() in wp-admin/includes/class-wp-list-table.php */ | |
| 578 | - $this->_actions = apply_filters( 'bulk_actions-' . $this->screen->id, $this->_actions ); | |
| 579 | - $this->_actions = array_intersect_assoc( $this->_actions, $no_new_actions ); | |
| 580 | - $two = ''; | |
| 581 | - } else { | |
| 582 | - $two = '2'; | |
| 583 | - } | |
| 584 | - | |
| 585 | - if ( empty( $this->_actions ) ) { | |
| 586 | - return; | |
| 587 | - } | |
| 588 | - | |
| 589 | - $name_id = "bulk-action-{$which}"; | |
| 590 | - echo "<label for='{$name_id}' class='screen-reader-text'>" . __( 'Select Bulk Action', 'tablepress' ) . "</label>\n"; | |
| 591 | - echo "<select name='{$name_id}' id='{$name_id}'>\n"; | |
| 592 | - echo "<option value='-1' selected='selected'>" . __( 'Bulk Actions', 'tablepress' ) . "</option>\n"; | |
| 593 | - foreach ( $this->_actions as $name => $title ) { | |
| 594 | - echo "\t<option value='{$name}'>{$title}</option>\n"; | |
| 595 | - } | |
| 596 | - echo "</select>\n"; | |
| 597 | - submit_button( __( 'Apply', 'tablepress' ), 'action', '', false, array( 'id' => "doaction{$two}" ) ); | |
| 598 | - echo "\n"; | |
| 599 | - } | |
| 600 | - | |
| 601 | - /** | |
| 602 | - * Holds the message to be displayed when there are no items in the table. | |
| 603 | - * | |
| 604 | - * @since 1.0.0 | |
| 605 | - */ | |
| 606 | - public function no_items() { | |
| 607 | - _e( 'No tables found.', 'tablepress' ); | |
| 608 | - if ( 0 === $this->items_count ) { | |
| 609 | - $user_can_add_tables = current_user_can( 'tablepress_add_tables' ); | |
| 610 | - $user_can_import_tables = current_user_can( 'tablepress_import_tables' ); | |
| 611 | - | |
| 612 | - $add_url = TablePress::url( array( 'action' => 'add' ) ); | |
| 613 | - $import_url = TablePress::url( array( 'action' => 'import' ) ); | |
| 614 | - | |
| 615 | - if ( $user_can_add_tables && $user_can_import_tables ) { | |
| 616 | - echo ' ' . sprintf( __( 'You should <a href="%1$s">add</a> or <a href="%2$s">import</a> a table to get started!', 'tablepress' ), $add_url, $import_url ); | |
| 617 | - } elseif ( $user_can_add_tables ) { | |
| 618 | - echo ' ' . sprintf( __( 'You should <a href="%s">add</a> a table to get started!', 'tablepress' ), $add_url ); | |
| 619 | - } elseif ( $user_can_import_tables ) { | |
| 620 | - echo ' ' . sprintf( __( 'You should <a href="%s">import</a> a table to get started!', 'tablepress' ), $import_url ); | |
| 621 | - } | |
| 622 | - } | |
| 623 | - } | |
| 624 | - | |
| 625 | - /** | |
| 626 | - * Generate the elements above or below the table (like bulk actions and pagination). | |
| 627 | - * | |
| 628 | - * In comparison with parent class, this has modified HTML (no nonce field), and a check whether there are items. | |
| 629 | - * | |
| 630 | - * @since 1.0.0 | |
| 631 | - * | |
| 632 | - * @param string $which Location ("top" or "bottom"). | |
| 633 | - */ | |
| 634 | - protected function display_tablenav( $which ) { | |
| 635 | - if ( ! $this->has_items() ) { | |
| 636 | - return; | |
| 637 | - } | |
| 638 | - ?> | |
| 639 | - <div class="tablenav <?php echo esc_attr( $which ); ?>"> | |
| 640 | - <div class="alignleft actions"> | |
| 641 | - <?php $this->bulk_actions( $which ); ?> | |
| 642 | - </div> | |
| 643 | - <?php | |
| 644 | - $this->extra_tablenav( $which ); | |
| 645 | - $this->pagination( $which ); | |
| 646 | - ?> | |
| 647 | - <br class="clear" /> | |
| 648 | - </div> | |
| 649 | - <?php | |
| 650 | - } | |
| 651 | - | |
| 652 | - /** | |
| 653 | - * Callback to determine whether the given $item contains the search term. | |
| 654 | - * | |
| 655 | - * @since 1.0.0 | |
| 656 | - * | |
| 657 | - * @param string $item Table ID that shall be searched. | |
| 658 | - * @return bool Whether the search term was found or not. | |
| 659 | - */ | |
| 660 | - protected function _search_callback( $item ) { | |
| 661 | - static $term, $json_encoded_term; | |
| 662 | - if ( is_null( $term ) || is_null( $json_encoded_term ) ) { | |
| 663 | - $term = wp_unslash( $_GET['s'] ); | |
| 664 | - $json_encoded_term = substr( wp_json_encode( $term, TABLEPRESS_JSON_OPTIONS ), 1, -1 ); | |
| 665 | - } | |
| 666 | - | |
| 667 | - static $debug; | |
| 668 | - if ( is_null( $debug ) ) { | |
| 669 | - // Set debug variable to allow searching in corrupted tables. | |
| 670 | - $debug = isset( $_GET['debug'] ) ? ( 'true' === $_GET['debug'] ) : WP_DEBUG; | |
| 671 | - } | |
| 672 | - | |
| 673 | - // load table again, with data and options (for last_editor). | |
| 674 | - $item = TablePress::$model_table->load( $item, true, true ); | |
| 675 | - | |
| 676 | - // Don't search corrupted tables, except when debug mode is enabled via $_GET parameter or WP_DEBUG constant. | |
| 677 | - if ( ! $debug && isset( $item['is_corrupted'] ) && $item['is_corrupted'] ) { | |
| 678 | - return false; | |
| 679 | - } | |
| 680 | - | |
| 681 | - // Search from easy to hard, so that "expensive" code maybe doesn't have to run. | |
| 682 | - if ( false !== stripos( $item['id'], $term ) | |
| 683 | - || false !== stripos( $item['name'], $term ) | |
| 684 | - || false !== stripos( $item['description'], $term ) | |
| 685 | - || false !== stripos( TablePress::get_user_display_name( $item['author'] ), $term ) | |
| 686 | - || false !== stripos( TablePress::get_user_display_name( $item['options']['last_editor'] ), $term ) | |
| 687 | - || false !== stripos( TablePress::format_datetime( $item['last_modified'], 'mysql', ' ' ), $term ) | |
| 688 | - || false !== stripos( wp_json_encode( $item['data'], TABLEPRESS_JSON_OPTIONS ), $json_encoded_term ) ) { | |
| 689 | - return true; | |
| 690 | - } | |
| 691 | - | |
| 692 | - return false; | |
| 693 | - } | |
| 694 | - | |
| 695 | - /** | |
| 696 | - * Callback to for the array sort function. | |
| 697 | - * | |
| 698 | - * @since 1.0.0 | |
| 699 | - * | |
| 700 | - * @param array $item_a First item that shall be compared to. | |
| 701 | - * @param array $item_b The second item for the comparison. | |
| 702 | - * @return int (-1, 0, 1) depending on which item sorts "higher". | |
| 703 | - */ | |
| 704 | - protected function _order_callback( array $item_a, array $item_b ) { | |
| 705 | - global $orderby, $order; | |
| 706 | - | |
| 707 | - if ( 'last_modified_by' !== $orderby ) { | |
| 708 | - if ( $item_a[ $orderby ] === $item_b[ $orderby ] ) { | |
| 709 | - return 0; | |
| 710 | - } | |
| 711 | - } else { | |
| 712 | - if ( $item_a['options']['last_editor'] === $item_b['options']['last_editor'] ) { | |
| 713 | - return 0; | |
| 714 | - } | |
| 715 | - } | |
| 716 | - | |
| 717 | - // Certain fields require some extra work before being sortable. | |
| 718 | - switch ( $orderby ) { | |
| 719 | - case 'last_modified': | |
| 720 | - // Compare UNIX timestamps for "last modified", which actually is a mySQL datetime string. | |
| 721 | - $result = ( strtotime( $item_a['last_modified'] ) > strtotime( $item_b['last_modified'] ) ) ? 1 : -1; | |
| 722 | - break; | |
| 723 | - case 'author': | |
| 724 | - // Get the actual author name, plain value is just the user ID. | |
| 725 | - $result = strnatcasecmp( TablePress::get_user_display_name( $item_a['author'] ), TablePress::get_user_display_name( $item_b['author'] ) ); | |
| 726 | - break; | |
| 727 | - case 'last_modified_by': | |
| 728 | - // Get the actual last editor name, plain value is just the user ID. | |
| 729 | - $result = strnatcasecmp( TablePress::get_user_display_name( $item_a['options']['last_editor'] ), TablePress::get_user_display_name( $item_b['options']['last_editor'] ) ); | |
| 730 | - break; | |
| 731 | - default: | |
| 732 | - // Other fields (ID, name, description) are sorted as strings. | |
| 733 | - $result = strnatcasecmp( $item_a[ $orderby ], $item_b[ $orderby ] ); | |
| 734 | - } | |
| 735 | - | |
| 736 | - return ( 'asc' === $order ) ? $result : - $result; | |
| 737 | - } | |
| 738 | - | |
| 739 | - /** | |
| 740 | - * Prepares the list of items for displaying, by maybe searching and sorting, and by doing pagination. | |
| 741 | - * | |
| 742 | - * @since 1.0.0 | |
| 743 | - */ | |
| 744 | - public function prepare_items() { | |
| 745 | - global $orderby, $order, $s; | |
| 746 | - wp_reset_vars( array( 'orderby', 'order', 's' ) ); | |
| 747 | - | |
| 748 | - // Maybe search in the items. | |
| 749 | - if ( $s ) { | |
| 750 | - $this->items = array_filter( $this->items, array( $this, '_search_callback' ) ); | |
| 751 | - } | |
| 752 | - | |
| 753 | - // Load actual tables after search for less memory consumption. | |
| 754 | - foreach ( $this->items as &$item ) { | |
| 755 | - // Don't load data, but load table options for access to last_editor. | |
| 756 | - $item = TablePress::$model_table->load( $item, false, true ); | |
| 757 | - } | |
| 758 | - // Break reference in foreach iterator. | |
| 759 | - unset( $item ); | |
| 760 | - | |
| 761 | - // Maybe sort the items. | |
| 762 | - $_sortable_columns = $this->get_sortable_columns(); | |
| 763 | - if ( $orderby && ! empty( $this->items ) && isset( $_sortable_columns[ "table_{$orderby}" ] ) ) { | |
| 764 | - usort( $this->items, array( $this, '_order_callback' ) ); | |
| 765 | - } | |
| 766 | - | |
| 767 | - // Number of records to show per page. | |
| 768 | - $per_page = $this->get_items_per_page( 'tablepress_list_per_page', 20 ); // hard-coded, as in filter in Admin_Controller | |
| 769 | - // Page number the user is currently viewing. | |
| 770 | - $current_page = $this->get_pagenum(); | |
| 771 | - // Number of records in the array. | |
| 772 | - $total_items = count( $this->items ); | |
| 773 | - | |
| 774 | - // Slice items array to hold only items for the current page. | |
| 775 | - $this->items = array_slice( $this->items, ( ( $current_page - 1 ) * $per_page ), $per_page ); | |
| 776 | - | |
| 777 | - // Register pagination options and calculation results. | |
| 778 | - $this->set_pagination_args( array( | |
| 779 | - 'total_items' => $total_items, // Total number of records/items | |
| 780 | - 'per_page' => $per_page, // Number of items per page | |
| 781 | - 'total_pages' => ceil( $total_items / $per_page ), // Total number of pages | |
| 782 | - ) ); | |
| 783 | - } | |
| 784 | - | |
| 785 | -} // class TablePress_All_Tables_List_Table | |