Completed
Push — update/jitm-test ( 03ced2...c48940 )
by
unknown
212:35 queued 203:56
created

Jetpack_Simple_Payments::output_admin_warning()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

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