Completed
Pull Request — develop (#1505)
by Zack
21:14 queued 01:15
created

GravityView_Admin_Views::tooltips()   B

Complexity

Conditions 8
Paths 18

Size

Total Lines 55

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
cc 8
nc 18
nop 1
dl 0
loc 55
ccs 0
cts 19
cp 0
crap 72
rs 7.7373
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Renders all the metaboxes on Add New / Edit View post type.
4
 *
5
 * @package   GravityView
6
 * @license   GPL2+
7
 * @author    GravityView <[email protected]>
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() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
24
		add_action( 'save_post', array( $this, 'save_postdata' ) );
25
26
		// set the blacklist field types across the entire plugin
27
		add_filter( 'gravityview_blacklist_field_types', array( $this, 'default_field_blacklist' ), 10, 2 );
28
29
		// Tooltips
30
		add_filter( 'gform_tooltips', array( $this, 'tooltips') );
31
32
		// adding styles and scripts
33
		add_action( 'admin_enqueue_scripts', array( 'GravityView_Admin_Views', 'add_scripts_and_styles'), 999 );
34
		add_filter( 'gform_noconflict_styles', array( $this, 'register_no_conflict') );
35
		add_filter( 'gform_noconflict_scripts', array( $this, 'register_no_conflict') );
36
		add_filter( 'gravityview_noconflict_styles', array( $this, 'register_no_conflict') );
37
		add_filter( 'gravityview_noconflict_scripts', array( $this, 'register_no_conflict') );
38
39
		add_action( 'gravityview_render_directory_active_areas', array( $this, 'render_directory_active_areas'), 10, 4 );
40
		add_action( 'gravityview_render_widgets_active_areas', array( $this, 'render_widgets_active_areas'), 10, 3 );
41
		add_action( 'gravityview_render_field_pickers', array( $this, 'render_field_pickers'), 10, 2 );
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
		add_action( 'gform_form_actions', array( 'GravityView_Admin_Views', 'gform_toolbar_menu' ), 10, 2 );
54
55
		add_action( 'manage_gravityview_posts_custom_column', array( $this, 'add_custom_column_content'), 10, 2 );
56
57
		add_action( 'restrict_manage_posts', array( $this, 'add_view_dropdown' ) );
58
59
		add_action( 'pre_get_posts', array( $this, 'filter_pre_get_posts_by_gravityview_form_id' ) );
60
61
		add_filter( 'gravityview/support_port/localization_data', array( $this, 'suggest_support_articles' ) );
62
	}
63
64
	/**
65
     * When on the Add/Edit View screen, suggest most popular articles related to that
66
     *
67
	 * @param array $localization_data Data to be passed to the Support Port JS
68
	 *
69
	 * @return array
70
	 */
71
	function suggest_support_articles( $localization_data = array() ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
72
73
	    if( ! gravityview()->request->is_view() ) {
74
	        return $localization_data;
75
        }
76
77
		$localization_data['suggest'] = array(
78
            '57ef23539033602e61d4a560',
79
            '54c67bb9e4b0512429885513',
80
            '54c67bb9e4b0512429885512',
81
            '54c67bbbe4b07997ea3f3f6b',
82
            '54d1a33ae4b086c0c0964ce9',
83
            '57ef253c9033602e61d4a563',
84
            '552355bfe4b0221aadf2572b',
85
            '54c67bcde4b051242988553e',
86
        );
87
88
		return $localization_data;
89
	}
90
91
	/**
92
	 * @since 1.15
93
	 * @param WP_Query $query
94
	 */
95
	public function filter_pre_get_posts_by_gravityview_form_id( &$query ) {
96
		global $pagenow;
97
98
		if ( !is_admin() ) {
99
			return;
100
		}
101
102
		$form_id = isset( $_GET['gravityview_form_id'] ) ? (int) $_GET['gravityview_form_id'] : false;
103
104
		if( 'edit.php' !== $pagenow || ! $form_id || ! isset( $query->query_vars[ 'post_type' ] ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $form_id of type integer|false is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
105
			return;
106
		}
107
108
		if ( $query->query_vars[ 'post_type' ] == 'gravityview' ) {
109
			$query->set( 'meta_query', array(
110
				array(
111
					'key' => '_gravityview_form_id',
112
					'value' => $form_id,
113
				)
114
			) );
115
		}
116
	}
117
118
	function add_view_dropdown() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
119
		$current_screen = get_current_screen();
120
121
		if( 'gravityview' !== $current_screen->post_type ) {
122
			return;
123
		}
124
125
		$forms = gravityview_get_forms();
126
		$current_form = \GV\Utils::_GET( 'gravityview_form_id' );
127
		// If there are no forms to select, show no forms.
128
		if( !empty( $forms ) ) { ?>
129
			<select name="gravityview_form_id" id="gravityview_form_id">
130
				<option value="" <?php selected( '', $current_form, true ); ?>><?php esc_html_e( 'All forms', 'gravityview' ); ?></option>
131
				<?php foreach( $forms as $form ) { ?>
132
					<option value="<?php echo $form['id']; ?>" <?php selected( $form['id'], $current_form, true ); ?>><?php echo esc_html( $form['title'] ); ?></option>
133
				<?php } ?>
134
			</select>
135
		<?php }
136
	}
137
138
139
	/**
140
	 * @deprecated since 1.2
141
	 * Start using GravityView_Render_Settings::render_setting_row
142
	 */
143
	public static function render_setting_row( $key = '', $current_settings = array(), $override_input = null, $name = 'template_settings[%s]', $id = 'gravityview_se_%s' ) {
144
		_deprecated_function( 'GravityView_Admin_Views::render_setting_row', '1.1.7', 'GravityView_Render_Settings::render_setting_row' );
145
		GravityView_Render_Settings::render_setting_row( $key, $current_settings, $override_input, $name , $id );
146
	}
147
148
	/**
149
	 * @deprecated since 1.2
150
	 * Start using GravityView_Render_Settings::render_field_option
151
	 */
152
	public static function render_field_option( $name = '', $option, $curr_value = NULL ) {
153
		_deprecated_function( 'GravityView_Admin_Views::render_field_option', '1.1.7', 'GravityView_Render_Settings::render_field_option' );
154
		return GravityView_Render_Settings::render_field_option( $name, $option, $curr_value );
155
	}
156
157
158
	/**
159
	 * Add a GravityView menu to the Form Toolbar with connected views
160
	 * @param  array  $menu_items Menu items, as set in GFForms::top_toolbar()
161
	 * @param  int $id         ID of the current Gravity form
162
	 * @return array            Modified array
163
	 */
