PluginProbe ʕ •ᴥ•ʔ
Kubio AI Page Builder / 2.9.1
Kubio AI Page Builder v2.9.1
2.9.1 2.9.0 2.8.6 2.8.5 2.8.4 2.8.3 2.8.2 2.8.1 trunk 1.0.0 1.0.1 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.9.0 2.0.0 2.1.1 2.1.2 2.1.3 2.2.0 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.5 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1 2.6.2 2.6.3 2.6.5 2.6.6 2.6.7 2.7.0 2.7.1 2.7.2 2.7.3 2.8.0
kubio / lib / src / Core / Blocks / BlockBase.php
kubio / lib / src / Core / Blocks Last commit date
Query 1 year ago BlockBase.php 2 weeks ago BlockContainerBase.php 1 year ago BlockElement.php 3 years ago BlockStyle.php 4 years ago DataHelper.php 1 year ago TemplatePartBlockBase.php 1 year ago
BlockBase.php
440 lines
1 <?php
2
3 namespace Kubio\Core\Blocks;
4
5 use Exception;
6 use Kubio\Config;
7 use Kubio\Core\LodashBasic;
8 use Kubio\Core\Registry;
9 use Kubio\Core\StyleManager\BlockStyleRender;
10 use Kubio\Core\StyleManager\StyleManager;
11 use IlluminateAgnostic\Arr\Support\Arr;
12 use Kubio\Core\Utils;
13 use WP_Block_Type_Registry;
14
15 /**
16 * @package Kubio\Core\Blocks
17 *
18 * @method serverSideRender( string $wp_block )
19 *
20 */
21 class BlockBase extends DataHelper {
22
23 public $block_data = null;
24 public $block_type = null;
25 public $parent_block_ = null;
26 public $block_context = null;
27
28 public $elements = array();
29 public $styledElementsByName = array();
30 private $defaultElement;
31
32 private $local_id = null;
33
34
35 private $mapped_props_with_defaults = null;
36
37 public function __construct( $block, $autoload = true, $context = array() ) {
38 $this->block_context = $context;
39 $this->block_data = $block;
40 $this->block_type = WP_Block_Type_Registry::get_instance()->get_registered(
41 $block['blockName']
42 );
43
44 $this->styledElementsByName = $this->getBlockStyledElementsByName();
45 $this->defaultElement = $this->getDefaultElement();
46
47 if ( ! $this->defaultElement ) {
48 throw new Exception(
49 // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
50 "Kubio \"{$block['name']}\" has no default element defined"
51 );
52 }
53
54 $attributesDefinitions = $this->block_type->attributes;
55 $attributesDefaults = LodashBasic::mapValues(
56 $attributesDefinitions,
57 'default'
58 );
59 $attributesValues = LodashBasic::get( $this->block_data, 'attrs' );
60
61 parent::__construct(
62 $this->getBlockSupport( 'default' ),
63 LodashBasic::mergeSkipSeqArray(
64 $attributesDefaults,
65 $attributesValues
66 )
67 );
68
69 if ( $autoload ) {
70 $this->create();
71 }
72
73 $this->local_id = Utils::uniqueId();
74 }
75
76 public function localId() {
77 return $this->local_id;
78 }
79
80 public function getBlockStyledElementsByName() {
81 $styledElementsByName = $this->getBlockSupport( Config::$elementsKey );
82 // allow empty elements to be skiped in elementsEnum//
83 $allElements = $this->getBlockSupport( Config::$elementsEnum );
84 foreach ( $allElements as $elementName ) {
85 if ( ! isset( $styledElementsByName[ $elementName ] ) ) {
86 $styledElementsByName[ $elementName ] = array();
87 }
88 }
89
90 return $styledElementsByName;
91 }
92
93 public function getBlockSupport( $path, $default = null ) {
94 return LodashBasic::get(
95 $this->block_type->supports,
96 Config::$mainAttributeKey . '.' . $path,
97 $default
98 );
99 }
100
101 public function getDefaultElement() {
102 if ( ! $this->defaultElement ) {
103 $this->defaultElement = $this->findElementBy(
104 'default',
105 true,
106 false
107 );
108 }
109
110 return $this->defaultElement;
111 }
112
113 public function getLinkAttribute() {
114 return $this->getAttribute( 'link', null );
115 }
116
117 public function findElementBy( $path, $value, $fallbackToDefault = true ) {
118 $elements = $this->styledElementsByName;
119
120 foreach ( (array) $elements as $name => $element ) {
121 if ( LodashBasic::get( $element, $path ) === $value ) {
122 return $name;
123 }
124 }
125
126 if ( $fallbackToDefault ) {
127 return $this->defaultElement;
128 }
129 }
130
131 public function create() {
132 $template = $this->getBlockSupport( 'template', null );
133 if ( ! $template ) {
134 $template = array(
135 'type' => 'element',
136 );
137 }
138
139 $this->createFromJson( $template );
140 }
141
142 public function createFromJson( $element ) {
143 $wrapper_element = $this->getWrapperElementName();
144 $this->elements[0] = $this->toElement( $element, $wrapper_element );
145 }
146
147
148 public function getWrapperElementName() {
149 return $this->findElementBy( 'wrapper', true, true );
150 }
151 public function toElement( $element, $wrapper_element, $level = 0 ) {
152 $children = array();
153 if ( isset( $element['children'] ) ) {
154 foreach ( $element['children'] as $child ) {
155 $children[] = $this->toElement(
156 $child,
157 $wrapper_element,
158 $level + 1
159 );
160 }
161 }
162
163 $element_name = LodashBasic::get( $element, 'props.name', null );
164 $props = LodashBasic::get( $element, 'props', array() );
165
166 $has_data_debug_attribute = apply_filters( 'kubio/blocks/element_add_data_debug_attribute', Utils::isDebug() );
167 $is_wrapper = $element_name === $wrapper_element;
168 if ( $is_wrapper ) {
169 $props = LodashBasic::merge(
170 array_merge(
171 array(
172 'className' => array(
173 'wp-block',
174 $this->blockClass(),
175 implode( ' ', $this->getAppliedMigrationsClasses() ),
176 ),
177 'data-kubio' => $this->block_data['blockName'],
178 ),
179 $has_data_debug_attribute ? array( 'data-debug' => json_encode( $this->block_data ) ) : array() // add data-debug attribute
180 ),
181 $props
182 );
183
184 $hidden = $this->getPropByMedia(
185 'isHidden',
186 false,
187 array(
188 'fromRoot' => true,
189 )
190 );
191
192 foreach ( $hidden as $media => $is_hidden ) {
193 if ( $is_hidden ) {
194 $props['className'] = array_merge(
195 isset( $props['className'] )
196 ? Arr::wrap( $props['className'] )
197 : array(),
198 array( "kubio-hide-on-{$media}" )
199 );
200 } else {
201 $appearanceEffect = $this->getAttribute( 'appearanceEffect' );
202 if ( $appearanceEffect && $appearanceEffect !== 'none' ) {
203 $props = LodashBasic::merge( array( 'data-kubio-aos' => $appearanceEffect ), $props );
204 }
205 }
206 }
207 }
208
209 $element = $this->createElement( $element['type'], $props, $children );
210
211 return $element;
212 }
213
214 public function getAppliedMigrations() {
215 return $this->getAttribute( 'kubio.migrations', array() );
216 }
217
218 public function getAppliedMigrationsClasses() {
219 $result = array();
220
221 $migrations = $this->getAppliedMigrations();
222 foreach ( $migrations as $migration_id ) {
223 $result[] = "kubio-migration--{$migration_id}";
224 }
225
226 return $result;
227 }
228
229 public function blockClass() {
230 return 'wp-block-' . $this->kebabBlockName();
231 }
232
233 public function kebabBlockName() {
234 return LodashBasic::kebabCase( str_replace( '/', '-', $this->name() ) );
235 }
236
237 public function name() {
238 return $this->block_type->name;
239 }
240
241 public function createElement( $type, $props, $children ) {
242 return Registry::getInstance()->createElement(
243 $type,
244 $props,
245 $children,
246 $this
247 );
248 }
249
250
251 public function elementClass( $element ) {
252 return 'wp-block-' . $this->kebabBlockName() . '__' . $element;
253 }
254
255 public function getStyledElementConfig( $name, $path = '', $defaultValue = null ) {
256 return LodashBasic::get( $this->styledElementsByName, array( $name, $path ), $defaultValue );
257 }
258
259 public function getLocalIdClass( $styledComponentName ) {
260 $localId = $this->localId();
261 $stylePrefix = apply_filters( 'kubio/element-style-class-prefix', 'style-' );
262 $stylePrefix = "{$stylePrefix}local-";
263 $localStyleClass = "{$stylePrefix}{$localId}-{$styledComponentName}";
264 return $localStyleClass;
265 }
266
267 public function render( $wp_block ) {
268 $this->parent_block_ = Registry::getInstance()->getParentBlock();
269 $content = '';
270 if ( $this->canRender() ) {
271
272 if ( $this->canRegisterStyle() ) {
273 $this->registerStyle();
274 }
275
276 $content = $this->elements[0] . '';
277 $inner_block_content = $this->renderInnerBlocks( $wp_block );
278 $content = str_replace( '<InnerBlocks/>', $inner_block_content, $content );
279 }
280
281 return $content;
282 }
283
284 public function wrapperStyledComponent() {
285 $wrapperElement = null;
286 $styledElementsByName = $this->styledElementsByName;
287 foreach ( $styledElementsByName as $name => $styledElement ) {
288 $wrapper = LodashBasic::get( $styledElement, 'wrapper', false );
289 if ( $wrapper ) {
290 $wrapperElement = $name;
291 }
292 }
293
294 return $wrapperElement;
295 }
296
297 public function canRender() {
298 global $wp;
299
300 $is_rest_call = defined( 'REST_REQUEST' ) && REST_REQUEST;
301 $route = Arr::get( $wp->query_vars, 'rest_route', '' );
302
303 if ( strpos( $route, '/block-renderer/' ) !== false ) {
304 return true;
305 }
306
307 $can_render = apply_filters( 'kubio/can_render_block', ! $is_rest_call && ! is_admin(), $this );
308
309 return $can_render;
310 }
311
312 public function canRegisterStyle() {
313 $is_rest_call = defined( 'REST_REQUEST' ) && REST_REQUEST;
314
315 return ! $is_rest_call;
316 }
317
318 public function registerStyle() {
319 $style = new BlockStyleRender( $this, $this->parent_block_ );
320 $styleByType = $style->export( $this->getDynamicStyle() );
321 StyleManager::getInstance()->registerBlockStyle( $styleByType );
322 }
323
324 public function getDynamicStyle() {
325 return $this->mapDynamicStyleToElements();
326 }
327
328 public function mapDynamicStyleToElements() {
329 return array();
330 }
331
332 public function renderInnerBlocks( $wp_block ) {
333 $block_content = '';
334 foreach ( $wp_block->inner_blocks as $inner_block ) {
335 $inner_block_context = $inner_block->context;
336 $source_block = $inner_block->parsed_block;
337
338 /** This filter is documented in wp-includes/blocks.php */
339 $inner_block->parsed_block = apply_filters( 'render_block_data', $inner_block->parsed_block, $source_block, $wp_block );
340
341 /** This filter is documented in wp-includes/blocks.php */
342 $inner_block->context = apply_filters( 'render_block_context', $inner_block->context, $inner_block->parsed_block, $wp_block );
343 /*
344 * The `refresh_context_dependents()` method already calls `refresh_parsed_block_dependents()`.
345 * Therefore the second condition is irrelevant if the first one is satisfied.
346 */
347 if ( $inner_block->context !== $inner_block_context ) {
348 $inner_block->refresh_context_dependents();
349 } elseif ( $inner_block->parsed_block !== $source_block ) {
350 $inner_block->refresh_parsed_block_dependents();
351 }
352 $block_content .= $inner_block->render();
353 }
354
355 return $block_content;
356 }
357
358 public function mapPropsToElements() {
359 return array();
360 }
361
362
363 public function mapPropsToElementsWithDefaults() {
364 if ( ! $this->mapped_props_with_defaults ) {
365
366 $mapPropsToElements = $this->mapPropsToElements();
367
368 if ( ! $mapPropsToElements ) {
369 $mapPropsToElements = array();
370 }
371 $basicAttributes = \WP_Block_Supports::get_instance()->apply_block_supports();
372
373 if ( ! $basicAttributes ) {
374 $basicAttributes = array();
375 }
376 //rename class to className to make it compatible with kubio classes
377 if ( isset( $basicAttributes['class'] ) ) {
378 $classList = array( $basicAttributes['class'] );
379 LodashBasic::set( $basicAttributes, 'className', $classList );
380 LodashBasic::unsetValue( $basicAttributes, 'class' );
381 }
382
383 /**
384 * Set anchor. Kubio sets anchor without the source and attribute parameters in the gutenberg attribute. If you
385 * set source attribute the anchor will not work anymore. When you publish any changes the anchor gets removed.
386 * Because of this when we register the anchor we only set the type: "string" paramter and we set the attribute from
387 * here
388 */
389 $anchor = LodashBasic::get( $this->block_data, array( 'attrs', 'anchor' ) );
390 if ( ! ! $anchor ) {
391 $basicAttributes['id'] = $anchor;
392 }
393
394 $wrapperStyledComponentName = $this->getWrapperElementName();
395
396 $wrapperData = LodashBasic::get( $mapPropsToElements, $wrapperStyledComponentName, array() );
397
398 foreach ( $basicAttributes as $attributeName => $attributeValue ) {
399 if ( is_array( $attributeValue ) ) {
400 $propValue = LodashBasic::get( $wrapperData, $attributeName, array() );
401
402 //if block value is string convert it to array
403 if ( ! is_array( $propValue ) ) {
404 $propValue = array( $propValue );
405 }
406 $mergedValue = array_merge( $attributeValue, $propValue );
407 LodashBasic::set( $wrapperData, $attributeName, $mergedValue );
408 }
409 if ( ! isset( $wrapperData[ $attributeName ] ) ) {
410 LodashBasic::set( $wrapperData, $attributeName, $attributeValue );
411 }
412 }
413
414 LodashBasic::set( $mapPropsToElements, $wrapperStyledComponentName, $wrapperData );
415
416 $this->mapped_props_with_defaults = $mapPropsToElements;
417
418 }
419
420 return $this->mapped_props_with_defaults;
421 }
422
423 public function getParentColibriContext() {
424 return Arr::get( $this->block_context, 'kubio/parentKubio', array() );
425 }
426
427
428 public function getBlockInnerHtml() {
429
430 $content = trim( $this->block_data['innerHTML'] );
431 $content = str_replace( array( "\r\n", "\r", "\n", "\\n" ), '<br/>', $content );
432
433 return $content;
434 }
435
436 public function isSandboxRender() {
437 return apply_filters( 'kubio/sandboxed_render', false );
438 }
439 }
440