PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.84
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.84
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 5.5.42 All 160 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.84, at WPDataAccess/Data_Publisher/WPDA_Publisher_List_Table.php

418 lines 17.7 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 // phpcs:ignore PluginCheck.CodeAnalysis.Heredoc.NotAllowed
124 $copy_form = <<<EOT
125 \t\t\t\t<form id='copy_form{$esc_attr( $form_id )}' method='post'
126 \t\t\t\t\t action='?page={$esc_attr( $this->page )}'
127 \t\t\t\t>
128 \t\t\t\t\t{$input_fields}
129 \t\t\t\t\t<input type='hidden' name='table_name' value='{$esc_attr( $this->table_name )}'>
130 \t\t\t\t\t<input type='hidden' name='action' value='copy' />
131 \t\t\t\t\t<input type='hidden' name='_wpnonce' value='{$esc_attr( $wp_nonce )}'>
132 \t\t\t\t\t{$page_field}
133 \t\t\t\t</form>
134 EOT;
135 ?>
136
137 <script type='text/javascript'>
138 jQuery("#wpda_invisible_container").append("<?php
139 // phpcs:disable WordPress.Security.EscapeOutput
140 echo str_replace( array("\n", "\r"), '', $copy_form );
141 // phpcs:enable WordPress.Security.EscapeOutput
142 ?>");
143 </script>
144
145 <?php
146 $copy_warning = __( "Copy table options set?\\n\\'Cancel\\' to stop, \\'OK\\' to copy.", 'wp-data-access' );
147 $actions['copy'] = sprintf(
148 '<a href="javascript:void(0)"
149 title="%s"
150 class="edit wpda_tooltip"
151 onclick="if (confirm(\'%s\')) jQuery(\'#%s\').submit()">
152 <span style="white-space: nowrap">
153 <i class="fas fa-copy wpda_icon_on_button"></i>
154 %s
155 </span>
156 </a>
157 ',
158 __( 'Copy: new table name = old table name_ + n', 'wp-data-access' ),
159 $copy_warning,
160 "copy_form{$form_id}",
161 __( 'Copy', 'wp-data-access' )
162 );
163 // Show Data Table shortcode directly from Data Tables main page
164 $shortcode_enabled = 'on' === WPDA::get_option( WPDA::OPTION_PLUGIN_WPDATAACCESS_POST ) && 'on' === WPDA::get_option( WPDA::OPTION_PLUGIN_WPDATAACCESS_PAGE );
165 ?>
166 <div id="wpda_publication_<?php
167 echo esc_attr( $item['pub_id'] );
168 ?>"
169 title="<?php
170 echo esc_attr__( 'Shortcode', 'wp-data-access' );
171 ?>"
172 style="display:none"
173 >
174 <p class="wpda_shortcode_content">
175 Copy the shortcode below into your post or page to make this data table available on your website.
176 </p>
177 <p class="wpda_shortcode_text">
178 <strong>
179 [wpdataaccess pub_id="<?php
180 echo esc_attr( $item['pub_id'] );
181 ?>"]
182 </strong>
183 </p>
184 <p class="wpda_shortcode_buttons">
185 <button class="button wpda_shortcode_clipboard wpda_shortcode_button"
186 type="button"
187 data-clipboard-text='[wpdataaccess pub_id="<?php
188 echo esc_attr( $item['pub_id'] );
189 ?>"]'
190 onclick="jQuery.notify('<?php
191 echo esc_attr__( 'Shortcode successfully copied to clipboard!', 'wp-data-access' );
192 ?>','info')"
193 >
194 <?php
195 echo esc_attr__( 'Copy', 'wp-data-access' );
196 ?>
197 </button>
198 <button class="button button-primary wpda_shortcode_button"
199 type="button"
200 onclick="jQuery('.ui-dialog-content').dialog('close')"
201 >
202 <?php
203 echo esc_attr__( 'Close', 'wp-data-access' );
204 ?>
205 </button>
206 </p>
207 <?php
208 if ( !$shortcode_enabled ) {
209 ?>
210 <p>
211 Shortcode wpdataaccess is not enabled for all output types.
212 <a href="<?php
213 echo esc_url( admin_url( 'options-general.php' ) );
214 ?>?page=wpdataaccess" class="wpda_shortcode_link">&raquo; Manage settings</a>
215 </p>
216 <?php
217 }
218 ?>
219 </div>
220 <?php
221 $actions['shortcode'] = sprintf(
222 '<a href="javascript:void(0)"
223 class="view wpda_tooltip"
224 title="%s"
225 onclick="jQuery(\'#wpda_publication_%s\').dialog()"
226 <span style="white-space:nowrap">
227 <i class="fas fa-code wpda_icon_on_button"></i>
228 %s
229 </span>
230 </a>
231 ',
232 __( 'Get shortcode', 'wp-data-access' ),
233 esc_attr( $item['pub_id'] ),
234 __( 'Shortcode', 'wp-data-access' )
235 );
236 $actions['test'] = sprintf(
237 '<a href="javascript:void(0)"
238 class="view wpda_tooltip"
239 title="%s"
240 onclick="test_publication(\'%s\', \'%s\')"
241 <span style="white-space:nowrap">
242 <i class="fas fa-bug wpda_icon_on_button"></i>
243 %s
244 </span>
245 </a>
246 ',
247 __( 'Test', 'wp-data-access' ),
248 esc_attr( wp_create_nonce( "wpda-publication-{$item['pub_id']}" ) ),
249 esc_attr( $item['pub_id'] ),
250 __( 'Test', 'wp-data-access' )
251 );
252 }
253
254 public function process_bulk_action() {
255 if ( 'copy' === $this->current_action() ) {
256 $wp_nonce_action = "wpda-copy-{$this->table_name}";
257 $wp_nonce = ( isset( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ) : '' );
258 // input var okay.
259 if ( !wp_verify_nonce( $wp_nonce, $wp_nonce_action ) ) {
260 die( esc_attr__( 'ERROR: Not authorized', 'wp-data-access' ) );
261 }
262 if ( isset( $_REQUEST['pub_id'] ) ) {
263 $pub_id = sanitize_text_field( wp_unslash( $_REQUEST['pub_id'] ) );
264 // input var okay.
265 }
266 $unique_pu_name = $this->get_unique_pub_name( $pub_id );
267 global $wpdb;
268 // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders
269 $pub_raw = $wpdb->get_results( $wpdb->prepare( 'SELECT * FROM `%1s` WHERE pub_id = %d', array(WPDA::remove_backticks( $this->table_name ), $pub_id) ), 'ARRAY_A' );
270 // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders
271 if ( $wpdb->num_rows > 0 ) {
272 $pub_raw[0]['pub_name'] = $unique_pu_name;
273 unset($pub_raw[0]['pub_id']);
274 // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
275 $rows_inserted = $wpdb->insert( $this->table_name, $pub_raw[0] );
276 // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
277 switch ( $rows_inserted ) {
278 case 0:
279 $msg = new WPDA_Message_Box(array(
280 'message_text' => __( 'Could not copy data table [source not found]', 'wp-data-access' ),
281 'message_type' => 'error',
282 'message_is_dismissible' => false,
283 ));
284 $msg->box();
285 break;
286 case 1:
287 $msg = new WPDA_Message_Box(array(
288 'message_text' => __( 'Data table copied', 'wp-data-access' ),
289 ));
290 $msg->box();
291 break;
292 default:
293 $msg = new WPDA_Message_Box(array(
294 'message_text' => __( 'Could not copy data table [too many rows]', 'wp-data-access' ),
295 'message_type' => 'error',
296 'message_is_dismissible' => false,
297 ));
298 $msg->box();
299 }
300 }
301 } else {
302 parent::process_bulk_action();
303 }
304 }
305
306 protected function get_unique_pub_name( $pub_id ) {
307 global $wpdb;
308 // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders
309 $db_pub_name = $wpdb->get_results( $wpdb->prepare( 'select pub_name from `%1s` where pub_id = %d', array(WPDA::remove_backticks( WPDA_Publisher_Model::get_base_table_name() ), $pub_id) ), 'ARRAY_A' );
310 if ( $wpdb->num_rows !== 1 ) {
311 wp_die( esc_attr__( 'ERROR: Data table not found', 'wp-data-access' ) );
312 }
313 $i = 2;
314 $pub_name = $db_pub_name[0]['pub_name'];
315 $unique_pub_name = "{$pub_name}_{$i}";
316 $wpdb->get_results( $wpdb->prepare( "select 'x' from `%1s` where pub_name = %s", array(WPDA::remove_backticks( WPDA_Publisher_Model::get_base_table_name() ), $unique_pub_name) ) );
317 while ( $wpdb->num_rows > 0 ) {
318 // Search until a free options set is found
319 $i++;
320 $unique_pub_name = "{$pub_name}_{$i}";
321 $wpdb->get_results( $wpdb->prepare( "select 'x' from `%1s` where pub_name = %s", array(WPDA::remove_backticks( WPDA_Publisher_Model::get_base_table_name() ), $unique_pub_name) ) );
322 }
323 // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQLPlaceholders
324 return $unique_pub_name;
325 }
326
327 public static function column_headers_labels() {
328 return array(
329 'pub_id' => __( 'ID', 'wp-data-access' ),
330 'pub_name' => __( 'Name', 'wp-data-access' ),
331 'pub_schema_name' => __( 'Database', 'wp-data-access' ),
332 'pub_data_source' => __( 'Data Source', 'wp-data-access' ),
333 'pub_table_name' => __( 'Table/View Name', 'wp-data-access' ),
334 'pub_column_names' => __( 'Column Names', 'wp-data-access' ),
335 'pub_format' => __( 'Format', 'wp-data-access' ),
336 'pub_query' => __( 'Query', 'wp-data-access' ),
337 'pub_sort_icons' => __( 'Sort Icons', 'wp-data-access' ),
338 'pub_styles' => __( 'Styling', 'wp-data-access' ),
339 'pub_style_premium' => __( 'Enable Premium Styling', 'wp-data-access' ),
340 'pub_style_user' => __( 'Custom Style', 'wp-data-access' ),
341 'pub_style_color' => __( 'Style Color', 'wp-data-access' ),
342 'pub_style_space' => __( 'Style Spacing', 'wp-data-access' ),
343 'pub_style_corner' => __( 'Style Corner', 'wp-data-access' ),
344 'pub_style_modal_width' => __( 'Modal Width', 'wp-data-access' ),
345 'pub_responsive' => __( 'Output', 'wp-data-access' ),
346 'pub_table_options_searching' => __( 'Searching?', 'wp-data-access' ),
347 'pub_table_options_ordering' => __( 'Ordering?', 'wp-data-access' ),
348 'pub_table_options_paging' => __( 'Paging?', 'wp-data-access' ),
349 'pub_table_options_serverside' => __( 'Server Side Processing?', 'wp-data-access' ),
350 'pub_table_options_nl2br' => __( 'NL > BR', 'wp-data-access' ),
351 'pub_table_options_advanced' => __( 'Advanced Options', 'wp-data-access' ),
352 'pub_default_where' => __( 'Default Where', 'wp-data-access' ),
353 'pub_default_orderby' => __( 'Default Order By', 'wp-data-access' ),
354 'pub_responsive_popup_title' => __( 'Popup Title', 'wp-data-access' ),
355 'pub_responsive_cols' => __( 'Responsive Cols', 'wp-data-access' ),
356 'pub_responsive_type' => __( 'Responsive Type', 'wp-data-access' ),
357 'pub_responsive_modal_hyperlinks' => __( 'Modal Hyperlinks', 'wp-data-access' ),
358 'pub_responsive_icon' => __( 'Responsive Icon?', 'wp-data-access' ),
359 'pub_flat_scrollx' => __( 'Horizontal Scrollbar', 'wp-data-access' ),
360 'pub_extentions' => __( 'Extensions', 'wp-data-access' ),
361 'pub_cpt' => __( 'Custom post type', 'wp-data-access' ),
362 'pub_cpt_fields' => __( 'Custom fields', 'wp-data-access' ),
363 'pub_cpt_query' => __( 'CPT query', 'wp-data-access' ),
364 'pub_cpt_format' => __( 'Field labels', 'wp-data-access' ),
365 );
366 }
367
368 // Overwrite method
369 public function show() {
370 parent::show();
371 WPDA::shortcode_popup();
372 ?>
373 <script type="application/javascript">
374 function test_publication(wpnonce, pub_id) {
375 if (jQuery('#data_publisher_test_container_' + pub_id).length>0) {
376 jQuery('#data_publisher_test_container_' + pub_id).show();
377 } else {
378 jQuery.ajax({
379 type: "POST",
380 url: "<?php
381 echo esc_url( admin_url( 'admin-ajax.php?action=wpda_test_publication' ) );
382 ?>",
383 data: {
384 wpnonce: wpnonce,
385 pub_id: pub_id
386 }
387 }).done(
388 function (html) {
389 jQuery("body").append(html);
390 jQuery('#data_publisher_test_container_' + pub_id).show();
391 }
392 );
393 }
394 }
395 jQuery(function() {
396 jQuery(".wpda_tooltip_cq").tooltip({
397 tooltipClass: "wpda_tooltip_cq wpda_tooltip_dashboard"
398 });
399 });
400 </script>
401 <style>
402 table.wp-list-table td.pub_data_source div {
403 overflow-x: hidden;
404 max-height: 70px;
405 overflow-y: auto;
406 }
407 .row-actions {
408 white-space: nowrap;
409 }
410 .wpda_tooltip_cq {
411 max-width: max-content;
412 }
413 </style>
414 <?php
415 }
416
417 }
418