164
	public static function gform_toolbar_menu( $menu_items = array(), $id = NULL ) {
165
166
		// Don't show on Trashed forms
167
		if( 'trash' === rgget( 'filter') ) {
168
			return $menu_items;
169
		}
170
171
		$connected_views = gravityview_get_connected_views( $id, array( 'post_status' => 'any' ) );
172
173
		$priority = 0;
174
175
		if( 'form_list' === GFForms::get_page() ) {
176
			$priority = 790;
177
        }
178
179
		if( empty( $connected_views ) ) {
180
181
		    $menu_items['gravityview'] = array(
182
				'label'          => esc_attr__( 'Create a View', 'gravityview' ),
183
				'icon'           => '<i class="fa fa-lg gv-icon-astronaut-head gv-icon"></i>',
184
				'title'          => esc_attr__( 'Create a View using this form as a data source', 'gravityview' ),
185
				'url'            => admin_url( 'post-new.php?post_type=gravityview&form_id=' . $id ),
186
				'menu_class'     => 'gv_connected_forms gf_form_toolbar_settings',
187
				'priority'       => $priority,
188
				'capabilities'   => array( 'edit_gravityviews' ),
189
			);
190
191
			return $menu_items;
192
		}
193
194
		$sub_menu_items = array();
195
		foreach ( (array)$connected_views as $view ) {
196
197
			if( ! GVCommon::has_cap( 'edit_gravityview', $view->ID ) ) {
198
				continue;
199
			}
200
201
			$label = empty( $view->post_title ) ? sprintf( __('No Title (View #%d)', 'gravityview' ), $view->ID ) : $view->post_title;
202
203
			$sub_menu_items[] = array(
204
				'label' => esc_attr( $label ),
205
				'url' => admin_url( 'post.php?action=edit&post='.$view->ID ),
206
			);
207
		}
208
209
		// If there were no items added, then let's create the parent menu
210
		if( $sub_menu_items ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $sub_menu_items of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
211
212
		    $sub_menu_items[] = array(
213
			    'label' => esc_attr__( 'Create a View', 'gravityview' ),
214
                'link_class' => 'gv-create-view',
215
			    'icon' => '<i>&nbsp;+&nbsp;</i>',
216
			    'title' => esc_attr__( 'Create a View using this form as a data source', 'gravityview' ),
217
			    'url'   => admin_url( 'post-new.php?post_type=gravityview&form_id=' . $id ),
218
			    'capabilities'   => array( 'edit_gravityviews' ),
219
            );
220
221
222
			/**
223
			 * In Gravity Forms 2.5, they got rid of the sub-menu items, so we are now forced to add them to the main dropdown
224
			 */
225
			if ( ! ( 'gf_edit_forms' === rgget( 'page' ) && '' === rgget( 'view' ) ) || version_compare( '2.5-beta', GFForms::$version, '>' ) ) {
226
227
				// Make sure Gravity Forms uses the submenu; if there's only one item, it uses a link instead of a dropdown
228
				$sub_menu_items[] = array(
229
					'url' => '#',
230
					'label' => '',
231
					'menu_class' => 'hidden',
232
					'capabilities' => '',
233
				);
234
235
				$menu_items['gravityview'] = array(
236
					'label'          => __( 'Connected Views', 'gravityview' ),
237
					'icon'           => '<i class="fa fa-lg gv-icon-astronaut-head gv-icon"></i>',
238
					'title'          => __( 'GravityView Views using this form as a data source', 'gravityview' ),
239
					'url'            => '#',
240
					'onclick'        => 'return false;',
241
					'menu_class'     => 'gv_connected_forms gf_form_toolbar_settings',
242
					'sub_menu_items' => $sub_menu_items,
243
					'priority'       => $priority,
244
					'capabilities'   => array( 'edit_gravityviews' ),
245
				);
246
247
			} else {
248
249
				$menu_items[ 'gravityview'] = array(
250
					'label' => __( 'Connected Views', 'gravityview' ),
251
					'url'   => '#gravityview-group-heading',
252
					'icon'  => '<i class="fa fa-lg gv-icon-astronaut-head gv-icon"></i>',
253
				);
254
				foreach ( $sub_menu_items as $key => $sub_menu_item ) {
255
256
					$menu_items[ 'gravityview-' . $key ] = array(
257
						'label'        => rgar( $sub_menu_item, 'label', '' ),
258
						'icon'         => rgar( $sub_menu_item, 'icon', '<i>&nbsp;&bull;&nbsp;</i>' ),
259
						'title'        => rgar( $sub_menu_item, 'title', '' ),
260
						'url'          => rgar( $sub_menu_item, 'url', '' ),
261
						'menu_class'   => 'gv_calendar gf_form_toolbar_settings',
262
						'priority'     => $priority,
263
						'capabilities' => array( 'edit_gravityviews' ),
264
					);
265
266
				}
267
			}
268
		}
269
270
		return $menu_items;
271
	}
272
273
	/**
274
	 * List the field types without presentation properties (on a View context)
275
	 *
276
	 * @param array $array Existing field types to add to a blacklist
277
	 * @param string|null $context Context for the blacklist. Default: NULL.
278
	 * @return array Default blacklist fields merged with existing blacklist fields
279
	 */
280
	function default_field_blacklist( $array = array(), $context = NULL ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
281
282
		$add = array( 'captcha', 'page' );
283
284
		// Don't allowing editing the following values:
285
		if( $context === 'edit' ) {
286
			$add[] = 'post_id';
287
		}
288
289
		$return = array_merge( $array, $add );
290
291
		return $return;
292
	}
293
294
	/**
295
	 * Add tooltip text for use throughout the UI
296
	 * @param  array       $tooltips Array of Gravity Forms tooltips
297
	 * @return array                Modified tooltips array
298
	 */
299
	public function tooltips( $tooltips = array() ) {
300
301
		$gv_tooltips = array();
302
303
		// Generate tooltips for View settings
304
		$default_args = \GV\View_Settings::defaults( true );
305
306
		foreach ( $default_args as $key => $arg ) {
307
308
			// If an arg has `tooltip` defined, but it's false, don't display a tooltip
309
			if( isset( $arg['tooltip'] ) && empty( $arg['tooltip'] ) ) { continue; }
310
311
			// By default, use `tooltip` if defined.
312
			$tooltip = empty( $arg['tooltip'] ) ? NULL : $arg['tooltip'];
313
314
			// If there's no tooltip set, continue
315
			if( empty( $tooltip ) ) {
316
				continue;
317
			}
318
319
			// Add the tooltip
320
			$gv_tooltips[ 'gv_'.$key ] = array(
321
				'title'	=> $arg['label'],
322
				'value'	=> $tooltip,
323
			);
324
325
		}
326
327
		$gv_tooltips['gv_css_merge_tags'] = array(
328
			'title' => __('CSS Merge Tags', 'gravityview'),
329
			'value' => sprintf( __( 'Developers: The CSS classes will be sanitized using the %ssanitize_title_with_dashes()%s function.', 'gravityview'), '<code>', '</code>' )
330
		);
331
332
		/**
333
		 * @filter `gravityview_tooltips` The tooltips GravityView adds to the Gravity Forms tooltip array
334
		 * @param array $gv_tooltips Associative array with unique keys containing array of `title` and `value` keys, as expected by `gform_tooltips` filter
335
		 * @deprecated Renamed to `gravityview/metaboxes/tooltips`
336
		 */
337
		$gv_tooltips = apply_filters( 'gravityview_tooltips', $gv_tooltips );
338
339
		/**
340
		 * @filter `gravityview/metaboxes/tooltips` The tooltips GravityView adds to the Gravity Forms tooltip array
341
		 * @param array $gv_tooltips Associative array with unique keys containing array of `title` and `value` keys, as expected by `gform_tooltips` filter
342
		 */
343
		$gv_tooltips = apply_filters( 'gravityview/metaboxes/tooltips', $gv_tooltips );
344
345
		foreach ( $gv_tooltips as $key => $tooltip ) {
346
347
			$title = empty( $tooltip['title'] ) ? '' : '<h6>'.esc_html( $tooltip['title'] ) .'</h6>';
348
349
			$tooltips[ $key ] = $title . wpautop( esc_html( $tooltip['value'] ) );
350
		}
351
352
		return $tooltips;
353
	}
