Completed
Push — master ( cd320e...b9ab02 )
by Zack
15s
created

GravityView_frontend   F

Complexity

Total Complexity 172

Size/Duplication

Total Lines 1444
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 12

Test Coverage

Coverage 51.67%

Importance

Changes 0
Metric Value
dl 0
loc 1444
ccs 232
cts 449
cp 0.5167
rs 3.4838
c 0
b 0
f 0
wmc 172
lcom 3
cbo 12

43 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 1 1
A initialize() 0 16 1
A getInstance() 0 9 2
A getSingleEntry() 0 3 1
A isPostHasShortcode() 0 3 1
A isGravityviewPostType() 0 3 1
A getGvOutputData() 0 3 1
A setGvOutputData() 0 3 1
A isSearch() 0 3 1
A setIsSearch() 0 3 1
A setSingleEntry() 0 5 1
A getEntry() 0 3 1
A setEntry() 0 8 2
A getPostId() 0 3 1
A setPostId() 0 3 1
A setPostHasShortcode() 0 3 1
A setIsGravityviewPostType() 0 3 1
B set_context_view_id() 0 21 6
A get_context_view_id() 0 3 1
C parse_query_fix_frontpage() 0 54 14
B parse_content() 0 26 6
A set_entry_data() 0 5 1
C is_searching() 0 42 8
A insert_view_in_content() 0 4 1
A comments_open() 0 16 2
B context_not_configured_warning() 0 38 6
B render_view() 0 25 5
C process_search_dates() 0 66 13
B process_search_only_approved() 0 22 4
B is_entry_approved() 0 17 6
B get_search_criteria() 0 58 7
B get_view_entries() 0 37 1
A get_view_entries_parameters() 0 55 4
B get_search_criteria_paging() 0 32 5
C updateViewSorting() 0 47 8
C single_entry_title() 0 61 11
D _override_sorting_id_by_field_type() 0 88 15
A is_single_entry() 0 20 2
C add_scripts_and_styles() 0 88 11
A enqueue_default_style() 0 17 3
A add_style() 0 12 4
B add_columns_sort_links() 0 43 6
B is_field_sortable() 0 30 3

How to fix   Complexity   

Complex Class

Complex classes like GravityView_frontend often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use GravityView_frontend, and based on these observations, apply Extract Interface, too.

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 15 and the first side effect is on line 1460.

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
 * GravityView Frontend functions
4
 *
5
 * @package   GravityView
6
 * @license   GPL2+
7
 * @author    Katz Web Services, Inc.
8
 * @link      http://gravityview.co
9
 * @copyright Copyright 2014, Katz Web Services, Inc.
10
 *
11
 * @since 1.0.0
12
 */
13
14
15
class GravityView_frontend {
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
16
17
	/**
18
	 * Regex strings that are used to determine whether the current request is a GravityView search or not.
19
	 * @see GravityView_frontend::is_searching()
20
	 * @since 1.7.4.1
21
	 * @var array
22
	 */
23
	private static $search_parameters = array( 'gv_search', 'gv_start', 'gv_end', 'gv_id', 'gv_by', 'filter_*' );
24
25
	/**
26
	 * Is the currently viewed post a `gravityview` post type?
27
	 * @var boolean
28
	 */
29
	var $is_gravityview_post_type = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $is_gravityview_post_type.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
30
31
	/**
32
	 * Does the current post have a `[gravityview]` shortcode?
33
	 * @var boolean
34
	 */
35
	var $post_has_shortcode = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $post_has_shortcode.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
36
37
	/**
38
	 * The Post ID of the currently viewed post. Not necessarily GV
39
	 * @var int
40
	 */
41
	var $post_id = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $post_id.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
42
43
	/**
44
	 * Are we currently viewing a single entry?
45
	 * If so, the int value of the entry ID. Otherwise, false.
46
	 * @var int|boolean
47
	 */
48
	var $single_entry = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $single_entry.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
49
50
	/**
51
	 * If we are viewing a single entry, the entry data
52
	 * @var array|false
53
	 */
54
	var $entry = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $entry.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
55
56
	/**
57
	 * When displaying the single entry we should always know to which View it belongs (the context is everything!)
58
	 * @var null
59
	 */
60
	var $context_view_id = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $context_view_id.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
61
62
	/**
63
	 * The View is showing search results
64
	 * @since 1.5.4
65
	 * @var boolean
66
	 */
67
	var $is_search = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $is_search.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
68
69
	/**
70
	 * The view data parsed from the $post
71
	 *
72
	 * @see  GravityView_View_Data::__construct()
73
	 * @var GravityView_View_Data
74
	 */
75
	var $gv_output_data = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $gv_output_data.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
76
77
	/**
78
	 * @var GravityView_frontend
79
	 */
80
	static $instance;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $instance.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
81
82
	/**
83
	 * Class constructor, enforce Singleton pattern
84
	 */
85
	private function __construct() {}
86
87 23
	private function initialize() {
88 23
		add_action( 'wp', array( $this, 'parse_content'), 11 );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
89 23
		add_filter( 'parse_query', array( $this, 'parse_query_fix_frontpage' ), 10 );
90 23
		add_action( 'template_redirect', array( $this, 'set_entry_data'), 1 );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
91
92
		// Enqueue scripts and styles after GravityView_Template::register_styles()
93 23
		add_action( 'wp_enqueue_scripts', array( $this, 'add_scripts_and_styles' ), 20 );
94
95
		// Enqueue and print styles in the footer. Added 1 priorty so stuff gets printed at 10 priority.
96 23
		add_action( 'wp_print_footer_scripts', array( $this, 'add_scripts_and_styles' ), 1 );
97
98 23
		add_filter( 'the_title', array( $this, 'single_entry_title' ), 1, 2 );
99 23
		add_filter( 'comments_open', array( $this, 'comments_open' ), 10, 2 );
100
101 23
		add_action( 'gravityview_after', array( $this, 'context_not_configured_warning' ) );
102 23
	}
103
104
	/**
105
	 * Get the one true instantiated self
106
	 * @return GravityView_frontend
107
	 */
108 30
	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...
109
110 30
		if ( empty( self::$instance ) ) {
111 23
			self::$instance = new self;
112 23
			self::$instance->initialize();
113
		}
114
115 30
		return self::$instance;
116
	}
117
118
	/**
119
	 * @return GravityView_View_Data
120
	 */
121 22
	public function getGvOutputData() {
0 ignored issues
show
Coding Style introduced by
The function name getGvOutputData is in camel caps, but expected get_gv_output_data instead as per the coding standard.
Loading history...
122 22
		return $this->gv_output_data;
123
	}
124
125
	/**
126
	 * @param GravityView_View_Data $gv_output_data
127
	 */
128 22
	public function setGvOutputData( $gv_output_data ) {
0 ignored issues
show
Coding Style introduced by
The function name setGvOutputData is in camel caps, but expected set_gv_output_data instead as per the coding standard.
Loading history...
129 22
		$this->gv_output_data = $gv_output_data;
130 22
	}
131
132
	/**
133
	 * @return boolean
134
	 */
135 22
	public function isSearch() {
0 ignored issues
show
Coding Style introduced by
The function name isSearch is in camel caps, but expected is_search instead as per the coding standard.
Loading history...
136 22
		return $this->is_search;
137
	}
138
139
	/**
140
	 * @param boolean $is_search
141
	 */
142 22
	public function setIsSearch( $is_search ) {
0 ignored issues
show
Coding Style introduced by
The function name setIsSearch is in camel caps, but expected set_is_search instead as per the coding standard.
Loading history...
143 22
		$this->is_search = $is_search;
144 22
	}
145
146
	/**
147
	 * @return bool|int
148
	 */
149 30
	public function getSingleEntry() {
0 ignored issues
show
Coding Style introduced by
The function name getSingleEntry is in camel caps, but expected get_single_entry instead as per the coding standard.
Loading history...
150 30
		return $this->single_entry;
151
	}
152
153
	/**
154
	 * Sets the single entry ID and also the entry
155
	 * @param bool|int|string $single_entry
156
	 */
