Completed
Push — master ( 1e5530...3e2977 )
by
unknown
10:33 queued 14s
created

Block_Container::set_inner_blocks_position()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 9
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 9
loc 9
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
namespace Carbon_Fields\Container;
4
5
use Carbon_Fields\Datastore\Datastore;
6
use Carbon_Fields\Helper\Helper;
7
8
class Block_Container extends Container {
9
	/**
10
	 * {@inheritDoc}
11
	 */
12
	public $settings = array(
13
		'preview' => true,
14
		'parent' => null,
15
		'inner_blocks' => array(
16
			'enabled' => false,
17
			'position' => 'above',
18
			'template' => null,
19
			'template_lock' => null,
20
			'allowed_blocks' => null,
21
		),
22
		'category' => array(
23
			'slug' => 'common',
24
		),
25
	);
26
27
	/***
28
	 * Block type render callback.
29
	 *
30
	 * @var callable
31
	 */
32
	protected $render_callback;
33
34
	/**
35
	 * {@inheritDoc}
36
	 */
37 View Code Duplication
	public function __construct( $id, $title, $type, $condition_collection, $condition_translator ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
38
		parent::__construct( $id, $title, $type, $condition_collection, $condition_translator );
39
40
		if ( ! $this->get_datastore() ) {
41
			$this->set_datastore( Datastore::make( 'empty' ), $this->has_default_datastore() );
42
		}
43
	}
44
45
	/**
46
	 * {@inheritDoc}
47
	 */
48
	public function init() {
49
		add_action( 'init', array( $this, '_attach' ) );
50
	}
51
52
	/**
53
	 * {@inheritDoc}
54
	 */
55
	public function is_valid_save() {
56
		// Return false because Gutenberg
57
		// will handle saving.
58
		return false;
59
	}
60
61
	/**
62
	 * {@inheritDoc}
63
	 */
64
	public function save( $data = null ) {
65
		// Nothing to do here because
66
		// the data is saved by Gutenberg.
67
	}
68
69
	/**
70
	 * {@inheritDoc}
71
	 */
72
	protected function get_environment_for_request() {
73
		return array();
74
	}
75
76
	/**
77
	 * {@inheritDoc}
78
	 */
79
	public function is_valid_attach_for_request() {
80
		return function_exists( 'register_block_type' );
81
	}
82
83
	/**
84
	 * {@inheritDoc}
85
	 */
86
	protected function get_environment_for_object( $object_id ) {
87
		return array();
88
	}
89
90
	/**
91
	 * {@inheritDoc}
92
	 */
93
	public function is_valid_attach_for_object( $object_id = null ) {
94
		return function_exists( 'register_block_type' );
95
	}
96
97
	/**
98
	 * {@inheritDoc}
99
	 */
100
	public function attach() {
101
		add_filter( 'block_categories', array( $this, 'attach_block_category' ), 10, 2 );
102
103
		$this->register_block();
104
	}
105
106
	/**
107
	 * Attach the category of the block type.
108
	 *
109
	 * @param  array $categories
110
	 * @return array
111
	 */
112
	public function attach_block_category( $categories ) {
113
		foreach ( $categories as $category ) {
114
			if ( $category[ 'slug' ] === $this->settings[ 'category' ][ 'slug' ] ) {
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
115
				return $categories;
116
			}
117
		}
118
119
		return array_merge( $categories, array( $this->settings[ 'category' ] ) );
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
120
	}
121
122
	/**
123
	 * Set the description of the block type.
124
	 *
125
	 * @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#description-optional
126
	 *
127
	 * @param  string $description
128
	 * @return Block_Container
129
	 */
130
	public function set_description( $description ) {
131
		$this->settings[ 'description' ] = $description;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
132
133
		return $this;
134
	}
135
136
	/**
137
	 * Set the category of the block type.
138
	 *
139
	 * @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#category
140
	 *
141
	 * @param  string $slug
142
	 * @param  string $title
143
	 * @param  string $icon
144
	 * @return Block_Container
145
	 */
146
	public function set_category( $slug, $title = null, $icon = null ) {
147
		$this->settings[ 'category' ][ 'slug' ] = $slug;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
148
		$this->settings[ 'category' ][ 'icon' ] = $icon;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
149
		$this->settings[ 'category' ][ 'title' ] = $title ?: Helper::normalize_label( $slug );
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
150
151
		return $this;
152
	}
153
154
	/**
155
	 * Set the icon of the block type.
156
	 *
157
	 * @see https://developer.wordpress.org/resource/dashicons
158
	 * @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#icon-optional
159
	 *
160
	 * @param  string $icon
161
	 * @return Block_Container
162
	 */
163
	public function set_icon( $icon ) {
164
		$this->settings[ 'icon' ] = $icon;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
165
166
		return $this;
167
	}
168
169
	/**
170
	 * Set the keywords of the block type.
171
	 *
172
	 * @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#keywords-optional
173
	 *
174
	 * @param  array $keywords
175
	 * @return Block_Container
176
	 */
177
	public function set_keywords( $keywords = array() ) {
178
		$this->settings[ 'keywords' ] = array_slice( $keywords, 0, 3 );
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
179
180
		return $this;
181
	}
182
183
	/**
184
	 * Set a style handle.
185
	 *
186
	 * @param  string $key
187
	 * @param  string $handle
188
	 * @return Block_Container
189
	 */
190
	protected function set_style_handle( $key, $handle ) {
191
		if ( ! wp_style_is( $handle ) ) {
192
			throw new \Exception( __( "Style '$handle' is not enqueued.", 'crb' ) );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '"Style '$handle' is not enqueued."'
Loading history...
193
		}
194
195
		$this->settings[ $key ] = $handle;
196
197
		return $this;
198
	}
199
200
	/**
201
	 * Set the style of the block type.
202
	 *
203
	 * @param  string $handle
204
	 * @return Block_Container
205
	 */
206
	public function set_style( $handle ) {
207
		return $this->set_style_handle( 'style', $handle );
208
	}
209
210
	/**
211
	 * Set the editor style of the block type.
212
	 *
213
	 * @param  string $handle
214
	 * @return Block_Container
215
	 */
216
	public function set_editor_style( $handle ) {
217
		return $this->set_style_handle( 'editor_style', $handle );
218
	}
219
220
	/**
221
	 * Set whether the preview mode is available for the block type.
222
	 *
223
	 * @param  boolean $preview
224
	 * @return Block_Container
225
	 */
226
	public function set_preview_mode( $preview = true ) {
227
		$this->settings[ 'preview' ] = $preview;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
228
229
		return $this;
230
	}
231
232
	/**
233
	 * Set the parent block(s) in which the block type can be inserted.
234
	 *
235
	 * @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-registration/#parent-optional
236
	 *
237
	 * @param  string|string[]|null $parent
238
	 * @return Block_Container
239
	 */
240
	public function set_parent( $parent = null ) {
241 View Code Duplication
		if ( ! is_array( $parent ) && ! is_string( $parent ) && ! is_null( $parent ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
242
			throw new \Exception( __( "The parent must be 'array', 'string' or 'null'.", 'crb' ) );
243
		}
244
245
		$this->settings[ 'parent' ] = is_string( $parent ) ? array( $parent ) : $parent;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
246
247
		return $this;
248
	}
249
250
	/**
251
	 * Set whether the inner blocks are available for the block type.
252
	 *
253
	 * @param  boolean $inner_blocks
254
	 * @return Block_Container
255
	 */
256
	public function set_inner_blocks( $inner_blocks = true ) {
257
		$this->settings[ 'inner_blocks' ][ 'enabled' ] = $inner_blocks;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
258
259
		return $this;
260
	}
261
262
	/**
263
	 * Set the position of the inner blocks to be rendered
264
	 * above or below the fields.
265
	 *
266
	 * @param  string $position
267
	 * @return Block_Container
268
	 */
269 View Code Duplication
	public function set_inner_blocks_position( $position = 'above' ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
270
		if ( ! in_array( $position, [ 'above', 'below' ] ) ) {
271
			throw new \Exception( __( "The position of inner blocks must be 'above' or 'below'.", 'crb' ) );
272
		}
273
274
		$this->settings[ 'inner_blocks' ][ 'position' ] = $position;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
275
276
		return $this;
277
	}
278
279
	/**
280
	 * Set the default template that should be rendered in inner blocks.
281
	 *
282
	 * @see https://github.com/WordPress/gutenberg/tree/master/packages/editor/src/components/inner-blocks#template
283
	 *
284
	 * @param  array[]|null $template
285
	 * @return Block_Container
286
	 */
287
	public function set_inner_blocks_template( $template = null ) {
288 View Code Duplication
		if ( ! is_array( $template ) && ! is_null( $template ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
289
			throw new \Exception( __( "The template must be an 'array' or 'null'.", 'crb' ) );
290
		}
291
292
		$this->settings[ 'inner_blocks' ][ 'template' ] = $template;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
293
294
		return $this;
295
	}
296
297
	/**
298
	 * Set the lock mode used by template of inner blocks.
299
	 *
300
	 * @see https://github.com/WordPress/gutenberg/tree/master/packages/editor/src/components/inner-blocks#templatelock
301
	 *
302
	 * @param  string|boolean|null $lock
303
	 * @return Block_Container
304
	 */
305 View Code Duplication
	public function set_inner_blocks_template_lock( $lock = null ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
306
		if ( is_string( $lock ) && ! in_array( $lock, [ 'all', 'insert' ] ) ) {
307
			throw new \Exception( __( "The template lock must be 'all', 'insert', 'false' or 'null'.", 'crb' ) );
308
		}
309
310
		$this->settings[ 'inner_blocks' ][ 'template_lock' ] = $lock;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
311
312
		return $this;
313
	}
314
315
	/**
316
	 * Set the list of allowed blocks that can be inserted.
317
	 *
318
	 * @see https://github.com/WordPress/gutenberg/tree/master/packages/editor/src/components/inner-blocks#allowedblocks
319
	 *
320
	 * @param  string[]|null $blocks
321
	 * @return Block_Container
322
	 */
323
	public function set_allowed_inner_blocks( $blocks = null ) {
324 View Code Duplication
		if ( ! is_array( $blocks ) && ! is_null( $blocks ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
325
			throw new \Exception( __( "The allowed blocks must be an 'array' or 'null'.", 'crb' ) );
326
		}
327
328
		if ( is_array( $blocks ) ) {
329
			$this->settings[ 'inner_blocks' ][ 'allowed_blocks' ] = array_map( function ( $block ) {
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
330
				if ( $block instanceof self ) {
331
					return $block->get_block_type_name();
332
				}
333
334
				return $block;
335
			}, $blocks );
336
		} else {
337
			$this->settings[ 'inner_blocks' ][ 'allowed_blocks' ] = $blocks;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
338
		}
339
340
		return $this;
341
	}
342
343
	/**
344
	 * Set the render callback of the block type.
345
	 *
346
	 * @see https://wordpress.org/gutenberg/handbook/designers-developers/developers/tutorials/block-tutorial/creating-dynamic-blocks/
347
	 *
348
	 * @param  callable $render_callback
349
	 * @return Block_Container
350
	 */
351
	public function set_render_callback( $render_callback ) {
352
		$this->render_callback = $render_callback;
353
354
		return $this;
355
	}
356
357
	/**
358
	 * Render the block type.
359
	 *
360
	 * @param  array  $attributes
361
	 * @param  string $content
362
	 * @return string
363
	 */
364
	public function render_block( $attributes, $content ) {
365
		$fields = $attributes['data'];
366
367
		// Unset the "data" property because we
368
		// pass it as separate argument to the callback.
369
		unset($attributes['data']);
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
370
371
		ob_start();
372
373
		call_user_func( $this->render_callback , $fields, $attributes, $content );
374
375
		return ob_get_clean();
376
	}
377
378
	/**
379
	 * Returns the block type name, e.g. "carbon-fields/testimonial"
380
	 */
381
	private function get_block_type_name() {
382
		return str_replace( 'carbon-fields-container-', 'carbon-fields/', str_replace( '_', '-', $this->id ) );
383
	}
384
385
	/**
386
	 * Register the block type.
387
	 *
388
	 * @return void
389
	 */
390
	protected function register_block() {
391
		if ( is_null( $this->render_callback ) ) {
392
			throw new \Exception( __( "'render_callback' is required for the blocks.", 'crb' ) );
393
		}
394
395
		if ( ! is_callable( $this->render_callback ) ) {
396
			throw new \Exception( __( "'render_callback' must be a callable.", 'crb' ) );
397
		}
398
399
		$style = isset( $this->settings[ 'style' ] ) ? $this->settings[ 'style' ] : null;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
400
		$editor_style = isset( $this->settings[ 'editor_style' ] ) ? $this->settings[ 'editor_style' ] : null;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
401
		$attributes = array_reduce( $this->get_fields(), function( $attributes, $field ) {
402
			$attributes[ 'data' ][ 'default' ][ $field->get_base_name() ] = $field->get_default_value();
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
403
404
			return $attributes;
405
		}, array(
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 12 spaces, but found 8.
Loading history...
406
			'data' => array(
407
				'type' => 'object',
408
				'default' => array(),
409
			),
410
		) );
411
412
		register_block_type( $this->get_block_type_name(), array(
413
			'style' => $style,
414
			'editor_style' => $editor_style,
415
			'attributes' => $attributes,
416
			'render_callback' => array( $this, 'render_block' ),
417
		) );
418
	}
419
}
420