Completed
Push — renovate/jest-monorepo ( bd2eaf...d289c3 )
by
unknown
44:07 queued 37:28
created

Jetpack_Simple_Payments::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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