Passed
Push — develop ( ebd8d2...570278 )
by Remco
07:21
created

Plugin::plugins_loaded()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 13
rs 9.4285
1
<?php
2
/**
3
 * Plugin
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2018 Pronamic
7
 * @license   GPL-3.0-or-later
8
 * @package   Pronamic\WordPress\Pay
9
 */
10
11
namespace Pronamic\WordPress\Pay;
12
13
use Pronamic\WordPress\Pay\Core\Gateway;
14
use Pronamic\WordPress\Pay\Core\PaymentMethods;
15
use Pronamic\WordPress\Pay\Core\Statuses;
16
use Pronamic\WordPress\Pay\Payments\Payment;
17
use Pronamic\WordPress\Pay\Payments\PaymentDataInterface;
18
use Pronamic\WordPress\Pay\Payments\PaymentPostType;
19
use Pronamic\WordPress\Pay\Subscriptions\SubscriptionPostType;
20
use WP_Query;
21
22
/**
23
 * Title: WordPress iDEAL plugin
24
 *
25
 * @author Remco Tolsma
26
 * @version 4.5.3
27
 * @since 1.0.0
28
 */
29
class Plugin {
30
	/**
31
	 * The root file of this WordPress plugin
32
	 *
33
	 * @var string
34
	 */
35
	public static $file;
36
37
	/**
38
	 * The plugin dirname
39
	 *
40
	 * @var string
41
	 */
42
	public static $dirname;
43
44
	/**
45
	 * The timezone
46
	 *
47
	 * @var string
48
	 */
49
	const TIMEZONE = 'UTC';
50
51
	/**
52
	 * Instance.
53
	 *
54
	 * @var Plugin
55
	 */
56
	protected static $instance = null;
57
58
	/**
59
	 * Instance.
60
	 *
61
	 * @param string $file The plugin file.
62
	 */
63
	public static function instance( $file = null ) {
64
		if ( is_null( self::$instance ) ) {
65
			self::$instance = new self();
66
67
			// Backward compatibility.
68
			self::$file    = $file;
69
			self::$dirname = dirname( $file );
70
		}
71
72
		return self::$instance;
73
	}
74
75
	/**
76
	 * Construct and initialize an Pronamic Pay plugin object
77
	 */
78
	public function __construct() {
79
		// Bootstrap the add-ons.
80
		Extensions\Charitable\Extension::bootstrap();
81
		Extensions\Give\Extension::bootstrap();
82
		Extensions\WooCommerce\Extension::bootstrap();
83
		Extensions\GravityForms\Extension::bootstrap();
84
		Extensions\Shopp\Extension::bootstrap();
85
		Extensions\Jigoshop\Extension::bootstrap();
86
		Extensions\WPeCommerce\Extension::bootstrap();
87
		Extensions\ClassiPress\Extension::bootstrap();
88
		Extensions\EventEspressoLegacy\Extension::bootstrap();
89
		Extensions\EventEspresso\Extension::bootstrap();
90
		Extensions\AppThemes\Extension::bootstrap();
91
		Extensions\S2Member\Extension::bootstrap();
92
		Extensions\Membership\Extension::bootstrap();
93
		Extensions\EasyDigitalDownloads\Extension::bootstrap();
94
		Extensions\IThemesExchange\Extension::bootstrap();
95
		Extensions\MemberPress\Extension::bootstrap();
96
		Extensions\FormidableForms\Extension::bootstrap();
97
		Extensions\RestrictContentPro\Extension::bootstrap();
98
99
		// Settings.
100
		$this->settings = new Settings( $this );
0 ignored issues
show
Bug Best Practice introduced by
The property settings does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
101
102
		// Data Stores.
103
		$this->payments_data_store      = new Payments\PaymentsDataStoreCPT();
0 ignored issues
show
Bug Best Practice introduced by
The property payments_data_store does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
104
		$this->subscriptions_data_store = new Subscriptions\SubscriptionsDataStoreCPT();
0 ignored issues
show
Bug Best Practice introduced by
The property subscriptions_data_store does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
105
106
		// Post Types.
107
		$this->gateway_post_type      = new GatewayPostType();
0 ignored issues
show
Bug Best Practice introduced by
The property gateway_post_type does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
108
		$this->payment_post_type      = new PaymentPostType();
0 ignored issues
show
Bug Best Practice introduced by
The property payment_post_type does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
109
		$this->subscription_post_type = new SubscriptionPostType();
0 ignored issues
show
Bug Best Practice introduced by
The property subscription_post_type does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
110
111
		// License Manager.
112
		$this->license_manager = new LicenseManager( $this );
0 ignored issues
show
Bug Best Practice introduced by
The property license_manager does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
113
114
		// Modules.
115
		$this->forms_module         = new Forms\FormsModule( $this );
0 ignored issues
show
Bug Best Practice introduced by
The property forms_module does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
116
		$this->payments_module      = new Payments\PaymentsModule( $this );
0 ignored issues
show
Bug Best Practice introduced by
The property payments_module does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
117
		$this->subscriptions_module = new Subscriptions\SubscriptionsModule( $this );
0 ignored issues
show
Bug Best Practice introduced by
The property subscriptions_module does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
118
119
		// Google Analytics Ecommerce.
120
		$this->google_analytics_ecommerce = new GoogleAnalyticsEcommerce();
0 ignored issues
show
Bug Best Practice introduced by
The property google_analytics_ecommerce does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
121
122
		// Admin.
123
		if ( is_admin() ) {
124
			$this->admin = new Admin\AdminModule( $this );
0 ignored issues
show
Bug Best Practice introduced by
The property admin does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
125
		}
126
127
		/*
128
		 * Plugins loaded.
129
		 *
130
		 * Priority should be at least lower then 8 to support the "WP eCommerce" plugin.
131
		 *
132
		 * new WP_eCommerce()
133
		 * add_action( 'plugins_loaded' , array( $this, 'init' ), 8 );
134
		 * $this->load();
135
		 * wpsc_core_load_gateways();
136
		 *
137
		 * @see https://github.com/wp-e-commerce/WP-e-Commerce/blob/branch-3.11.2/wp-shopping-cart.php#L342-L343
138
		 * @see https://github.com/wp-e-commerce/WP-e-Commerce/blob/branch-3.11.2/wp-shopping-cart.php#L26-L35
139
		 * @see https://github.com/wp-e-commerce/WP-e-Commerce/blob/branch-3.11.2/wp-shopping-cart.php#L54
140
		 * @see https://github.com/wp-e-commerce/WP-e-Commerce/blob/branch-3.11.2/wp-shopping-cart.php#L296-L297
141
		 */
142
		add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ), 5 );
