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/blocks.php +247 -10 2.9.12.13.0 View file →
@@ -7,8 +7,9 @@
7 7
8 8 use ABlocks\Classes\AssetsGenerator;
9 9 use ABlocks\Helper;
10 10 use ABlocks\Classes\FileUpload;
11 +use ABlocks\Classes\FontLoadLocally;
11 12 use ABlocks\Blocks\FormBuilder\BlockAttrSanitizer\Sanitizer as BlockSanitizer;
12 13 use ABlocks\Blocks\FormBuilder\Helper as FormBuilderHelper;
13 14
14 15 class Blocks {
@@ -19,8 +20,23 @@
19 20 add_action( 'enqueue_block_assets', [ $self, 'load_academy_core_scripts' ] );
20 21 add_filter( 'block_categories_all', [ $self, 'register_block_category' ], 10, 2 );
21 22 // Assets Generator
22 23 add_action( 'save_post', [ $self, 'generate_block_assets' ], 10, 3 );
24 + add_action( 'switch_theme', [ $self, 'clear_generated_block_assets' ] );
25 + add_action( 'save_post', [ $self, 'download_google_fonts_locally' ], 20, 3 );
26 + add_action( 'deleted_post', [ $self, 'flush_site_fonts_on_delete' ], 10, 2 );
27 + // Self-hosting template fonts discovered on a front-end request happens
28 + // here, off the visitor's request.
29 + add_action( 'ablocks/download_site_fonts', [ '\ABlocks\Classes\FontCollector', 'update_site_fonts' ] );
30 + // A theme swap changes which templates and template parts exist.
31 + add_action( 'switch_theme', [ '\ABlocks\Classes\FontCollector', 'flush_site_fonts' ] );
32 + // PERF-2: pre-warm the page's generated assets in the background after save,
33 + // so the first visitor doesn't pay the parse/generate/write cost.
34 + add_action( 'save_post', [ $self, 'prewarm_page_assets' ], 30, 3 );
35 + // Recompute global typography fonts whenever the plugin's global settings change.
36 + add_action( 'ablocks/after_save_settings', [ $self, 'refresh_global_fonts' ] );
37 + // Bust the cached global CSS variables when global settings change.
38 + add_action( 'ablocks/after_save_settings', [ $self, 'clear_global_css_cache' ] );
23 39
24 40 $self->register_block_sanitizer();
25 41 $self->form_builder_default_data();
26 42 }
@@ -25,8 +41,18 @@
25 41 $self->form_builder_default_data();
26 42 }
27 43
28 44 public function blocks_init() {
45 + // keep it common for Academy LMS and QuizPress
46 + if ( ( helper::is_gutenberg_editor() && ( Helper::check_post_type_from_admin( 'academy_certificate' ) || Helper::check_post_type_from_admin( 'qp_certificate' ) ) ) || ( ! helper::is_gutenberg_editor() && ! is_admin() ) ) {
47 + new \ABlocks\Blocks\AcademyCertificate\Block();
48 + new \ABlocks\Blocks\AcademyCertificateText\Block();
49 + new \ABlocks\Blocks\AcademyContainer\Block();
50 + if ( Helper::is_plugin_active( 'academy-pro/academy-pro.php' ) ) {
51 + new \ABlocks\Blocks\AcademyCertificateId\Block();
52 + }
53 + }
54 + // Academy LMS Block Register Here
29 55 if ( Helper::is_plugin_active( 'academy/academy.php' ) ) {
30 56 add_filter( 'academy/is_load_common_scripts', '__return_true' );
31 57 if ( Helper::is_gutenberg_editor() ) {
32 58 add_filter( 'academy/is_load_common_js_scripts', '__return_false' );
@@ -38,20 +64,75 @@
38 64 new \ABlocks\Blocks\AcademyInstructorRegistrationForm\Block();
39 65 new \ABlocks\Blocks\AcademyPdf\Block();
40 66 new \ABlocks\Blocks\AcademyPasswordResetForm\Block();
41 67 new \ABlocks\Blocks\AcademyLoginForm\Block();
68 + new \ABlocks\Blocks\AcademyCourseMedia\Block();
42 69
43 - if ( ( helper::is_gutenberg_editor() && Helper::check_post_type_from_admin( 'academy_certificate' ) ) || ( ! helper::is_gutenberg_editor() && ! is_admin() ) ) {
44 - new \ABlocks\Blocks\AcademyCertificate\Block();
45 - new \ABlocks\Blocks\AcademyCertificateText\Block();
46 - if ( Helper::is_plugin_active( 'academy-pro/academy-pro.php' ) ) {
47 - new \ABlocks\Blocks\AcademyCertificateId\Block();
48 - }
49 - }
70 + new \ABlocks\Blocks\AcademyCourseCurriculums\Block();
71 + new \ABlocks\Blocks\AcademyCourseReviews\Block();
72 + new \ABlocks\Blocks\AcademyReviewForm\Block();
73 + new \ABlocks\Blocks\AcademyReviewList\Block();
74 + new \ABlocks\Blocks\AcademyAdditionInfo\Block();
75 + new \ABlocks\Blocks\AcademyCourseDescription\Block();
76 + new \ABlocks\Blocks\AcademyCourseInstructor\Block();
77 + new \ABlocks\Blocks\AcademyEnrollContent\Block();
50 78 }//end if
79 + // StoreEngine Register Block
80 + if ( Helper::is_plugin_active( 'storeengine/storeengine.php' ) ) {
81 + new \ABlocks\Blocks\StoreengineProducts\Block();
82 + new \ABlocks\Blocks\StoreengineCouponForm\Block();
83 + new \ABlocks\Blocks\StoreengineCartList\Block();
84 + new \ABlocks\Blocks\StoreengineLoginForm\Block();
85 + new \ABlocks\Blocks\StoreengineProductFilter\Block();
86 + new \ABlocks\Blocks\StoreengineCheckoutForm\Block();
87 + new \ABlocks\Blocks\StoreengineContinueButton\Block();
88 + new \ABlocks\Blocks\StoreengineCheckoutButton\Block();
89 + new \ABlocks\Blocks\StoreengineCartSubTable\Block();
90 + new \ABlocks\Blocks\StoreengineCartButton\Block();
91 + new \ABlocks\Blocks\StoreengineOrderInfo\Block();
92 + new \ABlocks\Blocks\StoreengineBillingInfo\Block();
93 + new \ABlocks\Blocks\StoreengineShippingInfo\Block();
94 + new \ABlocks\Blocks\StoreengineCartNotice\Block();
95 + new \ABlocks\Blocks\StoreengineOrderDetails\Block();
96 + // Funnel Builder blocks (render the funnel shortcodes).
97 + new \ABlocks\Blocks\StoreengineFunnelCheckout\Block();
98 + new \ABlocks\Blocks\StoreengineFunnelOffer\Block();
99 + new \ABlocks\Blocks\StoreengineFunnelAccept\Block();
100 + new \ABlocks\Blocks\StoreengineFunnelDecline\Block();
101 + new \ABlocks\Blocks\StoreengineFunnelContinue\Block();
102 + new \ABlocks\Blocks\StoreengineMiniCart\Block();
103 + new \ABlocks\Blocks\StoreengineProductGallery\Block();
104 + new \ABlocks\Blocks\StoreengineProductSummary\Block();
105 + new \ABlocks\Blocks\StoreengineProductDescription\Block();
106 + new \ABlocks\Blocks\StoreengineProductReview\Block();
107 + }//end if
108 +
109 + if ( class_exists('EasyContentManager') ) {
110 + // Easy Content Manager Register Block
111 + new \ABlocks\Blocks\EcmBookmarkButton\Block();
112 + new \ABlocks\Blocks\EcmBookmarkBadge\Block();
113 + new \ABlocks\Blocks\EcmBookmarkList\Block();
114 + new \ABlocks\Blocks\EcmBookmarkCount\Block();
115 + new \ABlocks\Blocks\EcmReactionList\Block();
116 + new \ABlocks\Blocks\EcmReaction\Block();
117 + new \ABlocks\Blocks\EcmUpvote\Block();
118 + new \ABlocks\Blocks\EcmUpvoteCount\Block();
119 + new \ABlocks\Blocks\EcmUpvoteList\Block();
120 + new \ABlocks\Blocks\EcmClaimButton\Block();
121 + new \ABlocks\Blocks\EcmClaimBadge\Block();
122 + new \ABlocks\Blocks\EcmClaimList\Block();
123 + new \ABlocks\Blocks\EcmClaimCount\Block();
124 + }
125 +
51 126 new \ABlocks\Blocks\Container\Block();
52 127 new \ABlocks\Blocks\Heading\Block();
53 128 new \ABlocks\Blocks\Paragraph\Block();
129 + new \ABlocks\Blocks\AtomicText\Block();
130 + new \ABlocks\Blocks\AtomicImage\Block();
131 + new \ABlocks\Blocks\AtomicSvg\Block();
132 + new \ABlocks\Blocks\AtomicDiv\Block();
133 + new \ABlocks\Blocks\AtomicFlex\Block();
134 + new \ABlocks\Blocks\AtomicGrid\Block();
54 135 new \ABlocks\Blocks\Image\Block();
55 136 new \ABlocks\Blocks\Button\Block();
56 137 new \ABlocks\Blocks\DualButton\Block();
57 138 new \ABlocks\Blocks\Icon\Block();
@@ -61,8 +142,12 @@
61 142 new \ABlocks\Blocks\StarRatings\Block();
62 143 new \ABlocks\Blocks\Divider\Block();
63 144 new \ABlocks\Blocks\Spacer\Block();
64 145 new \ABlocks\Blocks\Video\Block();
146 + new \ABlocks\Blocks\LoopBuilder\Block();
147 + new \ABlocks\Blocks\LoopTemplate\Block();
148 + new \ABlocks\Blocks\LoopFilter\Block();
149 + new \ABlocks\Blocks\LoopLoadMore\Block();
65 150 new \ABlocks\Blocks\Search\Block();
66 151 new \ABlocks\Blocks\Carousel\Block();
67 152 new \ABlocks\Blocks\CarouselChild\Block();
68 153 new \ABlocks\Blocks\Chart\Block();
@@ -107,9 +192,12 @@
107 192 new \ABlocks\Blocks\PriceMenuItem\Block();
108 193 new \ABlocks\Blocks\SocialShares\Block();
109 194 new \ABlocks\Blocks\Notice\Block();
110 195 new \ABlocks\Blocks\SvgDraw\Block();
196 + new \ABlocks\Blocks\FrontendDashboard\Block();
197 + new \ABlocks\Blocks\LottieAnimation\Block();
111 198 new \ABlocks\Blocks\Marquee\Block();
199 + new \ABlocks\Blocks\DynamicText\Block();
112 200 new \ABlocks\Blocks\MarqueeChild\Block();
113 201 new \ABlocks\Blocks\Logout\Block();
114 202 new \ABlocks\Blocks\FilterableCards\Block();
115 203 new \ABlocks\Blocks\FilterableCardsItem\Block();
@@ -114,8 +202,13 @@
114 202 new \ABlocks\Blocks\FilterableCards\Block();
115 203 new \ABlocks\Blocks\FilterableCardsItem\Block();
116 204 new \ABlocks\Blocks\AdvanceLists\Block();
117 205 new \ABlocks\Blocks\AdvanceListItem\Block();
206 + new \ABlocks\Blocks\QrCode\Block();
207 + new \ABlocks\Blocks\FeaturedImage\Block();
208 + new \ABlocks\Blocks\ScrollToTop\Block();
209 + new \ABlocks\Blocks\Breadcrumb\Block();
210 + new \ABlocks\Blocks\InteractiveCircleInfographic\Block();
118 211 // Form Builder
119 212 new \ABlocks\Blocks\FormBuilder\Block();
120 213 new \ABlocks\Blocks\FormInput\Block();
121 214 new \ABlocks\Blocks\FormPassword\Block();
@@ -125,8 +218,10 @@
125 218 new \ABlocks\Blocks\FormMultiStep\Block();
126 219 new \ABlocks\Blocks\FormMultiStepChild\Block();
127 220 new \ABlocks\Blocks\FormRadio\Block();
128 221 new \ABlocks\Blocks\TextPath\Block();
222 + new \ABlocks\Blocks\taxonomyListing\Block();
223 + new \ABlocks\Blocks\Player\Block();
129 224 }
130 225
131 226 public function register_block_category( $categories, $post ) {
132 227 return array_merge(
@@ -131,8 +226,12 @@
131 226 public function register_block_category( $categories, $post ) {
132 227 return array_merge(
133 228 [
134 229 [
230 + 'slug' => 'ablocks-atomic',
231 + 'title' => __( 'aBlocks Atomic', 'ablocks' ),
232 + ],
233 + [
135 234 'slug' => 'ablocks',
136 235 'title' => __( 'ABlocks', 'ablocks' ),
137 236 ],
138 237 [
@@ -138,8 +237,16 @@
138 237 [
139 238 'slug' => 'academy',
140 239 'title' => __( 'Academy LMS', 'ablocks' ),
141 240 ],
241 + [
242 + 'slug' => 'storeengine',
243 + 'title' => __( 'StoreEngine', 'ablocks' ),
244 + ],
245 + [
246 + 'slug' => 'easy-content-manager',
247 + 'title' => __( 'Easy Content Manager', 'ablocks' ),
248 + ],
142 249 ],
143 250 $categories
144 251 );
145 252 }
@@ -168,16 +275,140 @@
168 275 if ( false !== wp_is_post_revision( $post_id ) ) {
169 276 return;
170 277 }
171 278
172 - // Don't save FSE theme assets
173 - if ( ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() ) ) {
279 + $uploader = new \ABlocks\Classes\FileUpload();
280 +
281 + // Template-like content is shared across many pages, so a change there must
282 + // invalidate every page's combined assets. Regular content only affects its
283 + // own page — scope the invalidation to that one post so a single edit can't
284 + // wipe the whole site's asset cache and cause a regeneration stampede.
285 + $global_impact_post_types = apply_filters(
286 + 'ablocks/global_asset_invalidation_post_types',
287 + [ 'ablocks_tb', 'wp_template', 'wp_template_part', 'wp_block' ]
288 + );
289 +
290 + if ( in_array( get_post_type( $post_id ), $global_impact_post_types, true ) ) {
291 + $this->clear_generated_block_assets();
174 292 return;
175 293 }
176 294
177 - AssetsGenerator::write_frontend_css_in_uploads_folder( $post_id );
295 + // Drop just this post's cached files; they regenerate on next visit.
296 + $uploader->delete_file( $post_id . '.min.css' );
297 + $uploader->delete_file( $post_id . '.min.js' );
178 298 }
179 299
300 + public function download_google_fonts_locally( $post_id, $post, $update ) {
301 + if ( isset( $post->post_status ) && 'auto-draft' === $post->post_status ) {
302 + return;
303 + }
304 +
305 + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
306 + return;
307 + }
308 +
309 + if ( false !== wp_is_post_revision( $post_id ) ) {
310 + return;
311 + }
312 +
313 + // Only process content that can contain aBlocks fonts (aBlocks blocks or
314 + // reusable blocks that might wrap them).
315 + if ( empty( $post->post_content )
316 + || ( false === strpos( $post->post_content, 'wp:ablocks' ) && false === strpos( $post->post_content, 'wp:block' ) ) ) {
317 + return;
318 + }
319 +
320 + // Collect the fonts this post actually uses from its saved attributes,
321 + // cache them in post meta, and self-host them locally.
322 + // See docs/FONT-MANAGEMENT-PLAN.md.
323 + \ABlocks\Classes\FontCollector::save_post_fonts( $post_id );
324 +
325 + // Templates, template parts and theme builder layouts render on pages that
326 + // are not the queried post, so their fonts are tracked site-wide. Recompute
327 + // (and download) here rather than on a visitor's request.
328 + if ( in_array( get_post_type( $post_id ), \ABlocks\Classes\FontCollector::get_site_font_post_types(), true ) ) {
329 + \ABlocks\Classes\FontCollector::update_site_fonts();
330 + }
331 + }
332 +
333 + /**
334 + * Deleting a template/part/layout can remove the last user of a font.
335 + *
336 + * @param int $post_id Post being deleted.
337 + * @param \WP_Post $post The deleted post — by this point it is gone from the
338 + * database, so the type has to come from here.
339 + */
340 + public function flush_site_fonts_on_delete( $post_id, $post = null ) {
341 + $post_type = $post instanceof \WP_Post ? $post->post_type : get_post_type( $post_id );
342 +
343 + if ( in_array( $post_type, \ABlocks\Classes\FontCollector::get_site_font_post_types(), true ) ) {
344 + \ABlocks\Classes\FontCollector::flush_site_fonts();
345 + }
346 + }
347 +
348 + /**
349 + * Pre-warm a published page's combined CSS/JS in the background after save,
350 + * via a non-blocking loopback request. This moves the parse/generate/write
351 + * cost off the first visitor's request (PERF-2). If loopback is unavailable,
352 + * the existing on-request generation still runs as a fallback.
353 + */
354 + public function prewarm_page_assets( $post_id, $post, $update ) {
355 + if ( ! Helper::is_enabled_assets_generation() ) {
356 + return;
357 + }
358 + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
359 + return;
360 + }
361 + if ( false !== wp_is_post_revision( $post_id ) ) {
362 + return;
363 + }
364 + if ( ! ( $post instanceof \WP_Post ) ) {
365 + $post = get_post( $post_id );
366 + }
367 + if ( ! $post || 'publish' !== $post->post_status || ! is_post_type_viewable( $post->post_type ) ) {
368 + return;
369 + }
370 + // Only for content that actually has aBlocks (or wrapping) blocks.
371 + if ( empty( $post->post_content )
372 + || ( false === strpos( $post->post_content, 'wp:ablocks' ) && false === strpos( $post->post_content, 'wp:block' ) ) ) {
373 + return;
374 + }
375 + if ( ! (bool) apply_filters( 'ablocks/perf/prewarm_assets', true, $post_id ) ) {
376 + return;
377 + }
378 +
379 + $url = get_permalink( $post_id );
380 + if ( ! $url ) {
381 + return;
382 + }
383 +
384 + wp_remote_get(
385 + $url,
386 + [
387 + 'blocking' => false,
388 + 'timeout' => 0.01,
389 + 'sslverify' => false,
390 + 'headers' => [ 'X-ABlocks-Prewarm' => '1' ],
391 + ]
392 + );
393 + }
394 +
395 + /**
396 + * Recompute the global typography font set after settings are saved.
397 + * Re-primes the in-memory settings so the collector reads fresh values.
398 + */
399 + public function refresh_global_fonts() {
400 + $GLOBALS['ablocks_settings'] = json_decode( get_option( ABLOCKS_SETTINGS_NAME, '{}' ) );
401 + \ABlocks\Classes\FontCollector::update_global_fonts();
402 + }
403 +
404 + /**
405 + * Invalidate the cached global CSS variables (see Assets::global_css_variable).
406 + */
407 + public function clear_global_css_cache() {
408 + delete_transient( 'ablocks_global_css_vars' );
409 + }
410 +
180 411 public function form_builder_default_data(): void {
181 412 add_filter(
182 413 'ablocks/assets/editor_scripts_data',
183 414 [ FormBuilderHelper::class, 'form_builder_default_data' ]
@@ -184,6 +415,12 @@
184 415 );
185 416 }
186 417 public function register_block_sanitizer(): void {
187 418 BlockSanitizer::init();
419 + }
420 +
421 + public function clear_generated_block_assets() {
422 + $uploader = new \ABlocks\Classes\FileUpload();
423 + $uploader->delete_files();
424 + Helper::clear_third_party_plugin_cache();
188 425 }
189 426 }