PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
← All changes | controllers/controller-admin_ajax.php +56 -37 2.1.7 → 3.4 View file →
@@ -7,8 +7,10 @@
7 7 * @author Tobias Bäthge
8 8 * @since 1.0.0
9 9 */
10 10
11 +declare(strict_types=1);
12 +
11 13 // Prohibit direct script loading.
12 14 defined( 'ABSPATH' ) || die( 'No direct script access allowed!' );
13 15
14 16 /**
@@ -42,9 +44,9 @@
42 44 * Hides a header message on an admin screen.
43 45 *
44 46 * @since 1.0.0
45 47 */
46 - public function ajax_action_hide_message() {
48 + public function ajax_action_hide_message(): void {
47 49 if ( empty( $_GET['item'] ) ) {
48 50 wp_die( '0' );
49 51 }
50 52
@@ -65,9 +67,9 @@
65 67 * Saves the table after the "Save Changes" button on the "Edit" screen has been clicked.
66 68 *
67 69 * @since 1.0.0
68 70 */
69 - public function ajax_action_save_table() {
71 + public function ajax_action_save_table(): void {
70 72 if ( empty( $_POST['tablepress']['id'] ) ) {
71 73 wp_die( '-1' );
72 74 }
73 75
@@ -84,12 +86,12 @@
84 86 // Default response data.
85 87 $success = false;
86 88 $message = 'error_save';
87 89 $error_details = '';
88 - do { // to be able to "break;" (allows for better readable code)
90 + do { // To be able to "break;" (allows for better readable code).
89 91 // Load table, without table data, but with options and visibility settings.
90 92 $existing_table = TablePress::$model_table->load( $edit_table['id'], false, true );
91 - if ( is_wp_error( $existing_table ) ) { // maybe somehow load a new table here? (TablePress::$model_table->get_table_template())?
93 + if ( is_wp_error( $existing_table ) ) {
92 94 $error = new WP_Error( 'ajax_save_table_load', '', $edit_table['id'] );
93 95 $error->merge_from( $existing_table );
94 96 $error_details = TablePress::get_wp_error_string( $error );
95 97 break;
@@ -94,19 +96,24 @@
94 96 $error_details = TablePress::get_wp_error_string( $error );
95 97 break;
96 98 }
97 99
98 - // Check and convert data that was transmitted as JSON.
99 - if ( empty( $edit_table['data'] )
100 - || empty( $edit_table['options'] )
101 - || empty( $edit_table['visibility'] ) ) {
102 - $error = new WP_Error( 'ajax_save_table_data_empty', '', $edit_table['id'] );
103 - $error_details = TablePress::get_wp_error_string( $error );
104 - break;
100 + // Check and convert all data that was transmitted as valid JSON.
101 + $keys = array( 'data', 'options', 'visibility' );
102 + foreach ( $keys as $key ) {
103 + if ( empty( $edit_table[ $key ] ) ) {
104 + $error = new WP_Error( "ajax_save_table_{$key}_empty", '', $edit_table['id'] );
105 + $error_details = TablePress::get_wp_error_string( $error );
106 + break 2;
107 + }
108 + $edit_table[ $key ] = json_decode( $edit_table[ $key ], true );
109 + if ( is_null( $edit_table[ $key ] ) ) {
110 + $error = new WP_Error( "ajax_save_table_{$key}_invalid_json", '', $edit_table['id'] );
111 + $error_details = TablePress::get_wp_error_string( $error );
112 + break 2;
113 + }
114 + $edit_table[ $key ] = (array) $edit_table[ $key ]; // Cast to array again, to catch strings, etc.
105 115 }
106 - $edit_table['data'] = (array) json_decode( $edit_table['data'], true );
107 - $edit_table['options'] = (array) json_decode( $edit_table['options'], true );
108 - $edit_table['visibility'] = (array) json_decode( $edit_table['visibility'], true );
109 116
110 117 // Check consistency of new table, and then merge with existing table.
111 118 $table = TablePress::$model_table->prepare_table( $existing_table, $edit_table, true );
112 119 if ( is_wp_error( $table ) ) {
@@ -165,13 +172,16 @@
165 172 'success' => $success,
166 173 'message' => $message,
167 174 );
168 175 if ( $success ) {
169 - $response['table_id'] = $table['id'];
170 - $response['new_edit_nonce'] = wp_create_nonce( TablePress::nonce( 'edit', $table['id'] ) );
171 - $response['new_preview_nonce'] = wp_create_nonce( TablePress::nonce( 'preview_table', $table['id'] ) );
172 - $response['last_modified'] = TablePress::format_datetime( $table['last_modified'] );
173 - $response['last_editor'] = TablePress::get_user_display_name( $table['options']['last_editor'] );
176 + // For the phpstan ignores in the next lines: If this is reached, $table is guaranteed to exist and is a valid array.
177 + $response['table_id'] = $table['id']; // @phpstan-ignore offsetAccess.nonOffsetAccessible, variable.undefined
178 + $response['new_edit_nonce'] = wp_create_nonce( TablePress::nonce( 'edit', $table['id'] ) ); // @phpstan-ignore offsetAccess.nonOffsetAccessible, variable.undefined
179 + $response['new_preview_nonce'] = wp_create_nonce( TablePress::nonce( 'preview_table', $table['id'] ) ); // @phpstan-ignore offsetAccess.nonOffsetAccessible, variable.undefined
180 + $response['new_copy_nonce'] = wp_create_nonce( TablePress::nonce( 'copy_table', $table['id'] ) ); // @phpstan-ignore offsetAccess.nonOffsetAccessible, variable.undefined
181 + $response['new_delete_nonce'] = wp_create_nonce( TablePress::nonce( 'delete_table', $table['id'] ) ); // @phpstan-ignore offsetAccess.nonOffsetAccessible, variable.undefined
182 + $response['last_modified'] = TablePress::format_datetime( $table['last_modified'] ); // @phpstan-ignore offsetAccess.nonOffsetAccessible, variable.undefined
183 + $response['last_editor'] = TablePress::get_user_display_name( $table['options']['last_editor'] ); // @phpstan-ignore offsetAccess.nonOffsetAccessible, variable.undefined
174 184 }
175 185 if ( ! empty( $error_details ) ) {
176 186 $response['error_details'] = esc_html( $error_details );
177 187 }
@@ -189,9 +199,9 @@
189 199 * Returns the live preview data of table that has non-saved changes.
190 200 *
191 201 * @since 1.0.0
192 202 */
193 - public function ajax_action_preview_table() {
203 + public function ajax_action_preview_table(): void {
194 204 if ( empty( $_POST['tablepress']['id'] ) ) {
195 205 wp_die( '-1' );
196 206 }
197 207
@@ -206,24 +216,27 @@
206 216 }
207 217
208 218 // Default response data.
209 219 $success = false;
210 - do { // to be able to "break;" (allows for better readable code)
220 + do { // To be able to "break;" (allows for better readable code).
211 221 // Load table, without table data, but with options and visibility settings.
212 222 $existing_table = TablePress::$model_table->load( $preview_table['id'], false, true );
213 - if ( is_wp_error( $existing_table ) ) { // maybe somehow load a new table here? (TablePress::$model_table->get_table_template())?
223 + if ( is_wp_error( $existing_table ) ) {
214 224 break;
215 225 }
216 226
217 - // Check and convert data that was transmitted as JSON.
218 - if ( empty( $preview_table['data'] )
219 - || empty( $preview_table['options'] )
220 - || empty( $preview_table['visibility'] ) ) {
221 - break;
227 + // Check and convert all data that was transmitted as valid JSON.
228 + $keys = array( 'data', 'options', 'visibility' );
229 + foreach ( $keys as $key ) {
230 + if ( empty( $preview_table[ $key ] ) ) {
231 + break 2;
232 + }
233 + $preview_table[ $key ] = json_decode( $preview_table[ $key ], true );
234 + if ( is_null( $preview_table[ $key ] ) ) {
235 + break 2;
236 + }
237 + $preview_table[ $key ] = (array) $preview_table[ $key ]; // Cast to array again, to catch strings, etc.
222 238 }
223 - $preview_table['data'] = (array) json_decode( $preview_table['data'], true );
224 - $preview_table['options'] = (array) json_decode( $preview_table['options'], true );
225 - $preview_table['visibility'] = (array) json_decode( $preview_table['visibility'], true );
226 239
227 240 // Check consistency of new table, and then merge with existing table.
228 241 $table = TablePress::$model_table->prepare_table( $existing_table, $preview_table, true );
229 242 if ( is_wp_error( $table ) ) {
@@ -255,13 +268,15 @@
255 268 // Merge desired options with default render options (see TablePress_Controller_Frontend::shortcode_table()).
256 269 $default_render_options = $_render->get_default_render_options();
257 270 /** This filter is documented in controllers/controller-frontend.php */
258 271 $default_render_options = apply_filters( 'tablepress_shortcode_table_default_shortcode_atts', $default_render_options );
259 - $render_options = shortcode_atts( $default_render_options, $table['options'] );
272 + // For the phpstan ignores in the next lines: If this is reached, $table is guaranteed to exist and is a valid array.
273 + $render_options = shortcode_atts( $default_render_options, $table['options'] ); // @phpstan-ignore offsetAccess.nonOffsetAccessible, variable.undefined
260 274 /** This filter is documented in controllers/controller-frontend.php */
261 275 $render_options = apply_filters( 'tablepress_shortcode_table_shortcode_atts', $render_options );
262 - $render_options['html_id'] = "tablepress-{$table['id']}";
263 - $_render->set_input( $table, $render_options );
276 + $render_options['html_id'] = "tablepress-{$table['id']}"; // @phpstan-ignore offsetAccess.nonOffsetAccessible, variable.undefined
277 + $render_options['block_preview'] = true;
278 + $_render->set_input( $table, $render_options ); // @phpstan-ignore variable.undefined
264 279 $head_html = $_render->get_preview_css();
265 280 $custom_css = TablePress::$model_options->get( 'custom_css' );
266 281 $use_custom_css = ( TablePress::$model_options->get( 'use_custom_css' ) && '' !== $custom_css );
267 282 if ( $use_custom_css ) {
@@ -270,17 +285,21 @@
270 285
271 286 $body_html = '<div id="tablepress-page"><p>'
272 287 . __( 'This is a preview of your table.', 'tablepress' ) . ' '
273 288 . __( 'Because of CSS styling in your theme, the table might look different on your page!', 'tablepress' ) . ' '
274 - . __( 'The Table Features for Site Visitors, like sorting, filtering, and pagination, are also not available in this preview!', 'tablepress' ) . '<br />';
289 + . __( 'The Table Features for Site Visitors, like sorting, filtering, and pagination, are also not available in this preview!', 'tablepress' ) . '<br>';
275 290 // Show the instructions string depending on whether the Block Editor is used on the site or not.
276 - if ( TablePress::site_uses_block_editor() ) {
291 + if ( 'block' === TablePress::site_used_editor() ) {
292 + /* translators: %1$s: Block name */
277 293 $body_html .= sprintf( __( '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' ) );
294 + } elseif ( 'elementor' === TablePress::site_used_editor() ) {
295 + /* translators: %1$s: Widget name */
296 + $body_html .= sprintf( __( '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' ) );
278 297 } else {
279 298 $body_html .= __( 'To insert a table into a post or page, paste its Shortcode at the desired place in the editor.', 'tablepress' ) . ' '
280 299 . __( 'Each table has a unique ID that needs to be adjusted in that Shortcode.', 'tablepress' );
281 300 }
282 - $body_html .= '</p>' . $_render->get_output() . '</div>';
301 + $body_html .= '</p><div class="preview">' . $_render->get_output( 'html' ) . '</div></div>';
283 302 } else {
284 303 $head_html = '';
285 304 $body_html = __( 'The preview could not be loaded.', 'tablepress' );
286 305 }
@@ -305,9 +324,9 @@
305 324 * Saves the screen options on the "Edit" screen when they are changed.
306 325 *
307 326 * @since 2.1.0
308 327 */
309 - public function ajax_action_save_screen_options() {
328 + public function ajax_action_save_screen_options(): void {
310 329 // Check if the submitted nonce matches the generated nonce we created earlier, dies -1 on failure.
311 330 TablePress::check_nonce( 'screen_options', false, '_ajax_nonce', true );
312 331
313 332 if ( empty( $_POST['tablepress'] ) ) {