157 22
	public function setSingleEntry( $single_entry ) {
0 ignored issues
show
Coding Style introduced by
The function name setSingleEntry is in camel caps, but expected set_single_entry instead as per the coding standard.
Loading history...
158
159 22
		$this->single_entry = $single_entry;
160
161 22
	}
162
163
	/**
164
	 * @return array
165
	 */
166 23
	public function getEntry() {
0 ignored issues
show
Coding Style introduced by
The function name getEntry is in camel caps, but expected get_entry instead as per the coding standard.
Loading history...
167 23
		return $this->entry;
168
	}
169
170
	/**
171
	 * Set the current entry
172
	 * @param array|int $entry Entry array or entry slug or ID
173
	 */
174 22
	public function setEntry( $entry ) {
0 ignored issues
show
Coding Style introduced by
The function name setEntry is in camel caps, but expected set_entry instead as per the coding standard.
Loading history...
175
176 22
		if ( ! is_array( $entry ) ) {
177 22
			$entry = GVCommon::get_entry( $entry );
178
		}
179
180 22
		$this->entry = $entry;
181 22
	}
182
183
	/**
184
	 * @return int
185
	 */
186 22
	public function getPostId() {
0 ignored issues
show
Coding Style introduced by
The function name getPostId is in camel caps, but expected get_post_id instead as per the coding standard.
Loading history...
187 22
		return $this->post_id;
188
	}
189
190
	/**
191
	 * @param int $post_id
192
	 */
193 22
	public function setPostId( $post_id ) {
0 ignored issues
show
Coding Style introduced by
The function name setPostId is in camel caps, but expected set_post_id instead as per the coding standard.
Loading history...
194 22
		$this->post_id = $post_id;
195 22
	}
196
197
	/**
198
	 * @return boolean
199
	 */
200 23
	public function isPostHasShortcode() {
0 ignored issues
show
Coding Style introduced by
The function name isPostHasShortcode is in camel caps, but expected is_post_has_shortcode instead as per the coding standard.
Loading history...
201 23
		return $this->post_has_shortcode;
202
	}
203
204
	/**
205
	 * @param boolean $post_has_shortcode
206
	 */
207 22
	public function setPostHasShortcode( $post_has_shortcode ) {
0 ignored issues
show
Coding Style introduced by
The function name setPostHasShortcode is in camel caps, but expected set_post_has_shortcode instead as per the coding standard.
Loading history...
208 22
		$this->post_has_shortcode = $post_has_shortcode;
209 22
	}
210
211
	/**
212
	 * @return boolean
213
	 */
214 23
	public function isGravityviewPostType() {
0 ignored issues
show
Coding Style introduced by
The function name isGravityviewPostType is in camel caps, but expected is_gravityview_post_type instead as per the coding standard.
Loading history...
215 23
		return $this->is_gravityview_post_type;
216
	}
217
218
	/**
219
	 * @param boolean $is_gravityview_post_type
220
	 */
221 22
	public function setIsGravityviewPostType( $is_gravityview_post_type ) {
0 ignored issues
show
Coding Style introduced by
The function name setIsGravityviewPostType is in camel caps, but expected set_is_gravityview_post_type instead as per the coding standard.
Loading history...
222 22
		$this->is_gravityview_post_type = $is_gravityview_post_type;
223 22
	}
224
225
	/**
226
	 * Set the context view ID used when page contains multiple embedded views or displaying the single entry view
227
	 *
228
	 *
229
	 *
230
	 * @param null $view_id
231
	 */
232 1
	public function set_context_view_id( $view_id = null ) {
233 1
		$multiple_views = $this->getGvOutputData() && $this->getGvOutputData()->has_multiple_views();
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_View_Data::has_multiple_views() has been deprecated.

This method has been deprecated.

Loading history...
234
235 1
		if ( ! empty( $view_id ) ) {
236
237 1
			$this->context_view_id = $view_id;
238
239 1
		} elseif ( isset( $_GET['gvid'] ) && $multiple_views ) {
240
			/**
241
			 * used on a has_multiple_views context
242
			 * @see GravityView_API::entry_link
243
			 */
244
			$this->context_view_id = $_GET['gvid'];
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...
245
246 1
		} elseif ( ! $multiple_views ) {
247 1
			$array_keys = array_keys( $this->getGvOutputData()->get_views() );
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_View_Data::get_views() has been deprecated.

This method has been deprecated.

Loading history...
248 1
			$this->context_view_id = array_pop( $array_keys );
249 1
			unset( $array_keys );
250
		}
251
252 1
	}
253
254
	/**
255
	 * Returns the the view_id context when page contains multiple embedded views or displaying single entry view
256
	 *
257
	 * @since 1.5.4
258
	 *
259
	 * @return string
260
	 */
261 26
	public function get_context_view_id() {
262 26
		return $this->context_view_id;
263
	}
264
265
	/**
266
	 * Allow GravityView entry endpoints on the front page of a site
267
	 *
268
	 * @link  https://core.trac.wordpress.org/ticket/23867 Fixes this core issue
269
	 * @link https://wordpress.org/plugins/cpt-on-front-page/ Code is based on this
270
	 *
271
	 * @since 1.17.3
272
	 *
273
	 * @param WP_Query &$query (passed by reference)
274
	 *
275
	 * @return void
276
	 */
277 71
	public function parse_query_fix_frontpage( &$query ) {
278 71
		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...
279
280 71
		$is_front_page = ( $query->is_home || $query->is_page );
281 71
		$show_on_front = ( 'page' === get_option('show_on_front') );
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...
282 71
		$front_page_id = get_option('page_on_front');
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...
283
284 71
		if (  $is_front_page && $show_on_front && $front_page_id ) {
285
286
			// Force to be an array, potentially a query string ( entry=16 )
287
			$_query = wp_parse_args( $query->query );
288
289
			// pagename can be set and empty depending on matched rewrite rules. Ignore an empty pagename.
290
			if ( isset( $_query['pagename'] ) && '' === $_query['pagename'] ) {
291
				unset( $_query['pagename'] );
292
			}
293
294
			// this is where will break from core wordpress
295
			/** @internal Don't use this filter; it will be unnecessary soon - it's just a patch for specific use case */
296
			$ignore = apply_filters( 'gravityview/internal/ignored_endpoints', array( 'preview', 'page', 'paged', 'cpage' ), $query );
297
			$endpoints = rgobj( $wp_rewrite, 'endpoints' );
298
			foreach ( (array) $endpoints as $endpoint ) {
299
				$ignore[] = $endpoint[1];
300
			}
301
			unset( $endpoints );
302
303
			// Modify the query if:
304
			// - We're on the "Page on front" page (which we are), and:
305
			// - The query is empty OR
306
			// - The query includes keys that are associated with registered endpoints. `entry`, for example.
307
			if ( empty( $_query ) || ! array_diff( array_keys( $_query ), $ignore ) ) {
308
309
				$qv =& $query->query_vars;
310
311
				// Prevent redirect when on the single entry endpoint
312
				if( self::is_single_entry() ) {
313
					add_filter( 'redirect_canonical', '__return_false' );
314
				}
315
316
				$query->is_page = true;
317
				$query->is_home = false;
318
				$qv['page_id']  = $front_page_id;
319
320
				// Correct <!--nextpage--> for page_on_front
321
				if ( ! empty( $qv['paged'] ) ) {
322
					$qv['page'] = $qv['paged'];
323
					unset( $qv['paged'] );
324
				}
325
			}
326
327
			// reset the is_singular flag after our updated code above
328
			$query->is_singular = $query->is_single || $query->is_page || $query->is_attachment;
329
		}
330 71
	}
331
332
	/**
333
	 * Read the $post and process the View data inside
334
	 * @param  array  $wp Passed in the `wp` hook. Not used.
335
	 * @return void
336
	 */
