Completed
Push — master ( 2cfa6f...8927a4 )
by Zack
10:00 queued 06:05
created

includes/class-admin-views.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Renders all the metaboxes on Add New / Edit View post type.
4
 *
5
 * @package   GravityView
6
 * @license   GPL2+
7
 * @author    Katz Web Services, Inc.
8
 * @link      http://gravityview.co
9
 * @copyright Copyright 2014, Katz Web Services, Inc.
10
 *
11
 * @since 1.0.0
12
 */
13
14
/** If this file is called directly, abort. */
15
if ( ! defined( 'ABSPATH' ) ) {
16
	die;
17
}
18
19
class GravityView_Admin_Views {
20
21
22
23
	function __construct() {
24
25
		add_action( 'save_post', array( $this, 'save_postdata' ) );
26
27
		// set the blacklist field types across the entire plugin
28
		add_filter( 'gravityview_blacklist_field_types', array( $this, 'default_field_blacklist' ), 10, 2 );
29
30
		// Tooltips
31
		add_filter( 'gform_tooltips', array( $this, 'tooltips') );
32
33
		// adding styles and scripts
34
		add_action( 'admin_enqueue_scripts', array( 'GravityView_Admin_Views', 'add_scripts_and_styles'), 999 );
35
		add_filter( 'gform_noconflict_styles', array( $this, 'register_no_conflict') );
36
		add_filter( 'gform_noconflict_scripts', array( $this, 'register_no_conflict') );
37
		add_filter( 'gravityview_noconflict_styles', array( $this, 'register_no_conflict') );
38
		add_filter( 'gravityview_noconflict_scripts', array( $this, 'register_no_conflict') );
39
40
		add_action( 'gravityview_render_directory_active_areas', array( $this, 'render_directory_active_areas'), 10, 4 );
41
		add_action( 'gravityview_render_widgets_active_areas', array( $this, 'render_widgets_active_areas'), 10, 3 );
42
		add_action( 'gravityview_render_available_fields', array( $this, 'render_available_fields'), 10, 2 );
43
		add_action( 'gravityview_render_available_widgets', array( $this, 'render_available_widgets') );
44
		add_action( 'gravityview_render_active_areas', array( $this, 'render_active_areas'), 10, 5 );
45
46
		// @todo check if this hook is needed..
47
		//add_action( 'gravityview_render_field_options', array( $this, 'render_field_options'), 10, 9 );
48
49
		// Add Connected Form column
50
		add_filter('manage_gravityview_posts_columns' , array( $this, 'add_post_type_columns' ) );
51
52
		add_filter( 'gform_toolbar_menu', array( 'GravityView_Admin_Views', 'gform_toolbar_menu' ), 10, 2 );
53
54
		add_action( 'manage_gravityview_posts_custom_column', array( $this, 'add_custom_column_content'), 10, 2 );
55
56
		add_action( 'restrict_manage_posts', array( $this, 'add_view_dropdown' ) );
57
58
		add_action( 'pre_get_posts', array( $this, 'filter_pre_get_posts_by_gravityview_form_id' ) );
59
60
	}
61
62
	/**
63
	 * @since 1.15
64
	 * @param WP_Query $query
65
	 */
66
	public function filter_pre_get_posts_by_gravityview_form_id( &$query ) {
67
		global $pagenow;
68
69
		if ( !is_admin() ) {
70
			return;
71
		}
72
73
		if( 'edit.php' !== $pagenow || ! rgget( 'gravityview_form_id' ) || ! isset( $query->query_vars[ 'post_type' ] ) ) {
74
			return;
75
		}
76
77
		if ( $query->query_vars[ 'post_type' ] == 'gravityview' ) {
78
			$query->set( 'meta_query', array(
79
				array(
80
					'key' => '_gravityview_form_id',
81
					'value' => rgget( 'gravityview_form_id' ),
82
				)
83
			) );
84
		}
85
	}
86
87
	function add_view_dropdown() {
88
		$current_screen = get_current_screen();
89
90
		if( 'gravityview' !== $current_screen->post_type ) {
91
			return;
92
		}
93
94
		$forms = gravityview_get_forms();
95
		$current_form = rgget( 'gravityview_form_id' );
96
		// If there are no forms to select, show no forms.
97
		if( !empty( $forms ) ) { ?>
98
			<select name="gravityview_form_id" id="gravityview_form_id">
99
				<option value="" <?php selected( '', $current_form, true ); ?>><?php esc_html_e( 'All forms', 'gravityview' ); ?></option>
100
				<?php foreach( $forms as $form ) { ?>
101
					<option value="<?php echo $form['id']; ?>" <?php selected( $form['id'], $current_form, true ); ?>><?php echo esc_html( $form['title'] ); ?></option>
102
				<?php } ?>
103
			</select>
104
		<?php }
105
	}
106
107
108
	/**
109
	 * @deprecated since 1.2
110
	 * Start using GravityView_Render_Settings::render_setting_row
111
	 */
112
	public static function render_setting_row( $key = '', $current_settings = array(), $override_input = null, $name = 'template_settings[%s]', $id = 'gravityview_se_%s' ) {
113
		_deprecated_function( 'GravityView_Admin_Views::render_setting_row', '1.1.7', 'GravityView_Render_Settings::render_setting_row' );
114
		GravityView_Render_Settings::render_setting_row( $key, $current_settings, $override_input, $name , $id );
115
	}
116
117
	/**
118
	 * @deprecated since 1.2
119
	 * Start using GravityView_Render_Settings::render_field_option
120
	 */
121
	public static function render_field_option( $name = '', $option, $curr_value = NULL ) {
122
		_deprecated_function( 'GravityView_Admin_Views::render_field_option', '1.1.7', 'GravityView_Render_Settings::render_field_option' );
123
		return GravityView_Render_Settings::render_field_option( $name, $option, $curr_value );
124
	}
125
126
127
	/**
128
	 * Add a GravityView menu to the Form Toolbar with connected views
129
	 * @param  array  $menu_items Menu items, as set in GFForms::top_toolbar()
130
	 * @param  int $id         ID of the current Gravity form
131
	 * @return array            Modified array
132
	 */
133
	static function gform_toolbar_menu( $menu_items = array(), $id = NULL ) {
134
135
		$connected_views = gravityview_get_connected_views( $id );
136
137
		if( empty( $connected_views ) ) {
138
139
		    $menu_items['gravityview'] = array(
140
				'label'          => esc_attr__( 'Create a View', 'gravityview' ),
141
				'icon'           => '<i class="fa fa-lg gv-icon-astronaut-head gv-icon"></i>',
142
				'title'          => esc_attr__( 'Create a View using this form as a data source', 'gravityview' ),
143
				'url'            => admin_url( 'post-new.php?post_type=gravityview&form_id=' . $id ),
144
				'menu_class'     => 'gv_connected_forms gf_form_toolbar_settings',
145
				'priority'       => 0,
146
				'capabilities'   => array( 'edit_gravityviews' ),
147
			);
148
149
			return $menu_items;
150
		}
151
152
		$sub_menu_items = array();
153
		foreach ( (array)$connected_views as $view ) {
154
155
			if( ! GVCommon::has_cap( 'edit_gravityview', $view->ID ) ) {
156
				continue;
157
			}
158
159
			$label = empty( $view->post_title ) ? sprintf( __('No Title (View #%d)', 'gravityview' ), $view->ID ) : $view->post_title;
160
161
			$sub_menu_items[] = array(
162
				'label' => esc_attr( $label ),
163
				'url' => admin_url( 'post.php?action=edit&post='.$view->ID ),
164
			);
165
		}
166
167
		// If there were no items added, then let's create the parent menu
168
		if( $sub_menu_items ) {
169
170
		    $sub_menu_items[] = array(
171
			    'label' => esc_attr__( 'Create a View', 'gravityview' ),
172
                'link_class' => 'gv-create-view',
173
			    'title' => esc_attr__( 'Create a View using this form as a data source', 'gravityview' ),
174
			    'url'   => admin_url( 'post-new.php?post_type=gravityview&form_id=' . $id ),
175
			    'capabilities'   => array( 'edit_gravityviews' ),
176
            );
177
178
			// Make sure Gravity Forms uses the submenu; if there's only one item, it uses a link instead of a dropdown
179
			$sub_menu_items[] = array(
180
				'url' => '#',
181
				'label' => '',
182
				'menu_class' => 'hidden',
183
				'capabilities' => '',
184
			);
185
186
			$menu_items['gravityview'] = array(
187
				'label'          => __( 'Connected Views', 'gravityview' ),
188
				'icon'           => '<i class="fa fa-lg gv-icon-astronaut-head gv-icon"></i>',
189
				'title'          => __( 'GravityView Views using this form as a data source', 'gravityview' ),
190
				'url'            => '#',
191
				'onclick'        => 'return false;',
192
				'menu_class'     => 'gv_connected_forms gf_form_toolbar_settings',
193
				'sub_menu_items' => $sub_menu_items,
194
				'priority'       => 0,
195
				'capabilities'   => array( 'edit_gravityviews' ),
196
			);
197
		}
198
199
		return $menu_items;
200
	}
201
202
	/**
203
	 * List the field types without presentation properties (on a View context)
204
	 *
205
	 * @param array $array Existing field types to add to a blacklist
206
	 * @param string|null $context Context for the blacklist. Default: NULL.
207
	 * @access public
208
	 * @return array Default blacklist fields merged with existing blacklist fields
209
	 */
210
	function default_field_blacklist( $array = array(), $context = NULL ) {
211
212
		$add = array( 'captcha', 'page' );
213
214
		// Don't allowing editing the following values:
215
		if( $context === 'edit' ) {
216
			$add[] = 'post_id';
217
		}
218
219
		$return = array_merge( $array, $add );
220
221
		return $return;
222
	}
223
224
	/**
225
	 * Add tooltip text for use throughout the UI
226
	 * @param  array       $tooltips Array of Gravity Forms tooltips
227
	 * @return array                Modified tooltips array
228
	 */
229
	public function tooltips( $tooltips = array() ) {
230
231
		$gv_tooltips = array();
232
233
		// Generate tooltips for View settings
234
		$default_args = GravityView_View_Data::get_default_args( true );
235
236
		foreach ( $default_args as $key => $arg ) {
237
238
			// If an arg has `tooltip` defined, but it's false, don't display a tooltip
239
			if( isset( $arg['tooltip'] ) && empty( $arg['tooltip'] ) ) { continue; }
240
241
			// By default, use `tooltip` if defined.
242
			$tooltip = empty( $arg['tooltip'] ) ? NULL : $arg['tooltip'];
243
244
			// Otherwise, use the description as a tooltip.
245
			if( empty( $tooltip ) && !empty( $arg['desc'] ) ) {
246
				$tooltip = $arg['desc'];
247
			}
248
249
			// If there's no tooltip set, continue
250
			if( empty( $tooltip ) ) {
251
				continue;
252
			}
253
254
			// Add the tooltip
255
			$gv_tooltips[ 'gv_'.$key ] = array(
256
				'title'	=> $arg['label'],
257
				'value'	=> $tooltip,
258
			);
259
260
		}
261
262
		$gv_tooltips['gv_css_merge_tags'] = array(
263
			'title' => __('CSS Merge Tags', 'gravityview'),
264
			'value' => sprintf( __( 'Developers: The CSS classes will be sanitized using the %ssanitize_title_with_dashes()%s function.', 'gravityview'), '<code>', '</code>' )
265
		);
266
267
		/**
268
		 * @filter `gravityview_tooltips` The tooltips GravityView adds to the Gravity Forms tooltip array
269
		 * @param array $gv_tooltips Associative array with unique keys containing array of `title` and `value` keys, as expected by `gform_tooltips` filter
270
		 */
271
		$gv_tooltips = apply_filters( 'gravityview_tooltips', $gv_tooltips );
272
273
		foreach ( $gv_tooltips as $key => $tooltip ) {
274
275
			$title = empty( $tooltip['title'] ) ? '' : '<h6>'.esc_html( $tooltip['title'] ) .'</h6>';
276
277
			$tooltips[ $key ] = $title . wpautop( esc_html( $tooltip['value'] ) );
278
		}
279
280
		return $tooltips;
281
	}
282
283
	/**
284
	 * Add the Data Source information
285
	 *
286
	 * @param null $column_name
287
	 * @param $post_id
288
	 *
289
	 * @return void
290
	 */
291
	public function add_custom_column_content( $column_name = NULL, $post_id )	{
292
293
		$output = '';
294
295
		switch ( $column_name ) {
296
			case 'gv_template':
297
298
				$template_id = gravityview_get_template_id( $post_id );
299
300
				// All Views should have a connected form. If it doesn't, that's not right.
301
				if ( empty( $template_id ) ) {
302
					do_action( 'gravityview_log_error', sprintf( __METHOD__ . ' View ID %s does not have a connected template.', $post_id ) );
303
					break;
304
				}
305
306
				$templates = gravityview_get_registered_templates();
307
308
				$template = isset( $templates[ $template_id ] ) ? $templates[ $template_id ] : false;
309
310
				// Generate backup if label doesn't exist: `example_name` => `Example Name`
311
				$template_id_pretty = ucwords( implode( ' ', explode( '_', $template_id ) ) );
312
313
				$output = $template ? $template['label'] : $template_id_pretty;
314
315
				break;
316
317
			case 'gv_connected_form':
318
319
				$form_id = gravityview_get_form_id( $post_id );
320
321
				// All Views should have a connected form. If it doesn't, that's not right.
322
				if ( empty( $form_id ) ) {
323
					do_action( 'gravityview_log_error', sprintf( '[add_data_source_column_content] View ID %s does not have a connected GF form.', $post_id ) );
324
					$output = __( 'Not connected.', 'gravityview' );
325
					break;
326
				}
327
328
				$form = gravityview_get_form( $form_id );
329
330
				if ( ! $form ) {
331
					do_action( 'gravityview_log_error', sprintf( '[add_data_source_column_content] Connected form not found: Form #%d', $form_id ) );
332
333
					$output = __( 'The connected form can not be found; it may no longer exist.', 'gravityview' );
334
				} else {
335
					$output = self::get_connected_form_links( $form );
336
				}
337
338
				break;
339
		}
340
341
		echo $output;
342
	}
343
344
345
	/**
346
	 * Get HTML links relating to a connected form, like Edit, Entries, Settings, Preview
347
	 * @param  array|int $form Gravity Forms forms array, or the form ID
348
	 * @param  boolean $include_form_link Whether to include the bold name of the form in the output
349
	 * @return string          HTML links
350
	 */
351
	static public function get_connected_form_links( $form, $include_form_link = true ) {
352
353
		// Either the form is empty or the form ID is 0, not yet set.
354
		if( empty( $form ) ) {
355
			return '';
356
		}
357
358
		// The $form is passed as the form ID
359
		if( !is_array( $form ) ) {
360
			$form = gravityview_get_form( $form );
361
		}
362
363
		$form_id = $form['id'];
364
		$links = array();
365
366
		if( GVCommon::has_cap( 'gravityforms_edit_forms' ) ) {
367
			$form_url = admin_url( sprintf( 'admin.php?page=gf_edit_forms&amp;id=%d', $form_id ) );
368
			$form_link = '<strong class="gv-form-title">'.gravityview_get_link( $form_url, $form['title'], 'class=row-title' ).'</strong>';
369
			$links[] = '<span>'.gravityview_get_link( $form_url, __('Edit Form', 'gravityview') ).'</span>';
370
		} else {
371
			$form_link = '<strong class="gv-form-title">'. esc_html( $form['title'] ). '</strong>';
372
		}
373
374
		if( GVCommon::has_cap( 'gravityforms_view_entries' ) ) {
375
			$entries_url = admin_url( sprintf( 'admin.php?page=gf_entries&amp;id=%d', $form_id ) );
376
			$links[] = '<span>'.gravityview_get_link( $entries_url, __('Entries', 'gravityview') ).'</span>';
377
		}
378
379
		if( GVCommon::has_cap( array( 'gravityforms_edit_settings', 'gravityview_view_settings' ) ) ) {
380
			$settings_url = admin_url( sprintf( 'admin.php?page=gf_edit_forms&amp;view=settings&amp;id=%d', $form_id ) );
381
			$links[] = '<span>'.gravityview_get_link( $settings_url, __('Settings', 'gravityview'), 'title='.__('Edit settings for this form', 'gravityview') ).'</span>';
382
		}
383
384
		if( GVCommon::has_cap( array("gravityforms_edit_forms", "gravityforms_create_form", "gravityforms_preview_forms") ) ) {
385
			$preview_url = site_url( sprintf( '?gf_page=preview&amp;id=%d', $form_id ) );
386
			$links[] = '<span>'.gravityview_get_link( $preview_url, __('Preview Form', 'gravityview'), 'title='.__('Preview this form', 'gravityview') ).'</span>';
387
		}
388
389
		$output = '';
390
391
		if( !empty( $include_form_link ) ) {
392
			$output .= $form_link;
393
		}
394
395
		/**
396
		 * @filter `gravityview_connected_form_links` Modify the links shown in the Connected Form links
397
		 * @since 1.6
398
		 * @param array $links Links to show
399
		 * @param array $form Gravity Forms form array
400
		 */
401
		$links = apply_filters( 'gravityview_connected_form_links', $links, $form );
402
403
		$output .= '<div class="row-actions">'. implode( ' | ', $links ) .'</div>';
404
405
		return $output;
406
	}
407
408
	/**
409
	 * Add the Data Source column to the Views page
410
	 * @param  array      $columns Columns array
411
	 */
412
	public function add_post_type_columns( $columns ) {
413
414
		// Get the date column and save it for later to add back in.
415
		// This adds it after the Data Source column.
416
		// This way, we don't need to do array_slice, array_merge, etc.
417
		$date = $columns['date'];
418
		unset( $columns['date'] );
419
420
		$data_source_required_caps = array(
421
			'gravityforms_edit_forms',
422
			'gravityforms_view_entries',
423
			'gravityforms_edit_settings',
424
			'gravityview_view_settings',
425
			'gravityforms_create_form',
426
			'gravityforms_preview_forms',
427
		);
428
429
		if( GVCommon::has_cap( $data_source_required_caps ) ) {
430
			$columns['gv_connected_form'] = __( 'Data Source', 'gravityview' );
431
		}
432
433
		$columns['gv_template'] = _x( 'Template', 'Column title that shows what template is being used for Views', 'gravityview' );
434
435
		// Add the date back in.
436
		$columns['date'] = $date;
437
438
		return $columns;
439
	}
440
441
	/**
442
	 * Save View configuration
443
	 *
444
	 * @access public
445
	 * @param int $post_id Currently saved Post ID
446
	 * @return void
447
	 */
448
	function save_postdata( $post_id ) {
449
450
		if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ){
451
			return;
452
		}
453
454
		// validate post_type
455
		if ( ! isset( $_POST['post_type'] ) || 'gravityview' != $_POST['post_type'] ) {
456
			return;
457
		}
458
459
		// validate user can edit and save View
460
		if ( ! GVCommon::has_cap( 'edit_gravityview', $post_id ) ) {
461
			do_action( 'gravityview_log_error', __METHOD__ . ' - Current user does not have the capability to edit View #' . $post_id, wp_get_current_user() );
462
			return;
463
		}
464
465
		do_action( 'gravityview_log_debug', '[save_postdata] Saving View post type.', $_POST );
466
467
		$statii = array();
468
469
		// check if this is a start fresh View
470
		if ( isset( $_POST['gravityview_select_form_nonce'] ) && wp_verify_nonce( $_POST['gravityview_select_form_nonce'], 'gravityview_select_form' ) ) {
471
472
			$form_id = !empty( $_POST['gravityview_form_id'] ) ? $_POST['gravityview_form_id'] : '';
473
			// save form id
474
			$statii['form_id'] = update_post_meta( $post_id, '_gravityview_form_id', $form_id );
475
476
		}
477
478
		if( false === GVCommon::has_cap( 'gravityforms_create_form' ) && empty( $statii['form_id'] ) ) {
479
			do_action( 'gravityview_log_error', __METHOD__ . ' - Current user does not have the capability to create a new Form.', wp_get_current_user() );
480
			return;
481
		}
482
483
		// Was this a start fresh?
484
		if ( ! empty( $_POST['gravityview_form_id_start_fresh'] ) ) {
485
			$statii['start_fresh'] = add_post_meta( $post_id, '_gravityview_start_fresh', 1 );
486
		} else {
487
			$statii['start_fresh'] = delete_post_meta( $post_id, '_gravityview_start_fresh' );
488
		}
489
490
		// Check if we have a template id
491
		if ( isset( $_POST['gravityview_select_template_nonce'] ) && wp_verify_nonce( $_POST['gravityview_select_template_nonce'], 'gravityview_select_template' ) ) {
492
493
			$template_id = !empty( $_POST['gravityview_directory_template'] ) ? $_POST['gravityview_directory_template'] : '';
494
495
			// now save template id
496
			$statii['directory_template'] = update_post_meta( $post_id, '_gravityview_directory_template', $template_id );
497
		}
498
0 ignored issues
show
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
499
500
		// save View Configuration metabox
501
		if ( isset( $_POST['gravityview_view_configuration_nonce'] ) && wp_verify_nonce( $_POST['gravityview_view_configuration_nonce'], 'gravityview_view_configuration' ) ) {
502
503
			// template settings
504
			if( empty( $_POST['template_settings'] ) ) {
505
				$_POST['template_settings'] = array();
506
			}
507
			$statii['template_settings'] = update_post_meta( $post_id, '_gravityview_template_settings', $_POST['template_settings'] );
508
509
			$fields = array();
510
511
			// Directory&single Visible Fields
512
			if( !empty( $preset_fields ) ) {
513
514
				$fields = $preset_fields;
515
516
			} elseif( !empty( $_POST['gv_fields'] ) ) {
517
				$fields = _gravityview_process_posted_fields();
518
			}
519
520
			$statii['directory_fields'] = update_post_meta( $post_id, '_gravityview_directory_fields', $fields );
521
522
			// Directory Visible Widgets
523
			if( empty( $_POST['widgets'] ) ) {
524
				$_POST['widgets'] = array();
525
			}
526
			$statii['directory_widgets'] = gravityview_set_directory_widgets( $post_id, $_POST['widgets'] );
527
528
		} // end save view configuration
529
530
		/**
531
		 * @action `gravityview_view_saved` After a View has been saved in the admin
532
		 * @param int $post_id ID of the View that has been saved
533
		 * @param array $statii Array of statuses of the post meta saving processes. If saving worked, each key should be mapped to a value of the post ID (`directory_widgets` => `124`). If failed (or didn't change), the value will be false.
534
		 * @since 1.17.2
535
		 */
536
		do_action('gravityview_view_saved', $post_id, $statii );
537
538
		do_action('gravityview_log_debug', '[save_postdata] Update Post Meta Statuses (also returns false if nothing changed)', array_map( 'intval', $statii ) );
539
	}
