Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/paid-memberships-pro/includes/rest-api.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
1 + <?php
2 +
3 + if ( class_exists( 'WP_REST_Controller' ) ) {
4 + class PMPro_REST_API_Routes extends WP_REST_Controller {
5 +
6 + public function pmpro_rest_api_register_routes() {
7 +
8 + // ================ DEPRECATED ================ //
9 + $namespace = 'wp/v2';
10 + register_rest_route( $namespace, '/users/(?P<id>\d+)'.'/pmpro_membership_level' ,
11 + array(
12 + array(
13 + 'methods' => WP_REST_Server::READABLE,
14 + 'callback' => array( $this, 'pmpro_rest_api_get_membership_level_for_user' ),
15 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
16 + ),));
17 +
18 + register_rest_route( $namespace, '/posts/(?P<post_id>\d+)'.'/user_id/(?P<user_id>\d+)/pmpro_has_membership_access' ,
19 + array(
20 + array(
21 + 'methods' => WP_REST_Server::READABLE,
22 + 'callback' => array( $this, 'pmpro_rest_api_get_has_membership_access' ),
23 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
24 + ),));
25 + // ================================================ //
26 +
27 + $pmpro_namespace = 'pmpro/v1';
28 +
29 + /**
30 + * Get user access for a specific post.
31 + * @since 2.3
32 + * Example: https://example.com/wp-json/pmpro/v1/has_membership_access
33 + */
34 + register_rest_route( $pmpro_namespace, '/has_membership_access',
35 + array(
36 + array(
37 + 'methods' => WP_REST_Server::READABLE,
38 + 'callback' => array( $this, 'pmpro_rest_api_get_has_membership_access'),
39 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
40 + )));
41 +
42 + /**
43 + * Get a membership level for a user.
44 + * @since 2.3
45 + * Example: https://example.com/wp-json/pmpro/v1/get_membership_level_for_user
46 + */
47 + register_rest_route( $pmpro_namespace, '/get_membership_level_for_user',
48 + array(
49 + array(
50 + 'methods' => WP_REST_Server::READABLE,
51 + 'callback' => array( $this, 'pmpro_rest_api_get_membership_level_for_user' ),
52 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
53 + ),));
54 +
55 + /**
56 + * Get a membership level for a user.
57 + * @since 2.3
58 + * Example: https://example.com/wp-json/pmpro/v1/get_membership_levels_for_user
59 + */
60 + register_rest_route( $pmpro_namespace, '/get_membership_levels_for_user',
61 + array(
62 + array(
63 + 'methods' => WP_REST_Server::READABLE,
64 + 'callback' => array( $this, 'pmpro_rest_api_get_membership_levels_for_user' ),
65 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
66 + ),));
67 +
68 +
69 + /**
70 + * Change a user's membership level. This also supports to cancel a membership if you pass through 0.
71 + * @since 2.3
72 + * Example: https://example.com/wp-json/pmpro/v1/change_membership_level
73 + */
74 + register_rest_route( $pmpro_namespace, '/change_membership_level',
75 + array(
76 + array(
77 + 'methods' => 'POST,PUT,PATCH',
78 + 'callback' => array( $this, 'pmpro_rest_api_change_membership_level' ),
79 + 'args' => array(
80 + 'user_id' => array(),
81 + 'level_id' => array(),
82 + 'email' => array(),
83 + 'first_name' => array(),
84 + 'last_name' => array(),
85 + 'user_url' => array(),
86 + 'user_login' => array(),
87 + 'description' => array(),
88 + 'create_user' => array(),
89 + ),
90 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
91 + )
92 + )
93 + );
94 +
95 + /**
96 + * Cancel a membership level.
97 + * @since 2.3
98 + * Example: https://example.com/wp-json/pmpro/v1/cancel_membership_level
99 + */
100 + register_rest_route( $pmpro_namespace, '/cancel_membership_level',
101 + array(
102 + array(
103 + 'methods' => 'POST,PUT,PATCH',
104 + 'callback' => array( $this, 'pmpro_rest_api_cancel_membership_level' ),
105 + 'args' => array(
106 + 'user_id' => array(),
107 + 'level_id' => array()
108 + ),
109 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
110 + )
111 + )
112 + );
113 +
114 + /**
115 + * Delete/Retrieve/Update/Create a Membership Level.
116 + * @since 2.3
117 + * Example: https://example.com/wp-json/pmpro/v1/membership_level
118 + */
119 + register_rest_route( $pmpro_namespace, '/membership_level' ,
120 + array(
121 + array(
122 + 'methods' => WP_REST_Server::READABLE,
123 + 'callback' => array( $this, 'pmpro_rest_api_get_membership_level' ),
124 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
125 + ),
126 + array(
127 + 'methods' => 'POST,PUT,PATCH',
128 + 'callback' => array( $this, 'pmpro_rest_api_set_membership_level' ),
129 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
130 + ),
131 + array(
132 + 'methods' => 'DELETE',
133 + 'callback' => array( $this, 'pmpro_rest_api_delete_membership_level' ),
134 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
135 + )
136 + ));
137 +
138 + /**
139 + * Get all membership levels.
140 + * @since 3.0
141 + * Example: https://example.com/wp-json/pmpro/v1/membership_levels
142 + */
143 + register_rest_route( $pmpro_namespace, '/membership_levels',
144 + array(
145 + array(
146 + 'methods' => WP_REST_Server::READABLE,
147 + 'callback' => array( $this, 'pmpro_rest_api_get_membership_levels' ),
148 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
149 + ),
150 + )
151 + );
152 +
153 + /**
154 + * Create/Retrieve discount code.
155 + * @since 2.3
156 + * Example: https://example.com/wp-json/pmpro/v1/discount_code
157 + */
158 + register_rest_route( $pmpro_namespace, '/discount_code',
159 + array(
160 + array(
161 + 'methods' => WP_REST_Server::READABLE,
162 + 'callback' => array( $this, 'pmpro_rest_api_get_discount_code' ),
163 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
164 + ),
165 + array(
166 + 'methods' => 'POST,PUT,PATCH',
167 + 'callback' => array( $this, 'pmpro_rest_api_set_discount_code' ),
168 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
169 + ),
170 + ));
171 +
172 + /**
173 + * Retrieve an order.
174 + * @since 2.8
175 + * Example: https://example.com/wp-json/pmpro/v1/order
176 + */
177 + register_rest_route( $pmpro_namespace, '/order',
178 + array(
179 + array(
180 + 'methods' => WP_REST_Server::READABLE,
181 + 'callback' => array( $this, 'pmpro_rest_api_get_order' ),
182 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
183 + ),
184 + ));
185 + add_filter( 'pmpro_rest_api_permissions', array( $this, 'pmpro_rest_api_permissions_get_order' ), 10, 2 );
186 +
187 + /**
188 + * Get membership level after checkout options are applied.
189 + * @since 2.4
190 + * Example: https://example.com/wp-json/pmpro/v1/checkout_level
191 + */
192 + register_rest_route( $pmpro_namespace, '/checkout_level',
193 + array(
194 + array(
195 + 'methods' => WP_REST_Server::READABLE,
196 + 'callback' => array( $this, 'pmpro_rest_api_get_checkout_level' ),
197 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
198 + ),
199 + ));
200 +
201 + /**
202 + * Get membership levels after checkout options are applied.
203 + * Example: https://example.com/wp-json/pmpro/v1/checkout_levels
204 + * @deprecated 3.0
205 + */
206 + register_rest_route( $pmpro_namespace, '/checkout_levels',
207 + array(
208 + array(
209 + 'methods' => WP_REST_Server::READABLE,
210 + 'callback' => array( $this, 'pmpro_rest_api_get_checkout_levels' ),
211 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
212 + ),
213 + ));
214 +
215 + /**
216 + * Authentication route for Zapier integration.
217 + *
218 + * Used to do authentication when connecting Zapier to PMPro.
219 + *
220 + * @since 2.6.0
221 + */
222 + register_rest_route( $pmpro_namespace, '/me',
223 + array(
224 + array(
225 + 'methods' => WP_REST_Server::READABLE,
226 + 'callback' => array( $this, 'validate_me' ),
227 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' )
228 + ),
229 + )
230 + );
231 +
232 + /**
233 + * Get the last couple of membership levels/members.
234 + *
235 + * @since 2.6.0
236 + */
237 + register_rest_route( $pmpro_namespace, '/recent_memberships',
238 + array(
239 + array(
240 + 'methods' => WP_REST_Server::READABLE,
241 + 'callback' => array( $this, 'pmpro_rest_api_recent_memberships' ),
242 + 'args' => array(
243 + 'status' => array(),
244 + ),
245 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
246 + )
247 + ));
248 +
249 + register_rest_route( $pmpro_namespace, '/recent_orders',
250 + array(
251 + array(
252 + 'methods' => WP_REST_Server::READABLE,
253 + 'callback' => array( $this, 'pmpro_rest_api_recent_orders' ),
254 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
255 + )
256 + )
257 + );
258 +
259 + /**
260 + * Get the IDs that a post has been restricted to.
261 + * @since 3.0
262 + * Example: https://example.com/wp-json/pmpro/v1/post_restrictions
263 + */
264 + register_rest_route( $pmpro_namespace, '/post_restrictions',
265 + array(
266 + array(
267 + 'methods' => WP_REST_Server::READABLE,
268 + 'callback' => array( $this, 'pmpro_rest_api_get_post_restrictions' ),
269 + 'args' => array(
270 + 'post_id' => array(),
271 + ),
272 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
273 + ),
274 + array(
275 + 'methods' => WP_REST_Server::EDITABLE,
276 + 'args' => array(
277 + 'post_id' => array(),
278 + 'level_ids' => array(),
279 + ),
280 + 'callback' => array( $this, 'pmpro_rest_api_set_post_restrictions' ),
281 + 'permission_callback' => array( $this, 'pmpro_rest_api_get_permissions_check' ),
282 + )
283 + )
284 + );
285 + }
286 +
287 + /**
288 + * Get user's membership level.
289 + * @since 2.3
290 + * Example: https://example.com/wp-json/pmpro/v1/get_membership_level_for_user?user_id=1
291 + */
292 + function pmpro_rest_api_get_membership_level_for_user($request) {
293 + $params = $request->get_params();
294 +
295 + $user_id = isset( $params['user_id'] ) ? intval( $params['user_id'] ) : null;
296 +
297 + // Param id was used instead (old style endpoint).
298 + if ( empty( $user_id ) && !empty( $params['id'] ) ) {
299 + $user_id = intval( $params['id'] );
300 + }
301 +
302 + // Query by email.
303 + if ( empty( $user_id ) && !empty( $params['email'] ) ) {
304 + $user = get_user_by( 'email', sanitize_email( $params['email'] ) );
305 + $user_id = $user->ID;
306 + }
307 +
308 + if ( ! empty( $user_id ) ) {
309 + $level = pmpro_getMembershipLevelForUser( $user_id );
310 + } else {
311 + $level = false;
312 + }
313 +
314 + return new WP_REST_Response( $level, 200 );
315 + }
316 +
317 + /**
318 + * Get user's membership levels. (MMPU)
319 + * @since 2.3
320 + * Example: https://example.com/wp-json/pmpro/v1/get_membership_levels_for_user?user_id=1
321 + */
322 + function pmpro_rest_api_get_membership_levels_for_user($request) {
323 + $params = $request->get_params();
324 +
325 + $user_id = isset( $params['user_id'] ) ? intval( $params['user_id'] ) : null;
326 +
327 + // Param id was used instead.
328 + if ( empty( $user_id ) && !empty( $params['id'] ) ) {
329 + $user_id = intval( $params['id'] );
330 + }
331 +
332 + // Param email was used instead.
333 + if ( empty( $user_id ) && !empty( $params['email'] ) ) {
334 + $user = get_user_by( 'email', sanitize_email( $params['email'] ) );
335 + $user_id = $user->ID;
336 + }
337 +
338 + if ( ! empty( $user_id ) ) {
339 + $levels = pmpro_getMembershipLevelsForUser( $user_id );
340 + } else {
341 + $levels = false;
342 + }
343 +
344 + return new WP_REST_Response( $levels, 200 );
345 + }
346 +
347 + /**
348 + * Get user's access status for a specific post.
349 + * @since 2.3
350 + * Example: https://example.com/wp-json/wp/v2/posts/58/user_id/2/pmpro_has_membership_access
351 + * Example: https://example.com/wp-json/pmpro/v1/has_membership_access?post_id=58&user_id=2
352 + */
353 + function pmpro_rest_api_get_has_membership_access($request) {
354 + $params = $request->get_params();
355 + $post_id = isset( $params['post_id'] ) ? intval( $params['post_id'] ) : null;
356 + $user_id = isset( $params['user_id'] ) ? intval( $params['user_id'] ) : null;
357 +
358 + if ( empty( $user_id ) ) {
359 + // see if they sent an email
360 + if ( ! empty( $params['email'] ) ) {
361 + $user = get_user_by( 'email', sanitize_email( $params['email'] ) );
362 + $user_id = $user->ID;
363 + } else {
364 + return new WP_REST_Response( 'No user information passed through.', 404 );
365 + }
366 + }
367 +
368 + if ( ! empty( $user_id ) ) {
369 + $has_access = pmpro_has_membership_access( $post_id, $user_id );
370 + } else {
371 + // No good user, so say no.
372 + // Technically this will make public posts look restricted.
373 + $has_access = false;
374 + }
375 +
376 + return new WP_REST_Response( $has_access, 200 );
377 + }
378 +
379 + /**
380 + * Change a user's membership level.
381 + * @since 2.3
382 + * Example: https://example.com/wp-json/pmpro/v1/change_membership_level
383 + */
384 + function pmpro_rest_api_change_membership_level( $request ) {
385 + $params = $request->get_params();
386 + $user_id = isset( $params['user_id'] ) ? (int) $params['user_id'] : null;
387 + $level_id = isset( $params['level_id'] ) ? (int) $params['level_id'] : null;
388 + $email = isset( $params['email'] ) ? sanitize_email( $params['email'] ) : null;
389 + $first_name = isset( $params['first_name'] ) ? sanitize_text_field( $params['first_name'] ) : '';
390 + $last_name = isset( $params['last_name'] ) ? sanitize_text_field( $params['last_name'] ) : '';
391 + $username = isset( $params['user_login'] ) ? sanitize_text_field( $params['user_login'] ) : $email;
392 + $user_url = isset( $params['user_url'] ) ? sanitize_text_field( $params['user_url'] ) : '';
393 + $description = isset( $params['description'] ) ? sanitize_textarea_field( $params['description'] ) : '';
394 + $create_user = isset( $params['create_user'] ) ? filter_var( $params['create_user'], FILTER_VALIDATE_BOOLEAN ) : false;
395 + $response_type = isset( $params['response_type'] ) ? sanitize_text_field( $params['response_type'] ) : null;
396 +
397 + if ( empty( $user_id ) ) {
398 +
399 + // see if they sent an email
400 + if ( ! empty( $email ) ) {
401 +
402 + $user = get_user_by( 'email', $email );
403 +
404 + // Assume the user doesn't already exist.
405 + if ( $create_user && ! $user ) {
406 +
407 + /**
408 + * Filter the user data arguments for wp_insert_user when creating the user via the REST API.
409 + * @since 2.7.4
410 + * @param array $user_data An associative array with user arguments when creating the user. See https://developer.wordpress.org/reference/functions/wp_insert_user/ for reference.
411 + */
412 + $user_data = apply_filters( 'pmpro_api_new_user_array', array(
413 + 'user_pass' => wp_generate_password(),
414 + 'user_email' => $email,
415 + 'user_login' => $username,
416 + 'first_name' => $first_name,
417 + 'last_name' => $last_name,
418 + 'user_url' => $user_url,
419 + 'description' => $description
420 + )
421 + );
422 +
423 + $user_id = wp_insert_user( $user_data );
424 +
425 + if ( is_wp_error( $user_id ) ) {
426 + $error = $user_id->get_error_message();
427 + return new WP_REST_Response( $error, 500 ); // Assume it failed and return a 500 error occurred like core WordPress.
428 + }
429 +
430 + pmpro_maybe_send_wp_new_user_notification( $user_id, $level_id );
431 + } else {
432 + $user_id = $user->ID;
433 + }
434 +
435 + } else {
436 +
437 + if ( 'json' === $response_type ) {
438 + wp_send_json_error( array( 'email' => $email, 'error' => 'No user information passed through.' ) );
439 + }
440 + return new WP_REST_Response( 'No user information passed through.', 404 );
441 + }
442 + }
443 +
444 + if ( ! function_exists( 'pmpro_changeMembershipLevel' ) ) {
445 + if ( 'json' === $response_type ) {
446 + wp_send_json_error( array( 'email' => $email, 'error' => 'Paid Memberships Pro function not found.' ) );
447 + }
448 + return new WP_REST_Response( 'Paid Memberships Pro function not found.', 404 );
449 + }
450 +
451 + // Make sure we have a user_id by now.
452 + if ( empty( $user_id ) ) {
453 + if ( 'json' === $response_type ) {
454 + wp_send_json_error( array( 'email' => $email, 'error' => 'No user found with that email address. Try the create_user parameter.' ) );
455 + }
456 + return new WP_REST_Response( 'No user found with that email address. Try the create_user parameter.', 404 );
457 + }
458 +
459 + /**
460 + * Filter to allow admin levels to be changed via the REST API or Zapier application.
461 + * Defaults to false to prevent admin users from having their level changed via API.
462 + * @since 2.7.4
463 + * @param boolean $can_change_admin_users Should API calls change admin account membership levels.
464 + */
465 + $can_change_admin_users = apply_filters( 'pmpro_api_change_membership_level_for_admin_users', false );
466 + if ( ! $can_change_admin_users && user_can( $user_id, 'manage_options' ) ) {
467 + if ( 'json' === $response_type ) {
468 + wp_send_json_error( array( 'email' => $email, 'error' => 'Sorry, you are not allowed to edit admin accounts.' ) );
469 + }
470 + return new WP_REST_Response( 'Sorry, you are not allowed to edit admin accounts.', 403 );
471 + }
472 +
473 + $response = pmpro_changeMembershipLevel( $level_id, $user_id );
474 +
475 + if ( 'json' === $response_type ) {
476 + wp_send_json_success( array( 'user_id' => $user_id, 'level_changed' => $level_id, 'response' => $response, 'status' => 200 ) );
477 + }
478 + return new WP_REST_Response( $response, 200 );
479 + }
480 +
481 + /**
482 + * Cancel a user's membership level.
483 + * @since 2.3
484 + * Example: https://example.com/wp-json/pmpro/v1/cancel_membership_level
485 + */
486 + function pmpro_rest_api_cancel_membership_level( $request ) {
487 + $params = $request->get_params();
488 + $user_id = isset( $params['user_id'] ) ? intval( $params['user_id'] ) : null;
489 + $level_id = isset( $params['level_id'] ) ? intval( $params['level_id'] ) : null;
490 + $email = isset( $params['email'] ) ? sanitize_email( $params['email'] ) : null;
491 + $response_type = isset( $params['response_type'] ) ? sanitize_text_field( $params['response_type'] ) : null;
492 +
493 + if ( empty( $user_id ) ) {
494 + // see if they sent an email
495 + if ( ! empty( $email ) ) {
496 + $user = get_user_by( 'email', $email );
497 + $user_id = $user->ID;
498 + } else {
499 + if ( 'json' === $response_type ) {
500 + wp_send_json_error( array( 'email' => $email ) );
501 + }
502 +
503 + return new WP_REST_Response( 'No user information passed through.', 404 );
504 + }
505 + }
506 +
507 + if ( empty( $level_id ) ) {
508 + if ( 'json' === $response_type ) {
509 + wp_send_json_error( array( 'email' => $email ) );
510 + }
511 +
512 + return new WP_REST_Response( 'No membership level ID data.', 400 );
513 + }
514 +
515 + if ( ! function_exists( 'pmpro_cancelMembershipLevel' ) ) {
516 + if ( 'json' === $response_type ) {
517 + wp_send_json_error( array( 'email' => $email ) );
518 + }
519 +
520 + return new WP_REST_Response( 'Paid Memberships Pro function not found.', 404 );
521 + }
522 +
523 + if ( ! empty( $user_id ) ) {
524 + $response = pmpro_cancelMembershipLevel( $level_id, $user_id, 'inactive' );
525 + } else {
526 + $response = false;
527 + }
528 +
529 + if ( 'json' === $response_type ) {
530 + wp_send_json_success( array( 'email' => $email ) );
531 + }
532 +
533 + return new WP_REST_Response( $response, 200 );
534 + }
535 +
536 + /**
537 + * Endpoint to get membership level data
538 + * @since 2.3
539 + * Example: https://example.com/wp-json/pmpro/v1/membership_level/
540 + */
541 + function pmpro_rest_api_get_membership_level( $request ) {
542 +
543 + if ( ! class_exists( 'PMPro_Membership_Level' ) ) {
544 + return new WP_REST_Response( 'Paid Memberships Pro level class not found.', 404 );
545 + }
546 +
547 + $params = $request->get_params();
548 + $id = isset( $params['id'] ) ? intval( $params['id'] ) : null;
549 + $response_type = isset( $params['response_type'] ) ? sanitize_text_field( $params['response_type'] ) : false;
550 +
551 + if ( empty( $id ) ) {
552 + return new WP_REST_Response( 'ID not passed through', 400 );
553 + }
554 +
555 + $level = new PMPro_Membership_Level( $id );
556 +
557 + // Hide confirmation message if not an admin or member.
558 + if ( ! empty( $level->confirmation )
559 + && ! pmpro_hasMembershipLevel( $id )
560 + && ! current_user_can( 'pmpro_edit_members' ) ) {
561 + $level->confirmation = '';
562 + }
563 +
564 + if ( 'json' === $response_type ) {
565 + wp_send_json_success( array( 'level' => $level ) );
566 + }
567 +
568 + return new WP_REST_Response( $level, 200 );
569 + }
570 +
571 + /**
572 + * Create/Update a Membership Level
573 + * @since 2.3
574 + * Example: https://example.com/wp-json/pmpro/v1/membership_level/
575 + */
576 + function pmpro_rest_api_set_membership_level( $request ) {
577 +
578 + if ( ! class_exists( 'PMPro_Membership_Level' ) ) {
579 + return new WP_REST_Response( 'Paid Memberships Pro level class not found.', 404 );
580 + }
581 +
582 + $params = $request->get_params();
583 + $method = $request->get_method();
584 +
585 + $id = isset( $params['id'] ) ? intval( $params['id'] ) : '';
586 + $response_type = isset( $params['response_type'] ) ? sanitize_text_field( $params['response_type'] ) : null;
587 +
588 + // Pass through an ID only for PUT/PATCH methods. POST treats it as a brand new level.
589 + if ( ! empty( $id ) && ( $method === 'PUT' || $method === 'PATCH' ) ) {
590 + $level = new PMPro_Membership_Level( $id );
591 + } elseif ( empty( $id ) && ( $method === 'PUT' || $method === 'PATCH' ) ) {
592 + return false; // Error trying to update
593 + } elseif ( $method === 'POST' ) {
594 + $level = new PMPro_Membership_Level();
595 + }
596 +
597 + $name = isset( $params['name'] ) ? sanitize_text_field( $params['name'] ) : $level->name;
598 + $description = isset( $params['description'] ) ? sanitize_text_field( $params['description'] ) : $level->description;
599 + $confirmation = isset( $params['confirmation'] ) ? sanitize_text_field( $params['confirmation'] ) : $level->confirmation;
600 + $initial_payment = isset( $params['initial_payment'] ) ? floatval( $params['initial_payment'] ) : $level->initial_payment;
601 + $billing_amount = isset( $params['billing_amount'] ) ? floatval( $params['billing_amount'] ) : $level->billing_amount;
602 + $cycle_number = isset( $params['cycle_number'] ) ? intval( $params['cycle_number'] ) : $level->cycle_number;
603 + $cycle_period = isset( $params['cycle_period'] ) ? pmpro_sanitize_period( $params['cycle_period'] ) : $level->cycle_period;
604 + $billing_limit = isset( $params['billing_limit'] ) ? sanitize_text_field( $params['billing_limit'] ) : $level->billing_limit;
605 + $trial_amount = isset( $params['trial_amount'] ) ? floatval( $params['trial_amount'] ) : $level->trial_amount;
606 + $trial_limit = isset( $params['trial_limit'] ) ? floatval( $params['trial_limit'] ) : $level->trial_limit;
607 + $allow_signups = isset( $params['allow_signups'] ) ? intval( $params['allow_signups'] ) : $level->allow_signups;
608 + $expiration_number = isset( $params['expiration_number'] ) ? intval( $params['expiration_number'] ) : $level->expiration_number;
609 + $expiration_period = isset( $params['expiration_period'] ) ? intval( $params['expiration_period'] ) : $level->expiration_period;
610 + $categories = isset( $params['categories'] ) ? PMPro_REST_API_Routes::pmpro_rest_api_convert_to_array( sanitize_text_field( $params['categories'] ) ) : $level->categories;
611 +
612 + // Set Level Object and save it.
613 + $level->name = $name;
614 + $level->description = $description;
615 + $level->confirmation = $confirmation;
616 + $level->initial_payment = $initial_payment;
617 + $level->billing_amount = $billing_amount;
618 + $level->cycle_number = $cycle_number;
619 + $level->billing_limit = $billing_limit;
620 + $level->trial_amount = $trial_amount;
621 + $level->allow_signups = $allow_signups;
622 + $level->expiration_number = $expiration_number;
623 + $level->expiration_period = $expiration_period;
624 + $level->categories = $categories;
625 + $level->save();
626 +
627 + if ( 'json' === $response_type ) {
628 + wp_send_json_success( array( "level" => $level ) );
629 + }
630 +
631 + return new WP_REST_Response( $level, 200 );
632 +
633 + }
634 +
635 + /**
636 + * Delete membership level and remove users from level. (And cancel their subscription.)
637 + * @since 2.3
638 + * Example: https://example.com/wp-json/pmpro/v1/membership_level/
639 + */
640 + function pmpro_rest_api_delete_membership_level( $request ) {
641 +
642 + if ( ! class_exists( 'PMPro_Membership_Level' ) ) {
643 + return new WP_REST_Response( 'Paid Memberships Pro level class not found.', 404 );
644 + }
645 +
646 + $params = $request->get_params();
647 + $id = isset( $params['id'] ) ? intval( $params['id'] ) : '';
648 +
649 + if ( empty( $id ) ) {
650 + return new WP_REST_Response( 'ID not passed through.', 400 );
651 + }
652 +
653 + $level = new PMPro_Membership_Level( $id );
654 +
655 + return new WP_REST_Response( $level->delete(), 200 );
656 + }
657 +
658 + /**
659 + * Get all membership levels.
660 + * @since 3.0
661 + * Example: https://example.com/wp-json/pmpro/v1/membership_levels
662 + */
663 + function pmpro_rest_api_get_membership_levels( $request ) {
664 +
665 + if ( ! class_exists( 'PMPro_Membership_Level' ) ) {
666 + return new WP_REST_Response( 'Paid Memberships Pro level class not found.', 404 );
667 + }
668 +
669 + $params = $request->get_params();
670 + $response_type = isset( $params['response_type'] ) ? sanitize_text_field( $params['response_type'] ) : null;
671 +
672 + $levels = pmpro_getAllLevels( true, true );
673 +
674 + // Hide confirmation message if not an admin or member.
675 + if ( ! current_user_can( 'manage_options' ) && ! current_user_can( 'pmpro_membershiplevels' ) ) {
676 + foreach ( $levels as $level ) {
677 + if ( ! pmpro_hasMembershipLevel( $level->id ) ) {
678 + $level->confirmation = '';
679 + }
680 + }
681 + }
682 +
683 + if ( 'json' === $response_type ) {
684 + wp_send_json_success( array( "levels" => $levels ) );
685 + }
686 +
687 + return new WP_REST_Response( $levels, 200 );
688 + }
689 +
690 + /**
691 + * Get a discount code
692 + * @since 2.3
693 + * Example: https://example.com/wp-json/pmpro/v1/discount_code
694 + */
695 + function pmpro_rest_api_get_discount_code( $request ) {
696 + if ( ! class_exists( 'PMPro_Discount_Code' ) ) {
697 + return new WP_REST_Response( 'Paid Memberships Pro discount code class not found.', 404 );
698 + }
699 +
700 + $params = $request->get_params();
701 + $code = isset( $params['code'] ) ? sanitize_text_field( $params['code'] ) : null;
702 +
703 + if ( empty( $code ) ) {
704 + return new WP_REST_Response( 'No discount code sent.', 400 );
705 + }
706 +
707 + return new WP_REST_Response( new PMPro_Discount_Code( $code ), 200 );
708 +
709 + }
710 +
711 + /**
712 + * Create/update a discount code.
713 + * @since 2.3
714 + * Example: https://example.com/wp-json/pmpro/v1/discount_code
715 + */
716 + function pmpro_rest_api_set_discount_code( $request ) {
717 +
718 + if ( ! class_exists( 'PMPro_Discount_Code' ) ) {
719 + return new WP_REST_Response( 'Paid Memberships Pro discount code class not found.', 404 );
720 + }
721 +
722 + $params = $request->get_params();
723 + $method = $request->get_method();
724 + $code = isset( $params['code'] ) ? sanitize_text_field( $params['code'] ) : '';
725 + $uses = isset( $params['uses'] ) ? intval( $params['uses'] ) : '';
726 + $starts = isset( $params['starts'] ) ? sanitize_text_field( $params['starts'] ) : '';
727 + $expires = isset( $params['expires'] ) ? sanitize_text_field( $params['expires'] ) : '';
728 + $levels = isset( $params['levels'] ) ? sanitize_text_field( $params['levels'] ) : null;
729 +
730 + if ( ! empty( $levels ) ) {
731 + $levels = json_decode( $levels, true );
732 +
733 + if ( is_array( $levels ) ) {
734 + $levels_array = array();
735 + foreach( $levels as $level ){
736 + $levels_array[$level['level']] = array(
737 + 'initial_payment' => isset( $level['initial_payment'] ) ? $level['initial_payment'] : null,
738 + 'billing_amount' => isset( $level['billing_amount'] ) ? $level['billing_amount'] : null,
739 + 'cycle_number' => isset( $level['cycle_number'] ) ? $level['cycle_number'] : null,
740 + 'cycle_period' => isset( $level['cycle_period'] ) ? $level['cycle_period'] : null,
741 + 'billing_limit' => isset( $level['cycle_period'] ) ? $level['cycle_period'] : null,
742 + 'custom_trial' => isset( $level['custom_trial'] ) ? $level['custom_trial'] : null,
743 + 'trial_amount' => isset( $level['trial_amount'] ) ? $level['trial_amount'] : null,
744 + 'trial_limit' => isset( $level['trial_limit'] ) ? $level['trial_limit'] : null,
745 + 'expiration_number' => isset( $level['expiration_number'] ) ? : null,
746 + 'expiration_period' => isset( $level['expiration_period'] ) ? : null
747 + );
748 + }
749 + }
750 + }
751 +
752 + $discount_code = new PMPro_Discount_Code();
753 +
754 + // See if code already exists when POSTING.
755 + if ( $method == 'POST' && ! empty( $code ) ) {
756 + // See if discount code exists.
757 + if ( is_numeric( $code ) ) {
758 + $discount_code->get_discount_code_by_id( $code );
759 + } else {
760 + $discount_code->get_discount_code_by_code( $code );
761 + }
762 +
763 + if ( ! empty( $discount_code->id ) ) {
764 + return new WP_REST_Response( 'Discount code already exists.', 400 );
765 + }
766 + }
767 +
768 + $discount_code->code = $code;
769 + $discount_code->starts = $starts;
770 + $discount_code->expires = $expires;
771 + $discount_code->uses = $uses;
772 + $discount_code->levels = !empty( $levels_array ) ? $levels_array : $levels;
773 + $discount_code->save();
774 +
775 + return new WP_REST_Response( $discount_code, 200 );
776 + }
777 +
778 + /**
779 + * Get an order.
780 + * @since 2.8
781 + * Example: https://example.com/wp-json/pmpro/v1/order
782 + */
783 + function pmpro_rest_api_get_order( $request ) {
784 + if ( ! class_exists( 'MemberOrder' ) ) {
785 + return new WP_REST_Response( 'Paid Memberships Pro order class not found.', 404 );
786 + }
787 +
788 + $params = $request->get_params();
789 + $code = isset( $params['code'] ) ? sanitize_text_field( $params['code'] ) : null;
790 +
791 + if ( empty( $code ) ) {
792 + return new WP_REST_Response( 'No order code sent.', 400 );
793 + }
794 +
795 + // Build the order object to return.
796 + // Need to do this because the order object now has private properties.
797 + $order = new MemberOrder( $code );
798 + $order_data_to_return = new stdClass();
799 + if ( ! empty( $order->id ) ) {
800 + $order_data_to_return->id = $order->id;
801 + $order_data_to_return->code = $order->code;
802 + $order_data_to_return->user_id = $order->user_id;
803 + $order_data_to_return->membership_id = $order->membership_id;
804 + $order_data_to_return->billing = $order->billing;
805 + $order_data_to_return->subtotal = $order->subtotal;
806 + $order_data_to_return->tax = $order->tax;
807 + $order_data_to_return->total = $order->total;
808 + $order_data_to_return->payment_type = $order->payment_type;
809 + $order_data_to_return->cardtype = $order->cardtype;
810 + $order_data_to_return->accountnumber = $order->accountnumber;
811 + $order_data_to_return->expirationmonth = $order->expirationmonth;
812 + $order_data_to_return->expirationyear = $order->expirationyear;
813 + $order_data_to_return->status = $order->status;
814 + $order_data_to_return->gateway = $order->gateway;
815 + $order_data_to_return->gateway_environment = $order->gateway_environment;
816 + $order_data_to_return->payment_transaction_id = $order->payment_transaction_id;
817 + $order_data_to_return->subscription_transaction_id = $order->subscription_transaction_id;
818 + $order_data_to_return->timestamp = $order->timestamp;
819 + $order_data_to_return->affiliate_id = $order->affiliate_id;
820 + $order_data_to_return->affiliate_subid = $order->affiliate_subid;
821 + $order_data_to_return->notes = $order->notes;
822 + $order_data_to_return->checkout_id = $order->checkout_id;
823 + }
824 +
825 + return new WP_REST_Response( $order_data_to_return, 200 );
826 + }
827 +
828 + /**
829 + * Make sure that users can GET their own orders.
830 + * @since 2.8
831 + */
832 + function pmpro_rest_api_permissions_get_order( $permission, $request ) {
833 + $method = $request->get_method();
834 + $route = $request->get_route();
835 +
836 + // Check if the user does not have access but is trying to get an order.
837 + if ( ! $permission && 'GET' === $method && '/pmpro/v1/order' === $route ) {
838 + // Check if the order belongs to the user.
839 + $params = $request->get_params();
840 + $code = isset( $params['code'] ) ? sanitize_text_field( $params['code'] ) : null;
841 +
842 + if ( ! empty( $code ) ) {
843 + $order = new MemberOrder( $code );
844 +
845 + if ( $order->user_id == get_current_user_id() ) {
846 + return true;
847 + }
848 + }
849 + }
850 + return $permission;
851 + }
852 +
853 + /**
854 + * Get a membership level at checkout.
855 + *
856 + * @since 2.4
857 + * Example: https://example.com/wp-json/pmpro/v1/checkout_level
858 + */
859 + function pmpro_rest_api_get_checkout_level( $request ) {
860 + $params = $request->get_params();
861 +
862 + if ( isset( $params['pmpro_level' ] ) ) {
863 + $level_id = intval( $params['pmpro_level'] );
864 + } elseif ( isset( $params['level_id'] ) ) {
865 + $level_id = intval( $params['level_id'] );
866 + } elseif ( isset( $params['level'] ) ) {
867 + $level_id = intval( $params['level'] );
868 + }
869 +
870 + if ( empty( $level_id ) ) {
871 + return new WP_REST_Response( 'No level found.', 400 );
872 + }
873 +
874 + if ( isset( $params['pmpro_discount_code'] ) ) {
875 + $discount_code = sanitize_text_field( $params['pmpro_discount_code'] );
876 + } elseif ( isset( $params['discount_code'] ) ) {
877 + $discount_code = sanitize_text_field( $params['discount_code'] );
878 + } else {
879 + $discount_code = null;
880 + }
881 +
882 + $checkout_level = pmpro_getLevelAtCheckout( $level_id, $discount_code );
883 +
884 + if ( ! empty( $checkout_level ) ) {
885 + // Hide confirmation message if not an admin or member.
886 + if ( ! empty( $checkout_level->confirmation )
887 + && ! pmpro_hasMembershipLevel( $level_id )
888 + && ! current_user_can( 'pmpro_edit_members' ) ) {
889 + $checkout_level->confirmation = '';
890 + }
891 +
892 + // Also add a formatted version of the initial payment.
893 + $checkout_level->initial_payment_formatted = pmpro_formatPrice( $checkout_level->initial_payment );
894 + }
895 +
896 + return new WP_REST_Response( $checkout_level );
897 + }
898 +
899 + /**
900 + * Get membership levels at checkout.
901 + * Example: https://example.com/wp-json/pmpro/v1/checkout_levels
902 + *
903 + * @deprecated 3.0 Use the /pmpro/v1/checkout_level endpoint instead.
904 + */
905 + function pmpro_rest_api_get_checkout_levels( $request ) {
906 + $params = $request->get_params();
907 +
908 + global $pmpro_checkout_level_ids;
909 + if ( ! empty( $pmpro_checkout_level_ids ) ) {
910 + // MMPU Compatibility...
911 + $level_ids = $pmpro_checkout_level_ids;
912 + } elseif ( isset( $params['pmpro_level' ] ) ) {
913 + $level_ids = explode( '+', intval( $params['pmpro_level'] ) );
914 + }elseif ( isset( $params['level_id'] ) ) {
915 + $level_ids = explode( '+', intval( $params['level_id'] ) );
916 + } elseif ( isset( $params['level'] ) ) {
917 + $level_ids = explode( '+', intval( $params['level'] ) );
918 + }
919 +
920 + if ( empty( $level_ids ) ) {
921 + return new WP_REST_Response( 'No levels found.', 400 );
922 + }
923 + $discount_code = isset( $params['discount_code'] ) ? sanitize_text_field( $params['discount_code'] ) : null;
924 +
925 + $r = array();
926 + $r['initial_payment'] = 0.00;
927 + foreach ( $level_ids as $level_id ) {
928 + $r[ $level_id ] = pmpro_getLevelAtCheckout( $level_id, $discount_code );
929 +
930 + // Increment the total initial_paymnent.
931 + if ( ! empty( $r[ $level_id ]->initial_payment ) ) {
932 + $r['initial_payment'] += floatval( $r[ $level_id ]->initial_payment );
933 + }
934 +
935 + // Hide confirmation message if not an admin or member.
936 + if ( ! empty( $r[ $level_id ]->confirmation )
937 + && ! pmpro_hasMembershipLevel( $level_id )
938 + && ! current_user_can( 'pmpro_membershiplevels' ) ) {
939 + $r[ $level_id ]->confirmation = '';
940 + }
941 + }
942 + $r['initial_payment_formatted'] = pmpro_formatPrice( $r['initial_payment'] );
943 + return new WP_REST_Response( $r );
944 + }
945 +
946 +
947 + /// ZAPIER TRIGGERS
948 + /**
949 + * Handle authentication testing for the Zapier API.
950 + *
951 + * @since 2.6.0
952 + *
953 + * @param WP_REST_Request $request The REST request.
954 + */
955 + public function validate_me( $request ) {
956 +
957 + $params = $request->get_params();
958 +
959 + if ( is_user_logged_in() ) {
960 + $me = wp_get_current_user()->display_name;
961 + } else {
962 + $me = false;
963 + }
964 +
965 + wp_send_json_success( array( 'username' => $me ) );
966 + }
967 +
968 + /**
969 + * Handle requests for the list of recent memberships.
970 + *
971 + * @since 2.6.0
972 + *
973 + * @param WP_REST_Request $request The REST request.
974 + *
975 + * @return WP_REST_Response The REST response.
976 + */
977 + public function pmpro_rest_api_recent_memberships( $request ) {
978 + $params = $request->get_params();
979 + if ( isset($params['limit']) ) {
980 + $limit = intval( $params['limit'] );
981 + } else {
982 + $limit = 1;
983 + }
984 + /**
985 + * Allow filtering the total number of recent members to show in the /recent_memberships PMPro endpoint.
986 + *
987 + * @param int $limit The total number of recent members to show.
988 + */
989 + $limit = apply_filters( 'pmpro_trigger_recent_members_limit', $limit );
990 +
991 + if ( empty( $params['level_status'] ) ) {
992 + $level_status = [ 'active' ];
993 + } else {
994 + $level_status = sanitize_text_field( trim( $params['level_status'] ) );
995 +
996 + // Force it into an array so we can implode it in the query itself.
997 + $level_status = explode( ',', $level_status );
998 + }
999 +
1000 + // Set up values to prepare.
1001 + $prepare = $level_status;
1002 + $prepare[] = $limit;
1003 +
1004 + // Set up the placeholders we want to use.
1005 + $level_status_placeholders = implode( ', ', array_fill( 0, count( $level_status ), '%s' ) );
1006 +
1007 + // Grab the useful information.
1008 + global $wpdb;
1009 +
1010 + $sql = "
1011 + SELECT
1012 + `mu`.`user_id` AS `id`,
1013 + `u`.`user_email`,
1014 + `u`.`user_nicename`,
1015 + `umf`.`meta_value` AS first_name,
1016 + `uml`.`meta_value` AS last_name,
1017 + `mu`.`membership_id`,
1018 + `ml`.`name` as membership_name,
1019 + `mu`.`status`,
1020 + `mu`.`modified`
1021 + FROM `{$wpdb->pmpro_memberships_users}` AS `mu`
1022 + LEFT JOIN `{$wpdb->users}` AS `u`
1023 + ON `mu`.`user_id` = `u`.`id`
1024 + LEFT JOIN `{$wpdb->pmpro_membership_levels}` AS `ml`
1025 + ON `ml`.`id` = `mu`.`membership_id`
1026 + LEFT JOIN `{$wpdb->usermeta}` AS `umf`
1027 + ON `umf`.`meta_key` = 'first_name'
1028 + AND `umf`.`user_id` = `u`.`id`
1029 + LEFT JOIN `{$wpdb->usermeta}` AS `uml`
1030 + ON `uml`.`meta_key` = 'last_name'
1031 + AND `uml`.`user_id` = `u`.`id`
1032 + WHERE
1033 + `mu`.`status` IN ( {$level_status_placeholders} )
1034 + ORDER BY
1035 + `mu`.`modified` DESC
1036 + LIMIT %d
1037 + ";
1038 +
1039 + $results = $wpdb->get_results( $wpdb->prepare( $sql, $prepare ) );
1040 +
1041 + // Let's format the date to ISO8601
1042 + $results[0]->modified = pmpro_format_date_iso8601( $results[0]->modified );
1043 +
1044 + return new WP_REST_Response( $results, 200 );
1045 +
1046 + }
1047 +
1048 + /**
1049 + * Handle requests for the list of recent orders.
1050 + *
1051 + * @since 2.6.0
1052 + *
1053 + * @param WP_REST_Request $request The REST request.
1054 + *
1055 + * @return WP_REST_Response The REST response.
1056 + */
1057 + public function pmpro_rest_api_recent_orders( $request ) {
1058 + $params = $request->get_params();
1059 +
1060 + if ( isset($params['limit']) ) {
1061 + $orders_limit = intval( $params['limit'] );
1062 + } else {
1063 + $orders_limit = 1;
1064 + }
1065 +
1066 + $limit = apply_filters( 'pmpro_trigger_recent_orders_limit', $orders_limit );
1067 +
1068 + global $wpdb;
1069 +
1070 + $sql = "
1071 + SELECT
1072 + `o`.`id`,
1073 + `o`.`code`,
1074 + `u`.`ID` AS `user_id`,
1075 + `u`.`user_email`,
1076 + `u`.`user_nicename`,
1077 + `umf`.`meta_value` AS first_name,
1078 + `uml`.`meta_value` AS last_name,
1079 + `o`.`membership_id`,
1080 + `o`.`billing_name`,
1081 + `o`.`billing_street`,
1082 + `o`.`billing_city`,
1083 + `o`.`billing_state`,
1084 + `o`.`billing_zip`,
1085 + `o`.`billing_country`,
1086 + `o`.`billing_phone`,
1087 + `o`.`subtotal`,
1088 + `o`.`tax`,
1089 + `o`.`total`,
1090 + `o`.`status`,
1091 + `o`.`gateway`,
1092 + `o`.`gateway_environment`,
1093 + `o`.`timestamp`
1094 + FROM `{$wpdb->pmpro_membership_orders}` AS `o`
1095 + LEFT JOIN `{$wpdb->users}` AS `u`
1096 + ON `o`.`user_id` = `u`.`ID`
1097 + LEFT JOIN `{$wpdb->usermeta}` AS `umf`
1098 + ON `umf`.`meta_key` = 'first_name'
1099 + AND `umf`.`user_id` = `u`.`ID`
1100 + LEFT JOIN `{$wpdb->usermeta}` AS `uml`
1101 + ON `uml`.`meta_key` = 'last_name'
1102 + AND `uml`.`user_id` = `u`.`ID`
1103 + ORDER BY
1104 + `o`.`timestamp` DESC
1105 + LIMIT %d
1106 + ";
1107 +
1108 + $results = $wpdb->get_results( $wpdb->prepare( $sql, $limit ) );
1109 +
1110 + $results[0]->timestamp = pmpro_format_date_iso8601( $results[0]->timestamp );
1111 +
1112 + return new WP_REST_Response( $results, 200 );
1113 + }
1114 +
1115 + /**
1116 + * Get the membership level IDs restricting a given post.
1117 + *
1118 + * @since 3.0
1119 + *
1120 + * @param WP_REST_Request $request The REST request.
1121 + *
1122 + * @return WP_REST_Response The REST response.
1123 + */
1124 + public function pmpro_rest_api_get_post_restrictions( $request ) {
1125 + global $wpdb;
1126 +
1127 + $params = $request->get_params();
1128 +
1129 + $post_id = isset( $params['post_id'] ) ? intval( $params['post_id'] ) : null;
1130 +
1131 + if ( empty( $post_id ) ) {
1132 + return new WP_REST_Response( array( 'error' => 'No post ID provided.' ), 400 );
1133 + }
1134 +
1135 + $level_ids = $wpdb->get_results( $wpdb->prepare( "SELECT `membership_id` FROM `{$wpdb->pmpro_memberships_pages}` WHERE `page_id` = %d", $post_id ) );
1136 +
1137 + return new WP_REST_Response( $level_ids, 200 );
1138 + }
1139 +
1140 + /**
1141 + * Set the membership level IDs restricting a given post.
1142 + *
1143 + * @since 3.0
1144 + *
1145 + * @param WP_REST_Request $request The REST request.
1146 + * @return WP_REST_Response The REST response.
1147 + */
1148 + public function pmpro_rest_api_set_post_restrictions( $request ) {
1149 + global $wpdb;
1150 +
1151 + $params = $request->get_params();
1152 +
1153 + $post_id = isset( $params['post_id'] ) ? intval( $params['post_id'] ) : null;
1154 + $level_ids = isset( $params['level_ids'] ) ? array_map( 'intval', $params['level_ids'] ) : null;
1155 +
1156 + if ( empty( $post_id ) ) {
1157 + return new WP_REST_Response( array( 'error' => 'No post ID provided.' ), 400 );
1158 + }
1159 +
1160 + if ( ! is_array( $level_ids ) ) {
1161 + return new WP_REST_Response( array( 'error' => 'No level IDs provided.' ), 400 );
1162 + }
1163 +
1164 + pmpro_update_post_level_restrictions( $post_id, $level_ids );
1165 +
1166 + return new WP_REST_Response( array( 'success' => $level_ids ), 200 );
1167 + }
1168 +
1169 + /**
1170 + * Default permissions check for endpoints/routes.
1171 + * Defaults to 'subscriber' for all GET requests and
1172 + * 'administrator' for any other type of request.
1173 + *
1174 + * @since 2.3
1175 + * @since 2.12.6 Now allowing arrays in $route_caps so you can have a different permission per HTTP method.
1176 + */
1177 + function pmpro_rest_api_get_permissions_check( $request ) {
1178 +
1179 + $method = $request->get_method();
1180 + $route = $request->get_route();
1181 +
1182 + // Default to requiring pmpro_edit_members capability.
1183 + // NOTE: This basically means that anyone with the pmpro_edit_members capability could potentially do anything made available through the API in this file.
1184 + $permission = current_user_can( 'pmpro_edit_members' );
1185 +
1186 + // Check other caps for some routes.
1187 + $route_caps = array(
1188 + '/pmpro/v1/has_membership_access' => 'pmpro_edit_members',
1189 + '/pmpro/v1/get_membership_level_for_user' => 'pmpro_edit_members',
1190 + '/pmpro/v1/get_membership_levels_for_user' => 'pmpro_edit_members',
1191 + '/pmpro/v1/change_membership_level' => 'pmpro_edit_members',
1192 + '/pmpro/v1/cancel_membership_level' => 'pmpro_edit_members',
1193 + '/pmpro/v1/membership_level' => array(
1194 + 'GET' => true,
1195 + 'POST' => 'pmpro_membershiplevels',
1196 + 'PUT' => 'pmpro_membershiplevels',
1197 + 'PATCH' => 'pmpro_membershiplevels',
1198 + 'DELETE' => 'pmpro_membershiplevels',
1199 + ),
1200 + '/pmpro/v1/membership_levels' => true,
1201 + '/pmpro/v1/discount_code' => 'pmpro_discountcodes',
1202 + '/pmpro/v1/order' => 'pmpro_orders',
1203 + '/pmpro/v1/checkout_level' => true,
1204 + '/pmpro/v1/checkout_levels' => true,
1205 + '/pmpro/v1/me' => true,
1206 + '/pmpro/v1/recent_memberships' => 'pmpro_edit_members',
1207 + '/pmpro/v1/recent_orders' => 'pmpro_orders',
1208 + '/pmpro/v1/post_restrictions' => array(
1209 + 'capability' => 'edit_post',
1210 + 'request_param' => 'post_id',
1211 + ),
1212 + );
1213 + $route_caps = apply_filters( 'pmpro_rest_api_route_capabilities', $route_caps, $request );
1214 +
1215 + // Check if we have a specific permission to check for this route/method.
1216 + if ( isset( $route_caps[$route] ) ) {
1217 + // Find the permission to check.
1218 + if ( is_array ( $route_caps[$route] ) && isset( $route_caps[$route][$method] ) ) {
1219 + // Different permission for this method, use it.
1220 + $permission_to_check = $route_caps[$route][$method];
1221 + } elseif ( is_array( $route_caps[$route] ) && ! isset( $route_caps[$route]['capability'] ) ) {
1222 + // No permission for this method, default to false.
1223 + // Skipping if there is a capability set as this is likely an array with a specific post/user ID to check a capability for.
1224 + $permission_to_check = false;
1225 + } else {
1226 + // Same permission for all methods, use it.
1227 + $permission_to_check = $route_caps[$route];
1228 + }
1229 +
1230 + // Check the permission.
1231 + if ( $permission_to_check === true || $permission_to_check === false ) {
1232 + // For true or false, just pass it along.
1233 + $permission = $permission_to_check;
1234 + } elseif ( is_array( $permission_to_check ) && isset( $permission_to_check['capability'] ) && isset( $permission_to_check['request_param'] ) ) {
1235 + // Check if the current user has this capability.
1236 + // This is used in cases like edit_post where we need to check a specific post ID.
1237 + $permission = current_user_can( $permission_to_check['capability'], $request->get_param( $permission_to_check['request_param'] ) );
1238 + } else {
1239 + // Check if the current user has this capability.
1240 + $permission = current_user_can( $permission_to_check );
1241 + }
1242 + }
1243 +
1244 + // Is the request method allowed? We disable DELETE by default.
1245 + if ( ! in_array( $method, pmpro_get_rest_api_methods( $route ) ) ) {
1246 + $permission = false;
1247 + }
1248 +
1249 + $permission = apply_filters( 'pmpro_rest_api_permissions', $permission, $request );
1250 + return $permission;
1251 + }
1252 +
1253 + /**
1254 + * Helper function to convert comma separated items to an array.
1255 + * @since 2.3
1256 + */
1257 + function pmpro_rest_api_convert_to_array( $string ) {
1258 + return explode( ',', $string );
1259 + }
1260 + } // End of class
1261 +
1262 + /**
1263 + * Register the routes for Paid Memberships Pro.
1264 + * @since 2.3
1265 + */
1266 + function pmpro_rest_api_register_custom_routes() {
1267 + $pmpro_rest_api_routes = new PMPro_REST_API_Routes;
1268 + $pmpro_rest_api_routes->pmpro_rest_api_register_routes();
1269 + }
1270 +
1271 + add_action( 'rest_api_init', 'pmpro_rest_api_register_custom_routes', 5 );
1272 + }
1273 +
1274 +
1275 + /**
1276 + * Get the allowed methods for PMPro REST API endpoints.
1277 + * To enable DELETE, hook into this filter.
1278 + * @since 2.3
1279 + */
1280 + function pmpro_get_rest_api_methods( $route = NULL ) {
1281 + $methods = array( 'GET', 'POST', 'PUT', 'PATCH' );
1282 + $methods = apply_filters( 'pmpro_rest_api_methods', $methods, $route );
1283 + return $methods;
1284 + }
1285 +