PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.4
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.4
3.4.4 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 All 197 releases
convertkit / includes / blocks / class-convertkit-block-product.php

class-convertkit-block-product.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 3.4.4, at includes/blocks/class-convertkit-block-product.php

462 lines 13.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ConvertKit Product Button Block class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * ConvertKit Product Button Block for Gutenberg and Shortcode.
11 *
12 * @package ConvertKit
13 * @author ConvertKit
14 */
15 class ConvertKit_Block_Product extends ConvertKit_Block {
16
17 /**
18 * Constructor
19 *
20 * @since 1.9.8.5
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_scripts_editor_and_frontend', array( $this, 'enqueue_scripts' ) );
35 add_action( 'convertkit_gutenberg_enqueue_styles_editor_and_frontend', array( $this, 'enqueue_styles' ) );
36
37 }
38
39 /**
40 * Enqueues scripts for this Gutenberg Block in the editor and frontend views.
41 *
42 * @since 1.9.8.5
43 */
44 public function enqueue_scripts() {
45
46 // Get URL for commerce.js from Products.
47 $convertkit_products = new ConvertKit_Resource_Products();
48 $commerce_js_url = $convertkit_products->get_commerce_js_url();
49
50 // Bail if the commerce.js URL could not be fetched, as this means there are no Products.
51 if ( ! $commerce_js_url ) {
52 return;
53 }
54
55 // Enqueue.
56 wp_enqueue_script( 'convertkit-commerce', $commerce_js_url, array(), false, true ); // phpcs:ignore
57
58 }
59
60 /**
61 * Enqueues styles for this Gutenberg Block in the editor and frontend views.
62 *
63 * @since 1.9.8.5
64 */
65 public function enqueue_styles() {
66
67 convertkit_enqueue_frontend_css();
68
69 // Enqueue the block button CSS.
70 wp_enqueue_style( 'wp-block-button' );
71
72 }
73
74 /**
75 * Returns this block's programmatic name, excluding the convertkit- prefix.
76 *
77 * @since 1.9.8.5
78 */
79 public function get_name() {
80
81 /**
82 * This will register as:
83 * - a shortcode, with the name [convertkit_product].
84 * - a shortcode, with the name [kit_product].
85 * - a Gutenberg block, with the name convertkit/product.
86 */
87 return 'product';
88
89 }
90
91 /**
92 * Returns this block's title.
93 *
94 * @since 3.1.1
95 */
96 public function get_title() {
97
98 return __( 'Kit Product', 'convertkit' );
99
100 }
101
102 /**
103 * Returns this block's plural title.
104 *
105 * @since 3.4.0
106 *
107 * @return string
108 */
109 public function get_title_plural() {
110
111 return __( 'Kit Products', 'convertkit' );
112
113 }
114
115 /**
116 * Returns this block's icon.
117 *
118 * @since 3.1.1
119 */
120 public function get_icon() {
121
122 return 'resources/backend/images/block-icon-product.svg';
123
124 }
125
126 /**
127 * Returns this block's Title, Icon, Categories, Keywords and properties.
128 *
129 * @since 1.9.8.5
130 */
131 public function get_overview() {
132
133 $convertkit_products = new ConvertKit_Resource_Products( 'block_edit' );
134 $settings = new ConvertKit_Settings();
135
136 return array(
137 'title' => $this->get_title(),
138 'description' => __( 'Displays a button to purchase a Kit product.', 'convertkit' ),
139 'icon' => $this->get_icon(),
140 'category' => 'convertkit',
141 'keywords' => array(
142 __( 'ConvertKit', 'convertkit' ),
143 __( 'Kit', 'convertkit' ),
144 __( 'Product', 'convertkit' ),
145 ),
146
147 // Function to call when rendering as a block or a shortcode on the frontend web site.
148 'render_callback' => array( $this, 'render' ),
149
150 // Shortcode: TinyMCE / QuickTags Modal Width and Height.
151 'modal' => array(
152 'width' => 600,
153 'height' => 518,
154 ),
155
156 // Shortcode: Include a closing [/shortcode] tag when using TinyMCE or QuickTag Modals.
157 'shortcode_include_closing_tag' => false,
158
159 // Gutenberg: Block Icon in Editor.
160 'gutenberg_icon' => convertkit_get_file_contents( CONVERTKIT_PLUGIN_PATH . '/resources/backend/images/block-icon-product.svg' ),
161
162 // Gutenberg: Example image showing how this block looks when choosing it in Gutenberg.
163 'gutenberg_example_image' => CONVERTKIT_PLUGIN_URL . 'resources/backend/images/block-example-product.png',
164
165 // Help descriptions, displayed when no Access Token / resources exist and this block/shortcode is added.
166 'no_access_token' => array(
167 'notice' => __( 'Not connected to Kit.', 'convertkit' ),
168 'link' => convertkit_get_setup_wizard_plugin_link(),
169 'link_text' => __( 'Click here to connect your Kit account.', 'convertkit' ),
170 'instruction_text' => __( 'Connect your Kit account at Settings > Kit, and then refresh this page to select a product.', 'convertkit' ),
171 ),
172 'no_resources' => array(
173 'notice' => __( 'No products exist in Kit.', 'convertkit' ),
174 'link' => convertkit_get_new_product_url(),
175 'link_text' => __( 'Click here to create your first product.', 'convertkit' ),
176 'instruction_text' => __( 'Add a product to your Kit account, and then refresh this page to select a product.', 'convertkit' ),
177 ),
178
179 // Gutenberg: Help description, displayed when the defined attribute has not been set for the block.
180 'gutenberg_help_description' => __( 'Select a Product using the Product option in the Gutenberg sidebar.', 'convertkit' ),
181 'gutenberg_help_description_attribute' => 'product',
182
183 // Whether an Access Token exists in the Plugin, and are the required resources (products) available.
184 // If no Access Token is specified in the Plugin's settings, render the "Not Connected" output.
185 'has_access_token' => $settings->has_access_and_refresh_token(),
186 'has_resources' => $convertkit_products->exist(),
187 );
188
189 }
190
191 /**
192 * Returns this block's Attributes
193 *
194 * @since 1.9.8.5
195 */
196 public function get_attributes() {
197
198 return array(
199 // Block attributes.
200 'product' => array(
201 'type' => 'string',
202 'default' => $this->get_default_value( 'product' ),
203 ),
204 'text' => array(
205 'type' => 'string',
206 'default' => $this->get_default_value( 'text' ),
207 ),
208 'discount_code' => array(
209 'type' => 'string',
210 'default' => $this->get_default_value( 'discount_code' ),
211 ),
212 'checkout' => array(
213 'type' => 'boolean',
214 'default' => $this->get_default_value( 'checkout' ),
215 ),
216 'disable_modal_on_mobile' => array(
217 'type' => 'boolean',
218 'default' => $this->get_default_value( 'disable_modal_on_mobile' ),
219 ),
220
221 // The below are built in Gutenberg attributes registered in get_supports().
222
223 // get_supports() style, color and typography attributes.
224 'style' => array(
225 'type' => 'object',
226 ),
227 'backgroundColor' => array(
228 'type' => 'string',
229 ),
230 'textColor' => array(
231 'type' => 'string',
232 ),
233 'fontSize' => array(
234 'type' => 'string',
235 ),
236
237 // Always required for Gutenberg.
238 'is_gutenberg_example' => array(
239 'type' => 'boolean',
240 'default' => false,
241 ),
242 );
243
244 }
245
246 /**
247 * Returns this block's supported built-in Attributes.
248 *
249 * @since 1.9.8.5
250 *
251 * @return array Supports
252 */
253 public function get_supports() {
254
255 return array(
256 'className' => true,
257 'color' => array(
258 'background' => true,
259 'text' => true,
260
261 // Don't apply styles to the block editor's div element.
262 // This ensures what's rendered in the Gutenberg editor matches the frontend output for styling.
263 // See: https://github.com/WordPress/gutenberg/issues/32417.
264 '__experimentalSkipSerialization' => true,
265 ),
266 'typography' => array(
267 'fontSize' => true,
268 'lineHeight' => true,
269 ),
270 'spacing' => array(
271 'margin' => true,
272 'padding' => true,
273 ),
274 );
275
276 }
277
278 /**
279 * Returns this block's Fields
280 *
281 * @since 1.9.8.5
282 *
283 * @return bool|array
284 */
285 public function get_fields() {
286
287 // Get ConvertKit Products.
288 $products = array();
289 $convertkit_products = new ConvertKit_Resource_Products();
290 if ( $convertkit_products->exist() ) {
291 foreach ( $convertkit_products->get() as $product ) {
292 $products[ absint( $product['id'] ) ] = sanitize_text_field( $product['name'] );
293 }
294 }
295
296 // Gutenberg's built-in fields (such as styling, padding etc) don't need to be defined here, as they'll be included
297 // automatically by Gutenberg.
298 return array(
299 'product' => array(
300 'label' => __( 'Product', 'convertkit' ),
301 'type' => 'resource',
302 'resource' => 'products',
303 'values' => $products,
304 ),
305 'text' => array(
306 'label' => __( 'Button Text', 'convertkit' ),
307 'type' => 'text',
308 'description' => __( 'The text to display for the button.', 'convertkit' ),
309 ),
310 'discount_code' => array(
311 'label' => __( 'Discount Code', 'convertkit' ),
312 'type' => 'text',
313 'description' => __( 'Optional: A discount code to include. Must be defined in the Kit Product.', 'convertkit' ),
314 ),
315 'checkout' => array(
316 'label' => __( 'Load checkout step', 'convertkit' ),
317 'type' => 'toggle',
318 'description' => __( 'If enabled, immediately loads the checkout screen, instead of the Kit Product description.', 'convertkit' ),
319 ),
320 'disable_modal_on_mobile' => array(
321 'label' => __( 'Disable modal on mobile', 'convertkit' ),
322 'type' => 'toggle',
323 'description' => __( 'Recommended if the Kit Product is a digital download being purchased on mobile, to ensure the subscriber can immediately download the PDF once purchased.', 'convertkit' ),
324 ),
325
326 // These fields will only display on the shortcode, and are deliberately not registered in get_attributes(),
327 // because Gutenberg will register its own color pickers for link, background and text.
328 'background_color' => array(
329 'label' => __( 'Background color', 'convertkit' ),
330 'type' => 'color',
331 ),
332 'text_color' => array(
333 'label' => __( 'Text color', 'convertkit' ),
334 'type' => 'color',
335 ),
336 );
337
338 }
339
340 /**
341 * Returns this block's UI panels / sections.
342 *
343 * @since 1.9.8.5
344 *
345 * @return bool|array
346 */
347 public function get_panels() {
348
349 // Gutenberg's built-in fields (such as styling, padding etc) don't need to be defined here, as they'll be included
350 // automatically by Gutenberg.
351 return array(
352 'general' => array(
353 'label' => __( 'General', 'convertkit' ),
354 'fields' => array(
355 'product',
356 'text',
357 'discount_code',
358 'checkout',
359 'disable_modal_on_mobile',
360 'background_color',
361 'text_color',
362 ),
363 ),
364 );
365
366 }
367
368 /**
369 * Returns this block's Default Values
370 *
371 * @since 1.9.8.5
372 *
373 * @return array
374 */
375 public function get_default_values() {
376
377 return array(
378 'product' => '',
379 'text' => __( 'Buy my product', 'convertkit' ),
380 'discount_code' => '',
381 'checkout' => false,
382 'disable_modal_on_mobile' => false,
383 'background_color' => '',
384 'text_color' => '',
385
386 // Built-in Gutenberg block attributes.
387 'backgroundColor' => '',
388 'textColor' => '',
389 'fontSize' => '',
390 'style' => array(
391 'visualizers' => array(
392 'padding' => array(
393 'top' => '',
394 'bottom' => '',
395 'left' => '',
396 'right' => '',
397 ),
398 ),
399 ),
400 );
401
402 }
403
404 /**
405 * Returns the block's output, based on the supplied configuration attributes.
406 *
407 * @since 1.9.8.5
408 *
409 * @param array $atts Block / Shortcode / Page Builder Module Attributes.
410 * @return string
411 */
412 public function render( $atts ) {
413
414 // Parse attributes, defining fallback defaults if required
415 // and moving some attributes (such as Gutenberg's styles), if defined.
416 $atts = $this->sanitize_and_declare_atts( $atts );
417
418 // Setup Settings class.
419 $settings = new ConvertKit_Settings();
420
421 // Get Products Resource.
422 $convertkit_products = new ConvertKit_Resource_Products();
423
424 // Build HTML.
425 $html = $convertkit_products->get_html(
426 $atts['product'],
427 $atts['text'],
428 array(
429 'discount_code' => $atts['discount_code'],
430 'checkout' => $atts['checkout'],
431 'disable_modal' => ( $atts['disable_modal_on_mobile'] && wp_is_mobile() ),
432 'css_classes' => $this->get_css_classes( array( 'wp-block-button__link', 'wp-element-button' ) ),
433 'css_styles' => $this->get_css_styles( $atts ),
434 'return_as_span' => $this->is_block_editor_request(),
435 )
436 );
437
438 // Bail if an error occurred.
439 if ( is_wp_error( $html ) ) {
440 if ( $settings->debug_enabled() ) {
441 return '<!-- ' . $html->get_error_message() . ' -->';
442 }
443
444 return '';
445 }
446
447 /**
448 * Filter the block's content immediately before it is output.
449 *
450 * @since 1.9.8.5
451 *
452 * @param string $html ConvertKit Product button HTML.
453 * @param array $atts Block Attributes.
454 */
455 $html = apply_filters( 'convertkit_block_product_render', $html, $atts );
456
457 return $html;
458
459 }
460
461 }
462