AI
9 months ago
admin-pages
2 days ago
api
6 days ago
blog
1 year ago
customizer
1 year ago
filters
2 days ago
full-site-editing
1 month ago
importer
1 year ago
integrations
1 month ago
menu
1 year ago
polyfills
1 year ago
preview
7 months ago
recommendations
1 month ago
shapes
2 years ago
shortcodes
1 year ago
src
2 days ago
add-edit-in-kubio.php
11 months ago
editor-assets.php
6 days ago
filters.php
1 year ago
frontend.php
1 year ago
global-data.php
1 year ago
init.php
1 year ago
kubio-block-library.php
1 month ago
kubio-editor.php
1 month ago
load.php
1 month ago
kubio-block-library.php
418 lines
| 1 | <?php |
| 2 | |
| 3 | use IlluminateAgnostic\Arr\Support\Arr; |
| 4 | use Kubio\Core\Registry; |
| 5 | use Kubio\Core\Utils; |
| 6 | |
| 7 | function kubio_prefix_block_category_title( $category_title ) { |
| 8 | // translators: %s is the category name |
| 9 | $prefix = __( 'Kubio - %s', 'kubio' ); |
| 10 | |
| 11 | return sprintf( $prefix, $category_title ); |
| 12 | } |
| 13 | |
| 14 | function kubio_block_categories( $categories ) { |
| 15 | |
| 16 | $kubio_categories = array( |
| 17 | array( |
| 18 | 'slug' => 'kubio-basic', |
| 19 | 'title' => __( 'Basic Blocks', 'kubio' ), |
| 20 | ), |
| 21 | array( |
| 22 | 'slug' => 'kubio-components', |
| 23 | 'title' => __( 'Advanced Blocks', 'kubio' ), |
| 24 | ), |
| 25 | array( |
| 26 | 'slug' => 'kubio-site-data', |
| 27 | 'title' => __( 'Site Data Blocks', 'kubio' ), |
| 28 | ), |
| 29 | array( |
| 30 | 'slug' => 'kubio-blog-components', |
| 31 | 'title' => __( 'Blog Blocks', 'kubio' ), |
| 32 | ), |
| 33 | |
| 34 | array( |
| 35 | 'slug' => 'kubio-layout', |
| 36 | 'title' => __( 'Layout', 'kubio' ), |
| 37 | ), |
| 38 | |
| 39 | array( |
| 40 | 'slug' => 'kubio-template-parts', |
| 41 | 'title' => __( 'Template Parts', 'kubio' ), |
| 42 | ), |
| 43 | |
| 44 | ); |
| 45 | |
| 46 | $prefixed_categories = array_map( |
| 47 | function ( $category ) { |
| 48 | $title = Arr::get( $category, 'title', '' ); |
| 49 | Arr::set( $category, 'title', kubio_prefix_block_category_title( $title ) ); |
| 50 | |
| 51 | $category['isKubio'] = true; |
| 52 | |
| 53 | return $category; |
| 54 | }, |
| 55 | $kubio_categories |
| 56 | ); |
| 57 | |
| 58 | return array_merge( |
| 59 | $prefixed_categories, |
| 60 | $categories |
| 61 | ); |
| 62 | } |
| 63 | |
| 64 | add_filter( 'block_categories_all', 'kubio_block_categories', 10, 1 ); |
| 65 | |
| 66 | |
| 67 | function kubio_get_block_metadata( $block_name ) { |
| 68 | $blocks_dir = __DIR__ . '/../build/block-library/blocks'; |
| 69 | $metadata_file = "{$blocks_dir}/{$block_name}/block.json"; |
| 70 | |
| 71 | return kubio_get_block_metadata_mixin( $metadata_file ); |
| 72 | } |
| 73 | |
| 74 | function kubio_get_block_metadata_mixin( $mixin ) { |
| 75 | if ( is_array( $mixin ) ) { |
| 76 | return $mixin; |
| 77 | } |
| 78 | |
| 79 | if ( file_exists( $mixin ) ) { |
| 80 | $metadata = json_decode( file_get_contents( $mixin ), true ); |
| 81 | |
| 82 | if ( ! is_array( $metadata ) ) { |
| 83 | return null; |
| 84 | } |
| 85 | |
| 86 | return $metadata; |
| 87 | } |
| 88 | |
| 89 | return null; |
| 90 | } |
| 91 | |
| 92 | function kubio_can_register_block( $block_name ) { |
| 93 | $kubio_editor_only_blocks = array( |
| 94 | 'core/post-content', |
| 95 | ); |
| 96 | |
| 97 | if ( in_array( $block_name, $kubio_editor_only_blocks ) ) { |
| 98 | return false; |
| 99 | } |
| 100 | |
| 101 | return true; |
| 102 | } |
| 103 | |
| 104 | function kubio_render_block_callback( $attributes, $content, $block ) { |
| 105 | $context = $block->context; |
| 106 | $block_wrapper = Registry::getInstance()->getBlock( $block->parsed_block, $context ); |
| 107 | |
| 108 | if ( ! $block_wrapper ) { |
| 109 | return ''; |
| 110 | } |
| 111 | |
| 112 | $render_fn = 'render'; |
| 113 | |
| 114 | /** |
| 115 | * check if a custom serverSideRender function is defined |
| 116 | */ |
| 117 | if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { |
| 118 | /** @var $wp WP */ |
| 119 | global $wp; |
| 120 | $route = (string) Arr::get( $wp->query_vars, 'rest_route', '' ); |
| 121 | |
| 122 | if ( strpos( $route, '/block-renderer/' ) !== false && method_exists( $block_wrapper, 'serverSideRender' ) ) { |
| 123 | $render_fn = 'serverSideRender'; |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | Registry::getInstance()->addBlockToStack( $block_wrapper ); |
| 128 | $result = $block_wrapper->$render_fn( $block ); |
| 129 | Registry::getInstance()->removeBlockFromStack( $block_wrapper ); |
| 130 | |
| 131 | return $result; |
| 132 | } |
| 133 | |
| 134 | function kubio_no_block_manifest_notice() { |
| 135 | |
| 136 | ?> |
| 137 | <div class="kubio-notice notice notice-error"> |
| 138 | <p><?php esc_html_e( 'Kubio Error: Blocks manifest file (blocks-manifest.php) does not exists. Please recompile the plugin', 'kubio' ); ?> </p> |
| 139 | </div> |
| 140 | <?php |
| 141 | } |
| 142 | |
| 143 | function kubio_register_block_types() { |
| 144 | |
| 145 | $library_dir = __DIR__ . '/../build/block-library/'; |
| 146 | $manifest_file = $library_dir . '/blocks-manifest.php'; |
| 147 | |
| 148 | if ( ! file_exists( $manifest_file ) ) { |
| 149 | if ( is_admin() ) { |
| 150 | add_action( 'admin_notices', 'kubio_no_block_manifest_notice' ); |
| 151 | |
| 152 | } |
| 153 | |
| 154 | return; |
| 155 | } |
| 156 | |
| 157 | global $kubio_autoloader; |
| 158 | |
| 159 | $blocks_dir = $library_dir . '/blocks'; |
| 160 | $blocks_manifest = require_once $manifest_file; |
| 161 | |
| 162 | $blocks_namespace = 'Kubio\\Blocks'; |
| 163 | $blocks_class_map = array(); |
| 164 | $block_files = array(); |
| 165 | |
| 166 | foreach ( $blocks_manifest as $block_data ) { |
| 167 | $block_file = $block_data['rel']; |
| 168 | $classes = $block_data['classes']; |
| 169 | |
| 170 | array_push( $block_files, $block_file ); |
| 171 | |
| 172 | foreach ( $classes as $class_name ) { |
| 173 | $blocks_class_map[ "{$blocks_namespace}\\{$class_name}" ] = "{$blocks_dir}/{$block_file}"; |
| 174 | |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | $kubio_autoloader->addClassMap( $blocks_class_map ); |
| 179 | |
| 180 | foreach ( $block_files as $file ) { |
| 181 | require_once "{$blocks_dir}/{$file}"; |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | |
| 186 | add_action( 'init', 'kubio_register_block_types', 9 ); |
| 187 | |
| 188 | |
| 189 | function kubio_enqueue_editor_assets() { |
| 190 | wp_enqueue_script( 'kubio-block-library' ); |
| 191 | wp_enqueue_style( 'kubio-block-library-editor' ); |
| 192 | wp_enqueue_style( 'kubio-format-library' ); |
| 193 | wp_enqueue_style( 'kubio-controls' ); |
| 194 | wp_enqueue_style( 'kubio-utils' ); |
| 195 | } |
| 196 | |
| 197 | add_action( 'enqueue_block_editor_assets', 'kubio_enqueue_editor_assets' ); |
| 198 | |
| 199 | |
| 200 | function kubio_register_block_type_from_metadata_array( $metadata, $args = array() ) { |
| 201 | if ( ! is_array( $metadata ) ) { |
| 202 | return false; |
| 203 | } |
| 204 | |
| 205 | $settings = array(); |
| 206 | $property_mappings = array( |
| 207 | 'title' => 'title', |
| 208 | 'category' => 'category', |
| 209 | 'parent' => 'parent', |
| 210 | 'icon' => 'icon', |
| 211 | 'description' => 'description', |
| 212 | 'keywords' => 'keywords', |
| 213 | 'attributes' => 'attributes', |
| 214 | 'providesContext' => 'provides_context', |
| 215 | 'usesContext' => 'uses_context', |
| 216 | 'supports' => 'supports', |
| 217 | 'styles' => 'styles', |
| 218 | 'example' => 'example', |
| 219 | 'apiVersion' => 'api_version', |
| 220 | ); |
| 221 | |
| 222 | foreach ( $property_mappings as $key => $mapped_key ) { |
| 223 | if ( isset( $metadata[ $key ] ) ) { |
| 224 | $value = $metadata[ $key ]; |
| 225 | if ( empty( $metadata['textdomain'] ) ) { |
| 226 | $settings[ $mapped_key ] = $value; |
| 227 | continue; |
| 228 | } |
| 229 | $textdomain = $metadata['textdomain']; |
| 230 | switch ( $key ) { |
| 231 | case 'title': |
| 232 | case 'description': |
| 233 | // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralContext,WordPress.WP.I18n.NonSingularStringLiteralDomain |
| 234 | $settings[ $mapped_key ] = translate_with_gettext_context( $value, sprintf( 'block %s', $key ), $textdomain ); |
| 235 | break; |
| 236 | case 'keywords': |
| 237 | $settings[ $mapped_key ] = array(); |
| 238 | if ( ! is_array( $value ) ) { |
| 239 | continue 2; |
| 240 | } |
| 241 | |
| 242 | foreach ( $value as $keyword ) { |
| 243 | // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain |
| 244 | $settings[ $mapped_key ][] = translate_with_gettext_context( $keyword, 'block keyword', $textdomain ); |
| 245 | } |
| 246 | |
| 247 | break; |
| 248 | case 'styles': |
| 249 | $settings[ $mapped_key ] = array(); |
| 250 | if ( ! is_array( $value ) ) { |
| 251 | continue 2; |
| 252 | } |
| 253 | |
| 254 | foreach ( $value as $style ) { |
| 255 | if ( ! empty( $style['label'] ) ) { |
| 256 | // phpcs:ignore WordPress.WP.I18n.LowLevelTranslationFunction,WordPress.WP.I18n.NonSingularStringLiteralText,WordPress.WP.I18n.NonSingularStringLiteralDomain |
| 257 | $style['label'] = translate_with_gettext_context( $style['label'], 'block style label', $textdomain ); |
| 258 | } |
| 259 | $settings[ $mapped_key ][] = $style; |
| 260 | } |
| 261 | |
| 262 | break; |
| 263 | default: |
| 264 | $settings[ $mapped_key ] = $value; |
| 265 | } |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | if ( ! empty( $metadata['editorScript'] ) ) { |
| 270 | $settings['editor_script'] = register_block_script_handle( |
| 271 | $metadata, |
| 272 | 'editorScript' |
| 273 | ); |
| 274 | } |
| 275 | |
| 276 | if ( ! empty( $metadata['script'] ) ) { |
| 277 | $settings['script'] = register_block_script_handle( |
| 278 | $metadata, |
| 279 | 'script' |
| 280 | ); |
| 281 | } |
| 282 | |
| 283 | if ( ! empty( $metadata['editorStyle'] ) ) { |
| 284 | $settings['editor_style'] = register_block_style_handle( |
| 285 | $metadata, |
| 286 | 'editorStyle' |
| 287 | ); |
| 288 | } |
| 289 | |
| 290 | if ( ! empty( $metadata['style'] ) ) { |
| 291 | $settings['style'] = register_block_style_handle( |
| 292 | $metadata, |
| 293 | 'style' |
| 294 | ); |
| 295 | } |
| 296 | |
| 297 | /** |
| 298 | * Filters the settings determined from the block type metadata. |
| 299 | * |
| 300 | * @param array $settings Array of determined settings for registering a block type. |
| 301 | * @param array $metadata Metadata provided for registering a block type. |
| 302 | * |
| 303 | * @since 5.7.0 |
| 304 | * |
| 305 | */ |
| 306 | $settings = apply_filters( |
| 307 | 'block_type_metadata_settings', |
| 308 | array_merge( |
| 309 | $settings, |
| 310 | $args |
| 311 | ), |
| 312 | $metadata |
| 313 | ); |
| 314 | |
| 315 | return WP_Block_Type_Registry::get_instance()->register( |
| 316 | $metadata['name'], |
| 317 | $settings |
| 318 | ); |
| 319 | } |
| 320 | |
| 321 | /** |
| 322 | * Returns a joined string of the aggregate serialization of the given parsed |
| 323 | * blocks. |
| 324 | * |
| 325 | * @param WP_Block_Parser_Block[] $blocks Parsed block objects. |
| 326 | * |
| 327 | * @return string String of rendered HTML. |
| 328 | * @since 5.3.1 |
| 329 | * |
| 330 | */ |
| 331 | function kubio_serialize_blocks( $blocks ) { |
| 332 | $blocks = is_array( $blocks ) ? $blocks : array( $blocks ); |
| 333 | |
| 334 | return implode( '', array_map( 'kubio_serialize_block', $blocks ) ); |
| 335 | } |
| 336 | |
| 337 | /** |
| 338 | * Returns the content of a block, including comment delimiters, serializing all |
| 339 | * attributes from the given parsed block. |
| 340 | * |
| 341 | * This should be used when preparing a block to be saved to post content. |
| 342 | * Prefer `render_block` when preparing a block for display. Unlike |
| 343 | * `render_block`, this does not evaluate a block's `render_callback`, and will |
| 344 | * instead preserve the markup as parsed. |
| 345 | * |
| 346 | * @param WP_Block_Parser_Block $block A single parsed block object. |
| 347 | * |
| 348 | * @return string String of rendered HTML. |
| 349 | * @since 5.3.1 |
| 350 | * |
| 351 | */ |
| 352 | function kubio_serialize_block( $block ) { |
| 353 | $block_content = ''; |
| 354 | |
| 355 | $kubio_attr = Arr::get( $block, 'attrs.kubio', false ); |
| 356 | |
| 357 | if ( $kubio_attr ) { |
| 358 | $kubio_attr = Utils::arrayRecursiveRemoveEmptyBranches( $kubio_attr ); |
| 359 | Arr::set( $block, 'attrs.kubio', $kubio_attr ); |
| 360 | } |
| 361 | |
| 362 | $index = 0; |
| 363 | |
| 364 | if ( isset( $block['innerContent'] ) ) { |
| 365 | foreach ( $block['innerContent'] as $chunk ) { |
| 366 | $block_content .= is_string( $chunk ) ? $chunk : kubio_serialize_block( $block['innerBlocks'][ $index++ ] ); |
| 367 | } |
| 368 | } |
| 369 | |
| 370 | if ( ! is_array( $block['attrs'] ) ) { |
| 371 | $block['attrs'] = array(); |
| 372 | } |
| 373 | |
| 374 | $blockName = $block['blockName'] ?? null; |
| 375 | |
| 376 | return kubio_get_comment_delimited_block_content( |
| 377 | $blockName, |
| 378 | $block['attrs'], |
| 379 | $block_content |
| 380 | ); |
| 381 | } |
| 382 | |
| 383 | |
| 384 | /** |
| 385 | * Returns the content of a block, including comment delimiters. |
| 386 | * |
| 387 | * @param string|null $block_name Block name. Null if the block name is unknown, |
| 388 | * e.g. Classic blocks have their name set to null. |
| 389 | * @param array $block_attributes Block attributes. |
| 390 | * @param string $block_content Block save content. |
| 391 | * |
| 392 | * @return string Comment-delimited block content. |
| 393 | * @since 5.3.1 |
| 394 | * |
| 395 | */ |
| 396 | function kubio_get_comment_delimited_block_content( $block_name, $block_attributes, $block_content ) { |
| 397 | if ( is_null( $block_name ) ) { |
| 398 | return $block_content; |
| 399 | } |
| 400 | |
| 401 | $serialized_block_name = strip_core_block_namespace( $block_name ); |
| 402 | $serialized_attributes = empty( $block_attributes ) ? '' : wp_json_encode( ( $block_attributes ), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . ' '; |
| 403 | |
| 404 | if ( empty( $block_content ) ) { |
| 405 | return sprintf( '<!-- wp:%s %s/-->', $serialized_block_name, $serialized_attributes ); |
| 406 | } |
| 407 | |
| 408 | $serialized_block = sprintf( |
| 409 | '<!-- wp:%s %s-->%s<!-- /wp:%s -->', |
| 410 | $serialized_block_name, |
| 411 | $serialized_attributes, |
| 412 | $block_content, |
| 413 | $serialized_block_name |
| 414 | ); |
| 415 | |
| 416 | return $serialized_block; |
| 417 | } |
| 418 |