Headline
CVE-2023-5614: plugin-core.php in theme-switcha/tags/3.3/inc – WordPress Plugin Repository
The Theme Switcha plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin’s ‘theme_switcha_list’ shortcode in all versions up to, and including, 3.3 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers with contributor-level and above permissions to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
1<?php // Theme Switcha - Core23if (!defined(‘ABSPATH’)) exit;45function theme_switcha_toolbar_add_menu() {6 7 global $theme_switcha_options, $wp_admin_bar;8 9 if (!current_user_can(‘switch_themes’) || !is_object($wp_admin_bar) || !function_exists(‘is_admin_bar_showing’) || !is_admin_bar_showing()) return;10 11 $options = $theme_switcha_options;12 13 $enable = (isset($options[‘enable_plugin’]) && !empty($options[‘enable_plugin’])) ? 1 : 0;14 15 $toolbar = (isset($options[‘enable_toolbar’]) && !empty($options[‘enable_toolbar’])) ? 1 : 0;16 17 if ($enable && $toolbar) {18 19 $text = __('Choose a theme…’, ‘theme-switcha’);20 21 $title = theme_switcha_display_dropdown($text);22 23 $wp_admin_bar->add_menu(array(‘id’ => 'theme-switcha’, ‘title’ => __('Theme Switcha’, ‘theme-switcha’), ‘href’ => false));24 25 $wp_admin_bar->add_menu(array(‘id’ => 'theme-switcha-menu’, ‘parent’ => 'theme-switcha’, ‘title’ => $title, ‘href’ => false));26 27 }28 29}3031function theme_switcha_check_cookie() {32 33 if (isset($_GET[‘theme-switch’]) && !empty($_GET[‘theme-switch’])) {34 35 global $theme_switcha_options;36 37 $options = $theme_switcha_options;38 39 $expire = time() + (int) $options[‘cookie_expire’];40 41 $theme = stripslashes($_GET[‘theme-switch’]);42 43 $domain = sanitize_text_field($_SERVER[‘HTTP_HOST’]);44 45 $port = parse_url($domain, PHP_URL_PORT);46 47 if (!empty($port)) { // localhost48 49 $domain = parse_url($domain, PHP_URL_HOST);50 51 }52 53 // setcookie($name, $value, $expires, $path, $domain, $secure, $httponly)54 55 setcookie('theme_switcha_theme_’. COOKIEHASH, $theme, $expire, COOKIEPATH, $domain, false, true);56 57 if (isset($_GET[‘passkey’]) && !empty($_GET[‘passkey’])) {58 59 $passkey = stripslashes($_GET[‘passkey’]);60 61 setcookie('theme_switcha_passkey_’. COOKIEHASH, $passkey, $expire, COOKIEPATH, $domain, false, true);62 63 }64 65 $params = array('theme-switch’, ‘passkey’);66 $redirect = esc_url_raw(remove_query_arg($params));67 wp_safe_redirect($redirect);68 69 exit;70 71 }72 73}7475function theme_switcha_core($current, $key = ‘Template’) {76 77 global $theme_switcha_options;78 79 $options = $theme_switcha_options;80 81 if (!isset($options[‘enable_plugin’]) || !$options[‘enable_plugin’]) return $current;82 83 if (!theme_switcha_check_permissions($options)) return $current;84 85 if (isset($_COOKIE['theme_switcha_theme_’. COOKIEHASH])) {86 87 $theme = $_COOKIE['theme_switcha_theme_’. COOKIEHASH];88 89 } else {90 91 return $current;92 93 }94 95 if (isset($theme) && !empty($theme)) {96 97 if ((!is_admin()) || (is_admin() && $options[‘enable_admin’])) {98 99 $theme_data = wp_get_theme($theme);100 101 if (!empty($theme_data)) {102 103 $theme_status = (isset($theme_data[‘Status’])) ? $theme_data[‘Status’] : false;104 105 if ($theme_status && ($theme_status !== ‘publish’) && ($theme_status !== ‘admin-only’)) return $current;106 107 return (string) $theme_data[$key];108 109 }110 111 $themes = wp_get_themes(array(‘errors’ => false , ‘allowed’ => true, ‘blog_id’ => 0));112 113 foreach ($themes as $theme_data) {114 115 if ((string) $theme_data[‘Stylesheet’] === $theme) {116 117 $theme_status = (isset($theme_data[‘Status’])) ? $theme_data[‘Status’] : false;118 119 if ($theme_status && ($theme_status !== ‘publish’) && ($theme_status !== ‘admin-only’)) return $current;120 121 return (string) $theme_data[$key];122 123 }124 125 }126 127 }128 129 }130 131 return $current;132 133}134135function theme_switcha_check_permissions($options) {136 137 switch ($options[‘allowed_users’]) {138 139 case ‘admin’ :140 141 if (current_user_can(‘switch_themes’)) return true;142 143 break;144 145 case ‘passkey’ :146 147 if (current_user_can(‘switch_themes’)) return true;148 149 if (isset($_COOKIE['theme_switcha_passkey_’. COOKIEHASH]) && $_COOKIE['theme_switcha_passkey_’. COOKIEHASH] === $options[‘passkey’]) return true;150 151 break;152 153 case ‘everyone’ :154 155 return true;156 157 break;158 159 }160 161 return false;162 163}164165function theme_switcha_filter_template($current) {166 167 return theme_switcha_core($current, ‘Template’);168 169}170171function theme_switcha_filter_stylesheet($current) {172 173 return theme_switcha_core($current, ‘Stylesheet’);174 175}176177function theme_switcha_add_filters() {178 179 add_filter('template’, ‘theme_switcha_filter_template’);180 181 add_filter('stylesheet’, ‘theme_switcha_filter_stylesheet’);182 183}184185function theme_switcha_active_theme() {186 187 $get_theme = wp_get_theme();188 189 $active_theme = $get_theme->get(‘Name’);190 191 $custom = apply_filters('theme_switcha_active_theme_custom’, true);192 193 if (isset($_COOKIE['theme_switcha_theme_’. COOKIEHASH]) && $custom) {194 195 $active_theme = $_COOKIE['theme_switcha_theme_’. COOKIEHASH];196 197 }198 199 return $active_theme;200 201}202203function theme_switcha_get_theme_names() {204 205 $blog_id = get_current_blog_id();206 207 $blog_id = is_int($blog_id) ? $blog_id : 0;208 209 $themes = wp_get_themes(array(‘errors’ => false , ‘allowed’ => true, ‘blog_id’ => $blog_id));210 211 $theme_names = array_keys($themes);212 213 $theme_names = array_map('strval’, $theme_names);214 215 natcasesort($theme_names);216 217 return $theme_names;218 219} 220221function theme_switcha_truncate($string, $length = 10, $dots = ‘…’) {222 223 return (strlen($string) > $length) ? substr($string, 0, $length - strlen($dots)) . $dots : $string;224 225}226227function theme_switcha_check_enabled() {228 229 global $theme_switcha_options;230 231 $options = $theme_switcha_options;232 233 $cookie_passkey = (isset($_COOKIE['theme_switcha_passkey_’. COOKIEHASH]) && $_COOKIE['theme_switcha_passkey_’. COOKIEHASH]) ? $_COOKIE['theme_switcha_passkey_’. COOKIEHASH] : null;234 235 $switch_themes = (current_user_can(‘switch_themes’)) ? true : false;236 237 $allowed_users = (isset($options[‘allowed_users’])) ? $options[‘allowed_users’] : null;238 239 $enable_plugin = (isset($options[‘enable_plugin’]) && $options[‘enable_plugin’]) ? true : false;240 241 $enable_cookie = (($switch_themes) || (($allowed_users === ‘passkey’) && ($cookie_passkey === $options[‘passkey’]))) ? true : false;242 243 $enable_user = (($switch_themes) || ($enable_cookie) || ($allowed_users === ‘everyone’)) ? true : false;244 245 $enabled = ($enable_plugin && $enable_user) ? true : false;246 247 return $enabled;248 249}250251function theme_switcha_display_themes() {252 253 if (!is_admin()) return;254 255 global $theme_switcha_options;256 257 $options = $theme_switcha_options;258 259 $themes = wp_get_themes(array(‘errors’ => false , ‘allowed’ => true, ‘blog_id’ => 0));260 261 $themes = apply_filters(‘theme_switcha_themes’, $themes);262 263 $default_theme = wp_get_theme();264 265 $default_screenshot = THEME_SWITCHA_URL .’img/screenshot.png’;266 267 $enable_admin = (isset($options[‘enable_admin’]) && $options[‘enable_admin’]) ? ' enable-admin’ : ‘’;268 269 $enable_plugin = (isset($options[‘enable_plugin’]) && $options[‘enable_plugin’]) ? ' enable-plugin’ : '’;270 271 $current_theme = (!empty($enable_plugin) && isset($_COOKIE['theme_switcha_theme_’. COOKIEHASH])) ? $_COOKIE['theme_switcha_theme_’. COOKIEHASH] : $default_theme->Stylesheet;272 273 $passkey = (isset($options[‘passkey’])) ? $options[‘passkey’] : '’;274 275 $base_url = trailingslashit(get_bloginfo(‘url’));276 277 if (empty($enable_plugin)) return;278 279 //280 281 $output = '<div id="theme-switcha" class="theme-switcha-thumbs">’;282 283 foreach($themes as $theme) {284 285 if (($theme->Status !== ‘publish’) && ($theme->Status !== ‘admin-only’)) continue;286 287 $src = ($theme->get_screenshot()) ? $theme->get_screenshot() : $default_screenshot;288 289 $dir = ($theme->get_stylesheet()) ? $theme->get_stylesheet() : get_stylesheet();290 291 $params = array(‘theme-switch’ => $dir, ‘passkey’ => $passkey);292 293 $href = add_query_arg($params, $base_url);294 295 $title = ($theme->Version !== ‘’) ? esc_attr__('Version ‘, ‘theme-switcha’) . $theme->Version .’ : ' : '’;296 297 $title .= theme_switcha_truncate($theme->Description, 120);298 299 $name = ($theme->Name !== ‘’) ? $theme->Name : esc_attr__(‘Untitled’, ‘theme-switcha’);300 301 $text = theme_switcha_truncate($name, 20);302 303 $active = ((string) $theme->Stylesheet === $current_theme) ? ' theme-active’ : '’;304 305 $admin = ($theme->Name === $default_theme->Name) ? ' <span class="theme-admin">’. esc_html__(‘Admin Theme’, ‘theme-switcha’) .’</span>’ : '’;306 307 $parent = ($theme->parent() && $theme->parent()->Name !== ‘’) ? ' <span class="theme-child">’. esc_html__(‘Child Theme’, ‘theme-switcha’) .’</span>’ : '’;308 309 $output .= '<a target="_blank" rel="noopener noreferrer" class="theme-screenshot theme-'. $dir . $enable_plugin . $enable_admin . $active .’" href="’. esc_url($href) .’" title="’. esc_attr($title) .’" data-switched="’. esc_attr($name) .’">’;310 311 $output .= '<img src="’. esc_url($src) .’" alt="" />’. esc_html($text) . $admin . $parent .’</a>’;312 313 }314 315 $output .= '</div>’;316 317 return $output;318 319}320321function theme_switcha_display_thumbs() {322 323 global $theme_switcha_options;324 325 $options = $theme_switcha_options;326 327 $themes = wp_get_themes(array(‘errors’ => false , ‘allowed’ => true, ‘blog_id’ => 0));328 329 $themes = apply_filters(‘theme_switcha_themes’, $themes);330 331 $default_theme = wp_get_theme();332 333 $default_screenshot = THEME_SWITCHA_URL .’img/screenshot.png’;334 335 $enable_plugin = (isset($options[‘enable_plugin’]) && $options[‘enable_plugin’]) ? ' enable-plugin’ : '’;336 337 $current_theme = (!empty($enable_plugin) && isset($_COOKIE['theme_switcha_theme_’. COOKIEHASH])) ? $_COOKIE['theme_switcha_theme_’. COOKIEHASH] : $default_theme->Stylesheet;338 339 $base_url = get_permalink();340 341 if (empty($enable_plugin)) return;342 343 //344 345 $output = '<div id="theme-switcha" class="theme-switcha-thumbs">’;346 347 $output .= (!theme_switcha_check_enabled()) ? '<p>’. esc_html__(‘Theme switching currently disabled.’, ‘theme-switcha’) .’</p>’ : '’;348 349 foreach($themes as $theme) {350 351 if (($theme->Status !== ‘publish’) && ($theme->Status !== ‘admin-only’)) continue;352 353 if ((!current_user_can(‘switch_themes’)) && ($theme->Status === ‘admin-only’)) continue;354 355 $src = ($theme->get_screenshot()) ? $theme->get_screenshot() : $default_screenshot;356 357 $dir = ($theme->get_stylesheet()) ? $theme->get_stylesheet() : get_stylesheet();358 359 $params = array(‘theme-switch’ => $dir);360 361 $href = add_query_arg($params, $base_url);362 363 $title = ($theme->Version !== ‘’) ? esc_attr__('Version ‘, ‘theme-switcha’) . $theme->Version .’ : ' : '’;364 365 $title .= theme_switcha_truncate($theme->Description, 120);366 367 $name = ($theme->Name !== ‘’) ? $theme->Name : esc_attr__(‘Untitled’, ‘theme-switcha’);368 369 $text = theme_switcha_truncate($name, 20);370 371 $active = ((string) $theme->Stylesheet === $current_theme) ? ' theme-active’ : '’;372 373 $parent = ($theme->parent() && $theme->parent()->Name !== ‘’) ? ' <span class="theme-child">’. esc_html__(‘Child Theme’, ‘theme-switcha’) .’</span>’ : '’;374 375 $output .= '<a class="theme-screenshot theme-'. $dir . $active .’" href="’. esc_url($href) .’" title="’. esc_attr($title) .’">’;376 377 $output .= '<img src="’. esc_url($src) .’" alt="" />’. esc_html($text) . $parent .’</a>’;378 379 }380 381 $output .= '</div>’;382 383 return $output;384 385}386387function theme_switcha_frontend_thumb_styles() {388 389 $styles = '.theme-switcha-thumbs{font-family:sans-serif;text-align:center}’;390 $styles .= '.theme-screenshot[style]:link,.theme-screenshot[style]:visited{color:#efefef!important}’;391 $styles .= '.theme-screenshot[style]:hover,.theme-screenshot[style]:active,.theme-screenshot[style]:focus{color:#fff!important}’;392 $styles .= '.theme-switcha-thumbs{margin-top:30px}.theme-screenshot:link,.theme-screenshot:visited{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:relative;display:inline-block;width:200px;height:auto;margin:0 10px 10px 0;padding:10px;font-size:12px;line-height:18px;text-decoration:none;text-align:center;cursor:pointer;border:0;border-radius:2px;color:#efefef;background-color:#555;opacity:.8;-webkit-transition:opacity .2s ease-in-out;-moz-transition:opacity .2s ease-in-out;transition:opacity .2s ease-in-out}.theme-screenshot:active,.theme-screenshot:focus,.theme-screenshot:hover{opacity:1;color:#fff}.theme-active:link,.theme-active:visited{background-color:#696}.theme-screenshot img{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;width:100%;height:auto;margin:0 0 8px;padding:0;border-radius:2px;border:1px solid #777;box-shadow:0 0 10px 0 rgba(0,0,0,.7)}.theme-admin,.theme-child{position:absolute;left:0;width:100%;height:50px;line-height:50px}.theme-admin{top:0;background-color:rgba(0,0,0,.7)}.theme-child{top:50px;background-color:rgba(153,51,51,.7)}’;393 394 $styles = apply_filters('theme_switcha_styles_thumb’, $styles);395 396 return '<style type="text/css">’. $styles .’</style>’;397 398}399400function theme_switcha_display_thumbs_shortcode($attr, $content = null) {401 402 extract(shortcode_atts(array(403 ‘style’ => 'true’,404 ), $attr));405 406 $output = theme_switcha_display_thumbs();407 408 if ($style === ‘true’) {409 410 $styles = theme_switcha_frontend_thumb_styles();411 412 $output = $styles . $output;413 414 }415 416 return $output;417 418}419add_shortcode('theme_switcha_thumbs’, ‘theme_switcha_display_thumbs_shortcode’);420421function theme_switcha_display_list($display) {422 423 global $theme_switcha_options;424 425 $options = $theme_switcha_options;426 427 $themes = wp_get_themes(array(‘errors’ => false , ‘allowed’ => true, ‘blog_id’ => 0));428 429 $themes = apply_filters(‘theme_switcha_themes’, $themes);430 431 $default_theme = wp_get_theme();432 433 $enable_plugin = (isset($options[‘enable_plugin’]) && $options[‘enable_plugin’]) ? ' enable-plugin’ : '’;434 435 $current_theme = (!empty($enable_plugin) && isset($_COOKIE['theme_switcha_theme_’. COOKIEHASH])) ? $_COOKIE['theme_switcha_theme_’. COOKIEHASH] : $default_theme->Stylesheet;436 437 $base_url = get_permalink();438 439 if (empty($enable_plugin)) return;440 441 //442 443 $output = (!theme_switcha_check_enabled()) ? '<p>’. esc_html__(‘Theme switching currently disabled.’, ‘theme-switcha’) .’</p>’ : '’;444 445 $output .= '<ul id="theme-switcha" class="theme-switcha-'. $display .’">’;446 447 foreach($themes as $theme) {448 449 if (($theme->Status !== ‘publish’) && ($theme->Status !== ‘admin-only’)) continue;450 451 if ((!current_user_can(‘switch_themes’)) && ($theme->Status === ‘admin-only’)) continue;452 453 $dir = ($theme->get_stylesheet()) ? $theme->get_stylesheet() : get_stylesheet();454 455 $params = array(‘theme-switch’ => $dir);456 457 $href = add_query_arg($params, $base_url);458 459 $title = ($theme->Version !== ‘’) ? esc_attr__('Version ‘, ‘theme-switcha’) . $theme->Version .’ : ' : '’;460 461 $title .= theme_switcha_truncate($theme->Description, 120);462 463 $text = ($theme->Name !== ‘’) ? $theme->Name : esc_attr__(‘Untitled’, ‘theme-switcha’);464 465 $active = ((string) $theme->Stylesheet === $current_theme) ? ' active-theme’ : '’;466 467 $output .= '<li><a class="theme-'. $dir . $active .’" href="’. esc_url($href) .’" title="’. esc_attr($title) .’">’. esc_html($text) .’</a></li>’;468 469 }470 471 $output .= '</ul>’;472 473 return $output;474}475476function theme_switcha_frontend_list_styles($display) {477 478 if ($display === ‘list’) {479 480 $styles = '.active-theme{font-weight:bold}’;481 482 } else {483 484 $styles = '.theme-switcha-list{margin-left:0;padding:0}.theme-switcha-list li{display:inline-block;margin:0 5px 5px 0}.theme-switcha-list a:link,.theme-switcha-list a:visited{display:inline-block;padding:5px 10px;border:1px solid #fbf0cb;border-radius:2px;color:#777;background-color:#fefaed;text-decoration:none}.theme-switcha-list a:hover,.theme-switcha-list a:active,.theme-switcha-list a:focus{color:#777;background-color:#fbf0cb}’;485 486 }487 488 $styles = apply_filters('theme_switcha_styles_list’, $styles);489 490 return '<style type="text/css">’. $styles .’</style>’;491 492}493494function theme_switcha_display_list_shortcode($attr, $content = null) {495 496 extract(shortcode_atts(array(497 ‘display’ => 'list’,498 ‘style’ => 'true’,499 ), $attr));500 501 $output = theme_switcha_display_list($display);502 503 if ($style === ‘true’) {504 505 $styles = theme_switcha_frontend_list_styles($display);506 507 $output = $styles . $output;508 509 }510 511 return $output;512 513}514add_shortcode('theme_switcha_list’, ‘theme_switcha_display_list_shortcode’);515516function theme_switcha_display_dropdown($text, $widget = false) {517 518 global $theme_switcha_options;519 520 $options = $theme_switcha_options;521 522 $themes = wp_get_themes(array(‘errors’ => false , ‘allowed’ => true, ‘blog_id’ => 0));523 524 $themes = apply_filters(‘theme_switcha_themes’, $themes);525 526 $default_theme = wp_get_theme();527 528 $enable_plugin = (isset($options[‘enable_plugin’]) && $options[‘enable_plugin’]) ? ' enable-plugin’ : '’;529 530 $current_theme = (!empty($enable_plugin) && isset($_COOKIE['theme_switcha_theme_’. COOKIEHASH])) ? $_COOKIE['theme_switcha_theme_’. COOKIEHASH] : $default_theme->Stylesheet;531 532 $protocol = is_ssl() ? ‘https://’ : 'http://’;533 534 $base_url = esc_url_raw($protocol . $_SERVER[‘HTTP_HOST’] . $_SERVER[‘REQUEST_URI’]);535 536 if (strpos($base_url, ‘/wp-admin/’) !== false) $base_url = get_home_url();537 538 if (empty($enable_plugin)) return;539 540 //541 542 $output = (!theme_switcha_check_enabled()) ? '<p>’. esc_html__(‘Theme switching currently disabled.’, ‘theme-switcha’) .’</p>’ : '’;543 544 if ($widget) {545 546 $output .= ‘<select id="theme-switcha" class="theme-switcha-dropdown" onChange="window.open( this.options[ this.selectedIndex ].value, \’_blank\’);">’;547 548 } else {549 550 $output .= '<select id="theme-switcha" class="theme-switcha-dropdown" onChange="window.document.location.href=this.options[this.selectedIndex].value;">’;551 552 }553 554 // 555 556 $output .= ($text !== ‘disable’) ? ‘<option value="’. esc_url($base_url) .’">’. $text .’</option>’ : '’;557 558 foreach($themes as $theme) {559 560 if (($theme->Status !== ‘publish’) && ($theme->Status !== ‘admin-only’)) continue;561 562 if ((!current_user_can(‘switch_themes’)) && ($theme->Status === ‘admin-only’)) continue;563 564 $dir = ($theme->get_stylesheet()) ? $theme->get_stylesheet() : get_stylesheet();565 566 $params = array(‘theme-switch’ => $dir);567 568 $href = add_query_arg($params, $base_url);569 570 $text = ($theme->Name !== ‘’) ? $theme->Name : esc_attr__(‘Untitled’, ‘theme-switcha’);571 572 $active = ((string) $theme->Stylesheet === $current_theme) ? ' selected="selected"’ : '’;573 574 $output .= '<option value="’. esc_url($href) .’"’. $active .’>’. esc_html($text) .’</option>’;575 576 }577 578 $output .= '</select>’;579 580 return $output;581}582583function theme_switcha_display_dropdown_shortcode($attr, $content = null) {584 585 extract(shortcode_atts(array(586 ‘text’ => 'Choose a theme…’,587 ), $attr));588 589 $output = theme_switcha_display_dropdown($text);590 591 return $output;592 593}594add_shortcode('theme_switcha_select’, ‘theme_switcha_display_dropdown_shortcode’);595596function theme_switcha_display_dropdown_echo() {597 598 $text = __('Choose a theme…’, ‘theme-switcha’);599 600 echo theme_switcha_display_dropdown($text, true);601 602}603604function theme_switcha_dashboard_widget() {605 606 global $theme_switcha_options;607 608 $enable = isset($theme_switcha_options[‘enable_plugin’]) ? $theme_switcha_options[‘enable_plugin’] : 0;609 610 if ($enable && theme_switcha_check_permissions($theme_switcha_options)) {611 612 wp_add_dashboard_widget('theme_switcha_dashboard_widget’, __('Theme Switcha’, ‘theme-switcha’), ‘theme_switcha_display_dropdown_echo’);613 614 }615 616}617618function theme_switcha_disable_widget() {619 620 global $theme_switcha_options;621 622 $disable_widget = (isset($theme_switcha_options[‘disable_widget’]) && !empty($theme_switcha_options[‘disable_widget’])) ? 1 : 0;623 624 if ($disable_widget && !current_user_can(‘manage_options’)) {625 626 remove_meta_box('theme_switcha_dashboard_widget’, 'dashboard’, ‘normal’);627 628 }629 630}631632function theme_switcha_display_text_link($attr, $content = null) {633 634 global $theme_switcha_options;635 636 $options = $theme_switcha_options;637 638 $passkey = isset($options[‘passkey’]) ? $options[‘passkey’] : null;639 640 $protocol = is_ssl() ? ‘https://’ : 'http://’;641 642 $base_url = esc_url_raw($protocol . $_SERVER[‘HTTP_HOST’] . $_SERVER[‘REQUEST_URI’]);643 644 if (strpos($base_url, ‘/wp-admin/’) !== false) $base_url = get_home_url();645 646 extract(shortcode_atts(array(‘theme’ => theme_switcha_active_theme(), ‘text’ => ‘Switch Theme’), $attr));647 648 $params = array(‘theme-switch’ => $theme, ‘passkey’ => $passkey);649 650 $href = add_query_arg($params, $base_url);651 652 $output = '<a href="’. esc_url($href) .’">’. esc_html($text) .’</a>’;653 654 return $output;655 656}657add_shortcode('theme_switcha_link’, ‘theme_switcha_display_text_link’);