Completed
Push — update/dialogue-focus-on-conte... ( 9f1745...fa862f )
by
unknown
80:03 queued 71:18
created

WPCOM_JSON_API_Sharing_Button_Endpoint::setup()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 6
nop 0
dl 0
loc 12
rs 8.8333
c 0
b 0
f 0
1
<?php
2
3
abstract class WPCOM_JSON_API_Sharing_Button_Endpoint extends WPCOM_JSON_API_Endpoint {
4
5
	public static $all_visibilities = array( 'visible', 'hidden' );
6
7
	protected $sharing_service;
8
9
	protected function setup() {
10
		if ( class_exists( 'Sharing_Service' ) ) {
11
			$this->sharing_service = new Sharing_Service();
12
		}
13
14
		if ( ! current_user_can( 'manage_options' ) ) {
15
			return new WP_Error( 'forbidden', 'You do not have the capability to manage sharing buttons for this site', 403 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'forbidden'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
16
		} else if ( ! class_exists( 'Sharing_Service' ) || ! class_exists( 'Sharing_Source' ) ||
17
				( method_exists( 'Jetpack', 'is_module_active' ) && ! Jetpack::is_module_active( 'sharedaddy' ) ) ) {
18
			return new WP_Error( 'missing_jetpack_module', 'The Sharing module must be activated in order to use this endpoint', 400 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'missing_jetpack_module'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
19
		}
20
	}
21
22
	public function format_sharing_button( $button ) {
23
		$response = array(
24
			'ID'           => $button->get_id(),
25
			'name'         => $button->get_name(),
26
			'shortname'    => $button->shortname,
27
			'custom'       => is_a( $button, 'Share_Custom' ),
28
			'enabled'      => $this->is_button_enabled( $button ),
29
		);
30
31
		if ( $response['enabled'] ) {
32
			// Status is either "disabled" or the visibility value
33
			$response['visibility'] = $this->get_button_visibility( $button );
34
		}
35
36
		if ( ! empty( $button->icon ) ) {
37
			// Only pre-defined sharing buttons include genericon
38
			$response['genericon'] = $button->icon;
39
		}
40
41
		if ( method_exists( $button, 'get_options' ) ) {
42
			// merge get_options() values into response, primarily to account
43
			// for custom sharing button values
44
			foreach ( $button->get_options() as $key => $value ) {
45
				// Capitalize URL property
46
				if ( 'url' === strtolower( $key ) ) {
47
					$key = strtoupper( $key );
48
				}
49
50
				$response[ $key ] = $value;
51
			}
52
		}
53
54
		return $response;
55
	}
56
57
	public function get_button_visibility( $button ) {
58
		$services = $this->sharing_service->get_blog_services();
59
		$visibilities = self::$all_visibilities;
60
		$button_id = $button->get_id();
61
62
		foreach ( $visibilities as $visibility ) {
63
			if ( isset( $services[ $visibility ][ $button_id ] ) ) {
64
				return $visibility;
65
			}
66
		}
67
68
		return false;
69
	}
70
71
	public function is_button_enabled( $button ) {
72
		return false !== $this->get_button_visibility( $button );
73
	}
74
75
	protected function is_button_input_for_custom( $button ) {
76
		return ( isset( $button['custom'] ) && $button['custom'] ) ||
77
			( isset( $button['ID'] ) && 1 === preg_match( '/^custom-/', $button['ID'] ) ) ||
78
			! empty( $button['name'] ) || ! empty( $button['URL'] ) || ! empty( $button['icon'] );
79
	}
80
81
	protected function validate_button_input( $button, $is_new = false ) {
82
		if ( ! empty( $button['visibility'] ) && ! in_array( $button['visibility'], self::$all_visibilities ) ) {
83
			return new WP_Error( 'invalid_visibility', sprintf( 'The visibility field must be one of the following values: %s', implode( ', ', self::$all_visibilities ) ), 400 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'invalid_visibility'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
84
		} else if ( $is_new && empty( $button['URL'] ) ) {
85
			return new WP_Error( 'invalid_request', 'The URL field is required', 400 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'invalid_request'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
86
		} else if ( $is_new && empty( $button['icon'] ) ) {
87
			return new WP_Error( 'invalid_request', 'The icon field is required', 400 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'invalid_request'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
88
		}
89
	}
90
91
	public function create_custom_button( $button ) {
92
		// Default visibility to 'visible' if enabled
93
		if ( empty( $button['visibility'] ) && true === $button['enabled'] ) {
94
			$button['visibility'] = 'visible';
95
		}
96
97
		$updated_service = $this->sharing_service->new_service( $button['name'], $button['URL'], $button['icon'] );
98
		if ( false !== $updated_service && ( true === $button['enabled'] || ! empty( $button['visibility'] ) ) ) {
99
			$blog_services = $this->sharing_service->get_blog_services();
100
			$blog_services[ $button['visibility'] ][ (string) $updated_service->get_id() ] = $updated_service;
101
			$this->sharing_service->set_blog_services( array_keys( $blog_services['visible'] ), array_keys( $blog_services['hidden'] ) );
102
		}
103
104
		return $updated_service;
105
	}
106
107
	public function update_button( $button_id, $button ) {
108
		$blog_services = $this->sharing_service->get_blog_services();
109
110
		// Find existing button
111
		$all_buttons = $this->sharing_service->get_all_services_blog();
112
		if ( ! array_key_exists( $button_id, $all_buttons ) ) {
113
			// Button doesn't exist
114
			return new WP_Error( 'not_found', 'The specified sharing button was not found', 404 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'not_found'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
115
		}
116
117
		$updated_service = $all_buttons[ $button_id ];
118
		$service_id = $updated_service->get_id();
119
		if ( is_a( $all_buttons[ $button_id ], 'Share_Custom' ) ) {
120
			// Replace options for existing custom button
121
			$options = $updated_service->get_options();
122
			$name = isset( $button['name'] ) ? $button['name'] : $options['name'];
123
			$url = isset( $button['URL'] ) ? $button['URL'] : $options['url'];
124
			$icon = isset( $button['icon'] ) ? $button['icon'] : $options['icon'];
125
			$updated_service = new Share_Custom( $service_id, array( 'name' => $name, 'url' => $url, 'icon' => $icon ) );
126
			$this->sharing_service->set_service( $button_id, $updated_service );
127
		}
128
129
		// Default visibility to 'visible' if enabled
130
		if ( empty( $button['visibility'] ) && true === $button['enabled'] ) {
131
			$button['visibility'] = 'visible';
132
		} else if ( false === $button['enabled'] ) {
133
			unset( $button['visibility'] );
134
		}
135
136
		// Update button visibility and enabled status
137
		$visibility_changed = ( isset( $button['visibility'] ) || true === $button['enabled'] ) && ! array_key_exists( $service_id, $blog_services[ $button['visibility'] ] );
138
		$is_disabling = false === $button['enabled'];
139
		if ( $visibility_changed || $is_disabling ) {
140
			// Remove from all other visibilities
141
			foreach ( $blog_services as $service_visibility => $services ) {
142
				if ( $is_disabling || $service_visibility !== $button['visibility']  ) {
143
					unset( $blog_services[ $service_visibility ][ $service_id ] );
144
				}
145
			}
146
147
			if ( $visibility_changed ) {
148
				$blog_services[ $button['visibility'] ][ $service_id ] = $updated_service;
149
			}
150
151
			$this->sharing_service->set_blog_services( array_keys( $blog_services['visible'] ), array_keys( $blog_services['hidden'] ) );
152
		}
153
154
		return $updated_service;
155
	}
156
157
}
158
159
new WPCOM_JSON_API_Get_Sharing_Buttons_Endpoint( array(
160
	'description' => 'Get a list of a site\'s sharing buttons.',
161
	'group'       => 'sharing',
162
	'stat'        => 'sharing-buttons',
163
	'method'      => 'GET',
164
	'path'        => '/sites/%s/sharing-buttons/',
165
	'path_labels' => array(
166
		'$site' => '(int|string) Site ID or domain',
167
	),
168
	'query_parameters' => array(
169
		'enabled_only' => '(bool) If true, only enabled sharing buttons are included in the response',
170
		'visibility'   => '(string) The type of enabled sharing buttons to filter by, either "visible" or "hidden"',
171
	),
172
	'response_format' => array(
173
		'found'           => '(int) The total number of sharing buttons found that match the request.',
174
		'sharing_buttons' => '(array:object) Array of sharing button objects',
175
	),
176
	'example_request'      => 'https://public-api.wordpress.com/rest/v1/sites/30434183/sharing-buttons/',
177
	'example_request_data' => array(
178
		'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ),
179
	),
180
	'example_response' => '
181
{
182
    "found": 2,
183
    "sharing_buttons": [
184
        {
185
            "ID": "twitter",
186
            "name": "Twitter",
187
            "shortname": "twitter",
188
            "custom": false,
189
            "enabled": true,
190
            "visibility": "visible",
191
            "genericon": "\\f202"
192
        },
193
        {
194
            "ID": "facebook",
195
            "name": "Facebook",
196
            "shortname": "facebook",
197
            "custom": false,
198
            "enabled": true,
199
            "visibility": "visible",
200
            "genericon": "\\f203"
201
        }
202
    ]
203
}'
204
) );
205
206
class WPCOM_JSON_API_Get_Sharing_Buttons_Endpoint extends WPCOM_JSON_API_Sharing_Button_Endpoint {
207
208
	// GET /sites/%s/sharing-buttons -> $blog_id
209
	public function callback( $path = '', $blog_id = 0 ) {
210
		$args = $this->query_args();
211
212
		// Validate request
213
		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
214
		if ( is_wp_error( $blog_id ) ) {
215
			return $blog_id;
216
		}
217
218
		$continue = $this->setup();
219
		if ( is_wp_error( $continue ) ) {
220
			return $continue;
221
		}
222
223
		if ( ! empty( $args['visibility'] ) && ! in_array( $args['visibility'], self::$all_visibilities ) ) {
224
			return new WP_Error( 'invalid_visibility', sprintf( 'The visibility field must be one of the following values: %s', implode( ', ', self::$all_visibilities ) ), 400 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'invalid_visibility'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
225
		}
226
227
		// Determine which visibilities to include based on request
228
		$visibilities = empty( $args['visibility'] ) ? self::$all_visibilities : array( $args['visibility'] );
229
230
		// Discover enabled services
231
		$buttons = array();
232
		$enabled_services = $this->sharing_service->get_blog_services();
233
		$all_services = $this->sharing_service->get_all_services_blog();
234
235
		// Include buttons of desired visibility
236
		foreach ( $visibilities as $visibility ) {
237
			$buttons = array_merge( $buttons, $enabled_services[ $visibility ] );
238
		}
239
240
		// Unless `enabled_only` or `visibility` is specified, append the
241
		// remaining buttons to the end of the array
242
		if ( ( ! isset( $args['enabled_only'] ) || ! $args['enabled_only'] ) && empty( $args['visibility'] ) ) {
243
			foreach ( $all_services as $id => $button ) {
244
				if ( ! array_key_exists( $id, $buttons ) ) {
245
					$buttons[ $id ] = $button;
246
				}
247
			}
248
		}
249
250
		// Format each button in the response
251
		$response = array();
252
		foreach ( $buttons as $button ) {
253
			$response[] = $this->format_sharing_button( $button );
254
		}
255
256
		return array(
257
			'found'           => count( $response ),
258
			'sharing_buttons' => $response
259
		);
260
	}
261
}
262
263
new WPCOM_JSON_API_Get_Sharing_Button_Endpoint( array(
264
	'description' => 'Get information about a single sharing button.',
265
	'group'       => '__do_not_document',
266
	'stat'        => 'sharing-buttons:1',
267
	'method'      => 'GET',
268
	'path'        => '/sites/%s/sharing-buttons/%s',
269
	'path_labels' => array(
270
		'$site'      => '(int|string) Site ID or domain',
271
		'$button_id' => '(string) The button ID',
272
	),
273
	'response_format' => array(
274
		'ID'           => '(int) Sharing button ID',
275
		'name'         => '(string) Sharing button name, used as a label on the button itself',
276
		'shortname'    => '(string) A generated short name for the sharing button',
277
		'URL'          => '(string) The URL pattern defined for a custom sharing button',
278
		'icon'         => '(string) URL to the 16x16 icon defined for a custom sharing button',
279
		'genericon'    => '(string) Icon character in Genericons icon set',
280
		'custom'       => '(bool) Is the button a user-created custom sharing button?',
281
		'enabled'      => '(bool) Is the button currently enabled for the site?',
282
		'visibility'   => '(string) If enabled, the current visibility of the sharing button, either "visible" or "hidden"',
283
	),
284
	'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/30434183/sharing-buttons/facebook',
285
	'example_request_data' => array(
286
		'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ),
287
	),
288
	'example_response' => '{
289
	"ID": "facebook",
290
	"name": "Facebook",
291
	"shortname": "facebook",
292
	"custom": false,
293
	"enabled": true,
294
	"visibility": "visible",
295
	"genericon": "\\f203"
296
}'
297
) );
298
299
class WPCOM_JSON_API_Get_Sharing_Button_Endpoint extends WPCOM_JSON_API_Sharing_Button_Endpoint {
300
301
	// GET /sites/%s/sharing-buttons/%s -> $blog_id, $button_id
302 View Code Duplication
	public function callback( $path = '', $blog_id = 0, $button_id = 0 ) {
303
		// Validate request
304
		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
305
		if ( is_wp_error( $blog_id ) ) {
306
			return $blog_id;
307
		}
308
309
		$continue = $this->setup();
310
		if ( is_wp_error( $continue ) ) {
311
			return $continue;
312
		}
313
314
		// Search existing services for button
315
		$all_buttons = $this->sharing_service->get_all_services_blog();
316
		if ( ! array_key_exists( $button_id, $all_buttons ) ) {
317
			return new WP_Error( 'not_found', 'The specified sharing button was not found', 404 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'not_found'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
318
		} else {
319
			return $this->format_sharing_button( $all_buttons[ $button_id ] );
320
		}
321
	}
322
323
}
324
325
new WPCOM_JSON_API_Update_Sharing_Buttons_Endpoint( array(
326
	'description' => 'Edit all sharing buttons for a site.',
327
	'group'       => 'sharing',
328
	'stat'        => 'sharing-buttons:X:POST',
329
	'method'      => 'POST',
330
	'path'        => '/sites/%s/sharing-buttons',
331
	'path_labels' => array(
332
		'$site'      => '(int|string) Site ID or domain',
333
	),
334
	'request_format' => array(
335
		'sharing_buttons' => '(array:sharing_button) An array of sharing button objects',
336
	),
337
	'response_format' => array(
338
		'success' => '(bool) Confirmation that all sharing buttons were updated as specified',
339
		'updated' => '(array) An array of updated sharing buttons',
340
	),
341
	'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/30434183/sharing-buttons',
342
	'example_request_data' => array(
343
		'headers' => array(
344
			'authorization' => 'Bearer YOUR_API_TOKEN',
345
		),
346
		'body' => array(
347
			'sharing_buttons' => array(
348
				array(
349
					'ID'         => 'facebook',
350
					'visibility' => 'hidden',
351
				)
352
			)
353
		)
354
	),
355
	'example_response' => '{
356
	"success": true,
357
	"updated": [
358
		{
359
			"ID": "facebook",
360
			"name": "Facebook",
361
			"shortname": "facebook",
362
			"custom": false,
363
			"enabled": true,
364
			"visibility": "hidden",
365
			"genericon": "\\f204"
366
		}
367
	]
368
}'
369
) );
370
371
class WPCOM_JSON_API_Update_Sharing_Buttons_Endpoint extends WPCOM_JSON_API_Sharing_Button_Endpoint {
372
373
	// POST /sites/%s/sharing-buttons -> $blog_id
374
	public function callback( $path = '', $blog_id = 0 ) {
375
		$input = $this->input();
376
377
		// Validate request
378
		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
379
		if ( is_wp_error( $blog_id ) ) {
380
			return $blog_id;
381
		}
382
383
		$continue = $this->setup();
384
		if ( is_wp_error( $continue ) ) {
385
			return $continue;
386
		}
387
388
		$all_buttons = $this->sharing_service->get_all_services_blog();
389
390
		if ( ! isset( $input['sharing_buttons'] ) ) {
391
			$input['sharing_buttons'] = array();
392
		}
393
394
		// We do a first pass of all buttons to verify that no validation
395
		// issues exist before continuing to update
396
		foreach ( $input['sharing_buttons'] as $button ) {
397
			$button_exists = isset( $button['ID'] ) && array_key_exists( $button['ID'], $all_buttons );
398
			$is_custom = $this->is_button_input_for_custom( $button );
399
400
			// If neither custom nor existing, bail
401
			if ( ! $button_exists && ! $is_custom ) {
402
				return new WP_Error( 'not_found', 'The specified sharing button was not found', 404 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'not_found'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
403
			}
404
405
			// Validate input, only testing custom values if the button doesn't
406
			// already exist
407
			$validation_error = $this->validate_button_input( $button, ! $button_exists );
408
			if ( is_wp_error( $validation_error ) ) {
409
				return $validation_error;
410
			}
411
		}
412
413
		// Reset all existing buttons
414
		$this->sharing_service->set_blog_services( array(), array() );
415
416
		// Finally, we iterate over each button and update or create
417
		$success = true;
418
		$updated = array();
419
		foreach ( $input['sharing_buttons'] as $button ) {
420
			$button_exists = isset( $button['ID'] ) && array_key_exists( $button['ID'], $all_buttons );
421
			if ( $button_exists ) {
422
				$updated_service = $this->update_button( $button['ID'], $button );
423
			} else {
424
				$updated_service = $this->create_custom_button( $button );
425
			}
426
427
			// We'll allow the request to continue if a failure occurred, but
428
			// log it for the response
429
			if ( false === $updated_service ) {
430
				$success = false;
431
			} else {
432
				$updated[] = $this->format_sharing_button( $updated_service );
433
			}
434
		}
435
436
		return array(
437
			'success' => $success,
438
			'updated' => $updated
439
		);
440
	}
441
442
}
443
444
new WPCOM_JSON_API_Update_Sharing_Button_Endpoint( array(
445
	'description' => 'Create a new custom sharing button.',
446
	'group'       => '__do_not_document',
447
	'stat'        => 'sharing-buttons:new',
448
	'method'      => 'POST',
449
	'path'        => '/sites/%s/sharing-buttons/new',
450
	'path_labels' => array(
451
		'$site' => '(int|string) Site ID or domain',
452
	),
453
	'request_format' => array(
454
		'name'       => '(string) The name for your custom sharing button, used as a label on the button itself',
455
		'URL'        => '(string) The URL to use for share links, including optional placeholders (%post_id%, %post_title%, %post_slug%, %post_url%, %post_full_url%, %post_excerpt%, %post_tags%, %home_url%)',
456
		'icon'       => '(string) The full URL to a 16x16 icon to display on the sharing button',
457
		'enabled'    => '(bool) Is the button currently enabled for the site?',
458
		'visibility' => '(string) If enabled, the visibility of the sharing button, either "visible" (default) or "hidden"',
459
	),
460
	'response_format' => array(
461
		'ID'           => '(string) Sharing button ID',
462
		'name'         => '(string) Sharing button name, used as a label on the button itself',
463
		'shortname'    => '(string) A generated short name for the sharing button',
464
		'URL'          => '(string) The URL pattern defined for a custom sharing button',
465
		'icon'         => '(string) URL to the 16x16 icon defined for a custom sharing button',
466
		'genericon'    => '(string) Icon character in Genericons icon set',
467
		'custom'       => '(bool) Is the button a user-created custom sharing button?',
468
		'enabled'      => '(bool) Is the button currently enabled for the site?',
469
		'visibility'   => '(string) If enabled, the current visibility of the sharing button, either "visible" or "hidden"',
470
	),
471
	'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/30434183/sharing-buttons/new/',
472
	'example_request_data' => array(
473
		'headers' => array(
474
			'authorization' => 'Bearer YOUR_API_TOKEN'
475
		),
476
		'body' => array(
477
			'name'       => 'Custom',
478
			'URL'        => 'https://www.wordpress.com/%post_name%',
479
			'icon'       => 'https://en.wordpress.com/i/stats-icon.gif',
480
			'enabled'    => true,
481
			'visibility' => 'visible'
482
		)
483
	),
484
	'example_response' => '{
485
	"ID": "custom-123456789",
486
	"name": "Custom",
487
	"shortname": "custom",
488
	"url": "https://www.wordpress.com/%post_name%",
489
	"icon": "https://en.wordpress.com/i/stats-icon.gif",
490
	"custom": true,
491
	"enabled": true,
492
	"visibility": "visible"
493
}'
494
) );
495
496
new WPCOM_JSON_API_Update_Sharing_Button_Endpoint( array(
497
	'description' => 'Edit a sharing button.',
498
	'group'       => '__do_not_document',
499
	'stat'        => 'sharing-buttons:1:POST',
500
	'method'      => 'POST',
501
	'path'        => '/sites/%s/sharing-buttons/%s',
502
	'path_labels' => array(
503
		'$site'      => '(int|string) Site ID or domain',
504
		'$button_id' => '(string) The button ID',
505
	),
506
	'request_format' => array(
507
		'name'       => '(string) Only if a custom sharing button, a new name used as a label on the button itself',
508
		'URL'        => '(string) Only if a custom sharing button, the URL to use for share links, including optional placeholders (%post_title%, %post_url%, %post_full_url%, %post_excerpt%, %post_tags%)',
509
		'icon'       => '(string) Only if a custom sharing button, the full URL to a 16x16 icon to display on the sharing button',
510
		'enabled'    => '(bool) Is the button currently enabled for the site?',
511
		'visibility' => '(string) If enabled, the visibility of the sharing button, either "visible" (default) or "hidden"',
512
	),
513
	'response_format' => array(
514
		'ID'           => '(string) Sharing button ID',
515
		'name'         => '(string) Sharing button name, used as a label on the button itself',
516
		'shortname'    => '(string) A generated short name for the sharing button',
517
		'URL'          => '(string) The URL pattern defined for a custom sharing button',
518
		'icon'         => '(string) URL to the 16x16 icon defined for a custom sharing button',
519
		'genericon'    => '(string) Icon character in Genericons icon set',
520
		'custom'       => '(bool) Is the button a user-created custom sharing button?',
521
		'enabled'      => '(bool) Is the button currently enabled for the site?',
522
		'visibility'   => '(string) If enabled, the current visibility of the sharing button, either "visible" or "hidden"',
523
	),
524
	'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/30434183/sharing-buttons/custom-123456789/',
525
	'example_request_data' => array(
526
		'headers' => array(
527
			'authorization' => 'Bearer YOUR_API_TOKEN'
528
		),
529
		'body' => array(
530
			'enabled' => false,
531
		)
532
	),
533
	'example_response' => '{
534
	"ID": "custom-123456789",
535
	"name": "Custom",
536
	"shortname": "custom",
537
	"custom": true,
538
	"enabled": false,
539
	"icon": "https://en.wordpress.com/i/stats-icon.gif",
540
	"url": "https://www.wordpress.com/%post_name%"
541
}'
542
) );
543
544
class WPCOM_JSON_API_Update_Sharing_Button_Endpoint extends WPCOM_JSON_API_Sharing_Button_Endpoint {
545
546
	// POST /sites/%s/sharing-buttons/new -> $blog_id
547
	// POST /sites/%s/sharing-buttons/%s -> $blog_id, $button_id
548
	public function callback( $path = '', $blog_id = 0, $button_id = 0 ) {
549
		$new = $this->api->ends_with( $path, '/new' );
550
		$input = $this->input();
551
552
		// Validate request
553
		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
554
		if ( is_wp_error( $blog_id ) ) {
555
			return $blog_id;
556
		}
557
558
		$continue = $this->setup();
559
		if ( is_wp_error( $continue ) ) {
560
			return $continue;
561
		}
562
563
		$validation_error = $this->validate_button_input( $input, $new );
564
		if ( is_wp_error( $validation_error ) ) {
565
			return $validation_error;
566
		}
567
568
		// Update or create button
569
		if ( $new ) {
570
			$updated_service = $this->create_custom_button( $input );
571
		} else {
572
			$updated_service = $this->update_button( $button_id, $input );
573
		}
574
575
		if ( false === $updated_service ) {
576
			return new WP_Error( 'invalid_request', sprintf( 'The sharing button was not %s', $new ? 'created' : 'updated' ), 400 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'invalid_request'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
577
		} else if ( is_wp_error( $updated_service ) ) {
578
			return $updated_service;
579
		} else {
580
			return $this->format_sharing_button( $updated_service );
581
		}
582
	}
583
584
}
585
586
new WPCOM_JSON_API_Delete_Sharing_Button_Endpoint( array(
587
	'description' => 'Delete a custom sharing button.',
588
	'group'		  => '__do_not_document',
589
	'stat'		  => 'sharing-buttons:1:delete',
590
	'method'	  => 'POST',
591
	'path'        => '/sites/%s/sharing-buttons/%s/delete',
592
	'path_labels' => array(
593
		'$site'      => '(int|string) Site ID or domain',
594
		'$button_id' => '(string) The button ID',
595
	),
596
	'response_format' => array(
597
		'ID'      => '(int) The ID of the deleted sharing button',
598
		'success' => '(bool) Confirmation that the sharing button has been removed'
599
	),
600
	'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/30434183/sharing-buttons/custom-123456789/delete',
601
	'example_request_data' => array(
602
		'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ),
603
	),
604
	'example_response' => '{
605
	"ID": "custom-123456789",
606
	"success": "true"
607
}'
608
) );
609
610
class WPCOM_JSON_API_Delete_Sharing_Button_Endpoint extends WPCOM_JSON_API_Sharing_Button_Endpoint {
611
612
	// POST /sites/%s/sharing-buttons/%s/delete -> $blog_id, $button_id
613
	public function callback( $path = '', $blog_id = 0, $button_id = 0 ) {
614
		// Validate request
615
		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
616
		if ( is_wp_error( $blog_id ) ) {
617
			return $blog_id;
618
		}
619
620
		$continue = $this->setup();
621
		if ( is_wp_error( $continue ) ) {
622
			return $continue;
623
		}
624
625
		// Find existing button
626
		$all_buttons = $this->sharing_service->get_all_services_blog();
627
		if ( ! array_key_exists( $button_id, $all_buttons ) ) {
628
			// Button doesn't exist
629
			return new WP_Error( 'not_found', 'The specified sharing button was not found', 404 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'not_found'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
630
		}
631
632
		// Verify button is custom
633
		if ( ! is_a( $all_buttons[ $button_id ], 'Share_Custom' ) ) {
634
			return new WP_error( 'invalid_request', 'Only custom sharing buttons can be deleted', 400 );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'invalid_request'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
635
		}
636
637
		$success = $this->sharing_service->delete_service( $button_id );
638
		return array(
639
			'ID'      => $button_id,
640
			'success' => $success
641
		);
642
	}
643
644
}
645