PluginProbe
Gutenberg / 22.9.0
Gutenberg v22.9.0
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 / experimental / content-guidelines / class-gutenberg-content-guidelines-post-type.php

class-gutenberg-content-guidelines-post-type.php in Gutenberg 22.9.0, at lib/experimental/content-guidelines/class-gutenberg-content-guidelines-post-type.php

261 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Content Guidelines Post Type registration.
4 *
5 * @package gutenberg
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 /**
13 * Handles registration of the Content Guidelines custom post type.
14 */
15 class Gutenberg_Content_Guidelines_Post_Type {
16
17 /**
18 * The post type name.
19 *
20 * @var string
21 */
22 const POST_TYPE = 'wp_content_guideline';
23
24 /**
25 * The standard guideline category meta keys.
26 *
27 * @var array
28 */
29 const CATEGORY_META_KEYS = array(
30 'copy',
31 'images',
32 'site',
33 'additional',
34 );
35
36 /**
37 * All valid guideline category keys for filtering.
38 *
39 * Includes standard categories plus 'blocks'.
40 *
41 * @var array
42 */
43 const VALID_CATEGORIES = array(
44 'copy',
45 'images',
46 'site',
47 'additional',
48 'blocks',
49 );
50
51 /**
52 * Valid guideline statuses.
53 *
54 * @var array
55 */
56 const VALID_STATUSES = array(
57 'draft',
58 'publish',
59 );
60
61 /**
62 * Prefix for block-specific guideline meta keys.
63 *
64 * @var string
65 */
66 const BLOCK_META_PREFIX = '_content_guideline_block_';
67
68 /**
69 * Register the custom post type.
70 */
71 public static function register() {
72 $args = array(
73 'labels' => array(
74 'name' => __( 'Guidelines', 'gutenberg' ),
75 'singular_name' => __( 'Guidelines', 'gutenberg' ),
76 ),
77 'public' => false,
78 'publicly_queryable' => false,
79 'show_ui' => false,
80 'show_in_menu' => false,
81 'show_in_rest' => true,
82 'rest_base' => 'content-guidelines',
83 'rest_controller_class' => 'Gutenberg_Content_Guidelines_REST_Controller',
84 'revisions_rest_controller_class' => 'Gutenberg_Content_Guidelines_Revisions_Controller',
85 'capability_type' => 'post',
86 'capabilities' => array(
87 'read' => 'edit_posts',
88 'create_posts' => 'manage_options',
89 'edit_posts' => 'manage_options',
90 'edit_published_posts' => 'manage_options',
91 'delete_posts' => 'manage_options',
92 'delete_published_posts' => 'manage_options',
93 'edit_others_posts' => 'manage_options',
94 'delete_others_posts' => 'manage_options',
95 'publish_posts' => 'manage_options',
96 ),
97 'map_meta_cap' => true,
98 'supports' => array( 'revisions' ),
99 'hierarchical' => false,
100 'has_archive' => false,
101 'rewrite' => false,
102 'query_var' => false,
103 'can_export' => true,
104 );
105
106 register_post_type( self::POST_TYPE, $args );
107 }
108
109 /**
110 * Register post meta fields with revision support.
111 */
112 public static function register_post_meta() {
113 $meta_args = array(
114 'show_in_rest' => true,
115 'single' => true,
116 'type' => 'string',
117 'revisions_enabled' => true,
118 'auth_callback' => function () {
119 return current_user_can( 'manage_options' );
120 },
121 'sanitize_callback' => 'sanitize_textarea_field',
122 );
123
124 // Register standard category meta.
125 foreach ( self::CATEGORY_META_KEYS as $category ) {
126 register_post_meta( self::POST_TYPE, '_content_guideline_' . $category, $meta_args );
127 }
128
129 // Register meta for content blocks.
130 foreach ( self::get_content_blocks() as $block_name ) {
131 register_post_meta( self::POST_TYPE, self::block_name_to_meta_key( $block_name ), $meta_args );
132 }
133 }
134
135 /**
136 * Get block names that have content role attributes.
137 *
138 * @return array Block names with content role.
139 */
140 public static function get_content_blocks() {
141 $content_blocks = array();
142 $registry = WP_Block_Type_Registry::get_instance();
143
144 foreach ( $registry->get_all_registered() as $block_type ) {
145 if ( self::block_has_content_role( $block_type ) ) {
146 $content_blocks[] = $block_type->name;
147 }
148 }
149
150 return $content_blocks;
151 }
152
153 /**
154 * Check if a block type has any attribute with content role.
155 *
156 * @param WP_Block_Type $block_type The block type to check.
157 * @return bool True if block has content role attribute.
158 */
159 private static function block_has_content_role( $block_type ) {
160 if ( empty( $block_type->attributes ) ) {
161 return false;
162 }
163
164 foreach ( $block_type->attributes as $attribute ) {
165 if ( isset( $attribute['role'] ) && 'content' === $attribute['role'] ) {
166 return true;
167 }
168 }
169
170 return false;
171 }
172
173 /**
174 * Convert a block name to a meta key.
175 *
176 * @param string $block_name The block name (e.g., 'core/paragraph').
177 * @return string The meta key (e.g., '_content_guideline_block_core_paragraph').
178 */
179 public static function block_name_to_meta_key( $block_name ) {
180 // Replace '/' with '_' to create a valid meta key.
181 $sanitized = str_replace( '/', '_', $block_name );
182 return self::BLOCK_META_PREFIX . $sanitized;
183 }
184
185 /**
186 * Convert a meta key back to a block name.
187 *
188 * @param string $meta_key The meta key (e.g., '_content_guideline_block_core_paragraph').
189 * @return string The block name (e.g., 'core/paragraph').
190 */
191 public static function meta_key_to_block_name( $meta_key ) {
192 // Remove prefix and convert first '_' back to '/'.
193 $without_prefix = str_replace( self::BLOCK_META_PREFIX, '', $meta_key );
194 // Replace first underscore with '/' (namespace separator).
195 return preg_replace( '/_/', '/', $without_prefix, 1 );
196 }
197
198 /**
199 * Check if a meta key is a block guideline meta key.
200 *
201 * @param string $meta_key The meta key to check.
202 * @return bool True if it's a block guideline meta key.
203 */
204 public static function is_block_meta_key( $meta_key ) {
205 return strpos( $meta_key, self::BLOCK_META_PREFIX ) === 0;
206 }
207
208 /**
209 * Gets guideline categories from post meta.
210 *
211 * Shared between the post controller and revisions controller.
212 *
213 * @param int $post_id Post ID (can be a post or revision ID).
214 * @return array Guideline categories.
215 */
216 public static function get_guideline_categories_from_meta( $post_id ) {
217 $category_labels = array(
218 'copy' => __( 'Copy Guidelines', 'gutenberg' ),
219 'images' => __( 'Image Guidelines', 'gutenberg' ),
220 'site' => __( 'Site Context', 'gutenberg' ),
221 'additional' => __( 'Additional Guidelines', 'gutenberg' ),
222 );
223
224 $guideline_categories = array();
225
226 // Get standard categories.
227 foreach ( self::CATEGORY_META_KEYS as $category ) {
228 $meta_key = '_content_guideline_' . $category;
229 $value = get_post_meta( $post_id, $meta_key, true );
230
231 $guideline_categories[ $category ] = array(
232 'label' => $category_labels[ $category ],
233 'guidelines' => $value,
234 );
235 }
236
237 // Get block-specific guidelines from individual meta keys.
238 $all_meta = get_post_meta( $post_id );
239
240 $blocks = array();
241 foreach ( $all_meta as $meta_key => $meta_values ) {
242 if ( self::is_block_meta_key( $meta_key ) ) {
243 $block_name = self::meta_key_to_block_name( $meta_key );
244 $value = $meta_values[0] ?? '';
245
246 if ( ! empty( $value ) ) {
247 $blocks[ $block_name ] = array(
248 'guidelines' => $value,
249 );
250 }
251 }
252 }
253
254 if ( ! empty( $blocks ) ) {
255 $guideline_categories['blocks'] = $blocks;
256 }
257
258 return $guideline_categories;
259 }
260 }
261