Passed
Push — develop ( a056ec...770b15 )
by Reüel
04:53
created

Plugin::get_file()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
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
	 * Version.
32
	 *
33
	 * @var string
34
	 */
35
	private $version = '5.0.0';
36
37
	/**
38
	 * The root file of this WordPress plugin
39
	 *
40
	 * @var string
41
	 */
42
	public static $file;
43
44
	/**
45
	 * The plugin dirname
46
	 *
47
	 * @var string
48
	 */
49
	public static $dirname;
50
51
	/**
52
	 * The timezone
53
	 *
54
	 * @var string
55
	 */
56
	const TIMEZONE = 'UTC';
57
58
	/**
59
	 * Instance.
60
	 *
61
	 * @var Plugin
62
	 */
63
	protected static $instance = null;
64
65
	/**
66
	 * Instance.
67
	 *
68
	 * @param string $file The plugin file.
69
	 */
70
	public static function instance( $file = null ) {
71
		if ( is_null( self::$instance ) ) {
72
			self::$instance = new self();
73
74
			// Backward compatibility.
75
			self::$file    = $file;
76
			self::$dirname = dirname( $file );
77
		}
78
79
		return self::$instance;
80
	}
81
82
	/**
83
	 * Construct and initialize an Pronamic Pay plugin object
84
	 */
85
	public function __construct() {
86
		// Bootstrap the add-ons.
87
		Extensions\Charitable\Extension::bootstrap();
88
		Extensions\Give\Extension::bootstrap();
89
		Extensions\WooCommerce\Extension::bootstrap();
90
		Extensions\GravityForms\Extension::bootstrap();
91
		Extensions\Shopp\Extension::bootstrap();
92
		Extensions\Jigoshop\Extension::bootstrap();
93
		Extensions\WPeCommerce\Extension::bootstrap();
94
		Extensions\ClassiPress\Extension::bootstrap();
95
		Extensions\EventEspressoLegacy\Extension::bootstrap();
96
		Extensions\EventEspresso\Extension::bootstrap();
97
		Extensions\AppThemes\Extension::bootstrap();
98
		Extensions\S2Member\Extension::bootstrap();
99
		Extensions\Membership\Extension::bootstrap();
100
		Extensions\EasyDigitalDownloads\Extension::bootstrap();
101
		Extensions\IThemesExchange\Extension::bootstrap();
102
		Extensions\MemberPress\Extension::bootstrap();
103
		Extensions\FormidableForms\Extension::bootstrap();
104
		Extensions\RestrictContentPro\Extension::bootstrap();
105
106
		// Settings.
107
		$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...
108
109
		// Data Stores.
110
		$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...
111
		$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...
112
113
		// Post Types.
114
		$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...
115
		$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...
116
		$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...
117
118
		// License Manager.
119
		$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...
120
121
		// Modules.
122
		$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...
123
		$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...
124
		$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...
125
126
		// Google Analytics Ecommerce.
127
		$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...
128
129
		// Admin.
130
		if ( is_admin() ) {
131
			$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...
132
		}
133
134
		/*
135
		 * Plugins loaded.
136
		 *
137
		 * Priority should be at least lower then 8 to support the "WP eCommerce" plugin.
138
		 *
139
		 * new WP_eCommerce()
140
		 * add_action( 'plugins_loaded' , array( $this, 'init' ), 8 );
141
		 * $this->load();
142
		 * wpsc_core_load_gateways();
143
		 *
144
		 * @see https://github.com/wp-e-commerce/WP-e-Commerce/blob/branch-3.11.2/wp-shopping-cart.php#L342-L343
145
		 * @see https://github.com/wp-e-commerce/WP-e-Commerce/blob/branch-3.11.2/wp-shopping-cart.php#L26-L35
146
		 * @see https://github.com/wp-e-commerce/WP-e-Commerce/blob/branch-3.11.2/wp-shopping-cart.php#L54
147
		 * @see https://github.com/wp-e-commerce/WP-e-Commerce/blob/branch-3.11.2/wp-shopping-cart.php#L296-L297
148
		 */
149
		add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ), 5 );