337
	public function parse_content( $wp = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $wp 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...
338
		global $post;
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...
339
340
		// If in admin and NOT AJAX request, get outta here.
341
		if ( gravityview()->request->is_admin() ) {
342
			return;
343
		}
344
345
		// Calculate requested Views
346
		$this->setGvOutputData( GravityView_View_Data::getInstance( $post ) );
347
348
		// !important: we need to run this before getting single entry (to kick the advanced filter)
349
		$this->set_context_view_id();
350
351
		$this->setIsGravityviewPostType( get_post_type( $post ) === 'gravityview' );
352
353
		$post_id = $this->getPostId() ? $this->getPostId() : (isset( $post ) ? $post->ID : null );
354
		$this->setPostId( $post_id );
355
		$post_has_shortcode = ! empty( $post->post_content ) ? gravityview_has_shortcode_r( $post->post_content, 'gravityview' ) : false;
356
		$this->setPostHasShortcode( $this->isGravityviewPostType() ? null : ! empty( $post_has_shortcode ) );
357
358
		// check if the View is showing search results (only for multiple entries View)
359
		$this->setIsSearch( $this->is_searching() );
360
361
		unset( $entry, $post_id, $post_has_shortcode );
362
	}
363
364
	/**
365
	 * Set the entry
366
	 */
367
	function set_entry_data() {
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...
368
		$entry_id = self::is_single_entry();
369
		$this->setSingleEntry( $entry_id );
370
		$this->setEntry( $entry_id );
371
	}
372
373
	/**
374
	 * Checks if the current View is presenting search results
375
	 *
376
	 * @since 1.5.4
377
	 *
378
	 * @return boolean True: Yes, it's a search; False: No, not a search.
379
	 */
380
	function is_searching() {
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...
381
382
		// It's a single entry, not search
383
		if ( $this->getSingleEntry() ) {
384
			return false;
385
		}
386
387
		$search_method = GravityView_Widget_Search::getInstance()->get_search_method();
388
389
		if( 'post' === $search_method ) {
390
			$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...
391
		} else {
392
			$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...
393
		}
394
395
		// No $_GET parameters
396
		if ( empty( $get ) || ! is_array( $get ) ) {
397
			return false;
398
		}
399
400
		// Remove empty values
401
		$get = array_filter( $get );
402
403
		// If the $_GET parameters are empty, it's no search.
404
		if ( empty( $get ) ) {
405
			return false;
406
		}
407
408
		$search_keys = array_keys( $get );
409
410
		$search_match = implode( '|', self::$search_parameters );
411
412
		foreach ( $search_keys as $search_key ) {
413
414
			// Analyze the search key $_GET parameter and see if it matches known GV args
415
			if ( preg_match( '/(' . $search_match . ')/i', $search_key ) ) {
416
				return true;
417
			}
418
		}
419
420
		return false;
421
	}
422
423
	/**
424
	 * Filter the title for the single entry view
425
	 *
426
	 *
427
	 * @param  string $title   current title
428
	 * @param  int $passed_post_id Post ID
429
	 * @return string          (modified) title
430
	 */
431 1
	public function single_entry_title( $title, $passed_post_id = null ) {
432 1
		global $post;
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...
433
434
		// If this is the directory view, return.
435 1
		if ( ! $this->getSingleEntry() ) {
436 1
			return $title;
437
		}
438
439 1
		$entry = $this->getEntry();
440
441
		/**
442
		 * @filter `gravityview/single/title/out_loop` Apply the Single Entry Title filter outside the WordPress loop?
443
		 * @param boolean $in_the_loop Whether to apply the filter to the menu title and the meta tag <title> - outside the loop
444
		 * @param array $entry Current entry
445
		 */
446 1
		$apply_outside_loop = apply_filters( 'gravityview/single/title/out_loop' , in_the_loop(), $entry );
447
448 1
		if ( ! $apply_outside_loop ) {
449 1
			return $title;
450
		}
451
452
		// User reported WooCommerce doesn't pass two args.
453
		if ( empty( $passed_post_id ) )  {
454
			return $title;
455
		}
456
457
		// Don't modify the title for anything other than the current view/post.
458
		// This is true for embedded shortcodes and Views.
459
		if ( is_object( $post ) && (int) $post->ID !== (int) $passed_post_id ) {
460
			return $title;
461
		}
462
463
		$context_view_id = $this->get_context_view_id();
464
465
		$multiple_views = $this->getGvOutputData()->has_multiple_views();
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_View_Data::has_multiple_views() has been deprecated.

This method has been deprecated.

Loading history...
466
467
		if ( $multiple_views && ! empty( $context_view_id ) ) {
468
			$view_meta = $this->getGvOutputData()->get_view( $context_view_id );
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_View_Data::get_view() has been deprecated.

This method has been deprecated.

Loading history...
469
		} else {
470
			foreach ( $this->getGvOutputData()->get_views() as $view_id => $view_data ) {
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_View_Data::get_views() has been deprecated.

This method has been deprecated.

Loading history...
471
				if ( intval( $view_data['form_id'] ) === intval( $entry['form_id'] ) ) {
472
					$view_meta = $view_data;
473
					break;
474
				}
475
			}
476
		}
477
478
		/** Deprecated stuff in the future. See the branch above. */
479
		if ( ! empty( $view_meta['atts']['single_title'] ) ) {
480
481
			$title = $view_meta['atts']['single_title'];
482
483
			// We are allowing HTML in the fields, so no escaping the output
484
			$title = GravityView_API::replace_variables( $title, $view_meta['form'], $entry );
485
486
			$title = do_shortcode( $title );
487
		}
488
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
489
490
		return $title;
491
	}
492
493
494
	/**
495
	 * In case View post is called directly, insert the view in the post content
496
	 *
497
	 * @deprecated Use \GV\View::content() instead.
498
	 *
499
	 * @access public
500
	 * @static
501
	 * @param mixed $content
502
	 * @return string Add the View output into View CPT content
503
	 */
504 2
	public function insert_view_in_content( $content ) {
505 2
		gravityview()->log->notice( '\GravityView_frontend::insert_view_in_content is deprecated. Use \GV\View::content()' );
506 2
		return \GV\View::content( $content );
507
	}
508
509
	/**
510
	 * Disable comments on GravityView post types
511
	 * @param  boolean $open    existing status
512
	 * @param  int $post_id Post ID
513
	 * @return boolean
514
	 */
515
	public function comments_open( $open, $post_id ) {
516
517
		if ( $this->isGravityviewPostType() ) {
518
			$open = false;
519
		}
520
521
		/**
522
		 * @filter `gravityview/comments_open` Whether to set comments to open or closed.
523
		 * @since  1.5.4
524
		 * @param  boolean $open Open or closed status
525
		 * @param  int $post_id Post ID to set comment status for
526
		 */
527
		$open = apply_filters( 'gravityview/comments_open', $open, $post_id );
528
529
		return $open;
530
	}
531
532
	/**
533
	 * Display a warning when a View has not been configured
534
	 *
535
	 * @since 1.19.2
536
	 *
537
	 * @param int $view_id The ID of the View currently being displayed
538
	 *
539
	 * @return void
540
	 */
541 2
	public function context_not_configured_warning( $view_id = 0 ) {
542
543 2
		if ( ! class_exists( 'GravityView_View' ) ) {
544
			return;
545
		}
546
547 2
		$fields = GravityView_View::getInstance()->getContextFields();
548
549 2
		if ( ! empty( $fields ) ) {
550 2
			return;
551
		}
552
553
		$context = GravityView_View::getInstance()->getContext();
554
555
		switch( $context ) {
556
			case 'directory':
557
				$tab = __( 'Multiple Entries', 'gravityview' );
558
				break;
559
			case 'edit':
560
				$tab = __( 'Edit Entry', 'gravityview' );
561
				break;
562
			case 'single':
563
			default:
564
				$tab = __( 'Single Entry', 'gravityview' );
565
				break;
566
		}
567
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
568
569
		$title = sprintf( esc_html_x('The %s layout has not been configured.', 'Displayed when a View is not configured. %s is replaced by the tab label', 'gravityview' ), $tab );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
570
		$edit_link = admin_url( sprintf( 'post.php?post=%d&action=edit#%s-view', $view_id, $context ) );
571
		$action_text = sprintf( esc_html__('Add fields to %s', 'gravityview' ), $tab );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
572
		$message = esc_html__( 'You can only see this message because you are able to edit this View.', 'gravityview' );
573
574
		$image =  sprintf( '<img alt="%s" src="%s" style="margin-top: 10px;" />', $tab, esc_url(plugins_url( sprintf( 'assets/images/tab-%s.png', $context ), GRAVITYVIEW_FILE ) ) );
0 ignored issues
show
introduced by
Expected 1 space after "="; 2 found
Loading history...
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
575
		$output = sprintf( '<h3>%s <strong><a href="%s">%s</a></strong></h3><p>%s</p>', $title, esc_url( $edit_link ), $action_text, $message );
576
577
		echo GVCommon::generate_notice( $output . $image, 'gv-error error', 'edit_gravityview', $view_id );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'GVCommon'
Loading history...
578
	}
