Completed
Push — master ( 4cc53b...9f385c )
by
unknown
03:15 queued 53s
created

WC_Stripe_Apple_Pay_Registration::get_option()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
1
<?php
2
/**
3
 * Stripe Apple Pay Registration Class.
4
 *
5
 * @since 4.0.6
6
 */
7
8
if ( ! defined( 'ABSPATH' ) ) {
9
	exit;
10
}
11
12
class WC_Stripe_Apple_Pay_Registration {
13
	/**
14
	 * Enabled.
15
	 *
16
	 * @var
17
	 */
18
	public $stripe_settings;
19
20
	/**
21
	 * Main Stripe Enabled.
22
	 *
23
	 * @var bool
24
	 */
25
	public $stripe_enabled;
26
27
	/**
28
	 * Do we accept Payment Request?
29
	 *
30
	 * @var bool
31
	 */
32
	public $payment_request;
33
34
	/**
35
	 * Apple Pay Domain Set.
36
	 *
37
	 * @var bool
38
	 */
39
	public $apple_pay_domain_set;
40
41
	/**
42
	 * Secret Key.
43
	 *
44
	 * @var string
45
	 */
46
	public $secret_key;
47
48
	/**
49
	 * Stores Apple Pay domain verification issues.
50
	 *
51
	 * @var string
52
	 */
53
	public $apple_pay_verify_notice;
54
55
	public function __construct() {
56
		add_action( 'woocommerce_stripe_updated', array( $this, 'verify_domain_if_needed' ) );
57
		add_action( 'update_option_woocommerce_stripe_settings', array( $this, 'verify_domain_on_new_secret_key' ), 10, 2 );
58
59
		$this->stripe_settings         = get_option( 'woocommerce_stripe_settings', array() );
60
		$this->stripe_enabled          = $this->get_option( 'enabled' );
0 ignored issues
show
Documentation Bug introduced by
The property $stripe_enabled was declared of type boolean, but $this->get_option('enabled') is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
61
		$this->payment_request         = 'yes' === $this->get_option( 'payment_request', 'yes' );
62
		$this->apple_pay_domain_set    = 'yes' === $this->get_option( 'apple_pay_domain_set', 'no' );
63
		$this->apple_pay_verify_notice = '';
64
		$this->secret_key              = $this->get_secret_key();
65
66
		if ( empty( $this->stripe_settings ) ) {
67
			return;
68
		}
69
70
		$this->init_apple_pay();
71
72
		add_action( 'admin_notices', array( $this, 'admin_notices' ) );
73
	}
74
75
	/**
76
	 * Gets the Stripe settings.
77
	 *
78
	 * @since 4.0.6
79
	 * @param string $setting
80
	 * @param string default
81
	 * @return string $setting_value
82
	 */
83
	public function get_option( $setting = '', $default = '' ) {
84
		if ( empty( $this->stripe_settings ) ) {
85
			return $default;
86
		}
87
88
		if ( ! empty( $this->stripe_settings[ $setting ] ) ) {
89
			return $this->stripe_settings[ $setting ];
90
		}
91
92
		return $default;
93
	}
94
95
	/**
96
	 * Gets the Stripe secret key for the current mode.
97
	 *
98
	 * @since 4.5.3
99
	 * @return string Secret key.
100
	 */
101
	private function get_secret_key() {
102
		$testmode = 'yes' === $this->get_option( 'testmode', 'no' );
103
		return $testmode ? $this->get_option( 'test_secret_key' ) : $this->get_option( 'secret_key' );
104
	}
105
106
	/**
107
	 * Initializes Apple Pay process on settings page.
108
	 *
109
	 * @since 3.1.0
110
	 * @version 3.1.0
111
	 */
112
	public function init_apple_pay() {
113
		if (
114
			is_admin() &&
115
			isset( $_GET['page'] ) && 'wc-settings' === $_GET['page'] &&
116
			isset( $_GET['tab'] ) && 'checkout' === $_GET['tab'] &&
117
			isset( $_GET['section'] ) && 'stripe' === $_GET['section'] &&
118
			$this->payment_request
119
		) {
120
			$this->verify_domain();
121
		}
122
	}
123
124
	/**
125
	 * Registers the domain with Stripe/Apple Pay
126
	 *
127
	 * @since 3.1.0
128
	 * @version 3.1.0
129
	 * @param string $secret_key
130
	 */
131
	private function register_domain_with_apple( $secret_key = '' ) {
132
		if ( empty( $secret_key ) ) {
133
			throw new Exception( __( 'Unable to verify domain - missing secret key.', 'woocommerce-gateway-stripe' ) );
134
		}
135
136
		$endpoint = 'https://api.stripe.com/v1/apple_pay/domains';
137
138
		$data = array(
139
			'domain_name' => $_SERVER['HTTP_HOST'],
140
		);
141
142
		$headers = array(
143
			'User-Agent'    => 'WooCommerce Stripe Apple Pay',
144
			'Authorization' => 'Bearer ' . $secret_key,
145
		);
146
147
		$response = wp_remote_post(
148
			$endpoint,
149
			array(
150
				'headers' => $headers,
151
				'body'    => http_build_query( $data ),
152
			)
153
		);
154
155
		if ( is_wp_error( $response ) ) {
156
			/* translators: error message */
157
			throw new Exception( sprintf( __( 'Unable to verify domain - %s', 'woocommerce-gateway-stripe' ), $response->get_error_message() ) );
158
		}
159
160
		if ( 200 !== $response['response']['code'] ) {
161
			$parsed_response = json_decode( $response['body'] );
162
163
			$this->apple_pay_verify_notice = $parsed_response->error->message;
164
165
			/* translators: error message */
166
			throw new Exception( sprintf( __( 'Unable to verify domain - %s', 'woocommerce-gateway-stripe' ), $parsed_response->error->message ) );
167
		}
168
	}
169
170
	/**
171
	 * Updates the Apple Pay domain association file.
172
	 *
173
	 * @param bool $force True to create the file if it didn't exist, false for just updating the file if needed.
174
	 *
175
	 * @version 4.3.0
176
	 * @since 4.3.0
177
	 * @return bool True on success, false on failure.
178
	 */
179
	public function update_domain_association_file( $force = false ) {
180
			$path     = untrailingslashit( $_SERVER['DOCUMENT_ROOT'] );
181
			$dir      = '.well-known';
182
			$file     = 'apple-developer-merchantid-domain-association';
183
			$fullpath = $path . '/' . $dir . '/' . $file;
184
185
			$existing_contents = @file_get_contents( $fullpath );
186
			$new_contents = @file_get_contents( WC_STRIPE_PLUGIN_PATH . '/' . $file );
187
			if ( ( ! $existing_contents && ! $force ) || $existing_contents === $new_contents ) {
188
				return true;
189
			}
190
191
			if ( ! file_exists( $path . '/' . $dir ) ) {
192 View Code Duplication
				if ( ! @mkdir( $path . '/' . $dir, 0755 ) ) { // @codingStandardsIgnoreLine
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...
193
					WC_Stripe_Logger::log( 'Error: ' . __( 'Unable to create domain association folder to domain root.', 'woocommerce-gateway-stripe' ) );
194
					return false;
195
				}
196
			}
197
198 View Code Duplication
			if ( ! @copy( WC_STRIPE_PLUGIN_PATH . '/' . $file, $fullpath ) ) { // @codingStandardsIgnoreLine
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...
199
				WC_Stripe_Logger::log( 'Error: ' . __( 'Unable to copy domain association file to domain root.', 'woocommerce-gateway-stripe' ) );
200
				return false;
201
			}
202
203
			WC_Stripe_Logger::log( 'Domain association file updated.' );
204
			return true;
205
	}
206
207
	/**
208
	 * Processes the Apple Pay domain verification.
209
	 *
210
	 * @since 3.1.0
211
	 * @version 3.1.0
212
	 */
213
	public function verify_domain() {
214
		if ( ! $this->update_domain_association_file( true ) ) {
215
			$this->stripe_settings['apple_pay_domain_set'] = 'no';
216
			update_option( 'woocommerce_stripe_settings', $this->stripe_settings );
217
			return;
218
		}
219
220
		try {
221
			// At this point then the domain association folder and file should be available.
222
			// Proceed to verify/and or verify again.
223
			$this->register_domain_with_apple( $this->secret_key );
224
225
			// No errors to this point, verification success!
226
			$this->stripe_settings['apple_pay_domain_set'] = 'yes';
227
			$this->apple_pay_domain_set                    = true;
228
229
			update_option( 'woocommerce_stripe_settings', $this->stripe_settings );
230
231
			WC_Stripe_Logger::log( 'Your domain has been verified with Apple Pay!' );
232
233
		} catch ( Exception $e ) {
234
			$this->stripe_settings['apple_pay_domain_set'] = 'no';
235
236
			update_option( 'woocommerce_stripe_settings', $this->stripe_settings );
237
238
			WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() );
239
		}
240
	}