354
355
	/**
356
	 * Add the Data Source information
357
	 *
358
	 * @param null $column_name
359
	 * @param $post_id
360
	 *
361
	 * @return void
362
	 */
363
	public function add_custom_column_content( $column_name = NULL, $post_id )	{
364
365
		$output = '';
366
367
		switch ( $column_name ) {
368
			case 'gv_template':
369
370
				$template_id = gravityview_get_template_id( $post_id );
371
372
				// All Views should have a connected form. If it doesn't, that's not right.
373
				if ( empty( $template_id ) ) {
374
					gravityview()->log->error( 'View ID {view_id} does not have a connected template.', array( 'view_id' => $post_id ) );
375
					break;
376
				}
377
378
				$templates = gravityview_get_registered_templates();
379
380
				$template = isset( $templates[ $template_id ] ) ? $templates[ $template_id ] : false;
381
382
				// Generate backup if label doesn't exist: `example_name` => `Example Name`
383
				$template_id_pretty = ucwords( implode( ' ', explode( '_', $template_id ) ) );
384
385
				$output = $template ? $template['label'] : $template_id_pretty;
386
387
				break;
388
389
			case 'gv_connected_form':
390
391
				$form_id = gravityview_get_form_id( $post_id );
392
393
				// All Views should have a connected form. If it doesn't, that's not right.
394
				if ( empty( $form_id ) ) {
395
					gravityview()->log->error( 'View ID {view_id} does not have a connected GF form.', array( 'view_id' => $post_id ) );
396
					$output = __( 'Not connected.', 'gravityview' );
397
					break;
398
				}
399
400
				$form = gravityview_get_form( $form_id );
401
402
				if ( ! $form ) {
403
					gravityview()->log->error( 'Connected form not found: Form #{form_id}', array( 'form_id' => $form_id ) );
404
405
					$output = __( 'The connected form can not be found; it may no longer exist.', 'gravityview' );
406
				} else {
407
					$output = self::get_connected_form_links( $form );
408
				}
409
410
				break;
411
		}
412
413
		echo $output;
414
	}
415
416
417
	/**
418
	 * Get HTML links relating to a connected form, like Edit, Entries, Settings, Preview
419
	 * @param  array|int $form Gravity Forms forms array, or the form ID
420
	 * @param  boolean $include_form_link Whether to include the bold name of the form in the output
421
	 * @return string          HTML links
422
	 */
423
	static public function get_connected_form_links( $form, $include_form_link = true ) {
424
425
		// Either the form is empty or the form ID is 0, not yet set.
426
		if( empty( $form ) ) {
427
			return '';
428
		}
429
430
		// The $form is passed as the form ID
431
		if( !is_array( $form ) ) {
432
			$form = gravityview_get_form( $form );
433
		}
434
435
		$form_id = $form['id'];
436
		$links = array();
437
438
		if( GVCommon::has_cap( 'gravityforms_edit_forms' ) ) {
439
			$form_url = admin_url( sprintf( 'admin.php?page=gf_edit_forms&amp;id=%d', $form_id ) );
440
			$form_link = '<strong class="gv-form-title">'.gravityview_get_link( $form_url, $form['title'], 'class=row-title' ).'</strong>';
441
			$links[] = '<span>'.gravityview_get_link( $form_url, __('Edit Form', 'gravityview') ).'</span>';
442
		} else {
443
			$form_link = '<strong class="gv-form-title">'. esc_html( $form['title'] ). '</strong>';
444
		}
445
446
		if( GVCommon::has_cap( 'gravityforms_view_entries' ) ) {
447
			$entries_url = admin_url( sprintf( 'admin.php?page=gf_entries&amp;id=%d', $form_id ) );
448
			$links[] = '<span>'.gravityview_get_link( $entries_url, __('Entries', 'gravityview') ).'</span>';
449
		}
450
451
		if( GVCommon::has_cap( array( 'gravityforms_edit_settings', 'gravityview_view_settings' ) ) ) {
452
			$settings_url = admin_url( sprintf( 'admin.php?page=gf_edit_forms&amp;view=settings&amp;id=%d', $form_id ) );
453
			$links[] = '<span>'.gravityview_get_link( $settings_url, __('Settings', 'gravityview'), 'title='.__('Edit settings for this form', 'gravityview') ).'</span>';
454
		}
455
456
		if( GVCommon::has_cap( array("gravityforms_edit_forms", "gravityforms_create_form", "gravityforms_preview_forms") ) ) {
457
			$preview_url = site_url( sprintf( '?gf_page=preview&amp;id=%d', $form_id ) );
458
			$links[] = '<span>'.gravityview_get_link( $preview_url, __('Preview Form', 'gravityview'), 'title='.__('Preview this form', 'gravityview') ).'</span>';
459
		}
460
461
		$output = '';
462
463
		if( !empty( $include_form_link ) ) {
464
			$output .= $form_link;
465
		}
466
467
		/**
468
		 * @filter `gravityview_connected_form_links` Modify the links shown in the Connected Form links
469
		 * @since 1.6
470
		 * @param array $links Links to show
471
		 * @param array $form Gravity Forms form array
472
		 */
473
		$links = apply_filters( 'gravityview_connected_form_links', $links, $form );
474
475
		$output .= '<div class="row-actions">'. implode( ' | ', $links ) .'</div>';
476
477
		return $output;
478
	}
479
480
	/**
481
	 * Add the Data Source column to the Views page
482
	 * @param  array      $columns Columns array
483
	 */
484
	public function add_post_type_columns( $columns ) {
485
486
		// Get the date column and save it for later to add back in.
487
		// This adds it after the Data Source column.
488
		// This way, we don't need to do array_slice, array_merge, etc.
489
		$date = $columns['date'];
490
		unset( $columns['date'] );
491
492
		$data_source_required_caps = array(
493
			'gravityforms_edit_forms',
494
			'gravityforms_view_entries',
495
			'gravityforms_edit_settings',
496
			'gravityview_view_settings',
497
			'gravityforms_create_form',
498
			'gravityforms_preview_forms',
499
		);
500
501
		if( GVCommon::has_cap( $data_source_required_caps ) ) {
502
			$columns['gv_connected_form'] = __( 'Data Source', 'gravityview' );
503
		}
504
505
		$columns['gv_template'] = _x( 'Template', 'Column title that shows what template is being used for Views', 'gravityview' );
506
507
		// Add the date back in.
508
		$columns['date'] = $date;
509
510
		return $columns;
511
	}
512
513
	/**
514
	 * Save View configuration
515
	 *
516
	 * @param int $post_id Currently saved Post ID
517
	 * @return void
518
	 */