540
541
	/**
542
	 * @deprecated 1.1.6
543
	 */
544
	function render_label() {
545
		_deprecated_function( 'GravityView_Admin_Views::render_label()', '1.1.6', 'Use the GravityView_Admin_View_Field class instead.' );
546
	}
547
548
	/**
549
	 * Render html for displaying available fields based on a Form ID
550
	 * $blacklist_field_types - contains the field types which are not proper to be shown in a directory.
551
	 *
552
     * @see GravityView_Ajax::get_available_fields_html() Triggers `gravityview_render_available_fields` action
553
	 * @access public
554
     *
555
	 * @param int $form Gravity Forms Form ID (default: '')
556
	 * @param string $context (default: 'single')
557
     *
558
	 * @return void
559
	 */
560
	function render_available_fields( $form = 0, $context = 'single' ) {
561
562
		/**
563
		 * @filter  `gravityview_blacklist_field_types` Modify the types of fields that shouldn't be shown in a View.
564
		 * @param[in,out] array $blacklist_field_types Array of field types to block for this context.
565
		 * @param[in] string $context View context ('single', 'directory', or 'edit')
566
		 */
567
		$blacklist_field_types = apply_filters( 'gravityview_blacklist_field_types', array(), $context );
568
569
		$fields = $this->get_available_fields( $form, $context );
570
571
		$output = '';
572
573
		if( !empty( $fields ) ) {
574
575
			foreach( $fields as $id => $details ) {
576
577
				if( in_array( $details['type'], $blacklist_field_types ) ) {
578
					continue;
579
				}
580
581
				// Edit mode only allows editing the parent fields, not single inputs.
582
				if( $context === 'edit' && !empty( $details['parent'] ) ) {
583
					continue;
584
				}
585
586
				$output .= new GravityView_Admin_View_Field( $details['label'], $id, $details );
587
588
			} // End foreach
589
		}
590
591
		echo $output;
592
593
		// For the EDIT view we only want to allow the form fields.
594
		if( $context === 'edit' ) {
595
			return;
596
		}
597
598
		$this->render_additional_fields( $form, $context );
599
	}