579
580
581
	/**
582
	 * Core function to render a View based on a set of arguments
583
	 *
584
	 * @access public
585
	 * @static
586
	 * @param array $passed_args {
587
	 *
588
	 *      Settings for rendering the View
589
	 *
590
	 *      @type int $id View id
591
	 *      @type int $page_size Number of entries to show per page
592
	 *      @type string $sort_field Form field id to sort
593
	 *      @type string $sort_direction Sorting direction ('ASC', 'DESC', or 'RAND')
594
	 *      @type string $start_date - Ymd
595
	 *      @type string $end_date - Ymd
596
	 *      @type string $class - assign a html class to the view
597
	 *      @type string $offset (optional) - This is the start point in the current data set (0 index based).
598
	 * }
599
	 *
600
	 * @deprecated Use \GV\View_Renderer
601
	 *
602
	 * @return string|null HTML output of a View, NULL if View isn't found
603
	 */
604 1
	public function render_view( $passed_args ) {
605 1
		gravityview()->log->notice( '\GravityView_frontend::render_view is deprecated. Use \GV\View_Renderer etc.' );
606
607
		/**
608
		 * We can use a shortcode here, since it's pretty much the same.
609
		 *
610
		 * But we do need to check embed permissions, since shortcodes don't do this.
611
		 */
612
613 1
		if ( ! $view = gravityview()->views->get( $passed_args ) ) {
0 ignored issues
show
Documentation introduced by
The property views does not exist on object<GV\Core>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
614
			return null;
615
		}
616
617 1
		$view->settings->update( $passed_args );
618
619 1
		$direct_access = apply_filters( 'gravityview_direct_access', true, $view->ID );
620 1
		$embed_only = $view->settings->get( 'embed_only' );
621
622 1
		if( ! $direct_access || ( $embed_only && ! GVCommon::has_cap( 'read_private_gravityviews' ) ) ) {
623 1
			return __( 'You are not allowed to view this content.', 'gravityview' );
624
		}
625
626 1
		$shortcode = new \GV\Shortcodes\gravityview();
627 1
		return $shortcode->callback( $passed_args );
628
	}
629
630
	/**
631
	 * Process the start and end dates for a view - overrides values defined in shortcode (if needed)
632
	 *
633
	 * The `start_date` and `end_date` keys need to be in a format processable by GFFormsModel::get_date_range_where(),
634
	 * which uses \DateTime() format.
635
	 *
636
	 * You can set the `start_date` or `end_date` to any value allowed by {@link http://www.php.net//manual/en/function.strtotime.php strtotime()},
637
	 * including strings like "now" or "-1 year" or "-3 days".
638
	 *
639
	 * @see GFFormsModel::get_date_range_where
640
	 *
641
	 * @param  array      $args            View settings
642
	 * @param  array      $search_criteria Search being performed, if any
643
	 * @return array                       Modified `$search_criteria` array
644
	 */
645 21
	public static function process_search_dates( $args, $search_criteria = array() ) {
646
647 21
		$return_search_criteria = $search_criteria;
648
649 21
		foreach ( array( 'start_date', 'end_date' ) as $key ) {
650
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
651
652
			// Is the start date or end date set in the view or shortcode?
653
			// If so, we want to make sure that the search doesn't go outside the bounds defined.
654 21
			if ( ! empty( $args[ $key ] ) ) {
655
656
				// Get a timestamp and see if it's a valid date format
657 1
				$date = strtotime( $args[ $key ] );
658
659
				// The date was invalid
660 1
				if ( empty( $date ) ) {
661
					gravityview()->log->error( ' Invalid {key} date format: {format}', array( 'key' => $key, 'format' => $args[ $key ] ) );
662
					continue;
663
				}
664
665
				// The format that Gravity Forms expects for start_date and day-specific (not hour/second-specific) end_date
666 1
				$datetime_format = 'Y-m-d H:i:s';
667 1
				$search_is_outside_view_bounds = false;
668
669 1
				if( ! empty( $search_criteria[ $key ] ) ) {
670
671 1
					$search_date = strtotime( $search_criteria[ $key ] );
672
673
					// The search is for entries before the start date defined by the settings
674 1
					switch ( $key ) {
675 1
						case 'end_date':
676
							/**
677
							 * If the end date is formatted as 'Y-m-d', it should be formatted without hours and seconds
678
							 * so that Gravity Forms can convert the day to 23:59:59 the previous day.
679
							 *
680
							 * If it's a relative date ("now" or "-1 day"), then it should use the precise date format
681
							 *
682
							 * @see GFFormsModel::get_date_range_where
683
							 */
684 1
							$datetime_format               = gravityview_is_valid_datetime( $args[ $key ] ) ? 'Y-m-d' : 'Y-m-d H:i:s';
685 1
							$search_is_outside_view_bounds = ( $search_date > $date );
686 1
							break;
687 1
						case 'start_date':
688 1
							$search_is_outside_view_bounds = ( $search_date < $date );
689 1
							break;
690
					}
691
				}
692
693
				// If there is no search being performed, or if there is a search being performed that's outside the bounds
694 1
				if ( empty( $search_criteria[ $key ] ) || $search_is_outside_view_bounds ) {
695
696
					// Then we override the search and re-set the start date
697 21
					$return_search_criteria[ $key ] = date_i18n( $datetime_format , $date, true );
698
				}
699
			}
700
		}
701
702 21
		if( isset( $return_search_criteria['start_date'] ) && isset( $return_search_criteria['end_date'] ) ) {
703
			// The start date is AFTER the end date. This will result in no results, but let's not force the issue.
704 1
			if ( strtotime( $return_search_criteria['start_date'] ) > strtotime( $return_search_criteria['end_date'] ) ) {
705 1
				gravityview()->log->error( 'Invalid search: the start date is after the end date.', array( 'data' => $return_search_criteria ) );
706
			}
707
		}
708
709 21
		return $return_search_criteria;
710
	}
711
712
713
	/**
714
	 * Process the approved only search criteria according to the View settings
715
	 *
716
	 * @param  array      $args            View settings
717
	 * @param  array      $search_criteria Search being performed, if any
718
	 * @return array                       Modified `$search_criteria` array
719
	 */
720 21
	public static function process_search_only_approved( $args, $search_criteria ) {
721
722
		/** @since 1.19 */
723 21
		if( ! empty( $args['admin_show_all_statuses'] ) && GVCommon::has_cap('gravityview_moderate_entries') ) {
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...
724
			gravityview()->log->debug( 'User can moderate entries; showing all approval statuses' );
725
			return $search_criteria;
726
		}
727
728 21
		if ( ! empty( $args['show_only_approved'] ) ) {
729
730 2
			$search_criteria['field_filters'][] = array(
731
				'key' => GravityView_Entry_Approval::meta_key,
732
				'value' => GravityView_Entry_Approval_Status::APPROVED
0 ignored issues
show
introduced by
Each line in an array declaration must end in a comma
Loading history...
733
			);
734
735 2
			$search_criteria['field_filters']['mode'] = 'all'; // force all the criterias to be met
736
737 2
			gravityview()->log->debug( '[process_search_only_approved] Search Criteria if show only approved: ', array( 'data' => $search_criteria ) );
738
		}
739
740 21
		return $search_criteria;
741
	}