143
144
		// Plugin locale.
145
		add_filter( 'plugin_locale', array( $this, 'plugin_locale' ), 10, 2 );
146
147
		// If WordPress is loaded check on returns and maybe redirect requests.
148
		add_action( 'wp_loaded', array( $this, 'handle_returns' ) );
149
		add_action( 'wp_loaded', array( $this, 'maybe_redirect' ) );
150
	}
151
152
	/**
153
	 * Get the version number of this plugin.
154
	 *
155
	 * @return string The version number of this plugin.
156
	 */
157
	public function get_version() {
158
		global $pronamic_pay_version;
159
160
		return $pronamic_pay_version;
161
	}
162
163
	/**
164
	 * Get plugin file path.
165
	 *
166
	 * @return string
167
	 */
168
	public function get_file() {
169
		return self::$file;
170
	}
171
172
	/**
173
	 * Get the plugin dir path.
174
	 *
175
	 * @return string
176
	 */
177
	public function get_plugin_dir_path() {
178
		return plugin_dir_path( $this->get_file() );
179
	}
180
181
	/**
182
	 * Update payment.
183
	 *
184
	 * @param Payment $payment      The payment to update.
185
	 * @param bool    $can_redirect Flag to indicate if redirect is allowed after the payment update.
186
	 */
187
	public static function update_payment( $payment = null, $can_redirect = true ) {
188
		if ( empty( $payment ) ) {
189
			return;
190
		}
191
192
		$gateway = Plugin::get_gateway( $payment->config_id );
193
194
		if ( empty( $gateway ) ) {
195
			return;
196
		}
197
198
		$amount = $payment->get_amount();
199
200
		if ( empty( $amount ) ) {
201
			$payment->set_status( Core\Statuses::SUCCESS );
202
		} else {
203
			$gateway->update_status( $payment );
204
205
			if ( $gateway->has_error() ) {
206
				foreach ( $gateway->error->get_error_codes() as $code ) {
207
					$payment->add_note( sprintf( '%s: %s', $code, $gateway->error->get_error_message( $code ) ) );
208
				}
209
			}
210
		}
211
212
		// Update payment in data store.
213
		pronamic_pay_plugin()->payments_data_store->update( $payment );
214
215
		// Maybe redirect.
216
		if ( defined( 'DOING_CRON' ) && ( empty( $payment->status ) || Statuses::OPEN === $payment->status ) ) {
217
			$can_redirect = false;
218
		}
219
220
		if ( $can_redirect ) {
221
			$url = $payment->get_return_redirect_url();
222
223
			wp_redirect( $url );
224
225
			exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
226
		}
227
	}
