Completed
Push — kraftbj-patch-1 ( 599bd6...9b0476 )
by
unknown
145:59 queued 137:31
created

Jetpack_Simple_Payments::sanitize_price()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
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( 'jetpack_register_gutenberg_extensions', array( $this, 'register_gutenberg_block' ) );
44
		add_action( 'rest_api_init', array( $this, 'register_meta_fields_in_rest_api' ) );
45
	}
46
47
	private function register_shortcode() {
48
		add_shortcode( self::$shortcode, array( $this, 'parse_shortcode' ) );
49
	}
50
51
	public function init_hook_action() {
52
		add_filter( 'rest_api_allowed_post_types', array( $this, 'allow_rest_api_types' ) );
53
		add_filter( 'jetpack_sync_post_meta_whitelist', array( $this, 'allow_sync_post_meta' ) );
54
		if ( ! is_admin() ) {
55
			$this->register_scripts_and_styles();
56
		}
57
		$this->register_shortcode();
58
		$this->setup_cpts();
59
60
		add_filter( 'the_content', array( $this, 'remove_auto_paragraph_from_product_description' ), 0 );
61
	}
62
63
	function register_gutenberg_block() {
64
		if ( $this->is_enabled_jetpack_simple_payments() ) {
65
			jetpack_register_block( 'jetpack/simple-payments' );
66
		} else {
67
			Jetpack_Gutenberg::set_extension_unavailable( 'jetpack/simple-payments', 'missing_plan' );
68
		}
69
	}
70
71
	function remove_auto_paragraph_from_product_description( $content ) {
72
		if ( get_post_type() === self::$post_type_product ) {
73
			remove_filter( 'the_content', 'wpautop' );
74
		}
75
76
		return $content;
77
	}
78
79
	function get_blog_id() {
80
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
81
			return get_current_blog_id();
82
		}
83
84
		return Jetpack_Options::get_option( 'id' );
85
	}
86
87
	/**
88
	 * Used to check whether Simple Payments are enabled for given site.
89
	 *
90
	 * @return bool True if Simple Payments are enabled, false otherwise.
91
	 */
92
	function is_enabled_jetpack_simple_payments() {
93
		/**
94
		 * Can be used by plugin authors to disable the conflicting output of Simple Payments.
95
		 *
96
		 * @since 6.3.0
97
		 *
98
		 * @param bool True if Simple Payments should be disabled, false otherwise.
99
		 */
100
		if ( apply_filters( 'jetpack_disable_simple_payments', false ) ) {
101
			return false;
102
		}
103
104
		// For WPCOM sites
105
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM && function_exists( 'has_any_blog_stickers' ) ) {
106
			$site_id = $this->get_blog_id();
107
			return has_any_blog_stickers( array( 'premium-plan', 'business-plan', 'ecommerce-plan' ), $site_id );
108
		}
109
110
		// For all Jetpack sites
111
		return Jetpack::is_active() && Jetpack_Plan::supports( 'simple-payments');
112
	}
