Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
54 / 54
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
Schema_Settings_Controller
100.00% covered (success)
100.00%
54 / 54
100.00% covered (success)
100.00%
6 / 6
7
100.00% covered (success)
100.00%
1 / 1
 register_routes
100.00% covered (success)
100.00%
42 / 42
100.00% covered (success)
100.00%
1 / 1
1
 permissions_check
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 get_item
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 update_item
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 get_author_profile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 update_author_profile
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * REST controller for the site-level Schema settings.
4 *
5 * Exposes {@see Schema_Settings} over a dedicated `jetpack/v4/seo/schema-settings`
6 * route rather than `/jetpack/v4/settings`, which rejects the nested schema
7 * container. GET returns the editing payload; the write method sanitizes,
8 * persists, and returns the new payload. Gated on `manage_options`.
9 *
10 * Also serves the signed-in user's author profile on `jetpack/v4/seo/author-profile`.
11 * Simple's loader registers only the controllers it names, so that route lives here.
12 *
13 * @package automattic/jetpack-seo-package
14 */
15
16namespace Automattic\Jetpack\SEO;
17
18use WP_REST_Request;
19use WP_REST_Server;
20
21/**
22 * Registers and serves the Schema settings and author profile REST routes.
23 */
24class Schema_Settings_Controller {
25
26    /**
27     * REST namespace, shared with the package's other Jetpack routes.
28     *
29     * @var string
30     */
31    const REST_NAMESPACE = 'jetpack/v4';
32
33    /**
34     * Route, relative to the namespace.
35     *
36     * @var string
37     */
38    const REST_BASE = '/seo/schema-settings';
39
40    /**
41     * Author profile route, relative to the namespace.
42     *
43     * @var string
44     */
45    const AUTHOR_PROFILE_BASE = '/seo/author-profile';
46
47    /**
48     * Register the GET (read) and write (sanitize + persist) routes.
49     *
50     * @return void
51     */
52    public static function register_routes() {
53        register_rest_route(
54            self::REST_NAMESPACE,
55            self::REST_BASE,
56            array(
57                array(
58                    'methods'             => WP_REST_Server::READABLE,
59                    'callback'            => array( __CLASS__, 'get_item' ),
60                    'permission_callback' => array( __CLASS__, 'permissions_check' ),
61                ),
62                array(
63                    'methods'             => WP_REST_Server::EDITABLE,
64                    'callback'            => array( __CLASS__, 'update_item' ),
65                    'permission_callback' => array( __CLASS__, 'permissions_check' ),
66                ),
67            )
68        );
69
70        register_rest_route(
71            self::REST_NAMESPACE,
72            self::AUTHOR_PROFILE_BASE,
73            array(
74                array(
75                    'methods'             => WP_REST_Server::READABLE,
76                    'callback'            => array( __CLASS__, 'get_author_profile' ),
77                    'permission_callback' => array( __CLASS__, 'permissions_check' ),
78                ),
79                array(
80                    'methods'             => WP_REST_Server::EDITABLE,
81                    'callback'            => array( __CLASS__, 'update_author_profile' ),
82                    'permission_callback' => array( __CLASS__, 'permissions_check' ),
83                    'args'                => array(
84                        'name'        => array( 'type' => 'string' ),
85                        'description' => array( 'type' => 'string' ),
86                        'url'         => array( 'type' => 'string' ),
87                        'jobTitle'    => array( 'type' => 'string' ),
88                        'sameAs'      => array(
89                            'type'  => 'array',
90                            'items' => array( 'type' => 'string' ),
91                        ),
92                    ),
93                ),
94            )
95        );
96    }
97
98    /**
99     * Only administrators, the SEO page's audience, can use these routes.
100     *
101     * @return bool
102     */
103    public static function permissions_check() {
104        return current_user_can( 'manage_options' );
105    }
106
107    /**
108     * GET: the editing payload (stored overrides plus placeholder defaults).
109     *
110     * @return \WP_REST_Response
111     */
112    public static function get_item() {
113        return rest_ensure_response( Schema_Settings::get_editable() );
114    }
115
116    /**
117     * POST/PUT: sanitize and persist the submission, then return the new payload.
118     * Unknown keys are ignored and omitted schema sections retain their stored values.
119     *
120     * @param WP_REST_Request $request The REST request.
121     * @return \WP_REST_Response
122     */
123    public static function update_item( WP_REST_Request $request ) {
124        $params = $request->get_json_params();
125        if ( ! is_array( $params ) ) {
126            $params = $request->get_params();
127        }
128
129        return rest_ensure_response( Schema_Settings::update( $params ) );
130    }
131
132    /**
133     * GET: the signed-in user's author profile.
134     *
135     * @return \WP_REST_Response
136     */
137    public static function get_author_profile() {
138        return rest_ensure_response( Author_Schema_Node::get_profile( get_current_user_id() ) );
139    }
140
141    /**
142     * POST/PUT: update the signed-in user's author profile and return it as stored.
143     *
144     * @param WP_REST_Request $request The REST request.
145     * @return \WP_REST_Response|\WP_Error
146     */
147    public static function update_author_profile( WP_REST_Request $request ) {
148        $fields = array_intersect_key(
149            $request->get_params(),
150            array_flip( array( 'name', 'description', 'url', 'jobTitle', 'sameAs' ) )
151        );
152
153        return rest_ensure_response( Author_Schema_Node::update_profile( get_current_user_id(), $fields ) );
154    }
155}