519
	function save_postdata( $post_id ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
520
521
		if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ){
522
			return;
523
		}
524
525
		// validate post_type
526
		if ( ! isset( $_POST['post_type'] ) || 'gravityview' != $_POST['post_type'] ) {
527
			return;
528
		}
529
530
		// validate user can edit and save View
531
		if ( ! GVCommon::has_cap( 'edit_gravityview', $post_id ) ) {
532
			gravityview()->log->error( 'Current user does not have the capability to edit View {view_id}', array( 'view_id' => $post_id, 'data' => wp_get_current_user() ) );
533
			return;
534
		}
535
536
		gravityview()->log->debug( '[save_postdata] Saving View post type.', array( 'data' => $_POST ) );
537
538
		$statii = array();
539
540
		// check if this is a start fresh View
541
		if ( isset( $_POST['gravityview_select_form_nonce'] ) && wp_verify_nonce( $_POST['gravityview_select_form_nonce'], 'gravityview_select_form' ) ) {
542
543
			$form_id = !empty( $_POST['gravityview_form_id'] ) ? $_POST['gravityview_form_id'] : '';
544
			// save form id
545
			$statii['form_id'] = update_post_meta( $post_id, '_gravityview_form_id', $form_id );
546
547
		}
548
549
		if( false === GVCommon::has_cap( 'gravityforms_create_form' ) && empty( $statii['form_id'] ) ) {
550
			gravityview()->log->error( 'Current user does not have the capability to create a new Form.', array( 'data' => wp_get_current_user() ) );
551
			return;
552
		}
553
554
		// Was this a start fresh?
555
		if ( ! empty( $_POST['gravityview_form_id_start_fresh'] ) ) {
556
			$statii['start_fresh'] = add_post_meta( $post_id, '_gravityview_start_fresh', 1 );
557
		} else {
558
			$statii['start_fresh'] = delete_post_meta( $post_id, '_gravityview_start_fresh' );
559
		}
560
561
		// Check if we have a template id
562
		if ( isset( $_POST['gravityview_select_template_nonce'] ) && wp_verify_nonce( $_POST['gravityview_select_template_nonce'], 'gravityview_select_template' ) ) {
563
564
			$template_id = !empty( $_POST['gravityview_directory_template'] ) ? $_POST['gravityview_directory_template'] : '';
565
566
			// now save template id
567
			$statii['directory_template'] = update_post_meta( $post_id, '_gravityview_directory_template', $template_id );
568
		}
569
570
571
		// save View Configuration metabox
572
		if ( isset( $_POST['gravityview_view_configuration_nonce'] ) && wp_verify_nonce( $_POST['gravityview_view_configuration_nonce'], 'gravityview_view_configuration' ) ) {
573
574
			// template settings
575
			if( empty( $_POST['template_settings'] ) ) {
576
				$_POST['template_settings'] = array();
577
			}
578
			$statii['template_settings'] = update_post_meta( $post_id, '_gravityview_template_settings', $_POST['template_settings'] );
579
580
			// guard against unloaded View configuration page
581
			if ( isset( $_POST['gv_fields'] ) && isset( $_POST['gv_fields_done'] ) ) {
582
				$fields = array();
583
584
				if ( ! empty( $_POST['gv_fields'] ) ) {
585
					$fields = _gravityview_process_posted_fields();
586
				}
587
588
				$fields = wp_slash( $fields );
589
590
				$statii['directory_fields'] = update_post_meta( $post_id, '_gravityview_directory_fields', $fields );
591
			}
592
593
			// Directory Visible Widgets
594
			if( empty( $_POST['widgets'] ) ) {
595
				$_POST['widgets'] = array();
596
			}
597
			$statii['directory_widgets'] = gravityview_set_directory_widgets( $post_id, $_POST['widgets'] );
598
599
		} // end save view configuration
600
601
		/**
602
		 * @action `gravityview_view_saved` After a View has been saved in the admin
603
		 * @param int $post_id ID of the View that has been saved
604
		 * @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.
605
		 * @since 1.17.2
606
		 */
607
		do_action('gravityview_view_saved', $post_id, $statii );
608
609
		gravityview()->log->debug( '[save_postdata] Update Post Meta Statuses (also returns false if nothing changed)', array( 'data' => array_map( 'intval', $statii ) ) );
610
	}
611
612
	/**
613
	 * @deprecated 1.1.6
614
	 */
615
	function render_label() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
616
		_deprecated_function( 'GravityView_Admin_Views::render_label()', '1.1.6', 'Use the GravityView_Admin_View_Field class instead.' );
617
	}
618
619
	/**
620
	 * Render html for displaying available fields based on a Form ID
621
	 *
622
     * @see GravityView_Ajax::get_available_fields_html() Triggers `gravityview_render_available_fields` action
623
	 *
624
	 * @param int $form Gravity Forms Form ID (default: '')
625
	 * @param string $context (default: 'single')
626
     *
627
	 * @return void
628
	 */
629
	function render_available_fields( $form = 0, $context = 'single' ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
630
631
	    // Determine if form is a preset and convert it to an array with fields
632
		$form = ( is_string( $form ) && preg_match( '/^preset_/', $form ) ) ? GravityView_Ajax::pre_get_form_fields( $form ) : $form;
633
634
		/**
635
		 * @filter  `gravityview_blacklist_field_types` Modify the types of fields that shouldn't be shown in a View.
636
		 * @param[in,out] array $blacklist_field_types Array of field types to block for this context.
637
		 * @param[in] string $context View context ('single', 'directory', or 'edit')
638
		 */
639
		$blacklist_field_types = apply_filters( 'gravityview_blacklist_field_types', array(), $context );
640
641
		if ( ! is_array( $blacklist_field_types ) ) {
642
643
		    gravityview()->log->error( '$blacklist_field_types is not an array', array( 'data' => print_r( $blacklist_field_types, true ) ) );
644
645
			$blacklist_field_types = array();
646
		}
647
648
		$fields = $this->get_available_fields( $form, $context );
649
650
		$output = '';
651
652
		if( !empty( $fields ) ) {
653
654
			foreach( $fields as $id => $details ) {
655
656
				if( in_array( $details['type'], (array) $blacklist_field_types ) ) {
657
					continue;
658
				}
659
660
				// Edit mode only allows editing the parent fields, not single inputs.
661
				if( $context === 'edit' && ! empty( $details['parent'] ) ) {
662
					continue;
663
				}
664
665
				$output .= new GravityView_Admin_View_Field( $details['label'], $id, $details, array(), $form );
666
667
			} // End foreach
668
		}
669
670
		echo $output;
671
672
		// For the EDIT view we only want to allow the form fields.
673
		if( $context === 'edit' ) {
674
			return;
675
		}
676
677
		$this->render_additional_fields( $form, $context );
678
	}
679
680
	/**
681
	 * Render html for displaying additional fields based on a Form ID
682
	 *
683
	 * @param int $form Gravity Forms Form ID (default: '')
684
	 * @param string $context (default: 'single')
685
	 * @return void
686
	 */