113
114
	function parse_shortcode( $attrs, $content = false ) {
115
		if ( empty( $attrs['id'] ) ) {
116
			return;
117
		}
118
		$product = get_post( $attrs['id'] );
119
		if ( ! $product || is_wp_error( $product ) ) {
120
			return;
121
		}
122
		if ( $product->post_type !== self::$post_type_product || 'publish' !== $product->post_status ) {
123
			return;
124
		}
125
126
		// We allow for overriding the presentation labels
127
		$data = shortcode_atts( array(
128
			'blog_id'     => $this->get_blog_id(),
129
			'dom_id'      => uniqid( self::$css_classname_prefix . '-' . $product->ID . '_', true ),
130
			'class'       => self::$css_classname_prefix . '-' . $product->ID,
131
			'title'       => get_the_title( $product ),
132
			'description' => $product->post_content,
133
			'cta'         => get_post_meta( $product->ID, 'spay_cta', true ),
134
			'multiple'    => get_post_meta( $product->ID, 'spay_multiple', true ) || '0'
135
		), $attrs );
136
137
		$data['price'] = $this->format_price(
138
			get_post_meta( $product->ID, 'spay_price', true ),
139
			get_post_meta( $product->ID, 'spay_currency', true )
140
		);
141
142
		$data['id'] = $attrs['id'];
143
144
		if( ! wp_style_is( 'jetpack-simple-payments', 'enqueued' ) ) {
145
			wp_enqueue_style( 'jetpack-simple-payments' );
146
		}
147
148
		if ( ! $this->is_enabled_jetpack_simple_payments() ) {
149
			return $this->output_admin_warning( $data );
150
		}
151
152
		if ( ! wp_script_is( 'paypal-express-checkout', 'enqueued' ) ) {
153
			wp_enqueue_script( 'paypal-express-checkout' );
154
		}
155
156
		wp_add_inline_script( 'paypal-express-checkout', sprintf(
157
			"try{PaypalExpressCheckout.renderButton( '%d', '%d', '%s', '%d' );}catch(e){}",
158
			esc_js( $data['blog_id'] ),
159
			esc_js( $attrs['id'] ),
160
			esc_js( $data['dom_id'] ),
161
			esc_js( $data['multiple'] )
162
		) );
163
164
		return $this->output_shortcode( $data );
165
	}
166
167
	function output_admin_warning( $data ) {
168
		if ( ! current_user_can( 'manage_options' ) ) {
169
			return;
170
		}
171
		$css_prefix = self::$css_classname_prefix;
172
173
		$support_url = ( defined( 'IS_WPCOM' ) && IS_WPCOM )
174
			? 'https://support.wordpress.com/simple-payments/'
175
			: 'https://jetpack.com/support/simple-payment-button/';
176
177
		return sprintf( '
178
<div class="%1$s">
179
	<div class="%2$s">
180
		<div class="%3$s">
181
			<div class="%4$s" id="%5$s">
182
				<p>%6$s</p>
183
				<p>%7$s</p>
184
			</div>
185
		</div>
186
	</div>
187
</div>
188
',
189
			esc_attr( "{$data['class']} ${css_prefix}-wrapper" ),
190
			esc_attr( "${css_prefix}-product" ),
191
			esc_attr( "${css_prefix}-details" ),
192
			esc_attr( "${css_prefix}-purchase-message show error" ),
193
			esc_attr( "{$data['dom_id']}-message-container" ),
194
			sprintf(
195
				wp_kses(
196
					__( 'Your plan doesn\'t include Simple Payments. <a href="%s" rel="noopener noreferrer" target="_blank">Learn more and upgrade</a>.', 'jetpack' ),
197
					array( 'a' => array( 'href' => array(), 'rel' => array(), 'target' => array() ) )
198
				),
199
				esc_url( $support_url )
200
			),
201
			esc_html__( '(Only administrators will see this message.)', 'jetpack' )
202
		);
203
	}
