Completed
Pull Request — master (#815)
by Zack
10:24 queued 07:03
created

GravityView_Field_Address::get_choices_state()   C

Complexity

Conditions 7
Paths 18

Size

Total Lines 34
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

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

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

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

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

Loading history...
2
/**
3
 * @file class-gravityview-field-address.php
4
 * @package GravityView
5
 * @subpackage includes\fields
6
 */
7
8
/**
9
 * Add custom options for address fields
10
 */
11
class GravityView_Field_Address extends GravityView_Field {
12
13
	var $name = 'address';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $name.

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

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
14
15
	var $group = 'advanced';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $group.

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

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
16
17
	var $_gf_field_class_name = 'GF_Field_Address';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_gf_field_class_name.

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

class A {
    var $property;
}

the property is implicitly global.

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

Loading history...
18
19
	public function __construct() {
20
		$this->label = esc_html__( 'Address', 'gravityview' );
21
22
		$this->add_hooks();
23
24
		parent::__construct();
25
	}
26
27
	/**
28
	 * Add filters for this field type
29
	 *
30
	 * @since 1.19.2
31
	 *
32
	 * @return void
33
	 */
34
	private function add_hooks() {
35
		add_filter( 'gravityview/extension/search/input_type', array( $this, 'search_bar_input_type' ), 10, 3 );
36
		add_filter( 'gravityview/search/input_types', array( $this, 'input_types' ) );
37
		add_filter( 'gravityview_widget_search_filters', array( $this, 'search_field_filter' ), 10, 3 );
38
	}
39
40
	/**
41
	 * Dynamically add choices to the address field dropdowns, if any
42
	 *
43
	 * @since 1.19.2
44
	 *
45
	 * @param array $search_fields Array of search filters with `key`, `label`, `value`, `type` keys
46
	 * @param GravityView_Widget_Search $widget Current widget object
47
	 * @param array $widget_args Args passed to this method. {@since 1.8}
48
	 *
49
	 * @return array If the search field GF Field type is `address`, and there are choices to add, adds them and changes the input type. Otherwise, sets the input to text.
50
	 */
51
	public function search_field_filter( $search_fields, $widget, $widget_args ) {
0 ignored issues
show
Unused Code introduced by
The parameter $widget 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 $widget_args 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...
52
53
		foreach ( $search_fields as & $search_field ) {
54
55
			if ( 'address' === rgar( $search_field, 'type' ) ) {
56
57
				$field_id = intval( floor( $search_field['key'] ) );
58
				$input_id = gravityview_get_input_id_from_id( $search_field['key'] );
59
				$form = GravityView_View::getInstance()->getForm();
60
61
				/** @var GF_Field_Address $address_field */
62
				$address_field = GFFormsModel::get_field( $form, $field_id );
63
64
				$choices = array();
65
66
				$method_name = 'get_choices_' . self::get_input_type_from_input_id( $input_id );
67
				if( method_exists( $this, $method_name ) ) {
68
					/**
69
					 * @uses GravityView_Field_Address::get_choices_country()
70
					 * @uses GravityView_Field_Address::get_choices_state()
71
					 */
72
					$choices = $this->{$method_name}( $address_field );
73
				}
74
75
				if( ! empty( $choices ) ) {
76
					$search_field['choices'] = $choices;
77
					$search_field['type'] = rgar( $search_field, 'input');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
78
				} else {
79
					$search_field['type'] = 'text';
80
					$search_field['input'] = 'input_text';
81
				}
82
			}
83
		}
84
85
		return $search_fields;
86
	}
87
88
	/**
89
	 * Get array of countries to use for the search choices
90
	 *
91
	 * @since 1.19.2
92
	 *
93
	 * @see GF_Field_Address::get_countries()
94
	 *
95
	 * @param GF_Field_Address $address_field
96
	 *
97
	 * @return array Array of countries with `value` and `text` keys as the name of the country
98
	 */
99
	private function get_choices_country( $address_field ) {
100
101
		$countries = $address_field->get_countries();
102
103
		$country_choices = array();
104
105
		foreach ( $countries as $key => $country ) {
106
			$country_choices[] = array(
107
				'value' => $country,
108
				'text' => $country,
109
			);
110
		}
111
112
		return $country_choices;
113
	}
114
115
	/**
116
	 * Get array of states to use for the search choices
117
	 *
118
	 * @since 1.19.2
119
	 *
120
	 * @uses GF_Field_Address::get_us_states()
121
	 * @uses GF_Field_Address::get_us_state_code()
122
	 * @uses GF_Field_Address::get_canadian_provinces()
123
	 *
124
	 * @param GF_Field_Address $address_field
125
	 *
126
	 * @return array Array of countries with `value` and `text` keys as the name of the country
127
	 */
128
	private function get_choices_state( $address_field ) {
129
130
		$address_type = empty( $address_field->addressType ) ? $address_field->get_default_address_type( $form['id'] ) : $address_field->addressType;
0 ignored issues
show
Bug introduced by
The variable $form does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
131
132
		$state_choices = array();
133
134
		switch ( $address_type ) {
135
			case 'us':
136
				$states = GFCommon::get_us_states();
137
				break;
138
			case 'canadian':
139
				$states = GFCommon::get_canadian_provinces();
140
				break;
141
			default:
142
				$states = empty( $address_types[ $address_type ]['states'] ) ? array() : $address_types[ $address_type ]['states'];
0 ignored issues
show
Bug introduced by
The variable $address_types does not exist. Did you mean $address_type?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
143
				break;
144
		}
145
146
		foreach ( $states as $key => $state ) {
147
148
			if( 'us' === $address_type ) {
149
				$value = GFCommon::get_us_state_code( $state );
150
			} else {
151
				$value = $state;
152
			}
153
154
			$state_choices[] = array(
155
				'value' => $value,
156
				'text' => $state,
157
			);
158
		}
159
160
		return $state_choices;
161
	}
162
163
	/**
164
	 * Add the input types available for each custom search field type
165
	 *
166
	 * @since 1.19.2
167
	 *
168
	 * @param array $input_types Array of input types as the keys (`select`, `radio`, `multiselect`, `input_text`) with a string or array of supported inputs as values
169
	 *
170
	 * @return array $input_types array, but
171
	 */
172
	public function input_types( $input_types ) {
173
174
		// Use the same inputs as the "text" input type allows
175
		$text_inputs = rgar( $input_types, 'text' );
176
177
		$input_types['street'] = $text_inputs;
178
		$input_types['street2'] = $text_inputs;
179
		$input_types['city'] = $text_inputs;
180
181
		$input_types['state'] = array( 'select', 'radio', 'link' ) + $text_inputs;
182
		$input_types['zip'] = array( 'input_text' );
183
		$input_types['country'] = array( 'select', 'radio', 'link' ) + $text_inputs;
184
185
		return $input_types;
186
	}
187
188
	/**
189
	 * Converts the custom input type (address) into the selected type
190
	 *
191
	 * @since 1.19.2
192
	 *
193
	 * @param string $input_type Assign an input type according to the form field type. Defaults: `boolean`, `multi`, `select`, `date`, `text`
194
	 * @param string $field_type Gravity Forms field type (also the `name` parameter of GravityView_Field classes)
195
	 * @param string|int|float $field_id ID of the field being processed
196
	 *
197
	 * @return string If the field ID matches an address field input, return those options {@see GravityView_Field_Address::input_types() }. Otherwise, original value is used.
198
	 */
199
	public function search_bar_input_type( $input_type, $field_type, $field_id ) {
200
201
		// Is this search field for an input (eg: 4.2) or the whole address field (eg: 4)?
202
		$input_id = gravityview_get_input_id_from_id( $field_id );
203
204
		if( 'address' === $field_type && $input_id ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $input_id of type false|integer 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...
205
206
			// If the input ID matches an expected address input, set to that. Otherwise, keep existing input type.
207
			if( $address_field_name = self::get_input_type_from_input_id( $input_id ) ) {
208
				$input_type = $address_field_name;
209
			}
210
		}
211
212
		return $input_type;
213
	}
214
215
	/**
216
	 * Get a name for the input based on the input ID
217
	 *
218
	 * @since 1.19.2
219
	 *
220
	 * @param int $input_id ID of the specific input for the address field
221
	 *
222
	 * @return false|string If the input ID matches a known address field input, returns a name for that input ("city", or "country"). Otherwise, returns false.
223
	 */
224
	private static function get_input_type_from_input_id( $input_id ) {
225
226
		$input_type = false;
227
228
		switch ( $input_id ) {
229
			case 1:
230
				$input_type = 'street';
231
				break;
232
			case 2:
233
				$input_type = 'street2';
234
				break;
235
			case 3:
236
				$input_type = 'city';
237
				break;
238
				break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

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

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

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

    return false;
}

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

Loading history...
239
			case 4:
240
				$input_type = 'state';
241
				break;
242
			case 5:
243
				$input_type = 'zip';
244
				break;
245
			case 6:
246
				$input_type = 'country';
247
				break;
248
		}
249
250
		return $input_type;
251
	}
252
253
	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...
254
255
		// If this is NOT the full address field, return default options.
256
		if( floor( $field_id ) !== floatval( $field_id ) ) {
257
			return $field_options;
258
		}
259
260
		if( 'edit' === $context ) {
261
			return $field_options;
262
		}
263
264
		$add_options = array();
265
266
		$add_options['show_map_link'] = array(
267
			'type' => 'checkbox',
268
			'label' => __( 'Show Map Link:', 'gravityview' ),
269
			'desc' => __('Display a "Map It" link below the address', 'gravityview'),
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
270
			'value' => true,
271
			'merge_tags' => false,
272
		);
273
274
		return $add_options + $field_options;
275
	}
276
277
}
278
279
new GravityView_Field_Address;
280