PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / 2.13.0
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder v2.13.0
2.13.0 2.13.1 2.12.0 2.11.1 2.11.0 2.10.0 2.9.0 2.7.4 2.7.5 2.7.6 2.7.7 2.8.0 2.8.1 2.9.1 trunk 1.0 1.0-beta1 1.0-beta2 1.0-beta3 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 All 80 releases
← All changes | includes/api/loop-builder-controller.php +124 -23 2.11.12.13.0 View file →
@@ -1,9 +1,8 @@
1 1 <?php
2 2
3 3 namespace ABlocks\API;
4 4
5 -use ABlocks\Helper;
6 5 use WP_REST_Server;
7 6 use WP_REST_Response;
8 7
9 8 if ( ! defined( 'ABSPATH' ) ) {
@@ -85,8 +84,9 @@
85 84 /* ---------------- ARCHIVE LOGIC (UNCHANGED) ---------------- */
86 85
87 86 if ( $is_archive ) {
88 87
88 + $template_slug = '';
89 89 if ( ! empty( $payload['archive_post_type'] ) ) {
90 90 $template_slug = 'archive-' . $payload['archive_post_type'];
91 91
92 92 } elseif ( ! empty( $payload['taxonomy'] ) ) {
@@ -113,29 +113,40 @@
113 113 ],
114 114 ],
115 115 ]);
116 116
117 - $post_content = current( $template_posts )->post_content;
118 - $blocks = parse_blocks( $post_content );
117 + $template_post = current( $template_posts );
118 + $blocks = $template_post ? parse_blocks( $template_post->post_content ) : [];
119 119
120 - $block_data = Helper::get_block_attributes_recursive(
121 - $loop_builder_block_id,
122 - 'ablocks/loop-builder',
123 - $blocks
124 - );
120 + } else {
125 121
126 - } else {
122 + $post = get_post( $post_id );
123 + $blocks = $this->is_post_readable( $post ) ? parse_blocks( $post->post_content ) : [];
124 + }//end if
127 125
128 - $block_data = Helper::get_block_attributes(
129 - $post_id,
130 - $loop_builder_block_id,
131 - 'ablocks/loop-builder'
126 + // The loop may sit inside a synced pattern or template part referenced
127 + // from the content, or in the theme template rendered around the post.
128 + $loop_builder_block = $this->find_block( $blocks, $loop_builder_block_id, 'ablocks/loop-builder' );
129 + if ( ! $loop_builder_block ) {
130 + $loop_builder_block = $this->find_block_in_theme_templates( $loop_builder_block_id, 'ablocks/loop-builder' );
131 + }
132 +
133 + if ( ! $loop_builder_block ) {
134 + return new WP_REST_Response(
135 + [
136 + 'success' => false,
137 + 'data' => [
138 + 'html' => '',
139 + 'term_id' => $term_id,
140 + 'post_id' => $post_id,
141 + ],
142 + ],
143 + 404
132 144 );
145 + }
133 146
134 - $post = get_post( $post_id );
135 - $post_content = $post->post_content;
136 - $blocks = parse_blocks( $post_content );
137 - }//end if
147 + $block_data = [ 'parentAttributes' => $loop_builder_block['attrs'] ];
148 + $blocks = [ $loop_builder_block ];
138 149
139 150 /* ---------------- QUERY LOGIC (UNCHANGED) ---------------- */
140 151
141 152 $query_vars = isset( $block_data['parentAttributes']['query'] )
@@ -162,13 +173,8 @@
162 173 ],
163 174 ];
164 175 }
165 176
166 - $blocks = $this->get_loop_builder_blocks_by_block_id(
167 - $blocks,
168 - $loop_builder_block_id
169 - );
170 -
171 177 $updated_blocks = $this->update_loop_builder_query(
172 178 $blocks,
173 179 $loop_template_block_id,
174 180 $query_vars,
@@ -180,9 +186,16 @@
180 186 foreach ( $updated_blocks as $block ) {
181 187 $html .= serialize_block( $block );
182 188 }
183 189
184 - $rendered = apply_filters( 'the_content', do_blocks( $html ) );
190 + // Render the fragment the way block templates are rendered. Running the
191 + // already-rendered markup through the_content re-applied wpautop (stray
192 + // <p> tags) and let other plugins append their post-content extras.
193 + $rendered = do_shortcode( shortcode_unautop( $html ) );
194 + $rendered = do_blocks( $rendered );
195 + $rendered = wptexturize( $rendered );
196 + $rendered = convert_smilies( $rendered );
197 + $rendered = wp_filter_content_tags( $rendered, 'template' );
185 198
186 199 /* ---------------- REST RESPONSE (ONLY CHANGE) ---------------- */
187 200
188 201 return new WP_REST_Response(
@@ -195,8 +208,96 @@
195 208 ],
196 209 ],
197 210 200
198 211 );
212 + }
213 +
214 + /**
215 + * Only published, non-password-protected content is public; anything else
216 + * needs the current user to be able to read it.
217 + */
218 + private function is_post_readable( $post ) {
219 + if ( ! $post instanceof \WP_Post ) {
220 + return false;
221 + }
222 + if ( 'publish' === $post->post_status && ! post_password_required( $post ) ) {
223 + return true;
224 + }
225 + return current_user_can( 'read_post', $post->ID );
226 + }
227 +
228 + /**
229 + * Find a block by name + block_id, following synced pattern references
230 + * (core/block) and template parts (core/template-part).
231 + */
232 + private function find_block( array $blocks, $block_id, $block_name, array $visited = [] ) {
233 + foreach ( $blocks as $block ) {
234 + $name = isset( $block['blockName'] ) ? $block['blockName'] : '';
235 +
236 + if ( $name === $block_name && ( isset( $block['attrs']['block_id'] ) ? $block['attrs']['block_id'] : '' ) === $block_id ) {
237 + return $block;
238 + }
239 +
240 + if ( ! empty( $block['innerBlocks'] ) ) {
241 + $found = $this->find_block( $block['innerBlocks'], $block_id, $block_name, $visited );
242 + if ( $found ) {
243 + return $found;
244 + }
245 + }
246 +
247 + $ref_key = '';
248 + $content = null;
249 + if ( 'core/block' === $name && ! empty( $block['attrs']['ref'] ) ) {
250 + $ref_key = 'wp_block:' . (int) $block['attrs']['ref'];
251 + if ( ! isset( $visited[ $ref_key ] ) ) {
252 + $ref_post = get_post( (int) $block['attrs']['ref'] );
253 + if ( $ref_post && 'wp_block' === $ref_post->post_type && $this->is_post_readable( $ref_post ) ) {
254 + $content = $ref_post->post_content;
255 + }
256 + }
257 + } elseif ( 'core/template-part' === $name && ! empty( $block['attrs']['slug'] ) ) {
258 + $theme = ! empty( $block['attrs']['theme'] ) ? $block['attrs']['theme'] : get_stylesheet();
259 + $ref_key = 'wp_template_part:' . $theme . '//' . $block['attrs']['slug'];
260 + if ( ! isset( $visited[ $ref_key ] ) ) {
261 + $part = get_block_template( $theme . '//' . $block['attrs']['slug'], 'wp_template_part' );
262 + if ( $part && 'publish' === $part->status ) {
263 + $content = $part->content;
264 + }
265 + }
266 + }
267 +
268 + if ( is_string( $content ) && '' !== $content ) {
269 + $visited[ $ref_key ] = true;
270 + $found = $this->find_block( parse_blocks( $content ), $block_id, $block_name, $visited );
271 + if ( $found ) {
272 + return $found;
273 + }
274 + }
275 + }//end foreach
276 + return null;
277 + }
278 +
279 + /**
280 + * Fallback for loops placed in the active theme's templates or template
281 + * parts rather than in the post content itself.
282 + */
283 + private function find_block_in_theme_templates( $block_id, $block_name ) {
284 + foreach ( [ 'wp_template', 'wp_template_part' ] as $template_type ) {
285 + foreach ( get_block_templates( [], $template_type ) as $template ) {
286 + $content = (string) $template->content;
287 + if (
288 + 'publish' !== $template->status ||
289 + ( false === strpos( $content, $block_id ) && false === strpos( $content, '<!-- wp:block ' ) && false === strpos( $content, '<!-- wp:template-part ' ) )
290 + ) {
291 + continue;
292 + }
293 + $found = $this->find_block( parse_blocks( $content ), $block_id, $block_name );
294 + if ( $found ) {
295 + return $found;
296 + }
297 + }
298 + }
299 + return null;
199 300 }
200 301
201 302 public function get_loop_builder_blocks_by_block_id( $blocks, $target_block_id ) {
202 303 foreach ( $blocks as $block ) {