PluginProbe
Block Animations, Motion & Scroll Effects – Ghost Kit / 3.6.0
Block Animations, Motion & Scroll Effects – Ghost Kit v3.6.0
3.7.1 3.7.0 3.6.1 trunk 1.6.3 2.25.0 3.3.0 3.3.1 3.3.2 3.3.3 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.5.0 3.5.1 3.6.0
ghostkit / classes / class-parse-blocks.php

class-parse-blocks.php in Block Animations, Motion & Scroll Effects – Ghost Kit 3.6.0, at classes/class-parse-blocks.php

218 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Parse blocks from content and widgets
4 *
5 * @package ghostkit
6 */
7
8 /**
9 * GhostKit_Parse_Blocks
10 */
11 class GhostKit_Parse_Blocks {
12 /**
13 * Array of content, that already parsed.
14 *
15 * @var array
16 */
17 public static $parsed_content = array();
18
19 /**
20 * Array of reusable block IDs, that already parsed.
21 *
22 * @var array
23 */
24 public static $parsed_reusable_blocks = array();
25
26 /**
27 * Init.
28 */
29 public static function init() {
30 add_action(
31 'wp',
32 function() {
33 // Parse methods [classic,modern].
34 $parse_methods = apply_filters( 'gkt_parse_blocks_methods', current_theme_supports( 'block-templates' ) ? array( 'modern' ) : array( 'classic' ) );
35
36 // Simple use `render_block` in FSE themes to enqueue assets.
37 if ( in_array( 'modern', $parse_methods, true ) ) {
38 // Parse all blocks.
39 add_action( 'render_block', 'GhostKit_Parse_Blocks::render_block', 11, 2 );
40 }
41
42 // Parse blocks manually from content and custom locations in Classic themes.
43 if ( in_array( 'classic', $parse_methods, true ) ) {
44 // parse blocks from post content.
45 GhostKit_Parse_Blocks::maybe_parse_blocks_from_content();
46
47 // parse blocks from custom locations, that uses 'the_content' filter.
48 add_filter( 'the_content', 'GhostKit_Parse_Blocks::maybe_parse_blocks_from_custom_location', 8 );
49 add_filter( 'widget_block_content', 'GhostKit_Parse_Blocks::maybe_parse_blocks_from_custom_location', 8 );
50 } else {
51 // FSE / modern-only: extra sources (e.g. Visual Portfolio) are not in the main query.
52 self::maybe_parse_blocks_from_content_sources();
53 }
54 }
55 );
56 }
57
58 /**
59 * Standard callback to parse blocks (mostly solves problem with FSE themes and blocks inside templates).
60 *
61 * @param string $block_content - block content.
62 * @param array $block - block data.
63 *
64 * @return string
65 */
66 public static function render_block( $block_content, $block ) {
67 // We don't need to parse inner blocks manually, because `render_block` filter will make it for us.
68 $block['innerBlocks'] = false;
69
70 self::parse_blocks( array( $block ), 'general' );
71
72 return $block_content;
73 }
74
75 /**
76 * Parse blocks from content.
77 */
78 public static function maybe_parse_blocks_from_content() {
79 global $wp_query;
80
81 if ( is_admin() || ! isset( $wp_query->posts ) ) {
82 return;
83 }
84
85 // parse all posts content.
86 foreach ( $wp_query->posts as $post ) {
87 if ( isset( $post->post_content ) ) {
88 self::maybe_parse_blocks( $post->post_content, 'content' );
89 }
90 }
91
92 self::maybe_parse_blocks_from_content_sources();
93 }
94
95 /**
96 * Parse block content from additional sources (themes, Visual Portfolio, etc.).
97 *
98 * Filter `gkt_parse_blocks_content_sources` returns an array of sources:
99 *
100 * array(
101 * array(
102 * 'content' => string, // Required. Raw post_content–style block markup.
103 * 'location' => string, // Optional. Default 'content'. Also 'widget'.
104 * ),
105 * )
106 *
107 * Runs on classic themes with post content and on modern-only themes via `wp`.
108 */
109 public static function maybe_parse_blocks_from_content_sources() {
110 $sources = apply_filters( 'gkt_parse_blocks_content_sources', array() );
111
112 if ( ! is_array( $sources ) || empty( $sources ) ) {
113 return;
114 }
115
116 foreach ( $sources as $source ) {
117 if ( ! is_array( $source ) || empty( $source['content'] ) || ! is_string( $source['content'] ) ) {
118 continue;
119 }
120
121 $location = 'content';
122 if ( ! empty( $source['location'] ) && is_string( $source['location'] ) ) {
123 $location = $source['location'];
124 }
125
126 self::maybe_parse_blocks( $source['content'], $location );
127 }
128 }
129
130 /**
131 * Parse blocks from custom locations.
132 *
133 * @param string $content - custom content.
134 */
135 public static function maybe_parse_blocks_from_custom_location( $content ) {
136 if ( is_admin() ) {
137 return $content;
138 }
139
140 if ( isset( $content ) ) {
141 self::maybe_parse_blocks( $content, 'content' );
142 }
143
144 return $content;
145 }
146
147 /**
148 * Maybe parse blocks.
149 *
150 * @param string $content - content.
151 * @param string $location - blocks location [content,widget].
152 */
153 public static function maybe_parse_blocks( $content, $location = 'content' ) {
154 if (
155 isset( $content ) &&
156 function_exists( 'has_blocks' ) &&
157 function_exists( 'parse_blocks' ) &&
158 $content &&
159 has_blocks( $content )
160 ) {
161 $is_parsed = false;
162
163 // check if this content is already parsed.
164 foreach ( self::$parsed_content as $parsed ) {
165 $is_parsed = $is_parsed || $parsed === $content;
166 }
167
168 if ( ! $is_parsed ) {
169 $blocks = parse_blocks( $content );
170 self::parse_blocks( $blocks, $location );
171
172 self::$parsed_content[] = $content;
173 }
174 }
175 }
176
177 /**
178 * Parse blocks including reusable and InnerBlocks and call action `ghostkit_parse_blocks`.
179 *
180 * @param array $blocks - blocks array.
181 * @param string $location - blocks location [content,widget].
182 * @param boolean $is_reusable - is from reusable block.
183 * @param boolean $is_inner_blocks - is from inner blocks.
184 */
185 public static function parse_blocks( $blocks, $location = 'content', $is_reusable = false, $is_inner_blocks = false ) {
186 if ( ! is_array( $blocks ) || empty( $blocks ) ) {
187 return;
188 }
189
190 do_action( 'ghostkit_parse_blocks', $blocks, $location, $is_reusable, $is_inner_blocks );
191
192 foreach ( $blocks as $block ) {
193 // Reusable Blocks.
194 if ( isset( $block['blockName'] ) && 'core/block' === $block['blockName'] && isset( $block['attrs']['ref'] ) ) {
195 // Check if this reusable block already parsed.
196 // Fixes possible error with nested reusable blocks.
197 if ( ! in_array( $block['attrs']['ref'], self::$parsed_reusable_blocks, true ) ) {
198 self::$parsed_reusable_blocks[] = $block['attrs']['ref'];
199
200 $reusable_block = get_post( $block['attrs']['ref'] );
201
202 if ( has_blocks( $reusable_block ) && isset( $reusable_block->post_content ) ) {
203 $post_blocks = parse_blocks( $reusable_block->post_content );
204 self::parse_blocks( $post_blocks, $location, true );
205 }
206 }
207 }
208
209 // Inner blocks.
210 if ( isset( $block['innerBlocks'] ) ) {
211 self::parse_blocks( $block['innerBlocks'], $location, $is_reusable, true );
212 }
213 }
214 }
215 }
216
217 GhostKit_Parse_Blocks::init();
218