Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 51
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Jetpack_BbPress_REST_API
0.00% covered (danger)
0.00%
0 / 51
0.00% covered (danger)
0.00%
0 / 6
380
0.00% covered (danger)
0.00%
0 / 1
 instance
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 allow_bbpress_post_types
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 allow_bbpress_public_metadata
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
2
 adjust_meta_caps
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
72
 should_adjust_meta_caps_return_early
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
42
1<?php
2/**
3 * REST API Compatibility: bbPress & Jetpack
4 * Enables bbPress to work with the Jetpack REST API
5 *
6 * @package automattic/jetpack
7 */
8
9/**
10 * REST API Compatibility: bbPress.
11 */
12class Jetpack_BbPress_REST_API {
13
14    /**
15     * Singleton
16     *
17     * @var Jetpack_BbPress_REST_API
18     */
19    private static $instance;
20
21    /**
22     * Returns or creates the singleton.
23     *
24     * @return Jetpack_BbPress_REST_API
25     */
26    public static function instance() {
27        if ( isset( self::$instance ) ) {
28            return self::$instance;
29        }
30
31        self::$instance = new self();
32    }
33
34    /**
35     * Jetpack_BbPress_REST_API constructor.
36     */
37    private function __construct() {
38        add_filter( 'rest_api_allowed_post_types', array( $this, 'allow_bbpress_post_types' ) );
39        add_filter( 'bbp_map_meta_caps', array( $this, 'adjust_meta_caps' ), 10, 4 );
40        add_filter( 'rest_api_allowed_public_metadata', array( $this, 'allow_bbpress_public_metadata' ) );
41    }
42
43    /**
44     * Adds the bbPress post types to the rest_api_allowed_post_types filter.
45     *
46     * @param array $allowed_post_types Allowed post types.
47     *
48     * @return array
49     */
50    public function allow_bbpress_post_types( $allowed_post_types ) {
51        $allowed_post_types[] = 'forum';
52        $allowed_post_types[] = 'topic';
53        $allowed_post_types[] = 'reply';
54        return $allowed_post_types;
55    }
56
57    /**
58     * Adds the bbpress meta keys to the rest_api_allowed_public_metadata filter.
59     *
60     * @param array $allowed_meta_keys Allowed meta keys.
61     *
62     * @return array
63     */
64    public function allow_bbpress_public_metadata( $allowed_meta_keys ) {
65        $allowed_meta_keys[] = '_bbp_forum_id';
66        $allowed_meta_keys[] = '_bbp_topic_id';
67        $allowed_meta_keys[] = '_bbp_status';
68        $allowed_meta_keys[] = '_bbp_forum_type';
69        $allowed_meta_keys[] = '_bbp_forum_subforum_count';
70        $allowed_meta_keys[] = '_bbp_reply_count';
71        $allowed_meta_keys[] = '_bbp_total_reply_count';
72        $allowed_meta_keys[] = '_bbp_topic_count';
73        $allowed_meta_keys[] = '_bbp_total_topic_count';
74        $allowed_meta_keys[] = '_bbp_topic_count_hidden';
75        $allowed_meta_keys[] = '_bbp_last_topic_id';
76        $allowed_meta_keys[] = '_bbp_last_reply_id';
77        $allowed_meta_keys[] = '_bbp_last_active_time';
78        $allowed_meta_keys[] = '_bbp_last_active_id';
79        $allowed_meta_keys[] = '_bbp_sticky_topics';
80        $allowed_meta_keys[] = '_bbp_voice_count';
81        $allowed_meta_keys[] = '_bbp_reply_count_hidden';
82        $allowed_meta_keys[] = '_bbp_anonymous_reply_count';
83
84        return $allowed_meta_keys;
85    }
86
87    /**
88     * Adds the needed caps to the bbp_map_meta_caps filter.
89     *
90     * @param array  $caps Capabilities for meta capability.
91     * @param string $cap Capability name.
92     * @param int    $user_id User id.
93     * @param array  $args Arguments.
94     *
95     * @return array
96     */
97    public function adjust_meta_caps( $caps, $cap, $user_id, $args ) {
98
99        // Return early if not a REST request or if not meta bbPress caps.
100        if ( $this->should_adjust_meta_caps_return_early( $caps, $cap, $user_id, $args ) ) {
101            return $caps;
102        }
103
104        // $args[0] could be a post ID or a post_type string.
105        if ( is_int( $args[0] ) ) {
106            $_post = get_post( $args[0] );
107            if ( ! empty( $_post ) ) {
108                $post_type = get_post_type_object( $_post->post_type );
109            }
110        } elseif ( is_string( $args[0] ) ) {
111            $post_type = get_post_type_object( $args[0] );
112        }
113
114        // no post type found, bail.
115        if ( empty( $post_type ) ) {
116            return $caps;
117        }
118
119        // reset the needed caps.
120        $caps = array();
121
122        // Add 'do_not_allow' cap if user is spam or deleted.
123        if ( bbp_is_user_inactive( $user_id ) ) {
124            $caps[] = 'do_not_allow';
125
126            // Moderators can always edit meta.
127        } elseif ( user_can( $user_id, 'moderate' ) ) { // phpcs:ignore WordPress.WP.Capabilities.Unknown
128            $caps[] = 'moderate';
129
130            // Unknown so map to edit_posts.
131        } else {
132            $caps[] = $post_type->cap->edit_posts;
133        }
134
135        return $caps;
136    }
137
138    /**
139     * Should adjust_meta_caps return early?
140     *
141     * @param array  $caps Capabilities for meta capability.
142     * @param string $cap Capability name.
143     * @param int    $user_id User id.
144     * @param array  $args Arguments.
145     *
146     * @return bool
147     */
148    private function should_adjust_meta_caps_return_early( $caps, $cap, $user_id, $args ) {
149        // only run for REST API requests.
150        if ( ! defined( 'REST_API_REQUEST' ) || ! REST_API_REQUEST ) {
151            return true;
152        }
153
154        // only modify caps for meta caps and for bbPress meta keys.
155        if ( ! in_array( $cap, array( 'edit_post_meta', 'delete_post_meta', 'add_post_meta' ), true ) || empty( $args[1] ) || ! str_contains( $args[1], '_bbp_' ) ) {
156            return true;
157        }
158
159        return false;
160    }
161}