600
601
	/**
602
	 * Render html for displaying additional fields based on a Form ID
603
	 *
604
	 * @access public
605
	 * @param int $form Gravity Forms Form ID (default: '')
606
	 * @param string $context (default: 'single')
607
	 * @return void
608
	 */
609
	public function render_additional_fields( $form = 0, $context = 'single' ) {
610
611
		/**
612
		 * @filter `gravityview_additional_fields` non-standard Fields to show at the bottom of the field picker
613
		 * @param array $additional_fields Associative array of field arrays, with `label_text`, `desc`, `field_id`, `label_type`, `input_type`, `field_options`, and `settings_html` keys
614
		 */
615
		$additional_fields = apply_filters( 'gravityview_additional_fields', array(
616
			array(
617
				'label_text' => __( '+ Add All Fields', 'gravityview' ),
618
				'desc' => __('Add all the available fields at once.', 'gravityview'),
619
				'field_id' => 'all-fields',
620
				'label_type' => 'field',
621
				'input_type' => NULL,
622
				'field_options' => NULL,
623
				'settings_html'	=> NULL,
624
			)
625
		));
626
627
		if( !empty( $additional_fields )) {
628
			foreach ( (array)$additional_fields as $item ) {
629
630
				// Prevent items from not having index set
631
				$item = wp_parse_args( $item, array(
632
					'label_text' => NULL,
633
					'field_id' => NULL,
634
					'label_type' => NULL,
635
					'input_type' => NULL,
636
					'field_options' => NULL,
637
					'settings_html'	=> NULL,
638
				));
639
640
				// Backward compat.
641
				if( !empty( $item['field_options'] ) ) {
642
					// Use settings_html from now on.
643
					$item['settings_html'] = $item['field_options'];
644
				}
645
646
				// Render a label for each of them
647
				echo new GravityView_Admin_View_Field( $item['label_text'], $item['field_id'], $item );
648
649
			}
650
		}
651
652
	}
