Completed
Push — develop ( 9148e3...08585c )
by Zack
17:51
created

GravityView_API::field_label()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
nc 2
nop 3
dl 0
loc 12
ccs 5
cts 5
cp 1
crap 3
rs 9.8666
c 0
b 0
f 0
1
<?php
2
/**
3
 * GravityView template tags API
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
class GravityView_API {
15
16
	/**
17
	 * Fetch Field Label
18
	 *
19
	 * @deprecated Use \GV\Field::get_label()
20
	 *
21
	 * @access public
22
	 * @static
23
	 * @param array $field GravityView field array
24
	 * @param array $entry Gravity Forms entry array
25
	 * @param boolean $force_show_label Whether to always show the label, regardless of field settings
26
	 * @return string
27
	 */
28 3
	public static function field_label( $field, $entry = array(), $force_show_label = false ) {
29
30 3
		$gravityview_view = GravityView_View::getInstance();
31
32 3
		$form = $gravityview_view->getForm();
33
34 3
		if ( defined( 'DOING_GRAVITYVIEW_TESTS' ) && ! empty( $GLOBALS['GravityView_API_field_label_override'] ) ) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
35
			/** Allow to fall through for back compatibility testing purposes. */
36
		} else {
37 3
			return \GV\Mocks\GravityView_API_field_label( $form, $field, $entry, $force_show_label );
38
		}
39
	}
40 1
41
	/**
42 1
	 * Alias for GravityView_Merge_Tags::replace_variables()
43
	 *
44 1
	 * @see GravityView_Merge_Tags::replace_variables() Moved in 1.8.4
45
	 * @since 1.22.4 - Added $nl2br, $format, $aux_data args
46
	 *
47 1
	 * @param  string     $text         Text to replace variables in
48
	 * @param  array      $form         GF Form array
49 1
	 * @param  array      $entry        GF Entry array
50
	 * @param  bool       $url_encode   Pass return value through `url_encode()`
51 1
	 * @param  bool       $esc_html     Pass return value through `esc_html()`
52
	 * @param  bool       $nl2br        Convert newlines to <br> HTML tags
53 1
	 * @param  string     $format       The format requested for the location the merge is being used. Possible values: html, text or url.
54
	 * @param  array      $aux_data     Additional data to be used to replace merge tags {@see https://www.gravityhelp.com/documentation/article/gform_merge_tag_data/}
55
	 * @return string                   Text with variables maybe replaced
56 1
	 */
57
	public static function replace_variables( $text, $form = array(), $entry = array(), $url_encode = false, $esc_html = true, $nl2br = true, $format = 'html', $aux_data = array() ) {
58
		return GravityView_Merge_Tags::replace_variables( $text, $form, $entry, $url_encode, $esc_html, $nl2br, $format, $aux_data );
59 1
	}
60
61
	/**
62
	 * Get column width from the field setting
63
	 *
64 1
	 * @since 1.9
65
	 *
66
	 * @param array $field Array of settings for the field
67
	 * @param string $format Format for width. "%" (default) will return
68
	 *
69
	 * @return string|null If not empty, string in $format format. Otherwise, null.
70
	 */
