PluginProbe
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder / 2.12.0
aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder v2.12.0
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 1.2.0 1.2.1 All 78 releases
ablocks / includes / blocks.php

blocks.php in aBlocks – Gutenberg Blocks, User Dashboard Builder, Popup Builder, Form Builder & Animation Builder 2.12.0, at includes/blocks.php

427 lines 16.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace ABlocks;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit(); // Exit if accessed directly.
6 }
7
8 use ABlocks\Classes\AssetsGenerator;
9 use ABlocks\Helper;
10 use ABlocks\Classes\FileUpload;
11 use ABlocks\Classes\FontLoadLocally;
12 use ABlocks\Blocks\FormBuilder\BlockAttrSanitizer\Sanitizer as BlockSanitizer;
13 use ABlocks\Blocks\FormBuilder\Helper as FormBuilderHelper;
14
15 class Blocks {
16 public static function init() {
17 $self = new self();
18 // block initialization
19 add_action( 'init', [ $self, 'blocks_init' ] );
20 add_action( 'enqueue_block_assets', [ $self, 'load_academy_core_scripts' ] );
21 add_filter( 'block_categories_all', [ $self, 'register_block_category' ], 10, 2 );
22 // Assets Generator
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' ] );
39
40 $self->register_block_sanitizer();
41 $self->form_builder_default_data();
42 }
43
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
55 if ( Helper::is_plugin_active( 'academy/academy.php' ) ) {
56 add_filter( 'academy/is_load_common_scripts', '__return_true' );
57 if ( Helper::is_gutenberg_editor() ) {
58 add_filter( 'academy/is_load_common_js_scripts', '__return_false' );
59 }
60 new \ABlocks\Blocks\AcademyCourses\Block();
61 new \ABlocks\Blocks\AcademyEnrollForm\Block();
62 new \ABlocks\Blocks\AcademyStudentRegistrationForm\Block();
63 new \ABlocks\Blocks\AcademyCourseSearch\Block();
64 new \ABlocks\Blocks\AcademyInstructorRegistrationForm\Block();
65 new \ABlocks\Blocks\AcademyPdf\Block();
66 new \ABlocks\Blocks\AcademyPasswordResetForm\Block();
67 new \ABlocks\Blocks\AcademyLoginForm\Block();
68 new \ABlocks\Blocks\AcademyCourseMedia\Block();
69
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();
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
126 new \ABlocks\Blocks\Container\Block();
127 new \ABlocks\Blocks\Heading\Block();
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();
135 new \ABlocks\Blocks\Image\Block();
136 new \ABlocks\Blocks\Button\Block();
137 new \ABlocks\Blocks\DualButton\Block();
138 new \ABlocks\Blocks\Icon\Block();
139 new \ABlocks\Blocks\InfoBox\Block();
140 new \ABlocks\Blocks\Lists\Block();
141 new \ABlocks\Blocks\Counter\Block();
142 new \ABlocks\Blocks\StarRatings\Block();
143 new \ABlocks\Blocks\Divider\Block();
144 new \ABlocks\Blocks\Spacer\Block();
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();
150 new \ABlocks\Blocks\Search\Block();
151 new \ABlocks\Blocks\Carousel\Block();
152 new \ABlocks\Blocks\CarouselChild\Block();
153 new \ABlocks\Blocks\Chart\Block();
154 new \ABlocks\Blocks\Toggle\Block();
155 new \ABlocks\Blocks\ToggleChild\Block();
156 new \ABlocks\Blocks\Accordion\Block();
157 new \ABlocks\Blocks\SingleAccordion\Block();
158 new \ABlocks\Blocks\Tabs\Block();
159 new \ABlocks\Blocks\TabsChild\Block();
160 new \ABlocks\Blocks\Countdown\Block();
161 new \ABlocks\Blocks\NewsTicker\Block();
162 new \ABlocks\Blocks\ImageHotspot\Block();
163 new \ABlocks\Blocks\ImageHotspotChild\Block();
164 new \ABlocks\Blocks\ProgressTracker\Block();
165 new \ABlocks\Blocks\ImageScroll\Block();
166 new \ABlocks\Blocks\Menu\Block();
167 new \ABlocks\Blocks\MenuItem\Block();
168 new \ABlocks\Blocks\MenuChildSub\Block();
169 new \ABlocks\Blocks\MenuChildMega\Block();
170 new \ABlocks\Blocks\StripeButton\Block();
171 new \ABlocks\Blocks\PaypalButton\Block();
172
173 new \ABlocks\Blocks\Table\Block();
174 new \ABlocks\Blocks\TableCell\Block();
175 new \ABlocks\Blocks\TableRow\Block();
176 new \ABlocks\Blocks\TableHeader\Block();
177 new \ABlocks\Blocks\TableFooter\Block();
178 new \ABlocks\Blocks\TableBody\Block();
179
180 new \ABlocks\Blocks\Coupon\Block();
181 new \ABlocks\Blocks\ContentTimeline\Block();
182 new \ABlocks\Blocks\ContentTimelineChild\Block();
183 new \ABlocks\Blocks\Map\Block();
184 new \ABlocks\Blocks\TableOfContent\Block();
185 new \ABlocks\Blocks\Modal\Block();
186 new \ABlocks\Blocks\ModalTrigger\Block();
187 new \ABlocks\Blocks\ModalPanel\Block();
188 new \ABlocks\Blocks\ImageComparison\Block();
189 new \ABlocks\Blocks\FlipBox\Block();
190 new \ABlocks\Blocks\FlipBoxChild\Block();
191 new \ABlocks\Blocks\PriceMenu\Block();
192 new \ABlocks\Blocks\PriceMenuItem\Block();
193 new \ABlocks\Blocks\SocialShares\Block();
194 new \ABlocks\Blocks\Notice\Block();
195 new \ABlocks\Blocks\SvgDraw\Block();
196 new \ABlocks\Blocks\FrontendDashboard\Block();
197 new \ABlocks\Blocks\LottieAnimation\Block();
198 new \ABlocks\Blocks\Marquee\Block();
199 new \ABlocks\Blocks\DynamicText\Block();
200 new \ABlocks\Blocks\MarqueeChild\Block();
201 new \ABlocks\Blocks\Logout\Block();
202 new \ABlocks\Blocks\FilterableCards\Block();
203 new \ABlocks\Blocks\FilterableCardsItem\Block();
204 new \ABlocks\Blocks\AdvanceLists\Block();
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();
211 // Form Builder
212 new \ABlocks\Blocks\FormBuilder\Block();
213 new \ABlocks\Blocks\FormInput\Block();
214 new \ABlocks\Blocks\FormPassword\Block();
215 new \ABlocks\Blocks\FormTextarea\Block();
216 new \ABlocks\Blocks\FormCheckbox\Block();
217 new \ABlocks\Blocks\FormSelect\Block();
218 new \ABlocks\Blocks\FormMultiStep\Block();
219 new \ABlocks\Blocks\FormMultiStepChild\Block();
220 new \ABlocks\Blocks\FormRadio\Block();
221 new \ABlocks\Blocks\TextPath\Block();
222 new \ABlocks\Blocks\taxonomyListing\Block();
223 new \ABlocks\Blocks\Player\Block();
224 }
225
226 public function register_block_category( $categories, $post ) {
227 return array_merge(
228 [
229 [
230 'slug' => 'ablocks-atomic',
231 'title' => __( 'aBlocks Atomic', 'ablocks' ),
232 ],
233 [
234 'slug' => 'ablocks',
235 'title' => __( 'ABlocks', 'ablocks' ),
236 ],
237 [
238 'slug' => 'academy',
239 'title' => __( 'Academy LMS', 'ablocks' ),
240 ],
241 [
242 'slug' => 'storeengine',
243 'title' => __( 'StoreEngine', 'ablocks' ),
244 ],
245 [
246 'slug' => 'easy-content-manager',
247 'title' => __( 'Easy Content Manager', 'ablocks' ),
248 ],
249 ],
250 $categories
251 );
252 }
253
254 public function load_academy_core_scripts() {
255 if ( ! Helper::is_plugin_active( 'academy/academy.php' ) || ! is_admin() ) {
256 return;
257 }
258 $ScriptsBase = new \Academy\Assets();
259 $ScriptsBase->frontend_common_assets();
260 }
261
262 public function generate_block_assets( $post_id, $post, $update ) {
263 if ( ! Helper::is_enabled_assets_generation() ) {
264 return;
265 }
266
267 if ( isset( $post->post_status ) && 'auto-draft' === $post->post_status ) {
268 return;
269 }
270
271 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
272 return;
273 }
274
275 if ( false !== wp_is_post_revision( $post_id ) ) {
276 return;
277 }
278
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();
292 return;
293 }
294
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' );
298 }
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
411 public function form_builder_default_data(): void {
412 add_filter(
413 'ablocks/assets/editor_scripts_data',
414 [ FormBuilderHelper::class, 'form_builder_default_data' ]
415 );
416 }
417 public function register_block_sanitizer(): void {
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();
425 }
426 }
427