PluginProbe
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards / 5.5.40
WP Data Access – App Builder for Tables, Forms, Charts, Maps & Dashboards v5.5.40
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_Parent_Form.php

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

561 lines 16.6 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\Data_Dictionary\WPDA_List_Columns_Cache;
12 use WPDataProjects\Data_Dictionary\WPDP_List_Columns_Cache;
13 use WPDataProjects\Simple_Form\WPDP_Simple_Form;
14
15 /**
16 * Class WPDP_Parent_Form extends WPDP_Simple_Form
17 *
18 * This class presumes the existence of (a) child relationship(s) (1:n or n:m). While the parent is maintained in
19 * the top of the page, child relationship(s) are maintained below the parent. If multiple child relationships are
20 * found, the user can switch between them via tabs.
21 *
22 * @see WPDP_Simple_Form
23 *
24 * @author Peter Schulz
25 * @since 2.0.0
26 */
27 class WPDP_Parent_Form extends WPDP_Simple_Form {
28
29 /**
30 * Possible values: edit and view
31 *
32 * @var string
33 */
34 protected $mode;
35
36 /**
37 * Parent key(s) column names
38 *
39 * @var array
40 */
41 protected $parent_key = array();
42 /**
43 * Parent key(s) values
44 *
45 * @var array
46 */
47 protected $parent_key_value = array();
48
49 /**
50 * Child relationships
51 *
52 * @var array
53 */
54 protected $children = array();
55
56 /**
57 * Tabs (1 for every child)
58 *
59 * @var array
60 */
61 protected $tabs = array();
62
63 /**
64 * Current tab
65 *
66 * @var string
67 */
68 protected $current_tab = null;
69
70 /**
71 * Requested child action
72 *
73 * @var string
74 */
75 protected $child_action;
76
77 /**
78 * Possible values: TRUE and null
79 *
80 * TRUE = request is a child request
81 * All other values (including null) = request is a parent request
82 *
83 * @var mixed
84 */
85 protected $child_request;
86
87 /**
88 * Relationships found for actual parent
89 *
90 * @var array
91 */
92 protected $relations;
93
94 /**
95 * Class used to instantiate edit form
96 *
97 * @var mixed|string
98 */
99 protected $edit_form_class = 'WPDataProjects\\Parent_Child\\WPDP_Child_Form';
100
101 /**
102 * Class used to instantiate list table
103 *
104 * @var mixed|string
105 */
106 protected $list_table_class = 'WPDataProjects\\Parent_Child\\WPDP_Child_List_Table';
107
108 /**
109 * Action value during post (saved because it might change during request processing)
110 *
111 * @var string
112 */
113 protected $action_posted;
114
115 /**
116 * Overwrites WPDP_Parent_Form constructor
117 *
118 * @param string $schema_name Database schema name
119 * @param string $table_name Database table name
120 * @param object $wpda_list_columns Handle to WPDP_List_Columns object
121 * @param array $args Arguments
122 * @param array $relationship Relationships
123 */
124 public function __construct(
125 $schema_name,
126 $table_name,
127 &$wpda_list_columns,
128 $args = array(),
129 $relationship = array()
130 ) {
131 if ( isset( $args['mode'] ) ) {
132 $this->mode = $args['mode'];
133 } else {
134 wp_die( __( 'ERROR: Wrong arguments [missing mode]', 'wp-data-access' ) );
135 }
136
137 if ( isset( $args['child_request'] ) ) {
138 $this->child_request = $args['child_request'];
139 } else {
140 wp_die( __( 'ERROR: Wrong arguments [missing child_request]', 'wp-data-access' ) );
141 }
142
143 $action = null;
144 if ( isset( $_REQUEST['action'] ) ) {
145 // Possible values: "new", "edit" and "view".
146 $action = sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ); // input var okay.
147 $this->action_posted = $action;
148 } elseif ( isset( $args['action'] ) ) {
149 $action = $args['action'];
150 $this->action_posted = $action;
151 }
152
153 $this->relations = $relationship;
154
155 $args['back_to_list_text'] = __( 'Parent List', 'wp-data-access' );
156
157 parent::__construct( $schema_name, $table_name, $wpda_list_columns, $args );
158
159 if ( 'new' !== $action || $this->child_request ) {
160 if ( isset( $this->relations['parent']['key'] ) && is_array( $this->relations['parent']['key'] ) ) {
161 foreach ( $this->relations['parent']['key'] as $key ) {
162 if ( isset( $_REQUEST[ 'WPDA_PARENT_KEY*' . $key ] ) ) {
163 array_push( $this->parent_key, $key );//phpcs:ignore - 8.1 proof
164 $this->parent_key_value[ $key ] = sanitize_text_field( wp_unslash( $_REQUEST[ 'WPDA_PARENT_KEY*' . $key ] ) ); // input var okay.
165 } elseif ( isset( $_REQUEST[ $key ] ) ) {
166 array_push( $this->parent_key, $key );//phpcs:ignore - 8.1 proof
167 $this->parent_key_value[ $key ] = sanitize_text_field( wp_unslash( $_REQUEST[ $key ] ) ); // input var okay.
168 }
169
170 if ( is_array( $this->relations['children'] ) ) {
171 $this->children = $this->relations['children'];
172 }
173 }
174 }
175 }
176
177 $this->set_child_action_member();
178 if ( $this->child_request ) {
179 if ( 'list' === $this->action || '-1' === $this->action ) {
180 $this->action = 'edit';
181 } else {
182 $this->action = 'view';
183 }
184 }
185 if ( 'view' === $this->mode ) {
186 $this->action = 'view';
187 }
188
189 foreach ( $this->children as $child ) {
190 if ( null === $this->current_tab ) {
191 $this->current_tab = $child['table_name'];
192 }
193
194 $this->tabs[ $child['table_name'] ] = $child['tab_label'];
195
196 if ( isset( $child['relation_nm'] ) ) {
197 $this->relations[ $child['table_name'] ]['relation_nm'] = $child['relation_nm'];
198 } elseif ( isset( $child['relation_1n'] ) ) {
199 $this->relations[ $child['table_name'] ]['relation_1n'] = $child['relation_1n'];
200 }
201 }
202
203 if ( isset( $_REQUEST['child_tab'] ) ) {
204 if ( isset( $this->tabs[ $_REQUEST['child_tab'] ] ) ) {
205 $this->current_tab = sanitize_text_field( wp_unslash( $_REQUEST['child_tab'] ) ); // input var okay.
206 }
207 }
208
209 if ( isset( $args['edit_form_class'] ) ) {
210 $this->edit_form_class = $args['edit_form_class'];
211 }
212
213 if ( isset( $args['list_form_class'] ) ) {
214 $this->list_table_class = $args['list_form_class'];
215 }
216 }
217
218 /**
219 * Overwrite method to add show less/more functionality
220 *
221 * @param bool $set_back_form_values
222 */
223 protected function prepare_items( $set_back_form_values = false ) {
224 parent::prepare_items( $set_back_form_values );
225
226 foreach ( $this->wpda_list_columns->get_table_columns() as $columns ) {
227 if ( isset( $columns['less'] ) && ! $columns['less'] ) {
228 foreach ( $this->form_items as $item ) {
229 if ( $item->get_item_name() === $columns['column_name'] ) {
230 $item->set_item_class( 'row-show-less-more' );
231 }
232 }
233 }
234 }
235 }
236
237 /**
238 * Determine and set action to be performed on child
239 */
240 protected function set_child_action_member() {
241 if ( $this->child_request ) {
242 if ( '-1' === $this->action ) {
243 $this->child_action = $this->action2;
244 } else {
245 $this->child_action = $this->action;
246 }
247 } else {
248 $this->child_action = 'list';
249 }
250 }
251
252 /**
253 * Overwrite method show
254 *
255 * @param bool $allow_save
256 * @param string $add_param
257 *
258 * @see WPDP_Simple_Form::show()
259 */
260 public function show( $allow_save = true, $add_param = '' ) {
261 if ( $this->child_request ) {
262 parent::show( false, $add_param );
263 } else {
264 parent::show( $allow_save, $add_param );
265 }
266 if ( 'new' === $this->action_posted && 'edit' === parent::get_form_action() ) {
267 // Record successfully inserted: reload page to show tabs
268 ?>
269 <script>
270 jQuery("#wpda_simple_form_0 input[name='wpda_message']").val("<?php echo __( 'Succesfully saved changes to database', 'wp-data-access' ); ?>");
271 jQuery("#wpda_simple_form_0").submit();
272 </script>
273 <?php
274 }
275 $this->add_tabs();
276 foreach ( $this->children as $child ) {
277 if ( $child['table_name'] === $this->current_tab ) {
278 if ( 'edit' === $this->child_action || 'new' === $this->child_action || 'view' === $this->child_action ) {
279 $this->show_child_form( $child['table_name'], $child );
280 } else {
281 $this->show_child_list_table( $child['table_name'], $child );
282 }
283 }
284 }
285 }
286
287 /**
288 * Show child form
289 *
290 * @param string $child_table_name Database table name
291 * @param array $child Child info
292 */
293 protected function show_child_form( $child_table_name, $child ) {
294 if (
295 'edit' === $this->mode &&
296 ( 'new' === $this->child_action || 'edit' === $this->child_action ) &&
297 ( ! ( isset( $_POST['postaction'] ) && 'childlist' === $_POST['postaction'] ) )
298 ) {
299 $this->button_add_new( $child, $child_table_name );
300 echo '<div style="clear:both;"></div>';
301 }
302 $wpda_list_columns = WPDP_List_Columns_Cache::get_list_columns( $this->schema_name, $child_table_name, 'tableform', $this->setname );
303 $wpda_child_form = new $this->edit_form_class(
304 $this->schema_name,
305 $child_table_name,
306 $wpda_list_columns,
307 array(
308 'show_title' => false,
309 'show_back_button' => true,
310 'mode' => $this->mode,
311 'parent' => array(
312 'parent_key' => $this->parent_key,
313 'parent_key_value' => $this->parent_key_value,
314 ),
315 'child' => $child,
316 'back_to_list_text' => __( 'Child List', 'wp-data-access' ),
317 )
318 );
319
320 $wpda_child_form->prepare_form();
321
322 if ( isset( $_POST['postaction'] ) && 'childlist' === $_POST['postaction'] ) {
323 $this->show_child_list_table( $child_table_name, $child );
324 } else {
325 $wpda_child_form->show();
326 }
327 }
328
329 /**
330 * Show child list table
331 *
332 * @param string $child_table_name Database table name
333 * @param array $child Child info
334 */
335 protected function show_child_list_table( $child_table_name, $child ) {
336 $is_list_table_selection = isset( $_REQUEST['list_table_selection'] );
337 if ( 'edit' === $this->mode ) {
338 $this->button_add_new( $child, $child_table_name );
339 }
340 if ( $is_list_table_selection || 'add' === $this->child_action || 'bulk-add' === $this->child_action ) {
341 $list_table_class = 'WPDataProjects\\Parent_Child\\WPDP_Child_List_Table_Selection';
342 } else {
343 $list_table_class = $this->list_table_class;
344 }
345 $wpda_list_columns = WPDP_List_Columns_Cache::get_list_columns( $this->schema_name, $child_table_name, 'listtable', $this->setname );
346 $wpda_list_table = new $list_table_class(
347 array(
348 'wpdaschema_name' => $this->schema_name,
349 'table_name' => $child_table_name,
350 'wpda_list_columns' => $wpda_list_columns,
351 'mode' => $this->mode,
352 'title' => '',
353 'subtitle' => '',
354 'allow_import' => 'off',
355 'parent' => array(
356 'parent_key' => $this->parent_key,
357 'parent_key_value' => $this->parent_key_value,
358 ),
359 'child' => $child,
360 )
361 );
362 $wpda_list_table->show();
363 }
364
365 /**
366 * Add a tab for every child
367 */
368 protected function add_tabs() {
369 if ( count( $this->children ) > 0 ) {//phpcs:ignore - 8.1 proof
370 ?>
371 <h2 class="nav-tab-wrapper">
372 <?php
373 $requested_page_number = 1;
374 if ( isset( $_REQUEST['page_number'] ) ) {
375 $requested_page_number = sanitize_text_field( wp_unslash( $_REQUEST['page_number'] ) ); // input var okay.
376 }
377 foreach ( $this->tabs as $tab => $name ) {
378 $class = ( $tab === $this->current_tab ) ? ' nav-tab-active' : '';
379 $id_from_name = preg_replace( '/[^a-zA-Z0-9]/', '', $name );
380
381 if ( is_admin() ) {
382 $url = "?page={$this->page}";
383 } else {
384 $url = '';
385 }
386 ?>
387 <form action="<?php echo esc_attr( $url ); ?>"
388 method="post"
389 id="form_tab_<?php echo esc_attr( $id_from_name ); ?>"
390 >
391 <a class="nav-tab<?php echo esc_attr( $class ); ?>"
392 href="javascript:void(0)"
393 onclick="jQuery('#form_tab_<?php echo esc_attr( $id_from_name ); ?>').submit()"
394 >
395 <?php echo esc_attr( $name ); ?>
396 <?php $this->add_parent_keys(); ?>
397 <input type="hidden" name="action" value="list">
398 <input type="hidden" name="mode" value="<?php echo esc_attr( $this->mode ); ?>">
399 <input type='hidden' name='child_request' value='TRUE'/>
400 <input type="hidden" name="child_tab" value="<?php echo esc_attr( $tab ); ?>">
401 <input type='hidden' name='page_number'
402 value="<?php echo esc_attr( $requested_page_number ); ?>">
403 </a>
404 </form>
405 <?php
406 }
407 ?>
408 </h2>
409 <?php
410 }
411 }
412
413 /**
414 * Add parent args to child request
415 */
416 protected function add_parent_args() {
417 $child_tab = '';
418 if ( isset( $_REQUEST['child_tab'] ) ) {
419 $child_tab = sanitize_text_field( wp_unslash( $_REQUEST['child_tab'] ) ); // input var okay.
420 }
421 ?>
422 <input type='hidden' name='child_tab' value='<?php echo esc_attr( $child_tab ); ?>'/>
423 <?php
424 }
425
426 /**
427 * Overwrites method get_url_arguments
428 */
429 protected function get_url_arguments() {
430 // Default behaviour.
431 parent::get_url_arguments();
432
433 // When we are coming from a child we'll need to get our parent key
434 if ( isset( $this->relations['parent']['key'] ) && is_array( $this->relations['parent']['key'] ) ) {
435 foreach ( $this->relations['parent']['key'] as $key ) {
436 if ( isset( $_REQUEST[ 'WPDA_PARENT_KEY*' . $key ] ) ) {
437 $this->form_items_new_values[ $key ] = sanitize_text_field( wp_unslash( $_REQUEST[ 'WPDA_PARENT_KEY*' . $key ] ) ); // input var okay.
438 }
439 }
440 }
441 }
442
443 /**
444 * Add button new to page top
445 *
446 * @param array $child Child info
447 * @param string $child_table_name Database table name
448 */
449 protected function button_add_new( $child, $child_table_name ) {
450 // Check if table has primary key. If not, disable adding a new record.
451 $check_pk = WPDA_List_Columns_Cache::get_list_columns( $this->schema_name, $child_table_name );
452 $title = 'Add new row';
453
454 if ( is_admin() ) {
455 $url = "?page={$this->page}";
456 } else {
457 $url = '';
458 }
459
460 if ( ! empty( $check_pk->get_table_primary_key() ) ) {
461 ?>
462 <form
463 method="post"
464 action="<?php echo esc_attr( $url ); ?>"
465 style="padding-top:15px;padding-left:5px;float:left;"
466 >
467 <?php $this->add_parent_keys( 'WPDA_PARENT_KEY*' ); ?>
468 <?php echo $this->page_number_item; // phpcs:ignore WordPress.Security.EscapeOutput ?>
469 <input type="hidden" name="mode" value="edit">
470 <input type="hidden" name="child_request" value="TRUE">
471 <input type="hidden" name="child_tab" value="<?php echo esc_attr( $child_table_name ); ?>">
472 <input type="hidden" name="action" value="new">
473 <button type="submit" class="button wpda_tooltip" title="<?php echo esc_attr( $title ); ?>">
474 <i class="fas fa-plus-circle wpda_icon_on_button"></i>
475 <?php echo __( 'Add New', 'wp-data-access' ); ?>
476 </button>
477 </form>
478 <?php
479 }
480 if ( isset( $child['relation_nm'] ) ) {
481 ?>
482 <form
483 method="post"
484 action="<?php echo esc_attr( $url ); ?>"
485 style="padding-top:15px;padding-left:5px;float:left;"
486 >
487 <?php $this->add_parent_keys( 'WPDA_PARENT_KEY*' ); ?>
488 <?php echo $this->page_number_item; // phpcs:ignore WordPress.Security.EscapeOutput ?>
489 <input type="hidden" name="mode" value="edit">
490 <input type="hidden" name="child_request" value="TRUE">
491 <input type="hidden" name="child_tab" value="<?php echo esc_attr( $child_table_name ); ?>">
492 <input type="hidden" name="action" value="add">
493 <button type="submit" class="button wpda_tooltip"
494 title="Add existing row"
495 >
496 <i class="fas fa-plus-circle wpda_icon_on_button"></i>
497 <?php echo __( 'Add Existing', 'wp-data-access' ); ?>
498 </button>
499 </form>
500 <?php
501 }
502 }
503
504 /**
505 * Add parent keys as hidden items
506 *
507 * @param string $name_prefix Added prefix to be flexible
508 */
509 protected function add_parent_keys( $name_prefix = '' ) {
510 foreach ( $this->parent_key as $parent_key ) {
511 ?>
512 <input type="hidden"
513 name="<?php echo esc_attr( $name_prefix ) . esc_attr( $parent_key ); ?>"
514 value="<?php echo esc_attr( $this->parent_key_value[ $parent_key ] ); ?>">
515 <?php
516 }
517 }
518
519 /**
520 * Overwrite method to add show less/more functionality
521 */
522 public function add_form_logic() {
523 if ( 'new' !== $this->action_posted || $this->child_request ) {
524 ?>
525 <input type="button"
526 value="<?php echo __( 'show more', 'wp-data-access' ); ?> &gt;&gt;&gt;"
527 class="button"
528 id="show_more_less_button"
529 style="float:right;display:none;">
530 <script type='text/javascript'>
531 function show_more_less() {
532 jQuery('.row-show-less-more').toggle();
533 if (jQuery('#show_more_less_button').val() === '<?php echo __( 'show more', 'wp-data-access' ); ?> &gt;&gt;&gt;') {
534 jQuery('#show_more_less_button').val('<<< <?php echo __( 'show less', 'wp-data-access' ); ?>');
535 } else {
536 jQuery('#show_more_less_button').val('<?php echo __( 'show more', 'wp-data-access' ); ?> &gt;&gt;&gt;');
537 }
538 }
539
540 if (jQuery('.row-show-less-more').length > 0) {
541 jQuery('#show_more_less_button').show();
542
543 jQuery('#show_more_less_button').on('click', function() {
544 show_more_less();
545 });
546 }
547 </script>
548 <?php
549 } else {
550 ?>
551 <script type='text/javascript'>
552 jQuery('.row-show-less-more').show();
553 </script>
554 <?php
555 }
556 }
557
558 }
559
560 }
561