summaryrefslogtreecommitdiff
blob: 6048cdf3fa9e08f3b5aa535e56cdc66d24c128c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
<?php

new WPCOM_JSON_API_Update_Invites_Endpoint( array(
	'description' => 'Delete an invite for a user to join a site.',
	'group'       => '__do_not_document',
	'stat'        => 'invites:1:delete',
	'method'      => 'POST',
	'path'        => '/sites/%s/invites/%s/delete',
	'path_labels' => array(
		'$site'      => '(int|string) Site ID or domain',
		'$invite_id' => '(string) The ID of the invite'
	),
	'response_format' => array(
		'invite_key' => '(string) Identifier for the deleted invite',
		'deleted' => '(bool) Was the invitation removed?'
	),

	'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/30434183/invites/123523562/delete',

	'example_request_data' => array(
		'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ),
	),
) );

new WPCOM_JSON_API_Update_Invites_Endpoint( array(
	'description' => 'Resend invitation for a user to join a site.',
	'group'       => '__do_not_document',
	'stat'        => 'invites:1',
	'method'      => 'POST',
	'path'        => '/sites/%s/invites/%s/resend',
	'path_labels' => array(
		'$site'      => '(int|string) Site ID or domain',
		'$invite_id' => '(string) The ID of the invite'
	),
	'response_format' => array(
		'result' => '(bool) Was the invitation resent?'
	),

	'example_request' => 'https://public-api.wordpress.com/rest/v1/sites/30434183/invites/123523562',

	'example_request_data' => array(
		'headers' => array( 'authorization' => 'Bearer YOUR_API_TOKEN' ),
	),
) );

class WPCOM_JSON_API_Update_Invites_Endpoint extends WPCOM_JSON_API_Endpoint {
	public $blog_id;
	public $invite_id;
	public $is_wpcom;
	public $invite;

	function callback( $path = '', $blog_id = 0, $invite_id = 0 ) {
		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ) );
		if ( is_wp_error( $blog_id ) ) {
			return $blog_id;
		}

		if ( ! is_multisite() ) {
			return new WP_Error( 'forbidden', 'To modify invites, site must be on a multisite installation.', 403 );
		}

		if ( ! current_user_can( 'promote_users' ) ) {
			return new WP_Error( 'unauthorized', 'Your token must have permission to promote users on this blog.', 401 );
		}

		$this->blog_id   = $blog_id;
		$this->invite_id = $invite_id;
		$this->is_wpcom  = defined( 'IS_WPCOM' ) && IS_WPCOM;

		$invite = $this->get_invite();
		if ( false === $invite ) {
			return new WP_Error( 'unknown_invite', 'Requested invite was not found.', 404 );
		}

		$this->invite = $invite;

		$returnValue = false;
		if ( $this->api->ends_with( $this->path, '/delete' ) ) {
			$returnValue = array(
				'invite_key' => $invite_id,
				'deleted'    => $this->delete_invite(),
			);
		} else if ( $this->api->ends_with( $this->path, '/resend' ) ) {
			$returnValue = array(
				'result' => $this->is_wpcom ? $this->resend_wpcom_invite() : $this->resend_self_hosted_invite()
			);
		}

		return $returnValue;
	}

	/**
	 * Returns an invite if found or false if not found.
	 *
	 * @return bool|object
	 */
	function get_invite() {
		global $wpdb, $wpcom_invite_users;

		$invite = false;
		if ( $this->is_wpcom ) {
			$invite = $wpcom_invite_users->get_invitation( $this->invite_id );
		} else {
			$query = $wpdb->prepare( "SELECT * FROM $wpdb->options WHERE option_name = %s LIMIT 1", $this->invite_id );
			$invite = $wpdb->get_results( $query );

			$invite = empty( $invite ) ? false : $invite;
		}

		return $invite;
	}

	/**
	 * Deletes an invitation.
	 *
	 * @return bool Whether the invite was deleted successfully.
	 */
	function delete_invite() {
		global $wpdb, $wpcom_invite_users;

		if ( $this->is_wpcom ) {
			return (bool) $wpcom_invite_users->delete_invitation( $this->invite_id );
		} else {
			$query = $wpdb->prepare( "DELETE FROM $wpdb->options WHERE option_name = %s", $this->invite_id );
			return 0 < $wpdb->query( $query );
		}
	}

	/**
	 * Sends an invitation email to a user to join a self-hosted site.
	 *
	 * This method duplicates the invitation email functionality that is present
	 * in wp-admin/user-new.php. Ideally, we should factor out the functionality
	 * in wp-admin/user-new.php that actually invites a user and sends the invite
	 * from the data validation checks that expect $_POST and $_REQUEST.
	 *
	 * @return bool Whether the email was sent successfully.
	 */
	function resend_self_hosted_invite() {
		$invite = (array) unserialize( $this->invite[0]->option_value );
		$roles = get_editable_roles();
		$role = $roles[ $invite['role'] ];
		$newuser_key = str_replace( 'new_user_', '', $this->invite_id );

		/* translators: 1: Site title 2: Site URL 3: Role name 4: URL to accept invitation */
		$message = __( 'Hi,

You\'ve been invited to join \'%1$s\' at
%2$s with the role of %3$s.

Please click the following link to confirm the invite:
%4$s', 'jetpack' );

		return wp_mail(
			$invite['email'],
			sprintf( __( '[%s] Joining confirmation', 'jetpack' ), wp_specialchars_decode( get_option( 'blogname' ) ) ),
			sprintf(
				$message,
				get_option( 'blogname' ),
				home_url(),
				wp_specialchars_decode( translate_user_role( $role['name'] ) ),
				home_url( "/newbloguser/$newuser_key/" )
			)
		);
	}

	/**
	 * Sends an invitation email to a user to join a WordPress.com site.
	 *
	 * @return bool Whether the invitation was sent successfully.
	 */
	function resend_wpcom_invite() {
		global $wpcom_invite_users;

		$wpcom_invite_users->update_invitation( $this->invite->invite_slug, array( 'invite_date' => gmdate( 'Y-m-d H:i:s' ) ) );

		if ( 'follower' == $this->invite->meta['role'] && ! is_private_blog() ) {
			$wpcom_invite_users->invite_followers( $this->invite->meta['sent_to'] );
		} else {
			$wpcom_invite_users->send_invitation( $this->invite->invite_slug );
		}

		return true;
	}
}