653
654
	/**
655
	 * Retrieve the default fields id, label and type
656
	 * @param  string|array $form form_ID or form object
657
	 * @param  string $zone   Either 'single', 'directory', 'header', 'footer'
658
	 * @return array
659
	 */
660
	function get_entry_default_fields($form, $zone) {
661
662
		$entry_default_fields = array();
663
664
		if( in_array( $zone, array( 'directory', 'single' ) ) ) {
665
666
			$entry_default_fields = array(
667
				'id' => array(
668
					'label' => __('Entry ID', 'gravityview'),
669
					'type' => 'id',
670
					'desc'	=> __('The unique ID of the entry.', 'gravityview'),
671
				),
672
				'date_created' => array(
673
					'label' => __('Entry Date', 'gravityview'),
674
					'desc'	=> __('The date the entry was created.', 'gravityview'),
675
					'type' => 'date_created',
676
				),
677
				'source_url' => array(
678
					'label' => __('Source URL', 'gravityview'),
679
					'type' => 'source_url',
680
					'desc'	=> __('The URL of the page where the form was submitted.', 'gravityview'),
681
				),
682
				'ip' => array(
683
					'label' => __('User IP', 'gravityview'),
684
					'type' => 'ip',
685
					'desc'	=> __('The IP Address of the user who created the entry.', 'gravityview'),
686
				),
687
				'created_by' => array(
688
					'label' => __('User', 'gravityview'),
689
					'type' => 'created_by',
690
					'desc'	=> __('Details of the logged-in user who created the entry (if any).', 'gravityview'),
691
				),
692
693
				/**
694
				 * @since  1.2
695
				 */
696
				'custom'	=> array(
697
					'label'	=> __('Custom Content', 'gravityview'),
698
					'type'	=> 'custom',
699
					'desc'	=> __('Insert custom text or HTML.', 'gravityview'),
700
				),
701
702
				/**
703
				 * @since 1.7.2
704
				 */
705
			    'other_entries' => array(
706
				    'label'	=> __('Other Entries', 'gravityview'),
707
				    'type'	=> 'other_entries',
708
				    'desc'	=> __('Display other entries created by the entry creator.', 'gravityview'),
709
			    ),
710
	        );
711
712
			if( 'single' !== $zone) {
713
714
				$entry_default_fields['entry_link'] = array(
715
					'label' => __('Link to Entry', 'gravityview'),
716
					'desc'	=> __('A dedicated link to the single entry with customizable text.', 'gravityview'),
717
					'type' => 'entry_link',
718
				);
719
			}
720
721
		} // if not zone directory or single
722
0 ignored issues
show
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
723
724
		/**
725
		 * @filter `gravityview_entry_default_fields` Modify the default fields for each zone and context
726
		 * @param array $entry_default_fields Array of fields shown by default
727
		 * @param  string|array $form form_ID or form object
728
		 * @param  string $zone   Either 'single', 'directory', 'header', 'footer'
729
		 */
730
		return apply_filters( 'gravityview_entry_default_fields', $entry_default_fields, $form, $zone);
731
	}