150
151
		// Plugin locale.
152
		add_filter( 'plugin_locale', array( $this, 'plugin_locale' ), 10, 2 );
153
154
		// If WordPress is loaded check on returns and maybe redirect requests.
155
		add_action( 'wp_loaded', array( $this, 'handle_returns' ) );
156
		add_action( 'wp_loaded', array( $this, 'maybe_redirect' ) );
157
	}
158
159
	/**
160
	 * Get the version number of this plugin.
161
	 *
162
	 * @return string The version number of this plugin.
163
	 */
164
	public function get_version() {
165
		return $this->version;
166
	}
167
168
	/**
169
	 * Get plugin file path.
170
	 *
171
	 * @return string
172
	 */
173
	public function get_file() {
174
		return self::$file;
175
	}
176
177
	/**
178
	 * Get the plugin dir path.
179
	 *
180
	 * @return string
181
	 */
182
	public function get_plugin_dir_path() {
183
		return plugin_dir_path( $this->get_file() );
184
	}
185
186
	/**
187
	 * Update payment.
188
	 *
189
	 * @param Payment $payment      The payment to update.
190
	 * @param bool    $can_redirect Flag to indicate if redirect is allowed after the payment update.
191
	 */
192
	public static function update_payment( $payment = null, $can_redirect = true ) {
193
		if ( empty( $payment ) ) {
194
			return;
195
		}
196
197
		$gateway = Plugin::get_gateway( $payment->config_id );
198
199
		if ( empty( $gateway ) ) {
200
			return;
201
		}
202
203
		$amount = $payment->get_amount();
204
205
		if ( empty( $amount ) ) {
206
			$payment->set_status( Core\Statuses::SUCCESS );
207
		} else {
208
			$gateway->update_status( $payment );
209
210
			if ( $gateway->has_error() ) {
211
				foreach ( $gateway->error->get_error_codes() as $code ) {
212
					$payment->add_note( sprintf( '%s: %s', $code, $gateway->error->get_error_message( $code ) ) );
213
				}
214
			}
215
		}
216
217
		// Update payment in data store.
218
		$payment->save();
219
220
		// Maybe redirect.
221
		if ( defined( 'DOING_CRON' ) && ( empty( $payment->status ) || Statuses::OPEN === $payment->status ) ) {
222
			$can_redirect = false;
223
		}
224
225
		if ( $can_redirect ) {
226
			$url = $payment->get_return_redirect_url();
227
228
			wp_redirect( $url );
229
230
			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...
231
		}
232
	}
233
234
	/**
235
	 * Handle returns.
236
	 */
237
	public function handle_returns() {
238
		if ( ! filter_has_var( INPUT_GET, 'payment' ) ) {
239
			return;
240
		}
241
242
		$payment_id = filter_input( INPUT_GET, 'payment', FILTER_SANITIZE_NUMBER_INT );
243
244
		$payment = get_pronamic_payment( $payment_id );
245
246
		// Check if payment key is valid.
247
		$valid_key = false;
248
249
		if ( empty( $payment->key ) ) {
250
			$valid_key = true;
251
		} elseif ( filter_has_var( INPUT_GET, 'key' ) ) {
252
			$key = filter_input( INPUT_GET, 'key', FILTER_SANITIZE_STRING );
253
254
			$valid_key = ( $key === $payment->key );
255
		}
256
257
		if ( ! $valid_key ) {
258
			wp_redirect( home_url() );
259
260
			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...
261
		}
262
263
		// Check if we should redirect.
264
		$should_redirect = true;
265
266
		// Check if the request is an callback request.
267
		// Sisow gatway will extend callback requests with querystring "callback=true".
268
		if ( filter_has_var( INPUT_GET, 'callback' ) && filter_input( INPUT_GET, 'callback', FILTER_VALIDATE_BOOLEAN ) ) {
269
			$should_redirect = false;
270
		}
271
272
		// Check if the request is an notify request.
273
		// Sisow gatway will extend callback requests with querystring "notify=true".
274
		if ( filter_has_var( INPUT_GET, 'notify' ) && filter_input( INPUT_GET, 'notify', FILTER_VALIDATE_BOOLEAN ) ) {
275
			$should_redirect = false;
276
		}
277
278
		self::update_payment( $payment, $should_redirect );
279
	}
