| @@ -65,10 +65,32 @@ | ||
| 65 | 65 | if ( ! wp_is_collaboration_enabled() ) { |
| 66 | 66 | return; |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | - $sync_storage = new WP_Sync_Post_Meta_Storage(); | |
| 70 | - $sync_server = new WP_HTTP_Polling_Sync_Server( $sync_storage ); | |
| 69 | + /** | |
| 70 | + * Filters the sync storage implementation for collaborative editing. | |
| 71 | + * | |
| 72 | + * Allows plugins to replace the default post meta storage with alternative | |
| 73 | + * backends. The primary use case is the realtime-collaboration plugin, | |
| 74 | + * which uses Presence API for awareness and a dedicated wp_collaboration | |
| 75 | + * table for CRDT updates, eliminating cache side effects. | |
| 76 | + * | |
| 77 | + * This filter is unstable and may change as RTC explores fundamental changes | |
| 78 | + * to how syncing works. The current interface assumes a pure naïve relay, | |
| 79 | + * which could change. | |
| 80 | + * | |
| 81 | + * @since Gutenberg 21.x | |
| 82 | + * | |
| 83 | + * @param WP_Sync_Storage $sync_storage Storage implementation. Must implement | |
| 84 | + * the WP_Sync_Storage interface. | |
| 85 | + */ | |
| 86 | + $sync_storage = apply_filters( '__unstable_wp_sync_storage', new WP_Sync_Post_Meta_Storage() ); | |
| 87 | + | |
| 88 | + if ( ! $sync_storage instanceof WP_Sync_Storage ) { | |
| 89 | + $sync_storage = new WP_Sync_Post_Meta_Storage(); | |
| 90 | + } | |
| 91 | + | |
| 92 | + $sync_server = new WP_HTTP_Polling_Sync_Server( $sync_storage ); | |
| 71 | 93 | $sync_server->register_routes(); |
| 72 | 94 | |
| 73 | 95 | $sync_save_server = new WP_Sync_Save_Server(); |
| 74 | 96 | $sync_save_server->register_routes(); |
| @@ -157,8 +179,38 @@ | ||
| 157 | 179 | */ |
| 158 | 180 | return (bool) apply_filters( 'wp_is_post_type_collaboration_disabled', false, $post_type ); |
| 159 | 181 | } |
| 160 | 182 | } |
| 183 | + | |
| 184 | +/** | |
| 185 | + * Disables real-time collaboration for post types that cannot persist the | |
| 186 | + * CRDT document. | |
| 187 | + * | |
| 188 | + * Collaboration stores its CRDT document in post meta. The REST API only | |
| 189 | + * exposes post meta for post types that support custom fields, so enabling | |
| 190 | + * collaboration for other post types can cause stale sync updates to replace | |
| 191 | + * newer entity content. | |
| 192 | + * | |
| 193 | + * @param bool $disabled Whether real-time collaboration is disabled for the post type. | |
| 194 | + * @param string $post_type Post type name. | |
| 195 | + * @return bool Whether real-time collaboration is disabled for the post type. | |
| 196 | + */ | |
| 197 | +function gutenberg_disable_collaboration_for_post_types_without_custom_fields( $disabled, $post_type ) { | |
| 198 | + if ( $disabled ) { | |
| 199 | + return $disabled; | |
| 200 | + } | |
| 201 | + | |
| 202 | + /* | |
| 203 | + * The attachments REST controller always exposes meta, regardless of | |
| 204 | + * whether the attachment post type supports custom fields. | |
| 205 | + */ | |
| 206 | + if ( 'attachment' === $post_type ) { | |
| 207 | + return false; | |
| 208 | + } | |
| 209 | + | |
| 210 | + return ! post_type_supports( $post_type, 'custom-fields' ); | |
| 211 | +} | |
| 212 | +add_filter( 'wp_is_post_type_collaboration_disabled', 'gutenberg_disable_collaboration_for_post_types_without_custom_fields', 10, 2 ); | |
| 161 | 213 | |
| 162 | 214 | if ( ! function_exists( 'gutenberg_get_active_edit_lock_user' ) ) { |
| 163 | 215 | /** |
| 164 | 216 | * Returns the user ID recorded in a fresh edit lock. |