PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.7
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.7
1.1.10 1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 All 34 releases
desktop-mode / includes / recycle-bin / rest.php

rest.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 1.1.7, at includes/recycle-bin/rest.php

287 lines 7.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * OpenStation — Recycle Bin: REST routes.
4 *
5 * Five routes, all under `/desktop-mode/v1/recycle-bin`:
6 *
7 * GET / — list trashed items
8 * POST /restore — body { ids: int[] }
9 * POST /purge — body { ids: int[] }
10 * POST /empty — empties the visible bin
11 * GET /count — total items in the bin (badge polling)
12 *
13 * Permission gating delegates to `openstation_recycle_bin_user_can_*` per item;
14 * the route-level callback only checks "are you logged in and in
15 * OpenStation at all?" via `openstation_is_enabled()`.
16 *
17 * @package OpenStation
18 */
19
20 defined( 'ABSPATH' ) || exit;
21
22 /**
23 * Register REST routes.
24 */
25 function openstation_recycle_bin_register_rest_routes() {
26 $namespace = 'desktop-mode/v1';
27
28 register_rest_route(
29 $namespace,
30 '/recycle-bin',
31 array(
32 'methods' => WP_REST_Server::READABLE,
33 'permission_callback' => 'openstation_recycle_bin_rest_permission',
34 'callback' => 'openstation_recycle_bin_rest_list',
35 'args' => array(
36 'page' => array(
37 'type' => 'integer',
38 'default' => 1,
39 'sanitize_callback' => 'absint',
40 ),
41 'per_page' => array(
42 'type' => 'integer',
43 'default' => 100,
44 'sanitize_callback' => 'absint',
45 ),
46 'type' => array(
47 'type' => 'string',
48 'default' => '',
49 'sanitize_callback' => 'sanitize_key',
50 ),
51 'search' => array(
52 'type' => 'string',
53 'default' => '',
54 'sanitize_callback' => 'sanitize_text_field',
55 ),
56 ),
57 )
58 );
59
60 register_rest_route(
61 $namespace,
62 '/recycle-bin/restore',
63 array(
64 'methods' => WP_REST_Server::CREATABLE,
65 'permission_callback' => 'openstation_recycle_bin_rest_permission',
66 'callback' => 'openstation_recycle_bin_rest_restore',
67 // Accepts either `items: [{id, type}]` (preferred) or
68 // `ids: int[]` (legacy — assumes post-ish entities).
69 // Both registered as optional; the handler validates.
70 'args' => array(
71 'items' => array(
72 'type' => 'array',
73 'required' => false,
74 ),
75 'ids' => array(
76 'type' => 'array',
77 'required' => false,
78 'items' => array( 'type' => 'integer' ),
79 ),
80 ),
81 )
82 );
83
84 register_rest_route(
85 $namespace,
86 '/recycle-bin/purge',
87 array(
88 'methods' => WP_REST_Server::CREATABLE,
89 'permission_callback' => 'openstation_recycle_bin_rest_permission',
90 'callback' => 'openstation_recycle_bin_rest_purge',
91 'args' => array(
92 'items' => array(
93 'type' => 'array',
94 'required' => false,
95 ),
96 'ids' => array(
97 'type' => 'array',
98 'required' => false,
99 'items' => array( 'type' => 'integer' ),
100 ),
101 ),
102 )
103 );
104
105 register_rest_route(
106 $namespace,
107 '/recycle-bin/empty',
108 array(
109 'methods' => WP_REST_Server::CREATABLE,
110 'permission_callback' => 'openstation_recycle_bin_rest_permission',
111 'callback' => 'openstation_recycle_bin_rest_empty',
112 )
113 );
114
115 register_rest_route(
116 $namespace,
117 '/recycle-bin/count',
118 array(
119 'methods' => WP_REST_Server::READABLE,
120 'permission_callback' => 'openstation_recycle_bin_rest_permission',
121 'callback' => static function () {
122 return rest_ensure_response(
123 array( 'count' => openstation_recycle_bin_count() )
124 );
125 },
126 )
127 );
128 }
129 add_action( 'rest_api_init', 'openstation_recycle_bin_register_rest_routes' );
130
131 /**
132 * Route-level permission gate.
133 *
134 * Per-item capability checks happen inside the store layer; here we
135 * only enforce "logged-in user with OpenStation opted in" — same
136 * baseline as every other desktop REST surface.
137 *
138 * @return bool|WP_Error
139 */
140 function openstation_recycle_bin_rest_permission() {
141 if ( ! is_user_logged_in() ) {
142 return new WP_Error(
143 'rest_forbidden',
144 __( 'Sorry, you must be logged in.', 'desktop-mode' ),
145 array( 'status' => 401 )
146 );
147 }
148 if ( function_exists( 'openstation_is_enabled' ) && ! openstation_is_enabled() ) {
149 return new WP_Error(
150 'rest_forbidden',
151 __( 'OpenStation is not enabled for this user.', 'desktop-mode' ),
152 array( 'status' => 403 )
153 );
154 }
155 return true;
156 }
157
158 /**
159 * GET /recycle-bin
160 *
161 * @param WP_REST_Request $request REST request.
162 * @return WP_REST_Response
163 */
164 function openstation_recycle_bin_rest_list( $request ) {
165 $payload = openstation_recycle_bin_get_items(
166 array(
167 'page' => (int) $request->get_param( 'page' ),
168 'per_page' => (int) $request->get_param( 'per_page' ),
169 'type' => (string) $request->get_param( 'type' ),
170 'search' => (string) $request->get_param( 'search' ),
171 )
172 );
173
174 return rest_ensure_response( $payload );
175 }
176
177 /**
178 * POST /recycle-bin/restore
179 *
180 * @param WP_REST_Request $request REST request.
181 * @return WP_REST_Response
182 */
183 function openstation_recycle_bin_rest_restore( $request ) {
184 $items = openstation_recycle_bin_normalize_items( $request );
185 return rest_ensure_response( openstation_recycle_bin_apply_bulk( $items, 'openstation_recycle_bin_restore' ) );
186 }
187
188 /**
189 * POST /recycle-bin/purge
190 *
191 * @param WP_REST_Request $request REST request.
192 * @return WP_REST_Response
193 */
194 function openstation_recycle_bin_rest_purge( $request ) {
195 $items = openstation_recycle_bin_normalize_items( $request );
196 return rest_ensure_response( openstation_recycle_bin_apply_bulk( $items, 'openstation_recycle_bin_purge' ) );
197 }
198
199 /**
200 * Read either `items: [{id, type}]` (preferred) or `ids: int[]`
201 * (legacy) and normalise into a list of `[id, type]` pairs the
202 * bulk runner can hand straight to a typed callback.
203 *
204 * @param WP_REST_Request $request REST request.
205 * @return array<int, array{id:int, type:string}>
206 */
207 function openstation_recycle_bin_normalize_items( $request ) {
208 $out = array();
209
210 $items = $request->get_param( 'items' );
211 if ( is_array( $items ) ) {
212 foreach ( $items as $entry ) {
213 if ( ! is_array( $entry ) ) {
214 continue;
215 }
216 $id = isset( $entry['id'] ) ? (int) $entry['id'] : 0;
217 $type = isset( $entry['type'] ) ? sanitize_key( (string) $entry['type'] ) : '';
218 if ( $id <= 0 ) {
219 continue;
220 }
221 $out[] = array(
222 'id' => $id,
223 'type' => $type,
224 );
225 }
226 return $out;
227 }
228
229 $ids = $request->get_param( 'ids' );
230 if ( is_array( $ids ) ) {
231 foreach ( $ids as $id ) {
232 $id = (int) $id;
233 if ( $id > 0 ) {
234 $out[] = array(
235 'id' => $id,
236 'type' => '',
237 );
238 }
239 }
240 }
241 return $out;
242 }
243
244 /**
245 * POST /recycle-bin/empty
246 *
247 * @return WP_REST_Response
248 */
249 function openstation_recycle_bin_rest_empty() {
250 return rest_ensure_response( openstation_recycle_bin_empty() );
251 }
252
253 /**
254 * Run a per-item callback over a list, capturing per-item results.
255 *
256 * @param array<int, array{id:int, type:string}> $items Items to operate on.
257 * @param callable $callback `($id, $type) → true|WP_Error`.
258 * @return array{ok:int[], errors:array<int, array{id:int, code:string, message:string}>}
259 */
260 function openstation_recycle_bin_apply_bulk( $items, $callback ) {
261 $ok = array();
262 $errors = array();
263
264 foreach ( $items as $item ) {
265 $id = isset( $item['id'] ) ? (int) $item['id'] : 0;
266 $type = isset( $item['type'] ) ? (string) $item['type'] : '';
267 if ( $id <= 0 ) {
268 continue;
269 }
270 $result = call_user_func( $callback, $id, $type );
271 if ( is_wp_error( $result ) ) {
272 $errors[] = array(
273 'id' => $id,
274 'code' => $result->get_error_code(),
275 'message' => $result->get_error_message(),
276 );
277 } else {
278 $ok[] = $id;
279 }
280 }
281
282 return array(
283 'ok' => $ok,
284 'errors' => $errors,
285 );
286 }
287