Completed
Push — update/wpcom-premium-block-reg... ( ceb48a )
by Jeremy
07:15
created

Jetpack_Simple_Payments::parse_shortcode()   C

Complexity

Conditions 11
Paths 11

Size

Total Lines 55

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
nc 11
nop 2
dl 0
loc 55
rs 6.8351
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/*
3
 * Simple Payments lets users embed a PayPal button fully integrated with wpcom to sell products on the site.
4
 * This is not a proper module yet, because not all the pieces are in place. Until everything is shipped, it can be turned
5
 * into module that can be enabled/disabled.
6
*/
7
class Jetpack_Simple_Payments {
8
	// These have to be under 20 chars because that is CPT limit.
9
	static $post_type_order = 'jp_pay_order';
10
	static $post_type_product = 'jp_pay_product';
11
12
	static $shortcode = 'simple-payment';
13
14
	static $css_classname_prefix = 'jetpack-simple-payments';
15
16
	// Increase this number each time there's a change in CSS or JS to bust cache.
17
	static $version = '0.25';
18
19
	// Classic singleton pattern:
20
	private static $instance;
21
	private function __construct() {}
22
	static function getInstance() {
23
		if ( ! self::$instance ) {
24
			self::$instance = new self();
25
			self::$instance->register_init_hooks();
26
		}
27
		return self::$instance;
28
	}
29
30
	private function register_scripts_and_styles() {
31
		/**
32
		 * Paypal heavily discourages putting that script in your own server:
33
		 * @see https://developer.paypal.com/docs/integration/direct/express-checkout/integration-jsv4/add-paypal-button/
34
		 */
35
		wp_register_script( 'paypal-checkout-js', 'https://www.paypalobjects.com/api/checkout.js', array(), null, true );
36
		wp_register_script( 'paypal-express-checkout', plugins_url( '/paypal-express-checkout.js', __FILE__ ),
37
			array( 'jquery', 'paypal-checkout-js' ), self::$version );
38
		wp_register_style( 'jetpack-simple-payments', plugins_url( '/simple-payments.css', __FILE__ ), array( 'dashicons' ) );
39
	}
40
41
	private function register_init_hooks() {
42
		add_action( 'init', array( $this, 'init_hook_action' ) );
43
		add_action( 'rest_api_init', array( $this, 'register_meta_fields_in_rest_api' ) );
44
	}
45
46
	private function register_shortcode() {
47
		add_shortcode( self::$shortcode, array( $this, 'parse_shortcode' ) );
48
	}
49
50
	public function init_hook_action() {
51
		add_filter( 'rest_api_allowed_post_types', array( $this, 'allow_rest_api_types' ) );
52
		add_filter( 'jetpack_sync_post_meta_whitelist', array( $this, 'allow_sync_post_meta' ) );
53
		if ( ! is_admin() ) {
54
			$this->register_scripts_and_styles();
55
		}
56
		$this->register_shortcode();
57
		$this->setup_cpts();
58
59
		add_filter( 'the_content', array( $this, 'remove_auto_paragraph_from_product_description' ), 0 );
60
61
		// Register block.
62
		jetpack_register_block(
63
			'jetpack/simple-payments',
64
			array(),
65
			array(
66
				'wpcom'   => 'value_bundle',
67
				'jetpack' => 'jetpack_premium',
68
			)
69
		);
70
	}
71
72
	function remove_auto_paragraph_from_product_description( $content ) {
73
		if ( get_post_type() === self::$post_type_product ) {
74
			remove_filter( 'the_content', 'wpautop' );
75
		}
76
77
		return $content;
78
	}
79
80
	function get_blog_id() {
81
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
82
			return get_current_blog_id();
83
		}
84
85
		return Jetpack_Options::get_option( 'id' );
86
	}
87
88
	/**
89
	 * Used to check whether Simple Payments are enabled for given site.
90
	 *
91
	 * @return bool True if Simple Payments are enabled, false otherwise.
92
	 */