71
	public static function field_width( $field, $format = '%d%%' ) {
72
73 1
		$width = NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
74
75 1
		if( !empty( $field['width'] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
76
			$width = absint( $field['width'] );
77
78
			// If using percentages, limit to 100%
79
			if( '%d%%' === $format && $width > 100 ) {
80
				$width = 100;
81
			}
82
83
			$width = sprintf( $format, $width );
84 1
		}
85
86
		return $width;
87
	}
88
89
	/**
90
	 * Fetch Field class
91
	 *
92
	 * @access public
93
	 * @static
94
	 * @param mixed $field
95
	 * @return string
96
	 */
97
	public static function field_class( $field, $form = NULL, $entry = NULL ) {
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
98 1
		$classes = array();
99
100 1
		if( !empty( $field['custom_class'] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
101
102
            $custom_class = $field['custom_class'];
103
104
            if( !empty( $entry ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
105
106
                // We want the merge tag to be formatted as a class. The merge tag may be
107
                // replaced by a multiple-word value that should be output as a single class.
108
                // "Office Manager" will be formatted as `.OfficeManager`, not `.Office` and `.Manager`
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
109
                add_filter('gform_merge_tag_filter', 'sanitize_html_class');
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...
110
111
                $custom_class = self::replace_variables( $custom_class, $form, $entry);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
112
113
                // And then we want life to return to normal
114
                remove_filter('gform_merge_tag_filter', 'sanitize_html_class');
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...
115
            }
116
117
			// And now we want the spaces to be handled nicely.
118
			$classes[] = gravityview_sanitize_html_class( $custom_class );
119 26
120 26
		}
121
122
		if(!empty($field['id'])) {
0 ignored issues
show
introduced by
No space after opening parenthesis is prohibited
Loading history...
introduced by
Expected 1 space before "!"; 0 found
Loading history...
introduced by
Expected 1 space after "!"; 0 found
Loading history...
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...
introduced by
No space before closing parenthesis is prohibited
Loading history...
123
			if( !empty( $form ) && !empty( $form['id'] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
124
				$form_id = '-'.$form['id'];
125
			} else {
126
				// @deprecated path. Form should always be given.
127
				gravityview()->log->warning( 'GravityView_View::getInstance() legacy API called' );
128
				$gravityview_view = GravityView_View::getInstance();
129
				$form_id = $gravityview_view->getFormId() ? '-'. $gravityview_view->getFormId() : '';
130
			}
131
132
			$classes[] = 'gv-field'.$form_id.'-'.$field['id'];
133 29
		}
134
135 29
		return esc_attr(implode(' ', $classes));
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...
136
	}
137 29
138 1
	/**
139
	 * Fetch Field HTML ID
140
	 *
141 1
	 * @since 1.11
142 1
	 *
143
	 * @access public
144
	 * @static
145 1
	 * @param array $field GravityView field array passed to gravityview_field_output()
146
	 * @param array $form Gravity Forms form array, if set.
147
	 * @param array $entry Gravity Forms entry array
148 29
	 * @return string Sanitized unique HTML `id` attribute for the field
149
	 */
150
	public static function field_html_attr_id( $field, $form = array(), $entry = array() ) {
0 ignored issues
show
Unused Code introduced by
The parameter $entry 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...
151
		$id = $field['id'];
152
153
		if ( ! empty( $id ) ) {
154
			if ( ! empty( $form ) && ! empty( $form['id'] ) ) {
155
				$form_id = '-' . $form['id'];
156
			} else {
157
				// @deprecated path. Form should always be given.
158
				gravityview()->log->warning( 'GravityView_View::getInstance() legacy API called' );
159 32
				$gravityview_view = GravityView_View::getInstance();
160 32
				$form_id = $gravityview_view->getFormId() ? '-' . $gravityview_view->getFormId() : '';
161
			}
162 32
163
			$id = 'gv-field' . $form_id . '-' . $field['id'];
164 2
		}
165
166 2
		return esc_attr( $id );
167
	}
168
169
170
	/**
171 2
	 * Given an entry and a form field id, calculate the entry value for that field.
172
	 *
173 2
	 * @deprecated Use \GV\Field_Template::render() or the more low-level \GV\Field::get_value()
174
	 *
175
	 * @access public
176 2
	 * @param array $entry
177
	 * @param array $field
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...
178
	 * @return null|string
179
	 */
180 2
	public static function field_value( $entry, $field_settings, $format = 'html' ) {
181
		gravityview()->log->notice( '\GravityView_API::field_value is deprecated. Use \GV\Field_Template::render() or \GV\Field::get_value()' );
182
		return \GV\Mocks\GravityView_API_field_value( $entry, $field_settings, $format );
0 ignored issues
show
Deprecated Code introduced by
The function GV\Mocks\GravityView_API_field_value() has been deprecated with message: Use \GV\Field_Template::render()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
183
	}
184 32
185 32
	/**
186 32
	 * Generate an anchor tag that links to an entry.
187
	 *
188
	 * @since 1.6
189
	 * @see GVCommon::get_link_html()
190
	 *
191
	 * @param string $anchor_text The text or HTML inside the link
192
	 * @param array $entry Gravity Forms entry array
193
	 * @param array|string $passed_tag_atts Attributes to be added to the anchor tag, such as `title` or `rel`.
194 32
	 * @param array $field_settings Array of field settings. Optional, but passed to the `gravityview_field_entry_link` filter
195
	 *
196
	 * @since 2.0
197 32
	 * @param int $base_id The post or the view that this entry is linked from.
198
	 *
199
	 * @return string|null Returns HTML for an anchor link. Null if $entry isn't defined or is missing an ID.
200
	 */
201
	public static function entry_link_html( $entry = array(), $anchor_text = '', $passed_tag_atts = array(), $field_settings = array(), $base_id = null ) {
202
203
		if ( empty( $entry ) || ! is_array( $entry ) || ! isset( $entry['id'] ) ) {
204
			gravityview()->log->debug( 'Entry not defined; returning null', array( 'data' => $entry ) );
205
			return NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
206
		}
207
208
		$href = self::entry_link( $entry, $base_id );
209
210
		if( '' === $href ) {
211
			return NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
212 28
		}
213 28
214
		$link = gravityview_get_link( $href, $anchor_text, $passed_tag_atts );
215 28
216 28
		/**
217 28
		 * @filter `gravityview_field_entry_link` Modify the link HTML
218
		 * @param string $link HTML output of the link
219
		 * @param string $href URL of the link
220
		 * @param array  $entry The GF entry array
221
		 * @param  array $field_settings Settings for the particular GV field
222
		 */
223
		$output = apply_filters( 'gravityview_field_entry_link', $link, $href, $entry, $field_settings );
224
225 28
		return $output;
226
	}
227
228 28
	/**
229
	 * Get the "No Results" text depending on whether there were results.
230
	 * @param  boolean     $wpautop Apply wpautop() to the output?
231
	 *
232
	 * @since 2.0
233
	 * @param \GV\Template_Context $context The context
234
	 *
235
	 * @return string               HTML of "no results" text
236
	 */
237
	public static function no_results( $wpautop = true, $context = null ) {
238
		$is_search = false;
239
240
		if ( $context instanceof \GV\Template_Context ) {
241
			if ( $context->request->is_search() ) {
242 3
				$is_search = true;
243 3
			}
244 3
		} else {
245
			$gravityview_view = GravityView_View::getInstance();
246
247
			if( $gravityview_view && ( $gravityview_view->curr_start || $gravityview_view->curr_end || $gravityview_view->curr_search ) ) {
0 ignored issues
show
Documentation introduced by
The property curr_start does not exist on object<GravityView_View>. 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...
Documentation introduced by
The property curr_end does not exist on object<GravityView_View>. 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...
Documentation introduced by
The property curr_search does not exist on object<GravityView_View>. 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...
248
				$is_search = true;
249
			}
250
		}
251
252
		if ( $is_search ) {
253
			$output = __( 'This search returned no results.', 'gravityview' );
254
		} else {
255
			$output = __( 'No entries match your request.', 'gravityview' );
256
		}
257
258
		/**
259
		 * @filter `gravitview_no_entries_text` Modify the text displayed when there are no entries.
260
		 * Note: this filter is, and always has been, misspelled. This will not be fixed, since the filter is deprecated.
261
		 * @param string $output The existing "No Entries" text
262
		 * @param boolean $is_search Is the current page a search result, or just a multiple entries screen?
263 3
		 * @return string The modified text.
264
		 * @deprecated Use `gravityview/template/text/no_entries`
265 3
		 */
266 1
		$output = apply_filters( 'gravitview_no_entries_text', $output, $is_search );
267 1
268
		/**
269
		 * @filter `gravityview/template/text/no_entries` Modify the text displayed when there are no entries.
270 3
		 * @since 2.0
271
		 * @param string $output The existing "No Entries" text
272 3
		 * @param boolean $is_search Is the current page a search result, or just a multiple entries screen?
273
		 * @param \GV\Template_Context $context The context.
274
		 * @return string The modified text.
275
		 */
276 3
		$output = apply_filters( 'gravityview/template/text/no_entries', $output, $is_search, $context );
277
278
		return $wpautop ? wpautop( $output ) : $output;
279
	}
280
281
	/**
282
	 * Generate a URL to the Directory context
283
	 *
284
	 * Uses `wp_cache_get` and `wp_cache_get` (since 1.3) to speed up repeated requests to get permalink, which improves load time. Since we may be doing this hundreds of times per request, it adds up!
285 3
	 *
286
	 * @param int $post_id Post ID
287 3
	 * @param boolean $add_query_args Add pagination and sorting arguments
288
	 *
289
	 * @since 2.0
290
	 * @param \GV\Template_Context $context The context this is being used in.
291
	 *
292
	 * @return string      Permalink to multiple entries view
293
	 */
294
	public static function directory_link( $post_id = NULL, $add_query_args = true, $context = null ) {
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
295
		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...
296
297
		if ( empty( $post_id ) ) {
298
			// DataTables passes the Post ID
299 9
			if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
300 9
				$post_id = \GV\Utils::_POST( 'post_id', false );
301
			} else {
302 9
				if ( $context instanceof \GV\Template_Context ) {
303 7
					// Shortcodes, embeds
304 7
					if ( is_a( $post, 'WP_Post' ) ) {
305
						$post_id = $post->ID;
306
307 2
					// Actual views
308
					} else {
309 2
						$post_id = $context->view ? $context->view->ID : false;
310 1
					}
311
				} else {
312
					/** @deprecated path of execution */
313
					$gravityview_view = GravityView_View::getInstance();
314 9
315 1
					// The Post ID has been passed via the shortcode
316
					if ( ! empty( $gravityview_view ) && $gravityview_view->getPostId() ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $gravityview_view->getPostId() of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

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

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

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

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
317 9
						$post_id = $gravityview_view->getPostId();
318
					} else {
319
						// This is a GravityView post type
320
						if ( GravityView_frontend::getInstance()->isGravityviewPostType() ) {
321
							$post_id = isset( $gravityview_view ) ? $gravityview_view->getViewId() : $post->ID;
322
						} else {
323
							// This is an embedded GravityView; use the embedded post's ID as the base.
324
							if ( GravityView_frontend::getInstance()->isPostHasShortcode() && is_a( $post, 'WP_Post' ) ) {
325
								$post_id = $post->ID;
326
							} elseif ( $gravityview_view->getViewId() ) {
327
								// The GravityView has been embedded in a widget or in a template, and
328 9
								// is not in the current content. Thus, we defer to the View's own ID.
329
								$post_id = $gravityview_view->getViewId();
330
							}
331
						}
332
					}
333
				}
334
			}
335
		}
336
337
		// No post ID, get outta here.
338 9
		if ( empty( $post_id ) ) {
339
			return null;
340 9
		}
341
342
		// If we've saved the permalink in memory, use it
343
		// @since 1.3
344
		$link = wp_cache_get( 'gv_directory_link_'.$post_id );
345
346
		if ( (int) $post_id === (int) get_option( 'page_on_front' ) ) {
347
			$link = home_url();
348
		}
349
350
		if ( empty( $link ) ) {
351
			$link = get_permalink( $post_id );
352
353
			// If not yet saved, cache the permalink.
354
			// @since 1.3
355
			wp_cache_set( 'gv_directory_link_'.$post_id, $link );
356 30
		}
357 30
358
		// Deal with returning to proper pagination for embedded views
359 30
		if ( $link && $add_query_args ) {
360
361 17
			$args = array();
362
363
			if( $pagenum = \GV\Utils::_GET( 'pagenum' ) ) {
364 17
				$args['pagenum'] = intval( $pagenum );
365
			}
366 14
367 3
			if( $sort = \GV\Utils::_GET( 'sort' ) ) {
368
				$args['sort'] = $sort;
369
				$args['dir'] = \GV\Utils::_GET( 'dir' );
370
			}
371 14
372
			$link = add_query_arg( $args, $link );
373
		}
374
375 3
		/**
376
		 * @filter `gravityview_directory_link` Modify the URL to the View "directory" context
377
		 * @since 1.19.4
378 3
		 * @param string $link URL to the View's "directory" context (Multiple Entries screen)
379 2
		 * @param int $post_id ID of the post to link to. If the View is embedded, it is the post or page ID
380
		 */
381
		$link = apply_filters( 'gravityview_directory_link', $link, $post_id );
382 1
383
		/**
384
		 * @filter `gravityview/view/links/directory` Modify the URL to the View "directory" context
385
		 * @since 2.0
386 1
		 * @param string $link URL to the View's "directory" context (Multiple Entries screen)
387
		 * @param \GV\Template_Context $context 
388 1
		 */
389
		return apply_filters( 'gravityview/view/links/directory', $link, $context );
390
	}
391
392
	/**
393
	 * Calculate an *unique* hash for an entry based on the entry ID
394
	 *
395
	 * This allows you to be more discrete as to the number of the entry - if you don't want users to know that you have made a certain number of sales, for example, or that their entry in the giveaway is entry #3.
396
	 *
397
	 * The hashed value MUST be unique, otherwise multiple entries will share the same URL, which leads to obvious problems.
398
	 *
399
	 * @param  int|string $id Entry ID to generate the hash for.
400 30
	 * @param  array  $entry        Entry data passed to provide additional information when generating the hash. Optional - don't rely on it being available.
401 1
	 * @return string               Hashed unique value for entry
402
	 */
403
	private static function get_custom_entry_slug( $id, $entry = array() ) {
404
405
		// Generate an unique hash to use as the default value
406 29
		$slug = substr( wp_hash( $id, 'gravityview'.$id ), 0, 8 );
407
408 29
		/**
409
		 * @filter `gravityview_entry_slug` Modify the unique hash ID generated, if you want to improve usability or change the format. This will allow for custom URLs, such as `{entryid}-{first-name}` or even, if unique, `{first-name}-{last-name}`
410
		 * @param string $hash Existing hash generated by GravityView
411
		 * @param  string $id The entry ID
412 29
		 * @param  array $entry Entry data array. May be empty.
413 29
		 */
414
		$slug = apply_filters( 'gravityview_entry_slug', $slug, $id, $entry );
415
416
		// Make sure we have something - use the original ID as backup.
417 29
		if( empty( $slug ) ) {
418
			$slug = $id;
419
		}
420
421 29
		return sanitize_title( $slug );
422
	}
423 24
424
	/**
425 24
	 * Get the entry slug for the entry. By default, it is the entry ID.
426 1
	 *
427
	 *
428
	 * @see gravityview_get_entry()
429 24
	 * @uses GravityView_API::get_custom_entry_slug() If using custom slug, gets the custom slug value
430
	 * @since 1.4
431
	 * @param  int|string $id_or_string ID of the entry, or custom slug string
432
	 * @param  array  $entry        Gravity Forms Entry array, optional. Used only to provide data to customize the `gravityview_entry_slug` filter
433
	 * @return string               Unique slug ID, passed through `sanitize_title()`
434 24
	 */
435
	public static function get_entry_slug( $id_or_string, $entry = array() ) {
436
437
		/**
438
		 * Default: use the entry ID as the unique identifier
439
		 */
440
		$slug = $id_or_string;
441
442
		/**
443 29
		 * @filter `gravityview_custom_entry_slug` Whether to enable and use custom entry slugs.
444
		 * @param boolean True: Allow for slugs based on entry values. False: always use entry IDs (default)
445
		 */
446
		$custom = apply_filters( 'gravityview_custom_entry_slug', false );
447
448
		// If we're using custom slug...
449
		if ( $custom ) {
450
451 29
			// Get the entry hash
452
			$hash = self::get_custom_entry_slug( $id_or_string, $entry );
453
454
			// Cache the slugs
455
			static $cache = array();
456
457
			if ( ! isset( $cache[ $id_or_string ] ) ) {
458
				global $wpdb;
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...
459
460
				if ( version_compare( GFFormsModel::get_database_version(), '2.3-dev-1', '>=' ) ) {
461
					$table = GFFormsModel::get_entry_meta_table_name();
462
					$column = 'entry_id';
463
				} else {
464
					$table = RGFormsModel::get_lead_meta_table_name();
465 3
					$column = 'lead_id';
466
				}
467
468 3
				$results = $wpdb->get_results( $wpdb->prepare( "SELECT $column, meta_value FROM $table WHERE form_id = (SELECT form_id FROM $table WHERE $column = %d LIMIT 1) AND meta_key = 'gravityview_unique_id'", $id_or_string ) );
0 ignored issues
show
introduced by
Usage of a direct database call is discouraged.
Loading history...
introduced by
Usage of a direct database call without caching is prohibited. Use wp_cache_get / wp_cache_set.
Loading history...
469
470
				if ( $results ) {
471
					$cache = array_replace( $cache, array_combine( wp_list_pluck( $results, $column ), wp_list_pluck( $results, 'meta_value' ) ) );
472
				}
473
474
				if ( ! isset( $cache[ $id_or_string ] ) ) {
475
					$cache[ $id_or_string ] = false;
476 3
				}
477
			}
478
479 3
			$value = $cache[ $id_or_string ];
480
481
			// If it does have a hash set, and the hash is expected, use it.
482
			// This check allows users to change the hash structure using the
483 3
			// gravityview_entry_hash filter and have the old hashes expire.
484
			if ( empty( $value ) || $value !== $hash ) {
485
				gravityview()->log->debug( 'Setting hash for entry {entry}: {hash}', array( 'entry' => $id_or_string, 'hash' => $hash ) );
486
				gform_update_meta( $id_or_string, 'gravityview_unique_id', $hash, \GV\Utils::get( $entry, 'form_id' ) );
487
			}
488
489
			$slug = $hash;
490
491
			unset( $value, $hash );
492
		}
493
494
		return sanitize_title( $slug );
495
	}
496
497 87
    /**
498
     * If using the entry custom slug feature, make sure the new entries have the custom slug created and saved as meta
499
     *
500
     * Triggered by add_action( 'gform_entry_created', array( 'GravityView_API', 'entry_create_custom_slug' ), 10, 2 );
501
     *
502 87
     * @param $entry array Gravity Forms entry object
503
     * @param $form array Gravity Forms form object
504
     */
505
    public static function entry_create_custom_slug( $entry, $form ) {
0 ignored issues
show
Unused Code introduced by
The parameter $form 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...
506
        /**
507
         * @filter `gravityview_custom_entry_slug` On entry creation, check if we are using the custom entry slug feature and update the meta
508 87
         * @param boolean $custom Should we process the custom entry slug?
509
         */
510
        $custom = apply_filters( 'gravityview_custom_entry_slug', false );
511 87
        if( $custom ) {
512
            // create the gravityview_unique_id and save it
513
514 3
            // Get the entry hash
515
            $hash = self::get_custom_entry_slug( $entry['id'], $entry );
516
517 3
	        gravityview()->log->debug( 'Setting hash for entry {entry_id}: {hash}', array( 'entry_id' => $entry['id'], 'hash' => $hash ) );
518
519 3
            gform_update_meta( $entry['id'], 'gravityview_unique_id', $hash, \GV\Utils::get( $entry, 'form_id' ) );
520 3
521
        }
522 3
    }
523 3
524 3
525
526
527
	/**
528
	 * return href for single entry
529
	 * @param  array|int $entry   Entry array or entry ID
530 3
	 * @param  int|null $post_id If wanting to define the parent post, pass a post ID
531
	 * @param boolean $add_directory_args True: Add args to help return to directory; False: only include args required to get to entry {@since 1.7.3}
532 3
	 * @return string          Link to the entry with the directory parent slug, or empty string if embedded post or View doesn't exist
533
	 */
534
	public static function entry_link( $entry, $post_id = NULL, $add_directory_args = true ) {
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
535
536 3
		if ( ! empty( $entry ) && ! is_array( $entry ) ) {
537 3
			$entry = GVCommon::get_entry( $entry );
538
		} else if( empty( $entry ) ) {
539
			// @deprecated path
540
			$entry = GravityView_frontend::getInstance()->getEntry();
541 3
		}
542
543
		// Second parameter used to be passed as $field; this makes sure it's not an array
544
		if ( ! is_numeric( $post_id ) ) {
545
			$post_id = NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
546 3
		}
547 3
548 3
		// Get the permalink to the View
549
		$directory_link = self::directory_link( $post_id, false );
550
551 3
		// No post ID? Get outta here.
552
		if ( empty( $directory_link ) ) {
553 3
			return '';
554
		}
555
556 87
		$query_arg_name = \GV\Entry::get_endpoint_name();
557
558
		$entry_slug = self::get_entry_slug( $entry['id'], $entry );
559
560
		if ( get_option('permalink_structure') && !is_preview() ) {
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...
introduced by
Expected 1 space after "!"; 0 found
Loading history...
561
562
			$args = array();
563
564
			/**
565
			 * Make sure the $directory_link doesn't contain any query otherwise it will break when adding the entry slug.
566
			 * @since 1.16.5
567
			 */
568
			$link_parts = explode( '?', $directory_link );
569
570
			$query = !empty( $link_parts[1] ) ? '?'.$link_parts[1] : '';
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
571
572
			$directory_link = trailingslashit( $link_parts[0] ) . $query_arg_name . '/'. $entry_slug .'/' . $query;
573
574
		} else {
575
576
			$args = array( $query_arg_name => $entry_slug );
577
		}
578
579
		/**
580
		 * @since 1.7.3
581
		 */
582
		if ( $add_directory_args ) {
583
584
			if ( ! empty( $_GET['pagenum'] ) ) {
585
				$args['pagenum'] = intval( $_GET['pagenum'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
586
			}
587
588
			/**
589
			 * @since 1.7
590
			 */
591
			if ( $sort = \GV\Utils::_GET( 'sort' ) ) {
592
				$args['sort'] = $sort;
593
				$args['dir'] = \GV\Utils::_GET( 'dir' );
594
			}
595
596 7
		}
597
598 7
		if ( class_exists( 'GravityView_View_Data' ) && GravityView_View_Data::getInstance()->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...
599
			$args['gvid'] = gravityview_get_view_id();
600 7
		}
601
602
		return add_query_arg( $args, $directory_link );
603
604
	}
605
606 7
607 1
}
608
609
610
// inside loop functions
611 7
612
/**
613
 * @deprecated Use \GV\Field::get_label()
614 7
 */
615 1
function gv_label( $field, $entry = NULL ) {
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
616
	return GravityView_API::field_label( $field, $entry );
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_API::field_label() has been deprecated with message: Use \GV\Field::get_label()

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

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

Loading history...
617
}
618 6
619
function gv_class( $field, $form = NULL, $entry = array() ) {
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
620 6
	return GravityView_API::field_class( $field, $form, $entry  );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 2 found
Loading history...
621
}
622 6
623
/**
624
 * Generate a CSS class to be added to the wrapper <div> of a View
625
 *
626
 * @since 1.5.4
627
 * @since 1.16 Added $echo parameter.
628
 * @since 2.0 Added $context parameter.
629
 *
630
 * @param string $passed_css_class Default: `gv-container gv-container-{view id}`. If View is hidden until search, adds ` hidden`
631
 * @param boolean $echo Whether to echo the output. Default: true
632
 * @param \GV\Template_Context $context The template context.
633
 *
634
 * @return string CSS class, sanitized by gravityview_sanitize_html_class()
635
 */
636
function gv_container_class( $passed_css_class = '', $echo = true, $context = null ) {
637
	if ( $context instanceof \GV\Template_Context ) {
638 6
		$hide_until_searched = false;
639
		$total_entries = 0;
640
		$view_id = 0;
641
		if ( $context->view ) {
642
			$view_id = $context->view->ID;
643
			if( $context->view->settings->get( 'hide_until_searched' ) ) {
644 6
				$hide_until_searched = ( empty( $context->entry ) && ! $context->request->is_search() );
645
			}
646 6
		}
647
		if ( $context->entries ) {
648
			$total_entries = $context->entries->total();
649
		} else if ( $context->entry ) {
650
			$total_entries = 1;
651
		}
652
	} else {
653 6
		/** @deprecated legacy execution path */
654
		$view_id = GravityView_View::getInstance()->getViewId();
655
		$hide_until_searched = GravityView_View::getInstance()->isHideUntilSearched();
656
		$total_entries = GravityView_View::getInstance()->getTotalEntries();
657
	}
658
659
	$passed_css_class = trim( $passed_css_class );
660 6
661
	$default_css_class = ! empty( $view_id ) ? sprintf( 'gv-container gv-container-%d', $view_id ) : 'gv-container';
662
663
	if ( $hide_until_searched ) {
664 6
		$default_css_class .= ' hidden';
665
	}
666
667
	if ( 0 === $total_entries ) {
668
		$default_css_class .= ' gv-container-no-results';
669
	}
670
671
	$css_class = trim( $passed_css_class . ' '. $default_css_class );
672
673
	/**
674
	 * @filter `gravityview/render/container/class` Modify the CSS class to be added to the wrapper <div> of a View
675
	 * @since 1.5.4
676
	 * @param[in,out] string $css_class Default: `gv-container gv-container-{view id}`. If View is hidden until search, adds ` hidden`. If the View has no results, adds `gv-container-no-results`
677
	 * @since 2.0
678 2
	 * @param \GV\Template_Context $context The context.
679
	 */
680
	$css_class = apply_filters( 'gravityview/render/container/class', $css_class, $context );
681
682 31
	$css_class = gravityview_sanitize_html_class( $css_class );
683
684
	if ( $echo ) {
685
		echo $css_class;
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$css_class'
Loading history...
686
	}
687
688
	return $css_class;
689
}
690
691
/**
692
 * @deprecated Use \GV\Field_Template::render()
693
 */
694
function gv_value( $entry, $field ) {
695
696
	$value = GravityView_API::field_value( $entry, $field );
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_API::field_value() has been deprecated with message: Use \GV\Field_Template::render() or the more low-level \GV\Field::get_value()

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

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

Loading history...
697
698
	if( $value === '' ) {
699 32
		/**
700 30
		 * @filter `gravityview_empty_value` What to display when a field is empty
701 30
		 * @param string $value (empty string)
702 30
		 */
703 30
		$value = apply_filters( 'gravityview_empty_value', '' );
704 30
	}
705 30
706 4
	return $value;
707
}
708
709 30
function gv_directory_link( $post = NULL, $add_pagination = true, $context = null ) {
0 ignored issues
show
introduced by
Overridding WordPress globals is prohibited
Loading history...
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
710 18
	return GravityView_API::directory_link( $post, $add_pagination, $context );
711 14
}
712 30
713
function gv_entry_link( $entry, $post_id = NULL ) {
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
714
	return GravityView_API::entry_link( $entry, $post_id );
715
}
716 3
717 3
function gv_no_results( $wpautop = true, $context = null ) {
718 3
	return GravityView_API::no_results( $wpautop, $context );
719
}
720
721 32
/**
722
 * Generate HTML for the back link from single entry view
723 32
 * @since 1.0.1
724
 * @since 2.0
725 32
 * @param \GV\Template_Context $context The context this link is being displayed from.
726 4
 * @return string|null      If no GV post exists, null. Otherwise, HTML string of back link.
727
 */
728
function gravityview_back_link( $context = null ) {
729 32
730 7
	$href = gv_directory_link( null, true, $context );
731
732
	/**
733 32
	 * @filter `gravityview_go_back_url` Modify the back link URL
734
	 * @since 1.17.5
735
	 * @see gv_directory_link() Generated the original back link
736
	 * @param string $href Existing label URL
737
	 * @deprecated Use `gravityview/template/links/back/url`
738
	 */
739
	$href = apply_filters( 'gravityview_go_back_url', $href );
740
741
	/**
742 32
	 * @filter `gravityview/template/links/back/url` Modify the back link URL
743
	 * @since 2.0
744 32
	 * @see gv_directory_link() Generated the original back link
745
	 * @param string $href Existing label URL
746 32
	 * @param \GV\Template_Context The context.
747 32
	 */
748
	$href = apply_filters( 'gravityview/template/links/back/url', $href, $context );
749
750 32
	if ( empty( $href ) ) {
751
		return NULL;
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
752
	}
753
754
	if ( $context instanceof \GV\Template_Context ) {
755
		$view_id = $context->view->ID;
756
		$view_label = $context->template->get_back_label();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class GV\Template as the method get_back_label() does only exist in the following sub-classes of GV\Template: GV\Entry_Legacy_Template, GV\Entry_List_Template, GV\Entry_Table_Template, GV\Entry_Template. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
757
	} else {
758 2
		/** @deprecated legacy path */
759
		$gravityview_view = GravityView_View::getInstance();
760 2
		$view_id = $gravityview_view->getViewId();
761
		$view_label = $gravityview_view->getBackLinkLabel() ? $gravityview_view->getBackLinkLabel() : false;
0 ignored issues
show
Deprecated Code introduced by
The method GravityView_View::getBackLinkLabel() has been deprecated with message: Use $template->get_back_label();

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

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

Loading history...
762
	}
763
764
	/** Default */
765 1
	$label = $view_label ? $view_label : __( '&larr; Go back', 'gravityview' );
766
767
	/**
768 2
	 * @filter `gravityview_go_back_label` Modify the back link text
769
	 * @since 1.0.9
770
	 * @param string $label Existing label text
771
	 * @deprecated Use `gravityview/template/links/back/label`
772 15
	 */
773
	$label = apply_filters( 'gravityview_go_back_label', $label );
774
775
	/**
776 2
	 * @filter `gravityview/template/links/back/label` Modify the back link text
777
	 * @since 2.0
778
	 * @see gv_directory_link() Generated the original back link
779
	 * @param string $label Existing label text
780 8
	 * @param \GV\Template_Context The context.
781
	 */
782
	$label = apply_filters( 'gravityview/template/links/back/label', $label, $context );
783
784
	/**
785
	 * @filter `gravityview/template/links/back/atts` Modify the attributes used on the back link anchor tag
786
	 * @since 2.1
787
	 * @param array $atts Original attributes, default: [ data-viewid => $view_id ]
788
	 * @param \GV\Template_Context The context.
789
	 */
790
	$atts = apply_filters( 'gravityview/template/links/back/atts', array( 'data-viewid' => $view_id ), $context );
791
792 14
	$link = gravityview_get_link( $href, esc_html( $label ), $atts );
793
794
	return $link;
795
}
796
797
/**
798
 * Handle getting values for complex Gravity Forms fields
799
 *
800
 * If the field is complex, like a product, the field ID, for example, 11, won't exist. Instead,
801 14
 * it will be 11.1, 11.2, and 11.3. This handles being passed 11 and 11.2 with the same function.
802
 *
803
 * @since 1.0.4
804
 * @param  array      $entry    GF entry array
805
 * @param  string      $field_id [description]
806
 * @param  string 	$display_value The value generated by Gravity Forms
807
 * @return string                Value
808
 */
809
function gravityview_get_field_value( $entry, $field_id, $display_value ) {
810 14
811
	if( floatval( $field_id ) === floor( floatval( $field_id ) ) ) {
812 14
813 3
		// For the complete field value as generated by Gravity Forms
814
		return $display_value;
815
816 12
	} else {
817 12
818 12
		// For one part of the address (City, ZIP, etc.)
819
		return isset( $entry[ $field_id ] ) ? $entry[ $field_id ] : '';
820
821
	}
822
823
}
824
825
/**
826
 * Take a passed CSV of terms and generate a linked list of terms
827 12
 *
828
 * Gravity Forms passes categories as "Name:ID" so we handle that using the ID, which
829
 * is more accurate than checking the name, which is more likely to change.
830
 *
831
 * @param  string      $value    Existing value
832
 * @param  string      $taxonomy Type of term (`post_tag` or `category`)
833
 * @return string                CSV of linked terms
834
 */
835 12
function gravityview_convert_value_to_term_list( $value, $taxonomy = 'post_tag' ) {
836
837
	$output = array();
838
839
	if ( is_array( $value ) ) {
840
		$terms = array_filter( array_values( $value ), 'strlen' );
841
	} else {
842
		$terms = explode( ', ', $value );
843
	}
844 12
845
	foreach ($terms as $term_name ) {
0 ignored issues
show
introduced by
No space after opening parenthesis is prohibited
Loading history...
846
847
		// If we're processing a category,
848
		if( $taxonomy === 'category' ) {
0 ignored issues
show
introduced by
Found "=== '". Use Yoda Condition checks, you must
Loading history...
849
850
			// Use rgexplode to prevent errors if : doesn't exist
851
			list( $term_name, $term_id ) = rgexplode( ':', $term_name, 2 );
852 12
853
			// The explode was succesful; we have the category ID
854 12
			if( !empty( $term_id )) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
introduced by
No space before closing parenthesis is prohibited
Loading history...
855
				$term = get_term_by( 'id', $term_id, $taxonomy );
856 12
			} else {
857
			// We have to fall back to the name
858
				$term = get_term_by( 'name', $term_name, $taxonomy );
859
			}
860
861
		} else {
862
			// Use the name of the tag to get the full term information
863
			$term = get_term_by( 'name', $term_name, $taxonomy );
864
		}
865
866
		// There's still a tag/category here.
867
		if( $term ) {
868
869
			$term_link = get_term_link( $term, $taxonomy );
870
871
			// If there was an error, continue to the next term.
872
			if ( is_wp_error( $term_link ) ) {
873 9
			    continue;
874
			}
875
876 6
			$output[] = gravityview_get_link( $term_link, esc_html( $term->name ) );
877
		}
878
	}
879
880
	return implode(', ', $output );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
881 7
}
882
883
/**
884
 * Get the links for post_tags and post_category output based on post ID
885
 * @param  int      $post_id  The ID of the post
886
 * @param  boolean     $link     Add links or no?
887
 * @param  string      $taxonomy Taxonomy of term to fetch.
888
 * @return string                String with terms
889
 */
890
function gravityview_get_the_term_list( $post_id, $link = true, $taxonomy = 'post_tag' ) {
891
892
	$output = get_the_term_list( $post_id, $taxonomy, NULL, ', ' );
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
893
894
	if( empty( $link ) ) {
895
		return strip_tags( $output);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
896
	}
897
898
	return $output;
899 1
900
}
901 1
902 1
903
/**
904 1
 * Get all views processed so far for the current page load
905
 *
906
 * @see  GravityView_View_Data::add_view()
907 1
 * @return array Array of View data, each View data with `id`, `view_id`, `form_id`, `template_id`, `atts`, `fields`, `widgets`, `form` keys.
908
 */
909
function gravityview_get_current_views() {
910 1
911
	$fe = GravityView_frontend::getInstance();
912
913 1
	// Solve problem when loading content via admin-ajax.php
914
	if( ! $fe->getGvOutputData() ) {
915
916 1
		gravityview()->log->debug( 'gv_output_data not defined; parsing content.' );
917 1
918
		$fe->parse_content();
919
	}
920 1
921
	// Make 100% sure that we're dealing with a properly called situation
922
	if( !is_a( $fe->getGvOutputData(), 'GravityView_View_Data' ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
923
924
		gravityview()->log->debug( 'gv_output_data not an object or get_view not callable.', array( 'data' => $fe->getGvOutputData() ) );
925 1
926
		return array();
927
	}
928
929 1
	return $fe->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...
930
}
931 1
932
/**
933
 * Get data for a specific view
934 1
 *
935
 * @see  GravityView_View_Data::get_view()
936
 * @return array View data with `id`, `view_id`, `form_id`, `template_id`, `atts`, `fields`, `widgets`, `form` keys.
937
 */
938 1
function gravityview_get_current_view_data( $view_id = 0 ) {
939
940
	$fe = GravityView_frontend::getInstance();
941
942 1
	// If not set, grab the current view ID
943
	if ( empty( $view_id ) ) {
944
		$view_id = $fe->get_context_view_id();
945
	}
946
947
	if ( ! $fe->getGvOutputData() ) { return array(); }
948
949
	return $fe->getGvOutputData()->get_view( $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...
950
}
951
952
// Templates' hooks
953
function gravityview_before() {
954 1
	/**
955
	 * @action `gravityview/template/before` Append content to the view.
956 1
	 * @param object $gravityview The $gravityview object available in templates.
957 1
	 */
958
	if ( count( $args = func_get_args() ) ) {
959
		$gravityview = reset( $args );
960 1
		if ( $gravityview instanceof \GV\Template_Context ) {
961
			/**
962
			 * @action `gravityview/template/before` Prepend content to the view.
963
			 * @param \GV\Template_Context $gravityview The $gravityview object available in templates.
964
			 */
965
			do_action( 'gravityview/template/before', $gravityview );
966
967
			/**
968
			 * @deprecated Use `gravityview/template/before`
969
			 */
970
			return do_action( 'gravityview_before', $gravityview->view->ID );
971
		}
972
	}
973 1
974
	/**
975
	 * @action `gravityview_before` Prepend content to the View container `<div>`
976 1
	 * @deprecated Use `gravityview/template/before`.
977
	 * @param int $view_id The ID of the View being displayed
978 1
	 */
979
	do_action( 'gravityview_before', gravityview_get_view_id() );
980 1
}
981
982
function gravityview_header() {
983
	/**
984 1
	 * @action `gravityview/template/header` Append content to the view.
985
	 * @param object $gravityview The $gravityview object available in templates.
986
	 */
987
	if ( count( $args = func_get_args() ) ) {
988
		$gravityview = reset( $args );
989
		if ( $gravityview instanceof \GV\Template_Context ) {
990
			/**
991 1
			 * @action `gravityview/template/header` Prepend content to the view container <div>.
992
			 * @param \GV\Template_Context $gravityview The $gravityview object available in templates.
993
			 */
994
			do_action( 'gravityview/template/header', $gravityview );
995
996
			/**
997
			 * @deprecated Use `gravityview/template/header`
998
			 */
999
			return do_action( 'gravityview_header', $gravityview->view->ID );
1000
		}
1001
	}
1002
1003
	/**
1004
	 * @action `gravityview_header` Prepend content to the View container `<div>`
1005
	 * @deprecated Use `gravityview/template/header`.
1006
	 * @param int $view_id The ID of the View being displayed
1007
	 */
1008
	do_action( 'gravityview_header', gravityview_get_view_id() );
1009
}
1010
1011
function gravityview_footer() {
1012
	/**
1013
	 * @action `gravityview/template/footer` Append content to the view.
1014
	 * @param object $gravityview The $gravityview object available in templates.
1015
	 */
1016
	if ( count( $args = func_get_args() ) ) {
1017
		$gravityview = reset( $args );
1018
		if ( $gravityview instanceof \GV\Template_Context ) {
1019
			/**
1020 31
			 * @action `gravityview/template/footer` Prepend outside of the view container <div>.
1021 29
			 * @param \GV\Template_Context $gravityview The $gravityview object available in templates.
1022 29
			 */
1023
			do_action( 'gravityview/template/footer', $gravityview );
1024
1025
			/**
1026
			 * @deprecated Use `gravityview/template/footer`
1027 29
			 */
1028
			return do_action( 'gravityview_footer', $gravityview->view->ID );
1029
		}
1030
	}
1031
1032 29
	/**
1033
	 * @action `gravityview_after` Display content after a View. Used to render footer widget areas. Rendered outside the View container `<div>`
1034
	 * @deprecated Use `gravityview/template/footer`.
1035
	 * @param int $view_id The ID of the View being displayed
1036
	 */
1037
	do_action( 'gravityview_footer', gravityview_get_view_id() );
1038
}
1039
1040
function gravityview_after() {
1041 2
	if ( count( $args = func_get_args() ) ) {
1042 2
		$gravityview = reset( $args );
1043
		if ( $gravityview instanceof \GV\Template_Context ) {
1044
			/**
1045
			 * @action `gravityview/template/after` Append content to the view.
1046
			 * @param \GV\Template_Context $gravityview The $gravityview object available in templates.
1047
			 */
1048
			do_action( 'gravityview/template/after', $gravityview );
1049 27
1050 25
			/**
1051 25
			 * @deprecated Use `gravityview/template/after`
1052
			 */
1053
			do_action( 'gravityview_after', $gravityview->view->ID );
1054
1055
			return;
1056 25
		}
1057
	}
1058
1059
	/**
1060
	 * @action `gravityview_after` Append content to the View container `<div>`
1061 25
	 * @deprecated Use `gravityview/template/after`
1062
	 * @param int $view_id The ID of the View being displayed
1063
	 */
1064
	do_action( 'gravityview_after', gravityview_get_view_id() );
1065
}
1066
1067
/**
1068
 * Get the current View ID being rendered
1069
 *
1070 2
 * @global GravityView_View $gravityview_view
1071 2
 *
1072
 * @return int View ID, if exists. `0` if `GravityView_View` doesn't exist, like in the admin, or no View is set.
1073
 */
1074
function gravityview_get_view_id() {
1075
1076
	if ( ! class_exists( 'GravityView_View' ) ) {
1077
		return 0;
1078 27
	}
1079 25
1080 25
	return GravityView_View::getInstance()->getViewId();
1081
}
1082
1083
/**
1084
 * Returns the current GravityView context, or empty string if not GravityView
1085 25
 *
1086
 * - Returns empty string on GravityView archive pages
1087
 * - Returns empty string on archive pages containing embedded Views
1088
 * - Returns empty string for embedded Views, not 'directory'
1089
 * - Returns empty string for embedded entries (oEmbed or [gventry]), not 'single'
1090 25
 * - Returns 'single' when viewing a [gravityview] shortcode-embedded single entry
1091
 *
1092
 * @global GravityView_View $gravityview_view
1093
 * @deprecated since 2.0.6.2 Use `gravityview()->request`
1094
 * @return string View context "directory", "single", "edit", or empty string if not GravityView
1095
 */
1096
function gravityview_get_context() {
1097
	global $wp_query;
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...
1098
1099 2
	if ( isset( $wp_query ) && $wp_query->post_count > 1 ) {
1100 2
		return '';
1101
	}
1102
1103 31
	/**
1104 29
	 * @filter `gravityview_is_edit_entry` Whether we're currently on the Edit Entry screen \n
1105 29
	 * The Edit Entry functionality overrides this value.
1106
	 * @param boolean $is_edit_entry
1107
	 */
1108
	$is_edit_entry = apply_filters( 'gravityview_is_edit_entry', false );
1109
1110 29
	if ( $is_edit_entry ) {
1111
		return 'edit';
1112
	} else if ( gravityview()->request->is_entry() ) {
1113
		return 'single';
1114
	} else if ( gravityview()->request->is_view() ) {
1115 29
		return 'directory';
1116
	}
1117 29
1118
	return '';
1119
}
1120
1121
1122
/**
1123
 * Return an array of files prepared for output. Wrapper for GravityView_Field_FileUpload::get_files_array()
1124
 *
1125
 * Processes files by file type and generates unique output for each.
1126 2
 *
1127 2
 * Returns array for each file, with the following keys:
1128
 *
1129
 * `file_path` => The file path of the file, with a line break
1130
 * `html` => The file output HTML formatted
1131
 *
1132
 * @see GravityView_Field_FileUpload::get_files_array()
1133
 *
1134
 * @since  1.2
1135
 * @param  string $value    Field value passed by Gravity Forms. String of file URL, or serialized string of file URL array
1136
 * @param  string $gv_class Field class to add to the output HTML
1137
 * @since  2.0
1138 2
 * @param  \GV\Template_Context $context The context
1139
 * @return array           Array of file output, with `file_path` and `html` keys (see comments above)
1140
 */
1141
function gravityview_get_files_array( $value, $gv_class = '', $context = null ) {
1142 2
	/** @define "GRAVITYVIEW_DIR" "../" */
1143
1144
	if( !class_exists( 'GravityView_Field' ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1145
		include_once( GRAVITYVIEW_DIR .'includes/fields/class-gravityview-field.php' );
1146
	}
1147
1148
	if( !class_exists( 'GravityView_Field_FileUpload' ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
1149
		include_once( GRAVITYVIEW_DIR .'includes/fields/class-gravityview-field-fileupload.php' );
1150
	}
1151
1152
	if ( is_null( $context ) ) {
1153
		_doing_it_wrong( __FUNCTION__, '2.0', 'Please pass an \GV\Template_Context object as the 3rd parameter' );
1154
	}
1155
1156
	return GravityView_Field_FileUpload::get_files_array( $value, $gv_class, $context );
1157
}
1158
1159 4
/**
1160
 * Generate a mapping link from an address
1161 4
 *
1162
 * The address should be plain text with new line (`\n`) or `<br />` line breaks separating sections
1163
 *
1164
 * @todo use GF's field get_export_value() instead
1165
 *
1166
 * @see https://gravityview.co/support/documentation/201608159 Read how to modify the link
1167
 * @param  string $address Address
1168
 * @return string          URL of link to map of address
1169
 */
1170 4
function gravityview_get_map_link( $address ) {
1171
1172 4
	$address_qs = str_replace( array( '<br />', "\n" ), ' ', $address ); // Replace \n with spaces
1173
	$address_qs = urlencode( $address_qs );
1174 4
1175 1
	$url = "https://maps.google.com/maps?q={$address_qs}";
1176 3
1177 2
	$link_text = esc_html__( 'Map It', 'gravityview' );
1178
1179
	$link = gravityview_get_link( $url, $link_text, 'class=map-it-link' );
1180 1
1181
	/**
1182
	 * @filter `gravityview_map_link` Modify the map link generated. You can use a different mapping service, for example.
1183
	 * @param[in,out]  string $link Map link
1184
	 * @param[in] string $address Address to generate link for
1185
	 * @param[in] string $url URL generated by the function
1186
	 */
1187
	$link = apply_filters( 'gravityview_map_link', $link, $address, $url );
1188
1189
	return $link;
1190
}
1191
1192
1193
/**
1194
 * Output field based on a certain html markup
1195
 *
1196
 *   markup - string to be used on a sprintf statement.
1197
 *      Use:
1198
 *         {{label}} - field label
1199
 *         {{value}} - entry field value
1200
 *         {{class}} - field class
1201
 *
1202
 *   wpautop - true will filter the value using wpautop function
1203
 *
1204
 * @since  1.1.5
1205
 * @param  array $passed_args Associative array with field data. `field` and `form` are required.
1206 3
 * @since  2.0
1207
 * @param  \GV\Template_Context The template context.
1208
 * @return string Field output. If empty value and hide empty is true, return empty.
1209
 */
1210 3
function gravityview_field_output( $passed_args, $context = null ) {
1211
	$defaults = array(
1212
		'entry' => null,
1213
		'field' => null,
1214 3
		'form' => null,
1215
		'hide_empty' => true,
1216
		'markup' => '<div id="{{ field_id }}" class="{{ class }}">{{ label }}{{ value }}</div>',
1217
		'label_markup' => '',
1218 3
		'wpautop' => false,
1219
		'zone_id' => null,
1220
	);
1221
1222
	$args = wp_parse_args( $passed_args, $defaults );
1223
1224
	/**
1225
	 * @filter `gravityview/field_output/args` Modify the args before generation begins
1226
	 * @since 1.7
1227
	 * @param array $args Associative array; `field` and `form` is required.
1228
	 * @param array $passed_args Original associative array with field data. `field` and `form` are required.
1229
	 * @since 2.0
1230
	 * @param \GV\Template_Context $context The context.
1231
	 * @deprecated
1232
	 */
1233
	$args = apply_filters( 'gravityview/field_output/args', $args, $passed_args, $context );
1234
1235
	/**
1236
	 * @filter `gravityview/template/field_output/context` Modify the context before generation begins.
1237
	 * @since 2.0
1238
	 * @param[in,out] \GV\Template_Context $context The context.
1239
	 * @param array $args The sanitized arguments, these should not be trusted any longer.
1240
	 * @param array $passed_args The passed arguments, these should not be trusted any longer.
1241
	 */
1242
	$context = apply_filters( 'gravityview/template/field_output/context', $context, $args, $passed_args );
1243
1244
	if ( $context instanceof \GV\Template_Context ) {
1245
		if ( ! $context->field || ! $context->view || ! $context->view->form ) {
1246
			gravityview()->log->error( 'Field or form are empty.', array( 'data' => array( $context->field, $context->view->form ) ) );
1247
			return '';
1248
		}
1249
	} else {
1250
		// @deprecated path
1251
		// Required fields.
1252
		if ( empty( $args['field'] ) || empty( $args['form'] ) ) {
1253
			gravityview()->log->error( 'Field or form are empty.', array( 'data' => $args ) );
1254
			return '';
1255
		}
1256
	}
1257
1258
	if ( $context instanceof \GV\Template_Context ) {
1259
		$entry = $args['entry'] ? : ( $context->entry ? $context->entry->as_entry() : array() );
1260
		$field = $args['field'] ? : ( $context->field ? $context->field->as_configuration() : array() );
1261
		$form = $args['form'] ? : ( $context->view->form ? $context->view->form->form : array() );
0 ignored issues
show
Documentation introduced by
The property $form is declared private in GV\Form. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write 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.");
        }
    }

}

Since the property has write access only, you can use the @property-write 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...
1262
	} else {
1263
		// @deprecated path
1264
		$entry = empty( $args['entry'] ) ? array() : $args['entry'];
1265
		$field = $args['field'];
1266
		$form = $args['form'];
1267
	}
1268
1269
	/**
1270
	 * Create the content variables for replacing.
1271
	 * @since 1.11
1272
	 */
1273
	$placeholders = array(
1274 28
		'value' => '',
1275
		'width' => '',
1276
		'width:style' => '',
1277
		'label' => '',
1278
		'label_value' => '',
1279
		'label_value:esc_attr' => '',
1280
		'label_value:data-label' => '',
1281
		'class' => '',
1282
		'field_id' => '',
1283
	);
1284 28
1285
	if ( $context instanceof \GV\Template_Context ) {
1286
		$placeholders['value'] = \GV\Utils::get( $args, 'value', '' );
1287
	} else {
1288
		// @deprecated path
1289
		$placeholders['value'] = gv_value( $entry, $field );
0 ignored issues
show
Deprecated Code introduced by
The function gv_value() has been deprecated with message: Use \GV\Field_Template::render()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
1290
	}
1291
1292
	// If the value is empty and we're hiding empty, return empty.
1293
	if ( $placeholders['value'] === '' && ! empty( $args['hide_empty'] ) ) {
1294
		return '';
1295 28
	}
1296
1297
	if ( $placeholders['value'] !== '' && ! empty( $args['wpautop'] ) ) {
1298
		$placeholders['value'] = wpautop( $placeholders['value'] );
1299
	}
1300
1301
	// Get width setting, if exists
1302
	$placeholders['width'] = GravityView_API::field_width( $field );
1303
1304 28
	// If replacing with CSS inline formatting, let's do it.
1305
	$placeholders['width:style'] = GravityView_API::field_width( $field, 'width:' . $placeholders['width'] . '%;' );
1306 28
1307 26
	// Grab the Class using `gv_class`
1308
	$placeholders['class'] = gv_class( $field, $form, $entry );
1309 26
	$placeholders['field_id'] = GravityView_API::field_html_attr_id( $field, $form, $entry );
1310
1311
	if ( $context instanceof \GV\Template_Context ) {
1312
		$placeholders['label_value'] = \GV\Utils::get( $args, 'label' );
1313
	} else {
1314 2
		// Default Label value
1315
		$placeholders['label_value'] = gv_label( $field, $entry );
0 ignored issues
show
Deprecated Code introduced by
The function gv_label() has been deprecated with message: Use \GV\Field::get_label()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
1316
	}
1317
1318
	$placeholders['label_value:data-label'] = trim( esc_attr( strip_tags( str_replace( '>&nbsp;', '>', $placeholders['label_value'] ) ) ) );
1319
	$placeholders['label_value:esc_attr'] = esc_attr( $placeholders['label_value'] );
1320 28
1321 26
	if ( empty( $placeholders['label'] ) && ! empty( $placeholders['label_value'] ) ){
1322 26
		$placeholders['label'] = '<span class="gv-field-label">{{ label_value }}</span>';
1323 26
	}
1324
1325
	/**
1326 2
	 * @filter `gravityview/field_output/pre_html` Allow Pre filtering of the HTML
1327 2
	 * @since 1.11
1328 2
	 * @param string $markup The HTML for the markup
1329
	 * @param array $args All args for the field output
1330
	 * @since 2.0
1331
	 * @param \GV\Template_Context $context The context.
1332
	 */
1333
	$html = apply_filters( 'gravityview/field_output/pre_html', $args['markup'], $args, $context );
1334
1335
	/**
1336 28
	 * @filter `gravityview/field_output/open_tag` Modify the opening tags for the template content placeholders
1337
	 * @since 1.11
1338
	 * @param string $open_tag Open tag for template content placeholders. Default: `{{`
1339
	 * @since 2.0
1340
	 * @param \GV\Template_Context $context The context.
1341
	 */
1342
	$open_tag = apply_filters( 'gravityview/field_output/open_tag', '{{', $args, $context );
1343
1344
	/**
1345
	 * @filter `gravityview/field_output/close_tag` Modify the closing tags for the template content placeholders
1346
	 * @since 1.11
1347 28
	 * @param string $close_tag Close tag for template content placeholders. Default: `}}`
1348 26
	 * @since 2.0
1349
	 * @param \GV\Template_Context $context The context.
1350
	 */
1351 2
	$close_tag = apply_filters( 'gravityview/field_output/close_tag', '}}', $args, $context );
1352
1353
	/**
1354
	 * Loop through each of the tags to replace and replace both `{{tag}}` and `{{ tag }}` with the values
1355 28
	 * @since 1.11
1356 5
	 */
1357
	foreach ( $placeholders as $tag => $value ) {
1358
1359 28
		// If the tag doesn't exist just skip it
1360 5
		if ( false === strpos( $html, $open_tag . $tag . $close_tag ) && false === strpos( $html, $open_tag . ' ' . $tag . ' ' . $close_tag ) ){
1361
			continue;
1362
		}
1363
1364 28
		// Array to search
1365
		$search = array(
1366
			$open_tag . $tag . $close_tag,
1367 28
			$open_tag . ' ' . $tag . ' ' . $close_tag,
1368
		);
1369
1370 28
		/**
1371 28
		 * `gravityview/field_output/context/{$tag}` Allow users to filter content on context
1372
		 * @since 1.11
1373 28
		 * @param string $value The content to be shown instead of the {{tag}} placeholder
1374 26
		 * @param array $args Arguments passed to the function
1375
		 * @since 2.0
1376
		 * @param \GV\Template_Context $context The context.
1377 2
		 */
1378
		$value = apply_filters( 'gravityview/field_output/context/' . $tag, $value, $args, $context );
1379
1380 28
		// Finally do the replace
1381 28
		$html = str_replace( $search, $value, $html );
1382
	}
1383 28
1384 28
	/**
1385
	 * @filter `gravityview_field_output` Modify field HTML output
1386
	 * @param string $html Existing HTML output
1387
	 * @param array $args Arguments passed to the function
1388
	 * @since 2.0
1389
	 * @param \GV\Template_Context $context The context.
1390
	 */
1391
	$html = apply_filters( 'gravityview_field_output', $html, $args, $context );
1392
1393
	/**
1394
	 * @filter `gravityview/field_output/html` Modify field HTML output
1395 28
	 * @param string $html Existing HTML output
1396
	 * @param array $args Arguments passed to the function
1397
	 * @since 2.0
1398
	 * @param \GV\Template_Context $context The context.
1399
	 */
1400
	$html = apply_filters( 'gravityview/field_output/html', $html, $args, $context );
1401
1402
	/** @since 2.0.8 Remove unused atts */
1403
	$html = str_replace( array( ' style=""', ' class=""', ' id=""' ), '', $html );
1404 28
1405
	return $html;
1406
}
1407