This repository has been archived by the owner on Nov 6, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 63
/
helpers.php
391 lines (332 loc) · 11 KB
/
helpers.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
<?php
/**
* Helper functions.
*
* @package Block_Lab
* @copyright Copyright(c) 2020, Block Lab
* @license http://opensource.org/licenses/GPL-2.0 GNU General Public License, version 2 (GPL-2.0)
*/
use Block_Lab\Blocks;
/**
* Return the value of a block field.
*
* @param string $name The name of the field.
* @param bool $echo Whether to echo and return the field, or just return the field.
*
* @return mixed
*/
function block_field( $name, $echo = true ) {
$attributes = block_lab()->loader->get_data( 'attributes' );
if ( ! $attributes ) {
return null;
}
$config = block_lab()->loader->get_data( 'config' );
if ( ! $config ) {
return null;
}
$default_fields = [ 'className' => 'string' ];
/**
* Filters the default fields that are allowed in addition to Block Lab fields.
*
* Adding an attribute to this can enable outputting it via block_field().
* Normally, this function only returns or echoes Block Lab attributes (fields), and one default field.
* But this allows getting block attributes that might have been added by other plugins or JS.
* To allow getting another attribute, add it to the $default_fields associative array.
* For example, 'your-example-field' => 'array'.
*
* @param array $default_fields An associative array of $field_name => $field_type.
* @param string $name The name of value to get.
*/
$default_fields = apply_filters( 'block_lab_default_fields', $default_fields, $name );
if ( ! isset( $config->fields[ $name ] ) && ! isset( $default_fields[ $name ] ) ) {
return null;
}
$field = null;
$value = false; // This is a good default, it allows us to pick up on unchecked checkboxes.
$control = null;
if ( array_key_exists( $name, $attributes ) ) {
$value = $attributes[ $name ];
}
if ( isset( $config->fields[ $name ] ) ) {
// Cast the value with the correct type.
$field = $config->fields[ $name ];
$value = $field->cast_value( $value );
$control = $field->control;
} elseif ( isset( $default_fields[ $name ] ) ) {
// Cast default Editor attributes and those added via a filter.
$field = new Blocks\Field( [ 'type' => $default_fields[ $name ] ] );
$value = $field->cast_value( $value );
}
/**
* Filters the value to be made available or echoed on the front-end template.
*
* @param mixed $value The value.
* @param string|null $control The type of the control, like 'user', or null if this is the 'className', which has no control.
* @param bool $echo Whether or not this value will be echoed.
*/
$value = apply_filters( 'block_lab_field_value', $value, $control, $echo );
if ( $echo ) {
if ( $field ) {
$value = $field->cast_value_to_string( $value );
}
/*
* Escaping this value may cause it to break in some use cases.
* If this happens, retrieve the field's value using block_value(),
* and then output the field with a more suitable escaping function.
*/
echo wp_kses_post( $value );
return null;
}
return $value;
}
/**
* Return the value of a block field, without echoing it.
*
* @param string $name The name of the field as created in the UI.
*
* @uses block_field()
*
* @return mixed
*/
function block_value( $name ) {
return block_field( $name, false );
}
/**
* Prepare a loop with the first or next row in a repeater.
*
* @param string $name The name of the repeater field.
*
* @return int
*/
function block_row( $name ) {
block_lab()->loop()->set_active( $name );
return block_lab()->loop()->increment( $name );
}
/**
* Determine whether another repeater row exists to loop through.
*
* @param string $name The name of the repeater field.
*
* @return bool
*/
function block_rows( $name ) {
$attributes = block_lab()->loader->get_data( 'attributes' );
if ( ! isset( $attributes[ $name ] ) ) {
return false;
}
$current_row = block_lab()->loop()->get_row( $name );
if ( false === $current_row ) {
$next_row = 0;
} else {
$next_row = $current_row + 1;
}
if ( isset( $attributes[ $name ]['rows'][ $next_row ] ) ) {
return true;
}
return false;
}
/**
* Resets the repeater block rows after the while loop.
*
* Similar to wp_reset_postdata(). Call this after the repeater loop.
* For example:
*
* while ( block_rows( 'example-repeater-name' ) ) :
* block_row( 'example-repeater-name' );
* block_sub_field( 'example-field' );
* endwhile;
* reset_block_rows( 'example-repeater-name' );
*
* @param string $name The name of the repeater field.
*/
function reset_block_rows( $name ) {
block_lab()->loop()->reset( $name );
}
/**
* Return the total amount of rows in a repeater.
*
* @param string $name The name of the repeater field.
* @return int|bool The total amount of rows. False if the repeater isn't found.
*/
function block_row_count( $name ) {
$attributes = block_lab()->loader->get_data( 'attributes' );
if ( ! isset( $attributes[ $name ]['rows'] ) ) {
return false;
}
return count( $attributes[ $name ]['rows'] );
}
/**
* Return the index of the current repeater row.
*
* Note: The index is zero-based, which means that the first row in a repeater has
* an index of 0, the second row has an index of 1, and so on.
*
* @param string $name (Optional) The name of the repeater field.
* @return int|bool The index of the row. False if the repeater isn't found.
*/
function block_row_index( $name = '' ) {
if ( '' === $name ) {
$name = block_lab()->loop()->active;
}
if ( ! isset( block_lab()->loop()->loops[ $name ] ) ) {
return false;
}
return block_lab()->loop()->loops[ $name ];
}
/**
* Return the value of a sub-field.
*
* @param string $name The name of the sub-field.
* @param bool $echo Whether to echo and return the field, or just return the field.
*
* @return mixed
*/
function block_sub_field( $name, $echo = true ) {
$attributes = block_lab()->loader->get_data( 'attributes' );
if ( ! is_array( $attributes ) ) {
return null;
}
$config = block_lab()->loader->get_data( 'config' );
if ( ! $config ) {
return null;
}
$parent = block_lab()->loop()->active;
$pointer = block_lab()->loop()->get_row( $parent );
if ( ! isset( $config->fields[ $parent ] ) ) {
return null;
}
$value = false; // This is a good default, it allows us to pick up on unchecked checkboxes.
$control = null;
// Get the value from the block attributes, with the correct type.
if ( ! array_key_exists( $parent, $attributes ) || ! isset( $attributes[ $parent ]['rows'] ) ) {
return;
}
$parent_attributes = $attributes[ $parent ]['rows'];
$row_attributes = $parent_attributes[ $pointer ];
if ( ! array_key_exists( $name, $row_attributes ) ) {
return;
}
$field = $config->fields[ $parent ]->settings['sub_fields'][ $name ];
$control = $field->control;
$value = $row_attributes[ $name ];
$value = $field->cast_value( $value );
/**
* Filters the value to be made available or echoed on the front-end template.
*
* @param mixed $value The value.
* @param string|null $control The type of the control, like 'user', or null if this is the 'className', which has no control.
* @param bool $echo Whether or not this value will be echoed.
*/
$value = apply_filters( 'block_lab_sub_field_value', $value, $control, $echo );
if ( $echo ) {
$value = $field->cast_value_to_string( $value );
/*
* Escaping this value may cause it to break in some use cases.
* If this happens, retrieve the field's value using block_value(),
* and then output the field with a more suitable escaping function.
*/
echo wp_kses_post( $value );
}
return $value;
}
/**
* Return the value of a sub-field, without echoing it.
*
* @param string $name The name of the sub-field.
*
* @uses block_field()
*
* @return mixed
*/
function block_sub_value( $name ) {
return block_sub_field( $name, false );
}
/**
* Convenience method to return the block configuration.
*
* @return array
*/
function block_config() {
$config = block_lab()->loader->get_data( 'config' );
if ( ! $config ) {
return null;
}
return (array) $config;
}
/**
* Convenience method to return a field's configuration.
*
* @param string $name The name of the field as created in the UI.
*
* @return array|null
*/
function block_field_config( $name ) {
$config = block_lab()->loader->get_data( 'config' );
if ( ! $config || ! isset( $config->fields[ $name ] ) ) {
return null;
}
return (array) $config->fields[ $name ];
}
/**
* Add a new block.
*
* @param string $block_name The block name (slug), like 'example-block'.
* @param array $block_config {
* An associative array containing the block configuration.
*
* @type string $title The block title.
* @type string $icon The block icon. See assets/icons.json for a JSON array of all possible values. Default: 'block_lab'.
* @type string $category The slug of a registered category. Categories include: common, formatting, layout, widgets, embed. Default: 'common'.
* @type array $excluded Exclude the block in these post types. Default: [].
* @type string[] $keywords An array of up to three keywords. Default: [].
* @type array $fields {
* An associative array containing block fields. Each key in the array should be the field slug.
*
* @type array {$slug} {
* An associative array describing a field. Refer to the $field_config parameter of block_lab_add_field().
* }
* }
* }
*/
function block_lab_add_block( $block_name, $block_config = [] ) {
$block_config['name'] = str_replace( '_', '-', sanitize_title( $block_name ) );
$default_config = [
'title' => str_replace( '-', ' ', ucwords( $block_config['name'], '-' ) ),
'icon' => 'block_lab',
'category' => 'common',
'excluded' => [],
'keywords' => [],
'fields' => [],
];
$block_config = wp_parse_args( $block_config, $default_config );
block_lab()->loader->add_block( $block_config );
}
/**
* Add a field to a block.
*
* @param string $block_name The block name (slug), like 'example-block'.
* @param string $field_name The field name (slug), like 'first-name'.
* @param array $field_config {
* An associative array containing the field configuration.
*
* @type string $name The field name.
* @type string $label The field label.
* @type string $control The field control type. Default: 'text'.
* @type int $order The order that the field appears in. Default: 0.
* @type array $settings {
* An associative array of settings for the field. Each field has a different set of possible settings.
* Check the register_settings method for the field, found in php/blocks/controls/class-{field name}.php.
* }
* }
*/
function block_lab_add_field( $block_name, $field_name, $field_config = [] ) {
$field_config['name'] = str_replace( '_', '-', sanitize_title( $field_name ) );
$default_config = [
'label' => str_replace( '-', ' ', ucwords( $field_config['name'], '-' ) ),
'control' => 'text',
'order' => 0,
'settings' => [],
];
$field_config = wp_parse_args( $field_config, $default_config );
block_lab()->loader->add_field( $block_name, $field_config );
}