GetPaid_Meta_Box_Invoice_Address   B
last analyzed

Complexity

Total Complexity 48

Size/Duplication

Total Lines 353
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 250
c 1
b 0
f 0
dl 0
loc 353
rs 8.5599
wmc 48

2 Methods

Rating   Name   Duplication   Size   Complexity  
D save() 0 90 35
C output() 0 247 13

How to fix   Complexity   

Complex Class

Complex classes like GetPaid_Meta_Box_Invoice_Address often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

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

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

1
<?php
2
3
/**
4
 * Invoice Address
5
 *
6
 * Display the invoice address meta box.
7
 *
8
 */
9
10
if ( ! defined( 'ABSPATH' ) ) {
11
	exit; // Exit if accessed directly
12
}
13
14
/**
15
 * GetPaid_Meta_Box_Invoice_Address Class.
16
 */
17
class GetPaid_Meta_Box_Invoice_Address {
18
19
	/**
20
	 * Output the metabox.
21
	 *
22
	 * @param WP_Post $post
23
	 */
24
	public static function output( $post ) {
25
26
		// Prepare the invoice.
27
		$invoice  = new WPInv_Invoice( $post );
28
		$customer = $invoice->exists() ? $invoice->get_user_id( 'edit' ) : get_current_user_id();
29
		$customer = new WP_User( $customer );
30
		$display  = sprintf( _x( '%1$s (%2$s)', 'user dropdown', 'invoicing' ), $customer->display_name, $customer->user_email );
31
		wp_nonce_field( 'getpaid_meta_nonce', 'getpaid_meta_nonce' );
32
33
		// Address fields.
34
		$address_fields = array(
35
			'first_name' => array(
36
				'label' => __( 'First Name', 'invoicing' ),
37
				'type'  => 'text',
38
			),
39
			'last_name'  => array(
40
				'label' => __( 'Last Name', 'invoicing' ),
41
				'type'  => 'text',
42
			),
43
			'company'    => array(
44
				'label' => __( 'Company', 'invoicing' ),
45
				'type'  => 'text',
46
				'class' => 'getpaid-recalculate-prices-on-change',
47
			),
48
			'vat_number' => array(
49
				'label' => __( 'VAT Number', 'invoicing' ),
50
				'type'  => 'text',
51
				'class' => 'getpaid-recalculate-prices-on-change',
52
			),
53
			'address'    => array(
54
				'label' => __( 'Address', 'invoicing' ),
55
				'type'  => 'text',
56
			),
57
			'city'       => array(
58
				'label' => __( 'City', 'invoicing' ),
59
				'type'  => 'text',
60
			),
61
			'country'    => array(
62
				'label'       => __( 'Country', 'invoicing' ),
63
				'type'        => 'select',
64
				'class'       => 'getpaid-recalculate-prices-on-change',
65
				'options'     => wpinv_get_country_list(),
66
				'placeholder' => __( 'Choose a country', 'invoicing' ),
67
			),
68
			'state'      => array(
69
				'label' => __( 'State', 'invoicing' ),
70
				'type'  => 'text',
71
				'class' => 'getpaid-recalculate-prices-on-change',
72
			),
73
			'zip'        => array(
74
				'label' => __( 'Zip', 'invoicing' ),
75
				'type'  => 'text',
76
			),
77
			'phone'      => array(
78
				'label' => __( 'Phone', 'invoicing' ),
79
				'type'  => 'text',
80
			),
81
		);
82
83
		$states = wpinv_get_country_states( $invoice->get_country( 'edit' ) );
84
85
		if ( ! empty( $states ) ) {
86
			$address_fields['state']['type']        = 'select';
87
			$address_fields['state']['options']     = $states;
88
			$address_fields['state']['placeholder'] = __( 'Choose a state', 'invoicing' );
89
		}
90
91
		// Maybe remove the VAT field.
92
		if ( ! wpinv_use_taxes() ) {
93
			unset( $address_fields['vat_number'] );
94
		}
95
96
		$address_fields = apply_filters( 'getpaid_admin_edit_invoice_address_fields', $address_fields, $invoice );
97
		?>
98
99
		<style>
100
			#wpinv-address label {
101
				margin-bottom: 3px;
102
				font-weight: 600;
103
			}
104
		</style>
105
			<div class="bsui" style="margin-top: 1.5rem; max-width: 820px;">
106
					<div class="row">
107
						<div class="col-12 col-sm-6">
108
							<div id="getpaid-invoice-user-id-wrapper" class="form-group mb-3">
109
								<div>
110
									<label for="post_author_override"><?php esc_html_e( 'Customer', 'invoicing' ); ?></label>
111
								</div>
112
								<div>
113
									<select name="post_author_override" id="wpinv_post_author_override" class="getpaid-customer-search form-control regular-text" data-placeholder="<?php esc_attr_e( 'Search for a customer by email or name', 'invoicing' ); ?>">
114
										<option selected="selected" value="<?php echo (int) $customer->ID; ?>"><?php echo esc_html( $display ); ?> </option>)
