Completed
Push — add/simple-payments-widget-cre... ( 0cf560...d78793 )
by
unknown
15:51 queued 02:53
created

Jetpack_Simple_Payments_Widget::enqueue_style()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Disable direct access/execution to/of the widget code.
4
 */
5
if ( ! defined( 'ABSPATH' ) ) {
6
	exit;
7
}
8
9
if ( ! class_exists( 'Jetpack_Simple_Payments_Widget' ) ) {
10
	/**
11
	 * Simple Payments Button
12
	 *
13
	 * Display a Simple Payment Button as a Widget.
14
	 */
15
	class Jetpack_Simple_Payments_Widget extends WP_Widget {
16
		// https://developer.paypal.com/docs/integration/direct/rest/currency-codes/
17
		private static $supported_currency_list = array(
0 ignored issues
show
Unused Code introduced by
The property $supported_currency_list is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
18
			'USD' => '$',
19
			'GBP' => '&#163;',
20
			'JPY' => '&#165;',
21
			'BRL' => 'R$',
22
			'EUR' => '&#8364;',
23
			'NZD' => 'NZ$',
24
			'AUD' => 'A$',
25
			'CAD' => 'C$',
26
			'INR' => '₹',
27
			'ILS' => '₪',
28
			'RUB' => '₽',
29
			'MXN' => 'MX$',
30
			'SEK' => 'Skr',
31
			'HUF' => 'Ft',
32
			'CHF' => 'CHF',
33
			'CZK' => 'Kč',
34
			'DKK' => 'Dkr',
35
			'HKD' => 'HK$',
36
			'NOK' => 'Kr',
37
			'PHP' => '₱',
38
			'PLN' => 'PLN',
39
			'SGD' => 'S$',
40
			'TWD' => 'NT$',
41
			'THB' => '฿',
42
		);
43
44
		/**
45
		 * Constructor.
46
		 */
47
		function __construct() {
48
			parent::__construct(
49
				'jetpack_simple_payments_widget',
50
				/** This filter is documented in modules/widgets/facebook-likebox.php */
51
				apply_filters( 'jetpack_widget_name', __( 'Simple Payments', 'jetpack' ) ),
52
				array(
53
					'classname' => 'jetpack-simple-payments',
54
					'description' => __( 'Add a Simple Payment Button as a Widget.', 'jetpack' ),
55
					'customize_selective_refresh' => true,
56
				)
57
			);
58
59
			if ( is_customize_preview() ) {
60
				add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_styles_and_scripts' ) );
61
62
				add_filter( 'customize_refresh_nonces', array( $this, 'filter_nonces' ) );
63
				add_action( 'wp_ajax_customize-jetpack-simple-payments-button-save', array( $this, 'ajax_save_payment_button' ) );
64
				add_action( 'wp_ajax_customize-jetpack-simple-payments-button-delete', array( $this, 'ajax_delete_payment_button' ) );
65
			}
66
67
			if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) {
68
				add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_style' ) );
69
			}
70
		}
71
72
		/**
73
		 * Return an associative array of default values.
74
		 *
75
		 * These values are used in new widgets.
76
		 *
77
		 * @return array Default values for the widget options.
78
		 */
79
		private function defaults() {
80
			return array(
81
				'title' => '',
82
				'product_post_id' => 0,
83
				'form_action' => '',
84
				'form_product_id' => 0,
85
				'form_product_title' => '',
86
				'form_product_description' => '',
87
				'form_product_image_id' => 0,
88
				'form_product_image_src' => '',
89
				'form_product_currency' => '',
90
				'form_product_price' => '',
91
				'form_product_multiple' => '',
92
				'form_product_email' => '',
93
			);
94
		}
95
96
		/**
97
		 * Adds a nonce for customizing menus.
98
		 *
99
		 * @param array $nonces Array of nonces.
100
		 * @return array $nonces Modified array of nonces.
101
		 */
102
		function filter_nonces( $nonces ) {
103
			$nonces['customize-jetpack-simple-payments'] = wp_create_nonce( 'customize-jetpack-simple-payments' );
104
			return $nonces;
105
		}
106
107
		function enqueue_style() {
108
			wp_enqueue_style( 'jetpack-simple-payments-widget-style', plugins_url( 'simple-payments/style.css', __FILE__ ), array(), '20180518' );
109
		}
110
111
		function admin_enqueue_styles_and_scripts(){
112
				wp_enqueue_style( 'jetpack-simple-payments-widget-customizer', plugins_url( 'simple-payments/customizer.css', __FILE__ ) );
113
114
				wp_enqueue_media();
115
				wp_enqueue_script( 'jetpack-simple-payments-widget-customizer', plugins_url( '/simple-payments/customizer.js', __FILE__ ), array( 'jquery' ), false, true );
116
		}
117
118
		public function ajax_save_payment_button() {
119
			if ( ! check_ajax_referer( 'customize-jetpack-simple-payments', 'customize-jetpack-simple-payments-nonce', false ) ) {
120
				wp_send_json_error( 'bad_nonce', 400 );
121
			}
122
123
			if ( ! current_user_can( 'customize' ) ) {
124
				wp_send_json_error( 'customize_not_allowed', 403 );
125
			}
126
127
			$post_type_object = get_post_type_object( Jetpack_Simple_Payments::$post_type_product );
0 ignored issues
show
Bug introduced by
The property post_type_product cannot be accessed from this context as it is declared private in class Jetpack_Simple_Payments.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
128
			if ( ! current_user_can( $post_type_object->cap->create_posts ) || ! current_user_can( $post_type_object->cap->publish_posts ) ) {
129
				wp_send_json_error( 'insufficient_post_permissions', 403 );
130
			}
131
132 View Code Duplication
			if ( empty( $_POST['params'] ) || ! is_array( $_POST['params'] ) ) {
133
				wp_send_json_error( 'missing_params', 400 );
134
			}
135
136
			$params = wp_unslash( $_POST['params'] );
137
			$illegal_params = array_diff( array_keys( $params ), array( 'product_post_id', 'post_title', 'post_content', 'image_id', 'currency', 'price', 'multiple', 'email' ) );
138
			if ( ! empty( $illegal_params ) ) {
139
				wp_send_json_error( 'illegal_params', 400 );
140
			}
141
142
			$product_post_id = isset( $params['product_post_id'] ) ? intval( $params['product_post_id'] ) : 0;
143
144
			$product_post = array(
145
				'ID' => $product_post_id,
146
				'post_type' => Jetpack_Simple_Payments::$post_type_product,
0 ignored issues
show
Bug introduced by
The property post_type_product cannot be accessed from this context as it is declared private in class Jetpack_Simple_Payments.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
147
				'post_status' => 'publish',
148
				'post_title' => $params['post_title'],
149
				'post_content' => $params['post_content'],
150
				'_thumbnail_id' => ! empty( $params['image_id'] ) ? $params['image_id'] : -1,
151
				'meta_input' => array(
152
					'spay_currency' => $params['currency'],
153
					'spay_price' => $params['price'],
154
					'spay_multiple' => isset( $params['multiple'] ) ? intval( $params['multiple'] ) : 0,
155
					'spay_email' => is_email( $params['email'] ),
156
				),
157
			);
158
159
			if ( empty( $product_post_id ) ) {
160
				$product_post_id = wp_insert_post( $product_post );
161
			} else {
162
				$product_post_id = wp_update_post( $product_post );
163
			}
164
165
			if ( ! $product_post_id || is_wp_error( $product_post_id ) ) {
166
				wp_send_json_error( $product_post_id );
167
			}
168
169
			wp_send_json_success( [
170
				'product_post_id' => $product_post_id,
171
				'product_post_title' => $params['post_title'],
172
			] );
173
		}
174
175
		public function ajax_delete_payment_button() {
176
			if ( ! check_ajax_referer( 'customize-jetpack-simple-payments', 'customize-jetpack-simple-payments-nonce', false ) ) {
177
				wp_send_json_error( 'bad_nonce', 400 );
178
			}
179
180
			if ( ! current_user_can( 'customize' ) ) {
181
				wp_send_json_error( 'customize_not_allowed', 403 );
182
			}
183
184 View Code Duplication
			if ( empty( $_POST['params'] ) || ! is_array( $_POST['params'] ) ) {
185
				wp_send_json_error( 'missing_params', 400 );
186
			}
187
188
			$params = wp_unslash( $_POST['params'] );
189
			$illegal_params = array_diff( array_keys( $params ), array( 'product_post_id' ) );
190
			if ( ! empty( $illegal_params ) ) {
191
				wp_send_json_error( 'illegal_params', 400 );
192
			}
193
194
			$product_id = ( int ) $params['product_post_id'];
195
			$product_post = get_post( $product_id );
196
197
			$return = array( 'status' => $product_post->post_status );
198
199
			wp_delete_post( $product_id, true );
200
			$status = get_post_status( $product_id );
201
			if ( false === $status ) {
202
				$return['status'] = 'deleted';
203
			}
204
205
			wp_send_json_success( $return );
206
		}
207
208
		/**
209
		 * Front-end display of widget.
210
		 *
211
		 * @see WP_Widget::widget()
212
		 *
213
		 * @param array $args     Widget arguments.
214
		 * @param array $instance Saved values from database.
215
		 */
216
		function widget( $args, $instance ) {
217
			$instance = wp_parse_args( $instance, $this->defaults() );
218
219
			echo $args['before_widget'];
220
221
			/** This filter is documented in core/src/wp-includes/default-widgets.php */
222
			$title = apply_filters( 'widget_title', $instance['title'] );
223
			if ( ! empty( $title ) ) {
224
				echo $args['before_title'] . $title . $args['after_title'];
225
			}
226
227
			echo '<div class="jetpack-simple-payments-content">';
228
229
			if ( ! empty( $instance['form_action'] ) && in_array( $instance['form_action'], array( 'add', 'edit' ) ) && is_customize_preview() ) {
230
				require( dirname( __FILE__ ) . '/simple-payments/widget.php' );
231
			} else {
232
				if ( ! empty( $instance['product_post_id'] ) ) {
233
					$attrs = array( 'id' => $instance['product_post_id'] );
234
				} else {
235
					$product_posts = get_posts( array(
236
						'numberposts' => 1,
237
						'orderby' => 'date',
238
						'post_type' => Jetpack_Simple_Payments::$post_type_product,
0 ignored issues
show
Bug introduced by
The property post_type_product cannot be accessed from this context as it is declared private in class Jetpack_Simple_Payments.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
239
						'post_status' => 'publish',
240
					 ) );
241
	
242
					$attrs = array( 'id' => $product_posts[0]->ID );
243
				}
244
245
				$jsp = Jetpack_Simple_Payments::getInstance();
246
				$simple_payments_button = $jsp->parse_shortcode( $attrs );
247
				if ( is_null( $simple_payments_button ) && ! is_customize_preview() ) {
248
					return;
249
				}
250
251
				echo $simple_payments_button;
252
			}
253
254
			echo '</div><!--simple-payments-->';
255
256
			echo $args['after_widget'];
257
258
			/** This action is already documented in modules/widgets/gravatar-profile.php */
259
			do_action( 'jetpack_stats_extra', 'widget_view', 'simple_payments' );
260
		}
261
262
		/**
263
		 * Gets the latests field value from either the old instance or the new instance.
264
		 *
265
		 * @param array $mixed Array of values for the new form instance.
0 ignored issues
show
Bug introduced by
There is no parameter named $mixed. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
266
		 * @param array $mixed Array of values for the old form instance.
0 ignored issues
show
Bug introduced by
There is no parameter named $mixed. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
267
		 * @return mixed $mixed Field value.
268
		 */
269
		private function get_latest_field_value( $new_instance, $old_instance, $field) {
270
			return ! empty( $new_instance[ $field ] )
271
				? sanitize_text_field( $new_instance[ $field ] )
272
				: $old_instance[ $field ];
273
		}
274
275
		/**
276
		 * Gets the product fields from the product post. If no post found
277
		 * it returns the default values.
278
		 *
279
		 * @param int Product Post ID.
280
		 * @return array $fields Product Fields from the Product Post.
281
		 */
282
		private function get_product_from_post( $product_post_id ) {
283
			$product_post = get_post( $product_post_id );
284
			$form_product_id = $product_post_id;
285
			if( ! empty( $product_post ) ) {
286
				$form_product_image_id = get_post_thumbnail_id( $product_post_id );
287
288
				return array(
289
					'form_product_id' => $form_product_id,
290
					'form_product_title' => get_the_title( $product_post ),
291
					'form_product_description' => $product_post->post_content,
292
					'form_product_image_id' => $form_product_image_id,
293
					'form_product_image_src' => wp_get_attachment_image_url( $form_product_image_id, 'thumbnail' ),
294
					'form_product_currency' => get_post_meta( $product_post_id, 'spay_currency', true ),
295
					'form_product_price' => get_post_meta( $product_post_id, 'spay_price', true ),
296
					'form_product_multiple' => get_post_meta( $product_post_id, 'spay_multiple', true ) || '0',
297
					'form_product_email' => get_post_meta( $product_post_id, 'spay_email', true ),
298
				);
299
			}
300
301
			return $this->defaults();
302
		}
303
304
		/**
305
		 * Sanitize widget form values as they are saved.
306
		 *
307
		 * @see WP_Widget::update()
308
		 *
309
		 * @param array $new_instance Values just sent to be saved.
310
		 * @param array $old_instance Previously saved values from database.
311
		 *
312
		 * @return array Updated safe values to be saved.
313
		 */
314
		function update( $new_instance, $old_instance ) {
315
			$new_instance = wp_parse_args( $new_instance, $this->defaults() );
316
			$old_instance = wp_parse_args( $old_instance, $this->defaults() );
317
318
			$required_widget_props = array(
319
				'title' => $this->get_latest_field_value( $new_instance, $old_instance, 'title' ),
320
				'product_post_id' => $this->get_latest_field_value( $new_instance, $old_instance, 'product_post_id' ),
321
				'form_action' => $this->get_latest_field_value( $new_instance, $old_instance, 'form_action' ),
322
			);
323
324
			if ( strcmp( $new_instance['form_action'], $old_instance['form_action'] ) !== 0 ) {
325
				if ( $new_instance['form_action'] == 'edit' ) {
326
					return array_merge( $this->get_product_from_post( ( int ) $old_instance['product_post_id'] ), $required_widget_props );
327
				}
328
329
				if ( $new_instance['form_action'] == 'clear' ) {
330
					return array_merge( $this->defaults(), $required_widget_props );
331
				}
332
			}
333
334
			$form_product_image_id = (int) $new_instance['form_product_image_id'];
335
			return array_merge( $required_widget_props, array(
336
				'form_product_id' => ( int ) $new_instance['form_product_id'],
337
				'form_product_title' => sanitize_text_field( $new_instance['form_product_title'] ),
338
				'form_product_description' => sanitize_text_field( $new_instance['form_product_description'] ),
339
				'form_product_image_id' => $form_product_image_id,
340
				'form_product_image_src' => wp_get_attachment_image_url( $form_product_image_id, 'thumbnail' ),
341
				'form_product_currency' => sanitize_text_field( $new_instance['form_product_currency'] ),
342
				'form_product_price' => sanitize_text_field( $new_instance['form_product_price'] ),
343
				'form_product_multiple' => sanitize_text_field( $new_instance['form_product_multiple'] ),
344
				'form_product_email' => sanitize_text_field( $new_instance['form_product_email'] ),
345
			) );
346
		}
347
348
		/**
349
		 * Back-end widget form.
350
		 *
351
		 * @see WP_Widget::form()
352
		 *
353
		 * @param array $instance Previously saved values from database.
354
		 */
355
		function form( $instance ) {
356
			$instance = wp_parse_args( $instance, $this->defaults() );
357
358
			$product_posts = get_posts( array(
359
				'numberposts' => 100,
360
				'orderby' => 'date',
361
				'post_type' => Jetpack_Simple_Payments::$post_type_product,
0 ignored issues
show
Bug introduced by
The property post_type_product cannot be accessed from this context as it is declared private in class Jetpack_Simple_Payments.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
362
				'post_status' => 'publish',
363
			 ) );
364
365
			require( dirname( __FILE__ ) . '/simple-payments/form.php' );
366
		}
367
	}
368
369
	// Register Jetpack_Simple_Payments_Widget widget.
370
	function register_widget_jetpack_simple_payments() {
371
		if ( ! Jetpack::is_active() ) {
372
			return;
373
		}
374
375
		register_widget( 'Jetpack_Simple_Payments_Widget' );
376
	}
377
	add_action( 'widgets_init', 'register_widget_jetpack_simple_payments' );
378
}
379