93
	function is_enabled_jetpack_simple_payments() {
94
		/**
95
		 * Can be used by plugin authors to disable the conflicting output of Simple Payments.
96
		 *
97
		 * @since 6.3.0
98
		 *
99
		 * @param bool True if Simple Payments should be disabled, false otherwise.
100
		 */
101
		if ( apply_filters( 'jetpack_disable_simple_payments', false ) ) {
102
			return false;
103
		}
104
105
		// For WPCOM sites
106 View Code Duplication
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM && function_exists( 'has_any_blog_stickers' ) ) {
107
			$site_id = $this->get_blog_id();
108
			return has_any_blog_stickers( array( 'premium-plan', 'business-plan', 'ecommerce-plan' ), $site_id );
109
		}
110
111
		// For all Jetpack sites
112
		return Jetpack::is_active() && Jetpack_Plan::supports( 'simple-payments');
113
	}
114
115
	function parse_shortcode( $attrs, $content = false ) {
116
		if ( empty( $attrs['id'] ) ) {
117
			return;
118
		}
119
		$product = get_post( $attrs['id'] );
120
		if ( ! $product || is_wp_error( $product ) ) {
121
			return;
122
		}
123
		if ( $product->post_type !== self::$post_type_product || 'publish' !== $product->post_status ) {
124
			return;
125
		}
126
127
		// We allow for overriding the presentation labels
128
		$data = shortcode_atts( array(
129
			'blog_id'     => $this->get_blog_id(),
130
			'dom_id'      => uniqid( self::$css_classname_prefix . '-' . $product->ID . '_', true ),
131
			'class'       => self::$css_classname_prefix . '-' . $product->ID,
132
			'title'       => get_the_title( $product ),
133
			'description' => $product->post_content,
134
			'cta'         => get_post_meta( $product->ID, 'spay_cta', true ),
135
			'multiple'    => get_post_meta( $product->ID, 'spay_multiple', true ) || '0'
136
		), $attrs );
137
138
		$data['price'] = $this->format_price(
139
			get_post_meta( $product->ID, 'spay_price', true ),
140
			get_post_meta( $product->ID, 'spay_currency', true )
141
		);
142
143
		$data['id'] = $attrs['id'];
144
145
		if( ! wp_style_is( 'jetpack-simple-payments', 'enqueued' ) ) {
146
			wp_enqueue_style( 'jetpack-simple-payments' );
147
		}
148
149
		if ( ! $this->is_enabled_jetpack_simple_payments() ) {
150
			if ( ! is_feed() ) {
151
				$this->output_admin_warning( $data );
152
			}
153
			return;
154
		}
155
156
		if ( ! wp_script_is( 'paypal-express-checkout', 'enqueued' ) ) {
157
			wp_enqueue_script( 'paypal-express-checkout' );
158
		}
159
160
		wp_add_inline_script( 'paypal-express-checkout', sprintf(
161
			"try{PaypalExpressCheckout.renderButton( '%d', '%d', '%s', '%d' );}catch(e){}",
162
			esc_js( $data['blog_id'] ),
163
			esc_js( $attrs['id'] ),
164
			esc_js( $data['dom_id'] ),
165
			esc_js( $data['multiple'] )
166
		) );
167
168
		return $this->output_shortcode( $data );
169
	}
170
171
	function output_admin_warning( $data ) {
172
		if ( ! current_user_can( 'manage_options' ) ) {
173
			return;
174
		}
175
176
		jetpack_require_lib( 'components' );
177
		return Jetpack_Components::render_upgrade_nudge( array(
178
			'plan' => ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ? 'value_bundle' : 'jetpack_premium',
179
		) );
180
	}
