PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.32
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.32
5.5.85 5.5.84 5.5.83 5.5.82 5.5.81 5.5.80 5.5.79 5.5.77 5.5.76 5.5.75 5.5.73 5.5.72 5.5.22 5.5.23 5.5.29 5.5.3 5.5.31 5.5.32 5.5.34 5.5.35 5.5.36 5.5.37 5.5.4 5.5.40 5.5.41 All 161 releases
wp-data-access / WPDataAccess / Data_Publisher / WPDA_Publisher_List_Table.php

WPDA_Publisher_List_Table.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.5.32, at WPDataAccess/Data_Publisher/WPDA_Publisher_List_Table.php

428 lines 17.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Suppress "error - 0 - No summary was found for this file" on phpdoc generation
5 *
6 * @package WPDataAccess\Data_Publisher
7 */
8 namespace WPDataAccess\Data_Publisher;
9
10 use WPDataAccess\Data_Dictionary\WPDA_Dictionary_Exist;
11 use WPDataAccess\Data_Dictionary\WPDA_Dictionary_Lists;
12 use WPDataAccess\Data_Tables\WPDA_Data_Tables;
13 use WPDataAccess\List_Table\WPDA_List_Table;
14 use WPDataAccess\Plugin_Table_Models\WPDA_Publisher_Model;
15 use WPDataAccess\Utilities\WPDA_Message_Box;
16 use WPDataAccess\WPDA;
17 /**
18 * Class WPDA_Publisher_List_Table extends WPDA_List_Table
19 *
20 * List table to support Data Tables.
21 *
22 * @author Peter Schulz
23 * @since 2.0.15
24 */
25 class WPDA_Publisher_List_Table extends WPDA_List_Table {
26 public function __construct( $args = array() ) {
27 $args['column_headers'] = self::column_headers_labels();
28 $args['title'] = 'Data Tables';
29 $args['subtitle'] = '';
30 parent::__construct( $args );
31 WPDA_Data_Tables::enqueue_styles_and_script();
32 }
33
34 public function get_columns() {
35 if ( is_array( $this->wpda_cached_columns ) ) {
36 return $this->wpda_cached_columns;
37 }
38 $columns = parent::get_columns();
39 // Remove data source column.
40 unset($columns['pub_data_source']);
41 // Add data source column after schema name.
42 $columns = WPDA::array_insert_after( $columns, 'pub_schema_name', array(
43 'pub_data_source' => __( 'Data Source', 'wp-data-access' ),
44 ) );
45 return $columns;
46 }
47
48 /**
49 * Overwrite method column_default
50 *
51 * Column pub_responsive should return 'Flat' or 'Responsive'.
52 */
53 public function column_default( $item, $column_name ) {
54 if ( 'pub_id' === $column_name ) {
55 // Validate schema, table and column names
56 $warning = WPDA::validate_names( $item['pub_schema_name'], $item['pub_table_name'] );
57 if ( '' !== $warning ) {
58 return $item['pub_id'] . $warning . substr( parent::column_default( $item, $column_name ), strlen( $item['pub_id'] ) );
59 }
60 }
61 if ( 'pub_schema_name' === $column_name ) {
62 if ( 'CPT' === $item['pub_data_source'] ) {
63 return '';
64 }
65 global $wpdb;
66 if ( $wpdb->dbname === $item[$column_name] ) {
67 return "WordPress database ({$item[$column_name]})";
68 }
69 }
70 if ( 'pub_data_source' === $column_name ) {
71 switch ( $item[$column_name] ) {
72 case 'Query':
73 // Show SQL query.
74 return '<div>' . 'Custom query ' . '<i class="fas fa-eye wpda_tooltip_cq" title="' . $this->render_column_content( $item, 'pub_query', false ) . '"></i>' . '</div>';
75 case 'CPT':
76 // Show CPT query.
77 return 'Custom post type: ' . $this->render_column_content( $item, 'pub_cpt' );
78 default:
79 // Show database table.
80 return $this->render_column_content( $item, 'pub_table_name' );
81 }
82 }
83 if ( 'pub_table_name' === $column_name ) {
84 if ( 'Query' === $item['pub_data_source'] ) {
85 return '';
86 }
87 }
88 if ( 'pub_responsive' === $column_name ) {
89 if ( 'Yes' === $item[$column_name] ) {
90 return 'Responsive';
91 } else {
92 return 'Flat';
93 }
94 }
95 if ( 'pub_table_options_searching' === $column_name || 'pub_table_options_ordering' === $column_name || 'pub_table_options_paging' === $column_name || 'pub_table_options_serverside' === $column_name ) {
96 if ( 'on' === $item[$column_name] ) {
97 return 'Yes';
98 } else {
99 return 'No';
100 }
101 }
102 return parent::column_default( $item, $column_name );
103 }
104
105 /**
106 * Overwrites method column_default_add_action
107 *
108 * Add a link to show the shortcode of a data table.
109 *
110 * @param array $item
111 * @param string $column_name
112 * @param array $actions
113 */
114 public function column_default_add_action( $item, $column_name, &$actions ) {
115 parent::column_default_add_action( $item, $column_name, $actions );
116 // Add copy data table to actions
117 $wp_nonce_action = "wpda-copy-{$this->table_name}";
118 $wp_nonce = wp_create_nonce( $wp_nonce_action );
119 $form_id = '_' . (self::$list_number - 1);
120 $esc_attr = 'esc_attr';
121 $input_fields = $this->get_key_input_fields( $item );
122 $page_field = $this->page_number_item;
123 $copy_form = <<<EOT
124 \t\t\t\t<form id='copy_form{$esc_attr( $form_id )}' method='post'
125 \t\t\t\t\t action='?page={$esc_attr( $this->page )}'
126 \t\t\t\t>
127 \t\t\t\t\t{$input_fields}
128 \t\t\t\t\t<input type='hidden' name='table_name' value='{$esc_attr( $this->table_name )}'>
129 \t\t\t\t\t<input type='hidden' name='action' value='copy' />
130 \t\t\t\t\t<input type='hidden' name='_wpnonce' value='{$esc_attr( $wp_nonce )}'>
131 \t\t\t\t\t{$page_field}
132 \t\t\t\t</form>
133 EOT;
134 ?>
135
136 <script type='text/javascript'>
137 jQuery("#wpda_invisible_container").append("<?php
138 echo str_replace( array("\n", "\r"), '', $copy_form );
139 // phpcs:ignore WordPress.Security.EscapeOutput
140 ?>");
141 </script>
142
143 <?php
144 $copy_warning = __( "Copy table options set?\\n\\'Cancel\\' to stop, \\'OK\\' to copy.", 'wp-data-access' );
145 $actions['copy'] = sprintf(
146 '<a href="javascript:void(0)"
147 title="%s"
148 class="edit wpda_tooltip"
149 onclick="if (confirm(\'%s\')) jQuery(\'#%s\').submit()">
150 <span style="white-space: nowrap">
151 <i class="fas fa-copy wpda_icon_on_button"></i>
152 %s
153 </span>
154 </a>
155 ',
156 __( 'Copy: new table name = old table name_ + n', 'wp-data-access' ),
157 $copy_warning,
158 "copy_form{$form_id}",
159 __( 'Copy', 'wp-data-access' )
160 );
161 // Show Data Table shortcode directly from Data Tables main page
162 $shortcode_enabled = 'on' === WPDA::get_option( WPDA::OPTION_PLUGIN_WPDATAACCESS_POST ) && 'on' === WPDA::get_option( WPDA::OPTION_PLUGIN_WPDATAACCESS_PAGE );
163 ?>
164 <div id="wpda_publication_<?php
165 echo esc_attr( $item['pub_id'] );
166 ?>"
167 title="<?php
168 echo __( 'Shortcode', 'wp-data-access' );
169 ?>"
170 style="display:none"
171 >
172 <p class="wpda_shortcode_content">
173 Copy the shortcode below into your post or page to make this data table available on your website.
174 </p>
175 <p class="wpda_shortcode_text">
176 <strong>
177 [wpdataaccess pub_id="<?php
178 echo esc_attr( $item['pub_id'] );
179 ?>"]
180 </strong>
181 </p>
182 <p class="wpda_shortcode_buttons">
183 <button class="button wpda_shortcode_clipboard wpda_shortcode_button"
184 type="button"
185 data-clipboard-text='[wpdataaccess pub_id="<?php
186 echo esc_attr( $item['pub_id'] );
187 ?>"]'
188 onclick="jQuery.notify('<?php
189 echo __( 'Shortcode successfully copied to clipboard!' );
190 ?>','info')"
191 >
192 <?php
193 echo __( 'Copy', 'wp-data-access' );
194 ?>
195 </button>
196 <button class="button button-primary wpda_shortcode_button"
197 type="button"
198 onclick="jQuery('.ui-dialog-content').dialog('close')"
199 >
200 <?php
201 echo __( 'Close', 'wp-data-access' );
202 ?>
203 </button>
204 </p>
205 <?php
206 if ( !$shortcode_enabled ) {
207 ?>
208 <p>
209 Shortcode wpdataaccess is not enabled for all output types.
210 <a href="<?php
211 echo admin_url( 'options-general.php' );
212 // phpcs:ignore WordPress.Security.EscapeOutput
213 ?>?page=wpdataaccess" class="wpda_shortcode_link">&raquo; Manage settings</a>
214 </p>
215 <?php
216 }
217 ?>
218 </div>
219 <?php
220 $actions['shortcode'] = sprintf(
221 '<a href="javascript:void(0)"
222 class="view wpda_tooltip"
223 title="%s"
224 onclick="jQuery(\'#wpda_publication_%s\').dialog()"
225 <span style="white-space:nowrap">
226 <i class="fas fa-code wpda_icon_on_button"></i>
227 %s
228 </span>
229 </a>
230 ',
231 __( 'Get shortcode', 'wp-data-access' ),
232 esc_attr( $item['pub_id'] ),
233 __( 'Shortcode', 'wp-data-access' )
234 );
235 $actions['test'] = sprintf(
236 '<a href="javascript:void(0)"
237 class="view wpda_tooltip"
238 title="%s"
239 onclick="test_publication(\'%s\', \'%s\')"
240 <span style="white-space:nowrap">
241 <i class="fas fa-bug wpda_icon_on_button"></i>
242 %s
243 </span>
244 </a>
245 ',
246 __( 'Test', 'wp-data-access' ),
247 esc_attr( wp_create_nonce( "wpda-publication-{$item['pub_id']}" ) ),
248 esc_attr( $item['pub_id'] ),
249 __( 'Test', 'wp-data-access' )
250 );
251 }
252
253 public function process_bulk_action() {
254 if ( 'copy' === $this->current_action() ) {
255 $wp_nonce_action = "wpda-copy-{$this->table_name}";
256 $wp_nonce = ( isset( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ) : '' );
257 // input var okay.
258 if ( !wp_verify_nonce( $wp_nonce, $wp_nonce_action ) ) {
259 die( __( 'ERROR: Not authorized', 'wp-data-access' ) );
260 }
261 if ( isset( $_REQUEST['pub_id'] ) ) {
262 $pub_id = sanitize_text_field( wp_unslash( $_REQUEST['pub_id'] ) );
263 // input var okay.
264 }
265 $unique_pu_name = $this->get_unique_pub_name( $pub_id );
266 global $wpdb;
267 $pub_raw = $wpdb->get_results( $wpdb->prepare(
268 'SELECT * FROM `%1s` WHERE pub_id = %d',
269 // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
270 array(WPDA::remove_backticks( $this->table_name ), $pub_id)
271 ), 'ARRAY_A' );
272 if ( $wpdb->num_rows > 0 ) {
273 $pub_raw[0]['pub_name'] = $unique_pu_name;
274 unset($pub_raw[0]['pub_id']);
275 $rows_inserted = $wpdb->insert( $this->table_name, $pub_raw[0] );
276 switch ( $rows_inserted ) {
277 case 0:
278 $msg = new WPDA_Message_Box(array(
279 'message_text' => __( 'Could not copy data table [source not found]', 'wp-data-access' ),
280 'message_type' => 'error',
281 'message_is_dismissible' => false,
282 ));
283 $msg->box();
284 break;
285 case 1:
286 $msg = new WPDA_Message_Box(array(
287 'message_text' => __( 'Data table copied', 'wp-data-access' ),
288 ));
289 $msg->box();
290 break;
291 default:
292 $msg = new WPDA_Message_Box(array(
293 'message_text' => __( 'Could not copy data table [too many rows]', 'wp-data-access' ),
294 'message_type' => 'error',
295 'message_is_dismissible' => false,
296 ));
297 $msg->box();
298 }
299 }
300 } else {
301 parent::process_bulk_action();
302 }
303 }
304
305 protected function get_unique_pub_name( $pub_id ) {
306 global $wpdb;
307 $db_pub_name = $wpdb->get_results( $wpdb->prepare(
308 'select pub_name from `%1s` where pub_id = %d',
309 // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
310 array(WPDA::remove_backticks( WPDA_Publisher_Model::get_base_table_name() ), $pub_id)
311 ), 'ARRAY_A' );
312 if ( $wpdb->num_rows !== 1 ) {
313 wp_die( __( 'ERROR: Data table not found', 'wp-data-access' ) );
314 }
315 $i = 2;
316 $pub_name = $db_pub_name[0]['pub_name'];
317 $unique_pub_name = "{$pub_name}_{$i}";
318 $wpdb->get_results( $wpdb->prepare(
319 "select 'x' from `%1s` where pub_name = %s",
320 // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
321 array(WPDA::remove_backticks( WPDA_Publisher_Model::get_base_table_name() ), $unique_pub_name)
322 ) );
323 while ( $wpdb->num_rows > 0 ) {
324 // Search until a free options set is found
325 $i++;
326 $unique_pub_name = "{$pub_name}_{$i}";
327 $wpdb->get_results( $wpdb->prepare(
328 "select 'x' from `%1s` where pub_name = %s",
329 // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders
330 array(WPDA::remove_backticks( WPDA_Publisher_Model::get_base_table_name() ), $unique_pub_name)
331 ) );
332 }
333 return $unique_pub_name;
334 }
335
336 public static function column_headers_labels() {
337 return array(
338 'pub_id' => __( 'ID', 'wp-data-access' ),
339 'pub_name' => __( 'Name', 'wp-data-access' ),
340 'pub_schema_name' => __( 'Database', 'wp-data-access' ),
341 'pub_data_source' => __( 'Data Source', 'wp-data-access' ),
342 'pub_table_name' => __( 'Table/View Name', 'wp-data-access' ),
343 'pub_column_names' => __( 'Column Names', 'wp-data-access' ),
344 'pub_format' => __( 'Format', 'wp-data-access' ),
345 'pub_query' => __( 'Query', 'wp-data-access' ),
346 'pub_sort_icons' => __( 'Sort Icons', 'wp-data-access' ),
347 'pub_styles' => __( 'Styling', 'wp-data-access' ),
348 'pub_style_premium' => __( 'Enable Premium Styling', 'wp-data-access' ),
349 'pub_style_user' => __( 'Custom Style', 'wp-data-access' ),
350 'pub_style_color' => __( 'Style Color', 'wp-data-access' ),
351 'pub_style_space' => __( 'Style Spacing', 'wp-data-access' ),
352 'pub_style_corner' => __( 'Style Corner', 'wp-data-access' ),
353 'pub_style_modal_width' => __( 'Modal Width', 'wp-data-access' ),
354 'pub_responsive' => __( 'Output', 'wp-data-access' ),
355 'pub_table_options_searching' => __( 'Searching?', 'wp-data-access' ),
356 'pub_table_options_ordering' => __( 'Ordering?', 'wp-data-access' ),
357 'pub_table_options_paging' => __( 'Paging?', 'wp-data-access' ),
358 'pub_table_options_serverside' => __( 'Server Side Processing?', 'wp-data-access' ),
359 'pub_table_options_nl2br' => __( 'NL > BR', 'wp-data-access' ),
360 'pub_table_options_advanced' => __( 'Advanced Options', 'wp-data-access' ),
361 'pub_default_where' => __( 'Default Where', 'wp-data-access' ),
362 'pub_default_orderby' => __( 'Default Order By', 'wp-data-access' ),
363 'pub_responsive_popup_title' => __( 'Popup Title', 'wp-data-access' ),
364 'pub_responsive_cols' => __( 'Responsive Cols', 'wp-data-access' ),
365 'pub_responsive_type' => __( 'Responsive Type', 'wp-data-access' ),
366 'pub_responsive_modal_hyperlinks' => __( 'Modal Hyperlinks', 'wp-data-access' ),
367 'pub_responsive_icon' => __( 'Responsive Icon?', 'wp-data-access' ),
368 'pub_flat_scrollx' => __( 'Horizontal Scrollbar', 'wp-data-access' ),
369 'pub_extentions' => __( 'Extensions', 'wp-data-access' ),
370 'pub_cpt' => __( 'Custom post type', 'wp-data-access' ),
371 'pub_cpt_fields' => __( 'Custom fields', 'wp-data-access' ),
372 'pub_cpt_query' => __( 'CPT query', 'wp-data-access' ),
373 'pub_cpt_format' => __( 'Field labels', 'wp-data-access' ),
374 );
375 }
376
377 // Overwrite method
378 public function show() {
379 parent::show();
380 WPDA::shortcode_popup();
381 ?>
382 <script type="application/javascript">
383 function test_publication(wpnonce, pub_id) {
384 if (jQuery('#data_publisher_test_container_' + pub_id).length>0) {
385 jQuery('#data_publisher_test_container_' + pub_id).show();
386 } else {
387 jQuery.ajax({
388 type: "POST",
389 url: "<?php
390 echo admin_url( 'admin-ajax.php?action=wpda_test_publication' );
391 // phpcs:ignore WordPress.Security.EscapeOutput
392 ?>",
393 data: {
394 wpnonce: wpnonce,
395 pub_id: pub_id
396 }
397 }).done(
398 function (html) {
399 jQuery("body").append(html);
400 jQuery('#data_publisher_test_container_' + pub_id).show();
401 }
402 );
403 }
404 }
405 jQuery(function() {
406 jQuery(".wpda_tooltip_cq").tooltip({
407 tooltipClass: "wpda_tooltip_cq wpda_tooltip_dashboard"
408 });
409 });
410 </script>
411 <style>
412 table.wp-list-table td.pub_data_source div {
413 overflow-x: hidden;
414 max-height: 70px;
415 overflow-y: auto;
416 }
417 .row-actions {
418 white-space: nowrap;
419 }
420 .wpda_tooltip_cq {
421 max-width: max-content;
422 }
423 </style>
424 <?php
425 }
426
427 }
428