204
205
	function output_shortcode( $data ) {
206
		$items = '';
207
		$css_prefix = self::$css_classname_prefix;
208
209
		if ( $data['multiple'] ) {
210
			$items = sprintf( '
211
				<div class="%1$s">
212
					<input class="%2$s" type="number" value="1" min="1" id="%3$s" />
213
				</div>
214
				',
215
				esc_attr( "${css_prefix}-items" ),
216
				esc_attr( "${css_prefix}-items-number" ),
217
				esc_attr( "{$data['dom_id']}_number" )
218
			);
219
		}
220
		$image = "";
221
		if( has_post_thumbnail( $data['id'] ) ) {
222
			$image = sprintf( '<div class="%1$s"><div class="%2$s">%3$s</div></div>',
223
				esc_attr( "${css_prefix}-product-image" ),
224
				esc_attr( "${css_prefix}-image" ),
225
				get_the_post_thumbnail( $data['id'], 'full' )
226
			);
227
		}
228
		return sprintf( '
229
<div class="%1$s">
230
	<div class="%2$s">
231
		%3$s
232
		<div class="%4$s">
233
			<div class="%5$s"><p>%6$s</p></div>
234
			<div class="%7$s"><p>%8$s</p></div>
235
			<div class="%9$s"><p>%10$s</p></div>
236
			<div class="%11$s" id="%12$s"></div>
237
			<div class="%13$s">
238
				%14$s
239
				<div class="%15$s" id="%16$s"></div>
240
			</div>
241
		</div>
242
	</div>
243
</div>
244
',
245
			esc_attr( "{$data['class']} ${css_prefix}-wrapper" ),
246
			esc_attr( "${css_prefix}-product" ),
247
			$image,
248
			esc_attr( "${css_prefix}-details" ),
249
			esc_attr( "${css_prefix}-title" ),
250
			$data['title'],
251
			esc_attr( "${css_prefix}-description" ),
252
			$data['description'],
253
			esc_attr( "${css_prefix}-price" ),
254
			esc_html( $data['price'] ),
255
			esc_attr( "${css_prefix}-purchase-message" ),
256
			esc_attr( "{$data['dom_id']}-message-container" ),
257
			esc_attr( "${css_prefix}-purchase-box" ),
258
			$items,
259
			esc_attr( "${css_prefix}-button" ),
260
			esc_attr( "{$data['dom_id']}_button" )
261
		);
262
	}
263
264
	/**
265
	 * Format a price with currency
266
	 *
267
	 * Uses currency-aware formatting to output a formatted price with a simple fallback.
268
	 *
269
	 * Largely inspired by WordPress.com's Store_Price::display_currency
270
	 *
271
	 * @param  string $price    Price.
272
	 * @param  string $currency Currency.
273
	 * @return string           Formatted price.
274
	 */
275
	private function format_price( $price, $currency ) {
276
		$currency_details = self::get_currency( $currency );
277
278
		if ( $currency_details ) {
279
			// Ensure USD displays as 1234.56 even in non-US locales.
280
			$amount = 'USD' === $currency
281
				? number_format( $price, $currency_details['decimal'], '.', ',' )
282
				: number_format_i18n( $price, $currency_details['decimal'] );
283
284
			return sprintf(
285
				$currency_details['format'],
286
				$currency_details['symbol'],
287
				$amount
288
			);
289
		}
290
291
		// Fall back to unspecified currency symbol like `¤1,234.05`.
292
		// @link https://en.wikipedia.org/wiki/Currency_sign_(typography).
293
		if ( ! $currency ) {
294
			return '¤' . number_format_i18n( $price, 2 );
295
		}
296
297
		return number_format_i18n( $price, 2 ) . ' ' . $currency;
298
	}
299
300
	/**
301
	 * Allows custom post types to be used by REST API.
302
	 * @param $post_types
303
	 * @see hook 'rest_api_allowed_post_types'
304
	 * @return array
305
	 */
306
	function allow_rest_api_types( $post_types ) {
307
		$post_types[] = self::$post_type_order;
308
		$post_types[] = self::$post_type_product;
309
		return $post_types;
310
	}
311
312
	function allow_sync_post_meta( $post_meta ) {
313
		return array_merge( $post_meta, array(
314
			'spay_paypal_id',
315
			'spay_status',
316
			'spay_product_id',
317
			'spay_quantity',
318
			'spay_price',
319
			'spay_customer_email',
320
			'spay_currency',
321
			'spay_cta',
322
			'spay_email',
323
			'spay_multiple',
324
			'spay_formatted_price',
325
		) );
326
	}
327
328
	/**
329
	 * Enable Simple payments custom meta values for access through the REST API.
330
	 * Field’s value will be exposed on a .meta key in the endpoint response,
331
	 * and WordPress will handle setting up the callbacks for reading and writing
332
	 * to that meta key.
333
	 *
334
	 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/modifying-responses/
335
	 */