181
182
	function output_shortcode( $data ) {
183
		$items = '';
184
		$css_prefix = self::$css_classname_prefix;
185
186
		if ( $data['multiple'] ) {
187
			$items = sprintf( '
188
				<div class="%1$s">
189
					<input class="%2$s" type="number" value="1" min="1" id="%3$s" />
190
				</div>
191
				',
192
				esc_attr( "${css_prefix}-items" ),
193
				esc_attr( "${css_prefix}-items-number" ),
194
				esc_attr( "{$data['dom_id']}_number" )
195
			);
196
		}
197
		$image = "";
198
		if( has_post_thumbnail( $data['id'] ) ) {
199
			$image = sprintf( '<div class="%1$s"><div class="%2$s">%3$s</div></div>',
200
				esc_attr( "${css_prefix}-product-image" ),
201
				esc_attr( "${css_prefix}-image" ),
202
				get_the_post_thumbnail( $data['id'], 'full' )
203
			);
204
		}
205
		return sprintf( '
206
<div class="%1$s">
207
	<div class="%2$s">
208
		%3$s
209
		<div class="%4$s">
210
			<div class="%5$s"><p>%6$s</p></div>
211
			<div class="%7$s"><p>%8$s</p></div>
212
			<div class="%9$s"><p>%10$s</p></div>
213
			<div class="%11$s" id="%12$s"></div>
214
			<div class="%13$s">
215
				%14$s
216
				<div class="%15$s" id="%16$s"></div>
217
			</div>
218
		</div>
219
	</div>
220
</div>
221
',
222
			esc_attr( "{$data['class']} ${css_prefix}-wrapper" ),
223
			esc_attr( "${css_prefix}-product" ),
224
			$image,
225
			esc_attr( "${css_prefix}-details" ),
226
			esc_attr( "${css_prefix}-title" ),
227
			esc_html( $data['title'] ),
228
			esc_attr( "${css_prefix}-description" ),
229
			wp_kses( $data['description'], wp_kses_allowed_html( 'post' ) ),
230
			esc_attr( "${css_prefix}-price" ),
231
			esc_html( $data['price'] ),
232
			esc_attr( "${css_prefix}-purchase-message" ),
233
			esc_attr( "{$data['dom_id']}-message-container" ),
234
			esc_attr( "${css_prefix}-purchase-box" ),
235
			$items,
236
			esc_attr( "${css_prefix}-button" ),
237
			esc_attr( "{$data['dom_id']}_button" )
238
		);
239
	}
240
241
	/**
242
	 * Format a price with currency
243
	 *
244
	 * Uses currency-aware formatting to output a formatted price with a simple fallback.
245
	 *
246
	 * Largely inspired by WordPress.com's Store_Price::display_currency
247
	 *
248
	 * @param  string $price    Price.
249
	 * @param  string $currency Currency.
250
	 * @return string           Formatted price.
251
	 */
252
	private function format_price( $price, $currency ) {
253
		$currency_details = self::get_currency( $currency );
254
255
		if ( $currency_details ) {
256
			// Ensure USD displays as 1234.56 even in non-US locales.
257
			$amount = 'USD' === $currency
258
				? number_format( $price, $currency_details['decimal'], '.', ',' )
259
				: number_format_i18n( $price, $currency_details['decimal'] );
260
261
			return sprintf(
262
				$currency_details['format'],
263
				$currency_details['symbol'],
264
				$amount
265
			);
266
		}
267
268
		// Fall back to unspecified currency symbol like `¤1,234.05`.
269
		// @link https://en.wikipedia.org/wiki/Currency_sign_(typography).
270
		if ( ! $currency ) {
271
			return '¤' . number_format_i18n( $price, 2 );
272
		}
273
274
		return number_format_i18n( $price, 2 ) . ' ' . $currency;
275
	}
276
277
	/**
278
	 * Allows custom post types to be used by REST API.
279
	 * @param $post_types
280
	 * @see hook 'rest_api_allowed_post_types'
281
	 * @return array
282
	 */
283
	function allow_rest_api_types( $post_types ) {
284
		$post_types[] = self::$post_type_order;
285
		$post_types[] = self::$post_type_product;
286
		return $post_types;
287
	}
288
289
	function allow_sync_post_meta( $post_meta ) {
290
		return array_merge( $post_meta, array(
291
			'spay_paypal_id',
292
			'spay_status',
293
			'spay_product_id',
294
			'spay_quantity',
295
			'spay_price',
296
			'spay_customer_email',
297
			'spay_currency',
298
			'spay_cta',
299
			'spay_email',
300
			'spay_multiple',
301
			'spay_formatted_price',
302
		) );
303
	}
304
305
	/**
306
	 * Enable Simple payments custom meta values for access through the REST API.
307
	 * Field’s value will be exposed on a .meta key in the endpoint response,
308
	 * and WordPress will handle setting up the callbacks for reading and writing
309
	 * to that meta key.
310
	 *
311
	 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/
312
	 */