732
733
	/**
734
	 * Calculate the available fields
735
	 * @param  string|array $form form_ID or form object
736
	 * @param  string $zone   Either 'single', 'directory', 'header', 'footer'
737
	 * @return array         fields
738
	 */
739
	function get_available_fields( $form = '', $zone = NULL ) {
740
741
		if( empty( $form ) ) {
742
			do_action( 'gravityview_log_error', '[get_available_fields] $form is empty' );
743
			return array();
744
		}
745
746
		// get form fields
747
		$fields = gravityview_get_form_fields( $form, true );
748
749
		// get meta fields ( only if form was already created )
750
		if( !is_array( $form ) ) {
751
			$meta_fields = gravityview_get_entry_meta( $form );
752
		} else {
753
			$meta_fields = array();
754
		}
755
756
		// get default fields
757
		$default_fields = $this->get_entry_default_fields( $form, $zone );
758
759
		//merge without loosing the keys
760
		$fields = $fields + $meta_fields + $default_fields;
761
762
		return $fields;
763
	}
764
765
766
	/**
767
	 * Render html for displaying available widgets
768
	 * @return string html
769
	 */
770
	function render_available_widgets() {
771
772
		$widgets = $this->get_registered_widgets();
773
774
		if( !empty( $widgets ) ) {
775
776
			foreach( $widgets as $id => $details ) {
777
778
				echo new GravityView_Admin_View_Widget( $details['label'], $id, $details );
779
780
			}
781
		}
782
783
	}
