PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 3.2.2
Pods – Custom Content Types and Fields v3.2.2
trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9
pods / src / Pods / Blocks / API.php
pods / src / Pods / Blocks Last commit date
Collections 4 years ago Types 2 years ago API.php 2 years ago Blocks_Abstract.php 2 years ago Blocks_Interface.php 2 years ago Service_Provider.php 3 years ago
API.php
387 lines
1 <?php
2
3 namespace Pods\Blocks;
4
5 use Pods;
6 use Pods\Pod_Manager;
7 use Pods\Whatsit\Block;
8
9 /**
10 * Blocks functionality class.
11 *
12 * @since 2.8.0
13 */
14 class API {
15
16 /**
17 * Register blocks for the Pods Blocks API.
18 *
19 * @since 2.8.0
20 */
21 public function register_blocks() {
22 static $registered = false;
23
24 if ( $registered ) {
25 return;
26 }
27
28 // The 'block_categories' filter has been deprecated in WordPress 5.8+ and replaced by 'block_categories_all'.
29 if ( pods_version_check( 'wp', '5.8-beta0' ) ) {
30 add_filter( 'block_categories_all', [ $this, 'register_block_collections' ] );
31 } else {
32 add_filter( 'block_categories', [ $this, 'register_block_collections' ] );
33 }
34
35 $blocks = $this->get_blocks();
36
37 foreach ( $blocks as $block ) {
38 $block_name = $block['blockName'];
39
40 unset( $block['blockName'], $block['fields'] );
41
42 register_block_type( $block_name, $block );
43 }
44
45 add_action( 'admin_enqueue_scripts', [ $this, 'register_assets' ], 15 );
46
47 $registered = true;
48 }
49
50 /**
51 * @return void
52 */
53 public function register_assets() {
54 $js_blocks = $this->get_js_blocks();
55
56 // The Pods Blocks JS API.
57 $pods_blocks_options_file = file_get_contents( PODS_DIR . 'ui/js/blocks/pods-blocks-api.min.asset.json' );
58
59 $pods_blocks_options = null;
60
61 if ( $pods_blocks_options_file ) {
62 $pods_blocks_options = json_decode( $pods_blocks_options_file, true );
63 }
64
65 if ( ! is_array( $pods_blocks_options ) ) {
66 $pods_blocks_options = [
67 'dependencies' => [],
68 'version' => false,
69 ];
70 }
71
72 wp_register_script( 'pods-blocks-api', PODS_URL . 'ui/js/blocks/pods-blocks-api.min.js', $pods_blocks_options['dependencies'], $pods_blocks_options['version'], true );
73
74 wp_set_script_translations( 'pods-blocks-api', 'pods' );
75
76 $blocks_config = [
77 'blocks' => $js_blocks,
78 'commands' => [],
79 // No custom collections to register directly with JS right now.
80 'collections' => [],
81 ];
82
83 $is_admin = is_admin();
84 $screen = ( $is_admin && function_exists( 'get_current_screen' ) ) ? get_current_screen() : null;
85
86 // Maybe add commands if the person has the right access.
87 if ( $screen && 'post' === $screen->base && $screen->post_type && pods_is_admin( 'pods' ) ) {
88 // Check if this is a Pod or not.
89 $api = pods_api();
90
91 $pod = false;
92
93 try {
94 $pod = $api->load_pod( [
95 'name' => $screen->post_type,
96 'auto_setup' => false,
97 ] );
98
99 // Check if this was auto-setup before and isn't a full pod.
100 if ( $pod && true === $pod->get_arg( 'adhoc' ) ) {
101 $pod = false;
102 }
103 } catch ( \Exception $exception ) {
104 // Nothing to do here.
105 }
106
107 if ( $pod ) {
108 $blocks_config['commands'][] = [
109 'name' => 'pods/edit',
110 'label' => __( 'Edit this Pod configuration', 'pods' ),
111 'searchLabel' => __( 'Edit this Pod configuration > Manage Field Groups, Custom Fields, and other Custom Post Type settings in the Pods Admin', 'pods' ),
112 'icon' => 'pods',
113 'callbackUrl' => admin_url(
114 sprintf(
115 'admin.php?page=pods&action=edit&id=%d',
116 $pod->get_id()
117 )
118 ),
119 ];
120 } else {
121 $nonce = wp_create_nonce( 'pods_extend_post_type_' . $screen->post_type );
122
123 $blocks_config['commands'][] = [
124 'name' => 'pods/extend',
125 'label' => __( 'Extend this Post Type with Pods to add custom fields', 'pods' ),
126 'icon' => 'pods',
127 'callbackUrl' => admin_url(
128 sprintf(
129 'admin.php?page=pods-add-new&pods_extend_post_type=%1$s&pods_extend_post_type_nonce=%2$s',
130 $screen->post_type,
131 $nonce
132 )
133 ),
134 ];
135 }
136 }
137
138 /**
139 * Allow filtering the blocks API config data.
140 *
141 * @since 3.0.0
142 *
143 * @param array $blocks_config The blocks API config data.
144 */
145 $blocks_config = (array) apply_filters( 'pods_blocks_api_config', $blocks_config );
146
147 // Sanitize callbackUrl for security.
148 foreach ( $blocks_config['commands'] as $key => $command ) {
149 $blocks_config['commands'][ $key ]['callbackUrl'] = pods_enforce_safe_url( (string) $command['callbackUrl'] );
150 }
151
152 wp_localize_script( 'pods-blocks-api', 'podsBlocksConfig', $blocks_config );
153
154 wp_enqueue_style( 'pods-styles' );
155 }
156
157 /**
158 * Setup core blocks.
159 *
160 * @since 2.8.0
161 */
162 public function setup_core_blocks() {
163 static $setup = false;
164
165 if ( $setup ) {
166 return;
167 }
168
169 /**
170 * Allow any integrations to be set up before core blocks and collections are called.
171 *
172 * @since 2.8.0
173 */
174 do_action( 'pods_blocks_api_pre_init' );
175
176 pods_container( 'pods.blocks.collection.pods' );
177
178 // Check if the feature is enabled.
179 if ( pods_can_use_dynamic_feature( 'display' ) ) {
180 pods_container( 'pods.blocks.field' );
181 pods_container( 'pods.blocks.list' );
182 pods_container( 'pods.blocks.single' );
183 pods_container( 'pods.blocks.single-list-fields' );
184 }
185
186 // Check if the feature is enabled.
187 if ( pods_can_use_dynamic_feature( 'form' ) ) {
188 pods_container( 'pods.blocks.form' );
189 }
190
191 // Check if the feature is enabled.
192 if ( pods_can_use_dynamic_feature( 'view' ) ) {
193 pods_container( 'pods.blocks.view' );
194 }
195
196 /**
197 * Allow custom blocks to be registered with Pods.
198 *
199 * @since 2.8.0
200 */
201 do_action( 'pods_blocks_api_init' );
202
203 $setup = true;
204 }
205
206 /**
207 * Get list of registered blocks for the Pods Blocks API.
208 *
209 * @since 2.8.0
210 *
211 * @return array List of registered blocks.
212 */
213 public function get_blocks() {
214 $blocks = pods_static_cache_get( __FUNCTION__, __CLASS__ );
215
216 if ( ! empty( $blocks ) && is_array( $blocks ) ) {
217 return $blocks;
218 }
219
220 $this->setup_core_blocks();
221
222 $api = pods_api();
223
224 /**
225 * Allow filtering whether to bypass the post type find queries for blocks.
226 *
227 * @since 2.9.14
228 *
229 * @param bool $bypass_post_type_find Whether to bypass the post type find queries for blocks.
230 */
231 $bypass_post_type_find = apply_filters( 'pods_blocks_api_get_blocks_bypass_post_type_find', true );
232
233 /** @var Block[] $blocks */
234 $blocks = $api->_load_objects( [
235 'object_type' => 'block',
236 'bypass_cache' => true,
237 // Disable DB queries for now.
238 'bypass_post_type_find' => $bypass_post_type_find,
239 ] );
240
241 // Ensure the response is an array.
242 $blocks = array_values( $blocks );
243
244 $blocks = array_map( static function ( $block ) {
245 return $block->get_block_args();
246 }, $blocks );
247
248 pods_static_cache_set( __FUNCTION__, $blocks, __CLASS__ );
249
250 return $blocks;
251 }
252
253 /**
254 * Get list of registered blocks for the Pods Blocks API and prepare them for JavaScript registerBlockType().
255 *
256 * @since 2.8.0
257 *
258 * @return array List of registered blocks prepared for JavaScript registerBlockType().
259 */
260 public function get_js_blocks() {
261 static $js_blocks = [];
262
263 if ( ! empty( $js_blocks ) ) {
264 return $js_blocks;
265 }
266
267 $cached = pods_transient_get( 'pods_blocks_js' );
268
269 if ( is_array( $cached ) ) {
270 return $cached;
271 }
272
273 $blocks = $this->get_blocks();
274
275 foreach ( $blocks as $block_key => $block ) {
276 $js_block = [];
277
278 // Remove render options.
279 unset( $block['render_callback'], $block['render_custom_callback'], $block['render_template'], $block['render_template_path'] );
280
281 // Remove assets options.
282 unset( $block['enqueue_assets'], $block['enqueue_script'], $block['enqueue_style'] );
283
284 foreach ( $block as $key => $value ) {
285 // Prepare the keys as camelCase.
286 $key = pods_js_camelcase_name( $key );
287
288 // Skip if the value is null.
289 if ( null === $value ) {
290 continue;
291 }
292
293 $js_block[ $key ] = $value;
294 }
295
296 if ( ! isset( $js_block['usesContext'] ) ) {
297 $js_block['usesContext'] = [];
298 }
299
300 $js_blocks[ $block_key ] = $js_block;
301 }
302
303 pods_transient_set( 'pods_blocks_js', $js_blocks, DAY_IN_SECONDS * 7 );
304
305 return $js_blocks;
306 }
307
308 /**
309 * Get list of registered block collections for the Pods Blocks API.
310 *
311 * @since 2.8.0
312 *
313 * @return array List of registered block collections.
314 */
315 public function get_block_collections() {
316 static $collections = [];
317
318 if ( ! empty( $collections ) ) {
319 return $collections;
320 }
321
322 $this->setup_core_blocks();
323
324 $api = pods_api();
325
326 /** @var Block_Collection[] $block_collections */
327 $block_collections = $api->_load_objects( [
328 'object_type' => 'block-collection',
329 ] );
330
331 // Ensure the response is an array.
332 $block_collections = array_values( $block_collections );
333
334 $block_collections = array_map( static function ( $block_collection ) {
335 return $block_collection->get_block_collection_args();
336 }, $block_collections );
337
338 return $block_collections;
339 }
340
341 /**
342 * Register block collections by adding them to the list of 'categories'.
343 *
344 * @since 2.8.0
345 *
346 * @param array $collections List of block 'categories' from WordPress.
347 *
348 * @return array List of block 'categories' with custom block collections added.
349 */
350 public function register_block_collections( array $collections ) {
351 $block_collections = $this->get_block_collections();
352
353 if ( empty( $block_collections ) ) {
354 return $collections;
355 }
356
357 foreach ( $block_collections as $collection ) {
358 $collections[] = [
359 'slug' => $collection['namespace'],
360 'title' => $collection['title'],
361 'icon' => $collection['icon'],
362 ];
363 }
364
365 return $collections;
366 }
367
368 /**
369 * Remove our legacy Pods widgets from the Legacy Widget block.
370 *
371 * @since 2.8.0
372 *
373 * @param array $widgets An array of excluded widget-type IDs.
374 *
375 * @return array An array of excluded widget-type IDs.
376 */
377 public function remove_from_legacy_widgets( $widgets ) {
378 $widgets[] = 'pods_widget_field';
379 $widgets[] = 'pods_widget_form';
380 $widgets[] = 'pods_widget_list';
381 $widgets[] = 'pods_widget_single';
382 $widgets[] = 'pods_widget_view';
383
384 return $widgets;
385 }
386 }
387