687
	public function render_additional_fields( $form = 0, $context = 'single' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
688
689
		$additional_fields = array(
690
			array(
691
				'label_text' => '+ ' . __( 'Add All Form Fields', 'gravityview' ),
692
				'desc' => __('Insert all the form fields at once.', 'gravityview'),
693
				'field_id' => 'all-fields',
694
				'label_type' => 'field',
695
				'input_type' => null,
696
				'field_options' => null,
697
				'settings_html'	=> null,
698
				'icon' => null,
699
			)
700
		);
701
702
		/**
703
		 * @filter `gravityview_additional_fields` non-standard Fields to show at the bottom of the field picker
704
		 * @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
705
		 */
706
		$additional_fields = apply_filters( 'gravityview_additional_fields', $additional_fields );
707
708
		foreach ( (array) $additional_fields as $item ) {
709
710
			// Prevent items from not having index set
711
			$item = wp_parse_args( $item, array(
712
				'label_text' => null,
713
				'field_id' => null,
714
				'label_type' => null,
715
				'input_type' => null,
716
				'field_options' => null,
717
				'settings_html'	=> null,
718
				'icon' => null,
719
			));
720
721
			// Backward compat.
722
			if( !empty( $item['field_options'] ) ) {
723
				// Use settings_html from now on.
724
				$item['settings_html'] = $item['field_options'];
725
			}
726
727
			// Render a label for each of them
728
			echo new GravityView_Admin_View_Field( $item['label_text'], $item['field_id'], $item, $settings = array(), $form );
729
730
		}
731
732
	}
733
734
	/**
735
	 * Retrieve the default fields id, label and type
736
	 * @param  string|array $form form_ID or form object
737
	 * @param  string $zone   Either 'single', 'directory', 'header', 'footer'
738
	 * @return array
739
	 */
740
	function get_entry_default_fields($form, $zone) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
741
742
		$entry_default_fields = array();
743
744
		if( in_array( $zone, array( 'directory', 'single' ) ) ) {
745
746
			$entry_default_fields = array(
747
				'id' => array(
748
					'label' => __('Entry ID', 'gravityview'),
749
					'type' => 'id',
750
					'desc'	=> __('The unique ID of the entry.', 'gravityview'),
751
				),
752
				'date_created' => array(
753
					'label' => __('Entry Date', 'gravityview'),
754
					'desc'	=> __('The date the entry was created.', 'gravityview'),
755
					'type' => 'date_created',
756
				),
757
				'date_updated' => array(
758
						'label' => __( 'Date Updated', 'gravityview'),
759
						'desc'	=> __('The date the entry was last updated.', 'gravityview'),
760
						'type' => 'date_updated',
761
				),
762
				'source_url' => array(
763
					'label' => __('Source URL', 'gravityview'),
764
					'type' => 'source_url',
765
					'desc'	=> __('The URL of the page where the form was submitted.', 'gravityview'),
766
				),
767
				'ip' => array(
768
					'label' => __('User IP', 'gravityview'),
769
					'type' => 'ip',
770
					'desc'	=> __('The IP Address of the user who created the entry.', 'gravityview'),
771
				),
772
				'created_by' => array(
773
					'label' => __('User', 'gravityview'),
774
					'type' => 'created_by',
775
					'desc'	=> __('Details of the logged-in user who created the entry (if any).', 'gravityview'),
776
				),
777
778
				/**
779
				 * @since 1.7.2
780
				 */
781
			    'other_entries' => array(
782
				    'label'	=> __('Other Entries', 'gravityview'),
783
				    'type'	=> 'other_entries',
784
				    'desc'	=> __('Display other entries created by the entry creator.', 'gravityview'),
785
			    ),
786
	        );
787
788
			if( 'single' !== $zone) {
789
790
				$entry_default_fields['entry_link'] = array(
791
					'label' => __('Link to Entry', 'gravityview'),
792
					'desc'	=> __('A dedicated link to the single entry with customizable text.', 'gravityview'),
793
					'type' => 'entry_link',
794
				);
795
			}
796
797
		} // if not zone directory or single
798
799
		/**
800
		 * @since  1.2
801
		 */
802
		$entry_default_fields['custom']	= array(
803
			'label'	=> __('Custom Content', 'gravityview'),
804
			'type'	=> 'custom',
805
			'desc'	=> __('Insert custom text or HTML.', 'gravityview'),
806
		);
807
808
		/**
809
		 * @since develop
810
		 */
811
		$entry_default_fields['sequence'] = array(
812
			'label'	=> __('Result Number', 'gravityview'),
813
			'type'	=> 'sequence',
814
			'desc'	=> __('Display a sequential result number for each entry.', 'gravityview'),
815
		);
816
817
		/**
818
		 * @filter `gravityview_entry_default_fields` Modify the default fields for each zone and context
819
		 * @param array $entry_default_fields Array of fields shown by default
820
		 * @param  string|array $form form_ID or form object
821
		 * @param  string $zone   Either 'single', 'directory', 'header', 'footer'
822
		 */
823
		return apply_filters( 'gravityview_entry_default_fields', $entry_default_fields, $form, $zone);
824
	}
825
826
	/**
827
	 * Calculate the available fields
828
	 * @param  string|array $form form_ID or form object
829
	 * @param  string $zone   Either 'single', 'directory', 'header', 'footer'
830
	 * @return array         fields
831
	 */
832
	function get_available_fields( $form = '', $zone = NULL ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
833
834
		if( empty( $form ) ) {
835
			gravityview()->log->error( '$form is empty' );
836
			return array();
837
		}
838
839
		// get form fields
840
		$fields = gravityview_get_form_fields( $form, true );
841
842
		// get meta fields ( only if form was already created )
843
		if( !is_array( $form ) ) {
844
			$meta_fields = gravityview_get_entry_meta( $form );
845
		} else {
846
			$meta_fields = array();
847
		}
848
849
		// get default fields
850
		$default_fields = $this->get_entry_default_fields( $form, $zone );
851
852
		//merge without loosing the keys
853
		$fields = $fields + $meta_fields + $default_fields;
854
855
		// Move Custom Content to top
856
		$fields = array( 'custom' => $fields['custom'] ) + $fields;
857
858
		$gv_fields = GravityView_Fields::get_all();
859
860
		foreach ( $fields as &$field ) {
861
			foreach ( $gv_fields as $gv_field ) {
862
				if ( $field['type'] === $gv_field->name ) {
863
					$field['icon'] = $gv_field->icon;
864
				}
865
			}
866
		}
867
868
		/**
869
		 * @filter `gravityview/admin/available_fields` Modify the available fields that can be used in a View.
870
		 * @param[in,out] array $fields The fields.
871
		 * @param  string|array $form form_ID or form object
872
		 * @param  string $zone Either 'single', 'directory', 'header', 'footer'
873
		 */
874
		return apply_filters( 'gravityview/admin/available_fields', $fields, $form, $zone );
875
	}
876
877
878
	/**
879
	 * Render html for displaying available widgets
880
	 * @return string html
881
	 */
882
	function render_available_widgets() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
883
884
		$widgets = $this->get_registered_widgets();
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_Admin_Views::get_registered_widgets() has been deprecated with message: Use \GV\Widget::registered()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
885
886
		if( !empty( $widgets ) ) {
887
888
			foreach( $widgets as $id => $details ) {
889
890
				echo new GravityView_Admin_View_Widget( $details['label'], $id, $details );
891
892
			}
893
		}