280
281
	/**
282
	 * Maybe redirect.
283
	 */
284
	public function maybe_redirect() {
285
		if ( ! filter_has_var( INPUT_GET, 'payment_redirect' ) ) {
286
			return;
287
		}
288
289
		$payment_id = filter_input( INPUT_GET, 'payment_redirect', FILTER_SANITIZE_NUMBER_INT );
290
291
		$payment = get_pronamic_payment( $payment_id );
292
293
		// HTML Answer.
294
		$html_answer = $payment->get_meta( 'ogone_directlink_html_answer' );
295
296
		if ( ! empty( $html_answer ) ) {
297
			echo $html_answer; // WPCS: XSS ok.
298
299
			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...
300
		}
301
302
		$redirect_message = $payment->get_meta( 'payment_redirect_message' );
303
304
		if ( ! empty( $redirect_message ) ) {
305
			$key = filter_input( INPUT_GET, 'key', FILTER_SANITIZE_STRING );
306
307
			if ( $key !== $payment->key ) {
308
				wp_redirect( home_url() );
309
310
				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...
311
			}
312
313
			// @see https://github.com/woothemes/woocommerce/blob/2.3.11/includes/class-wc-cache-helper.php
314
			// @see https://www.w3-edge.com/products/w3-total-cache/
315
			if ( ! defined( 'DONOTCACHEPAGE' ) ) {
316
				define( 'DONOTCACHEPAGE', true );
317
			}
318
319
			if ( ! defined( 'DONOTCACHEDB' ) ) {
320
				define( 'DONOTCACHEDB', true );
321
			}
322
323
			if ( ! defined( 'DONOTMINIFY' ) ) {
324
				define( 'DONOTMINIFY', true );
325
			}
326
327
			if ( ! defined( 'DONOTCDN' ) ) {
328
				define( 'DONOTCDN', true );
329
			}
330
331
			if ( ! defined( 'DONOTCACHEOBJECT' ) ) {
332
				define( 'DONOTCACHEOBJECT', true );
333
			}
334
335
			nocache_headers();
336
337
			include Plugin::$dirname . '/views/redirect-message.php';
338
339
			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...
340
		}
341
342
		$gateway = Plugin::get_gateway( $payment->config_id );
343
344
		if ( $gateway && $gateway->is_html_form() ) {
345
			$gateway->start( $payment );
346
347
			$error = $gateway->get_error();
348
349
			if ( is_wp_error( $error ) ) {
350
				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

350
				Plugin::render_errors( /** @scrutinizer ignore-type */ $error );
Loading history...
351
			} else {
352
				$gateway->redirect( $payment );
353
			}
354
		}
355
356
		if ( ! empty( $payment->action_url ) ) {
357
			wp_redirect( $payment->action_url );
358
359
			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...
360
		}
361
	}
362
363
	/**
364
	 * Get number payments.
365
	 *
366
	 * @return int
367
	 */
368
	public static function get_number_payments() {
369
		$number = false;
370
371
		$count = wp_count_posts( 'pronamic_payment' );
372
373
		if ( isset( $count, $count->payment_completed ) ) {
374
			$number = intval( $count->payment_completed );
375
		}
376
377
		return $number;
378
	}
379
380
	/**
381
	 * Setup, creates or updates database tables. Will only run when version changes.
382
	 */
383
	public function plugins_loaded() {
384
		// Load plugin text domain.
385
		$rel_path = dirname( plugin_basename( self::$file ) ) . '/languages/';
386
387
		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

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

492
				/** @scrutinizer ignore-type */ get_post_meta( $id, '_pronamic_gateway_mode', true )
Loading history...
493
			);
494
		}
495
496
		return $options;
497
	}
498
499
	/**
500
	 * Maybe set active payment methods option.
501
	 *
502
	 * @since unreleased
503
	 */
