PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 3.3.4
Pods – Custom Content Types and Fields v3.3.4
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 11 months ago API.php 1 year ago Blocks_Abstract.php 2 years ago Blocks_Interface.php 3 years ago Service_Provider.php 1 year ago
API.php
409 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 'panelsToDisable' => [],
80 // No custom collections to register directly with JS right now.
81 'collections' => [],
82 ];
83
84 $is_admin = is_admin();
85 $screen = ( $is_admin && function_exists( 'get_current_screen' ) ) ? get_current_screen() : null;
86
87 if ( $screen && 'post' === $screen->base && $screen->post_type ) {
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 instanceof Pods\Whatsit\Pod ) {
108 // Check if we need to disable any specific taxonomies.
109 $taxonomy_sync_fields = $pod->get_fields( [
110 'type' => 'pick',
111 'args' => [
112 'pick_object' => 'taxonomy',
113 'pick_sync_taxonomy' => 1,
114 'pick_sync_taxonomy_hide_taxonomy_ui' => 1,
115 ],
116 ] );
117
118 foreach ( $taxonomy_sync_fields as $taxonomy_sync_field ) {
119 $taxonomy_name = $taxonomy_sync_field->get_related_object_name();
120
121 if ( $taxonomy_name ) {
122 $blocks_config['panelsToDisable'][] = 'taxonomy-panel-' . $taxonomy_name;
123 }
124 }
125
126 // Maybe add commands if the person has the right access.
127 if ( pods_is_admin( 'pods' ) ) {
128 $blocks_config['commands'][] = [
129 'name' => 'pods/edit',
130 'label' => __( 'Edit this Pod configuration', 'pods' ),
131 'searchLabel' => __( 'Edit this Pod configuration > Manage Field Groups, Custom Fields, and other Custom Post Type settings in the Pods Admin', 'pods' ),
132 'icon' => 'pods',
133 'callbackUrl' => admin_url(
134 sprintf(
135 'admin.php?page=pods&action=edit&id=%d',
136 $pod->get_id()
137 )
138 ),
139 ];
140 } else {
141 $nonce = wp_create_nonce( 'pods_extend_post_type_' . $screen->post_type );
142
143 $blocks_config['commands'][] = [
144 'name' => 'pods/extend',
145 'label' => __( 'Extend this Post Type with Pods to add custom fields', 'pods' ),
146 'icon' => 'pods',
147 'callbackUrl' => admin_url(
148 sprintf(
149 'admin.php?page=pods-add-new&pods_extend_post_type=%1$s&pods_extend_post_type_nonce=%2$s',
150 $screen->post_type,
151 $nonce
152 )
153 ),
154 ];
155 }
156 }
157 }
158
159 /**
160 * Allow filtering the blocks API config data.
161 *
162 * @since 3.0.0
163 *
164 * @param array $blocks_config The blocks API config data.
165 */
166 $blocks_config = (array) apply_filters( 'pods_blocks_api_config', $blocks_config );
167
168 // Sanitize callbackUrl for security.
169 foreach ( $blocks_config['commands'] as $key => $command ) {
170 $blocks_config['commands'][ $key ]['callbackUrl'] = pods_enforce_safe_url( (string) $command['callbackUrl'] );
171 }
172
173 wp_localize_script( 'pods-blocks-api', 'podsBlocksConfig', $blocks_config );
174
175 wp_enqueue_style( 'pods-styles' );
176 }
177
178 /**
179 * Setup core blocks.
180 *
181 * @since 2.8.0
182 */
183 public function setup_core_blocks() {
184 static $setup = false;
185
186 if ( $setup ) {
187 return;
188 }
189
190 /**
191 * Allow any integrations to be set up before core blocks and collections are called.
192 *
193 * @since 2.8.0
194 */
195 do_action( 'pods_blocks_api_pre_init' );
196
197 pods_container( 'pods.blocks.collection.pods' );
198
199 // Check if the feature is enabled.
200 if ( pods_can_use_dynamic_feature( 'display' ) ) {
201 pods_container( 'pods.blocks.field' );
202 pods_container( 'pods.blocks.list' );
203 pods_container( 'pods.blocks.related-list' );
204 pods_container( 'pods.blocks.single' );
205 pods_container( 'pods.blocks.single-list-fields' );
206 }
207
208 // Check if the feature is enabled.
209 if ( pods_can_use_dynamic_feature( 'form' ) ) {
210 pods_container( 'pods.blocks.form' );
211 }
212
213 // Check if the feature is enabled.
214 if ( pods_can_use_dynamic_feature( 'view' ) ) {
215 pods_container( 'pods.blocks.view' );
216 }
217
218 /**
219 * Allow custom blocks to be registered with Pods.
220 *
221 * @since 2.8.0
222 */
223 do_action( 'pods_blocks_api_init' );
224
225 $setup = true;
226 }
227
228 /**
229 * Get list of registered blocks for the Pods Blocks API.
230 *
231 * @since 2.8.0
232 *
233 * @return array List of registered blocks.
234 */
235 public function get_blocks() {
236 $blocks = pods_static_cache_get( __FUNCTION__, __CLASS__ );
237
238 if ( ! empty( $blocks ) && is_array( $blocks ) ) {
239 return $blocks;
240 }
241
242 $this->setup_core_blocks();
243
244 $api = pods_api();
245
246 /**
247 * Allow filtering whether to bypass the post type find queries for blocks.
248 *
249 * @since 2.9.14
250 *
251 * @param bool $bypass_post_type_find Whether to bypass the post type find queries for blocks.
252 */
253 $bypass_post_type_find = apply_filters( 'pods_blocks_api_get_blocks_bypass_post_type_find', true );
254
255 /** @var Block[] $blocks */
256 $blocks = $api->_load_objects( [
257 'object_type' => 'block',
258 'bypass_cache' => true,
259 // Disable DB queries for now.
260 'bypass_post_type_find' => $bypass_post_type_find,
261 ] );
262
263 // Ensure the response is an array.
264 $blocks = array_values( $blocks );
265
266 $blocks = array_map( static function ( $block ) {
267 return $block->get_block_args();
268 }, $blocks );
269
270 pods_static_cache_set( __FUNCTION__, $blocks, __CLASS__ );
271
272 return $blocks;
273 }
274
275 /**
276 * Get list of registered blocks for the Pods Blocks API and prepare them for JavaScript registerBlockType().
277 *
278 * @since 2.8.0
279 *
280 * @return array List of registered blocks prepared for JavaScript registerBlockType().
281 */
282 public function get_js_blocks() {
283 static $js_blocks = [];
284
285 if ( ! empty( $js_blocks ) ) {
286 return $js_blocks;
287 }
288
289 $cached = pods_transient_get( 'pods_blocks_js' );
290
291 if ( is_array( $cached ) ) {
292 return $cached;
293 }
294
295 $blocks = $this->get_blocks();
296
297 foreach ( $blocks as $block_key => $block ) {
298 $js_block = [];
299
300 // Remove render options.
301 unset( $block['render_callback'], $block['render_custom_callback'], $block['render_template'], $block['render_template_path'] );
302
303 // Remove assets options.
304 unset( $block['enqueue_assets'], $block['enqueue_script'], $block['enqueue_style'] );
305
306 foreach ( $block as $key => $value ) {
307 // Prepare the keys as camelCase.
308 $key = pods_js_camelcase_name( $key );
309
310 // Skip if the value is null.
311 if ( null === $value ) {
312 continue;
313 }
314
315 $js_block[ $key ] = $value;
316 }
317
318 if ( ! isset( $js_block['usesContext'] ) ) {
319 $js_block['usesContext'] = [];
320 }
321
322 $js_blocks[ $block_key ] = $js_block;
323 }
324
325 pods_transient_set( 'pods_blocks_js', $js_blocks, DAY_IN_SECONDS * 7 );
326
327 return $js_blocks;
328 }
329
330 /**
331 * Get list of registered block collections for the Pods Blocks API.
332 *
333 * @since 2.8.0
334 *
335 * @return array List of registered block collections.
336 */
337 public function get_block_collections() {
338 static $collections = [];
339
340 if ( ! empty( $collections ) ) {
341 return $collections;
342 }
343
344 $this->setup_core_blocks();
345
346 $api = pods_api();
347
348 /** @var Block_Collection[] $block_collections */
349 $block_collections = $api->_load_objects( [
350 'object_type' => 'block-collection',
351 ] );
352
353 // Ensure the response is an array.
354 $block_collections = array_values( $block_collections );
355
356 $block_collections = array_map( static function ( $block_collection ) {
357 return $block_collection->get_block_collection_args();
358 }, $block_collections );
359
360 return $block_collections;
361 }
362
363 /**
364 * Register block collections by adding them to the list of 'categories'.
365 *
366 * @since 2.8.0
367 *
368 * @param array $collections List of block 'categories' from WordPress.
369 *
370 * @return array List of block 'categories' with custom block collections added.
371 */
372 public function register_block_collections( array $collections ) {
373 $block_collections = $this->get_block_collections();
374
375 if ( empty( $block_collections ) ) {
376 return $collections;
377 }
378
379 foreach ( $block_collections as $collection ) {
380 $collections[] = [
381 'slug' => $collection['namespace'],
382 'title' => $collection['title'],
383 'icon' => $collection['icon'],
384 ];
385 }
386
387 return $collections;
388 }
389
390 /**
391 * Remove our legacy Pods widgets from the Legacy Widget block.
392 *
393 * @since 2.8.0
394 *
395 * @param array $widgets An array of excluded widget-type IDs.
396 *
397 * @return array An array of excluded widget-type IDs.
398 */
399 public function remove_from_legacy_widgets( $widgets ) {
400 $widgets[] = 'pods_widget_field';
401 $widgets[] = 'pods_widget_form';
402 $widgets[] = 'pods_widget_list';
403 $widgets[] = 'pods_widget_single';
404 $widgets[] = 'pods_widget_view';
405
406 return $widgets;
407 }
408 }
409