PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 0.9.6
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v0.9.6
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 / notes / recycle-bin.php

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

176 lines 5.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Desktop Mode — Pinned notes in the Recycle Bin.
4 *
5 * `wpd_note` is a headless CPT (`show_ui => false`), so the bin's
6 * auto-capture of admin-UI post types skips it — this file opts it in
7 * through the bin's existing filter pipeline and adapts the generic
8 * post handling to the notes ownership model:
9 *
10 * - OWNER-ONLY visibility. The bin's default gates use `edit_post`
11 * / `delete_post`, which (a) let administrators manage everyone's
12 * trashed notes (the live-notes REST controller deliberately does
13 * NOT allow that, and a private note's text should not surface in
14 * someone else's bin) and (b) lock out subscribers entirely (they
15 * hold no `edit_posts`-family caps, yet they own their notes).
16 * Both are replaced with a plain `post_author` check.
17 *
18 * - Badge-count correction. The generic count buckets post types by
19 * the viewer's `edit_posts`/`edit_others_posts` caps, which counts
20 * other users' notes for editors/admins and zero notes for
21 * subscribers — both diverge from what the list shows. The count
22 * filter re-scopes the notes contribution to owned-only.
23 *
24 * - A paper-flavored row: sticky-note icon, "Note" label, and the
25 * note text as the subtitle.
26 *
27 * Restoring from the bin runs `wp_untrash_post()`, so the
28 * `wp_untrash_post_status` filter in `cpt.php` brings the note back
29 * with its original private/publish status, and the Heartbeat delta
30 * re-pins it on the wall without a reload.
31 *
32 * @package WPDesktopMode
33 * @since 0.9.6
34 */
35
36 defined( 'ABSPATH' ) || exit;
37
38 /**
39 * Opt `wpd_note` into the recycle bin's capture list.
40 *
41 * @since 0.9.6
42 *
43 * @param string[] $types Tracked post types.
44 * @return string[]
45 */
46 function desktop_mode_notes_recycle_bin_capture_types( $types ) {
47 $types = (array) $types;
48 $types[] = DESKTOP_MODE_NOTES_POST_TYPE;
49 return $types;
50 }
51 add_filter( 'desktop_mode_recycle_bin_capture_post_types', 'desktop_mode_notes_recycle_bin_capture_types' );
52
53 /**
54 * Whether a trashed post is a note owned by the current user.
55 *
56 * @since 0.9.6
57 *
58 * @param WP_Post $post Trashed post.
59 * @return bool
60 */
61 function desktop_mode_notes_recycle_bin_owns( $post ) {
62 return (int) $post->post_author === get_current_user_id();
63 }
64
65 /**
66 * Owner-only view/restore/purge for notes — replaces the bin's
67 * default `edit_post`/`delete_post` gates for this post type.
68 *
69 * @since 0.9.6
70 *
71 * @param bool $can The bin's default answer.
72 * @param WP_Post $post Trashed post.
73 * @return bool
74 */
75 function desktop_mode_notes_recycle_bin_gate( $can, $post ) {
76 if ( DESKTOP_MODE_NOTES_POST_TYPE !== $post->post_type ) {
77 return $can;
78 }
79 return desktop_mode_notes_recycle_bin_owns( $post );
80 }
81 add_filter( 'desktop_mode_recycle_bin_user_can_view', 'desktop_mode_notes_recycle_bin_gate', 10, 2 );
82 add_filter( 'desktop_mode_recycle_bin_user_can_restore', 'desktop_mode_notes_recycle_bin_gate', 10, 2 );
83 add_filter( 'desktop_mode_recycle_bin_user_can_purge', 'desktop_mode_notes_recycle_bin_gate', 10, 2 );
84
85 /**
86 * Paper-flavored row shape for trashed notes.
87 *
88 * @since 0.9.6
89 *
90 * @param array $item Bin item shape.
91 * @param WP_Post $post Source post.
92 * @return array
93 */
94 function desktop_mode_notes_recycle_bin_item( $item, $post ) {
95 if ( DESKTOP_MODE_NOTES_POST_TYPE !== $post->post_type ) {
96 return $item;
97 }
98 $item['type_label'] = __( 'Note', 'desktop-mode' );
99 $item['icon'] = 'dashicons-sticky';
100 $item['subtitle'] = wp_trim_words( desktop_mode_recycle_bin_plain_text( (string) $post->post_content ), 18, '' );
101 // Notes have no admin edit screen — a chromeless post.php iframe
102 // would 403 on the headless CPT.
103 $item['edit_link'] = '';
104
105 // "Deleted by" fallback. The bin's who-deleted stamp is written at
106 // trash time, so notes trashed before wpd_note joined the capture
107 // list (or trashed with no logged-in user: WP-CLI, cron) have none.
108 // For notes the owner is the only principal who can trash, so
109 // attributing an unstamped row to the author is correct by
110 // construction. Display-time only — nothing is written back.
111 if ( '' === (string) $item['deleted_by'] ) {
112 $owner = get_userdata( (int) $post->post_author );
113 if ( $owner instanceof WP_User ) {
114 $item['deleted_by'] = $owner->display_name;
115 $item['deleted_by_id'] = (int) $post->post_author;
116 }
117 }
118
119 return $item;
120 }
121 add_filter( 'desktop_mode_recycle_bin_item', 'desktop_mode_notes_recycle_bin_item', 10, 2 );
122
123 /**
124 * Number of trashed notes for a given scope.
125 *
126 * @since 0.9.6
127 *
128 * @param int|null $author_id Scope to one author, or null for all.
129 * @return int
130 */
131 function desktop_mode_notes_recycle_bin_trashed_count( $author_id = null ) {
132 $args = array(
133 'post_type' => DESKTOP_MODE_NOTES_POST_TYPE,
134 'post_status' => 'trash',
135 'posts_per_page' => 1,
136 'fields' => 'ids',
137 'no_found_rows' => false,
138 );
139 if ( null !== $author_id ) {
140 $args['author'] = (int) $author_id;
141 }
142 $query = new WP_Query( $args );
143 return (int) $query->found_posts;
144 }
145
146 /**
147 * Re-scope the badge count's notes contribution to owned-only, so
148 * the badge always matches what the (owner-gated) list shows.
149 *
150 * The generic count already included: ALL trashed notes for users
151 * holding `edit_others_posts`, OWN trashed notes for `edit_posts`
152 * holders, and none for anyone else. Normalize every case to "own
153 * trashed notes".
154 *
155 * @since 0.9.6
156 *
157 * @param int $total Generic total.
158 * @return int
159 */
160 function desktop_mode_notes_recycle_bin_count( $total ) {
161 $total = (int) $total;
162 $own = desktop_mode_notes_recycle_bin_trashed_count( get_current_user_id() );
163
164 if ( current_user_can( 'edit_others_posts' ) ) {
165 // Counted everyone's notes; keep only ours.
166 $total = $total - desktop_mode_notes_recycle_bin_trashed_count() + $own;
167 } elseif ( ! current_user_can( 'edit_posts' ) ) {
168 // Counted none of ours; add them.
169 $total = $total + $own;
170 }
171 // `edit_posts`-only users were already counted author-scoped.
172
173 return max( 0, $total );
174 }
175 add_filter( 'desktop_mode_recycle_bin_count', 'desktop_mode_notes_recycle_bin_count' );
176