array( 'name' => __( 'Sync Updates', 'gutenberg' ), 'singular_name' => __( 'Sync Update', 'gutenberg' ), ), 'public' => false, 'hierarchical' => false, 'capabilities' => array( 'read' => 'do_not_allow', 'read_private_posts' => 'do_not_allow', 'create_posts' => 'do_not_allow', 'publish_posts' => 'do_not_allow', 'edit_posts' => 'do_not_allow', 'edit_others_posts' => 'do_not_allow', 'edit_published_posts' => 'do_not_allow', 'delete_posts' => 'do_not_allow', 'delete_others_posts' => 'do_not_allow', 'delete_published_posts' => 'do_not_allow', ), 'map_meta_cap' => false, 'publicly_queryable' => false, 'query_var' => false, 'rewrite' => false, 'show_in_menu' => false, 'show_in_rest' => false, 'show_ui' => false, 'supports' => array( 'custom-fields' ), ) ); } add_action( 'init', 'gutenberg_register_sync_storage_post_type' ); } if ( ! function_exists( 'gutenberg_register_collaboration_rest_routes' ) ) { /** * Registers REST API routes for collaborative editing. */ function gutenberg_register_collaboration_rest_routes(): void { $sync_storage = new WP_Sync_Post_Meta_Storage(); $sync_server = new WP_HTTP_Polling_Sync_Server( $sync_storage ); $sync_server->register_routes(); } add_action( 'rest_api_init', 'gutenberg_register_collaboration_rest_routes' ); } if ( ! function_exists( 'wp_collaboration_register_meta' ) ) { /** * Registers post meta for persisting CRDT documents. */ function gutenberg_rest_api_crdt_post_meta() { // This string must match WORDPRESS_META_KEY_FOR_CRDT_DOC_PERSISTENCE in @wordpress/sync. $persisted_crdt_post_meta_key = '_crdt_document'; register_meta( 'post', $persisted_crdt_post_meta_key, array( 'auth_callback' => static function ( bool $_allowed, string $_meta_key, int $object_id, int $user_id ): bool { return user_can( $user_id, 'edit_post', $object_id ); }, /* * Revisions must be disabled because we always want to preserve * the latest persisted CRDT document, even when a revision is restored. * This ensures that we can continue to apply updates to a shared document * and peers can simply merge the restored revision like any other incoming * update. * * If we want to persist CRDT documents alongside revisions in the * future, we should do so in a separate meta key. */ 'revisions_enabled' => false, 'show_in_rest' => array( 'schema' => array( 'type' => 'string', 'context' => array( 'edit' ), ), ), 'single' => true, 'type' => 'string', ) ); } add_action( 'init', 'gutenberg_rest_api_crdt_post_meta' ); } if ( ! function_exists( 'wp_collaboration_inject_setting' ) ) { /** * Registers the real-time collaboration setting. */ function gutenberg_register_real_time_collaboration_setting() { $option_name = 'wp_collaboration_enabled'; register_setting( 'writing', $option_name, array( 'type' => 'boolean', 'description' => __( 'Enable Real-Time Collaboration', 'gutenberg' ), 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => true, 'show_in_rest' => true, ) ); add_settings_field( $option_name, __( 'Collaboration', 'gutenberg' ), function () use ( $option_name ) { $option_value = get_option( $option_name ); if ( wp_is_collaboration_allowed() ) : ?>