742
743
744
	/**
745
	 * Check if a certain entry is approved.
746
	 *
747
	 * If we pass the View settings ($args) it will check the 'show_only_approved' setting before
748
	 *   checking the entry approved field, returning true if show_only_approved = false.
749
	 *
750
	 * @since 1.7
751
	 * @since 1.18 Converted check to use GravityView_Entry_Approval_Status::is_approved
752
	 *
753
	 * @uses GravityView_Entry_Approval_Status::is_approved
754
	 *
755
	 * @param array $entry  Entry object
756
	 * @param array $args   View settings (optional)
757
	 *
758
	 * @return bool
759
	 */
760
	public static function is_entry_approved( $entry, $args = array() ) {
761
762
		if ( empty( $entry['id'] ) || ( array_key_exists( 'show_only_approved', $args ) && ! $args['show_only_approved'] ) ) {
763
			// is implicitly approved if entry is null or View settings doesn't require to check for approval
764
			return true;
765
		}
766
767
		/** @since 1.19 */
768
		if( ! empty( $args['admin_show_all_statuses'] ) && GVCommon::has_cap('gravityview_moderate_entries') ) {
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...
769
			gravityview()->log->debug( 'User can moderate entries, so entry is approved for viewing' );
770
			return true;
771
		}
772
773
		$is_approved = gform_get_meta( $entry['id'], GravityView_Entry_Approval::meta_key );
774
775
		return GravityView_Entry_Approval_Status::is_approved( $is_approved );
776
	}
777
778
	/**
779
	 * Parse search criteria for a entries search.
780
	 *
781
	 * array(
782
	 * 	'search_field' => 1, // ID of the field
783
	 *  'search_value' => '', // Value of the field to search
784
	 *  'search_operator' => 'contains', // 'is', 'isnot', '>', '<', 'contains'
785
	 *  'show_only_approved' => 0 or 1 // Boolean
786
	 * )
787
	 *
788
	 * @param  array $args    Array of args
789
	 * @param  int $form_id Gravity Forms form ID
790
	 * @return array          Array of search parameters, formatted in Gravity Forms mode, using `status` key set to "active" by default, `field_filters` array with `key`, `value` and `operator` keys.
791
	 */
792 21
	public static function get_search_criteria( $args, $form_id ) {
793
		/**
794
		 * Compatibility with filters hooking in `gravityview_search_criteria` instead of `gravityview_fe_search_criteria`.
795
		 */
796 21
		$criteria = apply_filters( 'gravityview_search_criteria', array(), array( $form_id ), \GV\Utils::get( $args, 'id' ) );
797 21
		$search_criteria = isset( $criteria['search_criteria'] ) ? $criteria['search_criteria'] : array( 'field_filters' => array() );
798
799
		/**
800
		 * @filter `gravityview_fe_search_criteria` Modify the search criteria
801
		 * @see GravityView_Widget_Search::filter_entries Adds the default search criteria
802
		 * @param array $search_criteria Empty `field_filters` key
803
		 * @param int $form_id ID of the Gravity Forms form that is being searched
804
		 * @param array $args The View settings.
805
		 */
806 21
		$search_criteria = apply_filters( 'gravityview_fe_search_criteria', $search_criteria, $form_id, $args );
807
808 21
		$original_search_criteria = $search_criteria;
809
810 21
		gravityview()->log->debug( '[get_search_criteria] Search Criteria after hook gravityview_fe_search_criteria: ', array( 'data' =>$search_criteria ) );
0 ignored issues
show
introduced by
Expected 1 space between double arrow and "$search_criteria"; 0 found
Loading history...
introduced by
Expected 1 space after "=>"; 0 found
Loading history...
811
812
		// implicity search
813 21
		if ( ! empty( $args['search_value'] ) ) {
814
815
			// Search operator options. Options: `is` or `contains`
816 1
			$operator = ! empty( $args['search_operator'] ) && in_array( $args['search_operator'], array( 'is', 'isnot', '>', '<', 'contains' ) ) ? $args['search_operator'] : 'contains';
817
818 1
			$search_criteria['field_filters'][] = array(
819 1
				'key' => \GV\Utils::_GET( 'search_field', \GV\Utils::get( $args, 'search_field' ) ), // The field ID to search
820 1
				'value' => _wp_specialchars( $args['search_value'] ), // The value to search. Encode ampersands but not quotes.
821 1
				'operator' => $operator,
822
			);
823
824
			// Lock search mode to "all" with implicit presearch filter.
825 1
			$search_criteria['field_filters']['mode'] = 'all';
826
		}
827
828 21
		if( $search_criteria !== $original_search_criteria ) {
829 1
			gravityview()->log->debug( '[get_search_criteria] Search Criteria after implicity search: ', array( 'data' => $search_criteria ) );
830
		}
831
832
		// Handle setting date range
833 21
		$search_criteria = self::process_search_dates( $args, $search_criteria );
834
835 21
		if( $search_criteria !== $original_search_criteria ) {
836 1
			gravityview()->log->debug( '[get_search_criteria] Search Criteria after date params: ', array( 'data' => $search_criteria ) );
837
		}
838
839
		// remove not approved entries
840 21
		$search_criteria = self::process_search_only_approved( $args, $search_criteria );
841
842
		/**
843
		 * @filter `gravityview_status` Modify entry status requirements to be included in search results.
844
		 * @param string $status Default: `active`. Accepts all Gravity Forms entry statuses, including `spam` and `trash`
845
		 */
846 21
		$search_criteria['status'] = apply_filters( 'gravityview_status', 'active', $args );
847
848 21
		return $search_criteria;
849
	}
850
851
852
853
	/**
854
	 * Core function to calculate View multi entries (directory) based on a set of arguments ($args):
855
	 *   $id - View id
856
	 *   $page_size - Page
857
	 *   $sort_field - form field id to sort
858
	 *   $sort_direction - ASC / DESC
859
	 *   $start_date - Ymd
860
	 *   $end_date - Ymd
861
	 *   $class - assign a html class to the view
862
	 *   $offset (optional) - This is the start point in the current data set (0 index based).
863
	 *
864
	 *
865
	 *
866
	 * @uses  gravityview_get_entries()
867
	 * @access public
868
	 * @param array $args\n
0 ignored issues
show
Bug introduced by
There is no parameter named $args\n. 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...
869
	 *   - $id - View id
870
	 *   - $page_size - Page
871
	 *   - $sort_field - form field id to sort
872
	 *   - $sort_direction - ASC / DESC
873
	 *   - $start_date - Ymd
874
	 *   - $end_date - Ymd
875
	 *   - $class - assign a html class to the view
876
	 *   - $offset (optional) - This is the start point in the current data set (0 index based).
877
	 * @param int $form_id Gravity Forms Form ID
878
	 * @return array Associative array with `count`, `entries`, and `paging` keys. `count` has the total entries count, `entries` is an array with Gravity Forms full entry data, `paging` is an array with `offset` and `page_size` keys
879
	 */
880 1
	public static function get_view_entries( $args, $form_id ) {
881
882 1
		gravityview()->log->debug( '[get_view_entries] init' );
883
		// start filters and sorting
884
885 1
		$parameters = self::get_view_entries_parameters( $args, $form_id );
886
887 1
		$count = 0; // Must be defined so that gravityview_get_entries can use by reference
888
889
		// fetch entries
890
		list( $entries, $paging, $count ) =
891 1
			\GV\Mocks\GravityView_frontend_get_view_entries( $args, $form_id, $parameters, $count );
892
893 1
		gravityview()->log->debug( 'Get Entries. Found: {count} entries', array( 'count' => $count, 'data' => $entries ) );
894
895
		/**
896
		 * @filter `gravityview_view_entries` Filter the entries output to the View
897
		 * @deprecated since 1.5.2
898
		 * @param array $args View settings associative array
899
		 * @var array
900
		 */
901 1
		$entries = apply_filters( 'gravityview_view_entries', $entries, $args );
902
903
		$return = array(
904 1
			'count' => $count,
905 1
			'entries' => $entries,
906 1
			'paging' => $paging,
907
		);
908
909
		/**
910
		 * @filter `gravityview/view/entries` Filter the entries output to the View
911
		 * @param array $criteria associative array containing count, entries & paging
912
		 * @param array $args View settings associative array
913
		 * @since 1.5.2
914
		 */
915 1
		return apply_filters( 'gravityview/view/entries', $return, $args );
916
	}
