PluginProbe
TablePress – Tables in WordPress made easy / 1.14
TablePress – Tables in WordPress made easy v1.14
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
tablepress / views / view-edit.php

view-edit.php in TablePress – Tables in WordPress made easy 1.14, at views/view-edit.php

701 lines 41.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Edit Table View
4 *
5 * @package TablePress
6 * @subpackage Views
7 * @author Tobias Bäthge
8 * @since 1.0.0
9 */
10
11 // Prohibit direct script loading.
12 defined( 'ABSPATH' ) || die( 'No direct script access allowed!' );
13
14 /**
15 * Edit Table View class
16 * @package TablePress
17 * @subpackage Views
18 * @author Tobias Bäthge
19 * @since 1.0.0
20 */
21 class TablePress_Edit_View extends TablePress_View {
22
23 /**
24 * List of WP feature pointers for this view.
25 *
26 * @since 1.0.0
27 * @var array
28 */
29 protected $wp_pointers = array( 'tp09_edit_drag_drop_sort' );
30
31 /**
32 * Set up the view with data and do things that are specific for this view.
33 *
34 * @since 1.0.0
35 *
36 * @param string $action Action for this view.
37 * @param array $data Data for this view.
38 */
39 public function setup( $action, array $data ) {
40 parent::setup( $action, $data );
41
42 if ( isset( $data['table']['is_corrupted'] ) && $data['table']['is_corrupted'] ) {
43 $this->add_text_box( 'table-corrupted', array( $this, 'textbox_corrupted_table' ), 'header' );
44 return;
45 };
46
47 $action_messages = array(
48 'success_save' => __( 'The table was saved successfully.', 'tablepress' ),
49 'success_add' => __( 'The table was added successfully.', 'tablepress' ),
50 'success_copy' => _n( 'The table was copied successfully.', 'The tables were copied successfully.', 1, 'tablepress' ) . ' ' . sprintf( __( 'You are now seeing the copied table, which has the table ID &#8220;%s&#8221;.', 'tablepress' ), esc_html( $data['table']['id'] ) ),
51 'success_import' => __( 'The table was imported successfully.', 'tablepress' ),
52 'error_save' => __( 'Error: The table could not be saved.', 'tablepress' ),
53 'error_delete' => __( 'Error: The table could not be deleted.', 'tablepress' ),
54 'success_save_success_id_change' => __( 'The table was saved successfully, and the table ID was changed.', 'tablepress' ),
55 'success_save_error_id_change' => __( 'The table was saved successfully, but the table ID could not be changed!', 'tablepress' ),
56 );
57 // Custom handling instead of $this->process_action_messages(). Also, $action_messages is used below.
58 if ( $data['message'] && isset( $action_messages[ $data['message'] ] ) ) {
59 $class = ( 'error' === substr( $data['message'], 0, 5 ) || in_array( $data['message'], array( 'success_save_error_id_change' ), true ) ) ? 'notice-error' : 'notice-success';
60 $this->add_header_message( "<strong>{$action_messages[ $data['message'] ]}</strong>", $class );
61 }
62
63 // Load jQuery UI dialog here to get the CSS into the HTML <head> part.
64 wp_enqueue_style( 'wp-jquery-ui-dialog' );
65 wp_enqueue_script( 'wpdialogs' ); // for the Advanced Editor
66 // Remove default media-upload.js, in favor of own code.
67 add_action( 'admin_print_footer_scripts', array( $this, 'dequeue_media_upload_js' ), 2 );
68 add_thickbox();
69 add_filter( 'media_view_strings', array( $this, 'change_media_view_strings' ) );
70 wp_enqueue_media();
71
72 // Enqueue JS for the "Insert Link" button.
73 wp_enqueue_script( 'wplink' );
74
75 $this->admin_page->enqueue_style( 'edit' );
76 $this->admin_page->enqueue_script( 'edit', array( 'jquery', 'jquery-ui-sortable' ), array( // phpcs:ignore PEAR.Functions.FunctionCallSignature.MultipleArguments
77 'options' => array(
78 /**
79 * Filter whether debug output shall be printed to the page.
80 *
81 * The value before filtering is determined from the GET parameter "debug" or the WP_DEBUG constant.
82 *
83 * @since 1.4.0
84 *
85 * @param bool $print Whether debug output shall be printed.
86 */
87 'print_debug_output' => apply_filters( 'tablepress_print_debug_output', isset( $_GET['debug'] ) ? ( 'true' === $_GET['debug'] ) : WP_DEBUG ),
88 /**
89 * Filter whether the "Advanced Editor" button shall be enabled.
90 *
91 * @since 1.0.0
92 *
93 * @param bool $enable Whether the "Advanced Editor" shall be enabled. Default true.
94 */
95 'cells_advanced_editor' => apply_filters( 'tablepress_edit_cells_advanced_editor', true ),
96 /**
97 * Filter whether the size of the table input textareas shall increase when they are focused.
98 *
99 * @since 1.0.0
100 *
101 * @param bool $auto_grow Whether the size of the cell textareas shall increase. Default true.
102 */
103 'cells_auto_grow' => apply_filters( 'tablepress_edit_cells_auto_grow', true ),
104 'shortcode' => esc_js( TablePress::$shortcode ),
105 ),
106 'strings' => array_merge(
107 array(
108 'no_remove_all_rows' => __( 'You can not delete all table rows!', 'tablepress' ),
109 'no_remove_all_columns' => __( 'You can not delete all table columns!', 'tablepress' ),
110 'no_rows_selected' => __( 'You did not select any rows!', 'tablepress' ),
111 'no_columns_selected' => __( 'You did not select any columns!', 'tablepress' ),
112 'append_num_rows_invalid' => __( 'The value for the number of rows is invalid!', 'tablepress' ),
113 'append_num_columns_invalid' => __( 'The value for the number of columns is invalid!', 'tablepress' ),
114 'ays_remove_rows_singular' => _n( 'Do you really want to delete the selected row?', 'Do you really want to delete the selected rows?', 1, 'tablepress' ),
115 'ays_remove_rows_plural' => _n( 'Do you really want to delete the selected row?', 'Do you really want to delete the selected rows?', 2, 'tablepress' ),
116 'ays_remove_columns_singular' => _n( 'Do you really want to delete the selected column?', 'Do you really want to delete the selected columns?', 1, 'tablepress' ),
117 'ays_remove_columns_plural' => _n( 'Do you really want to delete the selected column?', 'Do you really want to delete the selected columns?', 2, 'tablepress' ),
118 'advanced_editor_open' => __( 'Please click into the cell that you want to edit using the &#8220;Advanced Editor&#8221;.', 'tablepress' ),
119 'rowspan_add' => __( 'To combine cells within a column, click into the cell below the cell that has the content the combined cells shall have.', 'tablepress' ),
120 'colspan_add' => __( 'To combine cells within a row, click into the cell to the right of the cell that has the content the combined cells shall have.', 'tablepress' ),
121 'span_add_datatables_warning' => __( 'Attention: You have enabled the usage of the DataTables JavaScript library for features like sorting, search, or pagination.', 'tablepress' ) . "\n" .
122 __( 'Unfortunately, these can not be used in tables with combined cells.', 'tablepress' ) . "\n" .
123 __( 'Do you want to proceed and automatically turn off the usage of DataTables for this table?', 'tablepress' ),
124 'link_add' => __( 'Please click into the cell that you want to add a link to.', 'tablepress' ) . "\n" .
125 __( 'You can then enter the Link URL and Text or choose an existing page or post.', 'tablepress' ),
126 'image_add' => __( 'Please click into the cell that you want to add an image to.', 'tablepress' ) . "\n" .
127 __( 'The Media Library will open, where you can select or upload the desired image or enter the image URL.', 'tablepress' ) . "\n" .
128 sprintf( __( 'Click the &#8220;%s&#8221; button to insert the image.', 'tablepress' ), __( 'Insert into Table', 'tablepress' ) ),
129 'unsaved_changes_unload' => __( 'The changes to this table were not saved yet and will be lost if you navigate away from this page.', 'tablepress' ),
130 'preparing_preview' => __( 'The Table Preview is being loaded...', 'tablepress' ),
131 'preview_error' => __( 'The Table Preview could not be loaded.', 'tablepress' ),
132 'save_changes_success' => __( 'Saving successful', 'tablepress' ),
133 'save_changes_error' => __( 'Saving failed', 'tablepress' ),
134 'saving_changes' => __( 'Changes are being saved...', 'tablepress' ),
135 'table_id_not_empty' => __( 'The Table ID field can not be empty. Please enter a Table ID!', 'tablepress' ),
136 'table_id_not_zero' => __( 'The Table ID &#8220;0&#8221; is not supported. Please enter a different Table ID!', 'tablepress' ),
137 'ays_change_table_id' => __( 'Do you really want to change the Table ID? All Shortcodes for this table in your pages and posts will have to be adjusted!', 'tablepress' ),
138 'extra_css_classes_invalid' => __( 'The entered value in the field &#8220;Extra CSS classes&#8221; is invalid.', 'tablepress' ),
139 'num_pagination_entries_invalid' => __( 'The entered value in the field &#8220;Pagination Entries&#8221; is not a number.', 'tablepress' ),
140 'sort_asc' => __( 'Sort ascending', 'tablepress' ),
141 'sort_desc' => __( 'Sort descending', 'tablepress' ),
142 'no_rowspan_first_row' => __( 'You can not add rowspan to the first row!', 'tablepress' ),
143 'no_colspan_first_col' => __( 'You can not add colspan to the first column!', 'tablepress' ),
144 'no_rowspan_table_head' => __( 'You can not connect cells into the table head row!', 'tablepress' ),
145 'no_rowspan_table_foot' => __( 'You can not connect cells out of the table foot row!', 'tablepress' ),
146 ),
147 // Merge this to have messages available for AJAX after save dialog.
148 $action_messages
149 ),
150 ) );
151
152 $this->add_text_box( 'head', array( $this, 'textbox_head' ), 'normal' );
153 $this->add_text_box( 'buttons-1', array( $this, 'textbox_buttons' ), 'normal' );
154 $this->add_meta_box( 'table-information', __( 'Table Information', 'tablepress' ), array( $this, 'postbox_table_information' ), 'normal' );
155 $this->add_meta_box( 'table-data', __( 'Table Content', 'tablepress' ), array( $this, 'postbox_table_data' ), 'normal' );
156 $this->add_meta_box( 'table-manipulation', __( 'Table Manipulation', 'tablepress' ), array( $this, 'postbox_table_manipulation' ), 'normal' );
157 $this->add_meta_box( 'table-options', __( 'Table Options', 'tablepress' ), array( $this, 'postbox_table_options' ), 'normal' );
158 $this->add_meta_box( 'datatables-features', __( 'Features of the DataTables JavaScript library', 'tablepress' ), array( $this, 'postbox_datatables_features' ), 'normal' );
159 $this->add_text_box( 'hidden-containers', array( $this, 'textbox_hidden_containers' ), 'additional' );
160 $this->add_text_box( 'buttons-2', array( $this, 'textbox_buttons' ), 'additional' );
161 $this->add_text_box( 'other-actions', array( $this, 'textbox_other_actions' ), 'submit' );
162 }
163
164 /**
165 * Dequeue 'media-upload' JavaScript, which gets added by the Media Library,
166 * but is undesired here, as we don't want the tb_position() function for resizing.
167 *
168 * @since 1.0.0
169 */
170 public function dequeue_media_upload_js() {
171 wp_dequeue_script( 'media-upload' );
172 }
173
174 /**
175 * Change Media View string "Insert into post" to "Insert into Table".
176 *
177 * @since 1.0.0
178 *
179 * @param array $strings Current set of Media View strings.
180 * @return array Changed Media View strings.
181 */
182 public function change_media_view_strings( array $strings ) {
183 $strings['insertIntoPost'] = __( 'Insert into Table', 'tablepress' );
184 return $strings;
185 }
186
187 /**
188 * Print hidden field with a nonce for the screen's action, to be transmitted in HTTP requests.
189 *
190 * @since 1.0.0
191 *
192 * @param array $data Data for this screen
193 * @param array $box Information about the text box.
194 */
195 protected function action_nonce_field( array $data, array $box ) {
196 // use custom nonce field here, that includes the table ID
197 wp_nonce_field( TablePress::nonce( $this->action, $data['table']['id'] ), 'nonce-edit-table' );
198 echo "\n";
199 wp_nonce_field( TablePress::nonce( 'preview_table', $data['table']['id'] ), 'nonce-preview-table', false, true );
200 }
201
202 /**
203 * Print the content of the "Table Information" post meta box.
204 *
205 * @since 1.0.0
206 *
207 * @param array $data Data for this screen.
208 * @param array $box Information about the meta box.
209 */
210 public function postbox_table_information( array $data, array $box ) {
211 ?>
212 <table class="tablepress-postbox-table fixed">
213 <tbody>
214 <tr class="bottom-border">
215 <th class="column-1" scope="row"><label for="table-new-id"><?php _e( 'Table ID', 'tablepress' ); ?>:</label></th>
216 <td class="column-2">
217 <input type="hidden" name="table[id]" id="table-id" value="<?php echo esc_attr( $data['table']['id'] ); ?>" />
218 <input type="text" name="table[new_id]" id="table-new-id" value="<?php echo esc_attr( $data['table']['id'] ); ?>" title="<?php esc_attr_e( 'The Table ID can only consist of letters, numbers, hyphens (-), and underscores (_).', 'tablepress' ); ?>" pattern="[A-Za-z0-9-_]+" required <?php echo ( ! current_user_can( 'tablepress_edit_table_id', $data['table']['id'] ) ) ? 'readonly ' : ''; ?>/>
219 <div style="float: right; margin-right: 1%;"><label for="table-information-shortcode"><?php _e( 'Shortcode', 'tablepress' ); ?>:</label>
220 <input type="text" id="table-information-shortcode" class="table-shortcode" value="<?php echo esc_attr( '[' . TablePress::$shortcode . " id={$data['table']['id']} /]" ); ?>" readonly="readonly" /></div>
221 </td>
222 </tr>
223 <tr class="top-border">
224 <th class="column-1" scope="row"><label for="table-name"><?php _e( 'Table Name', 'tablepress' ); ?>:</label></th>
225 <td class="column-2"><input type="text" name="table[name]" id="table-name" class="large-text" value="<?php echo esc_attr( $data['table']['name'] ); ?>" /></td>
226 </tr>
227 <tr class="bottom-border">
228 <th class="column-1 top-align" scope="row"><label for="table-description"><?php _e( 'Description', 'tablepress' ); ?>:</label></th>
229 <td class="column-2"><textarea name="table[description]" id="table-description" class="large-text" rows="4"><?php echo esc_textarea( $data['table']['description'] ); ?></textarea></td>
230 </tr>
231 <tr class="top-border">
232 <th class="column-1" scope="row"><?php _e( 'Last Modified', 'tablepress' ); ?>:</th>
233 <td class="column-2"><?php printf( __( '%1$s by %2$s', 'tablepress' ), '<span id="last-modified">' . TablePress::format_datetime( $data['table']['last_modified'] ) . '</span>', '<span id="last-editor">' . TablePress::get_user_display_name( $data['table']['options']['last_editor'] ) . '</span>' ); ?></td>
234 </tr>
235 </tbody>
236 </table>
237 <?php
238 }
239
240 /**
241 * Print the content of the "Table Content" post meta box.
242 *
243 * @since 1.0.0
244 *
245 * @param array $data Data for this screen.
246 * @param array $box Information about the meta box.
247 */
248 public function postbox_table_data( array $data, array $box ) {
249 $table = $data['table']['data'];
250 $options = $data['table']['options'];
251 $visibility = $data['table']['visibility'];
252 $rows = count( $table );
253 $columns = count( $table[0] );
254
255 $head_row_idx = -1;
256 $foot_row_idx = -1;
257 // Determine row index of the table head row, by excluding all hidden rows from the beginning.
258 if ( $options['table_head'] ) {
259 for ( $row_idx = 0; $row_idx < $rows; $row_idx++ ) {
260 if ( 1 === $visibility['rows'][ $row_idx ] ) {
261 $head_row_idx = $row_idx;
262 break;
263 }
264 }
265 }
266 // Determine row index of the table foot row, by excluding all hidden rows from the end.
267 if ( $options['table_foot'] ) {
268 for ( $row_idx = $rows - 1; $row_idx > -1; $row_idx-- ) {
269 if ( 1 === $visibility['rows'][ $row_idx ] ) {
270 $foot_row_idx = $row_idx;
271 break;
272 }
273 }
274 }
275 ?>
276 <table id="edit-form" class="tablepress-edit-screen-id-<?php echo esc_attr( $data['table']['id'] ); ?>">
277 <thead>
278 <tr id="edit-form-head">
279 <th scope="col"><span class="screen-reader-text"><?php esc_html_e( 'Row Number', 'tablepress' ); ?></span></th>
280 <th scope="col"><span class="screen-reader-text"><?php esc_html_e( 'Bulk action selectors for rows', 'tablepress' ); ?></span></th>
281 <?php
282 for ( $col_idx = 0; $col_idx < $columns; $col_idx++ ) {
283 $column_class = '';
284 if ( 0 === $visibility['columns'][ $col_idx ] ) {
285 $column_class = ' column-hidden';
286 }
287 $column = TablePress::number_to_letter( $col_idx + 1 );
288 echo "\t\t\t<th scope=\"col\" class=\"head{$column_class}\"><span class=\"sort-control sort-desc hide-if-no-js\" title=\"" . esc_attr__( 'Sort descending', 'tablepress' ) . '"><span class="sorting-indicator"></span></span><span class="sort-control sort-asc hide-if-no-js" title="' . esc_attr__( 'Sort ascending', 'tablepress' ) . "\"><span class=\"sorting-indicator\"></span></span><span class=\"move-handle\">{$column}</span></th>\n";
289 }
290 ?>
291 <th scope="col"><span class="screen-reader-text"><?php esc_html_e( 'Row Number', 'tablepress' ); ?></span></th>
292 </tr>
293 </thead>
294 <tbody id="edit-form-body">
295 <?php
296 foreach ( $table as $row_idx => $row_data ) {
297 $row = $row_idx + 1;
298 $classes = array();
299 if ( 0 === ( $row_idx % 2 ) ) {
300 $classes[] = 'odd';
301 }
302 if ( $head_row_idx === $row_idx ) {
303 $classes[] = 'head-row';
304 } elseif ( $foot_row_idx === $row_idx ) {
305 $classes[] = 'foot-row';
306 }
307 if ( 0 === $visibility['rows'][ $row_idx ] ) {
308 $classes[] = 'row-hidden';
309 }
310 $row_class = ( ! empty( $classes ) ) ? ' class="' . implode( ' ', $classes ) . '"' : '';
311 $row_selector_text = esc_html( sprintf( __( 'Bulk action selector for row %s', 'tablepress' ), number_format_i18n( $row ) ) );
312 echo "\t\t<tr{$row_class}>\n";
313 echo "\t\t\t<td><span class=\"move-handle\">{$row}</span></td>";
314 echo "<td><label class=\"hide-if-no-js\"><span class=\"screen-reader-text\">{$row_selector_text}</span><input type=\"checkbox\" /><input type=\"hidden\" class=\"visibility\" name=\"table[visibility][rows][]\" value=\"{$visibility['rows'][ $row_idx ]}\" /></label></td>";
315 foreach ( $row_data as $col_idx => $cell ) {
316 $column = TablePress::number_to_letter( $col_idx + 1 );
317 $column_class = '';
318 if ( 0 === $visibility['columns'][ $col_idx ] ) {
319 $column_class = ' class="column-hidden"';
320 }
321 // Sanitize, so that HTML is possible in table cells.
322 $cell = esc_textarea( $cell );
323 $cell_label = esc_html( sprintf( __( 'Column %1$s, Row %2$s', 'tablepress' ), number_format_i18n( $col_idx + 1 ), number_format_i18n( $row ) ) );
324 echo "<td{$column_class}><label for=\"cell-{$column}{$row}\"><span class=\"screen-reader-text\">{$cell_label}</span></label><textarea name=\"table[data][{$row_idx}][{$col_idx}]\" id=\"cell-{$column}{$row}\" rows=\"1\">{$cell}</textarea></td>";
325 }
326 echo "<td><span class=\"move-handle\">{$row}</span></td>\n";
327 echo "\t\t</tr>\n";
328 }
329 ?>
330 </tbody>
331 <tfoot>
332 <tr id="edit-form-foot">
333 <th scope="col"><span class="screen-reader-text"><?php esc_html_e( 'Row Number', 'tablepress' ); ?></span></th>
334 <th scope="col"><span class="screen-reader-text"><?php esc_html_e( 'Bulk action selectors for rows', 'tablepress' ); ?></span></th>
335 <?php
336 for ( $col_idx = 0; $col_idx < $columns; $col_idx++ ) {
337 $column_class = '';
338 if ( 0 === $visibility['columns'][ $col_idx ] ) {
339 $column_class = ' class="column-hidden"';
340 }
341 $column_selector_text = esc_html( sprintf( __( 'Bulk action selector for column %s', 'tablepress' ), TablePress::number_to_letter( $col_idx + 1 ) ) );
342 echo "\t\t\t<th scope=\"col\" {$column_class}><label class=\"hide-if-no-js\"><span class=\"screen-reader-text\">{$column_selector_text}</span><input type=\"checkbox\" /></label>";
343 echo "<input type=\"hidden\" class=\"visibility\" name=\"table[visibility][columns][]\" value=\"{$visibility['columns'][ $col_idx ]}\" /></th>\n";
344 }
345 ?>
346 <th scope="col"><span class="screen-reader-text"><?php esc_html_e( 'Row Number', 'tablepress' ); ?></span></th>
347 </tr>
348 </tfoot>
349 </table>
350 <input type="hidden" id="number-rows" name="table[number][rows]" value="<?php echo $rows; ?>" />
351 <input type="hidden" id="number-columns" name="table[number][columns]" value="<?php echo $columns; ?>" />
352 <?php
353 }
354
355 /**
356 * Print the content of the "Table Manipulation" post meta box.
357 *
358 * @since 1.0.0
359 *
360 * @param array $data Data for this screen.
361 * @param array $box Information about the meta box.
362 */
363 public function postbox_table_manipulation( array $data, array $box ) {
364 ?>
365 <table class="tablepress-postbox-table fixed hide-if-no-js">
366 <tbody>
367 <tr class="bottom-border">
368 <td class="column-1">
369 <input type="button" class="button" id="link-add" value="<?php esc_attr_e( 'Insert Link', 'tablepress' ); ?>" />
370 <input type="button" class="button" id="image-add" value="<?php esc_attr_e( 'Insert Image', 'tablepress' ); ?>" />
371 <input type="button" class="button" id="advanced-editor-open" value="<?php esc_attr_e( 'Advanced Editor', 'tablepress' ); ?>" />
372 </td>
373 <td class="column-2">
374 <?php _e( 'Combine cells', 'tablepress' ); ?>:&nbsp;
375 <input type="button" class="button" id="span-add-rowspan" value="<?php esc_attr_e( 'in a column (rowspan)', 'tablepress' ); ?>" />
376 <input type="button" class="button" id="span-add-colspan" value="<?php esc_attr_e( 'in a row (colspan)', 'tablepress' ); ?>" />
377 <input type="button" class="button show-help-box" value="<?php esc_attr_e( '?', 'tablepress' ); ?>" title="<?php esc_attr_e( 'Help on combining cells', 'tablepress' ); ?>" data-help-box="#help-box-combine-cells" />
378 <div id="help-box-combine-cells" class="hidden-container hidden-help-box-container">
379 <?php
380 echo '<p>' . __( 'Table cells can span across more than one column or row.', 'tablepress' ) . '</p>';
381 echo '<p>' . __( 'Combining consecutive cells within the same row is called &#8220;colspanning&#8221;.', 'tablepress' )
382 . ' ' . __( 'Combining consecutive cells within the same column is called &#8220;rowspanning&#8221;.', 'tablepress' ) . '</p>';
383 echo '<p>' . __( 'To combine adjacent cells in a row, add the keyword <code>#colspan#</code> to the cell to the right of the one with the content for the combined cell by using the corresponding button.', 'tablepress' )
384 . ' ' . __( 'To combine adjacent cells in a column, add the keyword <code>#rowspan#</code> to the cell below the one with the content for the combined cell by using the corresponding button.', 'tablepress' ) . '</p>';
385 echo '<p>' . __( 'Repeat this to add the keyword to all cells that shall be connected.', 'tablepress' ) . '</p>';
386 echo '<p><strong>' . __( 'Be aware that the functions of the DataTables JavaScript library will not work on tables which have combined cells.', 'tablepress' ) . '</strong></p>';
387 ?>
388 </div>
389 </td>
390 </tr>
391 <tr class="top-border">
392 <td class="column-1">
393 <?php _e( 'Selected rows', 'tablepress' ); ?>:&nbsp;
394 <input type="button" class="button" id="rows-hide" value="<?php esc_attr_e( 'Hide', 'tablepress' ); ?>" />
395 <input type="button" class="button" id="rows-unhide" value="<?php esc_attr_e( 'Show', 'tablepress' ); ?>" />
396 </td>
397 <td class="column-2">
398 <?php _e( 'Selected columns', 'tablepress' ); ?>:&nbsp;
399 <input type="button" class="button" id="columns-hide" value="<?php esc_attr_e( 'Hide', 'tablepress' ); ?>" />
400 <input type="button" class="button" id="columns-unhide" value="<?php esc_attr_e( 'Show', 'tablepress' ); ?>" />
401 </td>
402 </tr>
403 <tr class="bottom-border">
404 <td class="column-1">
405 <?php _e( 'Selected rows', 'tablepress' ); ?>:&nbsp;
406 <input type="button" class="button" id="rows-duplicate" value="<?php esc_attr_e( 'Duplicate', 'tablepress' ); ?>" />
407 <input type="button" class="button" id="rows-insert" value="<?php esc_attr_e( 'Insert', 'tablepress' ); ?>" />
408 <input type="button" class="button" id="rows-remove" value="<?php esc_attr_e( 'Delete', 'tablepress' ); ?>" />
409 </td>
410 <td class="column-2">
411 <?php _e( 'Selected columns', 'tablepress' ); ?>:&nbsp;
412 <input type="button" class="button" id="columns-duplicate" value="<?php esc_attr_e( 'Duplicate', 'tablepress' ); ?>" />
413 <input type="button" class="button" id="columns-insert" value="<?php esc_attr_e( 'Insert', 'tablepress' ); ?>" />
414 <input type="button" class="button" id="columns-remove" value="<?php esc_attr_e( 'Delete', 'tablepress' ); ?>" />
415 </td>
416 </tr>
417 <tr class="top-border">
418 <td class="column-1">
419 <label><?php printf( __( 'Add %s row(s)', 'tablepress' ), '<input type="number" id="rows-append-number" class="small-text numbers-only" title="' . esc_attr__( 'This field must contain a positive number.', 'tablepress' ) . '" value="1" min="1" max="99999" maxlength="5" required />' ); ?></label>&nbsp;<input type="button" class="button" id="rows-append" value="<?php esc_attr_e( 'Add', 'tablepress' ); ?>" />
420 </td>
421 <td class="column-2">
422 <label><?php printf( __( 'Add %s column(s)', 'tablepress' ), '<input type="number" id="columns-append-number" class="small-text numbers-only" title="' . esc_attr__( 'This field must contain a positive number.', 'tablepress' ) . '" value="1" min="1" max="99999" maxlength="5" required />' ); ?></label>&nbsp;<input type="button" class="button" id="columns-append" value="<?php esc_attr_e( 'Add', 'tablepress' ); ?>" />
423 </td>
424 </tr>
425 </table>
426 <p class="hide-if-js"><?php _e( 'To use the Table Manipulation features, JavaScript needs to be enabled in your browser.', 'tablepress' ); ?></p>
427 <?php
428 }
429
430 /**
431 * Print the "Preview" and "Save Changes" button.
432 *
433 * @since 1.0.0
434 *
435 * @param array $data Data for this screen.
436 * @param array $box Information about the text box.
437 */
438 public function textbox_buttons( array $data, array $box ) {
439 $preview_url = TablePress::url( array( 'action' => 'preview_table', 'item' => $data['table']['id'], 'return' => 'edit', 'return_item' => $data['table']['id'] ), true, 'admin-post.php' );
440
441 echo '<p class="submit">';
442 if ( current_user_can( 'tablepress_preview_table', $data['table']['id'] ) ) {
443 echo '<a href="' . $preview_url . '" class="button button-large show-preview-button" target="_blank">' . __( 'Preview', 'tablepress' ) . '</a>';
444 }
445 ?>
446 <input type="button" class="button button-primary button-large save-changes-button hide-if-no-js" value="<?php esc_attr_e( 'Save Changes', 'tablepress' ); ?>" />
447 <input type="submit" class="button button-primary button-large hide-if-js" value="<?php esc_attr_e( 'Save Changes', 'tablepress' ); ?>" />
448 <?php
449 echo '</p>';
450 }
451
452 /**
453 * Print the "Delete Table" and "Export Table" buttons.
454 *
455 * @since 1.0.0
456 *
457 * @param array $data Data for this screen.
458 * @param array $box Information about the text box.
459 */
460 public function textbox_other_actions( array $data, array $box ) {
461 $user_can_copy_table = current_user_can( 'tablepress_copy_table', $data['table']['id'] );
462 $user_can_export_table = current_user_can( 'tablepress_export_table', $data['table']['id'] );
463 $user_can_delete_table = current_user_can( 'tablepress_delete_table', $data['table']['id'] );
464
465 if ( ! $user_can_copy_table && ! $user_can_export_table && ! $user_can_delete_table ) {
466 return;
467 }
468
469 echo '<p class="submit">';
470 echo __( 'Other Actions', 'tablepress' ) . ':&nbsp; ';
471 if ( $user_can_copy_table ) {
472 echo '<a href="' . TablePress::url( array( 'action' => 'copy_table', 'item' => $data['table']['id'], 'return' => 'edit' ), true, 'admin-post.php' ) . '" class="button">' . __( 'Copy Table', 'tablepress' ) . '</a> ';
473 }
474 if ( $user_can_export_table ) {
475 echo '<a href="' . TablePress::url( array( 'action' => 'export', 'table_id' => $data['table']['id'] ) ) . '" class="button">' . __( 'Export Table', 'tablepress' ) . '</a> ';
476 }
477 if ( $user_can_delete_table ) {
478 echo '<a href="' . TablePress::url( array( 'action' => 'delete_table', 'item' => $data['table']['id'], 'return' => 'edit', 'return_item' => $data['table']['id'] ), true, 'admin-post.php' ) . '" class="button delete-link">' . __( 'Delete Table', 'tablepress' ) . '</a>';
479 }
480 echo '</p>';
481 }
482
483 /**
484 * Print the hidden containers for the Advanced Editor and the Preview.
485 *
486 * @since 1.0.0
487 *
488 * @param array $data Data for this screen.
489 * @param array $box Information about the text box.
490 */
491 public function textbox_hidden_containers( array $data, array $box ) {
492 ?>
493 <div class="hidden-container">
494 <div id="advanced-editor">
495 <label for="advanced-editor-content" class="screen-reader-text"><?php esc_html_e( 'Advanced Editor', 'tablepress' ); ?></label>
496 <?php
497 $wp_editor_options = array(
498 'textarea_rows' => 10,
499 'tinymce' => false,
500 'quicktags' => array(
501 'buttons' => 'strong,em,link,del,ins,img,code,spell,close',
502 ),
503 );
504 wp_editor( '', 'advanced-editor-content', $wp_editor_options );
505 ?>
506 <div class="submitbox">
507 <a href="#" class="submitdelete" id="advanced-editor-cancel"><?php _e( 'Cancel', 'tablepress' ); ?></a>
508 <input type="button" class="button button-primary button-large" id="advanced-editor-confirm" value="<?php esc_attr_e( 'OK', 'tablepress' ); ?>" />
509 </div>
510 </div>
511 </div>
512 <div id="preview-container" class="hidden-container">
513 <div id="table-preview"></div>
514 </div>
515 <?php
516 }
517
518 /**
519 * Print the content of the "Table Options" post meta box.
520 *
521 * @since 1.0.0
522 *
523 * @param array $data Data for this screen.
524 * @param array $box Information about the meta box.
525 */
526 public function postbox_table_options( array $data, array $box ) {
527 $options = $data['table']['options'];
528 ?>
529 <table class="tablepress-postbox-table fixed">
530 <tbody>
531 <tr>
532 <th class="column-1" scope="row"><?php _e( 'Table Head Row', 'tablepress' ); ?>:</th>
533 <td class="column-2"><label for="option-table-head"><input type="checkbox" id="option-table-head" name="table[options][table_head]" value="true"<?php checked( $options['table_head'] ); ?> /> <?php _e( 'The first row of the table is the table header.', 'tablepress' ); ?></label></td>
534 </tr>
535 <tr class="bottom-border">
536 <th class="column-1" scope="row"><?php _e( 'Table Foot Row', 'tablepress' ); ?>:</th>
537 <td class="column-2"><label for="option-table-foot"><input type="checkbox" id="option-table-foot" name="table[options][table_foot]" value="true"<?php checked( $options['table_foot'] ); ?> /> <?php _e( 'The last row of the table is the table footer.', 'tablepress' ); ?></label></td>
538 </tr>
539 <tr class="top-border">
540 <th class="column-1" scope="row"><?php _e( 'Alternating Row Colors', 'tablepress' ); ?>:</th>
541 <td class="column-2"><label for="option-alternating-row-colors"><input type="checkbox" id="option-alternating-row-colors" name="table[options][alternating_row_colors]" value="true"<?php checked( $options['alternating_row_colors'] ); ?> /> <?php _e( 'The background colors of consecutive rows shall alternate.', 'tablepress' ); ?></label></td>
542 </tr>
543 <tr class="bottom-border">
544 <th class="column-1" scope="row"><?php _e( 'Row Hover Highlighting', 'tablepress' ); ?>:</th>
545 <td class="column-2"><label for="option-row-hover"><input type="checkbox" id="option-row-hover" name="table[options][row_hover]" value="true"<?php checked( $options['row_hover'] ); ?> /> <?php _e( 'Highlight a row while the mouse cursor hovers above it by changing its background color.', 'tablepress' ); ?></label></td>
546 </tr>
547 <tr class="top-border">
548 <th class="column-1" scope="row"><label for="option-print-name"><?php _e( 'Print Table Name', 'tablepress' ); ?></label>:</th>
549 <?php
550 $position_select = '<select id="option-print-name-position" name="table[options][print_name_position]">';
551 $position_select .= '<option' . selected( 'above', $options['print_name_position'], false ) . ' value="above">' . __( 'above', 'tablepress' ) . '</option>';
552 $position_select .= '<option' . selected( 'below', $options['print_name_position'], false ) . ' value="below">' . __( 'below', 'tablepress' ) . '</option>';
553 $position_select .= '</select>';
554 ?>
555 <td class="column-2"><input type="checkbox" id="option-print-name" name="table[options][print_name]" value="true"<?php checked( $options['print_name'] ); ?> /> <label><?php printf( __( 'Show the table name %s the table.', 'tablepress' ), $position_select ); ?></label></td>
556 </tr>
557 <tr class="bottom-border">
558 <th class="column-1" scope="row"><label for="option-print-description"><?php _e( 'Print Table Description', 'tablepress' ); ?></label>:</th>
559 <?php
560 $position_select = '<select id="option-print-description-position" name="table[options][print_description_position]">';
561 $position_select .= '<option' . selected( 'above', $options['print_description_position'], false ) . ' value="above">' . __( 'above', 'tablepress' ) . '</option>';
562 $position_select .= '<option' . selected( 'below', $options['print_description_position'], false ) . ' value="below">' . __( 'below', 'tablepress' ) . '</option>';
563 $position_select .= '</select>';
564 ?>
565 <td class="column-2"><input type="checkbox" id="option-print-description" name="table[options][print_description]" value="true"<?php checked( $options['print_description'] ); ?> /> <label><?php printf( __( 'Show the table description %s the table.', 'tablepress' ), $position_select ); ?></label></td>
566 </tr>
567 <tr class="top-border">
568 <th class="column-1" scope="row"><?php _e( 'Extra CSS Classes', 'tablepress' ); ?>:</th>
569 <td class="column-2"><label for="option-extra-css-classes"><input type="text" id="option-extra-css-classes" class="large-text" name="table[options][extra_css_classes]" value="<?php echo esc_attr( $options['extra_css_classes'] ); ?>" title="<?php esc_attr_e( 'This field can only contain letters, numbers, spaces, hyphens (-), underscores (_), and colons (:).', 'tablepress' ); ?>" pattern="[A-Za-z0-9- _:]*" /><p class="description"><?php echo __( 'Additional CSS classes for styling purposes can be entered here.', 'tablepress' ) . ' ' . sprintf( __( 'This is NOT the place to enter <a href="%s">Custom CSS</a> code!', 'tablepress' ), TablePress::url( array( 'action' => 'options' ) ) ); ?></p></label></td>
570 </tr>
571 </tbody>
572 </table>
573 <?php
574 }
575
576 /**
577 * Print the content of the "Features of the DataTables JavaScript library" post meta box.
578 *
579 * @since 1.0.0
580 *
581 * @param array $data Data for this screen.
582 * @param array $box Information about the meta box.
583 */
584 public function postbox_datatables_features( array $data, array $box ) {
585 $options = $data['table']['options'];
586 ?>
587 <p id="notice-datatables-head-row" class="hide-if-js"><?php printf( __( 'These features and options are only available, when the &#8220;%1$s&#8221; checkbox in the &#8220;%2$s&#8221; section is checked.', 'tablepress' ), __( 'Table Head Row', 'tablepress' ), __( 'Table Options', 'tablepress' ) ); ?></p>
588 <table class="tablepress-postbox-table fixed">
589 <tbody>
590 <tr class="bottom-border">
591 <th class="column-1" scope="row"><?php _e( 'Use DataTables', 'tablepress' ); ?>:</th>
592 <td class="column-2"><label for="option-use-datatables"><input type="checkbox" id="option-use-datatables" name="table[options][use_datatables]" value="true"<?php checked( $options['use_datatables'] ); ?> /> <?php _e( 'Use the following features of the DataTables JavaScript library with this table:', 'tablepress' ); ?></label></td>
593 </tr>
594 <tr class="top-border">
595 <th class="column-1" scope="row"><?php _e( 'Sorting', 'tablepress' ); ?>:</th>
596 <td class="column-2"><label for="option-datatables-sort"><input type="checkbox" id="option-datatables-sort" name="table[options][datatables_sort]" value="true"<?php checked( $options['datatables_sort'] ); ?> /> <?php _e( 'Enable sorting of the table by the visitor.', 'tablepress' ); ?></label></td>
597 </tr>
598 <tr>
599 <th class="column-1" scope="row"><?php _e( 'Search/Filtering', 'tablepress' ); ?>:</th>
600 <td class="column-2"><label for="option-datatables-filter"><input type="checkbox" id="option-datatables-filter" name="table[options][datatables_filter]" value="true"<?php checked( $options['datatables_filter'] ); ?> /> <?php _e( 'Enable the visitor to filter or search the table. Only rows with the search word in them are shown.', 'tablepress' ); ?></label></td>
601 </tr>
602 <tr>
603 <th class="column-1" scope="row" style="vertical-align: top;"><?php _e( 'Pagination', 'tablepress' ); ?>:</th>
604 <td class="column-2"><label for="option-datatables-paginate"><input type="checkbox" id="option-datatables-paginate" name="table[options][datatables_paginate]" value="true"<?php checked( $options['datatables_paginate'] ); ?> /> <?php _e( 'Enable pagination of the table (viewing only a certain number of rows at a time) by the visitor.', 'tablepress' ); ?></label><br />
605 <label for="option-datatables-paginate_entries" class="checkbox-left"><?php printf( __( 'Show %s rows per page.', 'tablepress' ), '<input type="number" id="option-datatables-paginate_entries" name="table[options][datatables_paginate_entries]" value="' . (int) $options['datatables_paginate_entries'] . '" min="1" max="99999" maxlength="5" required />' ); ?></label></td>
606 </tr>
607 <tr>
608 <th class="column-1" scope="row"><?php _e( 'Pagination Length Change', 'tablepress' ); ?>:</th>
609 <td class="column-2"><label for="option-datatables-lengthchange"><input type="checkbox" id="option-datatables-lengthchange" name="table[options][datatables_lengthchange]" value="true"<?php checked( $options['datatables_lengthchange'] ); ?> /> <?php _e( 'Allow the visitor to change the number of rows shown when using pagination.', 'tablepress' ); ?></label></td>
610 </tr>
611 <tr>
612 <th class="column-1" scope="row"><?php _e( 'Info', 'tablepress' ); ?>:</th>
613 <td class="column-2"><label for="option-datatables-info"><input type="checkbox" id="option-datatables-info" name="table[options][datatables_info]" value="true"<?php checked( $options['datatables_info'] ); ?> /> <?php _e( 'Enable the table information display, with information about the currently visible data, like the number of rows.', 'tablepress' ); ?></label></td>
614 </tr>
615 <tr<?php echo current_user_can( 'unfiltered_html' ) ? ' class="bottom-border"' : ''; ?>>
616 <th class="column-1" scope="row"><?php _e( 'Horizontal Scrolling', 'tablepress' ); ?>:</th>
617 <td class="column-2"><label for="option-datatables-scrollx"><input type="checkbox" id="option-datatables-scrollx" name="table[options][datatables_scrollx]" value="true"<?php checked( $options['datatables_scrollx'] ); ?> /> <?php _e( 'Enable horizontal scrolling, to make viewing tables with many columns easier.', 'tablepress' ); ?></label></td>
618 </tr>
619 <?php
620 // "Custom Commands" must only be available to trusted users. The text field must be in the page however, so that it's part of the HTTP POST request.
621 ?>
622 <tr class="<?php echo current_user_can( 'unfiltered_html' ) ? 'top-border' : 'hidden'; ?>">
623 <th class="column-1" scope="row"><?php _e( 'Custom Commands', 'tablepress' ); ?>:</th>
624 <td class="column-2"><label for="option-datatables-custom-commands"><textarea id="option-datatables-custom-commands" class="large-text" name="table[options][datatables_custom_commands]" rows="1"><?php echo esc_textarea( $options['datatables_custom_commands'] ); ?></textarea><p class="description"><?php echo sprintf( __( 'Additional parameters from the <a href="%s">DataTables documentation</a> to be added to the JS call.', 'tablepress' ), 'https://www.datatables.net/' ) . ' ' . __( 'For advanced use only.', 'tablepress' ); ?></p></label></td>
625 </tr>
626 </tbody>
627 </table>
628 <?php
629 }
630
631 /**
632 * Print a notification about a corrupted table.
633 *
634 * @since 1.4.0
635 *
636 * @param array $data Data for this screen.
637 * @param array $box Information about the text box.
638 */
639 public function textbox_corrupted_table( array $data, array $box ) {
640 ?>
641 <div class="notice notice-error notice-large">
642 <h3><em>
643 <?php _e( 'Attention: Unfortunately, an error occurred.', 'tablepress' ); ?>
644 </em></h3>
645 <p>
646 <?php
647 printf( __( 'The internal data of table &#8220;%1$s&#8221; (ID %2$s) is corrupted.', 'tablepress' ), esc_html( $data['table']['name'] ), esc_html( $data['table']['id'] ) );
648 echo ' ';
649 printf( __( 'The following error was registered: %s.', 'tablepress' ), '<code>' . esc_html( $data['table']['json_error'] ) . '</code>' );
650 ?>
651 </p>
652 <p>
653 <?php
654 _e( 'Because of this error, the table can not be edited at this time, to prevent possible further data loss.', 'tablepress' );
655 echo ' ';
656 printf( __( 'Please see the <a href="%s">TablePress FAQ page</a> for further instructions.', 'tablepress' ), 'https://tablepress.org/faq/corrupted-tables/' );
657 ?>
658 </p>
659 <p>
660 <?php
661 echo '<a href="' . TablePress::url( array( 'action' => 'list' ) ) . '" class="button">' . __( 'Back to the List of Tables', 'tablepress' ) . '</a>';
662 ?>
663 </p>
664 </div>
665 <?php
666 }
667
668 /**
669 * Print the screen head text.
670 *
671 * @since 1.0.0
672 *
673 * @param array $data Data for this screen.
674 * @param array $box Information about the text box.
675 */
676 public function textbox_head( array $data, array $box ) {
677 ?>
678 <p>
679 <?php _e( 'To edit the content or modify the structure of this table, use the input fields and buttons below.', 'tablepress' ); ?>
680 <?php printf( __( 'To insert a table into a post or page, copy its Shortcode %s and paste it into a &#8220;Shortcode&#8221; block at the desired place in the block editor.', 'tablepress' ), '<label class="screen-reader-text" for="table-shortcode-inline">' . esc_html__( 'Shortcode text for editor', 'tablepress' ) . '</label>' . '<input type="text" class="table-shortcode table-shortcode-inline" id="table-shortcode-inline" value="' . esc_attr( '[' . TablePress::$shortcode . " id={$data['table']['id']} /]" ) . '" readonly="readonly" />' ); ?>
681 </p>
682 <?php
683 }
684
685 /**
686 * Set the content for the WP feature pointer about the drag and drop and sort on the "Edit" screen.
687 *
688 * @since 1.0.0
689 */
690 public function wp_pointer_tp09_edit_drag_drop_sort() {
691 $content = '<h3>' . __( 'TablePress Feature: Moving rows and columns', 'tablepress' ) . '</h3>';
692 $content .= '<p>' . __( 'Did you know? You can drag and drop rows and columns via the row number and the column title. And the arrows next to the column title can be used for sorting.', 'tablepress' ) . '</p>';
693
694 $this->admin_page->print_wp_pointer_js( 'tp09_edit_drag_drop_sort', '#edit-form-head', array( // phpcs:ignore PEAR.Functions.FunctionCallSignature.MultipleArguments
695 'content' => $content,
696 'position' => array( 'edge' => 'top', 'align' => 'left', 'offset' => '56 2' ),
697 ) );
698 }
699
700 } // class TablePress_Edit_View
701