Completed
Push — develop ( bd6ad5...7b688d )
by Zack
04:29
created

GravityView_Field::__construct()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 10

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 23
rs 8.7972
cc 4
eloc 10
nc 4
nop 0
1
<?php
2
/**
3
 * @file class-gravityview-field.php
4
 * @package GravityView
5
 * @subpackage includes\fields
6
 */
7
8
/**
9
 * Modify field settings by extending this class.
10
 */
11
abstract class GravityView_Field {
12
13
	/**
14
	 * The name of the GravityView field type
15
	 * Example: `created_by`, `text`, `fileupload`, `address`, `entry_link`
16
	 * @var string
17
	 */
18
	var $name;
19
20
	/**
21
	 * @internal Not yet implemented
22
	 * @since 1.15.2
23
	 * @type string The description of the field in the field picker
24
	 */
25
	var $description;
26
27
	/**
28
	 * @since 1.15.2
29
	 * @type string The label of the field in the field picker
30
	 */
31
	var $label;
32
33
	/**
34
	 * `standard`, `advanced`, `post`, `pricing`, `meta`, `gravityview`
35
	 * @internal Not yet implemented
36
	 * @since 1.15.2
37
	 * @type string The group belongs to this field in the field picker
38
	 */
39
	var $group;
40
41
	/**
42
	 * @internal Not yet implemented
43
	 * @type boolean Can the field be searched?
44
	 * @since 1.15.2
45
	 */
46
	var $is_searchable;
47
48
	/**
49
	 * @internal Not yet implemented
50
	 * @type array $search_operators The type of search operators available for this field
51
	 * @since 1.15.2
52
	 */
53
	var $search_operators;
54
55
	/**
56
	 * @type boolean Can the field be sorted in search?
57
	 * @since 1.15.2
58
	 */
59
	var $is_sortable = true;
60
61
	/**
62
	 * @type boolean Is field content number-based?
63
	 * @since 1.15.2
64
	 */
65
	var $is_numeric;
66
67
	/**
68
	 * @internal Not yet implemented
69
	 * @todo implement supports_context() method
70
	 * The contexts in which a field is available. Some fields aren't editable, for example.
71
	 * - `singular` is an alias for both `single` and `edit`
72
	 * - `multiple` is an alias for `directory` (backward compatibility)
73
	 * @type array
74
	 * @since 1.15.2
75
	 */
76
	var $contexts = array( 'single', 'multiple', 'edit', 'export' );
77
78
	/**
79
	 * @internal Not yet implemented
80
	 * @since 1.15.2
81
	 * @type string The name of a corresponding Gravity Forms GF_Field class, if exists
82
	 */
83
	protected $_gf_field_class_name;
84
85
	/**
86
	 * @var string The field ID being requested
87
	 * @since 1.14
88
	 */
89
	protected $_field_id = '';
90
91
	/**
92
	 * @var string Field options to be rendered
93
	 * @since 1.14
94
	 */
95
	protected $_field_options = array();
96
97
	/**
98
	 * @var bool|string Name of merge tag (without curly brackets), if the field has custom GravityView merge tags to add. Otherwise, false.
99
	 * @since 1.16
100
	 */
101
	protected $_custom_merge_tag = false;
102
103
	function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

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

Loading history...
104
105
		/**
106
		 * If this is a Gravity Forms field, use their labels. Spare our translation team!
107
		 */
108
		if( ! empty( $this->_gf_field_class_name ) && class_exists( $this->_gf_field_class_name ) ) {
109
			/** @var GF_Field $GF_Field */
110
			$GF_Field = new $this->_gf_field_class_name;
111
			$this->label = $GF_Field->get_form_editor_field_title();
112
		}
113
114
		// Modify the field options based on the name of the field type
115
		add_filter( sprintf( 'gravityview_template_%s_options', $this->name ), array( &$this, 'field_options' ), 10, 5 );
116
117
		add_filter( 'gravityview/sortable/field_blacklist', array( $this, '_filter_sortable_fields' ), 1 );
118
119
		if( $this->_custom_merge_tag ) {
120
			add_filter( 'gform_custom_merge_tags', array( $this, '_filter_gform_custom_merge_tags' ), 10, 4 );
121
			add_filter( 'gform_replace_merge_tags', array( $this, '_filter_gform_replace_merge_tags' ), 10, 7 );
122
		}
123
124
		GravityView_Fields::register( $this );
125
	}
