balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

class-redux-connection-banner.php (20181B)


      1 <?php
      2 /**
      3  * Redux Connection Banner Class
      4  *
      5  * @class Redux_Core
      6  * @version 4.0.0
      7  * @package Redux Framework
      8  */
      9 
     10 // @codingStandardsIgnoreStart
     11 if ( ! defined( 'ABSPATH' ) ) {
     12 	exit;
     13 }
     14 
     15 if ( ! class_exists( 'Redux_Connection_Banner', false ) ) {
     16 
     17 	/**
     18 	 * Class Redux_Connection_Banner
     19 	 */
     20 	class Redux_Connection_Banner {
     21 		/**
     22 		 * Plugin version, used for cache-busting of style and script file references.
     23 		 *
     24 		 * @since   1.0.0
     25 		 * @var     string
     26 		 */
     27 		protected $version = '1.0.0';
     28 
     29 		/**
     30 		 * Singleton instance.
     31 		 *
     32 		 * @var Redux_Connection_Banner
     33 		 **/
     34 		private static $instance = null;
     35 
     36 		/**
     37 		 * Register option.
     38 		 *
     39 		 * @var string $register_option
     40 		 */
     41 		private $register_option = 'redux-connection-register';
     42 		/**
     43 		 * Dismiss option.
     44 		 *
     45 		 * @var string $dismiss_option
     46 		 */
     47 		private $dismiss_option = 'redux-connection-dismiss';
     48 
     49 		/**
     50 		 * Nonce slug.
     51 		 *
     52 		 * @var string $dismiss_options
     53 		 */
     54 		private $nonce = 'redux-connection-nonce';
     55 
     56 		/**
     57 		 * URLs.
     58 		 *
     59 		 * @var array $urls
     60 		 */
     61 		private $urls = array();
     62 
     63 		/**
     64 		 * Init function.
     65 		 *
     66 		 * @return Redux_Connection_Banner
     67 		 */
     68 		public static function init(): ?Redux_Connection_Banner {
     69 			if ( is_null( self::$instance ) ) {
     70 				self::$instance = new Redux_Connection_Banner();
     71 			}
     72 
     73 			return self::$instance;
     74 		}
     75 
     76 		/**
     77 		 * Redux_Connection_Banner constructor.
     78 		 *
     79 		 * Since we call the Redux_Connection_Banner:init() method from the `Redux` class, and after
     80 		 * the admin_init action fires, we know that the admin is initialized at this point.
     81 		 */
     82 		private function __construct() {
     83 			$clean_get = $_GET; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
     84 			if ( isset( $clean_get['_wpnonce'] ) && wp_verify_nonce( $clean_get['_wpnonce'], $this->nonce ) ) {
     85 				if ( isset( $clean_get[ $this->register_option ] ) ) {
     86 					Redux_Functions_Ex::set_activated( $clean_get[ $this->register_option ] );
     87 					return;
     88 				}
     89 				if ( isset( $clean_get[ $this->dismiss_option ] ) ) {
     90 					Redux_Functions_Ex::set_deactivated();
     91 					update_option( 'redux-framework_tracking_notice', 'hide' );
     92 					return;
     93 				}
     94 			}
     95 
     96 			add_action( 'wp_ajax_redux_activation', array( $this, 'admin_ajax' ) ); // Executed when logged in.
     97 			add_action( 'current_screen', array( $this, 'maybe_initialize_hooks' ) );
     98 		}
     99 
    100 		/**
    101 		 * Get the URL for the current page to fallback if JS is broken.
    102 		 *
    103 		 * @param bool|string $location Used to determine the location of the banner for account creation.
    104 		 * @since 4.1.21
    105 		 * @return array
    106 		 */
    107 		private function get_urls( $location = true ): array {
    108 			if ( ! empty( $this->urls ) ) {
    109 				return $this->urls;
    110 			}
    111 
    112 			global $pagenow;
    113 
    114 			$clean_get = $_GET; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
    115 			if ( isset( $clean_get[ $this->register_option ] ) ) {
    116 				unset( $clean_get[ $this->register_option ] );
    117 			}
    118 			if ( isset( $clean_get[ $this->dismiss_option ] ) ) {
    119 				unset( $clean_get[ $this->dismiss_option ] );
    120 			}
    121 			$base_url = admin_url( add_query_arg( $clean_get, $pagenow ) );
    122 
    123 			return array(
    124 				'dismiss'  => wp_nonce_url( add_query_arg( $this->dismiss_option, true, $base_url ), $this->nonce ),
    125 				'register' => wp_nonce_url( add_query_arg( $this->register_option, $location, $base_url ), $this->nonce ),
    126 			);
    127 		}
    128 
    129 		/**
    130 		 * AJAX callback for dismissing the notice.
    131 		 */
    132 		public function admin_ajax() {
    133 			// phpcs:ignore WordPress.Security.NonceVerification.Recommended
    134 			$nonce = isset( $_REQUEST['nonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ) : '';
    135 			if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, $this->nonce ) ) {
    136 				die( __( 'Security check failed.', 'redux-framework' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    137 			}
    138 			if ( 'true' === $_REQUEST['activate'] ) {
    139 				Redux_Functions_Ex::set_activated( sanitize_text_field( wp_unslash( $_REQUEST['activate'] ) ) );
    140 			} else {
    141 				Redux_Functions_Ex::set_deactivated();
    142 				update_option( 'redux-framework_tracking_notice', 'hide' );
    143 			}
    144 			die();
    145 		}
    146 
    147 		/**
    148 		 * AJAX callback for dismissing the notice.
    149 		 *
    150 		 * @param string|null $admin_body_class Class string.
    151 		 *
    152 		 * @return string
    153 		 */
    154 		public function admin_body_class( ?string $admin_body_class = '' ): string {
    155 			$classes = explode( ' ', trim( $admin_body_class ) );
    156 
    157 			$classes[] = false ? 'redux-connected' : 'redux-disconnected';
    158 
    159 			$admin_body_class = implode( ' ', array_unique( $classes ) );
    160 			return " $admin_body_class ";
    161 		}
    162 
    163 		/**
    164 		 * Will initialize hooks to display the new (as of 4.4) connection banner if the current user can
    165 		 * connect Redux, if Redux has not been deactivated, and if the current page is the plugins page.
    166 		 *
    167 		 * This method should not be called if the site is connected to WordPress.com or if the site is in development mode.
    168 		 *
    169 		 * @since 4.4.0
    170 		 * @since 4.5.0 Made the new (as of 4.4) connection banner display to everyone by default.
    171 		 * @since 5.3.0 Running another split test between 4.4 banner and a new one in 5.3.
    172 		 * @since 7.2   B test was removed.
    173 		 *
    174 		 * @param $current_screen
    175 		 */
    176 		public function maybe_initialize_hooks( $current_screen ) {
    177 			// Redux_Functions_Ex::set_deactivated(); // Test code.
    178 
    179 			if ( Redux_Functions_Ex::activated() || 'hide' === get_option( 'redux-framework_tracking_notice', null ) ) {
    180 				return;
    181 			}
    182 
    183 			// Don't show the connect notice anywhere but the plugins.php after activating
    184 			if ( 'plugins' !== $current_screen->base && 'dashboard' !== $current_screen->base ) {
    185 				add_action( 'redux_admin_notices_run', array( $this, 'panel_admin_notice' ), 100, 2 );
    186 				add_action( 'admin_head', array( $this, 'admin_head' ) );
    187 				return;
    188 			}
    189 
    190 			// Only show this notice when the plugin is installed.
    191 			if ( class_exists( 'Redux_Framework_Plugin' ) && false === Redux_Framework_Plugin::$crash ) {
    192 				add_action( 'admin_notices', array( $this, 'render_banner' ) );
    193 				add_action( 'network_admin_notices', array( $this, 'network_connect_notice' ) );
    194 				add_action( 'admin_head', array( $this, 'admin_head' ) );
    195 				add_filter( 'admin_body_class', array( $this, 'admin_body_class' ), 20 );
    196 
    197 				// Only fires immediately after plugin activation
    198 				if ( get_transient( 'activated_Redux' ) ) {
    199 					add_action( 'admin_notices', array( $this, 'render_connect_prompt_full_screen' ) );
    200 					delete_transient( 'activated_Redux' );
    201 				}
    202 			}
    203 		}
    204 
    205 		/**
    206 		 * Enqueues JavaScript and CSS for new connect-in-place flow.
    207 		 *
    208 		 * @since 7.7
    209 		 */
    210 		public static function enqueue_connect_button_scripts() {
    211 			global $is_safari;
    212 
    213 			wp_enqueue_script(
    214 				'Redux-connect-button',
    215 				'_inc/connect-button.js',
    216 				array( 'jquery' ),
    217 				Redux_Core::$version,
    218 				true
    219 			);
    220 
    221 			wp_enqueue_style(
    222 				'Redux-connect-button',
    223 				'css/Redux-connect.css'
    224 			);
    225 
    226 			$ReduxApiUrl = wp_parse_url( Redux::connection()->api_url( '' ) );
    227 
    228 			// Due to the limitation in how 3rd party cookies are handled in Safari,
    229 			// we're falling back to the original flow on Safari desktop and mobile.
    230 			if ( $is_safari ) {
    231 				$force_variation = 'original';
    232 			} elseif ( Constants::is_true( 'Redux_SHOULD_USE_CONNECTION_IFRAME' ) ) {
    233 				$force_variation = 'in_place';
    234 			} elseif ( Constants::is_defined( 'Redux_SHOULD_USE_CONNECTION_IFRAME' ) ) {
    235 				$force_variation = 'original';
    236 			} else {
    237 				$force_variation = null;
    238 			}
    239 
    240 			$tracking = new Automattic\Redux\Tracking();
    241 			$identity = $tracking->tracks_get_identity( get_current_user_id() );
    242 
    243 			wp_localize_script(
    244 				'Redux-connect-button',
    245 				'reduxConnect',
    246 				array(
    247 					'apiBaseUrl'            => esc_url_raw( rest_url( 'Redux/v4' ) ),
    248 					'registrationNonce'     => wp_create_nonce( 'Redux-registration-nonce' ),
    249 					'apiNonce'              => wp_create_nonce( 'wp_rest' ),
    250 					'apiSiteDataNonce'      => wp_create_nonce( 'wp_rest' ),
    251 					'buttonTextRegistering' => __( 'Loading...', 'redux-framework' ),
    252 					'ReduxApiDomain'        => $ReduxApiUrl['scheme'] . '://' . $ReduxApiUrl['host'],
    253 					'forceVariation'        => $force_variation,
    254 					'connectInPlaceUrl'     => Redux::admin_url( 'page=Redux#/setup' ),
    255 					'dashboardUrl'          => Redux::admin_url( 'page=Redux#/dashboard' ),
    256 					'plansPromptUrl'        => Redux::admin_url( 'page=Redux#/plans-prompt' ),
    257 					'identity'              => $identity,
    258 					'preFetchScript'        => plugins_url( '_inc/build/admin.js', Redux__PLUGIN_FILE ) . '?ver=' . Redux__VERSION,
    259 				)
    260 			);
    261 		}
    262 
    263 		/**
    264 		 * Display the admin notice to users that have not opted-in or out
    265 		 *
    266 		 * @return void
    267 		 */
    268 		public function panel_admin_notice( $args ) {
    269 
    270 			$urls = $this->get_urls( 'panel_banner' );
    271 
    272 			$this->client = Redux_Core::$appsero;
    273 			// don't show tracking if a local server
    274 
    275 			if ( empty( $this->notice ) ) {
    276 				$name = 'Redux';
    277 				// if ( isset( $args['display_name'] ) && !empty( $args['display_name'] )) {
    278 				// $name = $name . ' & '.$args['display_name'];
    279 				// }
    280 				$notice = sprintf( __( 'Register <strong>%1$s</strong> to enable automatic Google Font updates service. Plus unlock all free block templates in the Redux template library.', 'redux-framework' ), $name );
    281 			} else {
    282 				$notice = $this->notice;
    283 			}
    284 
    285 			$notice .= ' (<a class="redux-insights-data-we-collect" href="#" style="white-space: nowrap;">' . __( 'learn more', 'redux-framework' ) . '</a>)';
    286 
    287 			$notice .= '<p class="description" style="display:none;">' . self::tos_blurb( 'option_panel' ) . ' </p>';
    288 
    289 			echo '<div class="updated" id="redux-connect-message" data-nonce="' . wp_create_nonce( $this->nonce ) . '" style="border-left-color: #24b0a6;"><p>';
    290 			echo $notice;
    291 			echo '</p><p class="submit">';
    292 			echo '&nbsp;<a href="' . esc_url( $urls['register'] ) . '" class="button-primary button-large redux-activate-connection redux-connection-banner-action" data-url="' . admin_url( 'admin-ajax.php' ) . '" data-activate="panel_banner">' . __( 'Register Now', 'redux-framework' ) . '</a>';
    293 			echo '&nbsp;&nbsp;&nbsp;<a href="' . esc_url( $urls['dismiss'] ) . '" style="color: #aaa;" class="redux-connection-banner-action" data-activate="false" data-url="' . admin_url( 'admin-ajax.php' ) . '">' . __( 'No thanks', 'redux-framework' ) . '</a>';
    294 			echo '</p></div>';
    295 			echo '<style>.wp-core-ui .button-primary.redux-activate-connection{background: #24b0a6;}.wp-core-ui .button-primary.redux-activate-connection:hover{background: #19837c;}</style>';
    296 
    297 			echo "<noscript><style>#redux-connect-message{display:none;}</style></noscript>";
    298 
    299 		}
    300 
    301 		/**
    302 		 * Hide Individual Dashboard Pages
    303 		 *
    304 		 * @access public
    305 		 * @since  4.0.0
    306 		 * @return void
    307 		 */
    308 		public function admin_head() {
    309 			?>
    310 
    311 			<link
    312 				rel='stylesheet' id='redux-banner-css' <?php // phpcs:ignore WordPress.WP.EnqueuedResources ?>
    313 				href='<?php echo esc_url( Redux_Core::$url ); ?>inc/welcome/css/redux-banner.css'
    314 				type='text/css' media='all'/>
    315 			<script
    316 				id="redux-banner-admin-js"
    317 				src='<?php echo esc_url( Redux_Core::$url ); ?>inc/welcome/js/redux-banner-admin.js'>
    318 			</script>
    319 			<?php
    320 		}
    321 
    322 		/**
    323 		 * Renders the new connection banner as of 4.4.0.
    324 		 *
    325 		 * @since 7.2   Copy and visual elements reduced to show the new focus of Redux on Security and Performance.
    326 		 * @since 4.4.0
    327 		 */
    328 		public function render_banner() {
    329 
    330 			$urls = $this->get_urls( 'main_banner' );
    331 
    332 			?>
    333 			<div id="redux-connect-message" class="updated redux-banner-container" data-nonce="<?php echo wp_create_nonce( $this->nonce ); ?>">
    334 				<div class="redux-banner-container-top-text">
    335 					<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="0" fill="none" width="24" height="24"/><g><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm1 15h-2v-2h2v2zm0-4h-2l-.5-6h3l-.5 6z"/></g></svg>
    336 					<span>
    337 						<?php esc_html_e( 'You’re almost done. Register for our service to unlock even more tools to help you build better sites faster in WordPress.', 'redux-framework' ); ?>
    338 					</span>
    339 				</div>
    340 				<div class="redux-banner-inner-container">
    341 					<a href="<?php echo esc_url( $urls['dismiss'] ); ?>" data-url="<?php echo admin_url( 'admin-ajax.php' ); ?>"
    342 					   class="notice-dismiss redux-banner-svg-dismiss redux-connection-banner-action"
    343 					   title="<?php esc_attr_e( 'Dismiss this notice', 'redux-framework' ); ?>" data-activate="false">
    344 					</a>
    345 
    346 					<div class="redux-banner-content-container">
    347 
    348 						<!-- slide 1: intro -->
    349 						<div class="redux-banner-slide redux-banner-slide-one redux-slide-is-active">
    350 
    351 							<div class="redux-banner-content-icon redux-illo">
    352 								<a href="<?php echo esc_url( 'https://redux.io/?utm_source=plugin&utm_medium=appsero&utm_campaign=redux_banner_logo' ); ?>" target="_blank"><img
    353 										src="<?php echo esc_url( Redux_Core::$url ); ?>assets/img/logo--color.svg"
    354 										class="redux-banner-content-logo"
    355 										alt="
    356 									<?php
    357 										esc_attr_e(
    358 											'Visit our website to learn more!',
    359 											'redux-framework'
    360 										);
    361 									?>
    362 									"
    363 									/></a>
    364 								<img
    365 									src="<?php echo esc_url( Redux_Core::$url ); ?>assets/img/redux-powering-up.svg"
    366 									class="redux-banner-hide-phone-and-smaller"
    367 									alt="
    368 									<?php
    369 									esc_attr_e(
    370 										'Redux helps you to take your site to the next level with tools that greatly enhance your WordPress experience.',
    371 										'redux-framework'
    372 									);
    373 									?>
    374 									"
    375 									height="auto"
    376 								/>
    377 							</div>
    378 
    379 							<div class="redux-banner-slide-text">
    380 								<h2><?php esc_html_e( 'Build better sites faster with Redux', 'redux-framework' ); ?></h2>
    381 								<p>
    382 									<?php
    383 									esc_html_e(
    384 										'The Redux block library service allows you to build any site you want in minutes with a click of a button. With over 1,000+ templates, Redux helps you build sites fast!',
    385 										'redux_framework'
    386 									);
    387 									?>
    388 								</p>
    389 
    390 								<p><em>
    391 										<?php
    392 										esc_html_e(
    393 											'No registration is required to use Redux as you always have. By registering for our service you gain access to Google Font updates as well as access to all free templates in our block template library.',
    394 											'redux-framework'
    395 										);
    396 										?>
    397 										</em>
    398 								</p>
    399 
    400 								<div class="redux-banner-button-container">
    401 									<span class="redux-banner-tos-blurb"><?php echo self::tos_blurb( 'plugin_dashboard' ); ?></span>
    402 
    403 									<a href="<?php echo esc_url( $urls['dismiss'] ); ?>" data-url="<?php echo admin_url( 'admin-ajax.php' ); ?>"
    404 									   class="button button-tiny button-link redux-connection-banner-action"
    405 									   title="<?php esc_attr_e( 'No thanks', 'redux-framework' ); ?>" data-activate="false"><?php esc_html_e( 'No Thanks', 'redux-framework' ); ?></a>&nbsp;&nbsp;
    406 
    407 									<a href="<?php echo esc_url( $urls['register'] ); ?>" data-url="<?php echo admin_url( 'admin-ajax.php' ); ?>" data-activate="main_banner"
    408 									   class="button button-primary button-large redux-alt-connect-button redux-connection-banner-action">
    409 										<?php esc_html_e( 'Register', 'redux-framework' ); ?>
    410 									</a>
    411 								</div>
    412 
    413 							</div>
    414 						</div> <!-- end slide 1 -->
    415 					</div>
    416 				</div>
    417 			</div>
    418 			<noscript><style>#redux-connect-message{display:none;}</style></noscript>
    419 			<?php
    420 		}
    421 
    422 		/**
    423 		 * Renders the full-screen connection prompt.  Only shown once and on plugin activation.
    424 		 */
    425 		public static function render_connect_prompt_full_screen() {
    426 			$current_screen = get_current_screen();
    427 			if ( 'plugins' === $current_screen->base ) {
    428 				$bottom_connect_url_from = 'full-screen-prompt';
    429 			} else {
    430 				$bottom_connect_url_from = 'landing-page-bottom';
    431 			}
    432 
    433 			if ( 'plugins' === $current_screen->base ) :
    434 				?>
    435 				<div class="redux-banner-full-container">
    436 					<div class="redux-banner-full-container-card">
    437 						<div class="redux-banner-full-dismiss">
    438 							<svg class="redux-banner-svg-dismiss" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><title>Dismiss Redux Connection Window</title><rect x="0" fill="none" /><g><path d="M17.705 7.705l-1.41-1.41L12 10.59 7.705 6.295l-1.41 1.41L10.59 12l-4.295 4.295 1.41 1.41L12 13.41l4.295 4.295 1.41-1.41L13.41 12l4.295-4.295z"/></g></svg>
    439 						</div>
    440 
    441 						<img
    442 							src="<?php echo esc_url( Redux_Core::$url ); ?>assets/img/logo.svg"
    443 							alt="<?php esc_attr_e( 'Redux Logo', 'redux-template' ); ?>"
    444 							class="redux-banner-logo"
    445 						/>
    446 
    447 						<div class="redux-banner-full-step-header">
    448 							<h2 class="redux-banner-full-step-header-title"><?php esc_html_e( 'Activate essential WordPress security and performance tools by setting up Redux', 'redux-framework' ); ?></h2>
    449 						</div>
    450 						<p class="redux-banner-full-tos-blurb">
    451 							<?php self::tos_blurb( 'fullscreen' ); ?>
    452 						</p>
    453 						<p class="redux-banner-button-container">
    454 							<a href=""
    455 							   class="dops-button is-primary redux-button">
    456 								<?php esc_html_e( 'Register', 'redux-framework' ); ?>
    457 							</a>
    458 						</p>
    459 
    460 						<div class="redux-banner-full-row" id="Redux-connection-cards">
    461 							<div class="redux-banner-full-slide">
    462 								<div class="redux-banner-full-slide-card illustration">
    463 									<img
    464 										src="<?php echo esc_url( Redux_Core::$url ); ?>assets/img/security.svg"
    465 										alt="<?php esc_attr_e( 'Security & Backups', 'redux-framework' ); ?>"
    466 									/>
    467 								</div>
    468 								<div class="redux-banner-full-slide-card">
    469 									<p>
    470 										<?php
    471 										esc_html_e(
    472 											'Redux protects you against brute force attacks and unauthorized logins. ' .
    473 											'Basic protection is always free, while premium plans add unlimited backups of your whole site, ' .
    474 											'spam protection, malware scanning, and automated fixes.',
    475 											'redux-framework'
    476 										);
    477 										?>
    478 									</p>
    479 								</div>
    480 							</div>
    481 							<div class="redux-banner-full-slide">
    482 								<div class="redux-banner-full-slide-card illustration">
    483 									<img
    484 										src="<?php echo esc_url( Redux_Core::$url ); ?>assets/img/redux-speed.svg"
    485 										alt="<?php esc_attr_e( 'Built-in Performance', 'redux-framework' ); ?>"
    486 									/>
    487 								</div>
    488 								<div class="redux-banner-full-slide-card">
    489 									<p>
    490 										<?php
    491 										esc_html_e(
    492 											'Activate site accelerator tools and watch your page load times decrease—' .
    493 											"we'll optimize your images and serve them from our own powerful global network of servers, " .
    494 											'and speed up your mobile site to reduce bandwidth usage.',
    495 											'redux-framework'
    496 										);
    497 										?>
    498 									</p>
    499 								</div>
    500 							</div>
    501 						</div>
    502 
    503 						<p class="redux-banner-full-dismiss-paragraph">
    504 							<a>
    505 								<?php
    506 								echo esc_html_x(
    507 									'Not now, thank you.',
    508 									'a link that closes the modal window that offers to connect Redux',
    509 									'redux-framework'
    510 								);
    511 								?>
    512 							</a>
    513 						</p>
    514 					</div>
    515 				</div>
    516 				<?php
    517 			endif;
    518 		}
    519 
    520 		/**
    521 		 * Renders the legacy network connection banner.
    522 		 */
    523 		public function network_connect_notice() {
    524 			?>
    525 			<div id="message" class="updated Redux-message">
    526 				<div class="squeezer">
    527 					<h2>
    528 						<?php
    529 						echo wp_kses(
    530 							__(
    531 								'<strong>Redux is activated!</strong> Each site on your network must be connected individually by an admin on that site.',
    532 								'Redux'
    533 							),
    534 							array( 'strong' => array() )
    535 						);
    536 						?>
    537 					</h2>
    538 				</div>
    539 			</div>
    540 			<noscript><style>#message{display:none;}</style></noscript>
    541 			<?php
    542 		}
    543 
    544 		/**
    545 		 * Prints a TOS blurb used throughout the connection prompts.
    546 		 *
    547 		 * @since 4.0
    548 		 *
    549 		 * @echo string
    550 		 */
    551 		public static function tos_blurb( $campaign = 'options_panel' ): string {
    552 			return sprintf(
    553 				__( 'By clicking the <strong>Register</strong> button, you agree to our <a href="%1$s" target="_blank">terms of service</a>, to create an account, and to share details of your usage metrics with Redux.io.', 'redux-framework' ),
    554 				Redux_Functions_Ex::get_site_utm_url( 'terms', 'appsero', 'activate', $campaign )
    555 			);
    556 		}
    557 
    558 	}
    559 }
    560 // @codingStandardsIgnoreEnd