917
918
	/**
919
	 * Get an array of search parameters formatted as Gravity Forms requires
920
	 *
921
	 * Results are filtered by `gravityview_get_entries` and `gravityview_get_entries_{View ID}` filters
922
	 *
923
	 * @uses GravityView_frontend::get_search_criteria
924
	 * @uses GravityView_frontend::get_search_criteria_paging
925
	 *
926
	 * @since 1.20
927
	 *
928
	 * @see \GV\View_Settings::defaults For $args options
929
	 *
930
	 * @param array $args Array of View settings, as structured in \GV\View_Settings::defaults
931
	 * @param int $form_id Gravity Forms form ID to search
932
	 *
933
	 * @return array With `search_criteria`, `sorting`, `paging`, `cache` keys
934
	 */
935 20
	public static function get_view_entries_parameters( $args = array(), $form_id = 0 ) {
936
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
937
938 20
		if ( ! is_array( $args ) || ! is_numeric( $form_id ) ) {
939
940
			gravityview()->log->error( 'Passed args are not an array or the form ID is not numeric' );
941
942
			return array();
943
		}
944
945 20
		$form_id = intval( $form_id );
946
947
		/**
948
		 * Process search parameters
949
		 * @var array
950
		 */
951 20
		$search_criteria = self::get_search_criteria( $args, $form_id );
952
953 20
		$paging = self::get_search_criteria_paging( $args );
954
955
		$parameters = array(
956 20
			'search_criteria' => $search_criteria,
957 20
			'sorting' => self::updateViewSorting( $args, $form_id ),
958 20
			'paging' => $paging,
959 20
			'cache' => isset( $args['cache'] ) ? $args['cache'] : true,
960
		);
961
962
		/**
963
		 * @filter `gravityview_get_entries` Filter get entries criteria
964
		 * @param array $parameters Array with `search_criteria`, `sorting` and `paging` keys.
965
		 * @param array $args View configuration args. {
966
		 *      @type int $id View id
967
		 *      @type int $page_size Number of entries to show per page
968
		 *      @type string $sort_field Form field id to sort
969
		 *      @type string $sort_direction Sorting direction ('ASC', 'DESC', or 'RAND')
970
		 *      @type string $start_date - Ymd
971
		 *      @type string $end_date - Ymd
972
		 *      @type string $class - assign a html class to the view
973
		 *      @type string $offset (optional) - This is the start point in the current data set (0 index based).
974
		 * }
975
		 * @param int $form_id ID of Gravity Forms form
976
		 */
977 20
		$parameters = apply_filters( 'gravityview_get_entries', $parameters, $args, $form_id );
978
979
		/**
980
		 * @filter `gravityview_get_entries_{View ID}` Filter get entries criteria
981
		 * @param array $parameters Array with `search_criteria`, `sorting` and `paging` keys.
982
		 * @param array $args View configuration args.
983
		 */
984 20
		$parameters = apply_filters( 'gravityview_get_entries_'.\GV\Utils::get( $args, 'id' ), $parameters, $args, $form_id );
985
986 20
		gravityview()->log->debug( '$parameters passed to gravityview_get_entries(): ', array( 'data' => $parameters ) );
987
988 20
		return $parameters;
989
	}
990
991
	/**
992
	 * Get the paging array for the View
993
	 *
994
	 * @since 1.19.5
995
	 *
996
	 * @param $args
997
	 * @param int $form_id
0 ignored issues
show
Bug introduced by
There is no parameter named $form_id. 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...
998
	 */