784
785
	/**
786
	 * Get the list of registered widgets. Each item is used to instantiate a GravityView_Admin_View_Widget object
787
	 * @since 1.13.1
788
	 * @return array
789
	 */
790
	function get_registered_widgets() {
791
		/**
792
		 * @filter `gravityview_register_directory_widgets` Get the list of registered widgets. Each item is used to instantiate a GravityView_Admin_View_Widget object
793
		 * @param array $registered_widgets Empty array
794
		 */
795
		$registered_widgets = apply_filters( 'gravityview_register_directory_widgets', array() );
796
797
		return $registered_widgets;
798
	}
799
800
	/**
801
	 * Generic function to render rows and columns of active areas for widgets & fields
802
	 * @param  string $template_id The current slug of the selected View template
803
	 * @param  string $type   Either 'widget' or 'field'
804
	 * @param  string $zone   Either 'single', 'directory', 'header', 'footer'
805
	 * @param  array $rows    The layout structure: rows, columns and areas
806
	 * @param  array $values  Saved objects
807
	 * @return void
808
	 */
809
	function render_active_areas( $template_id, $type, $zone, $rows, $values ) {
810
		global $post;
811
812
		if( $type === 'widget' ) {
813
			$button_label = __( 'Add Widget', 'gravityview' );
814
		} else {
815
			$button_label = __( 'Add Field', 'gravityview' );
816
		}
817
818
		$available_items = array();
819
820
		// if saved values, get available fields to label everyone
821
		if( !empty( $values ) && ( !empty( $post->ID ) || !empty( $_POST['template_id'] ) ) ) {
822
823
			if( !empty( $_POST['template_id'] ) ) {
824
				$form = GravityView_Ajax::pre_get_form_fields( $_POST['template_id'] );
825
			} else {
826
				$form = gravityview_get_form_id( $post->ID );
827
			}
828
829
			if( 'field' === $type ) {
830
				$available_items = $this->get_available_fields( $form, $zone );
831
			} else {
832
				$available_items = $this->get_registered_widgets();
833
			}
834
835
		}
836
837
		foreach( $rows as $row ) :
838
			foreach( $row as $col => $areas ) :
839
				$column = ($col == '2-2') ? '1-2' : $col; ?>
840
841
				<div class="gv-grid-col-<?php echo esc_attr( $column ); ?>">
842
843
					<?php foreach( $areas as $area ) : 	?>
844
845
						<div class="gv-droppable-area">
846
							<div class="active-drop active-drop-<?php echo esc_attr( $type ); ?>" data-areaid="<?php echo esc_attr( $zone .'_'. $area['areaid'] ); ?>">
847
848
								<?php // render saved fields
849
850
								if( !empty( $values[ $zone .'_'. $area['areaid'] ] ) ) {
851
852
									foreach( $values[ $zone .'_'. $area['areaid'] ] as $uniqid => $field ) {
853
854
										$input_type = NULL;
855
										$original_item = isset( $available_items[ $field['id'] ] ) ? $available_items[ $field['id'] ] : false ;
856
857
										if( !$original_item ) {
858
859
											do_action('gravityview_log_error', 'An item was not available when rendering the output; maybe it was added by a plugin that is now de-activated.', array('available_items' => $available_items, 'field' => $field ));
860
861
											$original_item = $field;
862
										} else {
863
864
											$input_type = isset( $original_item['type'] ) ? $original_item['type'] : NULL;
865
866
										}
867
868
										// Field options dialog box
869
										$field_options = GravityView_Render_Settings::render_field_options( $type, $template_id, $field['id'], $original_item['label'], $zone .'_'. $area['areaid'], $input_type, $uniqid, $field, $zone, $original_item );
870
871
										$item = array(
872
											'input_type' => $input_type,
873
											'settings_html' => $field_options,
874
											'label_type' => $type
875
										);
876
877
										// Merge the values with the current item to pass things like widget descriptions and original field names
878
										if( $original_item ) {
879
											$item = wp_parse_args( $item, $original_item );
880
										}
881
882
										switch( $type ) {
883
											case 'widget':
884
												echo new GravityView_Admin_View_Widget( $item['label'], $field['id'], $item, $field );
885
												break;
886
											default:
887
												echo new GravityView_Admin_View_Field( $item['label'], $field['id'], $item, $field );
888
										}
889
0 ignored issues
show
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
890
891
										//endif;
892
893
									}
894
895
								} // End if zone is not empty ?>
896
897
								<span class="drop-message"><?php echo sprintf(esc_attr__('"+ %s" or drag existing %ss here.', 'gravityview'), $button_label, $type ); ?></span>
898
							</div>
899
							<div class="gv-droppable-area-action">
900
								<a href="#" class="gv-add-field button-secondary" title="" data-objecttype="<?php echo esc_attr( $type ); ?>" data-areaid="<?php echo esc_attr( $zone .'_'. $area['areaid'] ); ?>" data-context="<?php echo esc_attr( $zone ); ?>"><?php echo '+ '.esc_html( $button_label ); ?></a>
901
								<p class="gv-droppable-area-title"><strong><?php echo esc_html( $area['title'] ); ?></strong><?php if( !empty( $area['subtitle'] ) ) { ?><span class="gv-droppable-area-subtitle"> &ndash; <?php echo esc_html( $area['subtitle'] ); ?></span><?php } ?></p>
902
							</div>
903
						</div>
904
905
					<?php endforeach; ?>
906
907
				</div>
908
			<?php endforeach;
909
		endforeach;
910
	}
