-
-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathwp-stage-switcher.php
More file actions
140 lines (121 loc) · 4.33 KB
/
wp-stage-switcher.php
File metadata and controls
140 lines (121 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<?php
/*
Plugin Name: Stage Switcher
Plugin URI: https://roots.io/plugins/stage-switcher/
Description: A WordPress plugin that allows you to switch between different environments from the admin bar.
Version: 2.3.0
Author: Roots
Author URI: https://roots.io/
License: MIT License
*/
namespace Roots\StageSwitcher;
/**
* Add stage/environment switcher to admin bar
* Inspired by http://37signals.com/svn/posts/3535-beyond-the-default-rails-environments
*
* ENVIRONMENTS constant must be an array of 'environment' => 'url' elements:
*
* $envs = [
* 'development' => 'http://example.dev',
* 'staging' => 'http://example-staging.com',
* 'production' => 'http://example.com'
* ];
*
* Config::define('ENVIRONMENTS', $envs);
*
* WP_ENV must be defined as the current environment.
*
* For multisite subdomain installations, the host portion of the specified
* environment URL will be treated as a suffix in constructing a matching blog
* URL in that environment.
*/
class StageSwitcher {
private $stages;
public function __construct() {
add_action('admin_bar_menu', [$this, 'admin_bar_stage_switcher']);
add_action('wp_before_admin_bar_render', [$this, 'admin_css']);
}
public function admin_bar_stage_switcher($admin_bar) {
if (!defined('ENVIRONMENTS') || !defined('WP_ENV') || !apply_filters('bedrock/stage_switcher_visibility', is_super_admin())) {
return;
}
$this->stages = maybe_unserialize(ENVIRONMENTS);
$subdomain_multisite = is_multisite() && is_subdomain_install();
$admin_bar->add_menu([
'id' => 'environment',
'parent' => 'top-secondary',
'title' => ucwords(WP_ENV),
'href' => '#',
'meta' => [
'class' => 'environment-' . sanitize_html_class(strtolower(WP_ENV)),
],
]);
foreach ($this->stages as $stage => $url) {
if ($stage === WP_ENV) {
continue;
}
if ($subdomain_multisite) {
$url = $this->multisite_url($url);
}
$url = apply_filters('bedrock/stage_switcher_url', rtrim($url, '/') . $_SERVER['REQUEST_URI'], $url, $stage);
$admin_bar->add_menu([
'id' => "stage_$stage",
'parent' => 'environment',
'title' => ucwords($stage),
'href' => $url,
'meta' => [
'class' => 'environment-' . sanitize_html_class(strtolower($stage)),
],
]);
}
}
public function admin_css() { ?>
<style>
#wpadminbar #wp-admin-bar-environment > .ab-item:before {
content: "\f177";
top: 2px;
}
<?php
$environment_colors = apply_filters('bedrock/stage_switcher_colors', self::default_environment_colors());
if (!empty($environment_colors) && !empty($this->stages)) {
// Style the current environment (parent menu item)
if (defined('WP_ENV') && !empty($environment_colors[WP_ENV])) { ?>
#wpadminbar #wp-admin-bar-environment {
background-color: <?= $environment_colors[WP_ENV]; ?>;
}
<?php
}
// Style other environments (child menu items)
foreach ($this->stages as $stage => $url) {
if (empty($environment_colors[$stage])) {
continue;
} ?>
#wpadminbar #wp-admin-bar-stage_<?= sanitize_html_class(strtolower($stage)); ?> {
background-color: <?= $environment_colors[$stage]; ?>;
}
<?php
}
} ?>
</style>
<?php
}
private function multisite_url($url) {
// Normalize URL to ensure it can be successfully parsed
$url = esc_url($url);
$current_host = wp_parse_url(get_home_url(get_current_blog_id()), PHP_URL_HOST);
$current_stage_host_suffix = wp_parse_url($this->stages[WP_ENV], PHP_URL_HOST);
$target_stage_host_suffix = wp_parse_url($url, PHP_URL_HOST);
// Using preg_replace to anchor to the end of the host string
$target_host = preg_replace('/' . preg_quote($current_stage_host_suffix) . '$/', $target_stage_host_suffix, $current_host);
// Use the stage URL as the base for replacement to keep scheme/port
return str_replace($target_stage_host_suffix, $target_host, $url);
}
private static function default_environment_colors() {
return [
'development' => 'firebrick',
'staging' => 'chocolate',
'production' => 'transparent',
];
}
}
new StageSwitcher;