Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
58.06% covered (warning)
58.06%
72 / 124
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
NotificationsApi
58.06% covered (warning)
58.06%
72 / 124
0.00% covered (danger)
0.00%
0 / 1
12.72
0.00% covered (danger)
0.00%
0 / 1
 registerRoutes
58.06% covered (warning)
58.06%
72 / 124
0.00% covered (danger)
0.00%
0 / 1
12.72
1<?php
2
3namespace NewfoldLabs\WP\Module\Notifications;
4
5use WP_Forge\Helpers\Arr;
6
7use function NewfoldLabs\WP\ModuleLoader\container;
8
9/**
10 * Class NotificationsApi
11 */
12class NotificationsApi {
13
14    /**
15     * Register notification routes.
16     */
17    public static function registerRoutes() {
18
19        // Add route for fetching notifications
20        register_rest_route(
21            'newfold-notifications/v1',
22            '/notifications',
23            array(
24                'methods'             => \WP_REST_Server::READABLE,
25                'callback'            => function ( \WP_REST_Request $request ) {
26
27                    $notifications = new NotificationsRepository();
28
29                    $results = $notifications
30                        ->collection()
31                        ->filter(
32                            function ( Notification $notification ) use ( $request ) {
33                                $params  = $request->get_params();
34                                $context = Arr::get( $params, 'context' );
35                                $page    = Arr::get( $params, 'page' );
36
37                                return $notification->shouldShow( $context, array( 'page' => $page ) );
38                            }
39                        )
40                        ->map(
41                            function ( Notification $notification ) {
42                                return $notification->asArray();
43                            }
44                        )
45                        ->values();
46
47                    return rest_ensure_response( $results );
48                },
49                'args'                => array(
50                    'context' => array(
51                        'required'          => true,
52                        'validate_callback' => function ( $value ) {
53                            return is_string( $value ) && in_array( $value, array(
54                                    container()->plugin()->id . '-plugin',
55                                    container()->plugin()->id . '-app-nav',
56                                    'wp-admin-notice',
57                                    'wp-admin-prime'
58                                ), true );
59                        },
60                    ),
61                    'page'    => array(
62                        'required'          => false,
63                        'validate_callback' => function ( $value, \WP_REST_Request $request ) {
64                            $context = $request->get_param( 'context' );
65                            if ( container()->plugin()->id . '-plugin' === $context || container()->plugin()->id . '-app-nav' === $context || 'wp-admin-notice' === $context ) {
66                                return is_string( $value );
67                            }
68
69                            return true;
70                        },
71                    ),
72                ),
73                'permission_callback' => function () {
74                    return current_user_can( 'manage_options' );
75                },
76            )
77        );
78
79        // Add route for dispatching events
80        register_rest_route(
81            'newfold-notifications/v1',
82            '/notifications/events',
83            array(
84                'methods'             => \WP_REST_Server::CREATABLE,
85                'args'                => array(
86                    'action'   => array(
87                        'required'          => true,
88                        'description'       => __( 'Event action', 'wp-module-notifications' ),
89                        'type'              => 'string',
90                        'sanitize_callback' => function ( $value ) {
91                            return sanitize_title( $value );
92                        },
93                    ),
94                    'category' => array(
95                        'default'           => 'admin',
96                        'description'       => __( 'Event category', 'wp-module-notifications' ),
97                        'type'              => 'string',
98                        'sanitize_callback' => function ( $value ) {
99                            return sanitize_title( $value );
100                        },
101                    ),
102                    'data'     => array(
103                        'description' => __( 'Event data', 'wp-module-notifications' ),
104                        'type'        => 'object',
105                    ),
106                    'queue'    => array(
107                        'default'           => true,
108                        'description'       => __( 'Whether or not to queue the event', 'wp-module-notifications' ),
109                        'type'              => 'boolean',
110                        'sanitize_callback' => function ( $value ) {
111                            return filter_var( $value, FILTER_VALIDATE_BOOLEAN );
112                        },
113                    ),
114                ),
115                'permission_callback' => function () {
116                    return current_user_can( 'manage_options' );
117                },
118                'callback'            => function ( \WP_REST_Request $request ) {
119
120                    $request = new \WP_REST_Request( 'POST', '/newfold-data/v1/events' );
121                    $request->set_body( \WP_REST_Server::get_raw_data() );
122                    $request->set_header( 'Content-Type', 'application/json' );
123                    $response = rest_do_request( $request );
124                    // The hiive API returns arrays of Notification objects. Each Notification has an array of
125                    // location objects. However, the WP REST API converts all nested objects to
126                    // associative arrays in a standard HTTP response. Since this proxying through an internal
127                    // request, we end up with the original nested objects.
128                    // The encode/decode here standardizes to all associative arrays.
129                    $data = json_decode( wp_json_encode( $response->data ), true );
130
131                    if ( ! $request->get_param( 'queue' ) && 201 === intval( $response->get_status() ) ) {
132                        $notifications = Arr::get( $data, 'data', array() );
133                        set_transient( NotificationsRepository::TRANSIENT, $notifications, 5 * MINUTE_IN_SECONDS );
134                    }
135
136                    return new \WP_REST_Response( $data, $response->get_status() );
137                },
138            )
139        );
140
141        // Add route for dismissing notifications
142        register_rest_route(
143            'newfold-notifications/v1',
144            '/notifications/(?P<id>[a-zA-Z0-9-]+)',
145            array(
146                'methods'             => \WP_REST_Server::DELETABLE,
147                'callback'            => function ( \WP_REST_Request $request ) {
148
149                    $id            = $request->get_param( 'id' );
150                    $notifications = new NotificationsRepository();
151
152                    if ( $notifications->has( $id ) ) {
153                        // Delete standard notifications
154                        $deleted = $notifications->get( $id )->asArray();
155                        $notifications->remove( $id );
156                    } else {
157                        // Delete realtime notifications
158                        $deleted      = array( 'id' => $id );
159                        $notification = new Notification( $deleted );
160                        $notification->dismiss();
161                    }
162
163                    return rest_ensure_response( $deleted );
164                },
165                'permission_callback' => function () {
166                    return current_user_can( 'manage_options' );
167                },
168            )
169        );
170
171    }
172
173}