PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.3
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.3
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 2.3.1 All 196 releases
← All changes | includes/blocks/class-convertkit-block-broadcasts.php +398 -101 2.2.23.4.3 View file →
@@ -26,30 +26,87 @@
26 26
27 27 // Register this as a Gutenberg block in the ConvertKit Plugin.
28 28 add_filter( 'convertkit_blocks', array( $this, 'register' ) );
29 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' ) );
30 + // Register this block's MCP abilities.
31 + add_filter( 'convertkit_abilities', array( $this, 'register_abilities' ) );
32 32
33 33 // Enqueue scripts and styles for this Gutenberg Block in the editor and frontend views.
34 34 add_action( 'convertkit_gutenberg_enqueue_scripts_editor_and_frontend', array( $this, 'enqueue_scripts' ) );
35 35 add_action( 'convertkit_gutenberg_enqueue_styles_editor_and_frontend', array( $this, 'enqueue_styles' ) );
36 36
37 - // Render Broadcasts block via AJAX.
38 - add_action( 'wp_ajax_nopriv_convertkit_broadcasts_render', array( $this, 'render_ajax' ) );
39 - add_action( 'wp_ajax_convertkit_broadcasts_render', array( $this, 'render_ajax' ) );
37 + // Register REST API routes.
38 + add_action( 'rest_api_init', array( $this, 'register_routes' ) );
40 39
41 40 }
42 41
43 42 /**
44 - * Enqueues scripts for this Gutenberg Block in the editor view.
43 + * Register REST API routes.
45 44 *
46 - * @since 2.0.1
45 + * @since 3.1.8
47 46 */
48 - public function enqueue_scripts_editor() {
47 + public function register_routes() {
49 48
50 - wp_enqueue_script( 'convertkit-gutenberg-block-broadcasts', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/gutenberg-block-broadcasts.js', array( 'convertkit-gutenberg' ), CONVERTKIT_PLUGIN_VERSION, true );
49 + register_rest_route(
50 + 'kit/v1',
51 + '/broadcasts',
52 + array(
53 + 'methods' => WP_REST_Server::READABLE,
54 + 'args' => array(
55 + 'date_format' => array(
56 + 'default' => $this->get_default_value( 'date_format' ),
57 + 'sanitize_callback' => 'sanitize_text_field',
58 + ),
59 + 'display_image' => array(
60 + 'default' => $this->get_default_value( 'display_image' ),
61 + 'sanitize_callback' => 'absint',
62 + ),
63 + 'display_description' => array(
64 + 'default' => $this->get_default_value( 'display_description' ),
65 + 'sanitize_callback' => 'absint',
66 + ),
67 + 'display_read_more' => array(
68 + 'default' => $this->get_default_value( 'display_read_more' ),
69 + 'sanitize_callback' => 'absint',
70 + ),
71 + 'read_more_label' => array(
72 + 'default' => $this->get_default_value( 'read_more_label' ),
73 + 'sanitize_callback' => 'sanitize_text_field',
74 + ),
75 + 'limit' => array(
76 + 'default' => $this->get_default_value( 'limit' ),
77 + 'sanitize_callback' => 'absint',
78 + ),
79 + 'page' => array(
80 + 'default' => $this->get_default_value( 'page' ),
81 + 'sanitize_callback' => 'absint',
82 + ),
83 + 'paginate' => array(
84 + 'default' => $this->get_default_value( 'paginate' ),
85 + 'sanitize_callback' => 'absint',
86 + ),
87 + 'paginate_label_next' => array(
88 + 'default' => $this->get_default_value( 'paginate_label_next' ),
89 + 'sanitize_callback' => 'sanitize_text_field',
90 + ),
91 + 'paginate_label_prev' => array(
92 + 'default' => $this->get_default_value( 'paginate_label_prev' ),
93 + 'sanitize_callback' => 'sanitize_text_field',
94 + ),
95 + 'link_color' => array(
96 + 'default' => $this->get_default_value( 'link_color' ),
97 + 'sanitize_callback' => 'sanitize_text_field',
98 + ),
99 + ),
100 + 'callback' => function ( $request ) {
101 + return rest_ensure_response( $this->render_ajax( $request ) );
102 + },
51 103
104 + // No authentication required, as this is on the frontend site.
105 + 'permission_callback' => '__return_true',
106 + )
107 + );
108 +
52 109 }
53 110
54 111 /**
55 112 * Enqueues scripts for this Gutenberg Block in the editor and frontend views.
@@ -60,23 +117,24 @@
60 117
61 118 // Get ConvertKit Settings.
62 119 $settings = new ConvertKit_Settings();
63 120
64 - wp_enqueue_script( 'convertkit-' . $this->get_name(), CONVERTKIT_PLUGIN_URL . 'resources/frontend/js/broadcasts.js', array( 'jquery' ), CONVERTKIT_PLUGIN_VERSION, true );
121 + // Enqueue frontend JS.
122 + convertkit_enqueue_frontend_js();
123 +
124 + // Define variables.
65 125 wp_localize_script(
66 - 'convertkit-' . $this->get_name(),
126 + 'convertkit-js',
67 127 'convertkit_broadcasts',
68 128 array(
69 - // WordPress AJAX URL endpoint.
70 - 'ajax_url' => admin_url( 'admin-ajax.php' ),
129 + // REST API URL endpoint.
130 + 'ajax_url' => rest_url( 'kit/v1/broadcasts' ),
71 131
72 - // AJAX action registered in __construct().
73 - 'action' => 'convertkit_broadcasts_render',
74 -
75 132 // Whether debugging is enabled.
76 133 'debug' => $settings->debug_enabled(),
77 134 )
78 135 );
136 +
79 137 }
80 138
81 139 /**
82 140 * Enqueues styles for this Gutenberg Block in the editor and frontend views.
@@ -84,9 +142,9 @@
84 142 * @since 1.9.7.4
85 143 */
86 144 public function enqueue_styles() {
87 145
88 - wp_enqueue_style( 'convertkit-' . $this->get_name(), CONVERTKIT_PLUGIN_URL . 'resources/frontend/css/broadcasts.css', array(), CONVERTKIT_PLUGIN_VERSION );
146 + convertkit_enqueue_frontend_css();
89 147
90 148 }
91 149
92 150 /**
@@ -105,8 +163,43 @@
105 163
106 164 }
107 165
108 166 /**
167 + * Returns this block's title.
168 + *
169 + * @since 3.1.1
170 + */
171 + public function get_title() {
172 +
173 + return __( 'Kit Broadcasts', 'convertkit' );
174 +
175 + }
176 +
177 + /**
178 + * Returns this block's plural title.
179 + *
180 + * @since 3.4.0
181 + *
182 + * @return string
183 + */
184 + public function get_title_plural() {
185 +
186 + return __( 'Kit Broadcasts', 'convertkit' );
187 +
188 + }
189 +
190 + /**
191 + * Returns this block's icon.
192 + *
193 + * @since 3.1.1
194 + */
195 + public function get_icon() {
196 +
197 + return 'resources/backend/images/block-icon-broadcasts.svg';
198 +
199 + }
200 +
201 + /**
109 202 * Returns this block's Title, Icon, Categories, Keywords and properties.
110 203 *
111 204 * @since 1.9.7.4
112 205 */
@@ -112,48 +205,59 @@
112 205 */
113 206 public function get_overview() {
114 207
115 208 // Fetch Posts.
116 - $posts = new ConvertKit_Resource_Posts( 'output_broadcasts' );
209 + $posts = new ConvertKit_Resource_Posts( 'output_broadcasts' );
210 + $settings = new ConvertKit_Settings();
117 211
118 212 return array(
119 - 'title' => __( 'ConvertKit Broadcasts', 'convertkit' ),
120 - 'description' => __( 'Displays a list of your ConvertKit broadcasts.', 'convertkit' ),
121 - 'icon' => 'resources/backend/images/block-icon-broadcasts.png',
122 - 'category' => 'convertkit',
123 - 'keywords' => array(
213 + 'title' => $this->get_title(),
214 + 'description' => __( 'Displays a list of your Kit broadcasts.', 'convertkit' ),
215 + 'icon' => $this->get_icon(),
216 + 'category' => 'convertkit',
217 + 'keywords' => array(
124 218 __( 'ConvertKit', 'convertkit' ),
219 + __( 'Kit', 'convertkit' ),
125 220 __( 'Broadcasts', 'convertkit' ),
126 221 __( 'Posts', 'convertkit' ),
127 222 ),
128 223
129 224 // Function to call when rendering as a block or a shortcode on the frontend web site.
130 - 'render_callback' => array( $this, 'render' ),
225 + 'render_callback' => array( $this, 'render' ),
131 226
132 227 // Shortcode: TinyMCE / QuickTags Modal Width and Height.
133 - 'modal' => array(
134 - 'width' => 500,
135 - 'height' => 580,
228 + 'modal' => array(
229 + 'width' => 650,
230 + 'height' => 455,
136 231 ),
137 232
138 233 // Shortcode: Include a closing [/shortcode] tag when using TinyMCE or QuickTag Modals.
139 - 'shortcode_include_closing_tag' => false,
234 + 'shortcode_include_closing_tag' => false,
140 235
141 236 // Gutenberg: Block Icon in Editor.
142 - 'gutenberg_icon' => convertkit_get_file_contents( CONVERTKIT_PLUGIN_PATH . '/resources/backend/images/block-icon-broadcasts.svg' ),
237 + 'gutenberg_icon' => convertkit_get_file_contents( CONVERTKIT_PLUGIN_PATH . '/resources/backend/images/block-icon-broadcasts.svg' ),
143 238
144 239 // Gutenberg: Example image showing how this block looks when choosing it in Gutenberg.
145 - 'gutenberg_example_image' => CONVERTKIT_PLUGIN_URL . 'resources/backend/images/block-example-broadcasts.png',
240 + 'gutenberg_example_image' => CONVERTKIT_PLUGIN_URL . 'resources/backend/images/block-example-broadcasts.png',
146 241
147 - // Gutenberg: Help description, displayed when no Posts exist.
148 - 'gutenberg_help_description' => __( 'No Broadcasts exist in ConvertKit. Send your first Broadcast in ConvertKit to see the link to it here.', 'convertkit' ),
242 + // Help descriptions, displayed when no Access Token / resources exist and this block/shortcode is added.
243 + 'no_access_token' => array(
244 + 'notice' => __( 'Not connected to Kit.', 'convertkit' ),
245 + 'link' => convertkit_get_setup_wizard_plugin_link(),
246 + 'link_text' => __( 'Click here to connect your Kit account.', 'convertkit' ),
247 + 'instruction_text' => __( 'Connect your Kit account at Settings > Kit, and then refresh this page to configure broadcasts to display.', 'convertkit' ),
248 + ),
249 + 'no_resources' => array(
250 + 'notice' => __( 'No broadcasts exist in Kit.', 'convertkit' ),
251 + 'link' => convertkit_get_new_broadcast_url(),
252 + 'link_text' => __( 'Click here to send your first broadcast.', 'convertkit' ),
253 + 'instruction_text' => __( 'Add a broadcast to your Kit account, and then refresh this page to configure broadcasts to display.', 'convertkit' ),
254 + ),
149 255
150 - // Gutenberg: JS function to call when rendering the block preview in the Gutenberg editor.
151 - // If not defined, render_callback above will be used.
152 - 'gutenberg_preview_render_callback' => 'convertKitGutenbergBroadcastsBlockRenderPreview',
153 -
154 - // Flag to determine if Broadcasts exist.
155 - 'has_posts' => $posts->exist(),
256 + // Whether an API Key exists in the Plugin, and are the required resources (broadcasts) available.
257 + // If no API Key is specified in the Plugin's settings, render the "No API Key" output.
258 + 'has_access_token' => $settings->has_access_and_refresh_token(),
259 + 'has_resources' => $posts->exist(),
156 260 );
157 261
158 262 }
159 263
@@ -165,12 +269,36 @@
165 269 public function get_attributes() {
166 270
167 271 return array(
168 272 // Block attributes.
273 + 'display_grid' => array(
274 + 'type' => 'boolean',
275 + 'default' => $this->get_default_value( 'display_grid' ),
276 + ),
277 + 'display_order' => array(
278 + 'type' => 'string',
279 + 'default' => $this->get_default_value( 'display_order' ),
280 + ),
169 281 'date_format' => array(
170 282 'type' => 'string',
171 283 'default' => $this->get_default_value( 'date_format' ),
172 284 ),
285 + 'display_image' => array(
286 + 'type' => 'boolean',
287 + 'default' => $this->get_default_value( 'display_image' ),
288 + ),
289 + 'display_description' => array(
290 + 'type' => 'boolean',
291 + 'default' => $this->get_default_value( 'display_description' ),
292 + ),
293 + 'display_read_more' => array(
294 + 'type' => 'boolean',
295 + 'default' => $this->get_default_value( 'display_read_more' ),
296 + ),
297 + 'read_more_label' => array(
298 + 'type' => 'string',
299 + 'default' => $this->get_default_value( 'read_more_label' ),
300 + ),
173 301 'limit' => array(
174 302 'type' => 'number',
175 303 'default' => $this->get_default_value( 'limit' ),
176 304 ),
@@ -190,9 +318,9 @@
190 318 'type' => 'string',
191 319 'default' => $this->get_default_value( 'paginate_label_next' ),
192 320 ),
193 321
194 - // get_supports() color attribute.
322 + // get_supports() style, color and typography attributes.
195 323 'style' => array(
196 324 'type' => 'object',
197 325 ),
198 326 'backgroundColor' => array(
@@ -200,8 +328,11 @@
200 328 ),
201 329 'textColor' => array(
202 330 'type' => 'string',
203 331 ),
332 + 'fontSize' => array(
333 + 'type' => 'string',
334 + ),
204 335
205 336 // Always required for Gutenberg.
206 337 'is_gutenberg_example' => array(
207 338 'type' => 'boolean',
@@ -220,14 +351,22 @@
220 351 */
221 352 public function get_supports() {
222 353
223 354 return array(
224 - 'className' => true,
225 - 'color' => array(
355 + 'className' => true,
356 + 'color' => array(
226 357 'link' => true,
227 358 'background' => true,
228 359 'text' => true,
229 360 ),
361 + 'typography' => array(
362 + 'fontSize' => true,
363 + 'lineHeight' => true,
364 + ),
365 + 'spacing' => array(
366 + 'margin' => true,
367 + 'padding' => true,
368 + ),
230 369 );
231 370
232 371 }
233 372
@@ -239,14 +378,22 @@
239 378 * @return bool|array
240 379 */
241 380 public function get_fields() {
242 381
243 - // Bail if the request is not for the WordPress Administration or frontend editor.
244 - if ( ! WP_ConvertKit()->is_admin_or_frontend_editor() ) {
245 - return false;
246 - }
247 -
248 382 return array(
383 + 'display_grid' => array(
384 + 'label' => __( 'Display as grid', 'convertkit' ),
385 + 'type' => 'toggle',
386 + 'description' => __( 'If enabled, displays broadcasts in a grid, instead of a list.', 'convertkit' ),
387 + ),
388 + 'display_order' => array(
389 + 'label' => __( 'Display order', 'convertkit' ),
390 + 'type' => 'select',
391 + 'values' => array(
392 + 'date-broadcast' => __( 'Date, Broadcast', 'convertkit' ),
393 + 'broadcast-date' => __( 'Broadcast, Date', 'convertkit' ),
394 + ),
395 + ),
249 396 'date_format' => array(
250 397 'label' => __( 'Date format', 'convertkit' ),
251 398 'type' => 'select',
252 399 'values' => array(
@@ -255,8 +402,29 @@
255 402 'm/d/Y' => date_i18n( 'm/d/Y', strtotime( 'now' ) ),
256 403 'd/m/Y' => date_i18n( 'd/m/Y', strtotime( 'now' ) ),
257 404 ),
258 405 ),
406 + 'display_image' => array(
407 + 'label' => __( 'Display images', 'convertkit' ),
408 + 'type' => 'toggle',
409 + ),
410 + 'display_description' => array(
411 + 'label' => __( 'Display descriptions', 'convertkit' ),
412 + 'type' => 'toggle',
413 + ),
414 + 'display_read_more' => array(
415 + 'label' => __( 'Display read more links', 'convertkit' ),
416 + 'type' => 'toggle',
417 + ),
418 + 'read_more_label' => array(
419 + 'label' => __( 'Read more label', 'convertkit' ),
420 + 'type' => 'text',
421 + 'description' => __( 'The label to display for the "read more" link below each broadcast.', 'convertkit' ),
422 + 'display_if' => array(
423 + 'key' => 'display_read_more',
424 + 'value' => 1,
425 + ),
426 + ),
259 427 'limit' => array(
260 428 'label' => __( 'Number of posts', 'convertkit' ),
261 429 'type' => 'number',
262 430 'min' => 1,
@@ -271,13 +439,21 @@
271 439 'paginate_label_prev' => array(
272 440 'label' => __( 'Newer posts label', 'convertkit' ),
273 441 'type' => 'text',
274 442 'description' => __( 'The label to display for the link to newer broadcasts.', 'convertkit' ),
443 + 'display_if' => array(
444 + 'key' => 'paginate',
445 + 'value' => 1,
446 + ),
275 447 ),
276 448 'paginate_label_next' => array(
277 449 'label' => __( 'Older posts label', 'convertkit' ),
278 450 'type' => 'text',
279 451 'description' => __( 'The label to display for the link to older broadcasts.', 'convertkit' ),
452 + 'display_if' => array(
453 + 'key' => 'paginate',
454 + 'value' => 1,
455 + ),
280 456 ),
281 457
282 458 // These fields will only display on the shortcode, and are deliberately not registered in get_attributes(),
283 459 // because Gutenberg will register its own color pickers for link, background and text.
@@ -305,22 +481,33 @@
305 481 * @return bool|array
306 482 */
307 483 public function get_panels() {
308 484
309 - // Bail if the request is not for the WordPress Administration or frontend editor.
310 - if ( ! WP_ConvertKit()->is_admin_or_frontend_editor() ) {
311 - return false;
312 - }
313 -
314 485 return array(
315 - 'general' => array(
486 + 'general' => array(
316 487 'label' => __( 'General', 'convertkit' ),
317 488 'fields' => array(
489 + 'display_grid',
490 + 'display_order',
318 491 'date_format',
492 + 'display_image',
493 + 'display_description',
494 + 'display_read_more',
495 + 'read_more_label',
496 + ),
497 + ),
498 + 'pagination' => array(
499 + 'label' => __( 'Pagination', 'convertkit' ),
500 + 'fields' => array(
319 501 'limit',
320 502 'paginate',
321 503 'paginate_label_prev',
322 504 'paginate_label_next',
505 + ),
506 + ),
507 + 'styles' => array(
508 + 'label' => __( 'Styles', 'convertkit' ),
509 + 'fields' => array(
323 510 'link_color',
324 511 'background_color',
325 512 'text_color',
326 513 ),
@@ -338,9 +525,15 @@
338 525 */
339 526 public function get_default_values() {
340 527
341 528 return array(
529 + 'display_grid' => false,
530 + 'display_order' => 'date-broadcast',
342 531 'date_format' => 'F j, Y',
532 + 'display_image' => false,
533 + 'display_description' => false,
534 + 'display_read_more' => false,
535 + 'read_more_label' => __( 'Read more', 'convertkit' ),
343 536 'limit' => 10,
344 537 'paginate' => false,
345 538 'paginate_label_prev' => __( 'Previous', 'convertkit' ),
346 539 'paginate_label_next' => __( 'Next', 'convertkit' ),
@@ -363,10 +556,10 @@
363 556 * Returns the block's output, based on the supplied configuration attributes.
364 557 *
365 558 * @since 1.9.7.4
366 559 *
367 - * @param array $atts Block / Shortcode Attributes.
368 - * @return string Output
560 + * @param array $atts Block / Shortcode / Page Builder Module Attributes.
561 + * @return string
369 562 */
370 563 public function render( $atts ) {
371 564
372 565 // Parse attributes, defining fallback defaults if required
@@ -378,19 +571,12 @@
378 571
379 572 // Fetch Posts.
380 573 $posts = new ConvertKit_Resource_Posts( 'output_broadcasts' );
381 574
382 - // If this is an admin request, refresh the Posts resource now from the API,
383 - // as it's an inexpensive query of ~ 0.5 seconds when we're editing a Page
384 - // containing this block.
385 - if ( function_exists( 'is_admin' ) && is_admin() ) {
386 - $posts->refresh();
387 - }
388 -
389 575 // If no Posts exist, bail.
390 576 if ( ! $posts->exist() ) {
391 577 if ( $settings->debug_enabled() ) {
392 - return '<!-- ' . __( 'No Broadcasts exist in ConvertKit.', 'convertkit' ) . ' -->';
578 + return '<!-- ' . __( 'No Broadcasts exist in Kit.', 'convertkit' ) . ' -->';
393 579 }
394 580
395 581 return '';
396 582 }
@@ -395,9 +581,29 @@
395 581 return '';
396 582 }
397 583
398 584 // Build HTML.
399 - $html = $this->build_html( $posts, $atts );
585 + if ( $this->is_block_editor_request() ) {
586 + // For the block editor, don't include compiled CSS classes and styles,
587 + // as the block editor will add these to the parent container.
588 + // Otherwise the block will render incorrectly with double padding, double margins etc.
589 + $html = $this->build_html(
590 + $posts,
591 + $atts,
592 + true,
593 + array(
594 + 'convertkit-' . $this->get_name(),
595 + )
596 + );
597 + } else {
598 + $html = $this->build_html(
599 + $posts,
600 + $atts,
601 + true,
602 + $this->get_css_classes(),
603 + $this->get_css_styles( $atts )
604 + );
605 + }
400 606
401 607 /**
402 608 * Filter the block's content immediately before it is output.
403 609 *
@@ -402,10 +608,10 @@
402 608 * Filter the block's content immediately before it is output.
403 609 *
404 610 * @since 1.9.7.4
405 611 *
406 - * @param string $html ConvertKit Broadcasts HTML.
407 - * @param array $atts Block Attributes.
612 + * @param string $html ConvertKit Broadcasts HTML.
613 + * @param array $atts Block Attributes.
408 614 */
409 615 $html = apply_filters( 'convertkit_block_broadcasts_render', $html, $atts );
410 616
411 617 return $html;
@@ -416,23 +622,27 @@
416 622 * Returns the block's output, based on the supplied configuration attributes,
417 623 * when requested via AJAX.
418 624 *
419 625 * @since 1.9.7.6
626 + *
627 + * @param WP_REST_Request $request The REST request.
628 + * @return string
420 629 */
421 - public function render_ajax() {
630 + public function render_ajax( $request ) {
422 631
423 - // Check nonce.
424 - check_ajax_referer( 'convertkit-broadcasts', 'nonce' );
425 -
426 632 // Build attributes array.
427 633 $atts = array(
428 - 'date_format' => stripslashes( sanitize_text_field( $_REQUEST['date_format'] ) ),
429 - 'limit' => stripslashes( sanitize_text_field( $_REQUEST['limit'] ) ),
430 - 'page' => absint( $_REQUEST['page'] ),
431 - 'paginate' => absint( $_REQUEST['paginate'] ),
432 - 'paginate_label_next' => stripslashes( sanitize_text_field( $_REQUEST['paginate_label_next'] ) ),
433 - 'paginate_label_prev' => stripslashes( sanitize_text_field( $_REQUEST['paginate_label_prev'] ) ),
434 - 'link_color' => stripslashes( sanitize_text_field( $_REQUEST['link_color'] ) ),
634 + 'date_format' => $request->get_param( 'date_format' ),
635 + 'display_image' => $request->get_param( 'display_image' ),
636 + 'display_description' => $request->get_param( 'display_description' ),
637 + 'display_read_more' => $request->get_param( 'display_read_more' ),
638 + 'read_more_label' => $request->get_param( 'read_more_label' ),
639 + 'limit' => $request->get_param( 'limit' ),
640 + 'page' => $request->get_param( 'page' ),
641 + 'paginate' => $request->get_param( 'paginate' ),
642 + 'paginate_label_next' => $request->get_param( 'paginate_label_next' ),
643 + 'paginate_label_prev' => $request->get_param( 'paginate_label_prev' ),
644 + 'link_color' => $request->get_param( 'link_color' ),
435 645 );
436 646
437 647 // Parse attributes, defining fallback defaults if required
438 648 // and moving some attributes (such as Gutenberg's styles), if defined.
@@ -437,11 +647,23 @@
437 647 // Parse attributes, defining fallback defaults if required
438 648 // and moving some attributes (such as Gutenberg's styles), if defined.
439 649 $atts = $this->sanitize_and_declare_atts( $atts );
440 650
651 + // Setup Settings class.
652 + $settings = new ConvertKit_Settings();
653 +
441 654 // Fetch Posts.
442 655 $posts = new ConvertKit_Resource_Posts( 'output_broadcasts' );
443 656
657 + // If no Posts exist, bail.
658 + if ( ! $posts->exist() ) {
659 + if ( $settings->debug_enabled() ) {
660 + return '<!-- ' . __( 'No Broadcasts exist in Kit.', 'convertkit' ) . ' -->';
661 + }
662 +
663 + return '';
664 + }
665 +
444 666 // Build HTML.
445 667 $html = $this->build_html( $posts, $atts, false );
446 668
447 669 /**
@@ -454,10 +676,9 @@
454 676 * @param array $atts Block Attributes.
455 677 */
456 678 $html = apply_filters( 'convertkit_block_broadcasts_render_ajax', $html, $atts );
457 679
458 - // Send HTML as response.
459 - wp_send_json_success( $html );
680 + return $html;
460 681
461 682 }
462 683
463 684 /**
@@ -468,11 +689,13 @@
468 689 *
469 690 * @param ConvertKit_Resource_Posts $posts ConvertKit Posts Resource class.
470 691 * @param array $atts Block attributes.
471 692 * @param bool $include_container Include container div in HTML.
472 - * @return string HTML
693 + * @param array $css_classes CSS classes to apply to block.
694 + * @param array $css_styles CSS inline styles to apply to block.
695 + * @return string
473 696 */
474 - private function build_html( $posts, $atts, $include_container = true ) {
697 + private function build_html( $posts, $atts, $include_container = true, $css_classes = array(), $css_styles = array() ) {
475 698
476 699 // Get paginated subset of Posts.
477 700 $broadcasts = $posts->get_paginated_subset( $atts['page'], $atts['limit'] );
478 701
@@ -483,34 +706,18 @@
483 706 $html = '';
484 707
485 708 // Include container, if required.
486 709 if ( $include_container ) {
487 - $html = '<div class="' . implode( ' ', map_deep( $atts['_css_classes'], 'sanitize_html_class' ) ) . '" style="' . implode( ';', map_deep( $atts['_css_styles'], 'esc_attr' ) ) . '" ' . $this->get_atts_as_html_data_attributes( $atts ) . '>';
710 + $html .= '<div class="' . implode( ' ', map_deep( $css_classes, 'sanitize_html_class' ) ) . '" style="' . implode( ';', map_deep( $css_styles, 'esc_attr' ) ) . '" ' . $this->get_atts_as_html_data_attributes( $atts ) . '>';
488 711 }
489 712
490 713 // Start list.
491 714 $html .= '<ul class="convertkit-broadcasts-list">';
492 715
493 - // Iterate through broadcasts.
716 + // Iterate through broadcasts, building HTML list items.
494 717 foreach ( $broadcasts['items'] as $count => $broadcast ) {
495 - // Convert UTC date to timestamp.
496 - $date_timestamp = strtotime( $broadcast['published_at'] );
497 -
498 - // Build broadcast URL.
499 - $url = add_query_arg(
500 - array(
501 - 'utm_source' => 'wordpress',
502 - 'utm_term' => get_locale(),
503 - 'utm_content' => 'convertkit',
504 - ),
505 - $broadcast['url']
506 - );
507 -
508 718 // Add broadcast as list item.
509 - $html .= '<li class="convertkit-broadcast">
510 - <time datetime="' . esc_attr( date_i18n( 'Y-m-d', $date_timestamp ) ) . '">' . esc_html( date_i18n( $atts['date_format'], $date_timestamp ) ) . '</time>
511 - <a href="' . esc_attr( $url ) . '" target="_blank" rel="nofollow noopener"' . $this->get_link_style_tag( $atts ) . '>' . esc_html( $broadcast['title'] ) . '</a>
512 - </li>';
719 + $html .= $this->build_html_list_item( $broadcast, $atts );
513 720 }
514 721
515 722 // End list.
516 723 $html .= '</ul>';
@@ -545,8 +752,18 @@
545 752 if ( $include_container ) {
546 753 $html .= '</div>';
547 754 }
548 755
756 + /**
757 + * Filter the block's content immediately before it is output.
758 + *
759 + * @since 2.2.3
760 + *
761 + * @param string $html ConvertKit Broadcasts HTML.
762 + * @param array $atts Block Attributes.
763 + */
764 + $html = apply_filters( 'convertkit_block_broadcasts_render', $html, $atts );
765 +
549 766 // Return.
550 767 return $html;
551 768
552 769 }
@@ -551,8 +768,88 @@
551 768
552 769 }
553 770
554 771 /**
772 + * Defines the HTML for an individual broadcast item in the Broadcasts block.
773 + *
774 + * @since 2.2.3
775 + *
776 + * @param array $broadcast Broadcast.
777 + * @param array $atts Block attributes.
778 + * @return string HTML
779 + */
780 + private function build_html_list_item( $broadcast, $atts ) {
781 +
782 + // Convert UTC date to timestamp.
783 + $date_timestamp = strtotime( $broadcast['published_at'] );
784 +
785 + // Build broadcast URL.
786 + $url = add_query_arg(
787 + array(
788 + 'utm_source' => 'wordpress',
789 + 'utm_term' => get_locale(),
790 + 'utm_content' => 'convertkit',
791 + ),
792 + $broadcast['url']
793 + );
794 +
795 + // Build HTML.
796 + $html = '<li class="convertkit-broadcast">';
797 +
798 + // Display date.
799 + $html .= '<time datetime="' . esc_attr( date_i18n( 'Y-m-d', $date_timestamp ) ) . '">' . esc_html( date_i18n( $atts['date_format'], $date_timestamp ) ) . '</time>';
800 +
801 + // Display linked title.
802 + $html .= '<a href="' . esc_url( $url ) . '" target="_blank" rel="nofollow noopener"' . $this->get_link_style_tag( $atts ) . ' class="convertkit-broadcast-title">' . esc_html( $broadcast['title'] ) . '</a>';
803 +
804 + // Display image.
805 + // We check for thumbnail_url, as these were added to the API in https://github.com/ConvertKit/convertkit/pull/23938,
806 + // and might not immediately be available until the resources are refreshed.
807 + if ( $atts['display_image'] && array_key_exists( 'thumbnail_url', $broadcast ) && ! is_null( $broadcast['thumbnail_url'] ) ) {
808 + $html .= '<a href="' . esc_url( $url ) . '" target="_blank" rel="nofollow noopener" class="convertkit-broadcast-image">
809 + <img src="' . esc_url( $broadcast['thumbnail_url'] ) . '" alt="' . esc_attr( $broadcast['thumbnail_alt'] ) . '" />
810 + </a>';
811 + }
812 +
813 + // Display description / read more.
814 + if ( $atts['display_description'] || $atts['display_read_more'] ) {
815 + $html .= '<span class="convertkit-broadcast-text">';
816 +
817 + // Display description.
818 + // We check for description, as these were added to the API in https://github.com/ConvertKit/convertkit/pull/23938,
819 + // and might not immediately be available until the resources are refreshed.
820 + if ( $atts['display_description'] && array_key_exists( 'description', $broadcast ) && ! is_null( $broadcast['description'] ) ) {
821 + $html .= '<span class="convertkit-broadcast-description">' . esc_html( $broadcast['description'] ) . '</span>';
822 + }
823 +
824 + // Display read more link.
825 + if ( $atts['display_read_more'] ) {
826 + $html .= '<a href="' . esc_url( $url ) . '" target="_blank" rel="nofollow noopener" class="convertkit-broadcast-read-more">' . esc_html( $atts['read_more_label'] ) . '</a>';
827 + }
828 +
829 + $html .= '</span>';
830 + }
831 +
832 + // Close list item.
833 + $html .= '</li>';
834 +
835 + /**
836 + * Defines the HTML for an individual broadcast item in the Broadcasts block.
837 + *
838 + * @since 2.2.3
839 + *
840 + * @param string $html HTML.
841 + * @param array $broadcast Broadcast.
842 + * @param array $atts Block attributes.
843 + * @return string HTML
844 + */
845 + $html = apply_filters( 'convertkit_block_broadcasts_build_html_list_item', $html, $broadcast, $atts );
846 +
847 + return $html;
848 +
849 + }
850 +
851 + /**
555 852 * Returns the HTML link to paginate to the previous page, to view
556 853 * newer broadcasts.
557 854 *
558 855 * @since 1.9.7.6
@@ -562,9 +859,9 @@
562 859 * @return string HTML Link
563 860 */
564 861 private function get_pagination_link_prev_html( $atts, $nonce ) {
565 862
566 - return '<a href="' . esc_attr( $this->get_pagination_link( $atts['page'] - 1, $nonce ) ) . '" title="' . esc_attr( $atts['paginate_label_prev'] ) . '" data-page="' . esc_attr( (string) ( $atts['page'] - 1 ) ) . '" data-nonce="' . esc_attr( $nonce ) . '"' . $this->get_link_style_tag( $atts ) . '>
863 + return '<a href="' . esc_url( $this->get_pagination_link( $atts['page'] - 1, $nonce ) ) . '" title="' . esc_attr( $atts['paginate_label_prev'] ) . '" data-page="' . esc_attr( (string) ( $atts['page'] - 1 ) ) . '" data-nonce="' . esc_attr( $nonce ) . '"' . $this->get_link_style_tag( $atts ) . '>
567 864 ' . esc_html( $atts['paginate_label_prev'] ) . '
568 865 </a>';
569 866
570 867 }
@@ -580,9 +877,9 @@
580 877 * @return string HTML Link
581 878 */
582 879 private function get_pagination_link_next_html( $atts, $nonce ) {
583 880
584 - return '<a href="' . esc_attr( $this->get_pagination_link( $atts['page'] + 1, $nonce ) ) . '" title="' . esc_attr( $atts['paginate_label_next'] ) . '" data-page="' . esc_attr( (string) ( $atts['page'] + 1 ) ) . '" data-nonce="' . esc_attr( $nonce ) . '"' . $this->get_link_style_tag( $atts ) . '>
881 + return '<a href="' . esc_url( $this->get_pagination_link( $atts['page'] + 1, $nonce ) ) . '" title="' . esc_attr( $atts['paginate_label_next'] ) . '" data-page="' . esc_attr( (string) ( $atts['page'] + 1 ) ) . '" data-nonce="' . esc_attr( $nonce ) . '"' . $this->get_link_style_tag( $atts ) . '>
585 882 ' . esc_html( $atts['paginate_label_next'] ) . '
586 883 </a>';
587 884
588 885 }