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

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