115
									</select>
116
								</div>
117
							</div>
118
119
							<div id="getpaid-invoice-email-wrapper" class="d-none">
120
								<input type="hidden" id="getpaid-invoice-create-new-user" name="wpinv_new_user" value="" />
121
								<?php
122
									aui()->input(
123
										array(
124
											'type'        => 'text',
125
											'id'          => 'getpaid-invoice-new-user-email',
126
											'name'        => 'wpinv_email',
127
											'label'       => __( 'Email', 'invoicing' ) . '<span class="required">*</span>',
128
											'label_type'  => 'vertical',
129
											'placeholder' => '[email protected]',
130
											'class'       => 'form-control-sm',
131
										),
132
										true
133
									);
134
								?>
135
							</div>
136
						</div>
137
						<div class="col-12 col-sm-6 form-group mb-3 mt-sm-4">
138
							<?php if ( ! $invoice->is_paid() && ! $invoice->is_refunded() ) : ?>
139
								<a id="getpaid-invoice-fill-user-details" class="button button-small button-secondary" href="javascript:void(0)">
140
									<i aria-hidden="true" class="fa fa-refresh"></i>
141
									<?php esc_html_e( 'Fill User Details', 'invoicing' ); ?>
142
								</a>
143
								<a id="getpaid-invoice-create-new-user-button" class="button button-small button-secondary" href="javascript:void(0)">
144
									<i aria-hidden="true" class="fa fa-plus"></i>
145
									<?php esc_html_e( 'Add New User', 'invoicing' ); ?>
146
								</a>
147
								<a id="getpaid-invoice-cancel-create-new-user" class="button button-small button-secondary d-none" href="javascript:void(0)">
148
									<i aria-hidden="true" class="fa fa-close"></i>
149
									<?php esc_html_e( 'Cancel', 'invoicing' ); ?>
150
								</a>
151
							<?php endif; ?>
152
						</div>
153
154
						<?php foreach ( $address_fields as $key => $field ) : ?>
155
							<div class="col-12 col-sm-6 getpaid-invoice-address-field__<?php echo esc_attr( $key ); ?>--wrapper">
156
								<?php
157
158
									if ( 'select' === $field['type'] ) {
159
										aui()->select(
160
											array(
161
												'id'               => 'wpinv_' . $key,
162
												'name'             => 'wpinv_' . $key,
163
												'label'            => $field['label'],
164
												'label_type'       => 'vertical',
165
												'placeholder'      => isset( $field['placeholder'] ) ? $field['placeholder'] : '',
166
												'class'            => 'form-control-sm ' . ( isset( $field['class'] ) ? $field['class'] : '' ),
167
												'value'            => $invoice->get( $key, 'edit' ),
168
												'options'          => $field['options'],
169
												'data-allow-clear' => 'false',
170
												'select2'          => true,
171
											),
172
											true
173
										);
174
									} else {
175
										aui()->input(
176
											array(
177
												'type'        => $field['type'],
178
												'id'          => 'wpinv_' . $key,
179
												'name'        => 'wpinv_' . $key,
180
												'label'       => $field['label'],
181
												'label_type'  => 'vertical',
182
												'placeholder' => isset( $field['placeholder'] ) ? $field['placeholder'] : '',
183
												'class'       => 'form-control-sm ' . ( isset( $field['class'] ) ? $field['class'] : '' ),
184
												'value'       => $invoice->get( $key, 'edit' ),
185
											),
186
											true
187
										);
188
									}
189
190
								?>
191
							</div>
192
						<?php endforeach; ?>
193
					</div>
194
195
					<?php if ( ! apply_filters( 'getpaid_use_new_invoice_items_metabox', false ) ) : ?>
196
						<?php do_action( 'wpinv_meta_box_before_invoice_template_row', $invoice->get_id() ); ?>
197
198
						<div class="row">
199
							<div class="col-12 col-sm-6">
200
								<?php