911
912
	/**
913
	 * Render the widget active areas
914
	 * @param  string $zone    Either 'header' or 'footer'
915
	 * @param  string $post_id Current Post ID (view)
916
	 * @return string          html
917
	 */
918
	function render_widgets_active_areas( $template_id = '', $zone, $post_id = '' ) {
919
920
		$default_widget_areas = GravityView_Plugin::get_default_widget_areas();
921
922
		$widgets = array();
923
		if( !empty( $post_id ) ) {
924
			$widgets = gravityview_get_directory_widgets( $post_id );
925
		}
926
927
		ob_start();
928
		?>
929
930
		<div class="gv-grid gv-grid-pad gv-grid-border" id="directory-<?php echo $zone; ?>-widgets">
931
			<?php $this->render_active_areas( $template_id, 'widget', $zone, $default_widget_areas, $widgets ); ?>
932
		</div>
933
934
		<?php
935
		$output = ob_get_clean();
936
937
		echo $output;
938
939
		return $output;
940
	}
941
942
	/**
943
	 * Render the Template Active Areas and configured active fields for a given template id and post id
944
	 *
945
	 * @access public
946
	 * @param string $template_id (default: '') Template ID, like `default_list`, `default_table`, `preset_business_data`, etc. {@see GravityView_Template::__construct()}
947
	 * @param string $post_id (default: '')
948
	 * @param string $context (default: 'single')
949
	 * @return string HTML of the active areas
950
	 */
951
	function render_directory_active_areas( $template_id = '', $context = 'single', $post_id = '', $echo = false ) {
952
953
		if( empty( $template_id ) ) {
954
			do_action( 'gravityview_log_debug', '[render_directory_active_areas] $template_id is empty' );
955
			return '';
956
		}
957
958
		/**
959
		 * @filter `gravityview_template_active_areas` 
960
		 * @see GravityView_Template::assign_active_areas()
961
		 * @param array $template_areas Empty array, to be filled in by the template class
962
		 * @param string $template_id Template ID, like `default_list`, `default_table`, `preset_business_data`, etc. {@see GravityView_Template::__construct()}
963
		 * @param string $context Current View context: `directory`, `single`, or `edit` (default: 'single')
964
		 */
965
		$template_areas = apply_filters( 'gravityview_template_active_areas', array(), $template_id, $context );
966
967
		if( empty( $template_areas ) ) {
968
969
			do_action( 'gravityview_log_debug', '[render_directory_active_areas] No areas defined. Maybe template %s is disabled.', $template_id );
970
			$output = '<div>';
971
			$output .= '<h2 class="description" style="font-size: 16px; margin:0">'. sprintf( esc_html__( 'This View is configured using the %s View type, which is disabled.', 'gravityview' ), '<em>'.$template_id.'</em>' ) .'</h2>';
972
			$output .= '<p class="description" style="font-size: 14px; margin:0 0 1em 0;padding:0">'.esc_html__('The data is not lost; re-activate the associated plugin and the configuration will re-appear.', 'gravityview').'</p>';
973
			$output .= '</div>';
974
		} else {
975
976
			$fields = '';
977
			if ( ! empty( $post_id ) ) {
978
				$fields = gravityview_get_directory_fields( $post_id );
979
			}
980
981
			ob_start();
982
			$this->render_active_areas( $template_id, 'field', $context, $template_areas, $fields );
983
			$output = ob_get_clean();
984
985
		}
986
987
		if( $echo ) {
988
			echo $output;
989
		}
990
991
		return $output;
992
	}
993
994
	/**
995
	 * Enqueue scripts and styles at Views editor
996
	 *
997
	 * @access public
998
	 * @param mixed $hook
999
	 * @return void
1000
	 */
