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

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