@@ -27,6 +27,7 @@ public function __construct() {
2727 add_action ( 'save_post ' , array ( $ this , 'save_cpt ' ) );
2828 add_filter ( 'content_save_pre ' , array ( $ this , 'strip_form_tags ' ), 10 , 1 );
2929 add_action ( 'add_meta_boxes ' , array ( $ this , 'add_meta_boxes_cpt ' ) );
30+ add_action ( 'add_meta_boxes ' , array ( $ this , 'maybe_load_imported_template ' ), 10 , 2 );
3031 add_action ( 'admin_enqueue_scripts ' , array ( $ this , 'admin_post_scripts_cpt ' ), 10 , 1 );
3132
3233 // edit.php view
@@ -131,7 +132,7 @@ public function disable_tinymce( $default ) {
131132 }
132133
133134 /**
134- * Include custom JS on the edit screen
135+ * Include custom JS and CSS on the edit screen
135136 */
136137 public function admin_post_scripts_cpt ( $ hook ) {
137138 global $ post ;
@@ -146,8 +147,13 @@ public function admin_post_scripts_cpt( $hook ) {
146147 return ;
147148 }
148149
150+ $ assets_url = plugins_url ( 'assets ' , dirname ( __FILE__ ) );
151+
149152 // enqueue the custom JS for this view
150- wp_enqueue_script ( 'wplf-form-edit-js ' , plugins_url ( 'assets/scripts/wplf-admin-form.js ' , dirname ( __FILE__ ) ) );
153+ wp_enqueue_script ( 'wplf-form-edit-js ' , $ assets_url . '/scripts/wplf-admin-form.js ' );
154+
155+ // enqueue the custom CSS for this view
156+ wp_enqueue_style ( 'wplf-form-edit-css ' , $ assets_url . '/styles/wplf-admin-form.css ' );
151157 }
152158
153159
@@ -460,6 +466,138 @@ class="code"
460466<?php
461467 }
462468
469+ /**
470+ * Check and maybe load a static HTML template for a specific form.
471+ *
472+ * Hooked to `add_meta_boxes`.
473+ *
474+ * @param string $post_type Post type for which editor is being rendered for.
475+ * @param \WP_Post $post Current post object.
476+ *
477+ * @return void
478+ */
479+ function maybe_load_imported_template ( $ post_type , $ post ) {
480+ if ( $ post_type !== 'wplf-form ' || $ post ->post_status === 'auto-draft ' ) {
481+ return ;
482+ }
483+
484+ $ form_id = (int ) $ post ->ID ;
485+
486+ /**
487+ * Allows importing a static HTML template for a specific form ID.
488+ *
489+ * If the template returned is `null` then no template is loaded.
490+ *
491+ * @param string|null $template_content Raw HTML to import for a form.
492+ * @param int $form_id Form ID (WP_Post ID) to import template for.
493+ */
494+ $ template_content = apply_filters ( 'wplf_import_html_template ' , null , $ form_id );
495+
496+ if ( $ template_content === null ) {
497+ return ;
498+ }
499+
500+ // Clear unwanted form tags. WPLF will insert those by itself when rendering a form.
501+ $ template_content = preg_replace ( '%<form ?[^>]*?>% ' , '' , $ template_content );
502+ $ template_content = preg_replace ( '%</form>% ' , '' , $ template_content );
503+
504+ $ this ->override_form_template ( $ template_content , $ form_id );
505+ }
506+
507+ /**
508+ * Override a form's template with an imported template file.
509+ *
510+ * @param string $template_content Raw HTML content to use for the form content.
511+ * @param int $form_id ID of form we're overriding the template for.
512+ *
513+ * @return void
514+ */
515+ protected function override_form_template ( $ template_content , $ form_id ) {
516+ $ this ->maybe_persist_override_template ( $ template_content , $ form_id );
517+
518+ static $ times_content_replaced = 0 ;
519+
520+ // Make the editor textarea uneditable.
521+ add_filter ( 'the_editor ' , function ( $ editor ) {
522+ if ( ! preg_match ( '%id="wp-content-editor-container"% ' , $ editor ) ) {
523+ return $ editor ;
524+ }
525+
526+ $ editor = preg_replace ( '%\<textarea % ' , '<textarea readonly="readonly" ' , $ editor );
527+
528+ $ notice = _x (
529+ 'This form template is being overridden by code, you must edit it in your project code ' ,
530+ 'Template override notice in form edit admin view ' ,
531+ 'wp-libre-form '
532+ );
533+
534+ $ notice = sprintf ( '<div class="wplf-template-override-notice">%s</div> ' , $ notice );
535+
536+ return $ notice . $ editor ;
537+ } );
538+
539+ // Custom settings for the form editor.
540+ add_filter ( 'wp_editor_settings ' , function ( $ settings , $ editor_id ) {
541+ if ( $ editor_id !== 'content ' ) {
542+ return $ settings ;
543+ }
544+
545+ $ settings ['tinymce ' ] = false ;
546+ $ settings ['quicktags ' ] = false ;
547+ $ settings ['media_buttons ' ] = false ;
548+
549+ return $ settings ;
550+ }, 10 , 2 );
551+
552+ // Replace all editor content with template content.
553+ add_filter ( 'the_editor_content ' , function ( $ content ) use ( $ template_content , &$ times_content_replaced ) {
554+ // This is hacky, yes. We only want to override the content for the first
555+ // editor field we come by, meaning 99% of the time we hit the wanted form
556+ // template editor field at the top of the edit view page.
557+ if ( $ times_content_replaced > 0 ) {
558+ return $ content ;
559+ }
560+
561+ $ times_content_replaced ++;
562+
563+ return $ template_content ;
564+ } );
565+ }
566+
567+ /**
568+ * Check if we need to auto-persist the form template override into WP database.
569+ *
570+ * @param string $template Template to maybe persist.
571+ * @param int $form_id Form ID to persist template for.
572+ * @param bool $force Force a persist even though not required?
573+ *
574+ * @return void
575+ */
576+ protected function maybe_persist_override_template ( $ template , $ form_id , $ force = false ) {
577+ $ hash_transient = 'wplf_form_tmpl_hash_ ' . $ form_id ;
578+ $ template_hash = md5 ( $ template );
579+ $ stored_hash = get_transient ( $ hash_transient );
580+
581+ if ( ! $ force && $ template_hash === $ stored_hash ) {
582+ return ;
583+ }
584+
585+ // Safe-guard to prevent accidental infinite loops.
586+ remove_action ( 'save_post ' , array ( $ this , 'save_cpt ' ) );
587+
588+ $ updated = wp_update_post ( array (
589+ 'ID ' => (int ) $ form_id ,
590+ 'post_content ' => $ template ,
591+ ) );
592+
593+ add_action ( 'save_post ' , array ( $ this , 'save_cpt ' ) );
594+
595+ // Maybe we should do something else than just silently fail if persisting failed above.
596+ if ( $ updated ) {
597+ set_transient ( $ hash_transient , $ template_hash , HOUR_IN_SECONDS * 8 );
598+ }
599+ }
600+
463601 /**
464602 * Handles saving our post meta
465603 */
0 commit comments