241
242
	/**
243
	 * Conditionally process the Apple Pay domain verification after a new secret key is set.
244
	 *
245
	 * @since 4.5.3
246
	 * @version 4.5.3
247
	 */
248
	public function verify_domain_on_new_secret_key( $prev_settings, $settings ) {
249
		$this->stripe_settings = $prev_settings;
250
		$prev_secret_key = $this->get_secret_key();
251
252
		$this->stripe_settings = $settings;
253
		$this->secret_key = $this->get_secret_key();
254
255
		if ( ! empty( $this->secret_key ) && $this->secret_key !== $prev_secret_key ) {
256
			$this->verify_domain();
257
		}
258
	}
259
260
	/**
261
	 * Process the Apple Pay domain verification if not already done - otherwise just update the file.
262
	 *
263
	 * @since 4.5.3
264
	 * @version 4.5.3
265
	 */
266
	public function verify_domain_if_needed() {
267
		if ( $this->apple_pay_domain_set ) {
268
			$this->update_domain_association_file();
269
		} else {
270
			$this->verify_domain();
271
		}
272
	}
273
274
	/**
275
	 * Display any admin notices to the user.
276
	 *
277
	 * @since 4.0.6
278
	 */
279
	public function admin_notices() {
280
		if ( ! $this->stripe_enabled ) {
281
			return;
282
		}
283
284
		if ( ! current_user_can( 'manage_woocommerce' ) ) {
285
			return;
286
		}
287
288
		if ( $this->payment_request && ! empty( $this->apple_pay_verify_notice ) ) {
289
			$allowed_html = array(
290
				'a' => array(
291
					'href'  => array(),
292
					'title' => array(),
293
				),
294
			);
295
296
			echo '<div class="error stripe-apple-pay-message"><p>' . wp_kses( make_clickable( $this->apple_pay_verify_notice ), $allowed_html ) . '</p></div>';
297
		}
298
299
		/**
300
		 * Apple pay is enabled by default and domain verification initializes
301
		 * when setting screen is displayed. So if domain verification is not set,
302
		 * something went wrong so lets notify user.
303
		 */
304
		if ( ! empty( $this->secret_key ) && $this->payment_request && ! $this->apple_pay_domain_set ) {
305
			/* translators: 1) HTML anchor open tag 2) HTML anchor closing tag */
306
			echo '<div class="error stripe-apple-pay-message"><p>' . sprintf( __( 'Apple Pay domain verification failed. Please check the %1$slog%2$s to see the issue. (Logging must be enabled to see recorded logs)', 'woocommerce-gateway-stripe' ), '<a href="' . admin_url( 'admin.php?page=wc-status&tab=logs' ) . '">', '</a>' ) . '</p></div>';
307
		}
308
	}
309
}
310
311
new WC_Stripe_Apple_Pay_Registration();
312