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