228
229
	/**
230
	 * Handle returns.
231
	 */
232
	public function handle_returns() {
233
		if ( ! filter_has_var( INPUT_GET, 'payment' ) ) {
234
			return;
235
		}
236
237
		$payment_id = filter_input( INPUT_GET, 'payment', FILTER_SANITIZE_NUMBER_INT );
238
239
		$payment = get_pronamic_payment( $payment_id );
240
241
		// Check if payment key is valid.
242
		$valid_key = false;
243
244
		if ( empty( $payment->key ) ) {
245
			$valid_key = true;
246
		} elseif ( filter_has_var( INPUT_GET, 'key' ) ) {
247
			$key = filter_input( INPUT_GET, 'key', FILTER_SANITIZE_STRING );
248
249
			$valid_key = ( $key === $payment->key );
250
		}
251
252
		if ( ! $valid_key ) {
253
			wp_redirect( home_url() );
254
255
			exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
256
		}
257
258
		// Check if we should redirect.
259
		$should_redirect = true;
260
261
		// Check if the request is an callback request.
262
		// Sisow gatway will extend callback requests with querystring "callback=true".
263
		if ( filter_has_var( INPUT_GET, 'callback' ) && filter_input( INPUT_GET, 'callback', FILTER_VALIDATE_BOOLEAN ) ) {
264
			$should_redirect = false;
265
		}
266
267
		// Check if the request is an notify request.
268
		// Sisow gatway will extend callback requests with querystring "notify=true".
269
		if ( filter_has_var( INPUT_GET, 'notify' ) && filter_input( INPUT_GET, 'notify', FILTER_VALIDATE_BOOLEAN ) ) {
270
			$should_redirect = false;
271
		}
272
273
		self::update_payment( $payment, $should_redirect );
274
	}
275
276
	/**
277
	 * Maybe redirect.
278
	 */
279
	public function maybe_redirect() {
280
		if ( ! filter_has_var( INPUT_GET, 'payment_redirect' ) ) {
281
			return;
282
		}
283
284
		$payment_id = filter_input( INPUT_GET, 'payment_redirect', FILTER_SANITIZE_NUMBER_INT );
285
286
		$payment = get_pronamic_payment( $payment_id );
287
288
		// HTML Answer.
289
		$html_answer = $payment->get_meta( 'ogone_directlink_html_answer' );
290
291
		if ( ! empty( $html_answer ) ) {
292
			echo $html_answer; // WPCS: XSS ok.
293
294
			exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
295
		}
296
297
		$redirect_message = $payment->get_meta( 'payment_redirect_message' );
298
299
		if ( ! empty( $redirect_message ) ) {
300
			$key = filter_input( INPUT_GET, 'key', FILTER_SANITIZE_STRING );
301
302
			if ( $key !== $payment->key ) {
303
				wp_redirect( home_url() );
304
305
				exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
306
			}
307
308
			// @see https://github.com/woothemes/woocommerce/blob/2.3.11/includes/class-wc-cache-helper.php
309
			// @see https://www.w3-edge.com/products/w3-total-cache/
310
			if ( ! defined( 'DONOTCACHEPAGE' ) ) {
311
				define( 'DONOTCACHEPAGE', true );
312
			}
313
314
			if ( ! defined( 'DONOTCACHEDB' ) ) {
315
				define( 'DONOTCACHEDB', true );
316
			}
317
318
			if ( ! defined( 'DONOTMINIFY' ) ) {
319
				define( 'DONOTMINIFY', true );
320
			}
321
322
			if ( ! defined( 'DONOTCDN' ) ) {
323
				define( 'DONOTCDN', true );
324
			}
325
326
			if ( ! defined( 'DONOTCACHEOBJECT' ) ) {
327
				define( 'DONOTCACHEOBJECT', true );
328
			}
329
330
			nocache_headers();
331
332
			include Plugin::$dirname . '/views/redirect-message.php';
333
334
			exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
335
		}
336
337
		$gateway = Plugin::get_gateway( $payment->config_id );
338
339
		if ( $gateway && $gateway->is_html_form() ) {
340
			$gateway->start( $payment );
341
342
			$error = $gateway->get_error();
343
344
			if ( is_wp_error( $error ) ) {
345
				Plugin::render_errors( $error );
0 ignored issues
show
Bug introduced by
$error of type WP_Error is incompatible with the type array expected by parameter $errors of Pronamic\WordPress\Pay\Plugin::render_errors(). ( Ignorable by Annotation )

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

345
				Plugin::render_errors( /** @scrutinizer ignore-type */ $error );
Loading history...
346
			} else {
347
				$gateway->redirect( $payment );
348
			}
349
		}
350
351
		if ( ! empty( $payment->action_url ) ) {
352
			wp_redirect( $payment->action_url );
353
354
			exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
355
		}
356
	}
