PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 2.7.5
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v2.7.5
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 / admin / section / class-convertkit-admin-section-broadcasts.php

class-convertkit-admin-section-broadcasts.php in Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages 2.7.5, at admin/section/class-convertkit-admin-section-broadcasts.php

662 lines 19.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * ConvertKit Settings Broadcasts class.
4 *
5 * @package ConvertKit
6 * @author ConvertKit
7 */
8
9 /**
10 * Registers Broadcasts Settings that can be edited at Settings > Kit > Broadcasts.
11 *
12 * @package ConvertKit
13 * @author ConvertKit
14 */
15 class ConvertKit_Admin_Section_Broadcasts extends ConvertKit_Admin_Section_Base {
16
17 /**
18 * Constructor.
19 *
20 * @since 2.2.9
21 */
22 public function __construct() {
23
24 // Define the class that reads/writes settings.
25 $this->settings = new ConvertKit_Settings_Broadcasts();
26
27 // Define the settings key.
28 $this->settings_key = $this->settings::SETTINGS_NAME;
29
30 // Define the programmatic name, Title and Tab Text.
31 $this->name = 'broadcasts';
32 $this->title = __( 'Broadcasts', 'convertkit' );
33 $this->tab_text = __( 'Broadcasts', 'convertkit' );
34
35 // Identify that this is beta functionality.
36 $this->is_beta = true;
37
38 // Define settings sections.
39 $this->settings_sections = array(
40 'general' => array(
41 'title' => $this->title,
42 'callback' => array( $this, 'print_section_info' ),
43 'wrap' => true,
44 ),
45 );
46
47 // Register and maybe output notices for this settings screen, and the Intercom messenger.
48 if ( $this->on_settings_screen( $this->name ) ) {
49 add_filter( 'convertkit_settings_base_register_notices', array( $this, 'register_notices' ) );
50 add_action( 'convertkit_settings_base_render_before', array( $this, 'maybe_output_notices' ) );
51 add_action( 'admin_footer', array( $this, 'output_intercom' ) );
52 }
53
54 // Enqueue scripts and CSS.
55 add_action( 'convertkit_admin_settings_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
56 add_action( 'convertkit_admin_settings_enqueue_styles', array( $this, 'enqueue_styles' ) );
57
58 parent::__construct();
59
60 $this->maybe_import_now();
61
62 }
63
64 /**
65 * Registers success and error notices for the Tools screen, to be displayed
66 * depending on the action.
67 *
68 * @since 2.5.1
69 *
70 * @param array $notices Regsitered success and error notices.
71 * @return array
72 */
73 public function register_notices( $notices ) {
74
75 return array_merge(
76 $notices,
77 array(
78 'broadcast_import_error' => __( 'Broadcasts import failed. Please try again.', 'convertkit' ),
79 'broadcast_import_success' => __( 'Broadcasts import started. Check the Posts screen shortly to confirm Broadcasts imported successfully.', 'convertkit' ),
80 )
81 );
82
83 }
84
85 /**
86 * Import Broadcasts now, if requested through the UI.
87 *
88 * @since 2.2.9
89 */
90 private function maybe_import_now() {
91
92 // Bail if nonce verification fails.
93 if ( ! isset( $_REQUEST['_convertkit_settings_broadcasts_nonce'] ) ) {
94 return false;
95 }
96 if ( ! wp_verify_nonce( sanitize_key( $_REQUEST['_convertkit_settings_broadcasts_nonce'] ), 'convertkit-settings-broadcasts' ) ) {
97 return false;
98 }
99
100 // Run the import task through WordPress' Cron system now.
101 $cron = new ConvertKit_Cron();
102 $result = $cron->run( 'convertkit_resource_refresh_posts' );
103
104 // If an error occured, show it now.
105 if ( is_wp_error( $result ) ) {
106 // Redirect to Broadcasts screen with error.
107 $this->redirect_with_error_description( $result->get_error_message() );
108 return;
109 }
110
111 // If here, the task scheduled.
112 // Redirect with success notice.
113 $this->redirect_with_success_notice( 'broadcast_import_success' );
114
115 }
116
117 /**
118 * Enqueues scripts for the Settings > Broadcasts screen.
119 *
120 * @since 2.2.9
121 *
122 * @param string $section Settings section / tab (general|tools|restrict-content|broadcasts).
123 */
124 public function enqueue_scripts( $section ) {
125
126 // Bail if we're not on the Broadcasts section.
127 if ( $section !== $this->name ) {
128 return;
129 }
130
131 // Enqueue Select2 JS.
132 convertkit_select2_enqueue_scripts();
133
134 // Enqueue JS.
135 wp_enqueue_script( 'convertkit-admin-settings-conditional-display', CONVERTKIT_PLUGIN_URL . 'resources/backend/js/settings-conditional-display.js', array( 'jquery' ), CONVERTKIT_PLUGIN_VERSION, true );
136
137 }
138
139 /**
140 * Enqueues styles for the Settings > General screen.
141 *
142 * @since 2.2.9
143 *
144 * @param string $section Settings section / tab (general|tools|restrict-content|broadcasts).
145 */
146 public function enqueue_styles( $section ) {
147
148 // Bail if we're not on the Broadcasts section.
149 if ( $section !== $this->name ) {
150 return;
151 }
152
153 // Enqueue Select2 CSS.
154 convertkit_select2_enqueue_styles();
155
156 }
157
158 /**
159 * Registers settings fields for this section.
160 *
161 * @since 2.2.9
162 */
163 public function register_fields() {
164
165 // Check if DOMDocument is installed.
166 // It should be installed as mosts hosts include php-dom and php-xml modules.
167 // If not, disable Broadcast to Posts import functionality as we can't parse
168 // imported Broadcasts.
169 if ( ! class_exists( 'DOMDocument' ) ) {
170 // Disable saving settings.
171 $this->save_disabled = true;
172
173 // Return if we're not on the Plugin settings screen.
174 if ( ! $this->on_settings_screen( 'broadcasts' ) ) {
175 return;
176 }
177
178 // Output a notice if we're on the Broadcasts settings screen.
179 $this->output_error(
180 __( 'Importing public broadcasts from Kit requires the PHP extensions `php-dom` and `php-xml` to be installed. Work with your web host to do this, and reload the page when done.', 'convertkit' )
181 );
182 return;
183 }
184
185 // Initialize classes that will be used.
186 $posts = new ConvertKit_Resource_Posts( 'cron' );
187
188 // Define description for the 'Enabled' setting.
189 // If enabled, include the next scheduled date and time the Plugin will import broadcasts.
190 // If the next scheduled timestamp is 1, the event is running now.
191 $enabled_description = '';
192 if ( $this->settings->enabled() && $posts->get_cron_event_next_scheduled() && $posts->get_cron_event_next_scheduled() > 1 ) {
193 $enabled_description = sprintf(
194 '%s %s<br />%s <strong>%s</strong> %s',
195 esc_html__( 'Broadcasts will next import at approximately ', 'convertkit' ),
196 // The cron event's next scheduled timestamp is always in UTC.
197 // Display it converted to the WordPress site's timezone.
198 get_date_from_gmt(
199 gmdate( 'Y-m-d H:i:s', $posts->get_cron_event_next_scheduled() ),
200 get_option( 'date_format' ) . ' ' . get_option( 'time_format' )
201 ),
202 esc_html__( 'Broadcasts', 'convertkit' ),
203 esc_html__( 'must', 'convertkit' ),
204 esc_html__( 'have their "Enabled on public feeds" setting enabled in Kit, to be eligible for import.', 'convertkit' )
205 );
206 }
207
208 add_settings_field(
209 'enabled',
210 __( 'Enable Automatic Import', 'convertkit' ),
211 array( $this, 'enable_callback' ),
212 $this->settings_key,
213 $this->name,
214 array(
215 'name' => 'enabled',
216 'label_for' => 'enabled',
217 'label' => __( 'Enables automatic publication of public Kit Broadcasts as WordPress Posts.', 'convertkit' ),
218 'description' => $enabled_description,
219 )
220 );
221
222 // Render import button if the feature is enabled.
223 if ( $this->settings->enabled() && $posts->get_cron_event_next_scheduled() ) {
224 add_settings_field(
225 'import_button',
226 '',
227 array( $this, 'import_button_callback' ),
228 $this->settings_key,
229 $this->name
230 );
231 }
232
233 add_settings_field(
234 'post_status',
235 __( 'Status', 'convertkit' ),
236 array( $this, 'post_status_callback' ),
237 $this->settings_key,
238 $this->name,
239 array(
240 'name' => 'post_status',
241 'label_for' => 'post_status',
242 'description' => __( 'The WordPress Post status to assign imported public broadcasts to.', 'convertkit' ),
243 )
244 );
245
246 add_settings_field(
247 'author_id',
248 __( 'Author', 'convertkit' ),
249 array( $this, 'author_id_callback' ),
250 $this->settings_key,
251 $this->name,
252 array(
253 'name' => 'author_id',
254 'label_for' => 'author_id',
255 'description' => __( 'The WordPress User to set as the author for WordPress Posts created from imported public broadcasts.', 'convertkit' ),
256 )
257 );
258
259 add_settings_field(
260 'category_id',
261 __( 'Category', 'convertkit' ),
262 array( $this, 'category_callback' ),
263 $this->settings_key,
264 $this->name,
265 array(
266 'name' => 'category_id',
267 'label_for' => 'category_id',
268 'description' => __( 'The category to assign imported public broadcasts to.', 'convertkit' ),
269 )
270 );
271
272 add_settings_field(
273 'import_thumbnail',
274 __( 'Include Thumbnail', 'convertkit' ),
275 array( $this, 'import_thumbnail_callback' ),
276 $this->settings_key,
277 $this->name,
278 array(
279 'name' => 'import_thumbnail',
280 'label_for' => 'import_thumbnail',
281 'label' => __( 'If enabled, the Broadcast\'s thumbnail will be used as the WordPress Post\'s featured image.', 'convertkit' ),
282 'description' => '',
283 )
284 );
285
286 add_settings_field(
287 'import_images',
288 __( 'Import Images', 'convertkit' ),
289 array( $this, 'import_images_callback' ),
290 $this->settings_key,
291 $this->name,
292 array(
293 'name' => 'import_images',
294 'label_for' => 'import_images',
295 'label' => __( 'If enabled, the imported Broadcast\'s inline images will be stored in the Media Library, instead of served by Kit.', 'convertkit' ),
296 'description' => '',
297 )
298 );
299
300 add_settings_field(
301 'published_at_min_date',
302 __( 'Earliest Date', 'convertkit' ),
303 array( $this, 'date_callback' ),
304 $this->settings_key,
305 $this->name,
306 array(
307 'name' => 'published_at_min_date',
308 'label_for' => 'published_at_min_date',
309 'description' => __( 'The earliest date to import public broadcasts from, based on the broadcast\'s published date and time.', 'convertkit' ),
310 )
311 );
312
313 add_settings_field(
314 'enabled_export',
315 __( 'Enable Export Actions', 'convertkit' ),
316 array( $this, 'enable_export_callback' ),
317 $this->settings_key,
318 $this->name,
319 array(
320 'name' => 'enabled_export',
321 'label_for' => 'enabled_export',
322 'label' => __( 'Displays actions in WordPress to create draft broadcasts from existing WordPress posts.', 'convertkit' ),
323 )
324 );
325
326 add_settings_field(
327 'no_styles',
328 __( 'Disable Styles', 'convertkit' ),
329 array( $this, 'no_styles_callback' ),
330 $this->settings_key,
331 $this->name,
332 array(
333 'name' => 'no_styles',
334 'label_for' => 'no_styles',
335 'description' => __( 'Removes inline styles and layout when importing broadcasts and exporting posts.', 'convertkit' ),
336 )
337 );
338
339 }
340
341 /**
342 * Prints help info for this section
343 *
344 * @since 2.2.9
345 */
346 public function print_section_info() {
347
348 ?>
349 <span class="convertkit-beta-label"><?php esc_html_e( 'Beta', 'convertkit' ); ?></span>
350 <p class="description"><?php esc_html_e( 'Defines whether public broadcasts ("Enabled on public feeds") in Kit should automatically be published on this site as WordPress Posts, and whether to enable options to create draft Kit Broadcasts from WordPress Posts.', 'convertkit' ); ?></p>
351 <?php
352
353 // If the DISABLE_WP_CRON constant exists and is true, display a warning that this functionality
354 // may not work.
355 if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON === true ) { // @phpstan-ignore-line Constant is not always true.
356 ?>
357 <div class="notice notice-info">
358 <p>
359 <?php
360 printf(
361 '%s %s %s %s %s',
362 esc_html__( 'We\'ve detected that the', 'convertkit' ),
363 '<code>DISABLE_WP_CRON</code>',
364 esc_html__( 'constant is enabled. If broadcasts do not import automatically or when using the import button below, either remove this constant from your', 'convertkit' ),
365 '<code>wp-config.php</code>',
366 esc_html__( 'file, or check that your web host is triggering the WordPress Cron via an alternate method. If importing broadcasts work, no changes to your WordPress configuration file are required.', 'convertkit' )
367 );
368 ?>
369 </p>
370 </div>
371 <?php
372 }
373
374 }
375
376
377 /**
378 * Returns the URL for the ConvertKit documentation for this setting section.
379 *
380 * @since 2.2.9
381 *
382 * @return string Documentation URL.
383 */
384 public function documentation_url() {
385
386 return 'https://help.kit.com/en/articles/2502591-the-convertkit-wordpress-plugin';
387
388 }
389
390 /**
391 * Renders the input for the Enable setting.
392 *
393 * @since 2.2.9
394 *
395 * @param array $args Setting field arguments (name,description).
396 */
397 public function enable_callback( $args ) {
398
399 // Output field.
400 echo $this->get_checkbox_field( // phpcs:ignore WordPress.Security.EscapeOutput
401 $args['name'],
402 'on',
403 $this->settings->enabled(), // phpcs:ignore WordPress.Security.EscapeOutput
404 $args['label'], // phpcs:ignore WordPress.Security.EscapeOutput
405 $args['description'], // phpcs:ignore WordPress.Security.EscapeOutput
406 array( 'convertkit-conditional-display' )
407 );
408
409 }
410
411 /**
412 * Renders the import button.
413 *
414 * @since 2.2.9
415 */
416 public function import_button_callback() {
417
418 // Define link to import Broadcasts now.
419 $import_url = add_query_arg(
420 array(
421 'page' => '_wp_convertkit_settings',
422 'tab' => 'broadcasts',
423 '_convertkit_settings_broadcasts_nonce' => wp_create_nonce( 'convertkit-settings-broadcasts' ),
424 ),
425 'options-general.php'
426 );
427
428 echo '<a href="' . esc_url( $import_url ) . '" class="button button-secondary enabled">' . esc_html__( 'Import now', 'convertkit' ) . '</a>';
429
430 }
431
432 /**
433 * Renders the input for the status setting.
434 *
435 * @since 2.3.4
436 *
437 * @param array $args Setting field arguments (name,description).
438 */
439 public function post_status_callback( $args ) {
440
441 // Build field.
442 $select_field = $this->get_select_field(
443 $args['name'],
444 $this->settings->post_status(),
445 get_post_statuses(),
446 $args['description'],
447 array(
448 'enabled',
449 'convertkit-select2',
450 )
451 );
452
453 // Output field.
454 echo '<div class="convertkit-select2-container">' . $select_field . '</div>'; // phpcs:ignore WordPress.Security.EscapeOutput
455
456 }
457
458 /**
459 * Renders the input for the author setting.
460 *
461 * @since 2.3.9
462 *
463 * @param array $args Setting field arguments (name,description).
464 */
465 public function author_id_callback( $args ) {
466
467 // Build field.
468 $select_field = wp_dropdown_users(
469 array(
470 'echo' => false,
471 'selected' => $this->settings->author_id(),
472 'include_selected' => true,
473 'name' => $this->settings_key . '[' . $args['name'] . ']',
474 'id' => $this->settings_key . '_' . $args['name'],
475 'class' => 'enabled convertkit-select2',
476 )
477 );
478
479 // Output field.
480 echo '<div class="convertkit-select2-container">' . $select_field . '</div>' . $this->get_description( $args['description'] ); // phpcs:ignore WordPress.Security.EscapeOutput
481
482 }
483
484 /**
485 * Renders the input for the category setting.
486 *
487 * @since 2.2.9
488 *
489 * @param array $args Setting field arguments (name,description).
490 */
491 public function category_callback( $args ) {
492
493 // Build field.
494 $select_field = wp_dropdown_categories(
495 array(
496 'show_option_none' => __( 'None', 'convertkit' ),
497 'echo' => 0,
498 'hierarhical' => 1,
499 'name' => $this->settings_key . '[' . $args['name'] . ']',
500 'id' => $this->settings_key . '_' . $args['name'],
501 'class' => 'convertkit-select2 enabled',
502 'selected' => $this->settings->category_id(),
503 'taxonomy' => 'category',
504 'hide_empty' => false,
505 )
506 );
507
508 // Output field.
509 echo '<div class="convertkit-select2-container">' . $select_field . '</div>' . $this->get_description( $args['description'] ); // phpcs:ignore WordPress.Security.EscapeOutput
510
511 }
512
513 /**
514 * Renders the input for the Import Thumbnail setting.
515 *
516 * @since 2.4.1
517 *
518 * @param array $args Setting field arguments (name,description).
519 */
520 public function import_thumbnail_callback( $args ) {
521
522 // Output field.
523 echo $this->get_checkbox_field( // phpcs:ignore WordPress.Security.EscapeOutput
524 $args['name'],
525 'on',
526 $this->settings->import_thumbnail(), // phpcs:ignore WordPress.Security.EscapeOutput
527 $args['label'], // phpcs:ignore WordPress.Security.EscapeOutput
528 $args['description'], // phpcs:ignore WordPress.Security.EscapeOutput
529 array(
530 'enabled',
531 )
532 );
533
534 }
535
536 /**
537 * Renders the input for the Import Images setting.
538 *
539 * @since 2.6.3
540 *
541 * @param array $args Setting field arguments (name,description).
542 */
543 public function import_images_callback( $args ) {
544
545 // Output field.
546 echo $this->get_checkbox_field( // phpcs:ignore WordPress.Security.EscapeOutput
547 $args['name'],
548 'on',
549 $this->settings->import_images(), // phpcs:ignore WordPress.Security.EscapeOutput
550 $args['label'], // phpcs:ignore WordPress.Security.EscapeOutput
551 $args['description'], // phpcs:ignore WordPress.Security.EscapeOutput
552 array(
553 'enabled',
554 )
555 );
556
557 }
558
559 /**
560 * Renders the input for the date setting.
561 *
562 * @since 2.2.9
563 *
564 * @param array $args Setting field arguments (name,description).
565 */
566 public function date_callback( $args ) {
567
568 // Output field.
569 echo $this->get_date_field( // phpcs:ignore WordPress.Security.EscapeOutput
570 $args['name'],
571 esc_attr( $this->settings->published_at_min_date() ),
572 $args['description'], // phpcs:ignore WordPress.Security.EscapeOutput
573 array(
574 'enabled',
575 )
576 );
577
578 }
579
580 /**
581 * Renders the input for the Enable Export setting.
582 *
583 * @since 2.4.0
584 *
585 * @param array $args Setting field arguments (name,description).
586 */
587 public function enable_export_callback( $args ) {
588
589 // Output field.
590 echo $this->get_checkbox_field( // phpcs:ignore WordPress.Security.EscapeOutput
591 $args['name'],
592 'on',
593 $this->settings->enabled_export(), // phpcs:ignore WordPress.Security.EscapeOutput
594 $args['label'] // phpcs:ignore WordPress.Security.EscapeOutput
595 );
596
597 }
598
599 /**
600 * Renders the input for the No Styles setting.
601 *
602 * @since 2.2.9
603 *
604 * @param array $args Setting field arguments (name,description).
605 */
606 public function no_styles_callback( $args ) {
607
608 // Output field.
609 echo $this->get_checkbox_field( // phpcs:ignore WordPress.Security.EscapeOutput
610 $args['name'],
611 'on',
612 $this->settings->no_styles(), // phpcs:ignore WordPress.Security.EscapeOutput
613 $args['description'] // phpcs:ignore WordPress.Security.EscapeOutput
614 );
615
616 }
617
618 /**
619 * Sanitizes the settings prior to being saved.
620 *
621 * @since 2.4.1
622 *
623 * @param array $settings Submitted Settings Fields.
624 * @return array Sanitized Settings with Defaults
625 */
626 public function sanitize_settings( $settings ) {
627
628 // If the 'Include Thumbnail' setting isn't checked, it won't be included
629 // in the array of settings, and the defaults will enable this.
630 // Therefore, if the setting doesn't exist, set it to blank.
631 if ( ! array_key_exists( 'import_thumbnail', $settings ) ) {
632 $settings['import_thumbnail'] = '';
633 }
634
635 // If the 'Include Images' setting isn't checked, it won't be included
636 // in the array of settings, and the defaults will enable this.
637 // Therefore, if the setting doesn't exist, set it to blank.
638 if ( ! array_key_exists( 'import_images', $settings ) ) {
639 $settings['import_images'] = '';
640 }
641
642 // Merge settings with defaults.
643 $settings = wp_parse_args( $settings, $this->settings->get_defaults() );
644
645 // Return settings to be saved.
646 return $settings;
647
648 }
649
650 }
651
652 // Bootstrap.
653 add_action(
654 'convertkit_admin_settings_register_sections',
655 function ( $sections ) {
656
657 $sections['broadcasts'] = new ConvertKit_Admin_Section_Broadcasts();
658 return $sections;
659
660 }
661 );
662