894
895
	}
896
897
	/**
898
	 * Get the list of registered widgets. Each item is used to instantiate a GravityView_Admin_View_Widget object
899
	 * @deprecated Use \GV\Widget::registered()
900
	 * @since 1.13.1
901
	 * @return array
902
	 */
903
	function get_registered_widgets() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
904
		return \GV\Widget::registered();
905
	}
906
907
	/**
908
	 * Generic function to render rows and columns of active areas for widgets & fields
909
	 * @param  string $template_id The current slug of the selected View template
910
	 * @param  string $type   Either 'widget' or 'field'
911
	 * @param  string $zone   Either 'single', 'directory', 'edit', 'header', 'footer'
912
	 * @param  array $rows    The layout structure: rows, columns and areas
913
	 * @param  array $values  Saved objects
914
	 * @return void
915
	 */
916
	function render_active_areas( $template_id, $type, $zone, $rows, $values ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
917
		global $post;
918
919
		if( $type === 'widget' ) {
920
			$button_label = __( 'Add Widget', 'gravityview' );
921
		} else {
922
			$button_label = __( 'Add Field', 'gravityview' );
923
		}
924
925
		/**
926
		 * @internal Don't rely on this filter! This is for internal use and may change.
927
		 *
928
		 * @since 2.8.1
929
		 *
930
		 * @param string $button_label Text for button: "Add Widget" or "Add Field"
931
		 * @param array $atts {
932
		 *   @type string $type 'widget' or 'field'
933
		 *   @type string $template_id The current slug of the selected View template
934
		 *   @type string $zone Where is this button being shown? Either 'single', 'directory', 'edit', 'header', 'footer'
935
		 * }
936
		 */
937
		$button_label = apply_filters( 'gravityview/admin/add_button_label', $button_label, array( 'type' => $type, 'template_id' => $template_id, 'zone' => $zone ) );
938
939
		$available_items = array();
940
941
		$view = \GV\View::from_post( $post );
942
		$form_id = null;
943
944
		// if saved values, get available fields to label everyone
945
		if( !empty( $values ) && ( !empty( $post->ID ) || !empty( $_POST['template_id'] ) ) ) {
946
947
			if( !empty( $_POST['template_id'] ) ) {
948
				$form = GravityView_Ajax::pre_get_form_fields( $_POST['template_id'] );
949
			} else {
950
				$form_id = $form = gravityview_get_form_id( $post->ID );
951
			}
952
953
			if ( 'field' === $type ) {
954
				$available_items[ $form ] = $this->get_available_fields( $form, $zone );
955
956
				$joined_forms = gravityview_get_joined_forms( $post->ID );
957
958
                foreach ( $joined_forms as $form ) {
959
                    $available_items[ $form->ID ] = $this->get_available_fields( $form->ID, $zone );
960
                }
961
			} else {
962
				$available_items[ $form ] = \GV\Widget::registered();
963
			}
964
		}
965
966
		foreach( $rows as $row ) :
967
			foreach( $row as $col => $areas ) :
968
				$column = ($col == '2-2') ? '1-2' : $col; ?>
969
970
				<div class="gv-grid-col-<?php echo esc_attr( $column ); ?>">
971
972
					<?php foreach( $areas as $area ) : 	?>
973
974
						<div class="gv-droppable-area" data-areaid="<?php echo esc_attr( $zone .'_'. $area['areaid'] ); ?>" data-context="<?php echo esc_attr( $zone ); ?>">
975
							<div class="active-drop active-drop-<?php echo esc_attr( $type ); ?>" data-areaid="<?php echo esc_attr( $zone .'_'. $area['areaid'] ); ?>">
976
								<?php // render saved fields
977
								if( ! empty( $values[ $zone .'_'. $area['areaid'] ] ) ) {
978
979
									foreach( $values[ $zone .'_'. $area['areaid'] ] as $uniqid => $field ) {
980
981
										// Maybe has a form ID
982
										$form_id = empty( $field['form_id'] ) ? $form_id : $field['form_id'];
983
984
										$input_type = NULL;
985
986
										if ( $form_id ) {
987
											$original_item = isset( $available_items[ $form_id ] [ $field['id'] ] ) ? $available_items[ $form_id ] [ $field['id'] ] : false ;
988
                                        } else {
989
											$original_item = isset( $available_items[ $field['id'] ] ) ? $available_items[ $field['id'] ] : false ;
990
                                        }
991
992
										if ( !$original_item ) {
993
											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(' data' => array('available_items' => $available_items, 'field' => $field ) ) );
994
995
											$original_item = $field;
996
										} else {
997
											$input_type = isset( $original_item['type'] ) ? $original_item['type'] : NULL;
998
										}
999
1000
										// Field options dialog box
1001
										$field_options = GravityView_Render_Settings::render_field_options( $form_id, $type, $template_id, $field['id'], $original_item['label'], $zone .'_'. $area['areaid'], $input_type, $uniqid, $field, $zone, $original_item );
1002
1003
										$item = array(
1004
											'input_type' => $input_type,
1005
											'settings_html' => $field_options,
1006
											'label_type' => $type,
1007
										);
1008
1009
										// Merge the values with the current item to pass things like widget descriptions and original field names
1010
										if ( $original_item ) {
1011
											$item = wp_parse_args( $item, $original_item );
1012
										}
1013
1014
										switch( $type ) {
1015
											case 'widget':
1016
												echo new GravityView_Admin_View_Widget( $item['label'], $field['id'], $item, $field );
1017
												break;
1018
											default:
1019
												echo new GravityView_Admin_View_Field( $field['label'], $field['id'], $item, $field, $form_id );
1020
										}
1021
									}
1022
1023
								} // End if zone is not empty ?>
1024
1025
								<span class="drop-message"><?php echo sprintf( esc_html__('"+ %s" or drag existing %ss here.', 'gravityview'), esc_html( $button_label ), esc_html( $type ) ); ?></span>
1026
							</div>
1027
							<div class="gv-droppable-area-action">
1028
								<button 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 ); ?>" data-formid="<?php echo $view ? esc_attr( $view->form ? $view->form->ID : '' ) : ''; ?>"><?php echo '+ '.esc_html( $button_label ); ?></button>
1029
								<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>
1030
							</div>
1031
						</div>
1032
1033
					<?php endforeach; ?>
1034
1035
				</div>
1036
			<?php endforeach;
1037
		endforeach;
1038
	}
1039
1040
	/**
1041
	 * Render the widget active areas
1042
     * @param  string $template_id The current slug of the selected View template
1043
	 * @param  string $zone    Either 'header' or 'footer'
1044
	 * @param  string $post_id Current Post ID (view)
1045
	 * @return string          html
1046
	 */