126
127
	/**
128
	 * Match the merge tag in replacement text for the field.  DO NOT OVERRIDE.
129
	 *
130
	 * @see replace_merge_tag Override replace_merge_tag() to handle any matches
131
	 *
132
	 * @since 1.16
133
	 *
134
	 * @param string $text Text to replace
135
	 * @param array $form Gravity Forms form array
136
	 * @param array $entry Entry array
137
	 * @param bool $url_encode Whether to URL-encode output
138
	 *
139
	 * @return string Original text if {_custom_merge_tag} isn't found. Otherwise, replaced text.
140
	 */
141
	public function _filter_gform_replace_merge_tags( $text, $form = array(), $entry = array(), $url_encode = false, $esc_html = false  ) {
142
143
		/**
144
		 * This prevents the gform_replace_merge_tags filter from being called twice, as defined in:
145
		 * @see GFCommon::replace_variables()
146
		 * @see GFCommon::replace_variables_prepopulate()
147
		 * @todo Remove eventually: Gravity Forms fixed this issue in 1.9.14
148
		 */
149
		if( false === $form ) {
150
			return $text;
151
		}
152
153
		// Is there is field merge tag? Strip whitespace off the ned, too.
154
		preg_match_all( '/{' . preg_quote( $this->_custom_merge_tag ) . ':?(.*?)(?:\s)?}/ism', $text, $matches, PREG_SET_ORDER );
155
156
		// If there are no matches, return original text
157
		if ( empty( $matches ) ) {
158
			return $text;
159
		}
160
161
		return $this->replace_merge_tag( $matches, $text, $form, $entry, $url_encode, $esc_html );
162
	}
163
164
	/**
165
	 * Run GravityView filters when using GFCommon::replace_variables()
166
	 *
167
	 * Instead of adding multiple hooks, add all hooks into this one method to improve speed
168
	 *
169
	 * @since 1.8.4
170
	 *
171
	 * @param array $matches Array of Merge Tag matches found in text by preg_match_all
172
	 * @param string $text Text to replace
173
	 * @param array|bool $form Gravity Forms form array. When called inside {@see GFCommon::replace_variables()} (now deprecated), `false`
174
	 * @param array|bool $entry Entry array.  When called inside {@see GFCommon::replace_variables()} (now deprecated), `false`
175
	 * @param bool $url_encode Whether to URL-encode output
176
	 * @param bool $esc_html Whether to apply `esc_html()` to output
177
	 *
178
	 * @return mixed
179
	 */
180
	public function replace_merge_tag( $matches = array(), $text = '', $form = array(), $entry = array(), $url_encode = false, $esc_html = false ) {
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...
181
182
		foreach( $matches as $match ) {
183
184
			$full_tag = $match[0];
185
186
			// Strip the Merge Tags
187
			$tag = str_replace( array( '{', '}'), '', $full_tag );
188
189
			// Replace the value from the entry, if exists
190
			if( isset( $entry[ $tag ] ) ) {
191
				$text = str_replace( $full_tag, $entry[ $tag ], $text );
192
			}
193
		}
194
195
		return $text;
196
	}
197
198
	/**
199
	 * Add custom merge tags to merge tag options. DO NOT OVERRIDE.
200
	 *
201
	 * @internal Not to be overridden by fields
202
	 *
203
	 * @since 1.8.4
204
	 *
205
	 * @param array $existing_merge_tags
0 ignored issues
show
Bug introduced by
There is no parameter named $existing_merge_tags. 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...
206
	 * @param int $form_id GF Form ID
207
	 * @param GF_Field[] $fields Array of fields in the form
208
	 * @param string $element_id The ID of the input that Merge Tags are being used on
209
	 *
210
	 * @return array Modified merge tags
211
	 */
212
	public function _filter_gform_custom_merge_tags( $custom_merge_tags = array(), $form_id, $fields = array(), $element_id = '' ) {
0 ignored issues
show
Unused Code introduced by
The parameter $element_id 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...
213
214
		$form = GVCommon::get_form( $form_id );
215
216
		$field_merge_tags = $this->custom_merge_tags( $form, $fields );
217
218
		return array_merge( $custom_merge_tags, $field_merge_tags );
219
	}
220
221
	/**
222
	 * Add custom Merge Tags to Merge Tag options, if custom Merge Tags exist
223
	 *
224
	 * Should be overridden if there's more than one Merge Tag to add or if the Merge Tag isn't {_custom_merge_tag}
225
	 *
226
	 * @since 1.16
227
	 *
228
	 * @param array $form GF Form array
229
	 * @param GF_Field[] $fields Array of fields in the form
230
	 *
231
	 * @return array Merge tag array with `label` and `tag` keys based on class `label` and `_custom_merge_tag` variables
232
	 */