999 20
	public static function get_search_criteria_paging( $args ) {
1000
1001
		/**
1002
		 * @filter `gravityview_default_page_size` The default number of entries displayed in a View
1003
		 * @since 1.1.6
1004
		 * @param int $default_page_size Default: 25
1005
		 */
1006 20
		$default_page_size = apply_filters( 'gravityview_default_page_size', 25 );
1007
1008
		// Paging & offset
1009 20
		$page_size = ! empty( $args['page_size'] ) ? intval( $args['page_size'] ) : $default_page_size;
1010
1011 20
		if ( -1 === $page_size ) {
1012
			$page_size = PHP_INT_MAX;
1013
		}
1014
1015 20
		$curr_page = empty( $_GET['pagenum'] ) ? 1 : intval( $_GET['pagenum'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
1016 20
		$offset = ( $curr_page - 1 ) * $page_size;
1017
1018 20
		if ( ! empty( $args['offset'] ) ) {
1019
			$offset += intval( $args['offset'] );
1020
		}
1021
1022
		$paging = array(
1023 20
			'offset' => $offset,
1024 20
			'page_size' => $page_size,
1025
		);
1026
1027 20
		gravityview()->log->debug( 'Paging: ', array( 'data' => $paging ) );
1028
1029 20
		return $paging;
1030
	}
1031
1032
	/**
1033
	 * Updates the View sorting criteria
1034
	 *
1035
	 * @since 1.7
1036
	 *
1037
	 * @param array $args View settings. Required to have `sort_field` and `sort_direction` keys
1038
	 * @param int $form_id The ID of the form used to sort
1039
	 * @return array $sorting Array with `key`, `direction` and `is_numeric` keys
1040
	 */
1041 20
	public static function updateViewSorting( $args, $form_id ) {
0 ignored issues
show
Coding Style introduced by
The function name updateViewSorting is in camel caps, but expected update_view_sorting instead as per the coding standard.
Loading history...
1042 20
		$sorting = array();
1043 20
		$sort_field_id = isset( $_GET['sort'] ) ? $_GET['sort'] : \GV\Utils::get( $args, 'sort_field' );
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...
1044 20
		$sort_direction = isset( $_GET['dir'] ) ? $_GET['dir'] : \GV\Utils::get( $args, 'sort_direction' );
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...
1045
1046 20
		$sort_field_id = self::_override_sorting_id_by_field_type( $sort_field_id, $form_id );
1047
1048 20
		if ( ! empty( $sort_field_id ) ) {
1049
			$sorting = array(
1050
				'key' => $sort_field_id,
1051
				'direction' => strtolower( $sort_direction ),
1052
				'is_numeric' => GVCommon::is_field_numeric( $form_id, $sort_field_id )
1053
			);
1054
		}
1055
1056 20
		if ( 'RAND' === $sort_direction ) {
1057
1058
			$form = GFAPI::get_form( $form_id );
1059
1060
			// Get the first GF_Field field ID, set as the key for entry randomization
1061
			if( ! empty( $form['fields'] ) ) {
1062
1063
				/** @var GF_Field $field */
1064
				foreach ( $form['fields'] as $field ) {
1065
1066
					if( ! is_a( $field, 'GF_Field' ) ) {
1067
						continue;
1068
					}
1069
1070
					$sorting = array(
1071
						'key'        => $field->id,
1072
						'is_numeric' => false,
1073
						'direction'  => 'RAND',
1074
					);
1075
1076
					break;
1077
				}
1078
			}
1079
		}
1080
1081 20
		GravityView_View::getInstance()->setSorting( $sorting );
1082
1083 20
		gravityview()->log->debug( '[updateViewSorting] Sort Criteria : ', array( 'data' => $sorting ) );
1084
1085 20
		return $sorting;
1086
1087
	}
1088
1089
	/**
1090
	 * Override sorting per field
1091
	 *
1092
	 * Currently only modifies sorting ID when sorting by the full name. Sorts by first name.
1093
	 * Use the `gravityview/sorting/full-name` filter to override.
1094
	 *
1095
	 * @todo Filter from GravityView_Field
1096
	 * @since 1.7.4
1097
	 * @internal Hi developer! Although this is public, don't call this method; we're going to replace it.
1098
	 *
1099
	 * @param int|string $sort_field_id Field used for sorting (`id` or `1.2`)
1100
	 * @param int $form_id GF Form ID
1101
	 *
1102
	 * @return string Possibly modified sorting ID
1103
	 */
1104 20
	public static function _override_sorting_id_by_field_type( $sort_field_id, $form_id ) {
1105
1106 20
		$form = gravityview_get_form( $form_id );
1107
1108 20
		$sort_field = GFFormsModel::get_field( $form, $sort_field_id );
1109
1110 20
		if( ! $sort_field ) {
1111 20
			return $sort_field_id;
1112
		}
1113
1114
		switch ( $sort_field['type'] ) {
1115
1116
			case 'address':
1117
				// Sorting by full address
1118
				if ( floatval( $sort_field_id ) === floor( $sort_field_id ) ) {
1119
1120
					/**
1121
					 * Override how to sort when sorting address
1122
					 *
1123
					 * @since 1.8
1124
					 *
1125
					 * @param string $address_part `street`, `street2`, `city`, `state`, `zip`, or `country` (default: `city`)
1126
					 * @param string $sort_field_id Field used for sorting
1127
					 * @param int $form_id GF Form ID
1128
					 */
1129
					$address_part = apply_filters( 'gravityview/sorting/address', 'city', $sort_field_id, $form_id );
1130
1131
					switch( strtolower( $address_part ) ){
1132
						case 'street':
1133
							$sort_field_id .= '.1';
1134
							break;
1135
						case 'street2':
1136
							$sort_field_id .= '.2';
1137
							break;
1138
						default:
1139
						case 'city':
0 ignored issues
show
Unused Code introduced by
case 'city': $sort_f..._id .= '.3'; break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1140
							$sort_field_id .= '.3';
1141
							break;
1142
						case 'state':
1143
							$sort_field_id .= '.4';
1144
							break;
1145
						case 'zip':
1146
							$sort_field_id .= '.5';
1147
							break;
1148
						case 'country':
1149
							$sort_field_id .= '.6';
1150
							break;
1151
					}
1152
1153
				}
1154
				break;
1155
			case 'name':
1156
				// Sorting by full name, not first, last, etc.
1157
				if ( floatval( $sort_field_id ) === floor( $sort_field_id ) ) {
1158
					/**
1159
					 * @filter `gravityview/sorting/full-name` Override how to sort when sorting full name.
1160
					 * @since 1.7.4
1161
					 * @param[in,out] string $name_part Sort by `first` or `last` (default: `first`)
1162
					 * @param[in] string $sort_field_id Field used for sorting
1163
					 * @param[in] int $form_id GF Form ID
1164
					 */
1165
					$name_part = apply_filters( 'gravityview/sorting/full-name', 'first', $sort_field_id, $form_id );
1166
1167
					if ( 'last' === strtolower( $name_part ) ) {
1168
						$sort_field_id .= '.6';
1169
					} else {
1170
						$sort_field_id .= '.3';
1171
					}
1172
				}
1173
				break;
1174
			case 'list':
1175
				$sort_field_id = false;
1176
				break;
1177
			case 'time':
1178
1179
				/**
1180
				 * @filter `gravityview/sorting/time` Override how to sort when sorting time
1181
				 * @see GravityView_Field_Time
1182
				 * @since 1.14
1183
				 * @param[in,out] string $name_part Field used for sorting
1184
				 * @param[in] int $form_id GF Form ID
1185
				 */
1186
				$sort_field_id = apply_filters( 'gravityview/sorting/time', $sort_field_id, $form_id );
1187
				break;
1188
		}
1189
1190
		return $sort_field_id;
1191
	}
1192
1193
	/**
1194
	 * Verify if user requested a single entry view
1195
	 * @return boolean|string false if not, single entry slug if true
1196
	 */
1197 7
	public static function is_single_entry() {
1198
1199 7
		$var_name = \GV\Entry::get_endpoint_name();
1200
1201 7
		$single_entry = get_query_var( $var_name );
1202
1203
		/**
1204
		 * Modify the entry that is being displayed.
1205
		 *
1206
		 * @internal Should only be used by things like the oEmbed functionality.
1207
		 * @since 1.6
1208
		 */
1209 7
		$single_entry = apply_filters( 'gravityview/is_single_entry', $single_entry );
1210
1211 7
		if ( empty( $single_entry ) ){
1212 4
			return false;
1213
		} else {
1214 3
			return $single_entry;
1215
		}
1216
	}
1217
1218
1219
	/**
1220
	 * Register styles and scripts
1221
	 *
1222
	 * @access public
1223
	 * @return void
1224
	 */
1225 1
	public function add_scripts_and_styles() {
1226 1
		global $post, $posts;
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...
1227
		// enqueue template specific styles
1228 1
		if ( $this->getGvOutputData() ) {
1229
1230 1
			$views = $this->getGvOutputData()->get_views();
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_View_Data::get_views() has been deprecated.

This method has been deprecated.

Loading history...
1231
1232 1
			foreach ( $views as $view_id => $data ) {
1233 1
				$view = \GV\View::by_id( $data['id'] );
1234 1
				$view_id = $view->ID;
1235 1
				$template_id = gravityview_get_template_id( $view->ID );
1236 1
				$data = $view->as_data();
0 ignored issues
show
Deprecated Code introduced by
The method GV\View::as_data() has been deprecated.

This method has been deprecated.

Loading history...
1237
1238
				/**
1239
				 * Don't enqueue the scripts or styles if it's not going to be displayed.
1240
				 * @since 1.15
1241
				 */
1242 1
				if( is_user_logged_in() && false === GVCommon::has_cap( 'read_gravityview', $view_id ) ) {
1243
					continue;
1244
				}
1245
1246
				// By default, no thickbox
1247 1
				$js_dependencies = array( 'jquery', 'gravityview-jquery-cookie' );
1248 1
				$css_dependencies = array();
1249
1250 1
				$lightbox = $view->settings->get( 'lightbox' );
1251
1252
				// If the thickbox is enqueued, add dependencies
1253 1
				if ( $lightbox ) {
1254
1255
					/**
1256
					 * @filter `gravity_view_lightbox_script` Override the lightbox script to enqueue. Default: `thickbox`
1257
					 * @param string $script_slug If you want to use a different lightbox script, return the name of it here.
1258
					 */
1259 1
					$js_dependencies[] = apply_filters( 'gravity_view_lightbox_script', 'thickbox' );
1260
1261
					/**
1262
					 * @filter `gravity_view_lightbox_style` Modify the lightbox CSS slug. Default: `thickbox`
1263
					 * @param string $script_slug If you want to use a different lightbox script, return the name of its CSS file here.
1264
					 */
1265 1
					$css_dependencies[] = apply_filters( 'gravity_view_lightbox_style', 'thickbox' );
1266
				}
1267
1268
				/**
1269
				 * If the form has checkbox fields, enqueue dashicons
1270
				 * @see https://github.com/katzwebservices/GravityView/issues/536
1271
				 * @since 1.15
1272
				 */
1273 1
				if( gravityview_view_has_single_checkbox_or_radio( $data['form'], $data['fields'] ) ) {
1274
					$css_dependencies[] = 'dashicons';
1275
				}
1276
1277 1
				wp_register_script( 'gravityview-jquery-cookie', plugins_url( 'assets/lib/jquery.cookie/jquery.cookie.min.js', GRAVITYVIEW_FILE ), array( 'jquery' ), GravityView_Plugin::version, true );
0 ignored issues
show
Deprecated Code introduced by
The constant GravityView_Plugin::version has been deprecated with message: Use \GV\Plugin::$version

This class constant 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 constant will be removed from the class and what other constant to use instead.

Loading history...
1278
1279 1
				$script_debug = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
1280
1281 1
				wp_register_script( 'gravityview-fe-view', plugins_url( 'assets/js/fe-views' . $script_debug . '.js', GRAVITYVIEW_FILE ), apply_filters( 'gravityview_js_dependencies', $js_dependencies ) , GravityView_Plugin::version, true );
0 ignored issues
show
Deprecated Code introduced by
The constant GravityView_Plugin::version has been deprecated with message: Use \GV\Plugin::$version

This class constant 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 constant will be removed from the class and what other constant to use instead.

Loading history...
1282
1283 1
				wp_enqueue_script( 'gravityview-fe-view' );
1284
1285 1
				if ( ! empty( $data['atts']['sort_columns'] ) ) {
1286
					wp_enqueue_style( 'gravityview_font', plugins_url( 'assets/css/font.css', GRAVITYVIEW_FILE ), $css_dependencies, GravityView_Plugin::version, 'all' );
0 ignored issues
show
Deprecated Code introduced by
The constant GravityView_Plugin::version has been deprecated with message: Use \GV\Plugin::$version

This class constant 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 constant will be removed from the class and what other constant to use instead.

Loading history...
1287
				}
1288
1289 1
				$this->enqueue_default_style( $css_dependencies );
1290
1291 1
				self::add_style( $template_id );
1292
			}
1293
1294 1
			if ( 'wp_print_footer_scripts' === current_filter() ) {
1295
1296
				$js_localization = array(
1297
					'cookiepath' => COOKIEPATH,
1298
					'clear' => _x( 'Clear', 'Clear all data from the form', 'gravityview' ),
1299
					'reset' => _x( 'Reset', 'Reset the search form to the state that existed on page load', 'gravityview' ),
1300
				);
1301
1302
				/**
1303
				 * @filter `gravityview_js_localization` Modify the array passed to wp_localize_script()
1304
				 * @param array $js_localization The data padded to the Javascript file
1305
				 * @param array $views Array of View data arrays with View settings
1306
				 */
1307
				$js_localization = apply_filters( 'gravityview_js_localization', $js_localization, $views );
1308
1309
				wp_localize_script( 'gravityview-fe-view', 'gvGlobals', $js_localization );
1310
			}
1311
		}
1312 1
	}
1313
1314
	/**
1315
	 * Handle enqueuing the `gravityview_default_style` stylesheet
1316
	 *
1317
	 * @since 1.17
1318
	 *
1319
	 * @param array $css_dependencies Dependencies for the `gravityview_default_style` stylesheet
1320
	 *
1321
	 * @return void
1322
	 */
1323
	private function enqueue_default_style( $css_dependencies = array() ) {
1324
1325
		/**
1326
		 * @filter `gravityview_use_legacy_search_css` Should GravityView use the legacy Search Bar stylesheet (from before Version 1.17)?
1327
		 * @since 1.17
1328
		 * @param bool $use_legacy_search_style If true, loads `gv-legacy-search(-rtl).css`. If false, loads `gv-default-styles(-rtl).css`. `-rtl` is added on RTL websites. Default: `false`
1329
		 */
1330
		$use_legacy_search_style = apply_filters( 'gravityview_use_legacy_search_style', false );
1331
1332
		$rtl = is_rtl() ? '-rtl' : '';
1333
1334
		$css_file_base = $use_legacy_search_style ? 'gv-legacy-search' : 'gv-default-styles';
1335
1336
		$path = gravityview_css_url( $css_file_base . $rtl . '.css' );
1337
1338
		wp_enqueue_style( 'gravityview_default_style', $path, $css_dependencies, GravityView_Plugin::version, 'all' );
0 ignored issues
show
Deprecated Code introduced by
The constant GravityView_Plugin::version has been deprecated with message: Use \GV\Plugin::$version

This class constant 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 constant will be removed from the class and what other constant to use instead.

Loading history...
1339
	}
1340
1341
	/**
1342
	 * Add template extra style if exists
1343
	 * @param string $template_id
1344
	 */
1345
	public static function add_style( $template_id ) {
1346
1347
		if ( ! empty( $template_id ) && wp_style_is( 'gravityview_style_' . $template_id, 'registered' ) ) {
1348
			gravityview()->log->debug(  'Adding extra template style for {template_id}', array( 'template_id' => $template_id ) );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 2 found
Loading history...
1349
			wp_enqueue_style( 'gravityview_style_' . $template_id );
1350
		} elseif ( empty( $template_id ) ) {
1351
			gravityview()->log->error( 'Cannot add template style; template_id is empty' );
1352
		} else {
1353
			gravityview()->log->error( 'Cannot add template style; {template_id} is not registered', array( 'template_id' => 'gravityview_style_' . $template_id ) );
1354
		}
1355
1356
	}
1357
1358
1359
	/**
1360
	 * Inject the sorting links on the table columns
1361
	 *
1362
	 * Callback function for hook 'gravityview/template/field_label'
1363
	 * @see GravityView_API::field_label() (in includes/class-api.php)
1364
	 *
1365
	 * @since 1.7
1366
	 *
1367
	 * @param string $label Field label
1368
	 * @param array $field Field settings
1369
	 * @param array $form Form object
1370
	 *
1371
	 * @return string Field Label
1372
	 */
1373
	public function add_columns_sort_links( $label = '', $field, $form ) {
1374
1375
		/**
1376
		 * Not a table-based template; don't add sort icons
1377
		 * @since 1.12
1378
		 */
1379
		if( ! preg_match( '/table/ism', GravityView_View::getInstance()->getTemplatePartSlug() ) ) {
1380
			return $label;
1381
		}
1382
1383
		if ( ! $this->is_field_sortable( $field['id'], $form ) ) {
1384
			return $label;
1385
		}
1386
1387
		$sorting = GravityView_View::getInstance()->getSorting();
1388
1389
		$class = 'gv-sort';
1390
1391
		$sort_field_id = self::_override_sorting_id_by_field_type( $field['id'], $form['id'] );
1392
1393
		$sort_args = array(
1394
			'sort' => $field['id'],
1395
			'dir' => 'asc',
1396
		);
1397
1398
		if ( ! empty( $sorting['key'] ) && (string) $sort_field_id === (string) $sorting['key'] ) {
1399
			//toggle sorting direction.
1400
			if ( 'asc' === $sorting['direction'] ) {
1401
				$sort_args['dir'] = 'desc';
1402
				$class .= ' gv-icon-sort-desc';
1403
			} else {
1404
				$sort_args['dir'] = 'asc';
1405
				$class .= ' gv-icon-sort-asc';
1406
			}
1407
		} else {
1408
			$class .= ' gv-icon-caret-up-down';
1409
		}
1410
1411
		$url = add_query_arg( $sort_args, remove_query_arg( array('pagenum') ) );
0 ignored issues
show
introduced by
No space after opening parenthesis of array is bad style
Loading history...
introduced by
No space before closing parenthesis of array is bad style
Loading history...
1412
1413
		return '<a href="'. esc_url_raw( $url ) .'" class="'. $class .'" ></a>&nbsp;'. $label;
1414
1415
	}
1416
1417
	/**
1418
	 * Checks if field (column) is sortable
1419
	 *
1420
	 * @param string $field Field settings
0 ignored issues
show
Bug introduced by
There is no parameter named $field. 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...
1421
	 * @param array $form Gravity Forms form array
1422
	 *
1423
	 * @since 1.7
1424
	 *
1425
	 * @return bool True: Yes, field is sortable; False: not sortable
1426
	 */
1427
	public function is_field_sortable( $field_id = '', $form = array() ) {
1428
1429
		$field_type = $field_id;
1430
1431
		if( is_numeric( $field_id ) ) {
1432
			$field = GFFormsModel::get_field( $form, $field_id );
1433
			$field_type = $field->type;
1434
		}
1435
1436
		$not_sortable = array(
1437
			'edit_link',
1438
			'delete_link',
1439
		);
1440
1441
		/**
1442
		 * @filter `gravityview/sortable/field_blacklist` Modify what fields should never be sortable.
1443
		 * @since 1.7
1444
		 * @param[in,out] array $not_sortable Array of field types that aren't sortable
1445
		 * @param string $field_type Field type to check whether the field is sortable
1446
		 * @param array $form Gravity Forms form
1447
		 */
1448
		$not_sortable = apply_filters( 'gravityview/sortable/field_blacklist', $not_sortable, $field_type, $form );
1449
1450
		if ( in_array( $field_type, $not_sortable ) ) {
1451
			return false;
1452
		}
1453
1454
		return apply_filters( "gravityview/sortable/formfield_{$form['id']}_{$field_id}", apply_filters( "gravityview/sortable/field_{$field_id}", true, $form ) );
1455
1456
	}
1457
1458
}
1459
1460
GravityView_frontend::getInstance();
1461
1462
1463
1464