336
	public function register_meta_fields_in_rest_api() {
337
		register_meta( 'post', 'spay_price', array(
338
			'description'       => esc_html__( 'Simple payments; price.', 'jetpack' ),
339
			'object_subtype'    => self::$post_type_product,
340
			'sanitize_callback' => array( $this, 'sanitize_price' ),
341
			'show_in_rest'      => true,
342
			'single'            => true,
343
			'type'              => 'number',
344
		) );
345
346
		register_meta( 'post', 'spay_currency', array(
347
			'description'       => esc_html__( 'Simple payments; currency code.', 'jetpack' ),
348
			'object_subtype'    => self::$post_type_product,
349
			'sanitize_callback' => array( $this, 'sanitize_currency' ),
350
			'show_in_rest'      => true,
351
			'single'            => true,
352
			'type'              => 'string',
353
		) );
354
355
		register_meta( 'post', 'spay_cta', array(
356
			'description'       => esc_html__( 'Simple payments; text with "Buy" or other CTA', 'jetpack' ),
357
			'object_subtype'    => self::$post_type_product,
358
			'sanitize_callback' => 'sanitize_text_field',
359
			'show_in_rest'      => true,
360
			'single'            => true,
361
			'type'              => 'string',
362
		) );
363
364
		register_meta( 'post', 'spay_multiple', array(
365
			'description'       => esc_html__( 'Simple payments; allow multiple items', 'jetpack' ),
366
			'object_subtype'    => self::$post_type_product,
367
			'sanitize_callback' => 'rest_sanitize_boolean',
368
			'show_in_rest'      => true,
369
			'single'            => true,
370
			'type'              => 'boolean',
371
		) );
372
373
		register_meta( 'post', 'spay_email', array(
374
			'description'       => esc_html__( 'Simple payments button; paypal email.', 'jetpack' ),
375
			'sanitize_callback' => 'sanitize_email',
376
			'show_in_rest'      => true,
377
			'single'            => true,
378
			'type'              => 'string',
379
		) );
380
381
		register_meta( 'post', 'spay_status', array(
382
			'description'       => esc_html__( 'Simple payments; status.', 'jetpack' ),
383
			'object_subtype'    => self::$post_type_product,
384
			'sanitize_callback' => 'sanitize_text_field',
385
			'show_in_rest'      => true,
386
			'single'            => true,
387
			'type'              => 'string',
388
		) );
389
	}
390
391
	/**
392
	 * Sanitize three-character ISO-4217 Simple payments currency
393
	 *
394
	 * List has to be in sync with list at the client side:
395
	 * @link https://github.com/Automattic/wp-calypso/blob/6d02ffe73cc073dea7270a22dc30881bff17d8fb/client/lib/simple-payments/constants.js
396
	 *
397
	 * Currencies should be supported by PayPal:
398
	 * @link https://developer.paypal.com/docs/integration/direct/rest/currency-codes/
399
	 */
400
	public static function sanitize_currency( $currency ) {
401
		$valid_currencies = array(
402
			'USD',
403
			'EUR',
404
			'AUD',
405
			'BRL',
406
			'CAD',
407
			'CZK',
408
			'DKK',
409
			'HKD',
410
			'HUF',
411
			'ILS',
412
			'JPY',
413
			'MYR',
414
			'MXN',
415
			'TWD',
416
			'NZD',
417
			'NOK',
418
			'PHP',
419
			'PLN',
420
			'GBP',
421
			'RUB',
422
			'SGD',
423
			'SEK',
424
			'CHF',
425
			'THB',
426
		);
427
428
		return in_array( $currency, $valid_currencies ) ? $currency : false;
429
	}
430
431
	/**
432
	 * Sanitize price:
433
	 *
434
	 * Positive integers and floats
435
	 * Supports two decimal places.
436
	 * Maximum length: 10.
437
	 *
438
	 * See `price` from PayPal docs:
439
	 * @link https://developer.paypal.com/docs/api/orders/v1/#definition-item
440
	 *
441
	 * @param      $value
442
	 * @return null|string
443
	 */
444
	public static function sanitize_price( $price ) {
445
		return preg_match( '/^[0-9]{0,10}(\.[0-9]{0,2})?$/', $price ) ? $price : false;
446
	}
447
448
	/**
449
	 * Sets up the custom post types for the module.
450
	 */
