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

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