313
	public function register_meta_fields_in_rest_api() {
314
		register_meta( 'post', 'spay_price', array(
315
			'description'       => esc_html__( 'Simple payments; price.', 'jetpack' ),
316
			'object_subtype'    => self::$post_type_product,
317
			'sanitize_callback' => array( $this, 'sanitize_price' ),
318
			'show_in_rest'      => true,
319
			'single'            => true,
320
			'type'              => 'number',
321
		) );
322
323
		register_meta( 'post', 'spay_currency', array(
324
			'description'       => esc_html__( 'Simple payments; currency code.', 'jetpack' ),
325
			'object_subtype'    => self::$post_type_product,
326
			'sanitize_callback' => array( $this, 'sanitize_currency' ),
327
			'show_in_rest'      => true,
328
			'single'            => true,
329
			'type'              => 'string',
330
		) );
331
332
		register_meta( 'post', 'spay_cta', array(
333
			'description'       => esc_html__( 'Simple payments; text with "Buy" or other CTA', 'jetpack' ),
334
			'object_subtype'    => self::$post_type_product,
335
			'sanitize_callback' => 'sanitize_text_field',
336
			'show_in_rest'      => true,
337
			'single'            => true,
338
			'type'              => 'string',
339
		) );
340
341
		register_meta( 'post', 'spay_multiple', array(
342
			'description'       => esc_html__( 'Simple payments; allow multiple items', 'jetpack' ),
343
			'object_subtype'    => self::$post_type_product,
344
			'sanitize_callback' => 'rest_sanitize_boolean',
345
			'show_in_rest'      => true,
346
			'single'            => true,
347
			'type'              => 'boolean',
348
		) );
349
350
		register_meta( 'post', 'spay_email', array(
351
			'description'       => esc_html__( 'Simple payments button; paypal email.', 'jetpack' ),
352
			'sanitize_callback' => 'sanitize_email',
353
			'show_in_rest'      => true,
354
			'single'            => true,
355
			'type'              => 'string',
356
		) );
357
358
		register_meta( 'post', 'spay_status', array(
359
			'description'       => esc_html__( 'Simple payments; status.', 'jetpack' ),
360
			'object_subtype'    => self::$post_type_product,
361
			'sanitize_callback' => 'sanitize_text_field',
362
			'show_in_rest'      => true,
363
			'single'            => true,
364
			'type'              => 'string',
365
		) );
366
	}
367
368
	/**
369
	 * Sanitize three-character ISO-4217 Simple payments currency
370
	 *
371
	 * List has to be in sync with list at the block's client side and widget's backend side:
372
	 * @link https://github.com/Automattic/jetpack/blob/31efa189ad223c0eb7ad085ac0650a23facf9ef5/extensions/blocks/simple-payments/constants.js#L9-L39
373
	 * @link https://github.com/Automattic/jetpack/blob/31efa189ad223c0eb7ad085ac0650a23facf9ef5/modules/widgets/simple-payments.php#L19-L44
374
	 *
375
	 * Currencies should be supported by PayPal:
376
	 * @link https://developer.paypal.com/docs/api/reference/currency-codes/
377
	 *
378
	 * Indian Rupee (INR) not supported because at the time of the creation of this file
379
	 * because it's limited to in-country PayPal India accounts only.
380
	 * Discussion: https://github.com/Automattic/wp-calypso/pull/28236
381
	 */
382
	public static function sanitize_currency( $currency ) {
383
		$valid_currencies = array(
384
			'USD',
385
			'EUR',
386
			'AUD',
387
			'BRL',
388
			'CAD',
389
			'CZK',
390
			'DKK',
391
			'HKD',
392
			'HUF',
393
			'ILS',
394
			'JPY',
395
			'MYR',
396
			'MXN',
397
			'TWD',
398
			'NZD',
399
			'NOK',
400
			'PHP',
401
			'PLN',
402
			'GBP',
403
			'RUB',
404
			'SGD',
405
			'SEK',
406
			'CHF',
407
			'THB',
408
		);
409
410
		return in_array( $currency, $valid_currencies ) ? $currency : false;
411
	}
412
413
	/**
414
	 * Sanitize price:
415
	 *
416
	 * Positive integers and floats
417
	 * Supports two decimal places.
418
	 * Maximum length: 10.
419
	 *
420
	 * See `price` from PayPal docs:
421
	 * @link https://developer.paypal.com/docs/api/orders/v1/#definition-item
422
	 *
423
	 * @param      $value
424
	 * @return null|string
425
	 */
