PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.4
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.4
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 / WPDataProjects / Parent_Child / WPDP_Child_List_Table.php

WPDP_Child_List_Table.php in WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards 5.5.4, at WPDataProjects/Parent_Child/WPDP_Child_List_Table.php

490 lines 14.4 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 WPDataProjects\Parent_Child
7 */
8
9 namespace WPDataProjects\Parent_Child {
10
11 use WPDataAccess\Connection\WPDADB;
12 use WPDataAccess\WPDA;
13 use WPDataProjects\List_Table\WPDP_List_Table_Lookup;
14
15 /**
16 * Class WPDP_Child_List_Table extends WPDP_List_Table_Lookup
17 *
18 * @see WPDP_List_Table_Lookup
19 *
20 * @author Peter Schulz
21 * @since 2.0.0
22 */
23 class WPDP_Child_List_Table extends WPDP_List_Table_Lookup {
24
25 /**
26 * Possible values: edit and view
27 *
28 * @var string
29 */
30 protected $mode;
31
32 /**
33 * Parent key values
34 *
35 * @var array
36 */
37 protected $parent;
38
39 /**
40 * Child relationships (for actual parent)
41 *
42 * @var array
43 */
44 protected $child;
45
46 /**
47 * Tab value of actual child
48 *
49 * @var string
50 */
51 protected $child_tab = '';
52
53 /**
54 * Flexible usage of IN and NOT IN :-o
55 *
56 * @var string
57 */
58 protected $where_in = 'in'; // Just to save code! (opposite using in WPDP_Child_List_Table_Selection: not in)
59
60 /**
61 * Indicates that this is a list table for a child
62 *
63 * Parent and stand-alone list tables do not have this property.
64 *
65 * @var bool
66 */
67 public $is_child = true;
68
69 /**
70 * Overwrites WPDP_Child_List_Table constructor
71 *
72 * @param array $args
73 */
74 public function __construct( $args = array() ) {
75 if ( isset( $args['mode'] ) ) {
76 $this->mode = $args['mode'];
77 } else {
78 wp_die( __( 'ERROR: Wrong arguments [missing mode]', 'wp-data-access' ) );
79 }
80
81 if ( isset( $args['parent'] ) ) {
82 $this->parent = $args['parent'];
83 } else {
84 wp_die( __( 'ERROR: Wrong arguments [missing parent]', 'wp-data-access' ) );
85 }
86
87 if ( isset( $args['child'] ) ) {
88 $this->child = $args['child'];
89 } else {
90 wp_die( __( 'ERROR: Wrong arguments [missing child]', 'wp-data-access' ) );
91 }
92
93 $args['child_request'] = true;
94 $args['allow_insert'] = 'off';
95
96 if ( 'view' === $this->mode ) {
97 $args['allow_delete'] = 'off';
98 } else {
99 $args['allow_delete'] = 'on';
100 }
101
102 if ( 'edit' === $this->mode ) {
103 $args['bulk_actions_enabled'] = true;
104 } else {
105 $args['bulk_actions_enabled'] = false;
106 }
107
108 if ( isset( $_REQUEST['child_tab'] ) ) {
109 $this->child_tab = sanitize_text_field( wp_unslash( $_REQUEST['child_tab'] ) ); // input var okay.
110 }
111
112 $this->page_number_item_name = 'child_page_number';
113
114 parent::__construct( $args );
115
116 }
117
118 /**
119 * Overwrite method get_search_value to add parent arguments
120 *
121 * @param null $param_cookie_name
122 *
123 * @return string
124 */
125 protected function get_search_value( $param_cookie_name = null ) {
126 $parent_key_values = '';
127 foreach ( $this->parent['parent_key_value'] as $parent_key_value ) {
128 $parent_key_values .= esc_attr( $parent_key_value );
129 }
130
131 return parent::get_search_value(
132 $this->page . '_search_child_' . $parent_key_values .
133 str_replace( '.', '_', $this->table_name )
134 );
135 }
136
137 /**
138 * Overwrites method search_box to add parent arguments
139 *
140 * @param string $text
141 * @param string $input_id
142 */
143 public function search_box( $text, $input_id ) {
144 parent::search_box( $text, $input_id );
145
146 $this->add_parent_args();
147 }
148
149 /**
150 * Add parent arguments as hidden items
151 */
152 protected function add_parent_args() {
153 foreach ( $this->parent['parent_key'] as $parent_key ) {
154 ?>
155 <input type='hidden'
156 name='WPDA_PARENT_KEY*<?php echo( esc_attr( $parent_key ) ); ?>'
157 value='<?php echo( esc_attr( $this->parent['parent_key_value'][ $parent_key ] ) ); ?>'
158 />
159 <?php
160 }
161 ?>
162 <input type="hidden" name="mode" value="<?php echo esc_attr( $this->mode ); ?>">
163 <input type='hidden' name='child_request' value='TRUE'/>
164 <input type='hidden' name='child_tab' value='<?php echo esc_attr( $this->child_tab ); ?>'/>
165 <?php
166 if ( ! $this->has_items() ) {
167 ?>
168 <input type='hidden' name='action' value='-1'/>
169 <input type='hidden' name='action2' value='-1'/>
170 <input type='hidden' name='paged' value='1'/>
171 <?php
172 }
173 }
174
175 /**
176 * Add parent arguments as string
177 */
178 protected function add_parent_args_as_string( $item ) {
179 $parent_args = '';
180
181 foreach ( $this->parent['parent_key'] as $parent_key ) {
182 $p_key = esc_attr( $parent_key );
183 $p_val = esc_attr( $this->parent['parent_key_value'][ $parent_key ] );
184 $parent_args .= "<input type='hidden' name='WPDA_PARENT_KEY*$p_key' value='$p_val'/>";
185 }
186
187 $mode = esc_attr( $this->mode );
188 $child_tab = esc_attr( $this->child_tab );
189
190 $parent_args .= "<input type='hidden' name='mode' value='$mode'>";
191 $parent_args .= "<input type='hidden' name='child_request' value='TRUE'/>";
192 $parent_args .= "<input type='hidden' name='child_tab' value='$child_tab'/>";
193
194 if ( ! $this->has_items() ) {
195 $parent_args .= "<input type='hidden' name='action' value='-1'/>";
196 $parent_args .= "<input type='hidden' name='action2' value='-1'/>";
197 $parent_args .= "<input type='hidden' name='paged' value='1'/>";
198 }
199
200 return $parent_args;
201 }
202
203 /**
204 * Constructs the where clause depending on the relationship type
205 *
206 * Adds a subquery for n:m relationships. Adds parent key value comparison for 1:n relationships.
207 */
208 protected function construct_where_clause() {
209 $wpdadb = WPDADB::get_db_connection( $this->schema_name );
210 if ( null === $wpdadb ) {
211 if ( is_admin() ) {
212 wp_die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
213 } else {
214 die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
215 }
216 }
217
218 if (
219 isset( $this->child['default_where'] ) &&
220 null !== $this->child['default_where'] &&
221 '' !== trim( $this->child['default_where'] )
222 ) {
223 $default_where = " and ( {$this->child['default_where']} ) ";
224 $default_where = WPDA::substitute_environment_vars( $default_where );
225 } else {
226 $default_where = '';
227 }
228
229 if ( isset( $this->child['relation_nm'] ) ) {
230 $child_table = $this->child['relation_nm']['child_table'];
231 $parent_key = $this->child['relation_nm']['parent_key'];
232 $child_table_select = $this->child['relation_nm']['child_table_select'];
233 $child_table_where = $this->child['relation_nm']['child_table_where'];
234 $data_type = $this->child['relation_nm']['data_type'];
235
236 $parent_key_column_names = '';
237 $select_column_names = '';
238 $index = 0;
239
240 foreach ( $parent_key as $key ) {
241 if ( $key === reset( $parent_key ) ) {//phpcs:ignore - 8.1 proof
242 $parent_key_column_names .= "(`$key`";
243 $select_column_names .= '`' . $child_table_select[ $index ] . '`';
244 } else {
245 $parent_key_column_names .= ",`$key`";
246 $select_column_names .= ', `' . $child_table_select[ $index ] . '`';
247 }
248 $index ++;
249 }
250 $parent_key_column_names .= ')';
251
252 $index = 0;
253 $where = '';
254
255 foreach ( $child_table_where as $child_where ) {
256 if ( $child_where === reset( $child_table_where ) ) {//phpcs:ignore - 8.1 proof
257 $and = '';
258 } else {
259 $and = ' and ';
260 }
261 if ( 'number' === strtolower( $data_type[ $index ] ) ) {
262 $where .=
263 $wpdadb->prepare(
264 " $and `$child_where` = %f ",
265 $this->parent['parent_key_value'][ $this->parent['parent_key'][ $index ] ]
266 ); // phpcs:ignore Standard.Category.SniffName.ErrorCode
267 } else {
268 $where .=
269 $wpdadb->prepare(
270 " $and `$child_where` = %s ",
271 $this->parent['parent_key_value'][ $this->parent['parent_key'][ $index ] ]
272 ); // phpcs:ignore Standard.Category.SniffName.ErrorCode
273 }
274 $index ++;
275 }
276
277 if ( '' === $this->schema_name ) {
278 $schema_table_name = "`$child_table`";
279 } else {
280 $schema_table_name = "`{$wpdadb->dbname}`.`$child_table`";
281 }
282
283 $this->where =
284 " where ($parent_key_column_names {$this->where_in} " .
285 " (select $select_column_names from $schema_table_name where $where)) "; // phpcs:ignore Standard.Category.SniffName.ErrorCode
286 } elseif ( isset( $this->child['relation_1n'] ) ) {
287 $child_key = $this->child['relation_1n']['child_key'];
288 $data_type = $this->child['relation_1n']['data_type'];
289
290 if (
291 isset( $this->child['relation_1n']['parent_key'] ) &&
292 is_array( $this->child['relation_1n']['parent_key'] )
293 ) {
294 $parent_key = $this->child['relation_1n']['parent_key'];
295 } else {
296 $parent_key = null;
297 }
298
299 $index = 0;
300 $where = '';
301
302 foreach ( $child_key as $key ) {
303 if ( $key === reset( $child_key ) ) {//phpcs:ignore - 8.1 proof
304 $and = '';
305 } else {
306 $and = ' and ';
307 }
308
309 if ( null === $parent_key ) {
310 $parent_key_value = $this->parent['parent_key_value'][ $this->parent['parent_key'][ $index ] ];
311 } else {
312 if ( $parent_key == $this->parent['parent_key'] ) {
313 $parent_key_value = $this->parent['parent_key_value'][ $this->parent['parent_key'][ $index ] ];
314 } else {
315 if ( isset( $_REQUEST[ 'WPDA_PARENT_KEY*' . $parent_key[ $index ] ] ) ) {
316 $parent_key_value = sanitize_text_field( wp_unslash( $_REQUEST[ 'WPDA_PARENT_KEY*' . $parent_key[ $index ] ] ) ); // input var okay.
317 } elseif ( isset( $_REQUEST[ $parent_key[ $index ] ] ) ) {
318 $parent_key_value = sanitize_text_field( wp_unslash( $_REQUEST[ $parent_key[ $index ] ] ) ); // input var okay.
319 } else {
320 wp_die( '<p style="clear: both; padding: 10px;">' . __( 'ERROR: No value for parent key found', 'wp-data-access' ) . '</p>' );
321 }
322 }
323 }
324
325 if ( isset( $data_type[ $index ] ) && 'number' === strtolower( $data_type[ $index ] ) ) {
326 $where .= $wpdadb->prepare(
327 " $and `$key` = %f ",
328 $parent_key_value
329 ); // phpcs:ignore Standard.Category.SniffName.ErrorCode
330 } else {
331 $where .= $wpdadb->prepare(
332 " $and `$key` = %s ",
333 $parent_key_value
334 ); // phpcs:ignore Standard.Category.SniffName.ErrorCode
335 }
336
337 $index++;
338 }
339
340 $this->where = " where ($where) "; // phpcs:ignore Standard.Category.SniffName.ErrorCode
341 }
342
343 // Add default where
344 $this->where .= $default_where;
345
346 parent::construct_where_clause();
347 }
348
349 protected function get_order_by() {
350 $orderby = parent::get_order_by();
351 if ( '' !== $orderby ) {
352 return $orderby;
353 }
354
355 if (
356 isset( $this->child['default_orderby'] ) &&
357 null !== $this->child['default_orderby'] &&
358 '' !== trim( $this->child['default_orderby'] )
359 ) {
360 $default_orderby = " order by {$this->child['default_orderby']} ";
361 } else {
362 $default_orderby = '';
363 }
364
365 // Add default order by
366 return $default_orderby; // phpcs:ignore Standard.Category.SniffName.ErrorCode
367 }
368
369 /**
370 * Overwrites method column_default_add_action
371 *
372 * Adds parent arguments
373 *
374 * @param array $item
375 * @param string $column_name
376 * @param array $actions
377 */
378 protected function column_default_add_action( $item, $column_name, &$actions ) {
379 $form_id = '_' . ( self::$list_number - 1 );
380 if ( isset( $this->child['relation_nm'] ) ) {
381 $link_label = __( 'Delete Relationship', 'wp-data-access' );
382 $link_title = __( 'Delete child row (this only affects the relationship table)', 'wp-data-access' );
383 } else {
384 $link_label = __( 'Delete', 'wp-data-access' );
385 $link_title = __( 'Delete child row', 'wp-data-access' );
386 }
387 $warning = __( "You are about to permanently delete these items from your site.\\nThis action cannot be undone.\\n\\'Cancel\\' to stop, \\'OK\\' to delete.", 'wp-data-access' );
388 $actions['delete'] = sprintf(
389 '<a href="javascript:void(0)"
390 class="delete wpda_tooltip"
391 title="%s"
392 onclick="if (confirm(\'%s\')) jQuery(\'#%s\').submit()">
393 <span style="white-space:nowrap">
394 <i class="fas fa-trash wpda_icon_on_button"></i>
395 %s
396 </span>
397 </a>
398 ',
399 $link_title,
400 $warning,
401 "delete_form$form_id",
402 $link_label
403 );
404 }
405
406 /**
407 * Overwrites method get_bulk_actions
408 *
409 * Adds 'Delete Relationship' action for n:m relationships and 'Delete' action for 1:n relationships to bulk
410 * listbox.
411 *
412 * @return array|string
413 */
414 public function get_bulk_actions() {
415 if ( ! $this->bulk_actions_enabled ) {
416 // Bulk actions disabled.
417 return '';
418 }
419
420 if ( empty( $this->wpda_list_columns->get_table_primary_key() ) ) {
421 // Tables has no primary key: no bulk actions allowed!
422 // Primary key is necessary to ensure uniqueness.
423 return '';
424 }
425
426 $actions = parent::get_bulk_actions();
427
428 if ( isset( $this->child['relation_nm'] ) ) {
429 $actions['bulk-delete'] = __( 'Delete Relationship', 'wp-data-access' );
430 } else {
431 $actions['bulk-delete'] = __( 'Delete', 'wp-data-access' );
432 }
433
434 return $actions;
435 }
436
437 /**
438 * Overwrite method delete_row
439 *
440 * Adds parent arguments
441 *
442 * @param string $where where clause
443 * @param string $engine connect or empty
444 *
445 * @return mixed
446 */
447 public function delete_row( $where, $engine = '' ) {
448 // Expand named array with parent key for delete operation.
449 $next_row_to_be_deleted = array();
450 $i = 0;
451 foreach ( $where as $key => $value ) {
452 if ( isset( $this->child['relation_nm'] ) ) {
453 $next_row_to_be_deleted[ $this->child['relation_nm']['child_table_select'][ $i ] ] = $value;
454 $next_row_to_be_deleted[ $this->child['relation_nm']['child_table_where'][ $i ] ] =
455 $this->parent['parent_key_value'][ $this->parent['parent_key'][ $i ] ];
456 } else {
457 $next_row_to_be_deleted[ $key ] = $value;
458 }
459 $i ++;
460 }
461
462 if ( isset( $this->child['relation_nm'] ) ) {
463 $table_name = $this->child['relation_nm']['child_table'];
464 } else {
465 $table_name = $this->table_name;
466 }
467
468 $wpdadb = WPDADB::get_db_connection( $this->schema_name );
469 if ( null === $wpdadb ) {
470 if ( is_admin() ) {
471 wp_die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
472 } else {
473 die( sprintf( __( 'ERROR - Remote database %s not available', 'wp-data-access' ), esc_attr( $this->schema_name ) ) );
474 }
475 }
476
477 $row_deleted = $wpdadb->delete( $table_name, $next_row_to_be_deleted ); // db call ok; no-cache ok.
478
479 if ( 'connect' === strtolower( $engine ) ) {
480 // Connect engine does not return number of rows deleted
481 // Presuming delete was successful when no error message was returned
482 return '' === $wpdadb->last_error;
483 }
484 return $row_deleted;
485 }
486
487 }
488
489 }
490