201
									aui()->select(
202
										array(
203
											'id'          => 'wpinv_template',
204
											'name'        => 'wpinv_template',
205
											'label'       => __( 'Template', 'invoicing' ),
206
											'label_type'  => 'vertical',
207
											'placeholder' => __( 'Choose a template', 'invoicing' ),
208
											'class'       => 'form-control-sm',
209
											'value'       => $invoice->get_template( 'edit' ),
210
											'options'     => array(
211
												'quantity' => __( 'Quantity', 'invoicing' ),
212
												'hours'    => __( 'Hours', 'invoicing' ),
213
											),
214
											'data-allow-clear' => 'false',
215
											'select2'     => true,
216
										),
217
										true
218
									);
219
								?>
220
							</div>
221
							<div class="col-12 col-sm-6">
222
								<?php
223
224
									// Set currency.
225
									aui()->select(
226
										array(
227
											'id'          => 'wpinv_currency',
228
											'name'        => 'wpinv_currency',
229
											'label'       => __( 'Currency', 'invoicing' ),
230
											'label_type'  => 'vertical',
231
											'placeholder' => __( 'Select Invoice Currency', 'invoicing' ),
232
											'class'       => 'form-control-sm getpaid-recalculate-prices-on-change',
233
											'value'       => $invoice->get_currency( 'edit' ),
234
											'required'    => false,
235
											'data-allow-clear' => 'false',
236
											'select2'     => true,
237
											'options'     => wpinv_get_currencies(),
238
										),
239
										true
240
									);
241
242
								?>
243
							</div>
244
						</div>
245
246
						<?php do_action( 'wpinv_meta_box_invoice_template_row', $invoice->get_id() ); ?>
247
					<?php endif; ?>
248
249
					<div class="row">
250
						<div class="col-12 col-sm-6">
251
							<?php
252
								aui()->input(
253
									array(
254
										'type'        => 'text',
255
										'id'          => 'wpinv_company_id',
256
										'name'        => 'wpinv_company_id',
257
										'label'       => __( 'Company ID', 'invoicing' ),
258
										'label_type'  => 'vertical',
259
										'placeholder' => '',
260
										'class'       => 'form-control-sm',
261
										'value'       => $invoice->get_company_id( 'edit' ),
262
									),
263
									true
264
								);
265
							?>
266
						</div>
267
					</div>
268
269
					<?php do_action( 'getpaid_after_metabox_invoice_address', $invoice ); ?>
270
			</div>
271
		<?php
272
	}
273
274
	/**
275
	 * Save meta box data.
276
	 *
277
	 * @param int $post_id
278
	 * @param array $posted the posted data.
279
	 */