1047
	function render_widgets_active_areas( $template_id = '', $zone = '', $post_id = '' ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1048
1049
		$default_widget_areas = \GV\Widget::get_default_widget_areas();
1050
1051
		$widgets = array();
1052
		if ( ! empty( $post_id ) ) {
1053
			if ( 'auto-draft' === get_post_status( $post_id ) ) {
1054
				// This is a new View, prefill the widgets
1055
				$widgets = array(
1056
					'header_top' => array(
1057
						substr( md5( microtime( true ) ), 0, 13 ) => array (
1058
							'id' => 'search_bar',
1059
							'label' => __( 'Search Bar', 'gravityview' ),
1060
							'search_layout' => 'horizontal',
1061
							'search_clear' => '0',
1062
							'search_fields' => '[{"field":"search_all","input":"input_text"}]',
1063
							'search_mode' => 'any',
1064
						),
1065
					),
1066
					'header_left' => array(
1067
						substr( md5( microtime( true ) ), 0, 13 ) => array(
1068
							'id' => 'page_info',
1069
							'label' => __( 'Show Pagination Info', 'gravityview' ),
1070
						),
1071
					),
1072
					'header_right' => array(
1073
						substr( md5( microtime( true ) ), 0, 13 ) => array(
1074
							'id' => 'page_links',
1075
							'label' => __( 'Page Links', 'gravityview' ),
1076
							'show_all' => '0',
1077
						),
1078
					),
1079
					'footer_right' => array(
1080
						substr( md5( microtime( true ) ), 0, 13 ) => array(
1081
							'id' => 'page_links',
1082
							'label' => __( 'Page Links', 'gravityview' ),
1083
							'show_all' => '0',
1084
						),
1085
					),
1086
				);
1087
1088
				/**
1089
				 * @filter `gravityview/view/widgets/default` Modify the default widgets for new Views
1090
				 * @param[in,out] array $widgets A Widget configuration array
1091
				 * @param string $zone The widget zone that's being requested
1092
				 * @param int $post_id The auto-draft post ID
1093
				 */
1094
				$widgets = apply_filters( 'gravityview/view/widgets/default', $widgets, $template_id, $zone, $post_id );
1095
			} else {
1096
				$widgets = gravityview_get_directory_widgets( $post_id );
1097
			}
1098
		}
1099
1100
		ob_start();
1101
		?>
1102
1103
		<div class="gv-grid" id="directory-<?php echo $zone; ?>-widgets">
1104
			<?php $this->render_active_areas( $template_id, 'widget', $zone, $default_widget_areas, $widgets ); ?>
1105
		</div>
1106
1107
		<?php
1108
		$output = ob_get_clean();
1109
1110
		echo $output;
1111
1112
		return $output;
1113
	}
1114
1115
	/**
1116
	 * Renders "Add Field" tooltips
1117
	 *
1118
	 * @since 2.0.11
1119
	 *
1120
	 * @param string $context  "directory", "single", or "edit"
1121
	 * @param array  $form_ids (default: array) Array of form IDs
1122
	 *
1123
	 * @return void
1124
	 */
1125
	function render_field_pickers( $context = 'directory', $form_ids = array() ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1126
1127
		global $post;
1128
1129
		if ( $post ) {
1130
			$source_form_id = gravityview_get_form_id( $post->ID );
1131
			if ( $source_form_id ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $source_form_id of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
1132
				$form_ids[] = $source_form_id;
1133
			}
1134
1135
			$joined_forms = \GV\View::get_joined_forms( $post->ID );
1136
			foreach ( $joined_forms as $joined_form ) {
1137
				$form_ids[] = $joined_form->ID;
1138
			}
1139
		}
1140
		foreach ( array_unique( $form_ids ) as $form_id ) {
1141
			$filter_field_id = sprintf( 'gv-field-filter-%s-%s', $context, $form_id );
1142
1143
			?>
1144
            <div id="<?php echo esc_html( $context ); ?>-available-fields-<?php echo esc_attr( $form_id ); ?>" class="hide-if-js gv-tooltip">
1145
                <span class="close" role="button" aria-label="<?php esc_html_e( 'Close', 'gravityview' ); ?>"><i class="dashicons dashicons-dismiss"></i></span>
1146
1147
                <div class="gv-field-filter-form">
1148
                    <label class="screen-reader-text" for="<?php echo esc_html( $filter_field_id ); ?>"><?php esc_html_e( 'Filter Fields:', 'gravityview' ); ?></label>
1149
                    <input type="search" class="widefat gv-field-filter" aria-controls="<?php echo $filter_field_id; ?>" id="<?php echo esc_html( $filter_field_id ); ?>" placeholder="<?php esc_html_e( 'Filter fields by name or label', 'gravityview' ); ?>" />
1150
                </div>
1151
1152
                <div id="available-fields-<?php echo $filter_field_id; ?>" aria-live="polite" role="listbox">
1153
					<?php do_action( 'gravityview_render_available_fields', $form_id, $context ); ?>
1154
                </div>
1155
1156
                <div class="gv-no-results hidden description"><?php esc_html_e( 'No fields were found matching the search.', 'gravityview' ); ?></div>
1157
            </div>
1158
			<?php
1159
		}
1160
	}
1161
1162
	/**
1163
	 * Render the Template Active Areas and configured active fields for a given template id and post id
1164
	 *
1165
	 * @param string $template_id (default: '') Template ID, like `default_list`, `default_table`, `preset_business_data`, etc. {@see GravityView_Template::__construct()}
1166
	 * @param string $post_id (default: '')
1167
	 * @param string $context (default: 'single')
1168
	 * @return string HTML of the active areas
1169
	 */
1170
	function render_directory_active_areas( $template_id = '', $context = 'single', $post_id = '', $echo = false ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1171
		if( empty( $template_id ) ) {
1172
			gravityview()->log->debug( '[render_directory_active_areas] {template_id} is empty', array( 'template_id' => $template_id ) );
1173
			return '';
1174
		}
1175
1176
		/**
1177
		 * @filter `gravityview_template_active_areas`
1178
		 * @see GravityView_Template::assign_active_areas()
1179
		 * @param array $template_areas Empty array, to be filled in by the template class
1180
		 * @param string $template_id Template ID, like `default_list`, `default_table`, `preset_business_data`, etc. {@see GravityView_Template::__construct()}
1181
		 * @param string $context Current View context: `directory`, `single`, or `edit` (default: 'single')
1182
		 */
1183
		$template_areas = apply_filters( 'gravityview_template_active_areas', array(), $template_id, $context );
1184
1185
		if( empty( $template_areas ) ) {
1186
1187
			gravityview()->log->debug( '[render_directory_active_areas] No areas defined. Maybe template {template_id} is disabled.', array( 'data' => $template_id ) );
1188
			$output = '<div>';
1189
			$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>';
1190
			$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>';
1191
			$output .= '</div>';
1192
		} else {
1193
1194
			$fields = '';
1195
			if ( ! empty( $post_id ) ) {
1196
				$fields = gravityview_get_directory_fields( $post_id );
1197
			}
1198
1199
			ob_start();
1200
			$this->render_active_areas( $template_id, 'field', $context, $template_areas, $fields );
1201
			$output = ob_get_clean();
1202
1203
		}
1204
1205
		if( $echo ) {
1206
			echo $output;
1207
		}
1208
1209
		return $output;
1210
	}
1211
1212
	/**
1213
	 * Enqueue scripts and styles at Views editor
1214
	 *
1215
	 * @param mixed $hook
1216
	 * @return void
1217
	 */