357
358
	/**
359
	 * Get number payments.
360
	 *
361
	 * @return int
362
	 */
363
	public static function get_number_payments() {
364
		$number = false;
365
366
		$count = wp_count_posts( 'pronamic_payment' );
367
368
		if ( isset( $count, $count->payment_completed ) ) {
369
			$number = intval( $count->payment_completed );
370
		}
371
372
		return $number;
373
	}
374
375
	/**
376
	 * Setup, creates or updates database tables. Will only run when version changes.
377
	 */
378
	public function plugins_loaded() {
379
		// Load plugin text domain.
380
		$rel_path = dirname( plugin_basename( self::$file ) ) . '/languages/';
381
382
		load_plugin_textdomain( 'pronamic_ideal', false, $rel_path );
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $deprecated of load_plugin_textdomain(). ( Ignorable by Annotation )

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

382
		load_plugin_textdomain( 'pronamic_ideal', /** @scrutinizer ignore-type */ false, $rel_path );
Loading history...
383
384
		// Gateway Integrations.
385
		$integrations = new GatewayIntegrations();
386
387
		$this->gateway_integrations = $integrations->register_integrations();
0 ignored issues
show
Bug Best Practice introduced by
The property gateway_integrations does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
388
389
		// Maybes.
390
		self::maybe_set_active_payment_methods();
391
	}
392
393
	/**
394
	 * Filter plugin locale.
395
	 *
396
	 * @param string $locale A WordPress locale identifier.
397
	 * @param string $domain A WordPress text domain indentifier.
398
	 *
399
	 * @return string
400
	 */
401
	public function plugin_locale( $locale, $domain ) {
402
		if ( 'pronamic_ideal' !== $domain ) {
403
			return $locale;
404
		}
405
406
		if ( 'nl_NL_formal' === $locale ) {
407
			return 'nl_NL';
408
		}
409
410
		if ( 'nl_BE' === $locale ) {
411
			return 'nl_NL';
412
		}
413
414
		return $locale;
415
	}
416
417
	/**
418
	 * Get payment states.
419
	 *
420
	 * @return array
421
	 */
422
	public static function get_payment_states() {
423
		return array(
424
			'payment_pending'    => _x( 'Pending', 'Payment status', 'pronamic_ideal' ),
425
			'payment_processing' => _x( 'Processing', 'Payment status', 'pronamic_ideal' ),
426
			'payment_on_hold'    => _x( 'On Hold', 'Payment status', 'pronamic_ideal' ),
427
			'payment_completed'  => _x( 'Completed', 'Payment status', 'pronamic_ideal' ),
428
			'payment_cancelled'  => _x( 'Cancelled', 'Payment status', 'pronamic_ideal' ),
429
			'payment_refunded'   => _x( 'Refunded', 'Payment status', 'pronamic_ideal' ),
430
			'payment_failed'     => _x( 'Failed', 'Payment status', 'pronamic_ideal' ),
431
			'payment_expired'    => _x( 'Expired', 'Payment status', 'pronamic_ideal' ),
432
		);
433
	}
434
435
	/**
436
	 * Get subscription states.
437
	 *
438
	 * @return array
439
	 */
440
	public static function get_subscription_states() {
441
		return array(
442
			'subscr_pending'   => _x( 'Pending', 'Subscription status', 'pronamic_ideal' ),
443
			'subscr_cancelled' => _x( 'Cancelled', 'Subscription status', 'pronamic_ideal' ),
444
			'subscr_expired'   => _x( 'Expired', 'Subscription status', 'pronamic_ideal' ),
445
			'subscr_failed'    => _x( 'Failed', 'Subscription status', 'pronamic_ideal' ),
446
			'subscr_active'    => _x( 'Active', 'Subscription status', 'pronamic_ideal' ),
447
			'subscr_completed' => _x( 'Completed', 'Subscription status', 'pronamic_ideal' ),
448
		);
449
	}
450
451
	/**
452
	 * Get default error message.
453
	 *
454
	 * @return string
455
	 */