280
	public static function save( $post_id, $posted ) {
281
282
		// Prepare the invoice.
283
		$invoice = new WPInv_Invoice( $post_id );
284
285
		// Load new data.
286
		$invoice->set_props(
287
			array(
288
				'template'       => isset( $posted['wpinv_template'] ) ? wpinv_clean( $posted['wpinv_template'] ) : null,
289
				'email_cc'       => isset( $posted['wpinv_cc'] ) ? wpinv_clean( $posted['wpinv_cc'] ) : null,
290
				'disable_taxes'  => ! empty( $posted['disable_taxes'] ),
291
				'currency'       => isset( $posted['wpinv_currency'] ) ? wpinv_clean( $posted['wpinv_currency'] ) : null,
292
				'gateway'        => ( $invoice->needs_payment() && isset( $posted['wpinv_gateway'] ) ) ? wpinv_clean( $posted['wpinv_gateway'] ) : null,
293
				'address'        => isset( $posted['wpinv_address'] ) ? wpinv_clean( $posted['wpinv_address'] ) : null,
294
				'vat_number'     => isset( $posted['wpinv_vat_number'] ) ? wpinv_clean( $posted['wpinv_vat_number'] ) : null,
295
				'company'        => isset( $posted['wpinv_company'] ) ? wpinv_clean( $posted['wpinv_company'] ) : null,
296
				'company_id'     => isset( $posted['wpinv_company_id'] ) ? wpinv_clean( $posted['wpinv_company_id'] ) : null,
297
				'zip'            => isset( $posted['wpinv_zip'] ) ? wpinv_clean( $posted['wpinv_zip'] ) : null,
298
				'state'          => isset( $posted['wpinv_state'] ) ? wpinv_clean( $posted['wpinv_state'] ) : null,
299
				'city'           => isset( $posted['wpinv_city'] ) ? wpinv_clean( $posted['wpinv_city'] ) : null,
300
				'country'        => isset( $posted['wpinv_country'] ) ? wpinv_clean( $posted['wpinv_country'] ) : null,
301
				'phone'          => isset( $posted['wpinv_phone'] ) ? wpinv_clean( $posted['wpinv_phone'] ) : null,
302
				'first_name'     => isset( $posted['wpinv_first_name'] ) ? wpinv_clean( $posted['wpinv_first_name'] ) : null,
303
				'last_name'      => isset( $posted['wpinv_last_name'] ) ? wpinv_clean( $posted['wpinv_last_name'] ) : null,
304
				'author'         => isset( $posted['post_author_override'] ) ? wpinv_clean( $posted['post_author_override'] ) : null,
305
				'date_created'   => isset( $posted['date_created'] ) ? wpinv_clean( $posted['date_created'] ) : null,
306
				'date_completed' => isset( $posted['wpinv_date_completed'] ) ? wpinv_clean( $posted['wpinv_date_completed'] ) : null,
307
				'due_date'       => isset( $posted['wpinv_due_date'] ) ? wpinv_clean( $posted['wpinv_due_date'] ) : null,
308
				'number'         => isset( $posted['wpinv_number'] ) ? wpinv_clean( $posted['wpinv_number'] ) : null,
309
				'status'         => isset( $posted['wpinv_status'] ) ? wpinv_clean( $posted['wpinv_status'] ) : null,
310
			)
311
		);
312
313
		// Discount code.
314
		if ( ! $invoice->is_paid() && ! $invoice->is_refunded() ) {
315
316
			if ( isset( $posted['wpinv_discount_code'] ) ) {
317
				$invoice->set_discount_code( wpinv_clean( $posted['wpinv_discount_code'] ) );
0 ignored issues
show
Bug introduced by
It seems like wpinv_clean($posted['wpinv_discount_code']) can also be of type array; however, parameter $value of WPInv_Invoice::set_discount_code() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

317
				$invoice->set_discount_code( /** @scrutinizer ignore-type */ wpinv_clean( $posted['wpinv_discount_code'] ) );
Loading history...
318
			}
319
320
			$discount = new WPInv_Discount( $invoice->get_discount_code() );
321
			if ( $discount->exists() ) {
322
				$invoice->add_discount( getpaid_calculate_invoice_discount( $invoice, $discount ) );
323
			} else {
324
				$invoice->remove_discount( 'discount_code' );
325
			}
326
327
			// Recalculate totals.
328
			$invoice->recalculate_total();
329
330
		}
331
332
		// If we're creating a new user...
333
		if ( ! empty( $posted['wpinv_new_user'] ) && is_email( stripslashes( $posted['wpinv_email'] ) ) ) {
334
335
			// Attempt to create the user.
336
			$user = wpinv_create_user( sanitize_email( stripslashes( $posted['wpinv_email'] ) ), $invoice->get_first_name() . $invoice->get_last_name() );
337
338
			// If successful, update the invoice author.
339
			if ( is_numeric( $user ) ) {
0 ignored issues
show
introduced by
The condition is_numeric($user) is always false.
Loading history...
340
				$invoice->set_author( $user );
341
			} else {
342
				wpinv_error_log( $user->get_error_message(), __( 'Invoice add new user', 'invoicing' ), __FILE__, __LINE__ );
343
			}
344
		}
345
346
		// Do not send new invoice notifications.
347
		$GLOBALS['wpinv_skip_invoice_notification'] = true;
348
349
		// Save the invoice.
350
		$invoice->save();
351
352
		// Save the user address.
353
		getpaid_save_invoice_user_address( $invoice );
354
355
		// Undo do not send new invoice notifications.
356
		$GLOBALS['wpinv_skip_invoice_notification'] = false;
357
358
		// (Maybe) send new user notification.
359
		$should_send_notification = wpinv_get_option( 'disable_new_user_emails' );
360
		if ( ! empty( $user ) && is_numeric( $user ) && apply_filters( 'getpaid_send_new_user_notification', empty( $should_send_notification ) ) ) {
361
			wp_send_new_user_notifications( $user, 'user' );
362
		}
363
364
		if ( ! empty( $posted['send_to_customer'] ) && ! $invoice->is_draft() ) {
365
			getpaid()->get( 'invoice_emails' )->user_invoice( $invoice, true );
366
		}
367
368
		// Fires after an invoice is saved.
369
		do_action( 'wpinv_invoice_metabox_saved', $invoice );
370
	}
371
}
372