Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
77.42% |
72 / 93 |
|
60.00% |
3 / 5 |
CRAP | |
0.00% |
0 / 1 |
| Form_Editor | |
77.42% |
72 / 93 |
|
60.00% |
3 / 5 |
17.59 | |
0.00% |
0 / 1 |
| init | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
| allowed_blocks_for_jetpack_form | |
100.00% |
61 / 61 |
|
100.00% |
1 / 1 |
3 | |||
| block_editor_settings_all | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
| disable_block_directory | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
| enqueue_admin_scripts | |
15.00% |
3 / 20 |
|
0.00% |
0 / 1 |
20.35 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Jetpack forms editor. |
| 4 | * |
| 5 | * @package automattic/jetpack-forms |
| 6 | */ |
| 7 | |
| 8 | namespace Automattic\Jetpack\Forms\Editor; |
| 9 | |
| 10 | use Automattic\Jetpack\Assets; |
| 11 | use Automattic\Jetpack\Forms\ContactForm\Contact_Form; |
| 12 | |
| 13 | /** |
| 14 | * Class Form_Editor |
| 15 | * |
| 16 | * Handles the form editor functionality for jetpack-form post type. |
| 17 | */ |
| 18 | class Form_Editor { |
| 19 | |
| 20 | /** |
| 21 | * Script handle for the form editor. |
| 22 | * |
| 23 | * @var string |
| 24 | */ |
| 25 | const SCRIPT_HANDLE = 'jetpack-form-editor'; |
| 26 | |
| 27 | /** |
| 28 | * Initialize the form editor. |
| 29 | */ |
| 30 | public static function init() { |
| 31 | add_filter( 'allowed_block_types_all', array( __CLASS__, 'allowed_blocks_for_jetpack_form' ), 10, 2 ); |
| 32 | add_filter( 'block_editor_settings_all', array( __CLASS__, 'block_editor_settings_all' ), 10, 2 ); |
| 33 | add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_admin_scripts' ) ); |
| 34 | add_action( 'current_screen', array( __CLASS__, 'disable_block_directory' ) ); |
| 35 | } |
| 36 | |
| 37 | /** |
| 38 | * Restrict allowed blocks when editing jetpack-form posts. |
| 39 | * |
| 40 | * Only allows field blocks and supporting blocks. The contact-form block is excluded |
| 41 | * because visual wrapping is handled via DOM manipulation in the editor script. |
| 42 | * |
| 43 | * @param bool|array $allowed_block_types Array of block type slugs, or boolean to enable/disable all. |
| 44 | * @param object $editor_context The current editor context. |
| 45 | * @return bool|array Array of allowed block types for jetpack-form posts. |
| 46 | */ |
| 47 | public static function allowed_blocks_for_jetpack_form( $allowed_block_types, $editor_context ) { |
| 48 | // Only apply to jetpack-form post type. |
| 49 | if ( ! isset( $editor_context->post ) || Contact_Form::POST_TYPE !== $editor_context->post->post_type ) { |
| 50 | return $allowed_block_types; |
| 51 | } |
| 52 | |
| 53 | // Allow only field blocks, button, and core blocks. |
| 54 | // Visual wrapping is handled by JavaScript DOM manipulation. |
| 55 | return array( |
| 56 | // Field blocks. |
| 57 | 'jetpack/field-name', |
| 58 | 'jetpack/field-email', |
| 59 | 'jetpack/field-url', |
| 60 | 'jetpack/field-telephone', |
| 61 | 'jetpack/field-textarea', |
| 62 | 'jetpack/field-checkbox', |
| 63 | 'jetpack/field-checkbox-multiple', |
| 64 | 'jetpack/field-radio', |
| 65 | 'jetpack/field-select', |
| 66 | 'jetpack/field-date', |
| 67 | 'jetpack/field-consent', |
| 68 | 'jetpack/field-rating', |
| 69 | 'jetpack/field-text', |
| 70 | 'jetpack/field-number', |
| 71 | 'jetpack/field-hidden', |
| 72 | 'jetpack/field-file', |
| 73 | 'jetpack/field-time', |
| 74 | 'jetpack/field-slider', |
| 75 | 'jetpack/field-image-select', |
| 76 | |
| 77 | // Supporting blocks. |
| 78 | 'jetpack/button', // Used for the submit button previously. |
| 79 | 'jetpack/label', |
| 80 | 'jetpack/input', |
| 81 | 'jetpack/options', |
| 82 | 'jetpack/option', |
| 83 | 'jetpack/phone-input', |
| 84 | 'jetpack/dropzone', |
| 85 | 'jetpack/input-range', |
| 86 | 'jetpack/input-rating', |
| 87 | 'jetpack/fieldset-image-options', |
| 88 | 'jetpack/input-image-option', |
| 89 | |
| 90 | // Multistep blocks. |
| 91 | 'jetpack/form-step', |
| 92 | 'jetpack/form-step-container', |
| 93 | 'jetpack/form-step-divider', |
| 94 | 'jetpack/form-step-navigation', |
| 95 | 'jetpack/form-progress-indicator', |
| 96 | |
| 97 | // Core blocks for rich content. |
| 98 | 'core/accordion', |
| 99 | 'core/audio', |
| 100 | 'core/button', // Used for the submit button. |
| 101 | 'core/code', |
| 102 | 'core/column', |
| 103 | 'core/columns', |
| 104 | 'core/details', |
| 105 | 'core/group', |
| 106 | 'core/heading', |
| 107 | 'core/html', |
| 108 | 'core/icon', |
| 109 | 'core/image', |
| 110 | 'core/list-item', |
| 111 | 'core/list', |
| 112 | 'core/math', |
| 113 | 'core/paragraph', |
| 114 | 'core/row', |
| 115 | 'core/separator', |
| 116 | 'core/spacer', |
| 117 | 'core/stack', |
| 118 | 'core/subhead', |
| 119 | 'core/video', |
| 120 | ); |
| 121 | } |
| 122 | |
| 123 | /** |
| 124 | * Modify block editor settings for jetpack-form posts. |
| 125 | * |
| 126 | * @param array $settings Block editor settings. |
| 127 | * @param object $editor_context The current editor context. |
| 128 | * @return array Modified block editor settings for jetpack-form posts. |
| 129 | */ |
| 130 | public static function block_editor_settings_all( $settings, $editor_context ) { |
| 131 | // Only apply to jetpack-form post type. |
| 132 | if ( ! isset( $editor_context->post ) || Contact_Form::POST_TYPE !== $editor_context->post->post_type ) { |
| 133 | return $settings; |
| 134 | } |
| 135 | |
| 136 | // Disable block locking capability. |
| 137 | $settings['canLockBlocks'] = false; |
| 138 | |
| 139 | return $settings; |
| 140 | } |
| 141 | |
| 142 | /** |
| 143 | * Disable the block directory in the form editor. |
| 144 | * |
| 145 | * Removes the block directory assets (install blocks from the inserter) |
| 146 | * since this feature is not needed in the form editor. |
| 147 | * Hooked to `current_screen` so it runs before scripts are enqueued. |
| 148 | * |
| 149 | * @param \WP_Screen $screen The current screen object. |
| 150 | */ |
| 151 | public static function disable_block_directory( $screen ) { |
| 152 | if ( ! isset( $screen->post_type ) ) { |
| 153 | return; |
| 154 | } |
| 155 | if ( Contact_Form::POST_TYPE === $screen->post_type ) { |
| 156 | remove_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_block_directory_assets' ); |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | /** |
| 161 | * Enqueue admin scripts for block editor. |
| 162 | * Loads in all post block editor contexts (excluding the site editor) so that the |
| 163 | * rename command is available and can be used when a form block is selected. |
| 164 | */ |
| 165 | public static function enqueue_admin_scripts() { |
| 166 | $screen = get_current_screen(); |
| 167 | |
| 168 | // Only load in block editor contexts, not site editor |
| 169 | if ( ! $screen || $screen->id === 'site-editor' || ! $screen->is_block_editor ) { |
| 170 | return; |
| 171 | } |
| 172 | $asset_file = __DIR__ . '/../../dist/form-editor/jetpack-form-editor.asset.php'; |
| 173 | if ( ! file_exists( $asset_file ) ) { |
| 174 | // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log |
| 175 | error_log( 'Form Editor asset file not found: ' . $asset_file ); |
| 176 | return; |
| 177 | } |
| 178 | $asset = require $asset_file; |
| 179 | Assets::register_script( |
| 180 | self::SCRIPT_HANDLE, |
| 181 | '../../dist/form-editor/jetpack-form-editor.js', |
| 182 | __FILE__, |
| 183 | array( |
| 184 | 'in_footer' => true, |
| 185 | 'textdomain' => 'jetpack-forms', |
| 186 | 'enqueue' => true, |
| 187 | 'dependencies' => $asset['dependencies'], |
| 188 | 'version' => $asset['version'], |
| 189 | ) |
| 190 | ); |
| 191 | } |
| 192 | } |