1218
	static function add_scripts_and_styles( $hook ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1219
		global $plugin_page, $pagenow;
1220
1221
		$script_debug    = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
1222
		$is_widgets_page = ( $pagenow === 'widgets.php' );
1223
1224
		// Add legacy (2.4 and older) Gravity Forms tooltip script/style
1225
		if ( gravityview()->plugin->is_GF_25() && gravityview()->request->is_admin( '', 'single' ) ) {
0 ignored issues
show
Unused Code introduced by
The call to Frontend_Request::is_admin() has too many arguments starting with ''.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Unused Code introduced by
The call to Request::is_admin() has too many arguments starting with ''.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
1226
			wp_dequeue_script( 'gform_tooltip_init' );
1227
			wp_dequeue_style( 'gform_tooltip' );
1228
			wp_enqueue_style( 'gravityview_gf_tooltip', plugins_url( 'assets/css/gf_tooltip.css', GRAVITYVIEW_FILE ), array(), \GV\Plugin::$version );
1229
			wp_enqueue_script( 'gravityview_gf_tooltip', plugins_url( 'assets/js/gf_tooltip' . $script_debug . '.js', GRAVITYVIEW_FILE ), array(), \GV\Plugin::$version );
1230
		}
1231
1232
		// Add the GV font (with the Astronaut)
1233
        wp_enqueue_style( 'gravityview_global', plugins_url('assets/css/admin-global.css', GRAVITYVIEW_FILE), array(), \GV\Plugin::$version );
1234
		wp_register_style( 'gravityview_views_styles', plugins_url( 'assets/css/admin-views.css', GRAVITYVIEW_FILE ), array( 'dashicons', 'wp-jquery-ui-dialog' ), \GV\Plugin::$version );
1235
1236
		wp_register_script( 'gravityview-jquery-cookie', plugins_url('assets/lib/jquery.cookie/jquery.cookie.min.js', GRAVITYVIEW_FILE), array( 'jquery' ), \GV\Plugin::$version, true );
1237
1238
		if( GFForms::get_page() === 'form_list' ) {
1239
			wp_enqueue_style( 'gravityview_views_styles' );
1240
			return;
1241
        }
1242
1243
		// Don't process any scripts below here if it's not a GravityView page.
1244
		if( ! gravityview()->request->is_admin( $hook, 'single' ) && ! $is_widgets_page ) {
0 ignored issues
show
Unused Code introduced by
The call to Frontend_Request::is_admin() has too many arguments starting with $hook.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Unused Code introduced by
The call to Request::is_admin() has too many arguments starting with $hook.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
1245
		    return;
1246
		}
1247
1248
        wp_enqueue_script( 'jquery-ui-datepicker' );
1249
        wp_enqueue_style( 'gravityview_views_datepicker', plugins_url('assets/css/admin-datepicker.css', GRAVITYVIEW_FILE), \GV\Plugin::$version );
1250
1251
        // Enqueue scripts
1252
        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' ), \GV\Plugin::$version );
1253
1254
        wp_localize_script('gravityview_views_scripts', 'gvGlobals', array(
1255
            'cookiepath' => COOKIEPATH,
1256
            'passed_form_id' => (bool) \GV\Utils::_GET( 'form_id' ),
1257
            'nonce' => wp_create_nonce( 'gravityview_ajaxviews' ),
1258
            'label_viewname' => __( 'Enter View name here', 'gravityview' ),
1259
            'label_reorder_search_fields' => __( 'Reorder Search Fields', 'gravityview' ),
1260
            'label_add_search_field' => __( 'Add Search Field', 'gravityview' ),
1261
            'label_remove_search_field' => __( 'Remove Search Field', 'gravityview' ),
1262
            'label_close' => __( 'Close', 'gravityview' ),
1263
            'label_cancel' => __( 'Cancel', 'gravityview' ),
1264
            'label_continue' => __( 'Continue', 'gravityview' ),
1265
            'label_ok' => __( 'Ok', 'gravityview' ),
1266
            'label_publisherror' => __( 'Error while creating the View for you. Check the settings or contact GravityView support.', 'gravityview' ),
1267
            'loading_text' => esc_html__( 'Loading&hellip;', 'gravityview' ),
1268
            'loading_error' => esc_html__( 'There was an error loading dynamic content.', 'gravityview' ),
1269
            'field_loaderror' => __( 'Error while adding the field. Please try again or contact GravityView support.', 'gravityview' ),
1270
            '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' ),
1271
        ));
1272
1273
		wp_enqueue_style( 'gravityview_views_styles' );
1274
1275
        // Enqueue scripts needed for merge tags
1276
        self::enqueue_gravity_forms_scripts();
1277
	}
1278
1279
	/**
1280
	 * Enqueue Gravity Forms scripts, needed for Merge Tags
1281
     *
1282
     * @since 1.0.5-beta
1283
     *
1284
     * @return void
1285
	 */
1286
	static function enqueue_gravity_forms_scripts() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1287
		GFForms::register_scripts();
1288
1289
		$scripts = array(
1290
		    'sack',
1291
		    'gform_gravityforms',
1292
		    'gform_forms',
1293
		    'gform_form_admin',
1294
		    'jquery-ui-autocomplete'
1295
		);
1296
1297
		if ( wp_is_mobile() ) {
1298
		    $scripts[] = 'jquery-touch-punch';
1299
		}
1300
1301
		wp_enqueue_script( $scripts );
1302
	}
1303
1304
	/**
1305
	 * Add GravityView scripts and styles to Gravity Forms and GravityView No-Conflict modes
1306
	 *
1307
	 * @param array $registered Existing scripts or styles that have been registered (array of the handles)
1308
	 *
1309
	 * @return array
1310
	 */
1311
	function register_no_conflict( $registered ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1312
1313
		$allowed_dependencies = array();
1314
1315
		$filter = current_filter();
1316
1317
		if ( preg_match( '/script/ism', $filter ) ) {
1318
1319
			$allowed_dependencies = array(
1320
				'jquery-ui-core',
1321
				'jquery-ui-dialog',
1322
				'jquery-ui-tabs',
1323
				'jquery-ui-draggable',
1324
				'jquery-ui-droppable',
1325
				'jquery-ui-sortable',
1326
				'jquery-ui-tooltip',
1327
				'gravityview_views_scripts',
1328
				'gravityview-support',
1329
				'gravityview-jquery-cookie',
1330
				'gravityview_views_datepicker',
1331
				'gravityview_gf_tooltip',
1332
				'sack',
1333
				'gform_gravityforms',
1334
				'gform_forms',
1335
				'gform_form_admin',
1336
				'jquery-ui-autocomplete',
1337
			);
1338
1339
		} elseif ( preg_match( '/style/ism', $filter ) ) {
1340
1341
			$allowed_dependencies = array(
1342
				'dashicons',
1343
				'wp-jquery-ui-dialog',
1344
				'gravityview_views_styles',
1345
				'gravityview_global',
1346
				'gravityview_views_datepicker',
1347
				'gravityview_gf_tooltip',
1348
			);
1349
		}
1350
1351
		return array_merge( $registered, $allowed_dependencies );
1352
	}
1353
1354
1355
}
1356
1357
new GravityView_Admin_Views;
1358