Completed
Push — master ( 6337a4...1e5684 )
by Zack
11s
created

maybe_enqueue_flexibility()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 3
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 5
rs 9.4285
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 16 and the first side effect is on line 13.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * The GravityView New Search widget
4
 *
5
 * @package   GravityView-DataTables-Ext
6
 * @license   GPL2+
7
 * @author    Katz Web Services, Inc.
8
 * @link      http://gravityview.co
9
 * @copyright Copyright 2014, Katz Web Services, Inc.
10
 */
11
12
if ( ! defined( 'WPINC' ) ) {
13
	die;
14
}
15
16
class GravityView_Widget_Search extends GravityView_Widget {
17
18
	public static $file;
19
	public static $instance;
20
21
	private $search_filters = array();
0 ignored issues
show
Unused Code introduced by
The property $search_filters is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
22
23
	/**
24
	 * whether search method is GET or POST ( default: GET )
25
	 * @since 1.16.4
26
	 * @var string
27
	 */
28
	private $search_method = 'get';
29
30
	public function __construct() {
31
32
		$this->widget_description = esc_html__( 'Search form for searching entries.', 'gravityview' );
33
34
		self::$instance = &$this;
35
36
		self::$file = plugin_dir_path( __FILE__ );
37
38
		$default_values = array( 'header' => 0, 'footer' => 0 );
39
40
		$settings = array(
41
			'search_layout' => array(
42
				'type' => 'radio',
43
				'full_width' => true,
44
				'label' => esc_html__( 'Search Layout', 'gravityview' ),
45
				'value' => 'horizontal',
46
				'options' => array(
47
					'horizontal' => esc_html__( 'Horizontal', 'gravityview' ),
48
					'vertical' => esc_html__( 'Vertical', 'gravityview' ),
49
				),
50
			),
51
			'search_clear' => array(
52
				'type' => 'checkbox',
53
				'label' => __( 'Show Clear button', 'gravityview' ),
54
				'value' => false,
55
			),
56
			'search_fields' => array(
57
				'type' => 'hidden',
58
				'label' => '',
59
				'class' => 'gv-search-fields-value',
60
				'value' => '[{"field":"search_all","input":"input_text"}]', // Default: Search Everything text box
61
			),
62
			'search_mode' => array(
63
				'type' => 'radio',
64
				'full_width' => true,
65
				'label' => esc_html__( 'Search Mode', 'gravityview' ),
66
				'desc' => __('Should search results match all search fields, or any?', 'gravityview'),
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
67
				'value' => 'any',
68
				'class' => 'hide-if-js',
69
				'options' => array(
70
					'any' => esc_html__( 'Match Any Fields', 'gravityview' ),
71
					'all' => esc_html__( 'Match All Fields', 'gravityview' ),
72
				),
73
			),
74
		);
75
		parent::__construct( esc_html__( 'Search Bar', 'gravityview' ), 'search_bar', $default_values, $settings );
76
77
		// frontend - filter entries
78
		add_filter( 'gravityview_fe_search_criteria', array( $this, 'filter_entries' ), 10, 1 );
79
80
		// frontend - add template path
81
		add_filter( 'gravityview_template_paths', array( $this, 'add_template_path' ) );
82
83
		// Add hidden fields for "Default" permalink structure
84
		add_filter( 'gravityview_widget_search_filters', array( $this, 'add_no_permalink_fields' ), 10, 3 );
85
86
		// admin - add scripts - run at 1100 to make sure GravityView_Admin_Views::add_scripts_and_styles() runs first at 999
87
		add_action( 'admin_enqueue_scripts', array( $this, 'add_scripts_and_styles' ), 1100 );
88
		add_action( 'wp_enqueue_scripts', array( $this, 'register_scripts') );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
89
		add_filter( 'gravityview_noconflict_scripts', array( $this, 'register_no_conflict' ) );
90
91
		// ajax - get the searchable fields
92
		add_action( 'wp_ajax_gv_searchable_fields', array( 'GravityView_Widget_Search', 'get_searchable_fields' ) );
93
94
		// calculate the search method (POST / GET)
95
		$this->set_search_method();
96
97
	}
98
99
	/**
100
	 * @return GravityView_Widget_Search
101
	 */
102
	public static function getInstance() {
0 ignored issues
show
Coding Style introduced by
The function name getInstance is in camel caps, but expected get_instance instead as per the coding standard.
Loading history...
103
		if ( empty( self::$instance ) ) {
104
			self::$instance = new GravityView_Widget_Search;
105
		}
106
		return self::$instance;
107
	}
108
109
	/**
110
	 * Sets the search method to GET (default) or POST
111
	 * @since 1.16.4
112
	 */
113
	private function set_search_method() {
114
		/**
115
		 * @filter `gravityview/search/method` Modify the search form method (GET / POST)
116
		 * @since 1.16.4
117
		 * @param string $search_method Assign an input type according to the form field type. Defaults: `boolean`, `multi`, `select`, `date`, `text`
118
		 * @param string $field_type Gravity Forms field type (also the `name` parameter of GravityView_Field classes)
119
		 */
120
		$method = apply_filters( 'gravityview/search/method', $this->search_method );
121
122
		$method = strtolower( $method );
123
124
		$this->search_method = in_array( $method, array( 'get', 'post' ) ) ? $method : 'get';
125
	}
126
127
	/**
128
	 * Returns the search method
129
	 * @since 1.16.4
130
	 * @return string
131
	 */
132
	public function get_search_method() {
133
		return $this->search_method;
134
	}
135
136
	/**
137
	 * Get the input types available for different field types
138
	 *
139
	 * @since 1.17.5
140
	 *
141
	 * @return array [field type name] => (array|string) search bar input types
142
	 */
143
	public static function get_input_types_by_field_type() {
144
		/**
145
		 * Input Type groups
146
		 * @see admin-search-widget.js (getSelectInput)
147
		 * @var array
148
		 */
149
		$input_types = array(
150
			'text' => array( 'input_text' ),
151
			'address' => array( 'input_text' ),
152
			'number' => array( 'input_text' ),
153
			'date' => array( 'date', 'date_range' ),
154
			'boolean' => array( 'single_checkbox' ),
155
			'select' => array( 'select', 'radio', 'link' ),
156
			'multi' => array( 'select', 'multiselect', 'radio', 'checkbox', 'link' ),
157
		);
158
159
		$input_types = apply_filters( 'gravityview/search/input_types', $input_types );
160
161
		return $input_types;
162
	}
163
164
	/**
165
	 * Get labels for different types of search bar inputs
166
	 *
167
	 * @since 1.17.5
168
	 *
169
	 * @return array [input type] => input type label
170
	 */
171
	public static function get_search_input_labels() {
172
		/**
173
		 * Input Type labels l10n
174
		 * @see admin-search-widget.js (getSelectInput)
175
		 * @var array
176
		 */
177
		$input_labels = array(
178
			'input_text' => esc_html__( 'Text', 'gravityview' ),
179
			'date' => esc_html__( 'Date', 'gravityview' ),
180
			'select' => esc_html__( 'Select', 'gravityview' ),
181
			'multiselect' => esc_html__( 'Select (multiple values)', 'gravityview' ),
182
			'radio' => esc_html__( 'Radio', 'gravityview' ),
183
			'checkbox' => esc_html__( 'Checkbox', 'gravityview' ),
184
			'single_checkbox' => esc_html__( 'Checkbox', 'gravityview' ),
185
			'link' => esc_html__( 'Links', 'gravityview' ),
186
			'date_range' => esc_html__( 'Date range', 'gravityview' ),
187
		);
188
189
		$input_labels = apply_filters( 'gravityview/search/input_labels', $input_labels );
190
191
		return $input_labels;
192
	}
193
194
	public static function get_search_input_label( $input_type ) {
195
		$labels = self::get_search_input_labels();
196
197
		return rgar( $labels, $input_type, false );
198
	}
199
200
	/**
201
	 * Add script to Views edit screen (admin)
202
	 * @param  mixed $hook
203
	 */
204
	public function add_scripts_and_styles( $hook ) {
205
		global $pagenow;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
206
207
		// Don't process any scripts below here if it's not a GravityView page or the widgets screen
208
		if ( ! gravityview_is_admin_page( $hook ) && ( 'widgets.php' !== $pagenow ) ) {
209
			return;
210
		}
211
212
		$script_min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
213
		$script_source = empty( $script_min ) ? '/source' : '';
214
215
		wp_enqueue_script( 'gravityview_searchwidget_admin', plugins_url( 'assets/js'.$script_source.'/admin-search-widget'.$script_min.'.js', __FILE__ ), array( 'jquery', 'gravityview_views_scripts' ), GravityView_Plugin::version );
216
217
		wp_localize_script( 'gravityview_searchwidget_admin', 'gvSearchVar', array(
218
			'nonce' => wp_create_nonce( 'gravityview_ajaxsearchwidget' ),
219
			'label_nofields' => esc_html__( 'No search fields configured yet.', 'gravityview' ),
220
			'label_addfield' => esc_html__( 'Add Search Field', 'gravityview' ),
221
			'label_label' => esc_html__( 'Label', 'gravityview' ),
222
			'label_searchfield' => esc_html__( 'Search Field', 'gravityview' ),
223
			'label_inputtype' => esc_html__( 'Input Type', 'gravityview' ),
224
			'label_ajaxerror' => esc_html__( 'There was an error loading searchable fields. Save the View or refresh the page to fix this issue.', 'gravityview' ),
225
			'input_labels' => json_encode( self::get_search_input_labels() ),
226
			'input_types' => json_encode( self::get_input_types_by_field_type() ),
227
		) );
228
229
	}
230
231
	/**
232
	 * Add admin script to the no-conflict scripts whitelist
233
	 * @param array $allowed Scripts allowed in no-conflict mode
234
	 * @return array Scripts allowed in no-conflict mode, plus the search widget script
235
	 */
236
	public function register_no_conflict( $allowed ) {
237
		$allowed[] = 'gravityview_searchwidget_admin';
238
		return $allowed;
239
	}
240
241
	/**
242
	 * Ajax
243
	 * Returns the form fields ( only the searchable ones )
244
	 *
245
	 * @access public
246
	 * @return void
247
	 */
248
	public static function get_searchable_fields() {
249
250
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'gravityview_ajaxsearchwidget' ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
251
			exit( '0' );
0 ignored issues
show
Coding Style Compatibility introduced by
The method get_searchable_fields() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
252
		}
253
254
		$form = '';
255
256
		// Fetch the form for the current View
257
		if ( ! empty( $_POST['view_id'] ) ) {
258
259
			$form = gravityview_get_form_id( $_POST['view_id'] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
260
261
		} elseif ( ! empty( $_POST['formid'] ) ) {
262
263
			$form = (int) $_POST['formid'];
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
264
265
		} elseif ( ! empty( $_POST['template_id'] ) && class_exists( 'GravityView_Ajax' ) ) {
266
267
			$form = GravityView_Ajax::pre_get_form_fields( $_POST['template_id'] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
268
269
		}
270
271
		// fetch form id assigned to the view
272
		$response = self::render_searchable_fields( $form );
273
274
		exit( $response );
0 ignored issues
show
Coding Style Compatibility introduced by
The method get_searchable_fields() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
275
	}
276
277
	/**
278
	 * Generates html for the available Search Fields dropdown
279
	 * @param  int $form_id
280
	 * @param  string $current (for future use)
281
	 * @return string
282
	 */
283
	public static function render_searchable_fields( $form_id = null, $current = '' ) {
284
285
		if ( is_null( $form_id ) ) {
286
			return '';
287
		}
288
289
		// start building output
290
291
		$output = '<select class="gv-search-fields">';
292
293
		$custom_fields = array(
294
			'search_all' => array(
295
				'text' => esc_html__( 'Search Everything', 'gravityview' ),
296
				'type' => 'text',
297
			),
298
			'entry_date' => array(
299
				'text' => esc_html__( 'Entry Date', 'gravityview' ),
300
				'type' => 'date',
301
			),
302
			'entry_id' => array(
303
				'text' => esc_html__( 'Entry ID', 'gravityview' ),
304
				'type' => 'text',
305
			),
306
			'created_by' => array(
307
				'text' => esc_html__( 'Entry Creator', 'gravityview' ),
308
				'type' => 'select',
309
			)
310
		);
311
312
		foreach( $custom_fields as $custom_field_key => $custom_field ) {
313
			$output .= sprintf( '<option value="%s" %s data-inputtypes="%s" data-placeholder="%s">%s</option>', $custom_field_key, selected( $custom_field_key, $current, false ), $custom_field['type'], self::get_field_label( array('field' => $custom_field_key ) ), $custom_field['text'] );
0 ignored issues
show
introduced by
No space after opening parenthesis of array is bad style
Loading history...
314
		}
315
316
		// Get fields with sub-inputs and no parent
317
		$fields = gravityview_get_form_fields( $form_id, true, true );
318
319
		/**
320
		 * @filter `gravityview/search/searchable_fields` Modify the fields that are displayed as searchable in the Search Bar dropdown\n
321
		 * @since 1.17
322
		 * @see gravityview_get_form_fields() Used to fetch the fields
323
		 * @see GravityView_Widget_Search::get_search_input_types See this method to modify the type of input types allowed for a field
324
		 * @param array $fields Array of searchable fields, as fetched by gravityview_get_form_fields()
325
		 * @param  int $form_id
326
		 */
327
		$fields = apply_filters( 'gravityview/search/searchable_fields', $fields, $form_id );
328
329
		if ( ! empty( $fields ) ) {
330
331
			$blacklist_field_types = apply_filters( 'gravityview_blacklist_field_types', array( 'fileupload', 'post_image', 'post_id', 'section' ), null );
332
333
			foreach ( $fields as $id => $field ) {
334
335
				if ( in_array( $field['type'], $blacklist_field_types ) ) {
336
					continue;
337
				}
338
339
				$types = self::get_search_input_types( $id, $field['type'] );
340
341
				$output .= '<option value="'. $id .'" '. selected( $id, $current, false ).'data-inputtypes="'. esc_attr( $types ) .'">'. esc_html( $field['label'] ) .'</option>';
342
			}
343
		}
344
345
		$output .= '</select>';
346
347
		return $output;
348
349
	}
350
351
	/**
352
	 * Assign an input type according to the form field type
353
	 *
354
	 * @see admin-search-widget.js
355
	 *
356
	 * @param string|int|float $field_id Gravity Forms field ID
357
	 * @param string $field_type Gravity Forms field type (also the `name` parameter of GravityView_Field classes)
358
	 *
359
	 * @return string GV field search input type ('multi', 'boolean', 'select', 'date', 'text')
360
	 */
361
	public static function get_search_input_types( $field_id = '', $field_type = null ) {
362
363
		// @todo - This needs to be improved - many fields have . including products and addresses
364
		if ( false !== strpos( (string) $field_id, '.' ) && in_array( $field_type, array( 'checkbox' ) ) || in_array( $field_id, array( 'is_fulfilled' ) ) ) {
365
			$input_type = 'boolean'; // on/off checkbox
366
		} elseif ( in_array( $field_type, array( 'checkbox', 'post_category', 'multiselect' ) ) ) {
367
			$input_type = 'multi'; //multiselect
368
		} elseif ( in_array( $field_type, array( 'select', 'radio' ) ) ) {
369
			$input_type = 'select';
370
		} elseif ( in_array( $field_type, array( 'date' ) ) || in_array( $field_id, array( 'payment_date' ) ) ) {
371
			$input_type = 'date';
372
		} elseif ( in_array( $field_type, array( 'number' ) ) || in_array( $field_id, array( 'payment_amount' ) ) ) {
373
			$input_type = 'number';
374
		} else {
375
			$input_type = 'text';
376
		}
377
378
		/**
379
		 * @filter `gravityview/extension/search/input_type` Modify the search form input type based on field type
380
		 * @since 1.2
381
		 * @since 1.19.2 Added $field_id parameter
382
		 * @param string $input_type Assign an input type according to the form field type. Defaults: `boolean`, `multi`, `select`, `date`, `text`
383
		 * @param string $field_type Gravity Forms field type (also the `name` parameter of GravityView_Field classes)
384
		 * @param string|int|float $field_id ID of the field being processed
385
		 */
386
		$input_type = apply_filters( 'gravityview/extension/search/input_type', $input_type, $field_type, $field_id );
387
388
		return $input_type;
389
	}
390
391
	/**
392
	 * Display hidden fields to add support for sites using Default permalink structure
393
	 *
394
	 * @since 1.8
395
	 * @return array Search fields, modified if not using permalinks
396
	 */
397
	public function add_no_permalink_fields( $search_fields, $object, $widget_args = array() ) {
398
		/** @global WP_Rewrite $wp_rewrite */
399
		global $wp_rewrite;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
400
401
		// Support default permalink structure
402
		if ( false === $wp_rewrite->using_permalinks() ) {
403
404
			// By default, use current post.
405
			$post_id = 0;
406
407
			// We're in the WordPress Widget context, and an overriding post ID has been set.
408
			if ( ! empty( $widget_args['post_id'] ) ) {
409
				$post_id = absint( $widget_args['post_id'] );
410
			}
411
			// We're in the WordPress Widget context, and the base View ID should be used
412
			else if ( ! empty( $widget_args['view_id'] ) ) {
413
				$post_id = absint( $widget_args['view_id'] );
414
			}
415
416
			$args = gravityview_get_permalink_query_args( $post_id );
417
418
			// Add hidden fields to the search form
419
			foreach ( $args as $key => $value ) {
0 ignored issues
show
Bug introduced by
The expression $args of type array|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
420
				$search_fields[] = array(
421
					'name'  => $key,
422
					'input' => 'hidden',
423
					'value' => $value,
424
				);
425
			}
426
		}
427
428
		return $search_fields;
429
	}
430
431
432
	/** --- Frontend --- */
433
434
	/**
435
	 * Calculate the search criteria to filter entries
436
	 * @param  array $search_criteria
437
	 * @return array
438
	 */
439
	public function filter_entries( $search_criteria ) {
440
441
		if( 'post' === $this->search_method ) {
442
			$get = $_POST;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
443
		} else {
444
			$get = $_GET;
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
445
		}
446
447
		do_action( 'gravityview_log_debug', sprintf( '%s[filter_entries] Requested $_%s: ', get_class( $this ), $this->search_method ), $get );
448
449
		if ( empty( $get ) || ! is_array( $get ) ) {
450
			return $search_criteria;
451
		}
452
453
		$get = stripslashes_deep( $get );
454
455
		$get = gv_map_deep( $get, 'rawurldecode' );
456
457
		// add free search
458
		if ( ! empty( $get['gv_search'] ) ) {
459
460
			// Search for a piece
461
			$words = explode( ' ', $get['gv_search'] );
462
463
			$words = array_filter( $words );
464
465
			foreach ( $words as $word ) {
466
				$search_criteria['field_filters'][] = array(
467
					'key' => null, // The field ID to search
468
					'value' => $word, // The value to search
469
					'operator' => 'contains', // What to search in. Options: `is` or `contains`
470
				);
471
			}
472
		}
473
474
		//start date & end date
475
		$curr_start = !empty( $get['gv_start'] ) ? $get['gv_start'] : '';
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
476
		$curr_end = !empty( $get['gv_start'] ) ? $get['gv_end'] : '';
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
477
478
		/**
479
		 * @filter `gravityview_date_created_adjust_timezone` Whether to adjust the timezone for entries. \n
480
		 * date_created is stored in UTC format. Convert search date into UTC (also used on templates/fields/date_created.php)
481
		 * @since 1.12
482
		 * @param[out,in] boolean $adjust_tz  Use timezone-adjusted datetime? If true, adjusts date based on blog's timezone setting. If false, uses UTC setting. Default: true
483
		 * @param[in] string $context Where the filter is being called from. `search` in this case.
484
		 */
485
		$adjust_tz = apply_filters( 'gravityview_date_created_adjust_timezone', true, 'search' );
486
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
487
488
		/**
489
		 * Don't set $search_criteria['start_date'] if start_date is empty as it may lead to bad query results (GFAPI::get_entries)
490
		 */
491
		if( !empty( $curr_start ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
492
			$search_criteria['start_date'] = $adjust_tz ? get_gmt_from_date( $curr_start ) : $curr_start;
493
		}
494
		if( !empty( $curr_end ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
495
			$search_criteria['end_date'] = $adjust_tz ? get_gmt_from_date( $curr_end ) : $curr_end;
496
		}
497
498
		// search for a specific entry ID
499
		if ( ! empty( $get[ 'gv_id' ] ) ) {
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
500
			$search_criteria['field_filters'][] = array(
501
				'key' => 'id',
502
				'value' => absint( $get[ 'gv_id' ] ),
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
503
				'operator' => '=',
504
			);
505
		}
506
507
		// search for a specific Created_by ID
508
		if ( ! empty( $get[ 'gv_by' ] ) ) {
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
509
			$search_criteria['field_filters'][] = array(
510
				'key' => 'created_by',
511
				'value' => absint( $get['gv_by'] ),
512
				'operator' => '=',
513
			);
514
		}
515
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
516
517
		// Get search mode passed in URL
518
		$mode = isset( $get['mode'] ) && in_array( $get['mode'], array( 'any', 'all' ) ) ?  $get['mode'] : 'any';
519
520
		// get the other search filters
521
		foreach ( $get as $key => $value ) {
522
523
			if ( 0 !== strpos( $key, 'filter_' ) || empty( $value ) || ( is_array( $value ) && count( $value ) === 1 && empty( $value[0] ) ) ) {
0 ignored issues
show
introduced by
Found "=== 1". Use Yoda Condition checks, you must
Loading history...
524
				continue;
525
			}
526
527
			// could return simple filter or multiple filters
528
			$filter = $this->prepare_field_filter( $key, $value );
529
530
			if ( isset( $filter[0]['value'] ) ) {
531
				$search_criteria['field_filters'] = array_merge( $search_criteria['field_filters'], $filter );
532
533
				// if date range type, set search mode to ALL
534
				if ( ! empty( $filter[0]['operator'] ) && in_array( $filter[0]['operator'], array( '>=', '<=', '>', '<' ) ) ) {
535
					$mode = 'all';
536
				}
537
			} elseif( !empty( $filter ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
538
				$search_criteria['field_filters'][] = $filter;
539
			}
540
		}
541
542
		/**
543
		 * @filter `gravityview/search/mode` Set the Search Mode (`all` or `any`)
544
		 * @since 1.5.1
545
		 * @param[out,in] string $mode Search mode (`any` vs `all`)
546
		 */
547
		$search_criteria['field_filters']['mode'] = apply_filters( 'gravityview/search/mode', $mode );
548
549
		do_action( 'gravityview_log_debug', sprintf( '%s[filter_entries] Returned Search Criteria: ', get_class( $this ) ), $search_criteria );
550
551
		unset( $get );
552
553
		return $search_criteria;
554
	}
555
556
	/**
557
	 * Prepare the field filters to GFAPI
558
	 *
559
	 * The type post_category, multiselect and checkbox support multi-select search - each value needs to be separated in an independent filter so we could apply the ANY search mode.
560
	 *
561
	 * Format searched values
562
	 * @param  string $key   $_GET/$_POST search key
563
	 * @param  string $value $_GET/$_POST search value
564
	 * @return array        1 or 2 deph levels
565
	 */
566
	public function prepare_field_filter( $key, $value ) {
567
568
		$gravityview_view = GravityView_View::getInstance();
569
570
		$field_id = str_replace( 'filter_', '', $key );
571
572
		// calculates field_id, removing 'filter_' and for '_' for advanced fields ( like name or checkbox )
573
		if ( preg_match('/^[0-9_]+$/ism', $field_id ) ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
574
			$field_id = str_replace( '_', '.', $field_id );
575
		}
576
577
		// get form field array
578
		$form = $gravityview_view->getForm();
579
		$form_field = gravityview_get_field( $form, $field_id );
580
581
		// default filter array
582
		$filter = array(
583
			'key' => $field_id,
584
			'value' => $value,
585
		);
586
587
		switch ( $form_field['type'] ) {
588
589
			case 'select':
590
			case 'radio':
591
				$filter['operator'] = 'is';
592
				break;
593
594
			case 'post_category':
595
596
				if ( ! is_array( $value ) ) {
597
					$value = array( $value );
598
				}
599
600
				// Reset filter variable
601
				$filter = array();
602
603
				foreach ( $value as $val ) {
604
					$cat = get_term( $val, 'category' );
605
					$filter[] = array(
606
						'key' => $field_id,
607
						'value' => esc_attr( $cat->name ) . ':' . $val,
608
						'operator' => 'is',
609
					);
610
				}
611
612
				break;
613
614
			case 'multiselect':
615
616
				if ( ! is_array( $value ) ) {
617
					break;
618
				}
619
620
				// Reset filter variable
621
				$filter = array();
622
623
				foreach ( $value as $val ) {
624
					$filter[] = array( 'key' => $field_id, 'value' => $val );
625
				}
626
627
				break;
628
629
			case 'checkbox':
630
				// convert checkbox on/off into the correct search filter
631
				if ( false !== strpos( $field_id, '.' ) && ! empty( $form_field['inputs'] ) && ! empty( $form_field['choices'] ) ) {
632
					foreach ( $form_field['inputs'] as $k => $input ) {
633
						if ( $input['id'] == $field_id ) {
634
							$filter['value'] = $form_field['choices'][ $k ]['value'];
635
							$filter['operator'] = 'is';
636
							break;
637
						}
638
					}
639
				} elseif ( is_array( $value ) ) {
640
641
					// Reset filter variable
642
					$filter = array();
643
644
					foreach ( $value as $val ) {
645
						$filter[] = array(
646
							'key'   => $field_id,
647
							'value' => $val,
648
							'operator' => 'is',
649
						);
650
					}
651
				}
652
653
				break;
654
655
			case 'name':
656
			case 'address':
657
658
				if ( false === strpos( $field_id, '.' ) ) {
659
660
					$words = explode( ' ', $value );
661
662
					$filters = array();
663
					foreach ( $words as $word ) {
664
						if ( ! empty( $word ) && strlen( $word ) > 1 ) {
665
							// Keep the same key for each filter
666
							$filter['value'] = $word;
667
							// Add a search for the value
668
							$filters[] = $filter;
669
						}
670
					}
671
672
					$filter = $filters;
673
				}
674
675
				break;
676
677
			case 'date':
678
679
				if ( is_array( $value ) ) {
680
681
					// Reset filter variable
682
					$filter = array();
683
684
					foreach ( $value as $k => $date ) {
685
						if ( empty( $date ) ) {
686
							continue;
687
						}
688
						$operator = 'start' === $k ? '>=' : '<=';
689
690
						/**
691
						 * @hack
692
						 * @since 1.16.3
693
						 * Safeguard until GF implements '<=' operator
694
						 */
695
						if( !GFFormsModel::is_valid_operator( $operator ) && $operator === '<=' ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
696
							$operator = '<';
697
							$date = date( 'Y-m-d', strtotime( $date . ' +1 day' ) );
698
						}
699
700
						$filter[] = array(
701
							'key' => $field_id,
702
							'value' => self::get_formatted_date( $date, 'Y-m-d' ),
703
							'operator' => $operator,
704
						);
705
					}
706
				} else {
707
					$filter['value'] = self::get_formatted_date( $value, 'Y-m-d' );
708
				}
709
710
				break;
711
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
712
713
		} // switch field type
714
715
		return $filter;
716
	}
717
718
	/**
719
	 * Get the Field Format form GravityForms
720
	 *
721
	 * @param GF_Field_Date $field The field object
722
	 * @since 1.10
723
	 *
724
	 * @return string Format of the date in the database
725
	 */
726
	public static function get_date_field_format( GF_Field_Date $field ) {
727
		$format = 'm/d/Y';
728
		$datepicker = array(
729
			'mdy' => 'm/d/Y',
730
			'dmy' => 'd/m/Y',
731
			'dmy_dash' => 'd-m-Y',
732
			'dmy_dot' => 'm.d.Y',
733
			'ymd_slash' => 'Y/m/d',
734
			'ymd_dash' => 'Y-m-d',
735
			'ymd_dot' => 'Y.m.d',
736
		);
737
738
		if ( ! empty( $field->dateFormat ) && isset( $datepicker[ $field->dateFormat ] ) ){
739
			$format = $datepicker[ $field->dateFormat ];
740
		}
741
742
		return $format;
743
	}
744
745
	/**
746
	 * Format a date value
747
	 *
748
	 * @param string $value Date value input
749
	 * @param string $format Wanted formatted date
750
	 * @return string
751
	 */
752
	public static function get_formatted_date( $value = '', $format = 'Y-m-d' ) {
753
		$date = date_create( $value );
754
		if ( empty( $date ) ) {
755
			do_action( 'gravityview_log_debug', sprintf( '%s[get_formatted_date] Date format not valid: ', get_class( self::$instance ) ), $value );
756
			return '';
757
		}
758
		return $date->format( $format );
759
	}
760
761
762
	/**
763
	 * Include this extension templates path
764
	 * @param array $file_paths List of template paths ordered
765
	 */
766
	public function add_template_path( $file_paths ) {
767
768
		// Index 100 is the default GravityView template path.
769
		$file_paths[102] = self::$file . 'templates/';
770
771
		return $file_paths;
772
	}
773
774
	/**
775
	 * Check whether the configured search fields have a date field
776
	 *
777
	 * @since 1.17.5
778
	 *
779
	 * @param array $search_fields
780
	 *
781
	 * @return bool True: has a `date` or `date_range` field
782
	 */
783
	private function has_date_field( $search_fields ) {
784
785
		$has_date = false;
786
787
		foreach ( $search_fields as $k => $field ) {
788
			if ( in_array( $field['input'], array( 'date', 'date_range', 'entry_date' ) ) ) {
789
				$has_date = true;
790
				break;
791
			}
792
		}
793
794
		return $has_date;
795
	}
796
797
	/**
798
	 * Renders the Search Widget
799
	 * @param array $widget_args
800
	 * @param string $content
801
	 * @param string $context
802
	 *
803
	 * @return void
804
	 */
805
	public function render_frontend( $widget_args, $content = '', $context = '' ) {
806
		/** @var GravityView_View $gravityview_view */
807
		$gravityview_view = GravityView_View::getInstance();
808
809
		if ( empty( $gravityview_view ) ) {
810
			do_action( 'gravityview_log_debug', sprintf( '%s[render_frontend]: $gravityview_view not instantiated yet.', get_class( $this ) ) );
811
			return;
812
		}
813
814
		// get configured search fields
815
		$search_fields = ! empty( $widget_args['search_fields'] ) ? json_decode( $widget_args['search_fields'], true ) : '';
816
817
		if ( empty( $search_fields ) || ! is_array( $search_fields ) ) {
818
			do_action( 'gravityview_log_debug', sprintf( '%s[render_frontend] No search fields configured for widget:', get_class( $this ) ), $widget_args );
819
			return;
820
		}
821
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
822
823
		// prepare fields
824
		foreach ( $search_fields as $k => $field ) {
825
826
			$updated_field = $field;
827
828
			$updated_field = $this->get_search_filter_details( $updated_field );
829
830
			switch ( $field['field'] ) {
831
832
				case 'search_all':
833
					$updated_field['key'] = 'search_all';
834
					$updated_field['input'] = 'search_all';
835
					$updated_field['value'] = $this->rgget_or_rgpost( 'gv_search' );
836
					break;
837
838
				case 'entry_date':
839
					$updated_field['key'] = 'entry_date';
840
					$updated_field['input'] = 'entry_date';
841
					$updated_field['value'] = array(
842
						'start' => $this->rgget_or_rgpost( 'gv_start' ),
843
						'end' => $this->rgget_or_rgpost( 'gv_end' ),
844
					);
845
					break;
846
847
				case 'entry_id':
848
					$updated_field['key'] = 'entry_id';
849
					$updated_field['input'] = 'entry_id';
850
					$updated_field['value'] = $this->rgget_or_rgpost( 'gv_id' );
851
					break;
852
853
				case 'created_by':
854
					$updated_field['key'] = 'created_by';
855
					$updated_field['name'] = 'gv_by';
856
					$updated_field['value'] = $this->rgget_or_rgpost( 'gv_by' );
857
					$updated_field['choices'] = self::get_created_by_choices();
858
					break;
859
			}
860
861
			$search_fields[ $k ] = $updated_field;
862
		}
863
864
		do_action( 'gravityview_log_debug', sprintf( '%s[render_frontend] Calculated Search Fields: ', get_class( $this ) ), $search_fields );
865
866
		/**
867
		 * @filter `gravityview_widget_search_filters` Modify what fields are shown. The order of the fields in the $search_filters array controls the order as displayed in the search bar widget.
868
		 * @param array $search_fields Array of search filters with `key`, `label`, `value`, `type` keys
869
		 * @param GravityView_Widget_Search $this Current widget object
870
		 * @param array $widget_args Args passed to this method. {@since 1.8}
871
		 * @var array
872
		 */
873
		$gravityview_view->search_fields = apply_filters( 'gravityview_widget_search_filters', $search_fields, $this, $widget_args );
874
875
		$gravityview_view->search_layout = ! empty( $widget_args['search_layout'] ) ? $widget_args['search_layout'] : 'horizontal';
876
877
		/** @since 1.14 */
878
		$gravityview_view->search_mode = ! empty( $widget_args['search_mode'] ) ? $widget_args['search_mode'] : 'any';
879
880
		$custom_class = ! empty( $widget_args['custom_class'] ) ? $widget_args['custom_class'] : '';
881
882
		$gravityview_view->search_class = self::get_search_class( $custom_class );
883
884
		$gravityview_view->search_clear = ! empty( $widget_args['search_clear'] ) ? $widget_args['search_clear'] : false;
885
886
		if ( $this->has_date_field( $search_fields ) ) {
887
			// enqueue datepicker stuff only if needed!
888
			$this->enqueue_datepicker();
889
		}
890
891
		$this->maybe_enqueue_flexibility();
892
893
		$gravityview_view->render( 'widget', 'search', false );
894
	}
895
896
	/**
897
	 * Get the search class for a search form
898
	 *
899
	 * @since 1.5.4
900
	 *
901
	 * @return string Sanitized CSS class for the search form
902
	 */
903
	public static function get_search_class( $custom_class = '' ) {
904
		$gravityview_view = GravityView_View::getInstance();
905
906
		$search_class = 'gv-search-'.$gravityview_view->search_layout;
907
908
		if ( ! empty( $custom_class )  ) {
909
			$search_class .= ' '.$custom_class;
910
		}
911
912
		/**
913
		 * @filter `gravityview_search_class` Modify the CSS class for the search form
914
		 * @param string $search_class The CSS class for the search form
915
		 */
916
		$search_class = apply_filters( 'gravityview_search_class', $search_class );
917
918
		// Is there an active search being performed? Used by fe-views.js
919
		$search_class .= GravityView_frontend::getInstance()->isSearch() ? ' gv-is-search' : '';
920
921
		return gravityview_sanitize_html_class( $search_class );
922
	}
923
924
925
	/**
926
	 * Calculate the search form action
927
	 * @since 1.6
928
	 *
929
	 * @return string
930
	 */
931
	public static function get_search_form_action() {
932
		$gravityview_view = GravityView_View::getInstance();
933
934
		$post_id = $gravityview_view->getPostId() ? $gravityview_view->getPostId() : $gravityview_view->getViewId();
935
936
		$url = add_query_arg( array(), get_permalink( $post_id ) );
937
938
		return esc_url( $url );
939
	}
940
941
	/**
942
	 * Get the label for a search form field
943
	 * @param  array $field      Field setting as sent by the GV configuration - has `field`, `input` (input type), and `label` keys
944
	 * @param  array $form_field Form field data, as fetched by `gravityview_get_field()`
945
	 * @return string             Label for the search form
946
	 */
947
	private static function get_field_label( $field, $form_field = array() ) {
948
949
		$label = rgget( 'label', $field );
950
951
		if( '' === $label ) {
952
953
			$label = isset( $form_field['label'] ) ? $form_field['label'] : '';
954
955
			switch( $field['field'] ) {
956
				case 'search_all':
957
					$label = __( 'Search Entries:', 'gravityview' );
958
					break;
959
				case 'entry_date':
960
					$label = __( 'Filter by date:', 'gravityview' );
961
					break;
962
				case 'entry_id':
963
					$label = __( 'Entry ID:', 'gravityview' );
964
					break;
965
				default:
966
					// If this is a field input, not a field
967
					if ( strpos( $field['field'], '.' ) > 0 && ! empty( $form_field['inputs'] ) ) {
968
969
						// Get the label for the field in question, which returns an array
970
						$items = wp_list_filter( $form_field['inputs'], array( 'id' => $field['field'] ) );
971
972
						// Get the item with the `label` key
973
						$values = wp_list_pluck( $items, 'label' );
974
975
						// There will only one item in the array, but this is easier
976
						foreach ( $values as $value ) {
977
							$label = $value;
978
							break;
979
						}
980
					}
981
			}
982
		}
983
984
		/**
985
		 * @filter `gravityview_search_field_label` Modify the label for a search field. Supports returning HTML
986
		 * @since 1.17.3 Added $field parameter
987
		 * @param[in,out] string $label Existing label text, sanitized.
988
		 * @param[in] array $form_field Gravity Forms field array, as returned by `GFFormsModel::get_field()`
989
		 * @param[in] array $field Field setting as sent by the GV configuration - has `field`, `input` (input type), and `label` keys
990
		 */
991
		$label = apply_filters( 'gravityview_search_field_label', esc_attr( $label ), $form_field, $field );
992
993
		return $label;
994
	}
995
996
	/**
997
	 * Prepare search fields to frontend render with other details (label, field type, searched values)
998
	 *
999
	 * @param array $field
1000
	 * @return array
1001
	 */
1002
	private function get_search_filter_details( $field ) {
1003
1004
		$gravityview_view = GravityView_View::getInstance();
1005
1006
		$form = $gravityview_view->getForm();
1007
1008
		// for advanced field ids (eg, first name / last name )
1009
		$name = 'filter_' . str_replace( '.', '_', $field['field'] );
1010
1011
		// get searched value from $_GET/$_POST (string or array)
1012
		$value = $this->rgget_or_rgpost( $name );
1013
1014
		// get form field details
1015
		$form_field = gravityview_get_field( $form, $field['field'] );
1016
1017
		$filter = array(
1018
			'key' => $field['field'],
1019
			'name' => $name,
1020
			'label' => self::get_field_label( $field, $form_field ),
1021
			'input' => $field['input'],
1022
			'value' => $value,
1023
			'type' => $form_field['type'],
1024
		);
1025
1026
		// collect choices
1027
		if ( 'post_category' === $form_field['type'] && ! empty( $form_field['displayAllCategories'] ) && empty( $form_field['choices'] ) ) {
1028
			$filter['choices'] = gravityview_get_terms_choices();
1029
		} elseif ( ! empty( $form_field['choices'] ) ) {
1030
			$filter['choices'] = $form_field['choices'];
1031
		}
1032
1033
		if ( 'date_range' === $field['input'] && empty( $value ) ) {
1034
			$filter['value'] = array( 'start' => '', 'end' => '' );
1035
		}
1036
1037
		return $filter;
1038
1039
	}
1040
1041
	/**
1042
	 * Calculate the search choices for the users
1043
	 *
1044
	 * @since 1.8
1045
	 *
1046
	 * @return array Array of user choices (value = ID, text = display name)
1047
	 */
1048
	private static function get_created_by_choices() {
1049
1050
		/**
1051
		 * filter gravityview/get_users/search_widget
1052
		 * @see \GVCommon::get_users
1053
		 */
1054
		$users = GVCommon::get_users( 'search_widget', array( 'fields' => array( 'ID', 'display_name' ) ) );
1055
1056
		$choices = array();
1057
		foreach ( $users as $user ) {
1058
			$choices[] = array(
1059
				'value' => $user->ID,
1060
				'text' => $user->display_name,
1061
			);
1062
		}
1063
1064
		return $choices;
1065
	}
1066
1067
1068
	/**
1069
	 * Output the Clear Search Results button
1070
	 * @since 1.5.4
1071
	 */
1072
	public static function the_clear_search_button() {
1073
		$gravityview_view = GravityView_View::getInstance();
1074
1075
		if ( $gravityview_view->search_clear ) {
1076
1077
			$url = strtok( add_query_arg( array() ), '?' );
1078
1079
			echo gravityview_get_link( $url, esc_html__( 'Clear', 'gravityview' ), 'class=button gv-search-clear' );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'gravityview_get_link'
Loading history...
1080
1081
		}
1082
	}
1083
1084
	/**
1085
	 * Based on the search method, fetch the value for a specific key
1086
	 *
1087
	 * @since 1.16.4
1088
	 *
1089
	 * @param string $name Name of the request key to fetch the value for
1090
	 *
1091
	 * @return mixed|string Value of request at $name key. Empty string if empty.
1092
	 */
1093
	private function rgget_or_rgpost( $name ) {
1094
		$value = 'get' === $this->search_method ? rgget( $name ) : rgpost( $name );
1095
1096
		$value = stripslashes_deep( $value );
1097
1098
		$value = gv_map_deep( $value, 'rawurldecode' );
1099
1100
		$value = gv_map_deep( $value, '_wp_specialchars' );
1101
1102
		return $value;
1103
	}
1104
1105
1106
	/**
1107
	 * Require the datepicker script for the frontend GV script
1108
	 * @param array $js_dependencies Array of existing required scripts for the fe-views.js script
1109
	 * @return array Array required scripts, with `jquery-ui-datepicker` added
1110
	 */
1111
	public function add_datepicker_js_dependency( $js_dependencies ) {
1112
1113
		$js_dependencies[] = 'jquery-ui-datepicker';
1114
1115
		return $js_dependencies;
1116
	}
1117
1118
	/**
1119
	 * Modify the array passed to wp_localize_script()
1120
	 *
1121
	 * @param array $js_localization The data padded to the Javascript file
0 ignored issues
show
Bug introduced by
There is no parameter named $js_localization. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1122
	 * @param array $view_data View data array with View settings
1123
	 *
1124
	 * @return array
1125
	 */
1126
	public function add_datepicker_localization( $localizations = array(), $view_data = array() ) {
1127
		global $wp_locale;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1128
1129
		/**
1130
		 * @filter `gravityview_datepicker_settings` Modify the datepicker settings
1131
		 * @see http://api.jqueryui.com/datepicker/ Learn what settings are available
1132
		 * @see http://www.renegadetechconsulting.com/tutorials/jquery-datepicker-and-wordpress-i18n Thanks for the helpful information on $wp_locale
1133
		 * @param array $js_localization The data padded to the Javascript file
1134
		 * @param array $view_data View data array with View settings
1135
		 */
1136
		$datepicker_settings = apply_filters( 'gravityview_datepicker_settings', array(
1137
			'yearRange' => '-5:+5',
1138
			'changeMonth' => true,
1139
			'changeYear' => true,
1140
			'closeText' => esc_attr_x( 'Close', 'Close calendar', 'gravityview' ),
1141
			'prevText' => esc_attr_x( 'Prev', 'Previous month in calendar', 'gravityview' ),
1142
			'nextText' => esc_attr_x( 'Next', 'Next month in calendar', 'gravityview' ),
1143
			'currentText' => esc_attr_x( 'Today', 'Today in calendar', 'gravityview' ),
1144
			'weekHeader' => esc_attr_x( 'Week', 'Week in calendar', 'gravityview' ),
1145
			'monthStatus'       => __( 'Show a different month', 'gravityview' ),
1146
			'monthNames'        => array_values( $wp_locale->month ),
1147
			'monthNamesShort'   => array_values( $wp_locale->month_abbrev ),
1148
			'dayNames'          => array_values( $wp_locale->weekday ),
1149
			'dayNamesShort'     => array_values( $wp_locale->weekday_abbrev ),
1150
			'dayNamesMin'       => array_values( $wp_locale->weekday_initial ),
1151
			// get the start of week from WP general setting
1152
			'firstDay'          => get_option( 'start_of_week' ),
1153
			// is Right to left language? default is false
1154
			'isRTL'             => is_rtl(),
1155
		), $view_data );
1156
1157
		$localizations['datepicker'] = $datepicker_settings;
1158
1159
		return $localizations;
1160
1161
	}
1162
1163
	/**
1164
	 * Register search widget scripts, including Flexibility
1165
	 *
1166
	 * @see https://github.com/10up/flexibility
1167
	 *
1168
	 * @since 1.17
1169
	 *
1170
	 * @return void
1171
	 */
1172
	public function register_scripts() {
1173
1174
		wp_register_script( 'gv-flexibility', plugins_url( 'assets/lib/flexibility/dist/flexibility.js', GRAVITYVIEW_FILE ), array(), GravityView_Plugin::version, true );
1175
1176
	}
1177
1178
	/**
1179
	 * If the current visitor is running IE 8 or 9, enqueue Flexibility
1180
	 *
1181
	 * @since 1.17
1182
	 *
1183
	 * @return void
1184
	 */
1185
	private function maybe_enqueue_flexibility() {
1186
		if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && preg_match( '/MSIE [8-9]/', $_SERVER['HTTP_USER_AGENT'] ) ) {
0 ignored issues
show
introduced by
Due to using Batcache, server side based client related logic will not work, use JS instead.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
1187
			wp_enqueue_script( 'gv-flexibility' );
1188
		}
1189
	}
1190
1191
	/**
1192
	 * Enqueue the datepicker script
1193
	 *
1194
	 * It sets the $gravityview->datepicker_class parameter
1195
	 *
1196
	 * @todo Use own datepicker javascript instead of GF datepicker.js - that way, we can localize the settings and not require the changeMonth and changeYear pickers.
1197
	 * @return void
1198
	 */
1199
	public function enqueue_datepicker() {
1200
		$gravityview_view = GravityView_View::getInstance();
1201
1202
		wp_enqueue_script( 'jquery-ui-datepicker' );
1203
1204
		add_filter( 'gravityview_js_dependencies', array( $this, 'add_datepicker_js_dependency' ) );
1205
		add_filter( 'gravityview_js_localization', array( $this, 'add_datepicker_localization' ), 10, 2 );
1206
1207
		$scheme = is_ssl() ? 'https://' : 'http://';
1208
		wp_enqueue_style( 'jquery-ui-datepicker', $scheme.'ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/themes/smoothness/jquery-ui.css' );
1209
1210
		/**
1211
		 * @filter `gravityview_search_datepicker_class`
1212
		 * Modify the CSS class for the datepicker, used by the CSS class is used by Gravity Forms' javascript to determine the format for the date picker. The `gv-datepicker` class is required by the GravityView datepicker javascript.
1213
		 * @param string $css_class CSS class to use. Default: `gv-datepicker datepicker mdy` \n
1214
		 * Options are:
1215
		 * - `mdy` (mm/dd/yyyy)
1216
		 * - `dmy` (dd/mm/yyyy)
1217
		 * - `dmy_dash` (dd-mm-yyyy)
1218
		 * - `dmy_dot` (dd.mm.yyyy)
1219
		 * - `ymp_slash` (yyyy/mm/dd)
1220
		 * - `ymd_dash` (yyyy-mm-dd)
1221
		 * - `ymp_dot` (yyyy.mm.dd)
1222
		 */
1223
		$datepicker_class = apply_filters( 'gravityview_search_datepicker_class', 'gv-datepicker datepicker mdy' );
1224
1225
		$gravityview_view->datepicker_class = $datepicker_class;
1226
1227
	}
1228
1229
1230
} // end class
1231
1232
new GravityView_Widget_Search;