504
	public static function maybe_set_active_payment_methods() {
505
		$active_methods = get_option( 'pronamic_pay_active_payment_methods' );
506
507
		if ( is_array( $active_methods ) ) {
508
			return;
509
		}
510
511
		PaymentMethods::update_active_payment_methods();
512
	}
513
514
	/**
515
	 * Render errors.
516
	 *
517
	 * @param array $errors An array with errors to render.
518
	 */
519
	public static function render_errors( $errors = array() ) {
520
		if ( ! is_array( $errors ) ) {
0 ignored issues
show
introduced by
The condition is_array($errors) is always true.
Loading history...
521
			$errors = array( $errors );
522
		}
523
524
		foreach ( $errors as $error ) {
525
			include Plugin::$dirname . '/views/error.php';
526
		}
527
	}
528
529
	/**
530
	 * Get gateway.
531
	 *
532
	 * @param string|integer|boolean $config_id A gateway configuration ID.
533
	 *
534
	 * @return Gateway|null
535
	 */
536
	public static function get_gateway( $config_id ) {
537
		if ( empty( $config_id ) ) {
538
			return null;
539
		}
540
541
		$gateway_id = get_post_meta( $config_id, '_pronamic_gateway_id', true );
0 ignored issues
show
Bug introduced by
It seems like $config_id can also be of type string and boolean; however, parameter $post_id of get_post_meta() does only seem to accept integer, 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

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

659
		/** @scrutinizer ignore-call */ 
660
  $payment->user_id             = $data->get_user_id();
Loading history...
660
		$payment->config_id           = $config_id;
661
		$payment->key                 = uniqid( 'pay_' );
662
		$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

662
		/** @scrutinizer ignore-call */ 
663
  $payment->order_id            = $data->get_order_id();
Loading history...
663
		$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

663
		/** @scrutinizer ignore-call */ 
664
  $payment->currency            = $data->get_currency();
Loading history...
664
		$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

664
		/** @scrutinizer ignore-call */ 
665
  $payment->amount              = $data->get_amount();
Loading history...
665
		$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

665
		/** @scrutinizer ignore-call */ 
666
  $payment->language            = $data->get_language();
Loading history...
666
		$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

666
		/** @scrutinizer ignore-call */ 
667
  $payment->locale              = $data->get_language_and_country();
Loading history...
667
		$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

667
		/** @scrutinizer ignore-call */ 
668
  $payment->entrance_code       = $data->get_entrance_code();
Loading history...
668
		$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

668
		/** @scrutinizer ignore-call */ 
669
  $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...
669
		$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

669
		/** @scrutinizer ignore-call */ 
670
  $payment->source              = $data->get_source();
Loading history...
670
		$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

670
		/** @scrutinizer ignore-call */ 
671
  $payment->source_id           = $data->get_source_id();
Loading history...
671
		$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

671
		/** @scrutinizer ignore-call */ 
672
  $payment->email               = $data->get_email();
Loading history...
672
		$payment->status              = null;
673
		$payment->method              = $payment_method;
674
		$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

674
		/** @scrutinizer ignore-call */ 
675
  $payment->issuer              = $data->get_issuer( $payment_method );
Loading history...
675
		$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

675
		/** @scrutinizer ignore-call */ 
676
  $payment->first_name          = $data->get_first_name();
Loading history...
676
		$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

676
		/** @scrutinizer ignore-call */ 
677
  $payment->last_name           = $data->get_last_name();
Loading history...
677
		$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

677
		/** @scrutinizer ignore-call */ 
678
  $payment->customer_name       = $data->get_customer_name();
Loading history...
678
		$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

678
		/** @scrutinizer ignore-call */ 
679
  $payment->address             = $data->get_address();
Loading history...
679
		$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

679
		/** @scrutinizer ignore-call */ 
680
  $payment->zip                 = $data->get_zip();
Loading history...
680
		$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

680
		/** @scrutinizer ignore-call */ 
681
  $payment->city                = $data->get_city();
Loading history...
681
		$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

681
		/** @scrutinizer ignore-call */ 
682
  $payment->country             = $data->get_country();
Loading history...
682
		$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

682
		/** @scrutinizer ignore-call */ 
683
  $payment->telephone_number    = $data->get_telephone_number();
Loading history...
683
		$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

683
		/** @scrutinizer ignore-call */ 
684
  $payment->analytics_client_id = $data->get_analytics_client_id();
Loading history...
684
		$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

684
		/** @scrutinizer ignore-call */ 
685
  $payment->recurring           = $data->get_recurring();
Loading history...
685
		$payment->subscription        = $data->get_subscription();
686
		$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

686
		/** @scrutinizer ignore-call */ 
687
  $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...
687
		$payment->set_credit_card( $data->get_credit_card() );
688
689
		// User Agent (@see https://github.com/WordPress/WordPress/blob/4.9.4/wp-includes/comment.php#L1962-L1965).
690
		$payment->user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : null;
691
692
		// IP (@see https://github.com/WordPress/WordPress/blob/4.9.4/wp-includes/comment.php#L1957-L1960).
693
		$payment->user_ip = isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : null;
694
695
		return self::start_payment( $payment, $gateway );
696
	}
