PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.4
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.4
3.4.4 3.4.3 3.4.2 3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 All 197 releases
convertkit / includes / blocks / class-convertkit-block-form.php

class-convertkit-block-form.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 3.4.4, at includes/blocks/class-convertkit-block-form.php

505 lines 14.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ConvertKit Form Block class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * ConvertKit Form Block for Gutenberg and Shortcode.
11 *
12 * @package ConvertKit
13 * @author ConvertKit
14 */
15 class ConvertKit_Block_Form extends ConvertKit_Block {
16
17 /**
18 * Constructor
19 *
20 * @since 1.9.6
21 */
22 public function __construct() {
23
24 // Register this as a shortcode in the ConvertKit Plugin.
25 add_filter( 'convertkit_shortcodes', array( $this, 'register' ) );
26
27 // Register this as a Gutenberg block in the ConvertKit Plugin.
28 add_filter( 'convertkit_blocks', array( $this, 'register' ) );
29
30 // Register this block's MCP abilities.
31 add_filter( 'convertkit_abilities', array( $this, 'register_abilities' ) );
32
33 // Enqueue scripts for this Gutenberg Block in the editor view.
34 add_action( 'convertkit_gutenberg_enqueue_scripts', array( $this, 'enqueue_scripts_editor' ) );
35
36 // Enqueue styles for this Gutenberg Block in the editor view.
37 add_action( 'convertkit_gutenberg_enqueue_styles', array( $this, 'enqueue_styles_editor' ) );
38
39 // Enqueue scripts and styles for this Gutenberg Block in the editor and frontend views.
40 add_action( 'convertkit_gutenberg_enqueue_styles_editor_and_frontend', array( $this, 'enqueue_styles' ) );
41
42 }
43
44 /**
45 * Enqueues scripts for this Gutenberg Block in the editor view.
46 *
47 * @since 1.9.6.5
48 */
49 public function enqueue_scripts_editor() {
50
51 wp_enqueue_script( 'convertkit-gutenberg-block-form', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/gutenberg-block-form.js', array( 'convertkit-gutenberg' ), CONVERTKIT_PLUGIN_VERSION, true );
52
53 }
54
55 /**
56 * Enqueues styles for this Gutenberg Block in the editor view.
57 *
58 * @since 1.9.6.9
59 */
60 public function enqueue_styles_editor() {
61
62 wp_enqueue_style( 'convertkit-gutenberg', CONVERTKIT_PLUGIN_URL . 'resources/backend/css/gutenberg.css', array( 'wp-edit-blocks' ), CONVERTKIT_PLUGIN_VERSION );
63
64 }
65
66 /**
67 * Enqueues styles for this Gutenberg Block in the editor and frontend views.
68 *
69 * @since 2.3.3
70 */
71 public function enqueue_styles() {
72
73 convertkit_enqueue_frontend_css();
74
75 }
76
77 /**
78 * Returns this block's programmatic name, excluding the convertkit- prefix.
79 *
80 * @since 1.9.6
81 *
82 * @return string
83 */
84 public function get_name() {
85
86 /**
87 * This will register as:
88 * - a shortcode, with the name [convertkit_form].
89 * - a shortcode, with the name [kit_form].
90 * - a shortcode, with the name [convertkit], for backward compat.
91 * - a shortcode, with the name [kit].
92 * - a Gutenberg block, with the name convertkit/form.
93 */
94 return 'form';
95
96 }
97
98 /**
99 * Returns this block's title.
100 *
101 * @since 3.1.1
102 */
103 public function get_title() {
104
105 return __( 'Kit Form', 'convertkit' );
106
107 }
108
109 /**
110 * Returns this block's plural title.
111 *
112 * @since 3.4.0
113 *
114 * @return string
115 */
116 public function get_title_plural() {
117
118 return __( 'Kit Forms', 'convertkit' );
119
120 }
121
122 /**
123 * Returns this block's icon.
124 *
125 * @since 3.1.1
126 */
127 public function get_icon() {
128
129 return 'resources/backend/images/block-icon-form.svg';
130
131 }
132
133 /**
134 * Returns this block's Title, Icon, Categories, Keywords and properties.
135 *
136 * @since 1.9.6
137 *
138 * @return array
139 */
140 public function get_overview() {
141
142 $convertkit_forms = new ConvertKit_Resource_Forms( 'block_edit' );
143 $settings = new ConvertKit_Settings();
144
145 return array(
146 'title' => $this->get_title(),
147 'description' => __( 'Displays a Kit Form.', 'convertkit' ),
148 'icon' => $this->get_icon(),
149 'category' => 'convertkit',
150 'keywords' => array(
151 __( 'ConvertKit', 'convertkit' ),
152 __( 'Kit', 'convertkit' ),
153 __( 'Form', 'convertkit' ),
154 ),
155
156 // Function to call when rendering as a block or a shortcode on the frontend web site.
157 'render_callback' => array( $this, 'render' ),
158
159 // Shortcode: TinyMCE / QuickTags Modal Width and Height.
160 'modal' => array(
161 'width' => 500,
162 'height' => 55,
163 ),
164
165 // Shortcode: Include a closing [/shortcode] tag when using TinyMCE or QuickTag Modals.
166 'shortcode_include_closing_tag' => false,
167
168 // Gutenberg: Block Icon in Editor.
169 'gutenberg_icon' => convertkit_get_file_contents( CONVERTKIT_PLUGIN_PATH . '/resources/backend/images/block-icon-form.svg' ),
170
171 // Gutenberg: Example image showing how this block looks when choosing it in Gutenberg.
172 'gutenberg_example_image' => CONVERTKIT_PLUGIN_URL . 'resources/backend/images/block-example-form.png',
173
174 // Help descriptions, displayed when no API key / resources exist and this block/shortcode is added.
175 'no_access_token' => array(
176 'notice' => __( 'Not connected to Kit.', 'convertkit' ),
177 'link' => convertkit_get_setup_wizard_plugin_link(),
178 'link_text' => __( 'Click here to connect your Kit account.', 'convertkit' ),
179 'instruction_text' => __( 'Connect your Kit account at Settings > Kit, and then refresh this page to select a form.', 'convertkit' ),
180 ),
181 'no_resources' => array(
182 'notice' => __( 'No forms exist in Kit.', 'convertkit' ),
183 'link' => convertkit_get_new_form_url(),
184 'link_text' => __( 'Click here to create your first form.', 'convertkit' ),
185 'instruction_text' => __( 'Add a form to your Kit account, and then refresh this page to select a form.', 'convertkit' ),
186 ),
187
188 // Gutenberg: Help descriptions, displayed when no settings defined for a newly added Block.
189 'gutenberg_help_description' => __( 'Select a Form using the Form option in the Gutenberg sidebar.', 'convertkit' ),
190
191 // Gutenberg: JS function to call when rendering the block preview in the Gutenberg editor.
192 // If not defined, render_callback above will be used.
193 'gutenberg_preview_render_callback' => 'convertKitGutenbergFormBlockRenderPreview',
194
195 // General: Any other strings for use in JS that need to support translation / i18n.
196 'i18n' => array(
197 /* translators: Form name in ConvertKit */
198 'gutenberg_form_modal' => __( 'Modal form "%s" selected. View on the frontend site to see the modal form.', 'convertkit' ),
199
200 /* translators: Form name in ConvertKit */
201 'gutenberg_form_slide_in' => __( 'Slide in form "%s" selected. View on the frontend site to see the slide in form.', 'convertkit' ),
202
203 /* translators: Form name in ConvertKit */
204 'gutenberg_form_sticky_bar' => __( 'Sticky bar form "%s" selected. View on the frontend site to see the sticky bar form.', 'convertkit' ),
205 ),
206
207 // Whether an API Key exists in the Plugin, and are the required resources (forms) available.
208 // If no API Key is specified in the Plugin's settings, render the "No API Key" output.
209 'has_access_token' => $settings->has_access_and_refresh_token(),
210 'has_resources' => $convertkit_forms->exist(),
211 );
212
213 }
214
215 /**
216 * Returns this block's Attributes
217 *
218 * @since 1.9.6.5
219 *
220 * @return array
221 */
222 public function get_attributes() {
223
224 return array(
225 'form' => array(
226 'type' => 'string',
227 ),
228
229 // get_supports() style, color and typography attributes.
230 'align' => array(
231 'type' => 'string',
232 ),
233 'style' => array(
234 'type' => 'object',
235 ),
236 'backgroundColor' => array(
237 'type' => 'string',
238 ),
239
240 // Always required for Gutenberg.
241 'is_gutenberg_example' => array(
242 'type' => 'boolean',
243 'default' => false,
244 ),
245 );
246
247 }
248
249 /**
250 * Returns this block's supported built-in Attributes.
251 *
252 * @since 1.9.7.4
253 *
254 * @return array Supports
255 */
256 public function get_supports() {
257
258 return array(
259 'align' => true,
260 'className' => true,
261 'color' => array(
262 'link' => false,
263 'background' => true,
264 'text' => false,
265 ),
266 'spacing' => array(
267 'margin' => true,
268 'padding' => true,
269 ),
270 );
271
272 }
273
274 /**
275 * Returns this block's Fields
276 *
277 * @since 1.9.6
278 *
279 * @return bool|array
280 */
281 public function get_fields() {
282
283 // Get ConvertKit Forms. Non-legacy forms populate the sidebar dropdown;
284 // legacy forms are exposed separately as a fallback so the sidebar can
285 // keep displaying a previously-saved legacy form as the current
286 // selection without offering other legacy forms as new choices.
287 $forms = array();
288 $legacy_forms = array();
289 $convertkit_forms = new ConvertKit_Resource_Forms( 'block_edit' );
290 if ( $convertkit_forms->exist() ) {
291 foreach ( $convertkit_forms->get() as $form ) {
292 $label = sprintf(
293 '%s [%s]',
294 sanitize_text_field( $form['name'] ),
295 // Legacy forms don't include a `format` key, so define them as inline.
296 ( ! empty( $form['format'] ) ? sanitize_text_field( $form['format'] ) : 'inline' )
297 );
298
299 if ( ! empty( $form['format'] ) ) {
300 $forms[ absint( $form['id'] ) ] = $label;
301 } else {
302 $legacy_forms[ absint( $form['id'] ) ] = $label;
303 }
304 }
305 }
306
307 return array(
308 'form' => array(
309 'label' => __( 'Form', 'convertkit' ),
310 'type' => 'resource',
311 'resource' => 'forms',
312 'values' => $forms,
313 'legacy_values' => $legacy_forms,
314 'data' => array(
315 // Used by resources/backend/js/gutenberg-block-form.js to determine the selected form's format
316 // (modal, slide in, sticky bar) and output a message in the block editor for the preview to explain
317 // why some formats cannot be previewed. Includes legacy forms so the preview code can still find
318 // them when a saved block references a legacy form.
319 'forms' => ( $convertkit_forms->exist() ? $convertkit_forms->get() : array() ),
320 ),
321 ),
322 );
323
324 }
325
326 /**
327 * Returns this block's UI panels / sections.
328 *
329 * @since 1.9.6
330 *
331 * @return bool|array
332 */
333 public function get_panels() {
334
335 return array(
336 'general' => array(
337 'label' => __( 'General', 'convertkit' ),
338 'fields' => array(
339 'form',
340 ),
341 ),
342 );
343
344 }
345
346 /**
347 * Returns this block's Default Values
348 *
349 * @since 1.9.6
350 *
351 * @return array
352 */
353 public function get_default_values() {
354
355 return array(
356 'form' => '',
357 'id' => '', // Backward compat.
358 );
359
360 }
361
362 /**
363 * Returns the block's output, based on the supplied configuration attributes.
364 *
365 * @since 1.9.6
366 *
367 * @param array $atts Block / Shortcode Attributes.
368 * @return string Output
369 */
370 public function render( $atts ) {
371
372 global $post;
373
374 $post_id = is_a( $post, 'WP_Post' ) ? $post->ID : 0;
375
376 // Check if the Block Visibility Plugin permits displaying this block.
377 if ( ! $this->is_block_visible( $atts ) ) {
378 // Block should not be displayed due to Block Visibility Plugin conditions.
379 // Return a blank string now.
380 return '';
381 }
382
383 // Parse shortcode attributes, defining fallback defaults if required.
384 $atts = shortcode_atts(
385 $this->get_default_values(),
386 $this->sanitize_atts( $atts ),
387 $this->get_name()
388 );
389
390 // Setup Settings class.
391 $settings = new ConvertKit_Settings();
392
393 // Determine Form ID.
394 // 'id' attribute is for backward compat.
395 $form_id = 0;
396 if ( $atts['form'] > 0 ) {
397 $form_id = $atts['form'];
398 } elseif ( $atts['id'] > 0 ) {
399 $form_id = $atts['id'];
400 }
401
402 // If no Form ID specified, bail.
403 if ( ! $form_id ) {
404 if ( $settings->debug_enabled() ) {
405 return '<!-- No Form ID Specified -->';
406 }
407
408 return '';
409 }
410
411 // Get Form HTML.
412 $forms = new ConvertKit_Resource_Forms( 'output_form' );
413 $form = $forms->get_html( $form_id, $post_id );
414
415 // If an error occurred, it might be that we're requesting a Form ID that exists in ConvertKit
416 // but does not yet exist in the Plugin's Form Resources.
417 // If so, refresh the Form Resources and try again.
418 if ( is_wp_error( $form ) && $form->get_error_data() === 404 ) {
419 // Refresh Forms from the API.
420 $result = $forms->refresh();
421
422 // Bail if an error occurred.
423 if ( is_wp_error( $result ) ) {
424 if ( $settings->debug_enabled() ) {
425 return '<!-- ' . $result->get_error_message() . ' --> <!-- ' . $form->get_error_message() . ' -->';
426 }
427
428 return '';
429 }
430
431 // Refresh succeeded.
432 // Get Form HTML again.
433 $form = $forms->get_html( $form_id, $post_id );
434 }
435
436 // If an error still occurred, the shortcode might be from the ConvertKit App for a Legacy Form ID
437 // These ConvertKit App shortcodes, for some reason, use a different Form ID than the one presented
438 // to us in the API.
439 // For example, a Legacy Form ID might be 470099, but the ConvertKit app says to use the shortcode [convertkit form=5281783]).
440 // In this instance, fetch the Form HTML without checking that the Form ID exists in the Form Resources.
441 if ( is_wp_error( $form ) ) {
442 // Initialize the API.
443 $api = new ConvertKit_API_V4(
444 CONVERTKIT_OAUTH_CLIENT_ID,
445 CONVERTKIT_OAUTH_CLIENT_REDIRECT_URI,
446 $settings->get_access_token(),
447 $settings->get_refresh_token(),
448 $settings->debug_enabled(),
449 'output_form'
450 );
451
452 // Return Legacy Form HTML from the API, which bypasses any internal Plugin check to see if the Form ID exists.
453 $form = $api->get_form_html( $form_id, $settings->get_api_key() );
454 }
455
456 // Finally, if we still get an error, there's nothing more we can do. The Form ID isn't valid.
457 if ( is_wp_error( $form ) ) {
458 if ( $settings->debug_enabled() ) {
459 return '<!-- ' . $form->get_error_message() . ' -->';
460 }
461
462 return '';
463 }
464
465 // Build HTML.
466 // For the block editor, don't include compiled CSS classes and styles,
467 // as the block editor will add these to the parent container.
468 // Otherwise the block will render incorrectly with double padding, double margins etc.
469 // If there's no Form HTML, it's a non-inline form, so don't render any output.
470 if ( ! $this->is_block_editor_request() && ! empty( $form ) ) {
471 $form = sprintf(
472 '<div class="%s" style="%s">%s</div>',
473 implode( ' ', map_deep( $this->get_css_classes(), 'sanitize_html_class' ) ),
474 implode( ';', map_deep( $this->get_css_styles( $atts ), 'esc_attr' ) ),
475 $form
476 );
477 }
478
479 /**
480 * Filter the block's content immediately before it is output.
481 *
482 * @since 1.9.6
483 *
484 * @param string $form ConvertKit Form HTML.
485 * @param array $atts Block Attributes.
486 * @param int $form_id Form ID.
487 */
488 $form = apply_filters( 'convertkit_block_form_render', $form, $atts, $form_id );
489
490 /**
491 * Backward compat. filter for < 1.9.6. Filter the block's content immediately before it is output.
492 *
493 * @since 1.0.0
494 *
495 * @param string $form ConvertKit Form HTML.
496 * @param array $atts Block Attributes.
497 */
498 $form = apply_filters( 'wp_convertkit_get_form_embed', $form, $atts );
499
500 return $form;
501
502 }
503
504 }
505