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-trigger.php

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

503 lines 13.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ConvertKit Form Trigger Button Block class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * ConvertKit Form Trigger Button Block for Gutenberg and Shortcode.
11 *
12 * @package ConvertKit
13 * @author ConvertKit
14 */
15 class ConvertKit_Block_Form_Trigger extends ConvertKit_Block {
16
17 /**
18 * Constructor
19 *
20 * @since 2.2.0
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 and styles for this Gutenberg Block in the editor and frontend views.
34 add_action( 'convertkit_gutenberg_enqueue_styles_editor_and_frontend', array( $this, 'enqueue_styles' ) );
35
36 }
37
38 /**
39 * Enqueues styles for this Gutenberg Block in the editor and frontend views.
40 *
41 * @since 2.2.0
42 */
43 public function enqueue_styles() {
44
45 convertkit_enqueue_frontend_css();
46
47 // Enqueue the block button CSS.
48 wp_enqueue_style( 'wp-block-button' );
49
50 }
51
52 /**
53 * Returns this block's programmatic name, excluding the convertkit- prefix.
54 *
55 * @since 2.2.0
56 */
57 public function get_name() {
58
59 /**
60 * This will register as:
61 * - a shortcode, with the name [convertkit_formtrigger].
62 * - a shortcode, with the name [kit_formtrigger].
63 * - a Gutenberg block, with the name convertkit/formtrigger.
64 */
65 return 'formtrigger';
66
67 }
68
69 /**
70 * Returns this block's title.
71 *
72 * @since 3.1.1
73 */
74 public function get_title() {
75
76 return __( 'Kit Form Trigger', 'convertkit' );
77
78 }
79
80 /**
81 * Returns this block's plural title.
82 *
83 * @since 3.4.0
84 *
85 * @return string
86 */
87 public function get_title_plural() {
88
89 return __( 'Kit Form Triggers', 'convertkit' );
90
91 }
92
93 /**
94 * Returns this block's icon.
95 *
96 * @since 3.1.1
97 */
98 public function get_icon() {
99
100 return 'resources/backend/images/block-icon-formtrigger.svg';
101
102 }
103
104 /**
105 * Returns this block's Title, Icon, Categories, Keywords and properties.
106 *
107 * @since 2.2.0
108 */
109 public function get_overview() {
110
111 $convertkit_forms = new ConvertKit_Resource_Forms( 'block_edit' );
112 $settings = new ConvertKit_Settings();
113
114 return array(
115 'title' => $this->get_title(),
116 'description' => __( 'Displays a modal, sticky bar or slide in form to display when the button is pressed.', 'convertkit' ),
117 'icon' => $this->get_icon(),
118 'category' => 'convertkit',
119 'keywords' => array(
120 __( 'ConvertKit', 'convertkit' ),
121 __( 'Kit', 'convertkit' ),
122 __( 'Form', 'convertkit' ),
123 ),
124
125 // Function to call when rendering as a block or a shortcode on the frontend web site.
126 'render_callback' => array( $this, 'render' ),
127
128 // Shortcode: TinyMCE / QuickTags Modal Width and Height.
129 'modal' => array(
130 'width' => 500,
131 'height' => 282,
132 ),
133
134 // Shortcode: Include a closing [/shortcode] tag when using TinyMCE or QuickTag Modals.
135 'shortcode_include_closing_tag' => false,
136
137 // Gutenberg: Block Icon in Editor.
138 'gutenberg_icon' => convertkit_get_file_contents( CONVERTKIT_PLUGIN_PATH . '/resources/backend/images/block-icon-formtrigger.svg' ),
139
140 // Gutenberg: Example image showing how this block looks when choosing it in Gutenberg.
141 'gutenberg_example_image' => CONVERTKIT_PLUGIN_URL . 'resources/backend/images/block-example-formtrigger.png',
142
143 // Help descriptions, displayed when no API key / resources exist and this block/shortcode is added.
144 'no_access_token' => array(
145 'notice' => __( 'Not connected to Kit.', 'convertkit' ),
146 'link' => convertkit_get_setup_wizard_plugin_link(),
147 'link_text' => __( 'Click here to connect your Kit account.', 'convertkit' ),
148 'instruction_text' => __( 'Connect your Kit account at Settings > Kit, and then refresh this page to select a form.', 'convertkit' ),
149 ),
150 'no_resources' => array(
151 'notice' => __( 'No modal, sticky bar or slide in forms exist in Kit.', 'convertkit' ),
152 'link' => convertkit_get_new_form_url(),
153 'link_text' => __( 'Click here to create a form.', 'convertkit' ),
154 'instruction_text' => __( 'Add a non-inline form to your Kit account, and then refresh this page to select a form.', 'convertkit' ),
155 ),
156
157 // The attribute to check if a value exists when rendering the block in the editor,
158 // and the message to display if no value exists.
159 'gutenberg_help_description' => __( 'Select a Form using the Form option in the Gutenberg sidebar.', 'convertkit' ),
160 'gutenberg_help_description_attribute' => 'form',
161
162 // Whether an API Key exists in the Plugin, and are the required resources (non-inline forms) available.
163 // If no API Key is specified in the Plugin's settings, render the "No API Key" output.
164 'has_access_token' => $settings->has_access_and_refresh_token(),
165 'has_resources' => $convertkit_forms->non_inline_exist(),
166 );
167
168 }
169
170 /**
171 * Returns this block's Attributes
172 *
173 * @since 2.2.0
174 */
175 public function get_attributes() {
176
177 return array(
178 // Block attributes.
179 'form' => array(
180 'type' => 'string',
181 'default' => $this->get_default_value( 'form' ),
182 ),
183 'text' => array(
184 'type' => 'string',
185 'default' => $this->get_default_value( 'text' ),
186 ),
187
188 // The below are built in Gutenberg attributes registered in get_supports().
189
190 // get_supports() style, color and typography attributes.
191 'style' => array(
192 'type' => 'object',
193 ),
194 'backgroundColor' => array(
195 'type' => 'string',
196 ),
197 'textColor' => array(
198 'type' => 'string',
199 ),
200 'fontSize' => array(
201 'type' => 'string',
202 ),
203
204 // Always required for Gutenberg.
205 'is_gutenberg_example' => array(
206 'type' => 'boolean',
207 'default' => false,
208 ),
209 );
210
211 }
212
213 /**
214 * Returns this block's supported built-in Attributes.
215 *
216 * @since 2.2.0
217 *
218 * @return array Supports
219 */
220 public function get_supports() {
221
222 return array(
223 'className' => true,
224 'color' => array(
225 'background' => true,
226 'text' => true,
227
228 // Don't apply styles to the block editor's div element.
229 // This ensures what's rendered in the Gutenberg editor matches the frontend output for styling.
230 // See: https://github.com/WordPress/gutenberg/issues/32417.
231 '__experimentalSkipSerialization' => true,
232 ),
233 'typography' => array(
234 'fontSize' => true,
235 'lineHeight' => true,
236 ),
237 'spacing' => array(
238 'margin' => true,
239 'padding' => true,
240 ),
241 );
242
243 }
244
245 /**
246 * Returns this block's Fields
247 *
248 * @since 2.2.0
249 *
250 * @return bool|array
251 */
252 public function get_fields() {
253
254 // Get non-inline ConvertKit Forms.
255 $forms = array();
256 $convertkit_forms = new ConvertKit_Resource_Forms( 'block_edit' );
257 if ( $convertkit_forms->non_inline_exist() ) {
258 foreach ( $convertkit_forms->get_non_inline() as $form ) {
259 // Legacy forms don't include a `format` key, so define them as inline.
260 $forms[ absint( $form['id'] ) ] = sprintf(
261 '%s [%s]',
262 sanitize_text_field( $form['name'] ),
263 ( ! empty( $form['format'] ) ? sanitize_text_field( $form['format'] ) : 'inline' )
264 );
265 }
266 }
267
268 // Gutenberg's built-in fields (such as styling, padding etc) don't need to be defined here, as they'll be included
269 // automatically by Gutenberg.
270 return array(
271 'form' => array(
272 'label' => __( 'Form', 'convertkit' ),
273 'type' => 'resource',
274 'resource' => 'forms',
275 'values' => $forms,
276 'description' => __( 'The modal, sticky bar or slide in form to display when the button is pressed. To embed a form, use the Kit Form block instead.', 'convertkit' ),
277 ),
278 'text' => array(
279 'label' => __( 'Button Text', 'convertkit' ),
280 'type' => 'text',
281 'description' => __( 'The text to display for the button.', 'convertkit' ),
282 ),
283
284 // These fields will only display on the shortcode, and are deliberately not registered in get_attributes(),
285 // because Gutenberg will register its own color pickers for link, background and text.
286 'background_color' => array(
287 'label' => __( 'Background color', 'convertkit' ),
288 'type' => 'color',
289 ),
290 'text_color' => array(
291 'label' => __( 'Text color', 'convertkit' ),
292 'type' => 'color',
293 ),
294 );
295
296 }
297
298 /**
299 * Returns this block's UI panels / sections.
300 *
301 * @since 2.2.0
302 *
303 * @return bool|array
304 */
305 public function get_panels() {
306
307 // Gutenberg's built-in fields (such as styling, padding etc) don't need to be defined here, as they'll be included
308 // automatically by Gutenberg.
309 return array(
310 'general' => array(
311 'label' => __( 'General', 'convertkit' ),
312 'fields' => array(
313 'form',
314 'text',
315 'background_color',
316 'text_color',
317 ),
318 ),
319 );
320
321 }
322
323 /**
324 * Returns this block's Default Values
325 *
326 * @since 2.2.0
327 *
328 * @return array
329 */
330 public function get_default_values() {
331
332 return array(
333 'form' => '',
334 'text' => __( 'Subscribe', 'convertkit' ),
335 'background_color' => '',
336 'text_color' => '',
337
338 // Built-in Gutenberg block attributes.
339 'backgroundColor' => '',
340 'textColor' => '',
341 'fontSize' => '',
342 'style' => array(
343 'visualizers' => array(
344 'padding' => array(
345 'top' => '',
346 'bottom' => '',
347 'left' => '',
348 'right' => '',
349 ),
350 ),
351 ),
352 );
353
354 }
355
356 /**
357 * Returns the block's output, based on the supplied configuration attributes.
358 *
359 * @since 2.2.0
360 *
361 * @param array $atts Block / Shortcode / Page Builder Module Attributes.
362 * @return string
363 */
364 public function render( $atts ) {
365
366 // Parse attributes, defining fallback defaults if required
367 // and moving some attributes (such as Gutenberg's styles), if defined.
368 $atts = $this->sanitize_and_declare_atts( $atts );
369
370 // Setup Settings class.
371 $settings = new ConvertKit_Settings();
372
373 // Build HTML.
374 $html = $this->get_html(
375 $atts['form'],
376 $atts['text'],
377 $this->get_css_classes( array( 'wp-block-button__link', 'wp-element-button' ) ),
378 $this->get_css_styles( $atts ),
379 $this->is_block_editor_request()
380 );
381
382 // Bail if an error occurred.
383 if ( is_wp_error( $html ) ) {
384 if ( $settings->debug_enabled() ) {
385 return '<!-- ' . $html->get_error_message() . ' -->';
386 }
387
388 return '';
389 }
390
391 /**
392 * Filter the block's content immediately before it is output.
393 *
394 * @since 2.2.0
395 *
396 * @param string $html ConvertKit Button HTML.
397 * @param array $atts Block Attributes.
398 */
399 $html = apply_filters( 'convertkit_block_form_trigger_render', $html, $atts );
400
401 return $html;
402
403 }
404
405 /**
406 * Returns the HTML button markup for the given Form ID.
407 *
408 * @since 2.0.0
409 *
410 * @param int $id Form ID.
411 * @param string $button_text Button Text.
412 * @param array $css_classes CSS classes to apply to link (typically included when using Gutenberg).
413 * @param array $css_styles CSS inline styles to apply to link (typically included when using Shortcode or third party page builder module / widget).
414 * @param bool $return_as_span If true, returns a <span> instead of <a>. Useful for the block editor so that the element is interactible.
415 * @return WP_Error|string Button HTML
416 */
417 private function get_html( $id, $button_text, $css_classes = array(), $css_styles = array(), $return_as_span = false ) {
418
419 // Cast ID to integer.
420 $id = absint( $id );
421
422 // Load classes.
423 $convertkit_forms = new ConvertKit_Resource_Forms( 'render' );
424
425 // Get form.
426 $form = $convertkit_forms->get_by_id( $id );
427
428 // Bail if the form could not be found.
429 if ( ! $form ) {
430 return new WP_Error(
431 'convertkit_block_form_trigger_get_html',
432 sprintf(
433 /* translators: ConvertKit Form ID */
434 __( 'Kit Form ID %s does not exist on Kit.', 'convertkit' ),
435 $id
436 )
437 );
438 }
439
440 // Bail if no uid or embed_js properties exist.
441 if ( ! array_key_exists( 'uid', $form ) ) {
442 return new WP_Error(
443 'convertkit_block_form_trigger_get_html',
444 sprintf(
445 /* translators: ConvertKit Form ID */
446 __( 'Kit Form ID %s has no uid property.', 'convertkit' ),
447 $id
448 )
449 );
450 }
451 if ( ! array_key_exists( 'embed_js', $form ) ) {
452 return new WP_Error(
453 'convertkit_block_form_trigger_get_html',
454 sprintf(
455 /* translators: ConvertKit Form ID */
456 __( 'Kit Form ID %s has no embed_js property.', 'convertkit' ),
457 $id
458 )
459 );
460 }
461
462 // Build button HTML.
463 $html = '<div class="convertkit-button">';
464
465 if ( $return_as_span ) {
466 $html .= '<span';
467 } else {
468 $html .= '<a data-formkit-toggle="' . esc_attr( $form['uid'] ) . '" href="' . esc_url( $form['embed_url'] ) . '"';
469 }
470
471 $html .= ' class="' . implode( ' ', map_deep( $css_classes, 'sanitize_html_class' ) ) . '" style="' . implode( ';', map_deep( $css_styles, 'esc_attr' ) ) . '">';
472 $html .= esc_html( $button_text );
473
474 if ( $return_as_span ) {
475 $html .= '</span>';
476 } else {
477 $html .= '</a>';
478 }
479
480 $html .= '</div>';
481
482 // Register the script, so it's only loaded once for this non-inline form across the entire page.
483 add_filter(
484 'convertkit_output_scripts_footer',
485 function ( $scripts ) use ( $form ) {
486
487 $scripts[] = array(
488 'async' => true,
489 'data-uid' => $form['uid'],
490 'src' => $form['embed_js'],
491 );
492
493 return $scripts;
494
495 }
496 );
497
498 // Return.
499 return $html;
500 }
501
502 }
503