PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.3
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.3
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 2.3.1 All 196 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.3, at includes/blocks/class-convertkit-block-form-trigger.php

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