PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / trunk
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin vtrunk
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 0.8.6 All 33 releases
desktop-mode / includes / notes / recycle-bin.php

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

163 lines 5.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * OpenStation — 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 OpenStation
33 */
34
35 defined( 'ABSPATH' ) || exit;
36
37 /**
38 * Opt `wpd_note` into the recycle bin's capture list.
39 *
40 * @param string[] $types Tracked post types.
41 * @return string[]
42 */
43 function openstation_notes_recycle_bin_capture_types( $types ) {
44 $types = (array) $types;
45 $types[] = OPENSTATION_NOTES_POST_TYPE;
46 return $types;
47 }
48 add_filter( 'openstation_recycle_bin_capture_post_types', 'openstation_notes_recycle_bin_capture_types' );
49
50 /**
51 * Whether a trashed post is a note owned by the current user.
52 *
53 * @param WP_Post $post Trashed post.
54 * @return bool
55 */
56 function openstation_notes_recycle_bin_owns( $post ) {
57 return get_current_user_id() === (int) $post->post_author;
58 }
59
60 /**
61 * Owner-only view/restore/purge for notes — replaces the bin's
62 * default `edit_post`/`delete_post` gates for this post type.
63 *
64 * @param bool $can The bin's default answer.
65 * @param WP_Post $post Trashed post.
66 * @return bool
67 */
68 function openstation_notes_recycle_bin_gate( $can, $post ) {
69 if ( OPENSTATION_NOTES_POST_TYPE !== $post->post_type ) {
70 return $can;
71 }
72 return openstation_notes_recycle_bin_owns( $post );
73 }
74 add_filter( 'openstation_recycle_bin_user_can_view', 'openstation_notes_recycle_bin_gate', 10, 2 );
75 add_filter( 'openstation_recycle_bin_user_can_restore', 'openstation_notes_recycle_bin_gate', 10, 2 );
76 add_filter( 'openstation_recycle_bin_user_can_purge', 'openstation_notes_recycle_bin_gate', 10, 2 );
77
78 /**
79 * Paper-flavored row shape for trashed notes.
80 *
81 * @param array $item Bin item shape.
82 * @param WP_Post $post Source post.
83 * @return array
84 */
85 function openstation_notes_recycle_bin_item( $item, $post ) {
86 if ( OPENSTATION_NOTES_POST_TYPE !== $post->post_type ) {
87 return $item;
88 }
89 $item['type_label'] = __( 'Note', 'desktop-mode' );
90 $item['icon'] = 'dashicons-sticky';
91 $item['subtitle'] = wp_trim_words( openstation_recycle_bin_plain_text( (string) $post->post_content ), 18, '' );
92 // Notes have no admin edit screen — a chromeless post.php iframe
93 // would 403 on the headless CPT.
94 $item['edit_link'] = '';
95
96 // "Deleted by" fallback. The bin's who-deleted stamp is written at
97 // trash time, so notes trashed before wpd_note joined the capture
98 // list (or trashed with no logged-in user: WP-CLI, cron) have none.
99 // For notes the owner is the only principal who can trash, so
100 // attributing an unstamped row to the author is correct by
101 // construction. Display-time only — nothing is written back.
102 if ( '' === (string) $item['deleted_by'] ) {
103 $owner = get_userdata( (int) $post->post_author );
104 if ( $owner instanceof WP_User ) {
105 $item['deleted_by'] = $owner->display_name;
106 $item['deleted_by_id'] = (int) $post->post_author;
107 }
108 }
109
110 return $item;
111 }
112 add_filter( 'openstation_recycle_bin_item', 'openstation_notes_recycle_bin_item', 10, 2 );
113
114 /**
115 * Number of trashed notes for a given scope.
116 *
117 * @param int|null $author_id Scope to one author, or null for all.
118 * @return int
119 */
120 function openstation_notes_recycle_bin_trashed_count( $author_id = null ) {
121 $args = array(
122 'post_type' => OPENSTATION_NOTES_POST_TYPE,
123 'post_status' => 'trash',
124 'posts_per_page' => 1,
125 'fields' => 'ids',
126 'no_found_rows' => false,
127 );
128 if ( null !== $author_id ) {
129 $args['author'] = (int) $author_id;
130 }
131 $query = new WP_Query( $args );
132 return (int) $query->found_posts;
133 }
134
135 /**
136 * Re-scope the badge count's notes contribution to owned-only, so
137 * the badge always matches what the (owner-gated) list shows.
138 *
139 * The generic count already included: ALL trashed notes for users
140 * holding `edit_others_posts`, OWN trashed notes for `edit_posts`
141 * holders, and none for anyone else. Normalize every case to "own
142 * trashed notes".
143 *
144 * @param int $total Generic total.
145 * @return int
146 */
147 function openstation_notes_recycle_bin_count( $total ) {
148 $total = (int) $total;
149 $own = openstation_notes_recycle_bin_trashed_count( get_current_user_id() );
150
151 if ( current_user_can( 'edit_others_posts' ) ) {
152 // Counted everyone's notes; keep only ours.
153 $total = $total - openstation_notes_recycle_bin_trashed_count() + $own;
154 } elseif ( ! current_user_can( 'edit_posts' ) ) {
155 // Counted none of ours; add them.
156 $total = $total + $own;
157 }
158 // `edit_posts`-only users were already counted author-scoped.
159
160 return max( 0, $total );
161 }
162 add_filter( 'openstation_recycle_bin_count', 'openstation_notes_recycle_bin_count' );
163