426
	public static function sanitize_price( $price ) {
427
		return preg_match( '/^[0-9]{0,10}(\.[0-9]{0,2})?$/', $price ) ? $price : false;
428
	}
429
430
	/**
431
	 * Sets up the custom post types for the module.
432
	 */
433
	function setup_cpts() {
434
435
		/*
436
		 * ORDER data structure. holds:
437
		 * title = customer_name | 4xproduct_name
438
		 * excerpt = customer_name + customer contact info + customer notes from paypal form
439
		 * metadata:
440
		 * spay_paypal_id - paypal id of transaction
441
		 * spay_status
442
		 * spay_product_id - post_id of bought product
443
		 * spay_quantity - quantity of product
444
		 * spay_price - item price at the time of purchase
445
		 * spay_customer_email - customer email
446
		 * ... (WIP)
447
		 */
448
		$order_capabilities = array(
449
			'edit_post'             => 'edit_posts',
450
			'read_post'             => 'read_private_posts',
451
			'delete_post'           => 'delete_posts',
452
			'edit_posts'            => 'edit_posts',
453
			'edit_others_posts'     => 'edit_others_posts',
454
			'publish_posts'         => 'publish_posts',
455
			'read_private_posts'    => 'read_private_posts',
456
		);
457
		$order_args = array(
458
			'label'                 => esc_html_x( 'Order', 'noun: a quantity of goods or items purchased or sold', 'jetpack' ),
459
			'description'           => esc_html__( 'Simple Payments orders', 'jetpack' ),
460
			'supports'              => array( 'custom-fields', 'excerpt' ),
461
			'hierarchical'          => false,
462
			'public'                => false,
463
			'show_ui'               => false,
464
			'show_in_menu'          => false,
465
			'show_in_admin_bar'     => false,
466
			'show_in_nav_menus'     => false,
467
			'can_export'            => true,
468
			'has_archive'           => false,
469
			'exclude_from_search'   => true,
470
			'publicly_queryable'    => false,
471
			'rewrite'               => false,
472
			'capabilities'          => $order_capabilities,
473
			'show_in_rest'          => true,
474
		);
475
		register_post_type( self::$post_type_order, $order_args );
476
477
		/*
478
		 * PRODUCT data structure. Holds:
479
		 * title - title
480
		 * content - description
481
		 * thumbnail - image
482
		 * metadata:
483
		 * spay_price - price
484
		 * spay_formatted_price
485
		 * spay_currency - currency code
486
		 * spay_cta - text with "Buy" or other CTA
487
		 * spay_email - paypal email
488
		 * spay_multiple - allow for multiple items
489
		 * spay_status - status. { enabled | disabled }
490
		 */
491
		$product_capabilities = array(
492
			'edit_post'             => 'edit_posts',
493
			'read_post'             => 'read_private_posts',
494
			'delete_post'           => 'delete_posts',
495
			'edit_posts'            => 'publish_posts',
496
			'edit_others_posts'     => 'edit_others_posts',
497
			'publish_posts'         => 'publish_posts',
498
			'read_private_posts'    => 'read_private_posts',
499
		);
500
		$product_args = array(
501
			'label'                 => esc_html__( 'Product', 'jetpack' ),
502
			'description'           => esc_html__( 'Simple Payments products', 'jetpack' ),
503
			'supports'              => array( 'title', 'editor','thumbnail', 'custom-fields', 'author' ),
504
			'hierarchical'          => false,
505
			'public'                => false,
506
			'show_ui'               => false,
507
			'show_in_menu'          => false,
508
			'show_in_admin_bar'     => false,
509
			'show_in_nav_menus'     => false,
510
			'can_export'            => true,
511
			'has_archive'           => false,
512
			'exclude_from_search'   => true,
513
			'publicly_queryable'    => false,
514
			'rewrite'               => false,
515
			'capabilities'          => $product_capabilities,
516
			'show_in_rest'          => true,
517
		);
518
		register_post_type( self::$post_type_product, $product_args );
519
	}