456
	public static function get_default_error_message() {
457
		return __( 'Something went wrong with the payment. Please try again later or pay another way.', 'pronamic_ideal' );
458
	}
459
460
	/**
461
	 * Get config select options.
462
	 *
463
	 * @param null|string $payment_method The gateway configuration options for the specified payment method.
464
	 *
465
	 * @return array
466
	 */
467
	public static function get_config_select_options( $payment_method = null ) {
468
		$args = array(
469
			'post_type' => 'pronamic_gateway',
470
			'nopaging'  => true,
471
		);
472
473
		if ( $payment_method ) {
474
			$args['post__in'] = PaymentMethods::get_config_ids( $payment_method );
475
		}
476
477
		$query = new WP_Query( $args );
478
479
		$options = array( __( '— Select Configuration —', 'pronamic_ideal' ) );
480
481
		foreach ( $query->posts as $post ) {
482
			$id = $post->ID;
483
484
			$options[ $id ] = sprintf(
485
				'%s (%s)',
486
				get_the_title( $id ),
487
				get_post_meta( $id, '_pronamic_gateway_mode', true )
0 ignored issues
show
Bug introduced by
It seems like get_post_meta($id, '_pro...ic_gateway_mode', true) can also be of type false; however, parameter $args of sprintf() 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

487
				/** @scrutinizer ignore-type */ get_post_meta( $id, '_pronamic_gateway_mode', true )
Loading history...
488
			);
489
		}
490
491
		return $options;
492
	}
493
494
	/**
495
	 * Maybe set active payment methods option.
496
	 *
497
	 * @since unreleased
498
	 */
499
	public static function maybe_set_active_payment_methods() {
500
		$active_methods = get_option( 'pronamic_pay_active_payment_methods' );
501
502
		if ( is_array( $active_methods ) ) {
503
			return;
504
		}
505
506
		PaymentMethods::update_active_payment_methods();
507
	}
508
509
	/**
510
	 * Render errors.
511
	 *
512
	 * @param array $errors An array with errors to render.
513
	 */
514
	public static function render_errors( $errors = array() ) {
515
		if ( ! is_array( $errors ) ) {
0 ignored issues
show
introduced by
The condition is_array($errors) is always true.
Loading history...
516
			$errors = array( $errors );
517
		}
518
519
		foreach ( $errors as $error ) {
520
			include Plugin::$dirname . '/views/error.php';
521
		}
522
	}
523
524
	/**
525
	 * Get gateway.
526
	 *
527
	 * @param string $config_id A gateway configuration ID.
528
	 *
529
	 * @return Gateway
530
	 */