451
	function setup_cpts() {
452
453
		/*
454
		 * ORDER data structure. holds:
455
		 * title = customer_name | 4xproduct_name
456
		 * excerpt = customer_name + customer contact info + customer notes from paypal form
457
		 * metadata:
458
		 * spay_paypal_id - paypal id of transaction
459
		 * spay_status
460
		 * spay_product_id - post_id of bought product
461
		 * spay_quantity - quantity of product
462
		 * spay_price - item price at the time of purchase
463
		 * spay_customer_email - customer email
464
		 * ... (WIP)
465
		 */
466
		$order_capabilities = array(
467
			'edit_post'             => 'edit_posts',
468
			'read_post'             => 'read_private_posts',
469
			'delete_post'           => 'delete_posts',
470
			'edit_posts'            => 'edit_posts',
471
			'edit_others_posts'     => 'edit_others_posts',
472
			'publish_posts'         => 'publish_posts',
473
			'read_private_posts'    => 'read_private_posts',
474
		);
475
		$order_args = array(
476
			'label'                 => esc_html_x( 'Order', 'noun: a quantity of goods or items purchased or sold', 'jetpack' ),
477
			'description'           => esc_html__( 'Simple Payments orders', 'jetpack' ),
478
			'supports'              => array( 'custom-fields', 'excerpt' ),
479
			'hierarchical'          => false,
480
			'public'                => false,
481
			'show_ui'               => false,
482
			'show_in_menu'          => false,
483
			'show_in_admin_bar'     => false,
484
			'show_in_nav_menus'     => false,
485
			'can_export'            => true,
486
			'has_archive'           => false,
487
			'exclude_from_search'   => true,
488
			'publicly_queryable'    => false,
489
			'rewrite'               => false,
490
			'capabilities'          => $order_capabilities,
491
			'show_in_rest'          => true,
492
		);
493
		register_post_type( self::$post_type_order, $order_args );
494
495
		/*
496
		 * PRODUCT data structure. Holds:
497
		 * title - title
498
		 * content - description
499
		 * thumbnail - image
500
		 * metadata:
501
		 * spay_price - price
502
		 * spay_formatted_price
503
		 * spay_currency - currency code
504
		 * spay_cta - text with "Buy" or other CTA
505
		 * spay_email - paypal email
506
		 * spay_multiple - allow for multiple items
507
		 * spay_status - status. { enabled | disabled }
508
		 */
509
		$product_capabilities = array(
510
			'edit_post'             => 'edit_posts',
511
			'read_post'             => 'read_private_posts',
512
			'delete_post'           => 'delete_posts',
513
			'edit_posts'            => 'publish_posts',
514
			'edit_others_posts'     => 'edit_others_posts',
515
			'publish_posts'         => 'publish_posts',
516
			'read_private_posts'    => 'read_private_posts',
517
		);
518
		$product_args = array(
519
			'label'                 => esc_html__( 'Product', 'jetpack' ),
520
			'description'           => esc_html__( 'Simple Payments products', 'jetpack' ),
521
			'supports'              => array( 'title', 'editor','thumbnail', 'custom-fields', 'author' ),
522
			'hierarchical'          => false,
523
			'public'                => false,
524
			'show_ui'               => false,
525
			'show_in_menu'          => false,
526
			'show_in_admin_bar'     => false,
527
			'show_in_nav_menus'     => false,
528
			'can_export'            => true,
529
			'has_archive'           => false,
530
			'exclude_from_search'   => true,
531
			'publicly_queryable'    => false,
532
			'rewrite'               => false,
533
			'capabilities'          => $product_capabilities,
534
			'show_in_rest'          => true,
535
		);
536
		register_post_type( self::$post_type_product, $product_args );
537
	}
538
539
	/**
540
	 * Format a price for display
541
	 *
542
	 * Largely taken from WordPress.com Store_Price class
543
	 *
544
	 * The currency array will have the shape:
545
	 *   format  => string sprintf format with placeholders `%1$s`: Symbol `%2$s`: Price.
546
	 *   symbol  => string Symbol string
547
	 *   desc    => string Text description of currency
548
	 *   decimal => int    Number of decimal places
549
	 *
550
	 * @param  string $the_currency The desired currency, e.g. 'USD'.
551
	 * @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...
552
	 */
