PluginProbe
TablePress – Tables in WordPress made easy / 3.2
TablePress – Tables in WordPress made easy v3.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-view.php +175 -96 2.0.43.2 View file →
@@ -24,51 +24,48 @@
24 24 /**
25 25 * Data for the view.
26 26 *
27 27 * @since 1.0.0
28 - * @var array
28 + * @var array<string, mixed>
29 29 */
30 - protected $data = array();
30 + protected array $data = array();
31 31
32 32 /**
33 33 * Number of screen columns for post boxes.
34 34 *
35 35 * @since 1.0.0
36 - * @var int
37 36 */
38 - protected $screen_columns = 0;
37 + protected int $screen_columns = 0;
39 38
40 39 /**
41 40 * User action for this screen.
42 41 *
43 42 * @since 1.0.0
44 - * @var string
45 43 */
46 - protected $action = '';
44 + protected string $action = '';
47 45
48 46 /**
49 47 * Instance of the Admin Page Helper Class, with necessary functions.
50 48 *
51 49 * @since 1.0.0
52 - * @var TablePress_Admin_Page
53 50 */
54 - protected $admin_page;
51 + protected \TablePress_Admin_Page $admin_page;
55 52
56 53 /**
57 54 * List of text boxes (similar to post boxes, but just with text and without extra functionality).
58 55 *
59 56 * @since 1.0.0
60 - * @var array
57 + * @var array<string, array<string, array<string, mixed>>>
61 58 */
62 - protected $textboxes = array();
59 + protected array $textboxes = array();
63 60
64 61 /**
65 62 * List of messages that are to be displayed as boxes below the page title.
66 63 *
67 64 * @since 1.0.0
68 - * @var array
65 + * @var string[]
69 66 */
70 - protected $header_messages = array();
67 + protected array $header_messages = array();
71 68
72 69 /**
73 70 * Whether there are post boxes registered for this screen,
74 71 * is automatically set to true, when a meta box is added.
@@ -73,22 +70,21 @@
73 70 * Whether there are post boxes registered for this screen,
74 71 * is automatically set to true, when a meta box is added.
75 72 *
76 73 * @since 1.0.0
77 - * @var bool
78 74 */
79 - protected $has_meta_boxes = false;
75 + protected bool $has_meta_boxes = false;
80 76
81 77 /**
82 78 * List of WP feature pointers for this view.
83 79 *
84 80 * @since 1.0.0
85 - * @var array
81 + * @var string[]
86 82 */
87 - protected $wp_pointers = array();
83 + protected array $wp_pointers = array();
88 84
89 85 /**
90 - * Initialize the View class, by setting the correct screen columns and adding help texts.
86 + * Initializes the View class, by setting the correct screen columns and adding help texts.
91 87 *
92 88 * @since 1.0.0
93 89 */
94 90 public function __construct() {
@@ -93,29 +89,36 @@
93 89 */
94 90 public function __construct() {
95 91 $screen = get_current_screen();
96 92 if ( 0 !== $this->screen_columns ) {
97 - $screen->add_option( 'layout_columns', array( 'max' => $this->screen_columns ) );
93 + $screen->add_option( 'layout_columns', array( 'max' => $this->screen_columns ) ); // @phpstan-ignore method.nonObject
98 94 }
99 95 // Enable two column layout.
100 - add_filter( "get_user_option_screen_layout_{$screen->id}", array( $this, 'set_current_screen_layout_columns' ) );
96 + add_filter( "get_user_option_screen_layout_{$screen->id}", array( $this, 'set_current_screen_layout_columns' ) ); // @phpstan-ignore property.nonObject
101 97
98 + /* translators: %1$s: URL to TablePress website, %2$s: URL to WordPress Plugin Directory */
102 99 $common_content = '<p>' . sprintf( __( 'More information about TablePress can be found on the <a href="%1$s">plugin website</a> or on its page in the <a href="%2$s">WordPress Plugin Directory</a>.', 'tablepress' ), 'https://tablepress.org/', 'https://wordpress.org/plugins/tablepress/' ) . '</p>';
103 - $common_content .= '<p>' . sprintf( __( 'For technical information, please see the <a href="%s">Documentation</a>.', 'tablepress' ), 'https://tablepress.org/documentation/' ) . ' ' . sprintf( __( 'Common questions are answered in the <a href="%s">FAQ</a>.', 'tablepress' ), 'https://tablepress.org/faq/' ) . '</p>';
100 + /* translators: %s: URL to Documentation page */
101 + $common_content .= '<p>' . sprintf( __( 'For technical information, please see the <a href="%s">Documentation</a>.', 'tablepress' ), 'https://tablepress.org/documentation/' ) . ' ';
102 + /* translators: %s: URL to FAQ page */
103 + $common_content .= sprintf( __( 'Common questions are answered in the <a href="%s">FAQ</a>.', 'tablepress' ), 'https://tablepress.org/faq/' ) . '</p>';
104 104
105 105 if ( tb_tp_fs()->is_free_plan() ) {
106 - $common_content .= '<p>' . sprintf( __( '<a href="%1$s">Support</a> is provided through the <a href="%2$s">WordPress Support Forums</a>.', 'tablepress' ), 'https://tablepress.org/support/', 'https://wordpress.org/tags/tablepress' ) . ' '
107 - . sprintf( __( 'Before asking for support, please carefully read the <a href="%s">Frequently Asked Questions</a>, where you will find answers to the most common questions, and search through the forums.', 'tablepress' ), 'https://tablepress.org/faq/' ) . '</p>';
108 - $common_content .= '<p><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/' ) . '</strong></p>';
106 + $common_content .= '<p>'
107 + . sprintf( __( '<a href="%1$s">Support</a> is provided through the <a href="%2$s">WordPress Support Forums</a>.', 'tablepress' ), 'https://tablepress.org/support/', 'https://wordpress.org/tags/tablepress' )
108 + . ' '
109 + . sprintf( __( 'Before asking for support, please carefully read the <a href="%s">Frequently Asked Questions</a>, where you will find answers to the most common questions, and search through the forums.', 'tablepress' ), 'https://tablepress.org/faq/' )
110 + . '</p>';
111 + $common_content .= '<p><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=help-tab' ) . '</strong></p>';
109 112 }
110 113
111 - $screen->add_help_tab( array(
114 + $screen->add_help_tab( array( // @phpstan-ignore method.nonObject
112 115 'id' => 'tablepress-help', // This should be unique for the screen.
113 116 'title' => __( 'TablePress Help', 'tablepress' ),
114 117 'content' => '<p>' . $this->help_tab_content() . '</p>' . $common_content,
115 118 ) );
116 119 // "Sidebar" in the help tab.
117 - $screen->set_help_sidebar(
120 + $screen->set_help_sidebar( // @phpstan-ignore method.nonObject
118 121 '<p><strong>' . __( 'For more information:', 'tablepress' ) . '</strong></p>'
119 122 . '<p><a href="https://tablepress.org/">TablePress Website</a></p>'
120 123 . '<p><a href="https://tablepress.org/faq/">TablePress FAQ</a></p>'
121 124 . '<p><a href="https://tablepress.org/documentation/">TablePress Documentation</a></p>'
@@ -123,9 +126,9 @@
123 126 );
124 127 }
125 128
126 129 /**
127 - * Change the value of the user option "screen_layout_{$screen->id}" through a filter.
130 + * Changes the value of the user option "screen_layout_{$screen->id}" through a filter.
128 131 *
129 132 * @since 1.0.0
130 133 *
131 134 * @param int|false $result Current value of the user option.
@@ -130,9 +133,9 @@
130 133 *
131 134 * @param int|false $result Current value of the user option.
132 135 * @return int New value for the user option.
133 136 */
134 - public function set_current_screen_layout_columns( $result ) {
137 + public function set_current_screen_layout_columns( /* int|false */ $result ): int {
135 138 if ( false === $result ) {
136 139 // The user option does not yet exist.
137 140 $result = $this->screen_columns;
138 141 } elseif ( $result > $this->screen_columns ) {
@@ -142,30 +145,32 @@
142 145 return $result;
143 146 }
144 147
145 148 /**
146 - * Set up the view with data and do things that are necessary for all views.
149 + * Sets up the view with data and do things that are necessary for all views.
147 150 *
148 151 * @since 1.0.0
149 152 *
150 - * @param string $action Action for this view.
151 - * @param array $data Data for this view.
153 + * @param string $action Action for this view.
154 + * @param array<string, mixed> $data Data for this view.
152 155 */
153 - public function setup( $action, array $data ) {
156 + public function setup( /* string */ $action, array $data ) /* : void */ {
157 + // Don't use type hints (except array $data) in method declaration, as the method is extended in some TablePress Extensions which are no longer updated.
158 +
154 159 $this->action = $action;
155 160 $this->data = $data;
156 161
157 162 // Set page title.
158 - $GLOBALS['title'] = sprintf( __( '%1$s &lsaquo; %2$s', 'tablepress' ), $this->data['view_actions'][ $this->action ]['page_title'], 'TablePress' );
163 + $GLOBALS['title'] = sprintf( __( '%1$s &lsaquo; %2$s', 'tablepress' ), $this->data['view_actions'][ $this->action ]['page_title'], 'TablePress' ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
159 164
160 165 // Admin page helpers, like script/style loading, could be moved to view.
161 166 $this->admin_page = TablePress::load_class( 'TablePress_Admin_Page', 'class-admin-page-helper.php', 'classes' );
162 - $this->admin_page->enqueue_style( 'common' );
167 + $this->admin_page->enqueue_style( 'common', array( 'wp-components' ) );
163 168 // RTL styles for the admin interface.
164 169 if ( is_rtl() ) {
165 170 $this->admin_page->enqueue_style( 'common-rtl', array( 'tablepress-common' ) );
166 171 }
167 - $this->admin_page->enqueue_script( 'common', array( 'postbox' ) );
172 + $this->admin_page->enqueue_script( 'common', array( 'jquery-core', 'postbox' ) );
168 173
169 174 $this->admin_page->add_admin_footer_text();
170 175
171 176 // Initialize WP feature pointers for TablePress.
@@ -177,9 +182,9 @@
177 182 $this->add_text_box( 'action_field', array( $this, 'action_field' ), 'header', false );
178 183 }
179 184
180 185 /**
181 - * Register a header message for the view.
186 + * Registers a header message for the view.
182 187 *
183 188 * @since 1.0.0
184 189 *
185 190 * @param string $text Text for the header message.
@@ -185,10 +190,10 @@
185 190 * @param string $text Text for the header message.
186 191 * @param string $css_class Optional. Additional CSS class for the header message.
187 192 * @param string $title Optional. Text for the header title.
188 193 */
189 - protected function add_header_message( $text, $css_class = 'notice-success', $title = '' ) {
190 - if ( ! strpos( $css_class, 'not-dismissible' ) ) {
194 + protected function add_header_message( string $text, string $css_class = 'is-success', string $title = '' ): void {
195 + if ( ! str_contains( $css_class, 'not-dismissible' ) ) {
191 196 $css_class .= ' is-dismissible';
192 197 }
193 198 if ( '' !== $title ) {
194 199 $title = "<h3>{$title}</h3>";
@@ -193,24 +198,24 @@
193 198 if ( '' !== $title ) {
194 199 $title = "<h3>{$title}</h3>";
195 200 }
196 201 // Wrap the message text in HTML <p> tags if it does not already start with one (potentially with attributes), indicating custom message HTML.
197 - if ( '' !== $text && 0 !== strpos( $text, '<p' ) ) {
202 + if ( '' !== $text && ! str_starts_with( $text, '<p' ) ) {
198 203 $text = "<p>{$text}</p>";
199 204 }
200 - $this->header_messages[] = "<div class=\"notice {$css_class}\">{$title}{$text}</div>\n";
205 + $this->header_messages[] = "<div class=\"notice components-notice {$css_class}\"><div class=\"components-notice__content\">{$title}{$text}</div></div>\n";
201 206 }
202 207
203 208 /**
204 - * Process header action messages, i.e. check if a message should be added to the page.
209 + * Processes header action messages, i.e. check if a message should be added to the page.
205 210 *
206 211 * @since 1.0.0
207 212 *
208 - * @param array $action_messages Action messages for the screen.
213 + * @param array<string, string> $action_messages Action messages for the screen.
209 214 */
210 - protected function process_action_messages( array $action_messages ) {
215 + protected function process_action_messages( array $action_messages ): void {
211 216 if ( $this->data['message'] && isset( $action_messages[ $this->data['message'] ] ) ) {
212 - $class = ( 0 === strpos( $this->data['message'], 'error' ) ) ? 'notice-error' : 'notice-success';
217 + $class = ( str_starts_with( $this->data['message'], 'error' ) ) ? 'is-error' : 'is-success';
213 218
214 219 if ( '' !== $this->data['error_details'] ) {
215 220 $this->data['error_details'] = '</p><p>' . sprintf( __( 'Error code: %s', 'tablepress' ), '<code>' . esc_html( $this->data['error_details'] ) . '</code>' );
216 221 }
@@ -219,18 +224,18 @@
219 224 }
220 225 }
221 226
222 227 /**
223 - * Register a text box for the view.
228 + * Registers a text box for the view.
224 229 *
225 230 * @since 1.0.0
226 231 *
227 232 * @param string $id Unique HTML ID for the text box container (only visible with $wrap = true).
228 - * @param callback $callback Callback that prints the contents of the text box.
233 + * @param callable $callback Callback that prints the contents of the text box.
229 234 * @param string $context Optional. Context/position of the text box (normal, side, additional, header, submit).
230 235 * @param bool $wrap Whether the content of the text box shall be wrapped in a <div> container.
231 236 */
232 - protected function add_text_box( $id, $callback, $context = 'normal', $wrap = false ) {
237 + protected function add_text_box( string $id, callable $callback, string $context = 'normal', bool $wrap = false ): void {
233 238 if ( ! isset( $this->textboxes[ $context ] ) ) {
234 239 $this->textboxes[ $context ] = array();
235 240 }
236 241
@@ -243,32 +248,32 @@
243 248 );
244 249 }
245 250
246 251 /**
247 - * Register a post meta box for the view, that is drag/droppable with WordPress functionality.
252 + * Registers a post meta box for the view, that is drag/droppable with WordPress functionality.
248 253 *
249 254 * @since 1.0.0
250 255 *
251 - * @param string $id Unique ID for the meta box.
252 - * @param string $title Title for the meta box.
253 - * @param callback $callback Callback that prints the contents of the post meta box.
254 - * @param string $context Optional. Context/position of the post meta box (normal, side, additional).
255 - * @param string $priority Optional. Order of the post meta box for the $context position (high, default, low).
256 - * @param array $callback_args Optional. Additional data for the callback function (e.g. useful when in different class).
256 + * @param string $id Unique ID for the meta box.
257 + * @param string $title Title for the meta box.
258 + * @param callable $callback Callback that prints the contents of the post meta box.
259 + * @param 'normal'|'side'|'additional' $context Optional. Context/position of the post meta box (normal, side, additional).
260 + * @param 'core'|'default'|'high'|'low' $priority Optional. Order of the post meta box for the $context position (high, default, low).
261 + * @param mixed[]|null $callback_args Optional. Additional data for the callback function (e.g. useful when in different class).
257 262 */
258 - protected function add_meta_box( $id, $title, $callback, $context = 'normal', $priority = 'default', $callback_args = null ) {
263 + protected function add_meta_box( string $id, string $title, callable $callback, string $context = 'normal', string $priority = 'default', ?array $callback_args = null ): void {
259 264 $this->has_meta_boxes = true;
260 265 add_meta_box( "tablepress_{$this->action}-{$id}", $title, $callback, null, $context, $priority, $callback_args );
261 266 }
262 267
263 268 /**
264 - * Render all text boxes for the given context.
269 + * Renders all text boxes for the given context.
265 270 *
266 271 * @since 1.0.0
267 272 *
268 273 * @param string $context Context (normal, side, additional, header, submit) for which registered text boxes shall be rendered.
269 274 */
270 - protected function do_text_boxes( $context ) {
275 + protected function do_text_boxes( string $context ): void {
271 276 if ( empty( $this->textboxes[ $context ] ) ) {
272 277 return;
273 278 }
274 279
@@ -283,32 +288,31 @@
283 288 }
284 289 }
285 290
286 291 /**
287 - * Render all post meta boxes for the given context, if there are post meta boxes.
292 + * Renders all post meta boxes for the given context, if there are post meta boxes.
288 293 *
289 294 * @since 1.0.0
290 295 *
291 296 * @param string $context Context (normal, side, additional) for which registered post meta boxes shall be rendered.
292 297 */
293 - protected function do_meta_boxes( $context ) {
294 - if ( ! $this->has_meta_boxes ) {
295 - return;
298 + protected function do_meta_boxes( string $context ): void {
299 + if ( $this->has_meta_boxes ) {
300 + do_meta_boxes( get_current_screen(), $context, $this->data ); // @phpstan-ignore argument.type
296 301 }
297 - do_meta_boxes( null, $context, $this->data );
298 302 }
299 303
300 304 /**
301 - * Print hidden fields with nonces for post meta box AJAX handling, if there are post meta boxes on the screen.
305 + * Prints hidden fields with nonces for post meta box AJAX handling, if there are post meta boxes on the screen.
302 306 *
303 307 * The check is possible as this function is executed after post meta boxes have to be registered.
304 308 *
305 309 * @since 1.0.0
306 310 *
307 - * @param array $data Data for this screen.
308 - * @param array $box Information about the text box.
311 + * @param array<string, mixed> $data Data for this screen.
312 + * @param array<string, mixed> $box Information about the text box.
309 313 */
310 - protected function default_nonce_fields( array $data, array $box ) {
314 + protected function default_nonce_fields( array $data, array $box ): void {
311 315 if ( ! $this->has_meta_boxes ) {
312 316 return;
313 317 }
314 318 wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
@@ -317,38 +321,38 @@
317 321 echo "\n";
318 322 }
319 323
320 324 /**
321 - * Print hidden field with a nonce for the screen's action, to be transmitted in HTTP requests.
325 + * Prints hidden field with a nonce for the screen's action, to be transmitted in HTTP requests.
322 326 *
323 327 * @since 1.0.0
324 328 *
325 - * @param array $data Data for this screen.
326 - * @param array $box Information about the text box.
329 + * @param array<string, mixed> $data Data for this screen.
330 + * @param array<string, mixed> $box Information about the text box.
327 331 */
328 - protected function action_nonce_field( array $data, array $box ) {
332 + protected function action_nonce_field( array $data, array $box ): void {
329 333 wp_nonce_field( TablePress::nonce( $this->action ) );
330 334 echo "\n";
331 335 }
332 336
333 337 /**
334 - * Print hidden field with the screen action.
338 + * Prints hidden field with the screen action.
335 339 *
336 340 * @since 1.0.0
337 341 *
338 - * @param array $data Data for this screen.
339 - * @param array $box Information about the text box.
342 + * @param array<string, mixed> $data Data for this screen.
343 + * @param array<string, mixed> $box Information about the text box.
340 344 */
341 - protected function action_field( array $data, array $box ) {
342 - echo "<input type=\"hidden\" name=\"action\" value=\"tablepress_{$this->action}\" />\n";
345 + protected function action_field( array $data, array $box ): void {
346 + echo "<input type=\"hidden\" name=\"action\" value=\"tablepress_{$this->action}\">\n";
343 347 }
344 348
345 349 /**
346 - * Render the current view.
350 + * Renders the current view.
347 351 *
348 352 * @since 1.0.0
349 353 */
350 - public function render() {
354 + public function render(): void {
351 355 ?>
352 356 <div id="tablepress-page" class="wrap">
353 357 <?php
354 358 $this->print_nav_tab_menu();
@@ -353,9 +357,9 @@
353 357 <?php
354 358 $this->print_nav_tab_menu();
355 359 ?>
356 360 <div id="tablepress-body">
357 - <hr class="wp-header-end" />
361 + <hr class="wp-header-end">
358 362 <?php
359 363 // Print all header messages.
360 364 foreach ( $this->header_messages as $message ) {
361 365 echo $message;
@@ -362,13 +366,14 @@
362 366 }
363 367 // "Import" screen has file upload.
364 368 $enctype = ( 'import' === $this->action ) ? ' enctype="multipart/form-data"' : '';
365 369 ?>
366 - <form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post"<?php echo $enctype; ?>>
370 + <form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post"<?php echo $enctype; ?> id="tablepress-page-form">
367 371 <?php
368 372 $this->do_text_boxes( 'header' );
373 + $hide_if_no_js = ( in_array( $this->action, array( 'export', 'import' ), true ) ) ? ' class="hide-if-no-js"' : '';
369 374 ?>
370 - <div id="poststuff">
375 + <div id="poststuff"<?php echo $hide_if_no_js; ?>>
371 376 <div id="post-body" class="metabox-holder columns-<?php echo ( isset( $GLOBALS['screen_layout_columns'] ) && ( 2 === $GLOBALS['screen_layout_columns'] ) ) ? '2' : '1'; ?>">
372 377 <div id="postbox-container-2" class="postbox-container">
373 378 <?php
374 379 $this->do_text_boxes( 'normal' );
@@ -388,9 +393,9 @@
388 393 $this->do_meta_boxes( 'side' );
389 394 ?>
390 395 </div>
391 396 </div>
392 - <br class="clear" />
397 + <br class="clear">
393 398 </div>
394 399 </form>
395 400 </div>
396 401 </div>
@@ -397,19 +402,24 @@
397 402 <?php
398 403 }
399 404
400 405 /**
401 - * Render the navigation menu with links to the possible actions, highlighting the current one.
406 + * Renders the navigation menu with links to the possible actions, highlighting the current one.
402 407 *
403 408 * @since 1.0.0
404 409 */
405 - protected function print_nav_tab_menu() {
410 + protected function print_nav_tab_menu(): void {
411 + $name = __( 'TablePress', 'tablepress' );
412 + $filename = 'admin/img/tablepress.svg';
406 413 ?>
407 414 <div id="tablepress-header" class="header">
408 - <h1 class="name"><img src="<?php echo plugins_url( 'admin/img/tablepress-icon.png', TABLEPRESS__FILE__ ); ?>" class="tablepress-icon" alt="<?php esc_attr_e( 'TablePress plugin logo', 'tablepress' ); ?>" /><?php _e( 'TablePress', 'tablepress' ); ?><?php echo tb_tp_fs()->is_plan_or_trial( 'pro', true ) ? ' Pro' : ( tb_tp_fs()->is_plan_or_trial( 'max', true ) ? ' Max' : '' ); ?></h1>
409 - <?php if ( tb_tp_fs()->is_free_plan() ) : ?>
415 + <h1 class="name">
416 + <img src="<?php echo plugins_url( $filename, TABLEPRESS__FILE__ ); ?>" alt="<?php esc_attr_e( 'TablePress plugin logo', 'tablepress' ); ?>">
417 + <span class="screen-reader-text"><?php echo $name; ?></span>
418 + </h1>
419 + <?php if ( ! TABLEPRESS_IS_PLAYGROUND_PREVIEW && tb_tp_fs()->is_free_plan() ) : ?>
410 420 <div class="buttons">
411 - <a href="<?php echo 'https://tablepress.org/premium/'; ?>" class="tablepress-button">
421 + <a href="<?php echo esc_url( tb_tp_fs()->pricing_url( WP_FS__PERIOD_ANNUALLY, false ) ); ?>" class="tablepress-button">
412 422 <span><?php _e( 'Upgrade to Premium', 'tablepress' ); ?></span>
413 423 <span class="dashicons dashicons-arrow-right-alt"></span>
414 424 </a>
415 425 </div>
@@ -437,40 +447,109 @@
437 447 <?php
438 448 }
439 449
440 450 /**
441 - * Print a submit button (only done when function is used as a callback for a text box).
451 + * Prints a notification about JavaScript not being activated in the browser.
442 452 *
453 + * @since 2.0.0
454 + *
455 + * @param array<string, mixed> $data Data for this screen.
456 + * @param array<string, mixed> $box Information about the text box.
457 + */
458 + public function textbox_no_javascript( array $data, array $box ): void {
459 + ?>
460 + <div class="notice components-notice is-error hide-if-js">
461 + <div class="components-notice__content">
462 + <h3><em>
463 + <?php _e( 'Attention: Unfortunately, there is a problem!', 'tablepress' ); ?>
464 + </em></h3>
465 + <p style="font-size:14px">
466 + <strong><?php _e( 'This screen requires JavaScript. Please enable JavaScript in your browser settings.', 'tablepress' ); ?></strong><br>
467 + <?php _e( 'For help, please follow <a href="https://www.enable-javascript.com/">the instructions on how to enable JavaScript in your browser</a>.', 'tablepress' ); ?>
468 + </p>
469 + <p>
470 + <?php echo '<a href="' . esc_url( TablePress::url( array( 'action' => 'list' ) ) ) . '">' . __( 'Back to the List of Tables', 'tablepress' ) . '</a>'; ?>
471 + </p>
472 + </div>
473 + </div>
474 + <?php
475 + }
476 +
477 + /**
478 + * Prints a submit button (only done when function is used as a callback for a text box).
479 + *
480 + * This method is soft-deprecated. It's no longer used in TablePress, but e.g. in the "TablePress Debug Extension".
481 + *
443 482 * @since 1.0.0
444 483 *
445 - * @param array $data Data for this screen.
446 - * @param array $box Information about the text box.
484 + * @param array<string, mixed> $data Data for this screen.
485 + * @param array<string, mixed> $box Information about the text box.
447 486 */
448 - protected function textbox_submit_button( array $data, array $box ) {
449 - $caption = isset( $data['submit_button_caption'] ) ? $data['submit_button_caption'] : __( 'Save Changes', 'tablepress' );
487 + protected function textbox_submit_button( array $data, array $box ): void {
450 488 ?>
451 - <p class="submit"><input type="submit" value="<?php echo esc_attr( $caption ); ?>" class="button button-primary button-large" /></p>
489 + <p class="submit"><input type="submit" class="components-button is-primary button-save-changes" value="<?php esc_attr_e( 'Save Changes', 'tablepress' ); ?>"></p>
452 490 <?php
453 491 }
454 492
455 493 /**
456 - * Return the content for the help tab for this screen.
494 + * Returns a safe JSON representation of a variable for printing inside of JavaScript code.
457 495 *
496 + * @since 2.0.0
497 + *
498 + * @param mixed $data Variable to convert to JSON.
499 + * @return string Safe JSON representation of a variable for printing inside of JavaScript code.
500 + */
501 + public function convert_to_json_parse_output( /* string|array|bool|int|float|null */ $data ): string {
502 + $json = wp_json_encode( $data, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES );
503 + if ( false === $json ) {
504 + // JSON encoding failed, return an error object. Use a prefixed "_error" key to avoid conflicts with intentionally added "error" keys.
505 + $json = '{ "_error": "The data could not be encoded to JSON!" }';
506 + }
507 + // Print the JSON data inside a `JSON.parse()` call in JS for speed gains, with necessary escaping of `\` and `'`.
508 + $json = str_replace( array( '\\', "'" ), array( '\\\\', "\'" ), $json );
509 + return "JSON.parse( '{$json}' )";
510 + }
511 +
512 + /**
513 + * Prints JavaScript variables for the screen.
514 + *
515 + * @since 3.1.0
516 + *
517 + * @param string $variable Name of the JavaScript variable.
518 + * @param array<string, mixed> $data Information about the text box.
519 + */
520 + protected function print_script_data_json( string $variable, array $data ): void {
521 + echo "<script>\n";
522 + echo "window.tp = window.tp || {};\n";
523 + echo "tp.{$variable} = {\n";
524 + foreach ( $data as $key => $value ) {
525 + $value = $this->convert_to_json_parse_output( $value );
526 + echo "\t{$key}: {$value},\n";
527 + }
528 + echo "};\n";
529 + echo "</script>\n";
530 + }
531 +
532 + /**
533 + * Returns the content for the help tab for this screen.
534 + *
458 535 * Has to be implemented for every view that is visible in the WP Dashboard!
459 536 *
460 537 * @since 1.0.0
538 + *
539 + * @return string Help tab content for the view.
461 540 */
462 - protected function help_tab_content() {
541 + protected function help_tab_content(): string {
463 542 // Has to be implemented for every view that is visible in the WP Dashboard!
464 543 return '';
465 544 }
466 545
467 546 /**
468 - * Initialize the WP feature pointers for TablePress.
547 + * Initializes the WP feature pointers for TablePress.
469 548 *
470 549 * @since 1.0.0
471 550 */
472 - protected function _init_wp_pointers() {
551 + protected function _init_wp_pointers(): void {
473 552 // Check if there are WP pointers for this view.
474 553 if ( empty( $this->wp_pointers ) ) {
475 554 return;
476 555 }
@@ -480,9 +559,9 @@
480 559
481 560 $pointers_on_page = false;
482 561 foreach ( array_diff( $this->wp_pointers, $dismissed ) as $pointer ) {
483 562 // Bind pointer print function.
484 - add_action( "admin_footer-{$GLOBALS['hook_suffix']}", array( $this, 'wp_pointer_' . $pointer ) );
563 + add_action( "admin_footer-{$GLOBALS['hook_suffix']}", array( $this, 'wp_pointer_' . $pointer ) ); // @phpstan-ignore argument.type
485 564 $pointers_on_page = true;
486 565 }
487 566
488 567 if ( $pointers_on_page ) {