PluginProbe
bbPress / trunk
bbPress vtrunk
trunk 2.0 2.0-beta-1 2.0-beta-2b 2.0-beta-3 2.0-beta-3b 2.0-rc-2 2.0-rc-3 2.0-rc-4 2.0-rc-5 2.0.1 2.0.2 2.0.3 2.1 2.1-beta-1 2.1-rc1 2.1-rc2 2.1-rc3 2.1-rc4 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.2.2 All 71 releases
bbpress / includes / common / blocks.php

blocks.php in bbPress trunk, at includes/common/blocks.php

346 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // phpcs:ignoreFile WordPress.Files.FileName.InvalidClassFileName
3 /**
4 * Blocks loader for bbPress.
5 *
6 * @package bbPress
7 * @subpackage Blocks
8 */
9
10 // Exit if accessed directly.
11 defined( 'ABSPATH' ) || exit;
12
13 if ( ! class_exists( 'BBP_Blocks' ) ) :
14 /**
15 * BbPress shortcode class.
16 *
17 * @since 2.0.0 bbPress (r3031)
18 */
19 class BBP_Blocks {
20
21 /** Vars ******************************************************************/
22
23 /**
24 * Map of block names to shortcode callbacks.
25 *
26 * @var array Block => function
27 */
28 public $blocks = array();
29
30 /** Functions *************************************************************/
31
32 /**
33 * Add the register_blocks action to bbp_init.
34 *
35 * @since 2.7.0 bbPress (r7382)
36 */
37 public function __construct() {
38 $this->setup_globals();
39 $this->register_blocks();
40 $this->setup_hooks();
41 }
42
43 /**
44 * Block globals.
45 *
46 * @since 2.7.0 bbPress (r7382)
47 */
48 private function setup_globals() {
49
50 // Initialize blocks array (will be populated during registration).
51 $this->blocks = array();
52 }
53
54 /**
55 * Register blocks from block.json files.
56 *
57 * @since 2.7.0 bbPress (r7382)
58 */
59 public function register_blocks() {
60
61 // Bail if no block type functionality.
62 if ( ! function_exists( 'register_block_type' ) ) {
63 return;
64 }
65
66 $blocks_dir = __DIR__ . '/blocks';
67
68 // Bail if blocks directory doesn't exist.
69 if ( ! is_dir( $blocks_dir ) ) {
70 return;
71 }
72
73 // Scan the blocks directory for block.json files.
74 $block_folders = glob( $blocks_dir . '/*', GLOB_ONLYDIR );
75
76 // Bail if no block folders found.
77 if ( empty( $block_folders ) ) {
78 return;
79 }
80
81 // Loop through the folders.
82 foreach ( $block_folders as $block_folder ) {
83 $block_json = $block_folder . '/block.json';
84
85 // Skip if block.json doesn't exist.
86 if ( ! file_exists( $block_json ) ) {
87 continue;
88 }
89
90 // Register the block from block.json.
91 $registered = register_block_type(
92 $block_folder,
93 array(
94 'render_callback' => array( $this, 'render_block' ),
95 )
96 );
97
98 // Add to blocks map for render callback lookup.
99 if ( empty( $registered->name ) ) {
100 continue;
101 }
102
103 // Derive shortcode slug from block name.
104 $shortcode_slug = str_replace( 'bbpress/', 'bbp-', $registered->name );
105 $this->blocks[ $registered->name ] = $shortcode_slug;
106 }
107 }
108
109 /**
110 * Setup actions & filters.
111 *
112 * @since 2.7.0 bbPress (r7382)
113 */
114 private function setup_hooks() {
115
116 // Enqueue and localize block editor scripts.
117 add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) );
118
119 // Register custom block category.
120 add_filter( 'block_categories_all', array( $this, 'register_block_category' ), 10, 2 );
121
122 // Allow plugins to modify these actions
123 do_action_ref_array( 'bbp_blocks_loaded', array( &$this ) );
124 }
125
126 /**
127 * Enqueue block editor assets and localize script data.
128 *
129 * @since 2.7.0 bbPress (r7382)
130 */
131 public function enqueue_block_editor_assets() {
132
133 // Localize script data for the block editor (script is loaded via block.json).
134 wp_localize_script(
135 'bbp-admin-blocks',
136 'bbpBlocksJS',
137 array(
138
139 // Nonce.
140 'ajax_nonce' => wp_create_nonce( 'bbp_blocks' ),
141
142 // Block metadata for registration.
143 'blocks' => self::get_block_metadata(),
144
145 // Block data.
146 'data' => array(
147 'forums' => self::get_localize_script_data( 'forums' ),
148 'views' => self::get_localize_script_data( 'views' ),
149 'tags' => self::get_localize_script_data( 'topic_tags' ),
150 ),
151
152 // Strings.
153 'strings' => array(
154
155 // Select text.
156 'forum_select' => esc_html__( 'Select a Forum', 'bbpress' ),
157 ),
158 )
159 );
160 }
161
162 /**
163 * Get block metadata from block.json files for JavaScript registration.
164 *
165 * @since 2.7.0 bbPress (r7382)
166 *
167 * @return array Array of block metadata objects.
168 */
169 public static function get_block_metadata() {
170 $blocks = array();
171 $blocks_dir = __DIR__ . '/blocks';
172
173 if ( ! is_dir( $blocks_dir ) ) {
174 return $blocks;
175 }
176
177 $block_folders = glob( $blocks_dir . '/*', GLOB_ONLYDIR );
178
179 foreach ( $block_folders as $block_folder ) {
180 $block_json_file = $block_folder . '/block.json';
181
182 if ( ! file_exists( $block_json_file ) ) {
183 continue;
184 }
185
186 $json_content = file_get_contents( $block_json_file ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Reading local block metadata.
187 $block_data = json_decode( $json_content, true );
188
189 if ( $block_data && ! empty( $block_data['name'] ) ) {
190 $blocks[] = $block_data;
191 }
192 }
193
194 return $blocks;
195 }
196
197 /**
198 * Reuse shortcode callbacks to render equivalent block output.
199 *
200 * @since 2.7.0 bbPress (r7382)
201 *
202 * @param array $attributes Block attributes.
203 * @param string|null $content Optional block content.
204 * @param WP_Block $block Parsed block instance, used to find mapping.
205 *
206 * @return string Block output or empty string on failure.
207 */
208 public function render_block( $attributes = array(), $content = '', $block = null ) {
209
210 // Ensure a valid block is provided and mapped to a shortcode.
211 if ( empty( $block ) || empty( $block->name ) || empty( $this->blocks[ $block->name ] ) ) {
212 return '';
213 }
214
215 $shortcode = $this->blocks[ $block->name ];
216 $shortcodes = bbpress()->shortcodes;
217
218 // Bail if the shortcode callable is missing.
219 if ( empty( $shortcodes ) || empty( $shortcodes->codes[ $shortcode ] ) ) {
220 return '';
221 }
222
223 $callback = $shortcodes->codes[ $shortcode ];
224
225 // Invoke the shortcode callback directly for server-side rendering.
226 return call_user_func( $callback, $attributes, $content );
227 }
228
229 /**
230 * Register custom "Forums" block category.
231 *
232 * @since 2.7.0 bbPress (r7382)
233 *
234 * @param array $categories Array of block categories.
235 * @param WP_Block_Editor_Context $context Block editor context.
236 *
237 * @return array Modified categories.
238 */
239 public function register_block_category( $categories, $context ) {
240
241 // Custom bbPress category.
242 $new = array(
243 array(
244 'slug' => 'bbpress',
245 'title' => esc_html__( 'Forums', 'bbpress' ),
246 'icon' => 'buddicons-bbpress-logo',
247 ),
248 );
249
250 // Merge our category with the existing categories.
251 return array_merge( $categories, $new );
252 }
253
254 /**
255 * Get data for localizing to block scripts.
256 *
257 * @since 2.7.0 bbPress (r7382)
258 *
259 * @param string $data Data key to retrieve.
260 * @return array|null Localized data or null when unavailable.
261 */
262 public static function get_localize_script_data( $data = '' ) {
263 switch ( $data ) {
264 case 'forums':
265 $forums = get_pages(
266 array(
267 'post_type' => bbp_get_forum_post_type(),
268 'numberposts' => -1,
269 'post_status' => array(
270 'publish',
271 'private',
272 ),
273 )
274 );
275
276 $return = array(
277 array(
278 'value' => 0,
279 'label' => __( 'Select a Forum', 'bbpress' ),
280 ),
281 );
282
283 foreach ( $forums as $forum ) {
284 $return[] = array(
285 'value' => (int) $forum->ID,
286 'label' => $forum->post_title,
287 );
288 }
289
290 return $return;
291
292 case 'views':
293 $views = bbp_get_views();
294 $return = array(
295 array(
296 'value' => '',
297 'label' => __( 'Select a View', 'bbpress' ),
298 ),
299 );
300
301 if ( ! empty( $views ) ) {
302 foreach ( $views as $view_id => $view ) {
303 $return[] = array(
304 'value' => $view_id,
305 'label' => isset( $view['title'] )
306 ? $view['title']
307 : ucwords( str_replace( '-', ' ', $view_id ) ),
308 );
309 }
310 }
311
312 return $return;
313
314 case 'topic_tags':
315 $terms = get_terms(
316 array(
317 'taxonomy' => bbp_get_topic_tag_tax_id(),
318 'hide_empty' => false,
319 )
320 );
321
322 $return = array(
323 array(
324 'value' => 0,
325 'label' => __( 'Select a Topic Tag', 'bbpress' ),
326 ),
327 );
328
329 if ( ! is_wp_error( $terms ) && ! empty( $terms ) ) {
330 foreach ( $terms as $term ) {
331 $return[] = array(
332 'value' => (int) $term->term_id,
333 'label' => $term->name,
334 );
335 }
336 }
337
338 return $return;
339
340 default:
341 return null;
342 }
343 }
344 }
345 endif;
346