PluginProbe
Gutenberg / 23.5.2
Gutenberg v23.5.2
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / lib / compat / wordpress-7.1 / class-wp-sync-config.php

class-wp-sync-config.php in Gutenberg 23.5.2, at lib/compat/wordpress-7.1/class-wp-sync-config.php

197 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WP_Sync_Config class
4 *
5 * @package gutenberg
6 */
7
8 if ( ! class_exists( 'WP_Sync_Config' ) ) {
9
10 /**
11 * Configuration helpers for sync entities.
12 *
13 * @since 7.1.0
14 * @access private
15 */
16 class WP_Sync_Config {
17 /**
18 * Entity sync configuration.
19 *
20 * Used to convert sync entity rooms (e.g. `postType/post:100`) to
21 * entity types and reject sync or save requests for unsupported entity
22 * types.
23 *
24 * @since 7.1.0
25 * @var array
26 */
27 const ENTITY_CONFIG = array(
28 'postType' => array(
29 'object_type' => 'post',
30 'supports_crdt_doc_persistence' => true,
31 ),
32 );
33
34 /**
35 * Parses a sync room identifier into entity parts.
36 *
37 * @since 7.1.0
38 *
39 * @param string $room Room identifier.
40 * @return array{entity_kind:string, entity_name:string, object_id:string|null}|null Parsed room, or null if invalid.
41 */
42 public static function parse_room( string $room ): ?array {
43 $type_parts = explode( '/', $room, 2 );
44 if ( 2 !== count( $type_parts ) || '' === $type_parts[0] || '' === $type_parts[1] ) {
45 return null;
46 }
47
48 if ( false !== strpos( $type_parts[1], '/' ) ) {
49 return null;
50 }
51
52 $object_parts = explode( ':', $type_parts[1], 2 );
53 if ( '' === $object_parts[0] ) {
54 return null;
55 }
56
57 $object_id = $object_parts[1] ?? null;
58 if ( '' === $object_id ) {
59 return null;
60 }
61
62 return array(
63 'entity_kind' => $type_parts[0],
64 'entity_name' => $object_parts[0],
65 'object_id' => $object_id,
66 );
67 }
68
69 /**
70 * Checks if the current user can sync a specific entity type.
71 *
72 * @since 7.1.0
73 *
74 * @param string $entity_kind The entity kind, e.g. 'postType', 'taxonomy', 'root'.
75 * @param string $entity_name The entity name, e.g. 'post', 'category', 'site'.
76 * @param string|null $object_id The numeric object ID / entity key for single entities, null for collections.
77 * @return bool True if user has permission, otherwise false.
78 */
79 public static function can_user_sync_entity_type( string $entity_kind, string $entity_name, ?string $object_id ): bool {
80 if ( is_string( $object_id ) ) {
81 if ( ! ctype_digit( $object_id ) ) {
82 return false;
83 }
84 $object_id = (int) $object_id;
85 }
86
87 if ( null !== $object_id && $object_id <= 0 ) {
88 return false;
89 }
90
91 if ( is_int( $object_id ) ) {
92 if ( 'postType' === $entity_kind ) {
93 if ( get_post_type( $object_id ) !== $entity_name ) {
94 return false;
95 }
96 return current_user_can( 'edit_post', $object_id );
97 }
98
99 if ( 'taxonomy' === $entity_kind ) {
100 $term_exists = term_exists( $object_id, $entity_name );
101 if ( ! is_array( $term_exists ) || ! isset( $term_exists['term_id'] ) ) {
102 return false;
103 }
104
105 return current_user_can( 'edit_term', $object_id );
106 }
107
108 if ( 'root' === $entity_kind && 'comment' === $entity_name ) {
109 return current_user_can( 'edit_comment', $object_id );
110 }
111 }
112
113 if ( null !== $object_id ) {
114 return false;
115 }
116
117 if ( 'postType' === $entity_kind ) {
118 $post_type_object = get_post_type_object( $entity_name );
119 if ( ! isset( $post_type_object->cap->edit_posts ) ) {
120 return false;
121 }
122
123 return current_user_can( $post_type_object->cap->edit_posts );
124 }
125
126 $allowed_collection_entity_kinds = array(
127 'postType',
128 'root',
129 'taxonomy',
130 );
131
132 return in_array( $entity_kind, $allowed_collection_entity_kinds, true );
133 }
134
135 /**
136 * Checks if a single entity room supports persisted CRDT documents.
137 *
138 * @since 7.1.0
139 *
140 * @param string $entity_kind The entity kind.
141 * @param string $entity_name The entity name.
142 * @param string|null $object_id The entity ID.
143 * @return bool True if the entity room supports persisted CRDT documents.
144 */
145 public static function supports_crdt_doc_persistence( string $entity_kind, string $entity_name, ?string $object_id ): bool {
146 return null !== self::get_crdt_doc_persistence_post_id( $entity_kind, $entity_name, $object_id );
147 }
148
149 /**
150 * Gets the post ID used to persist a CRDT document for an entity room.
151 *
152 * @since 7.1.0
153 *
154 * @param string $entity_kind The entity kind.
155 * @param string $entity_name The entity name.
156 * @param string|null $object_id The entity ID.
157 * @return int|null Post ID if persistence is supported, otherwise null.
158 */
159 public static function get_crdt_doc_persistence_post_id( string $entity_kind, string $entity_name, ?string $object_id ): ?int {
160 if ( ! self::entity_kind_supports_crdt_doc_persistence( $entity_kind ) || ! is_string( $object_id ) || ! ctype_digit( $object_id ) ) {
161 return null;
162 }
163
164 $post_id = (int) $object_id;
165 if ( $post_id <= 0 || 'post' !== self::get_object_type( $entity_kind ) || get_post_type( $post_id ) !== $entity_name ) {
166 return null;
167 }
168
169 return $post_id;
170 }
171
172 /**
173 * Checks if an entity kind supports persisted CRDT documents.
174 *
175 * @since 7.1.0
176 *
177 * @param string $entity_kind The entity kind.
178 * @return bool True if the entity kind supports persisted CRDT documents.
179 */
180 private static function entity_kind_supports_crdt_doc_persistence( string $entity_kind ): bool {
181 return true === ( self::ENTITY_CONFIG[ $entity_kind ]['supports_crdt_doc_persistence'] ?? false );
182 }
183
184 /**
185 * Gets the object type used to persist CRDT documents for an entity kind.
186 *
187 * @since 7.1.0
188 *
189 * @param string $entity_kind The entity kind.
190 * @return string|null Object type, or null if not supported.
191 */
192 private static function get_object_type( string $entity_kind ): ?string {
193 return self::ENTITY_CONFIG[ $entity_kind ]['object_type'] ?? null;
194 }
195 }
196 }
197