233
	protected function custom_merge_tags( $form = array(), $fields = array() ) {
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...
Unused Code introduced by
The parameter $fields 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...
234
235
		// Use variables to make it unnecessary for other fields to override
236
		$merge_tags = array(
237
			array(
238
				'label' => $this->label,
239
				'tag' => '{' . $this->_custom_merge_tag . '}',
240
			),
241
		);
242
243
		return $merge_tags;
244
	}
245
246
	/**
247
	 * Use field settings to modify whether a field is sortable
248
	 *
249
	 * @see GravityView_frontend::is_field_sortable
250
	 * @since 1.15.3
251
	 *
252
	 * @param array $not_sortable Existing field types that aren't sortable
253
	 *
254
	 * @return array
255
	 */
256
	public function _filter_sortable_fields( $not_sortable ) {
257
258
		if( ! $this->is_sortable ) {
259
			$not_sortable[] = $this->name;
260
		}
261
262
		return $not_sortable;
263
	}
264
265
	private function field_support_options() {
266
		$options = array(
267
			'link_to_post' => array(
268
				'type' => 'checkbox',
269
				'label' => __( 'Link to the post', 'gravityview' ),
270
				'desc' => __( 'Link to the post created by the entry.', 'gravityview' ),
271
				'value' => false,
272
			),
273
			'link_to_term' => array(
274
				'type' => 'checkbox',
275
				'label' => __( 'Link to the category or tag', 'gravityview' ),
276
				'desc' => __( 'Link to the current category or tag. "Link to single entry" must be unchecked.', 'gravityview' ),
277
				'value' => false,
278
			),
279
			'dynamic_data' => array(
280
				'type' => 'checkbox',
281
				'label' => __( 'Use the live post data', 'gravityview' ),
282
				'desc' => __( 'Instead of using the entry data, instead use the current post data.', 'gravityview' ),
283
				'value' => true,
284
			),
285
			'date_display' => array(
286
				'type' => 'text',
287
				'label' => __( 'Override Date Format', 'gravityview' ),
288
				'desc' => sprintf( __( 'Define how the date is displayed (using %sthe PHP date format%s)', 'gravityview'), '<a href="https://codex.wordpress.org/Formatting_Date_and_Time">', '</a>' ),
289
				/**
290
				 * @filter `gravityview_date_format` Override the date format with a [PHP date format](https://codex.wordpress.org/Formatting_Date_and_Time)
291
				 * @param[in,out] null|string $date_format Date Format (default: null)
292
				 */
293
				'value' => apply_filters( 'gravityview_date_format', null )
294
			),
295
			'new_window' => array(
296
				'type' => 'checkbox',
297
				'label' => __( 'Open link in a new tab or window?', 'gravityview' ),
298
				'value' => false,
299
			),
300
		);
301
302
		/**
303
		 * @filter `gravityview_field_support_options` Modify the settings that a field supports
304
		 * @param array $options Options multidimensional array with each key being the input name, with each array setting having `type`, `label`, `desc` and `value` (default values) keys
305
		 */
306
		return apply_filters( 'gravityview_field_support_options', $options );
307
	}
308
309
	function add_field_support( $key = '', &$field_options ) {
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...
310
311
		$options = $this->field_support_options();
312
313
		if( isset( $options[ $key ] ) ) {
314
			$field_options[ $key ] = $options[ $key ];
315
		}
316
317
		return $field_options;
318
	}
319
320
	/**
321
	 * Tap in here to modify field options.
322
	 *
323
	 * Here's an example:
324
	 *
325
	 * <pre>
326
	 * $field_options['name_display'] = array(
327
	 * 	'type' => 'select',
328
	 * 	'label' => __( 'User Format', 'gravityview' ),
329
	 * 	'desc' => __( 'How should the User information be displayed?', 'gravityview'),
330
	 * 	'choices' => array(
331
	 * 		array(
332
	 *		 	'value' => 'display_name',
333
	 *		  	'label' => __('Display Name (Example: "Ellen Ripley")', 'gravityview'),
334
	 *		),
335
	 *  	array(
336
	 *			'value' => 'user_login',
337
	 *			'label' => __('Username (Example: "nostromo")', 'gravityview')
338
	 *		),
339
	 * 	 'value' => 'display_name'
340
	 * );
341
	 * </pre>
342
	 *
343
	 * @param  [type]      $field_options [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
344
	 * @param  [type]      $template_id   [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
345
	 * @param  [type]      $field_id      [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
346
	 * @param  [type]      $context       [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
347
	 * @param  [type]      $input_type    [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
348
	 * @return [type]                     [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
349
	 */
350
	function field_options( $field_options, $template_id, $field_id, $context, $input_type ) {
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...
351
352
		$this->_field_options = $field_options;
353
		$this->_field_id = $field_id;
354
355
		return $field_options;
356
	}
357
358
}
359