531
	public static function get_gateway( $config_id ) {
532
		if ( empty( $config_id ) ) {
533
			return null;
534
		}
535
536
		$gateway_id = get_post_meta( $config_id, '_pronamic_gateway_id', true );
0 ignored issues
show
Bug introduced by
$config_id of type string is incompatible with the type integer expected by parameter $post_id of get_post_meta(). ( Ignorable by Annotation )

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

536
		$gateway_id = get_post_meta( /** @scrutinizer ignore-type */ $config_id, '_pronamic_gateway_id', true );
Loading history...
537
		$mode       = get_post_meta( $config_id, '_pronamic_gateway_mode', true );
538
		$is_utf8    = strcasecmp( get_bloginfo( 'charset' ), 'UTF-8' ) === 0;
539
540
		$config = Core\ConfigProvider::get_config( $gateway_id, $config_id );
541
542
		switch ( $gateway_id ) {
543
			case 'abnamro-ideal-easy':
544
			case 'abnamro-ideal-only-kassa':
545
			case 'abnamro-internetkassa':
546
				$config->form_action_url = sprintf(
547
					'https://internetkassa.abnamro.nl/ncol/%s/orderstandard%s.asp',
548
					'test' === $mode ? 'test' : 'prod',
549
					$is_utf8 ? '_utf8' : ''
550
				);
551
552
				break;
553
			case 'abnamro-ideal-zelfbouw-v3':
554
				$config->payment_server_url = 'https://abnamro.ideal-payment.de/ideal/iDEALv3';
555
556
				if ( 'test' === $mode ) {
557
					$config->payment_server_url = 'https://abnamro-test.ideal-payment.de/ideal/iDEALv3';
558
				}
559
560
				$config->certificates = array();
561
562
				break;
563
			case 'deutschebank-ideal-expert-v3':
564
				$config->payment_server_url = 'https://myideal.db.com/ideal/iDealv3';
565
566
				$config->certificates = array();
567
568
				break;
569
			case 'ideal-simulator-ideal-basic':
570
				$config->url = 'https://www.ideal-simulator.nl/lite/';
571
572
				break;
573
			case 'ideal-simulator-ideal-advanced-v3':
574
				$config->payment_server_url = 'https://www.ideal-checkout.nl/simulator/';
575
576
				$config->certificates = array();
577
578
				break;
579
			case 'ing-ideal-basic':
580
				$config->url = 'https://ideal.secure-ing.com/ideal/mpiPayInitIng.do';
581
582
				if ( 'test' === $mode ) {
583
					$config->url = 'https://idealtest.secure-ing.com/ideal/mpiPayInitIng.do';
584
				}
585
586
				break;
587
			case 'ing-ideal-advanced-v3':
588
				$config->payment_server_url = 'https://ideal.secure-ing.com/ideal/iDEALv3';
589
590
				if ( 'test' === $mode ) {
591
					$config->payment_server_url = 'https://idealtest.secure-ing.com/ideal/iDEALv3';
592
				}
593
594
				$config->certificates = array();
595
596
				break;
597
			case 'mollie-ideal-basic':
598
				$config->url = 'https://secure.mollie.nl/xml/idealAcquirer/lite/';
599
600
				if ( 'test' === $mode ) {
601
					$config->url = 'https://secure.mollie.nl/xml/idealAcquirer/testmode/lite/';
602
				}
603
604
				break;
605
			case 'postcode-ideal':
606
				$config->payment_server_url = 'https://ideal.postcode.nl/ideal';
607
608
				if ( 'test' === $mode ) {
609
					$config->payment_server_url = 'https://ideal-test.postcode.nl/ideal';
610
				}
611
612
				$config->certificates = array();
613
614
				break;
615
			case 'rabobank-ideal-professional-v3':
616
				$config->payment_server_url = 'https://ideal.rabobank.nl/ideal/iDEALv3';
617
618
				if ( 'test' === $mode ) {
619
					$config->payment_server_url = 'https://idealtest.rabobank.nl/ideal/iDEALv3';
620
				}
621
622
				$config->certificates = array();
623
624
				break;
625
			case 'sisow-ideal-basic':
626
				$config->url = 'https://www.sisow.nl/Sisow/iDeal/IssuerHandler.ashx';
627
628
				if ( 'test' === $mode ) {
629
					$config->url = 'https://www.sisow.nl/Sisow/iDeal/IssuerHandler.ashx/test';
630
				}
631
632
				break;
633
		}
634
635
		$gateway = Core\GatewayFactory::create( $config );
636
637
		return $gateway;
638
	}
639
640
	/**
641
	 * Start a payment.
642
	 *
643
	 * @param string               $config_id      A gateway configuration ID.
644
	 * @param Gateway              $gateway        The gateway to start the payment at.
645
	 * @param PaymentDataInterface $data           A payment data interface object with all the required payment info.
646
	 * @param string|null          $payment_method The payment method to use to start the payment.
647
	 *
648
	 * @return Payment
649
	 */