553
	private static function get_currency( $the_currency ) {
554
		$currencies = array(
555
			'USD' => array(
556
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
557
				'symbol'  => '$',
558
				'decimal' => 2,
559
			),
560
			'GBP' => array(
561
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
562
				'symbol'  => '&#163;',
563
				'decimal' => 2,
564
			),
565
			'JPY' => array(
566
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
567
				'symbol'  => '&#165;',
568
				'decimal' => 0,
569
			),
570
			'BRL' => array(
571
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
572
				'symbol'  => 'R$',
573
				'decimal' => 2,
574
			),
575
			'EUR' => array(
576
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
577
				'symbol'  => '&#8364;',
578
				'decimal' => 2,
579
			),
580
			'NZD' => array(
581
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
582
				'symbol'  => 'NZ$',
583
				'decimal' => 2,
584
			),
585
			'AUD' => array(
586
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
587
				'symbol'  => 'A$',
588
				'decimal' => 2,
589
			),
590
			'CAD' => array(
591
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
592
				'symbol'  => 'C$',
593
				'decimal' => 2,
594
			),
595
			'ILS' => array(
596
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
597
				'symbol'  => '₪',
598
				'decimal' => 2,
599
			),
600
			'RUB' => array(
601
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
602
				'symbol'  => '₽',
603
				'decimal' => 2,
604
			),
605
			'MXN' => array(
606
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
607
				'symbol'  => 'MX$',
608
				'decimal' => 2,
609
			),
610
			'MYR' => array(
611
				'format'  => '%2$s%1$s', // 1: Symbol 2: currency value
612
				'symbol'  => 'RM',
613
				'decimal' => 2,
614
			),
615
			'SEK' => array(
616
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
617
				'symbol'  => 'Skr',
618
				'decimal' => 2,
619
			),
620
			'HUF' => array(
621
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
622
				'symbol'  => 'Ft',
623
				'decimal' => 0, // Decimals are supported by Stripe but not by PayPal.
624
			),
625
			'CHF' => array(
626
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
627
				'symbol'  => 'CHF',
628
				'decimal' => 2,
629
			),
630
			'CZK' => array(
631
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
632
				'symbol'  => 'Kč',
633
				'decimal' => 2,
634
			),
635
			'DKK' => array(
636
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
637
				'symbol'  => 'Dkr',
638
				'decimal' => 2,
639
			),
640
			'HKD' => array(
641
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
642
				'symbol'  => 'HK$',
643
				'decimal' => 2,
644
			),
645
			'NOK' => array(
646
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
647
				'symbol'  => 'Kr',
648
				'decimal' => 2,
649
			),
650
			'PHP' => array(
651
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
652
				'symbol'  => '₱',
653
				'decimal' => 2,
654
			),
655
			'PLN' => array(
656
				'format'  => '%2$s %1$s', // 1: Symbol 2: currency value
657
				'symbol'  => 'PLN',
658
				'decimal' => 2,
659
			),
660
			'SGD' => array(
661
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
662
				'symbol'  => 'S$',
663
				'decimal' => 2,
664
			),
665
			'TWD' => array(
666
				'format'  => '%1$s%2$s', // 1: Symbol 2: currency value
667
				'symbol'  => 'NT$',
668
				'decimal' => 0, // Decimals are supported by Stripe but not by PayPal.
669
			),
670
			'THB' => array(
671
				'format'  => '%2$s%1$s', // 1: Symbol 2: currency value
672
				'symbol'  => '฿',
673
				'decimal' => 2,
674
			),
675
		);
676
677
		if ( isset( $currencies[ $the_currency ] ) ) {
678
			return $currencies[ $the_currency ];
679
		}
680
		return null;
681
	}
682
}
683
Jetpack_Simple_Payments::getInstance();
684