PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 2.6.1
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v2.6.1
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 2.3.2 2.3.3 All 194 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 2.6.1, at includes/blocks/class-convertkit-block-form-trigger.php

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