697
698
	/**
699
	 * Start payment.
700
	 *
701
	 * @param Payment $payment The payment to start at the specified gateway.
702
	 * @param Gateway $gateway The gateway to start the payment at.
703
	 *
704
	 * @return Payment
705
	 */
706
	public static function start_payment( Payment $payment, Gateway $gateway ) {
707
		global $pronamic_ideal;
708
709
		$pronamic_ideal->payments_data_store->create( $payment );
710
711
		// Prevent payment start at gateway if amount is empty.
712
		$amount = $payment->get_amount();
713
714
		if ( empty( $amount ) ) {
715
			// Keep track of free payments to update during shutdown.
716
			pronamic_pay_plugin()->payments_module->free[] = $payment->get_id();
717
718
			return $payment;
719
		}
720
721
		// Start payment at the gateway.
722
		$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...
723
724
		// If result is false the payment failed to start.
725
		if ( false === $result ) {
0 ignored issues
show
introduced by
The condition false === $result is always true.
Loading history...
726
			// If payment failed to start we directly update the payment status to 'failure'.
727
			$payment->set_status( Core\Statuses::FAILURE );
728
729
			// Check if there is a subscription attached to the payment.
730
			$subscription = $payment->get_subscription();
731
732
			if ( $subscription ) {
733
				if ( ! $payment->get_recurring() ) {
734
					// First payment.
735
					// Cancel subscription to prevent unwanted recurring payments in the future,
736
					// when a valid customer ID might be set for the user.
737
					$subscription->set_status( Core\Statuses::CANCELLED );
738
				} else {
739
					$subscription->set_status( Core\Statuses::FAILURE );
740
				}
741
742
				$subscription->save();
743
			}
744
		}
745
746
		// Check if the gateway has an error.
747
		if ( $gateway->has_error() ) {
748
			foreach ( $gateway->error->get_error_codes() as $code ) {
749
				$payment->add_note( sprintf( '%s: %s', $code, $gateway->error->get_error_message( $code ) ) );
750
			}
751
		}
752
753
		$payment->save();
754
755
		if ( $gateway->supports( 'payment_status_request' ) ) {
756
			Payments\StatusChecker::schedule_event( $payment );
757
		}
758
759
		return $payment;
760
	}
761
762
	/**
763
	 * Get pages.
764
	 *
765
	 * @return array
766
	 */
767
	public function get_pages() {
768
		$return = array();
769
770
		$pages = array(
771
			'completed' => __( 'Completed', 'pronamic_ideal' ),
772
			'cancel'    => __( 'Canceled', 'pronamic_ideal' ),
773
			'expired'   => __( 'Expired', 'pronamic_ideal' ),
774
			'error'     => __( 'Error', 'pronamic_ideal' ),
775
			'unknown'   => __( 'Unknown', 'pronamic_ideal' ),
776
		);
777
778
		foreach ( $pages as $key => $label ) {
779
			$id = sprintf( 'pronamic_pay_%s_page_id', $key );
780
781
			$return[ $id ] = $label;
782
		}
783
784
		return $return;
785
	}
786
}
787