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 / heartbeat.php

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

185 lines 5.1 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 Heartbeat sync.
4 *
5 * Same delta model as the sticky-notes sync
6 * (`includes/sticky-notes/heartbeat.php`): the client subscribes with
7 * the note ids it already renders plus a high-water modified
8 * timestamp; the server responds with notes changed since then and
9 * with removals (trashed, deleted, or made private by their owner).
10 *
11 * Visibility mirrors the REST list: the viewer's own notes (private +
12 * publish) plus every other user's public notes.
13 *
14 * @package WPDesktopMode
15 * @since 0.9.6
16 */
17
18 defined( 'ABSPATH' ) || exit;
19
20 /**
21 * Add pinned-note deltas to the Heartbeat response.
22 *
23 * @since 0.9.6
24 *
25 * @param array $response Pre-filtered response.
26 * @param array $data Client-sent payload.
27 * @return array
28 */
29 function desktop_mode_notes_heartbeat_received( $response, $data ) {
30 if ( ! is_array( $response ) ) {
31 $response = array();
32 }
33 if ( empty( $data['desktop_mode_notes_subscribe'] ) || ! is_array( $data['desktop_mode_notes_subscribe'] ) ) {
34 return $response;
35 }
36 if ( ! function_exists( 'desktop_mode_is_enabled' ) || ! desktop_mode_is_enabled() ) {
37 return $response;
38 }
39
40 $sub = $data['desktop_mode_notes_subscribe'];
41 $known_ids = isset( $sub['knownIds'] ) && is_array( $sub['knownIds'] )
42 ? array_values( array_unique( array_filter( array_map( 'absint', $sub['knownIds'] ) ) ) )
43 : array();
44 $known_ids = array_slice( $known_ids, 0, 500 );
45 $since_ms = isset( $sub['sinceMs'] ) ? max( 0, (int) $sub['sinceMs'] ) : 0;
46
47 $response['desktop_mode_notes'] = desktop_mode_notes_compute_heartbeat_delta( $known_ids, $since_ms, 100 );
48
49 return $response;
50 }
51 add_filter( 'heartbeat_received', 'desktop_mode_notes_heartbeat_received', 5, 2 );
52
53 /**
54 * Compute pinned-note Heartbeat deltas for the current user.
55 *
56 * @since 0.9.6
57 *
58 * @param int[] $known_ids Note ids currently rendered by the client.
59 * @param int $since_ms Last-seen modified timestamp in milliseconds.
60 * @param int $cap Maximum notes to send in one tick.
61 * @return array
62 */
63 function desktop_mode_notes_compute_heartbeat_delta( $known_ids, $since_ms, $cap ) {
64 $cap = max( 1, (int) $cap );
65 $query_ids = desktop_mode_notes_query_changed_ids( $since_ms, $cap + 1 );
66 $truncated = count( $query_ids ) > $cap;
67 if ( $truncated ) {
68 $query_ids = array_slice( $query_ids, 0, $cap );
69 }
70
71 $notes = array();
72 foreach ( $query_ids as $post_id ) {
73 $post = get_post( $post_id );
74 if ( $post instanceof WP_Post ) {
75 $notes[] = desktop_mode_notes_prepare( $post );
76 }
77 }
78
79 $alive_ids = desktop_mode_notes_alive_known_ids( $known_ids );
80 $removed = array_values( array_diff( array_map( 'intval', $known_ids ), $alive_ids ) );
81
82 return array(
83 'notes' => $notes,
84 'removed' => $removed,
85 'serverTimeMs' => (int) floor( microtime( true ) * 1000 ),
86 'truncated' => $truncated,
87 );
88 }
89
90 /**
91 * The `WP_Query` visibility clause shared by the delta queries: the
92 * viewer's own notes in any live status, or anyone's public notes.
93 *
94 * Expressed as two queries merged in PHP (like the REST list) rather
95 * than a hand-built OR — keeps every callsite on standard WP_Query.
96 *
97 * @since 0.9.6
98 *
99 * @param array $extra Extra WP_Query args merged into both halves.
100 * @return int[] Matching post ids, own notes first.
101 */
102 function desktop_mode_notes_query_visible_ids( $extra ) {
103 $user_id = get_current_user_id();
104 $base = array(
105 'post_type' => DESKTOP_MODE_NOTES_POST_TYPE,
106 'fields' => 'ids',
107 'no_found_rows' => true,
108 );
109
110 $own = new WP_Query(
111 array_merge(
112 $base,
113 $extra,
114 array(
115 'post_status' => array( 'private', 'publish' ),
116 'author' => $user_id,
117 )
118 )
119 );
120
121 $public = new WP_Query(
122 array_merge(
123 $base,
124 $extra,
125 array(
126 'post_status' => 'publish',
127 'author__not_in' => array( $user_id ),
128 )
129 )
130 );
131
132 $ids = array_map( 'intval', array_merge( (array) $own->posts, (array) $public->posts ) );
133 wp_reset_postdata();
134
135 return array_values( array_unique( $ids ) );
136 }
137
138 /**
139 * Query visible note ids modified since the client's high-water mark.
140 *
141 * @since 0.9.6
142 *
143 * @param int $since_ms Last-seen modified timestamp in milliseconds.
144 * @param int $limit Max ids to return (per visibility half).
145 * @return int[]
146 */
147 function desktop_mode_notes_query_changed_ids( $since_ms, $limit ) {
148 $extra = array(
149 'posts_per_page' => max( 1, (int) $limit ),
150 'orderby' => 'modified',
151 'order' => 'ASC',
152 );
153 if ( $since_ms > 0 ) {
154 $extra['date_query'] = array(
155 array(
156 'column' => 'post_modified_gmt',
157 'after' => gmdate( 'Y-m-d H:i:s', (int) floor( $since_ms / 1000 ) ),
158 'inclusive' => true,
159 ),
160 );
161 }
162 return desktop_mode_notes_query_visible_ids( $extra );
163 }
164
165 /**
166 * Return the subset of known ids still visible to the viewer.
167 *
168 * @since 0.9.6
169 *
170 * @param int[] $known_ids Client-known note ids.
171 * @return int[]
172 */
173 function desktop_mode_notes_alive_known_ids( $known_ids ) {
174 $known_ids = array_values( array_unique( array_filter( array_map( 'absint', (array) $known_ids ) ) ) );
175 if ( empty( $known_ids ) ) {
176 return array();
177 }
178 return desktop_mode_notes_query_visible_ids(
179 array(
180 'post__in' => $known_ids,
181 'posts_per_page' => count( $known_ids ),
182 )
183 );
184 }
185