650
	public static function start( $config_id, Gateway $gateway, PaymentDataInterface $data, $payment_method = null ) {
651
		$payment = new Payments\Payment();
652
653
		$payment->title               = sprintf( __( 'Payment for %s', 'pronamic_ideal' ), $data->get_title() );
654
		$payment->user_id             = $data->get_user_id();
0 ignored issues
show
Bug introduced by
The method get_user_id() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

654
		/** @scrutinizer ignore-call */ 
655
  $payment->user_id             = $data->get_user_id();
Loading history...
655
		$payment->config_id           = $config_id;
656
		$payment->key                 = uniqid( 'pay_' );
657
		$payment->order_id            = $data->get_order_id();
0 ignored issues
show
Bug introduced by
The method get_order_id() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

657
		/** @scrutinizer ignore-call */ 
658
  $payment->order_id            = $data->get_order_id();
Loading history...
658
		$payment->currency            = $data->get_currency();
0 ignored issues
show
Bug introduced by
The method get_currency() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

658
		/** @scrutinizer ignore-call */ 
659
  $payment->currency            = $data->get_currency();
Loading history...
659
		$payment->amount              = $data->get_amount();
0 ignored issues
show
Bug introduced by
The method get_amount() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

659
		/** @scrutinizer ignore-call */ 
660
  $payment->amount              = $data->get_amount();
Loading history...
660
		$payment->language            = $data->get_language();
0 ignored issues
show
Bug introduced by
The method get_language() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

660
		/** @scrutinizer ignore-call */ 
661
  $payment->language            = $data->get_language();
Loading history...
661
		$payment->locale              = $data->get_language_and_country();
0 ignored issues
show
Bug introduced by
The method get_language_and_country() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

661
		/** @scrutinizer ignore-call */ 
662
  $payment->locale              = $data->get_language_and_country();
Loading history...
662
		$payment->entrance_code       = $data->get_entrance_code();
0 ignored issues
show
Bug introduced by
The method get_entrance_code() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

662
		/** @scrutinizer ignore-call */ 
663
  $payment->entrance_code       = $data->get_entrance_code();
Loading history...
663
		$payment->description         = $data->get_description();
0 ignored issues
show
Bug introduced by
The method get_description() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Did you maybe mean get_subscription()? ( Ignorable by Annotation )

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

663
		/** @scrutinizer ignore-call */ 
664
  $payment->description         = $data->get_description();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
664
		$payment->source              = $data->get_source();
0 ignored issues
show
Bug introduced by
The method get_source() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

664
		/** @scrutinizer ignore-call */ 
665
  $payment->source              = $data->get_source();
Loading history...
665
		$payment->source_id           = $data->get_source_id();
0 ignored issues
show
Bug introduced by
The method get_source_id() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

665
		/** @scrutinizer ignore-call */ 
666
  $payment->source_id           = $data->get_source_id();
Loading history...
666
		$payment->email               = $data->get_email();
0 ignored issues
show
Bug introduced by
The method get_email() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

666
		/** @scrutinizer ignore-call */ 
667
  $payment->email               = $data->get_email();
Loading history...
667
		$payment->status              = null;
668
		$payment->method              = $payment_method;
669
		$payment->issuer              = $data->get_issuer( $payment_method );
0 ignored issues
show
Bug introduced by
The method get_issuer() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

669
		/** @scrutinizer ignore-call */ 
670
  $payment->issuer              = $data->get_issuer( $payment_method );
Loading history...
670
		$payment->first_name          = $data->get_first_name();
0 ignored issues
show
Bug introduced by
The method get_first_name() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. It seems like you code against a sub-type of Pronamic\WordPress\Pay\P...ts\PaymentDataInterface such as Pronamic\WordPress\Pay\Payments\PaymentData. ( Ignorable by Annotation )

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

670
		/** @scrutinizer ignore-call */ 
671
  $payment->first_name          = $data->get_first_name();
Loading history...
671
		$payment->last_name           = $data->get_last_name();
0 ignored issues
show
Bug introduced by
The method get_last_name() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. It seems like you code against a sub-type of Pronamic\WordPress\Pay\P...ts\PaymentDataInterface such as Pronamic\WordPress\Pay\Payments\PaymentData. ( Ignorable by Annotation )

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

671
		/** @scrutinizer ignore-call */ 
672
  $payment->last_name           = $data->get_last_name();
Loading history...
672
		$payment->customer_name       = $data->get_customer_name();
0 ignored issues
show
Bug introduced by
The method get_customer_name() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

672
		/** @scrutinizer ignore-call */ 
673
  $payment->customer_name       = $data->get_customer_name();
Loading history...
673
		$payment->address             = $data->get_address();
0 ignored issues
show
Bug introduced by
The method get_address() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

673
		/** @scrutinizer ignore-call */ 
674
  $payment->address             = $data->get_address();
Loading history...
674
		$payment->zip                 = $data->get_zip();
0 ignored issues
show
Bug introduced by
The method get_zip() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

674
		/** @scrutinizer ignore-call */ 
675
  $payment->zip                 = $data->get_zip();
Loading history...
675
		$payment->city                = $data->get_city();
0 ignored issues
show
Bug introduced by
The method get_city() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

675
		/** @scrutinizer ignore-call */ 
676
  $payment->city                = $data->get_city();
Loading history...
676
		$payment->country             = $data->get_country();
0 ignored issues
show
Bug introduced by
The method get_country() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

676
		/** @scrutinizer ignore-call */ 
677
  $payment->country             = $data->get_country();
Loading history...
677
		$payment->telephone_number    = $data->get_telephone_number();
0 ignored issues
show
Bug introduced by
The method get_telephone_number() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

677
		/** @scrutinizer ignore-call */ 
678
  $payment->telephone_number    = $data->get_telephone_number();
Loading history...
678
		$payment->analytics_client_id = $data->get_analytics_client_id();
0 ignored issues
show
Bug introduced by
The method get_analytics_client_id() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. It seems like you code against a sub-type of Pronamic\WordPress\Pay\P...ts\PaymentDataInterface such as Pronamic\WordPress\Pay\Payments\PaymentData. ( Ignorable by Annotation )

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

678
		/** @scrutinizer ignore-call */ 
679
  $payment->analytics_client_id = $data->get_analytics_client_id();
Loading history...
679
		$payment->recurring           = $data->get_recurring();
0 ignored issues
show
Bug introduced by
The method get_recurring() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. ( Ignorable by Annotation )

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

679
		/** @scrutinizer ignore-call */ 
680
  $payment->recurring           = $data->get_recurring();
Loading history...
680
		$payment->subscription        = $data->get_subscription();
681
		$payment->subscription_id     = $data->get_subscription_id();
0 ignored issues
show
Bug introduced by
The method get_subscription_id() does not exist on Pronamic\WordPress\Pay\P...ts\PaymentDataInterface. Did you maybe mean get_subscription()? ( Ignorable by Annotation )

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

681
		/** @scrutinizer ignore-call */ 
682
  $payment->subscription_id     = $data->get_subscription_id();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
682
		$payment->set_credit_card( $data->get_credit_card() );
683
684
		// User Agent (@see https://github.com/WordPress/WordPress/blob/4.9.4/wp-includes/comment.php#L1962-L1965).
685
		$payment->user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : null;
686
687
		// IP (@see https://github.com/WordPress/WordPress/blob/4.9.4/wp-includes/comment.php#L1957-L1960).
688
		$payment->user_ip = isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : null;
689
690
		return self::start_payment( $payment, $gateway );
691
	}
