PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 0.8.7
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v0.8.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 / window.php

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

260 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Desktop Mode — Recycle Bin: window + icon registration.
4 *
5 * Native window with id `desktop-mode-recycle-bin`, pinned to the taskbar with a
6 * matching wallpaper icon. Like the code editor, the template body is a
7 * static skeleton that the JS bundle enhances on first open — the table
8 * is populated from the REST list endpoint at render time.
9 *
10 * Both registrations are filterable via the standard
11 * `desktop_mode_recycle_bin_window_args` / `desktop_mode_recycle_bin_icon_args`
12 * filters so a plugin can swap the icon, change the dimensions, or
13 * restrict who sees the bin without touching this file.
14 *
15 * @package WPDesktopMode
16 * @since 0.19.0
17 */
18
19 defined( 'ABSPATH' ) || exit;
20
21 /**
22 * Echoes the recycle bin window's template body.
23 *
24 * The shell wraps this in `<template id="desktop-mode-native-window-desktop-mode-recycle-bin">`
25 * and clones it into the window body BEFORE the JS render callback runs.
26 * The `data-desktop-mode-recycle-bin-*` hooks below are the contract the JS
27 * relies on — keep them intact (or rename via the filter) when
28 * customizing the layout.
29 *
30 * @since 0.19.0
31 */
32 function desktop_mode_recycle_bin_render_template() {
33 ob_start();
34 ?>
35 <div class="desktop-mode-recycle-bin" data-desktop-mode-recycle-bin-root>
36 <header class="desktop-mode-recycle-bin__toolbar" data-desktop-mode-recycle-bin-toolbar>
37 <div class="desktop-mode-recycle-bin__toolbar-left">
38 <wpd-segmented data-desktop-mode-recycle-bin-filter>
39 <wpd-segment value="" selected><?php esc_html_e( 'All', 'desktop-mode' ); ?></wpd-segment>
40 <wpd-segment value="post"><?php esc_html_e( 'Posts', 'desktop-mode' ); ?></wpd-segment>
41 <wpd-segment value="page"><?php esc_html_e( 'Pages', 'desktop-mode' ); ?></wpd-segment>
42 <?php
43 // The Media segment is only useful when WP itself routes
44 // attachment deletions through Trash. That gate is the
45 // `MEDIA_TRASH` constant — defaults to false in core, can
46 // be flipped to true from `wp-config.php`. Without it,
47 // attachments permanent-delete on first click and the
48 // Trash bin will never have anything in this bucket, so
49 // the tab would always read "0" and confuse users.
50 if ( defined( 'MEDIA_TRASH' ) && MEDIA_TRASH ) :
51 ?>
52 <wpd-segment value="attachment"><?php esc_html_e( 'Media', 'desktop-mode' ); ?></wpd-segment>
53 <?php
54 endif;
55 ?>
56 <wpd-segment value="comment"><?php esc_html_e( 'Comments', 'desktop-mode' ); ?></wpd-segment>
57 <wpd-segment value="desktop"><?php esc_html_e( 'Desktop', 'desktop-mode' ); ?></wpd-segment>
58 </wpd-segmented>
59 <wpd-text-field
60 data-desktop-mode-recycle-bin-search
61 placeholder="<?php esc_attr_e( 'Search trash…', 'desktop-mode' ); ?>"
62 ></wpd-text-field>
63 </div>
64 <div class="desktop-mode-recycle-bin__toolbar-right" data-desktop-mode-recycle-bin-bulk hidden>
65 <span class="desktop-mode-recycle-bin__count" data-desktop-mode-recycle-bin-count></span>
66 <wpd-button variant="secondary" data-desktop-mode-recycle-bin-restore-selected>
67 <span class="dashicons dashicons-image-rotate" aria-hidden="true"></span>
68 <?php esc_html_e( 'Restore', 'desktop-mode' ); ?>
69 </wpd-button>
70 <wpd-button variant="secondary" data-desktop-mode-recycle-bin-pin-to-desktop>
71 <span class="dashicons dashicons-desktop" aria-hidden="true"></span>
72 <?php esc_html_e( 'Pin to desktop', 'desktop-mode' ); ?>
73 </wpd-button>
74 <wpd-button variant="danger" data-desktop-mode-recycle-bin-purge-selected>
75 <span class="dashicons dashicons-trash" aria-hidden="true"></span>
76 <?php esc_html_e( 'Delete forever', 'desktop-mode' ); ?>
77 </wpd-button>
78 </div>
79 <div class="desktop-mode-recycle-bin__toolbar-trailing">
80 <wpd-button variant="ghost" data-desktop-mode-recycle-bin-refresh title="<?php esc_attr_e( 'Refresh', 'desktop-mode' ); ?>">
81 <span class="dashicons dashicons-update" aria-hidden="true"></span>
82 </wpd-button>
83 <wpd-button variant="danger" data-desktop-mode-recycle-bin-empty>
84 <span class="dashicons dashicons-trash" aria-hidden="true"></span>
85 <?php esc_html_e( 'Empty bin', 'desktop-mode' ); ?>
86 </wpd-button>
87 </div>
88 </header>
89 <div class="desktop-mode-recycle-bin__body" data-desktop-mode-recycle-bin-body>
90 <wpd-table
91 data-desktop-mode-recycle-bin-table
92 selectable="multi"
93 sticky-header
94 hover
95 striped
96 loading
97 >
98 <div slot="empty" class="desktop-mode-recycle-bin__empty">
99 <span class="dashicons dashicons-trash" aria-hidden="true"></span>
100 <p><?php esc_html_e( 'The recycle bin is empty.', 'desktop-mode' ); ?></p>
101 <p class="desktop-mode-recycle-bin__empty-hint">
102 <?php esc_html_e( 'Deleted posts, pages, and media show up here. Restoring puts them back where they were.', 'desktop-mode' ); ?>
103 </p>
104 </div>
105 </wpd-table>
106 </div>
107 </div>
108 <?php
109 $html = (string) ob_get_clean();
110
111 /**
112 * Filter the recycle bin window's template HTML.
113 *
114 * Keep the `data-desktop-mode-recycle-bin-*` hooks intact so the JS render
115 * callback can find its mount points, or rename them and update the
116 * matching constants in `src/recycle-bin/index.ts`.
117 *
118 * @since 0.19.0
119 *
120 * @param string $html Default template HTML.
121 */
122 $filtered = (string) apply_filters( 'desktop_mode_recycle_bin_template_html', $html );
123 echo wp_kses( $filtered, desktop_mode_native_window_allowed_html() );
124 }
125
126 /**
127 * Whether the current user should see the recycle bin at all.
128 *
129 * Filterable so plugins can hide it from authors/contributors who
130 * don't manage trash, or invert the gate to expose it to a custom
131 * role.
132 *
133 * @since 0.19.0
134 *
135 * @return bool
136 */
137 function desktop_mode_recycle_bin_user_can_use() {
138 $can = current_user_can( 'edit_posts' );
139
140 /**
141 * Filter whether the current user can see the recycle bin window.
142 *
143 * @since 0.19.0
144 *
145 * @param bool $can Default: edit_posts capability.
146 */
147 return (bool) apply_filters( 'desktop_mode_recycle_bin_user_can_use', $can );
148 }
149
150 /**
151 * Register the recycle bin window + desktop icon on `init`.
152 *
153 * Hooked at priority 20, after `components.php` has bootstrapped the
154 * native-window registry — same timing as the code editor.
155 *
156 * @since 0.19.0
157 */
158 function desktop_mode_recycle_bin_register_window() {
159 if ( ! desktop_mode_recycle_bin_user_can_use() ) {
160 return;
161 }
162
163 $window_args = array(
164 'title' => __( 'Recycle Bin', 'desktop-mode' ),
165 'icon' => 'dashicons-trash',
166 'template' => 'desktop_mode_recycle_bin_render_template',
167 'script' => 'desktop-mode-recycle-bin',
168 'width' => 880,
169 'height' => 560,
170 'min_width' => 520,
171 'min_height' => 360,
172 'placement' => 'taskbar',
173 );
174
175 /**
176 * Filter the args used to register the recycle bin native window.
177 *
178 * @since 0.19.0
179 *
180 * @param array $window_args Args passed to `desktop_mode_register_window()`.
181 */
182 $window_args = (array) apply_filters( 'desktop_mode_recycle_bin_window_args', $window_args );
183
184 $registered = desktop_mode_register_window( 'desktop-mode-recycle-bin', $window_args );
185 if ( is_wp_error( $registered ) ) {
186 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
187 error_log( '[desktop-mode] Recycle bin window registration failed: ' . $registered->get_error_message() );
188 return;
189 }
190
191 $icon_args = array(
192 'title' => __( 'Recycle Bin', 'desktop-mode' ),
193 'icon' => 'dashicons-trash',
194 'window' => 'desktop-mode-recycle-bin',
195 'position' => 80,
196 );
197
198 /**
199 * Filter the args used to register the recycle bin desktop icon.
200 *
201 * @since 0.19.0
202 *
203 * @param array $icon_args Args passed to `desktop_mode_register_icon()`.
204 */
205 $icon_args = (array) apply_filters( 'desktop_mode_recycle_bin_icon_args', $icon_args );
206
207 desktop_mode_register_icon( 'desktop-mode-recycle-bin', $icon_args );
208 }
209 add_action( 'init', 'desktop_mode_recycle_bin_register_window', 20 );
210
211 /**
212 * Localize REST endpoints for the JS bundle.
213 *
214 * Same pattern as the code editor: the bundle reads its config off
215 * `window.desktopModeRecycleBinConfig` and never hardcodes URLs.
216 *
217 * @since 0.19.0
218 */
219 function desktop_mode_recycle_bin_localize_config() {
220 if ( ! desktop_mode_recycle_bin_user_can_use() ) {
221 return;
222 }
223
224 wp_localize_script(
225 'desktop-mode-recycle-bin',
226 'desktopModeRecycleBinConfig',
227 array(
228 'restNonce' => wp_create_nonce( 'wp_rest' ),
229 'listUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin' ) ),
230 'restoreUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin/restore' ) ),
231 'purgeUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin/purge' ) ),
232 'emptyUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin/empty' ) ),
233 'countUrl' => esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin/count' ) ),
234 )
235 );
236
237 wp_enqueue_style( 'desktop-mode-recycle-bin' );
238 }
239 add_action( 'admin_enqueue_scripts', 'desktop_mode_recycle_bin_localize_config', 30 );
240
241 /**
242 * Inject the initial trash count into the shell config so the
243 * dock/taskbar tile + desktop icon can paint a badge on the very
244 * first paint — before the bin window has ever opened.
245 *
246 * @since 0.21.0
247 *
248 * @param array $config Shell config blob.
249 * @return array
250 */
251 function desktop_mode_recycle_bin_inject_shell_config( $config ) {
252 if ( ! is_array( $config ) ) {
253 return $config;
254 }
255 $config['recycleBinCount'] = desktop_mode_recycle_bin_count();
256 $config['recycleBinCountUrl'] = esc_url_raw( rest_url( 'desktop-mode/v1/recycle-bin/count' ) );
257 return $config;
258 }
259 add_filter( 'desktop_mode_shell_config', 'desktop_mode_recycle_bin_inject_shell_config', 20 );
260