Completed
Push — master ( 764d24...7cd13b )
by Chris
01:37
created

EDU_SveaWebPay::update_booking()   C

Complexity

Conditions 11
Paths 144

Size

Total Lines 56

Duplication

Lines 6
Ratio 10.71 %

Importance

Changes 0
Metric Value
cc 11
nc 144
nop 3
dl 6
loc 56
rs 6.5199
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
defined( 'ABSPATH' ) or die( 'This plugin must be run within the scope of WordPress.' );
3
4
require_once( __DIR__ . '/class-edu-sveawebpay-config.php' );
5
6
use Svea\WebPay\WebPay;
7
use Svea\WebPay\WebPayItem;
8
9
if ( ! class_exists( 'EDU_SveaWebPay' ) ):
10
11
	/**
12
	 * EDU_SveaWebPay integrates EduAdmin-WordPress plugin with SveaWebPay as payment gateway
13
	 */
14
	class EDU_SveaWebPay extends EDU_Integration {
15
		/**
16
		 * Constructor
17
		 */
18
		public function __construct() {
19
			$this->id          = 'eduadmin-sveawebpay';
20
			$this->displayName = __( 'Svea Webpay (Checkout)', 'eduadmin-sveawebpay' );
21
			$this->description = '';
22
			$this->type        = 'payment';
23
24
			$this->init_form_fields();
25
			$this->init_settings();
26
27
			add_action( 'eduadmin-checkpaymentplugins', array( $this, 'intercept_booking' ) );
28
			add_action( 'eduadmin-processbooking', array( $this, 'process_booking' ) );
29
			add_action( 'eduadmin-bookingcompleted', array( $this, 'process_svearesponse' ) );
30
			add_action( 'wp_loaded', array( $this, 'process_paymentstatus' ) );
31
32
			add_shortcode( 'eduadmin-svea-testpage', array( $this, 'test_page' ) );
33
		}
34
35
		/**
36
		 * @param $attributes
37
		 */
38
		public function test_page( $attributes ) {
39
			$attributes = shortcode_atts(
40
				array(
41
					'bookingid'          => 0,
42
					'programmebookingid' => 0,
43
				),
44
				normalize_empty_atts( $attributes ),
45
				'test_page'
46
			);
47
48
			if ( $attributes['bookingid'] > 0 ) {
49
				$event_booking = EDUAPI()->OData->Bookings->GetItem(
50
					$attributes['bookingid'],
51
					null,
52
					'Customer($select=CustomerId;),ContactPerson($select=PersonId;),OrderRows',
53
					false
54
				);
55
			} elseif ( $attributes['programmebookingid'] > 0 ) {
56
				$event_booking = EDUAPI()->OData->ProgrammeBookings->GetItem(
57
					$attributes['programmebookingid'],
58
					null,
59
					'Customer($select=CustomerId;),ContactPerson($select=PersonId;),OrderRows',
60
					false
61
				);
62
			}
63
64
			$_customer = EDUAPI()->OData->Customers->GetItem(
65
				$event_booking['Customer']['CustomerId'],
0 ignored issues
show
Bug introduced by
The variable $event_booking does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
66
				null,
67
				"BillingInfo",
68
				false
69
			);
70
71
			$_contact = EDUAPI()->OData->Persons->GetItem(
72
				$event_booking['ContactPerson']['PersonId'],
73
				null,
74
				null,
75
				false
76
			);
77
78
			$ebi = new EduAdmin_BookingInfo( $event_booking, $_customer, $_contact );
79
80
			if ( ! empty( EDU()->session['svea-order-id'] ) && ! empty( $_GET['svea_order_id'] ) && EDU()->session['svea-order-id'] === $_GET['svea_order_id'] ) {
81
				do_action( 'eduadmin-bookingcompleted', $ebi );
82
			} else {
83
				do_action( 'eduadmin-processbooking', $ebi );
84
			}
85
		}
86
87
88
		/**
89
		 * @param EduAdmin_BookingInfo|null $ebi
90
		 */
91
		public function intercept_booking( $ebi = null ) {
92
			if ( 'no' === $this->get_option( 'enabled', 'no' ) ) {
93
				return;
94
			}
95
96
			if ( ! empty( $_POST['act'] ) && ( 'bookCourse' === $_POST['act'] || 'bookProgramme' === $_POST['act'] ) ) {
97
				$ebi->NoRedirect = true;
98
			}
99
		}
100
101
		/**
102
		 * Initializes the settingsfields
103
		 */
104
		public function init_form_fields() {
105
			$this->setting_fields = array(
106
				'enabled'         => array(
107
					'title'       => __( 'Enabled', 'eduadmin-sveawebpay' ),
108
					'type'        => 'checkbox',
109
					'description' => __( 'Enables/Disables the integration with Svea WebPay', 'eduadmin-sveawebpay' ),
110
					'default'     => 'no',
111
				),
112
				'testrun'         => array(
113
					'title'       => __( 'Sandbox mode', 'eduadmin-sveawebpay' ),
114
					'type'        => 'checkbox',
115
					'description' => __( 'Activate sandbox mode', 'eduadmin-sveawebpay' ),
116
					'default'     => 'no',
117
				),
118
				'merchant_key'    => array(
119
					'title'       => __( 'Merchant key', 'eduadmin-sveawebpay' ),
120
					'type'        => 'text',
121
					'description' => __( 'Please enter your merchant key from Svea WebPay.', 'eduadmin-sveawebpay' ),
122
					'placeholder' => __( 'Merchant key', 'eduadmin-sveawebpay' ),
123
				),
124
				'merchant_secret' => array(
125
					'title'       => __( 'Merchant secret', 'eduadmin-sveawebpay' ),
126
					'type'        => 'password',
127
					'description' => __( 'Please enter your merchant secret from Svea WebPay', 'eduadmin-sveawebpay' ),
128
					'placeholder' => __( 'Merchant secret', 'eduadmin-sveawebpay' ),
129
				),
130
			);
131
		}
132
133
		/**
134
		 *
135
		 */
136
		public function process_svearesponse() {
137
			if ( 'no' === $this->get_option( 'enabled', 'no' ) ) {
138
				return;
139
			}
140
141 View Code Duplication
			if ( isset( $_REQUEST['edu-thankyou'] ) && isset( $_REQUEST['svea'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
142
				$booking_id           = intval( $_GET['booking_id'] );
143
				$programme_booking_id = intval( $_GET['programme_booking_id'] );
144
145
				$deleted = $this->update_booking( intval( EDU()->session['svea-order-id'] ), $booking_id, $programme_booking_id );
146
147
				EDU()->session['svea-order-id'] = null;
148
149
				if ( $deleted ) {
150
					$this->handle_cancelled_payment();
151
				}
152
			}
153
		}
154
155
		/**
156
		 * @param $ebi EduAdmin_BookingInfo|null $bookingInfo
157
		 */
158
		public function process_booking( $ebi = null ) {
159
			if ( 'no' === $this->get_option( 'enabled', 'no' ) ) {
160
				return;
161
			}
162
163
			$ebi->NoRedirect = true;
164
165
			if ( empty( $_GET['svea_order_id'] ) || empty( EDU()->session['svea-order-id'] ) ) {
166
				$checkout = $this->create_checkout( $ebi );
167
168
				$snippet = $checkout['Gui']['Snippet'];
169
				echo "<div>{$snippet}</div>";
170
			}
171
		}
172
173
		/**
174
		 * @param $ebi EduAdmin_BookingInfo|null
175
		 *
176
		 * @returns array
177
		 */
178
		public function create_checkout( $ebi ) {
179
			$countries = EDUAPI()->OData->Countries->Search()['value'];
180
181
			$selectedCountry = 'SE';
182
			$selectedLocale  = 'sv-SE';
183
184
			$invoiceCountry = $ebi->Customer['BillingInfo']['Country'];
185
			if ( empty( $invoiceCountry ) ) {
186
				$invoiceCountry = $ebi->Customer['Country'];
187
			}
188
189
			foreach ( $countries as $country ) {
190
				if ( $invoiceCountry == $country['CountryName'] ) {
191
					$selectedCountry = $country['CountryCode'];
192
					if ( ! empty( $country['CultureName'] ) ) {
193
						$selectedLocale = $country['CultureName'];
194
					}
195
					break;
196
				}
197
			}
198
199
			$booking_id           = 0;
200
			$programme_booking_id = 0;
201
202
			$reference_id = 0;
203
204
			$_event = null;
205
206
			$eventName = '';
207
208 View Code Duplication
			if ( ! empty( $ebi->EventBooking['BookingId'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
209
				$booking_id   = intval( $ebi->EventBooking['BookingId'] );
210
				$reference_id = $booking_id;
211
212
				$_event = EDUAPI()->OData->Events->GetItem( $ebi->EventBooking['EventId'], null );
213
214
				$eventName = $_event['EventName'];
215
			}
216
217 View Code Duplication
			if ( ! empty( $ebi->EventBooking['ProgrammeBookingId'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
218
				$programme_booking_id = intval( $ebi->EventBooking['ProgrammeBookingId'] );
219
				$reference_id         = $programme_booking_id;
220
221
				$_event = EDUAPI()->OData->ProgrammeStarts->GetItem( $ebi->EventBooking['ProgrammeStartId'] );
222
223
				$eventName = $_event['ProgrammeStartName'];
224
			}
225
226
			$currency = EDU()->get_option( 'eduadmin-currency', 'SEK' );
227
228 View Code Duplication
			if ( 'no' !== $this->get_option( 'testrun', 'no' ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
229
				$wpConfig = new EduSveaWebPayTestConfig( $this );
230
			} else {
231
				$wpConfig = new EduSveaWebPayProductionConfig( $this );
232
			}
233
234
			$wpOrder = WebPay::checkout( $wpConfig );
235
236
			$customer = WebPayItem::companyCustomer();
237
238
			$customerName  = ! empty( $ebi->Customer['BillingInfo']['InvoiceName'] ) ? $ebi->Customer['BillingInfo']['InvoiceName'] : $ebi->Customer['CustomerName'];
239
			$streetAddress = ! empty( $ebi->Customer['BillingInfo']['Address'] ) ? $ebi->Customer['BillingInfo']['Address'] : $ebi->Customer['Address'];
240
			$zipCode       = ! empty( $ebi->Customer['BillingInfo']['Zip'] ) ? $ebi->Customer['BillingInfo']['Zip'] : $ebi->Customer['Zip'];
241
			$city          = $ebi->Customer['BillingInfo']['City'] ? $ebi->Customer['BillingInfo']['City'] : $ebi->Customer['City'];
242
			$phone         = $ebi->Customer['Phone'];
243
			$email         = ! empty( $ebi->Customer['BillingInfo']['Email'] ) ? $ebi->Customer['BillingInfo']['Email'] : $ebi->Customer['Email'];
244
245
			$customer->setCompanyName( $customerName );
246
			$customer->setStreetAddress( $streetAddress );
247
			$customer->setZipCode( $zipCode );
248
			$customer->setLocality( $city );
249
250
			if ( ! empty( $phone ) ) {
251
				$customer->setPhoneNumber( $phone );
252
				$phonePreset = WebPayItem::presetValue()
253
				                         ->setTypeName( \Svea\WebPay\Checkout\Model\PresetValue::PHONE_NUMBER )
254
				                         ->setValue( $phone )
255
				                         ->setIsReadonly( false );
256
				$wpOrder->addPresetValue( $phonePreset );
257
			}
258
			$customer->setEmail( $email );
259
260
			$zipPreset = WebPayItem::presetValue()
261
			                       ->setTypeName( \Svea\WebPay\Checkout\Model\PresetValue::POSTAL_CODE )
262
			                       ->setValue( $zipCode )
263
			                       ->setIsReadonly( false );
264
			$wpOrder->addPresetValue( $zipPreset );
265
266
			$emailPreset = WebPayItem::presetValue()
267
			                         ->setTypeName( \Svea\WebPay\Checkout\Model\PresetValue::EMAIL_ADDRESS )
268
			                         ->setValue( $email )
269
			                         ->setIsReadonly( false );
270
			$wpOrder->addPresetValue( $emailPreset );
271
272
			$current_url = esc_url( "{$_SERVER['REQUEST_SCHEME']}://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}" );
273
274
			$defaultThankYou = add_query_arg(
275
				array(
276
					'edu-thankyou'         => $reference_id,
277
					'svea'                 => '1',
278
					'booking_id'           => $booking_id,
279
					'programme_booking_id' => $programme_booking_id,
280
					'edu-valid-form'       => wp_create_nonce( 'edu-booking-confirm' ),
281
					'act'                  => 'paymentCompleted',
282
				),
283
				@get_page_link( get_option( 'eduadmin-thankYouPage', '/' ) )
284
			);
285
286
			$defaultCancel = add_query_arg(
287
				array(
288
					'edu-thankyou'         => $reference_id,
289
					'svea'                 => '1',
290
					'booking_id'           => $booking_id,
291
					'programme_booking_id' => $programme_booking_id,
292
					'status'               => 'cancel'
293
				),
294
				$current_url
295
			);
296
297
			$defaultPushUrl = add_query_arg(
298
				array(
299
					'edu-thankyou'         => $reference_id,
300
					'svea'                 => '1',
301
					'booking_id'           => $booking_id,
302
					'programme_booking_id' => $programme_booking_id,
303
					'svea_order_id'        => '{checkout.order.uri}',
304
					'status'               => 'push'
305
				),
306
				$current_url
307
			);
308
309
			$defaultTermsUrl = get_option( 'eduadmin-bookingTermsLink' );
310
311
			$wpBuild = $wpOrder
312
				->setCurrency( $currency )
313
				->setCountryCode( $selectedCountry )
314
				->setClientOrderNumber( $reference_id )
315
				->setLocale( $selectedLocale )
316
				->setTermsUri( $defaultTermsUrl )
317
				->setConfirmationUri( $defaultThankYou )
318
				->setPushUri( $defaultPushUrl )
319
				->setCheckoutUri( $defaultCancel ); // We have no "checkout"-url.. So we just cancel the booking instead.
320
321
			$orderRow = WebPayItem::orderRow();
322
			$orderRow->setName( substr( $eventName, 0, 40 ) );
323
			$orderRow->setQuantity( 0 );
324
			$orderRow->setAmountIncVat( 0 );
325
			$orderRow->setVatPercent( 0 );
326
327
			$wpBuild->addOrderRow( $orderRow );
328
329
			$timeLabel = $programme_booking_id > 0 ? "Programstart" : "Kursstart";
330
331
			$orderRow = WebPayItem::orderRow();
332
			$orderRow->setName( $timeLabel . ": " . date( "Y-m-d H:i", strtotime( $_event['StartDate'] ) ) );
333
			$orderRow->setQuantity( 0 );
334
			$orderRow->setAmountIncVat( 0 );
335
			$orderRow->setVatPercent( 0 );
336
337
			$wpBuild->addOrderRow( $orderRow );
338
339
			foreach ( $ebi->EventBooking['OrderRows'] as $eduOrderRow ) {
340
				$orderRow = WebPayItem::orderRow();
341
				$orderRow->setName( substr( $eduOrderRow['Description'], 0, 40 ) );
342
				$orderRow->setQuantity( $eduOrderRow['Quantity'] );
343
344
				$orderRow->setVatPercent( $eduOrderRow['VatPercent'] );
345
346
				if ( $eduOrderRow['PriceIncVat'] ) {
347
					$orderRow->setAmountIncVat( $eduOrderRow['TotalPrice'] );
348
				} else {
349
					$priceInclVat = $eduOrderRow['TotalPrice'];
350
					if ( $eduOrderRow['VatPercent'] > 0 ) {
351
						$priceInclVat = $eduOrderRow['TotalPrice'] * ( 1 + ( $eduOrderRow['VatPercent'] / 100 ) );
352
					}
353
					$orderRow->setAmountIncVat( $priceInclVat );
354
				}
355
356
				$orderRow->setDiscountPercent( $eduOrderRow['DiscountPercent'] );
357
358
				$wpBuild->addOrderRow( $orderRow );
359
			}
360
361
			$wpForm = $wpBuild->createOrder();
362
363
			EDU()->session['svea-order-id'] = $wpForm['OrderId'];
364
365
			return $wpForm;
366
		}
367
368
		public function process_paymentstatus() {
369
			if ( ! empty( $_GET['svea_order_id'] ) && intval( $_GET['svea_order_id'] ) != 0 && ! empty( $_GET['status'] ) ) {
370
371
				$booking_id           = intval( $_GET['booking_id'] );
372
				$programme_booking_id = intval( $_GET['programme_booking_id'] );
373
374
				$this->update_booking( intval( $_GET['svea_order_id'] ), $booking_id, $programme_booking_id );
375
376
				exit( 0 );
377
			}
378
379 View Code Duplication
			if ( isset( $_REQUEST['edu-thankyou'] ) && isset( $_REQUEST['svea'] ) && ! empty( $_GET['status'] ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
380
				$booking_id           = intval( $_GET['booking_id'] );
381
				$programme_booking_id = intval( $_GET['programme_booking_id'] );
382
383
				$deleted = $this->update_booking( intval( EDU()->session['svea-order-id'] ), $booking_id, $programme_booking_id );
384
385
				EDU()->session['svea-order-id'] = null;
386
387
				if ( $deleted ) {
388
					$this->handle_cancelled_payment();
389
				}
390
			}
391
		}
392
393
		private function handle_cancelled_payment() {
394
			@wp_redirect( get_home_url() );
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
395
			wp_add_inline_script( 'edu-svea-redirecthome', "location.href = '" . esc_js( get_home_url() ) . "';" );
396
			wp_enqueue_script( 'edu-svea-redirecthome', false, array( 'jquery' ) );
397
			exit( 0 );
398
		}
399
400
		/**
401
		 * @param $order_id numeric SVEA WebPay OrderId
402
		 * @param $booking_id
403
		 * @param $programme_booking_id
404
		 *
405
		 * @return bool If the booking was deleted, due to cancellation
406
		 * @throws \Svea\WebPay\BuildOrder\Validator\ValidationException
407
		 */
408
		private function update_booking( $order_id, $booking_id, $programme_booking_id ) {
409 View Code Duplication
			if ( 'no' !== $this->get_option( 'testrun', 'no' ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
410
				$wpConfig = new EduSveaWebPayTestConfig( $this );
411
			} else {
412
				$wpConfig = new EduSveaWebPayProductionConfig( $this );
413
			}
414
415
			$wpOrder = WebPay::checkout( $wpConfig );
416
			$wpOrder->setCheckoutOrderId( $order_id );
417
418
			$order = $wpOrder->getOrder();
419
420
			$delete_booking = false;
421
422
			$patch_booking                  = new stdClass();
423
			$patch_booking->PaymentMethodId = 2;
424
425
			if ( 'Cancelled' === $order['Status'] ) {
426
				$patch_booking->Paid = false;
427
				$delete_booking      = true;
428
			} else if ( 'Final' === $order['Status'] ) {
429
				$patch_booking->Paid = true;
430
			} else if ( 'Created' === $order['Status'] ) {
431
				$patch_booking->Paid = false;
432
			}
433
434
			if ( isset( $_GET['status'] ) && 'cancel' === $_GET['status'] ) {
435
				$patch_booking->Paid = false;
436
				$delete_booking      = true;
437
			}
438
439
			if ( $booking_id > 0 ) {
440
				EDUAPI()->REST->Booking->PatchBooking(
441
					$booking_id,
442
					$patch_booking
443
				);
444
445
				if ( $delete_booking ) {
446
					EDUAPI()->REST->Booking->DeleteBooking( $booking_id );
447
				}
448
			}
449
450
			if ( $programme_booking_id > 0 ) {
451
452
				EDUAPI()->REST->ProgrammeBooking->PatchBooking(
453
					$programme_booking_id,
454
					$patch_booking
455
				);
456
457
				if ( $delete_booking ) {
458
					EDUAPI()->REST->ProgrammeBooking->DeleteBooking( $programme_booking_id );
459
				}
460
			}
461
462
			return $delete_booking;
463
		}
464
	}
465
466
endif;
467