692
693
	/**
694
	 * Start payment.
695
	 *
696
	 * @param Payment $payment The payment to start at the specified gateway.
697
	 * @param Gateway $gateway The gateway to start the payment at.
698
	 *
699
	 * @return Payment
700
	 */
701
	public static function start_payment( Payment $payment, Gateway $gateway ) {
702
		global $pronamic_ideal;
703
704
		$pronamic_ideal->payments_data_store->create( $payment );
705
706
		// Start payment at the gateway.
707
		$result = $gateway->start( $payment );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $result is correct as $gateway->start($payment) targeting Pronamic\WordPress\Pay\Core\Gateway::start() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
708
709
		// If result is false the payment failed to start.
710
		if ( false === $result ) {
0 ignored issues
show
introduced by
The condition false === $result is always true.
Loading history...
711
			// If payment failed to start we directly update the payment status to 'failure'.
712
			$payment->set_status( Core\Statuses::FAILURE );
713
714
			// Check if there is a subscription attached to the payment.
715
			$subscription = $payment->get_subscription();
716
717
			if ( $subscription ) {
718
				if ( ! $payment->get_recurring() ) {
719
					// First payment.
720
					// Cancel subscription to prevent unwanted recurring payments in the future,
721
					// when a valid customer ID might be set for the user.
722
					$subscription->update_status( Core\Statuses::CANCELLED );
723
				} else {
724
					$subscription->set_status( Core\Statuses::FAILURE );
725
				}
726
727
				$pronamic_ideal->subscriptions_data_store->update( $subscription );
728
			}
729
		}
730
731
		// Check if the gateway has an error.
732
		if ( $gateway->has_error() ) {
733
			foreach ( $gateway->error->get_error_codes() as $code ) {
734
				$payment->add_note( sprintf( '%s: %s', $code, $gateway->error->get_error_message( $code ) ) );
735
			}
736
		}
737
738
		$pronamic_ideal->payments_data_store->update( $payment );
739
740
		if ( $gateway->supports( 'payment_status_request' ) ) {
741
			Payments\StatusChecker::schedule_event( $payment );
742
		}
743
744
		return $payment;
745
	}
746
747
	/**
748
	 * Get pages.
749
	 *
750
	 * @return array
751
	 */
752
	public function get_pages() {
753
		$return = array();
754
755
		$pages = array(
756
			'completed' => __( 'Completed', 'pronamic_ideal' ),
757
			'cancel'    => __( 'Canceled', 'pronamic_ideal' ),
758
			'expired'   => __( 'Expired', 'pronamic_ideal' ),
759
			'error'     => __( 'Error', 'pronamic_ideal' ),
760
			'unknown'   => __( 'Unknown', 'pronamic_ideal' ),
761
		);
762
763
		foreach ( $pages as $key => $label ) {
764
			$id = sprintf( 'pronamic_pay_%s_page_id', $key );
765
766
			$return[ $id ] = $label;
767
		}
768
769
		return $return;
770
	}
771
}
772