1001
	static function add_scripts_and_styles( $hook ) {
1002
		global $plugin_page, $pagenow;
1003
1004
		$is_widgets_page = ( $pagenow === 'widgets.php' );
1005
1006
		// Add the GV font (with the Astronaut)
1007
		wp_enqueue_style( 'gravityview_global', plugins_url('assets/css/admin-global.css', GRAVITYVIEW_FILE), array(), GravityView_Plugin::version );
1008
1009
		wp_register_script( 'gravityview-jquery-cookie', plugins_url('assets/lib/jquery.cookie/jquery.cookie.min.js', GRAVITYVIEW_FILE), array( 'jquery' ), GravityView_Plugin::version, true );
1010
1011
		// Don't process any scripts below here if it's not a GravityView page.
1012
		if( !gravityview_is_admin_page($hook) && !$is_widgets_page ) { return; }
1013
1014
		// Only enqueue the following on single pages
1015
		if( gravityview_is_admin_page($hook, 'single') || $is_widgets_page ) {
1016
1017
			wp_enqueue_script( 'jquery-ui-datepicker' );
1018
			wp_enqueue_style( 'gravityview_views_datepicker', plugins_url('assets/css/admin-datepicker.css', GRAVITYVIEW_FILE), GravityView_Plugin::version );
1019
1020
			$script_debug = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '.min';
1021
1022
			//enqueue scripts
1023
			wp_enqueue_script( 'gravityview_views_scripts', plugins_url( 'assets/js/admin-views' . $script_debug . '.js', GRAVITYVIEW_FILE ), array( 'jquery-ui-tabs', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-sortable', 'jquery-ui-tooltip', 'jquery-ui-dialog', 'gravityview-jquery-cookie', 'jquery-ui-datepicker', 'underscore' ), GravityView_Plugin::version );
1024
1025
			wp_localize_script('gravityview_views_scripts', 'gvGlobals', array(
1026
				'cookiepath' => COOKIEPATH,
1027
                'passed_form_id' => (bool) rgget( 'form_id' ),
1028
				'nonce' => wp_create_nonce( 'gravityview_ajaxviews' ),
1029
				'label_viewname' => __( 'Enter View name here', 'gravityview' ),
1030
				'label_close' => __( 'Close', 'gravityview' ),
1031
				'label_cancel' => __( 'Cancel', 'gravityview' ),
1032
				'label_continue' => __( 'Continue', 'gravityview' ),
1033
				'label_ok' => __( 'Ok', 'gravityview' ),
1034
				'label_publisherror' => __( 'Error while creating the View for you. Check the settings or contact GravityView support.', 'gravityview' ),
1035
				'loading_text' => esc_html__( 'Loading&hellip;', 'gravityview' ),
1036
				'loading_error' => esc_html__( 'There was an error loading dynamic content.', 'gravityview' ),
1037
				'field_loaderror' => __( 'Error while adding the field. Please try again or contact GravityView support.', 'gravityview' ),
1038
				'remove_all_fields' => __( 'Would you like to remove all fields in this zone? (You are seeing this message because you were holding down the ALT key)', 'gravityview' ),
1039
			));
1040
1041
			wp_enqueue_style( 'gravityview_views_styles', plugins_url( 'assets/css/admin-views.css', GRAVITYVIEW_FILE ), array('dashicons', 'wp-jquery-ui-dialog' ), GravityView_Plugin::version );
1042
1043
			self::enqueue_gravity_forms_scripts();
1044
1045
		} // End single page
1046
	}
1047
1048
	static function enqueue_gravity_forms_scripts() {
1049
		GFForms::register_scripts();
1050
1051
		$scripts = array(
1052
		    'sack',
1053
		    'gform_gravityforms',
1054
		    'gform_forms',
1055
		    'gform_form_admin',
1056
		    'jquery-ui-autocomplete'
1057
		);
1058
1059
		if ( wp_is_mobile() ) {
1060
		    $scripts[] = 'jquery-touch-punch';
1061
		}
1062
1063
		foreach ($scripts as $script) {
1064
			wp_enqueue_script( $script );
1065
		}
1066
	}
1067
1068
	/**
1069
	 * Add GravityView scripts and styles to Gravity Forms and GravityView No-Conflict modes
1070
	 *
1071
	 * @param array $registered Existing scripts or styles that have been registered (array of the handles)
1072
	 *
1073
	 * @return array
1074
	 */
1075
	function register_no_conflict( $registered ) {
1076
1077
		$allowed_dependencies = array();
1078
1079
		$filter = current_filter();
1080
1081
		if ( preg_match( '/script/ism', $filter ) ) {
1082
1083
			$allowed_dependencies = array(
1084
				'jquery-ui-core',
1085
				'jquery-ui-dialog',
1086
				'jquery-ui-tabs',
1087
				'jquery-ui-draggable',
1088
				'jquery-ui-droppable',
1089
				'jquery-ui-sortable',
1090
				'jquery-ui-tooltip',
1091
				'gravityview_views_scripts',
1092
				'gravityview-support',
1093
				'gravityview-jquery-cookie',
1094
				'gravityview_views_datepicker',
1095
				'sack',
1096
				'gform_gravityforms',
1097
				'gform_forms',
1098
				'gform_form_admin',
1099
				'jquery-ui-autocomplete'
1100
			);
1101
			
1102
		} elseif ( preg_match( '/style/ism', $filter ) ) {
1103
1104
			$allowed_dependencies = array(
1105
				'dashicons',
1106
				'wp-jquery-ui-dialog',
1107
				'gravityview_views_styles',
1108
				'gravityview_global',
1109
				'gravityview_views_datepicker'
1110
			);
1111
		}
1112
1113
		return array_merge( $registered, $allowed_dependencies );
1114
	}
1115
1116
1117
}
1118
1119
new GravityView_Admin_Views;
1120