520
521
	/**
522
	 * Format a price for display
523
	 *
524
	 * Largely taken from WordPress.com Store_Price class
525
	 *
526
	 * The currency array will have the shape:
527
	 *   format  => string sprintf format with placeholders `%1$s`: Symbol `%2$s`: Price.
528
	 *   symbol  => string Symbol string
529
	 *   desc    => string Text description of currency
530
	 *   decimal => int    Number of decimal places
531
	 *
532
	 * @param  string $the_currency The desired currency, e.g. 'USD'.
533
	 * @return ?array               Currency object or null if not found.
0 ignored issues
show
Documentation introduced by
The doc-type ?array could not be parsed: Unknown type name "?array" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
534
	 */
535
	private static function get_currency( $the_currency ) {
536
		$currencies = array(
537
			'USD' => array(
538
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
539
				'symbol'  => '$',
540
				'decimal' => 2,
541
			),
542
			'GBP' => array(
543
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
544
				'symbol'  => '&#163;',
545
				'decimal' => 2,
546
			),
547
			'JPY' => array(
548
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
549
				'symbol'  => '&#165;',
550
				'decimal' => 0,
551
			),
552
			'BRL' => array(
553
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
554
				'symbol'  => 'R$',
555
				'decimal' => 2,
556
			),
557
			'EUR' => array(
558
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
559
				'symbol'  => '&#8364;',
560
				'decimal' => 2,
561
			),
562
			'NZD' => array(
563
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
564
				'symbol'  => 'NZ$',
565
				'decimal' => 2,
566
			),
567
			'AUD' => array(
568
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
569
				'symbol'  => 'A$',
570
				'decimal' => 2,
571
			),
572
			'CAD' => array(
573
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
574
				'symbol'  => 'C$',
575
				'decimal' => 2,
576
			),
577
			'ILS' => array(
578
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
579
				'symbol'  => '₪',
580
				'decimal' => 2,
581
			),
582
			'RUB' => array(
583
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
584
				'symbol'  => '₽',
585
				'decimal' => 2,
586
			),
587
			'MXN' => array(
588
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
589
				'symbol'  => 'MX$',
590
				'decimal' => 2,
591
			),
592
			'MYR' => array(
593
				'format'  => '%2$s%1$s', // 1: Symbol 2: currency value
594
				'symbol'  => 'RM',
595
				'decimal' => 2,
596
			),
597
			'SEK' => array(
598
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
599
				'symbol'  => 'Skr',
600
				'decimal' => 2,
601
			),
602
			'HUF' => array(
603
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
604
				'symbol'  => 'Ft',
605
				'decimal' => 0, // Decimals are supported by Stripe but not by PayPal.
606
			),
607
			'CHF' => array(
608
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
609
				'symbol'  => 'CHF',
610
				'decimal' => 2,
611
			),
612
			'CZK' => array(
613
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
614
				'symbol'  => 'Kč',
615
				'decimal' => 2,
616
			),
617
			'DKK' => array(
618
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
619
				'symbol'  => 'Dkr',
620
				'decimal' => 2,
621
			),
622
			'HKD' => array(
623
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
624
				'symbol'  => 'HK$',
625
				'decimal' => 2,
626
			),
627
			'NOK' => array(
628
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
629
				'symbol'  => 'Kr',
630
				'decimal' => 2,
631
			),
632
			'PHP' => array(
633
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
634
				'symbol'  => '₱',
635
				'decimal' => 2,
636
			),
637
			'PLN' => array(
638
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
639
				'symbol'  => 'PLN',
640
				'decimal' => 2,
641
			),
642
			'SGD' => array(
643
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
644
				'symbol'  => 'S$',
645
				'decimal' => 2,
646
			),
647
			'TWD' => array(
648
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
649
				'symbol'  => 'NT$',
650
				'decimal' => 0, // Decimals are supported by Stripe but not by PayPal.
651
			),
652
			'THB' => array(
653
				'format'  => '%2$s%1$s', // 1: Symbol 2: currency value
654
				'symbol'  => '฿',
655
				'decimal' => 2,
656
			),
657
		);
658
659
		if ( isset( $currencies[ $the_currency ] ) ) {
660
			return $currencies[ $the_currency ];
661
		}
662
		return null;
663
	}
664
}
665
Jetpack_Simple_Payments::getInstance();
666