PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 3.9.2
WP STAGING – WordPress Backup, Restore, Migration & Clone v3.9.2
4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Frontend / Frontend.php
wp-staging / Frontend Last commit date
Frontend.php 1 year ago FrontendServiceProvider.php 2 years ago LoginAfterRestore.php 1 year ago LoginForm.php 1 year ago LoginNotice.php 5 years ago
Frontend.php
262 lines
1 <?php
2
3 namespace WPStaging\Frontend;
4
5 use WPStaging\Core\WPStaging;
6 use WPStaging\Framework\Rest\Rest;
7 use WPStaging\Framework\Security\Capabilities;
8 use WPStaging\Framework\SiteInfo;
9 use WPStaging\Pro\Auth\LoginByLink;
10
11 use function WPStaging\functions\debug_log;
12
13 /**
14 * Class Frontend
15 * @package WPStaging\Frontend
16 */
17 class Frontend
18 {
19 /**
20 * @var object
21 */
22 private $settings;
23
24 /**
25 * @var bool
26 */
27 private $accessDenied = false;
28
29 /** @var LoginForm */
30 private $loginForm;
31
32 public function __construct()
33 {
34 $this->defineHooks();
35
36 $this->settings = json_decode(json_encode(get_option("wpstg_settings", [])));
37
38 $this->loginForm = WPStaging::make(LoginForm::class);
39 }
40
41 /**
42 * Change admin_bar site_name
43 *
44 * @return void
45 * @global object $wp_admin_bar
46 */
47 public function changeSiteName()
48 {
49 global $wp_admin_bar;
50 $siteTitle = apply_filters('wpstg_staging_site_title', 'STAGING');
51 if ($this->isStagingSite()) {
52 // Main Title
53 $wp_admin_bar->add_menu(
54 [
55 'id' => 'site-name',
56 'title' => is_admin() ? ($siteTitle . ' - ' . get_bloginfo('name')) : ($siteTitle . ' - ' . get_bloginfo('name') . ' Dashboard'),
57 'href' => is_admin() ? home_url('/') : admin_url(),
58 ]
59 );
60 }
61 }
62
63 /**
64 * Check permissions for the page to decide whether to disable the page
65 * @return void
66 */
67 public function checkPermissions()
68 {
69 $this->resetPermaLinks();
70
71 if ($this->showLoginForm()) {
72 if ($this->accessDenied) {
73 wp_logout();
74 $this->loginForm->setError(__('Access Denied', 'wp-staging'));
75 }
76
77 $overrides = [
78 'label_username' => __('Username or Email Address', 'wp-staging'),
79 ];
80 $this->loginForm->renderForm($this->loginForm->getDefaultArguments($overrides));
81 die();
82 }
83 }
84
85 /**
86 * Define Hooks
87 * @return void
88 */
89 private function defineHooks()
90 {
91 static $isRegistered = false;
92 if ($isRegistered) {
93 return;
94 }
95
96 add_action("init", [$this, "checkPermissions"]);
97 add_action("init", [$this, "resavePermalinks"]);
98 add_filter("wp_before_admin_bar_render", [$this, "changeSiteName"]);
99
100 $isRegistered = true;
101 }
102
103 /**
104 * Show a login form if user is not authorized
105 * @return bool
106 */
107 private function showLoginForm(): bool
108 {
109 $this->accessDenied = false;
110
111 // Don't show login form if from wp-cli
112 if ('cli' === PHP_SAPI && defined('WP_CLI')) {
113 return false;
114 }
115
116 // Don't show login form if showLoginForm filter is set to false. Used by Real Cookie Banner plugin
117 if (apply_filters('wpstg.frontend.showLoginForm', false)) {
118 return false;
119 }
120
121 // Don't show login form for rest requests
122
123 /** @var Rest $rest */
124 $rest = WPStaging::make(Rest::class);
125 if ($rest->isRestUrl()) {
126 return false;
127 }
128
129 if ($this->isLoginPage() || is_admin()) {
130 return false;
131 }
132
133 if (!$this->isStagingSite()) {
134 return false;
135 }
136
137 // Allow access for administrator
138 if (current_user_can('manage_options')) {
139 return false;
140 }
141
142 // Simple check (free version only)
143 if (!defined('WPSTGPRO_VERSION')) {
144 return (!isset($this->settings->disableAdminLogin) || $this->settings->disableAdminLogin !== '1');
145 }
146
147 // Allow access for wp staging user role "all"
148 if (!empty($this->settings->userRoles) && in_array('all', $this->settings->userRoles)) {
149 return false;
150 }
151
152 if (!is_user_logged_in()) {
153 return true;
154 }
155
156 $currentUser = wp_get_current_user();
157
158 if ($currentUser->has_cap(Capabilities::WPSTG_VISITOR_ROLE)) {
159 return false;
160 }
161
162 // Allow access for administrators if no user roles are defined
163 if (!isset($this->settings->userRoles) || !is_array($this->settings->userRoles)) {
164 $this->accessDenied = true;
165 return true;
166 }
167
168 if (defined('WPSTGPRO_VERSION') && !empty($this->settings->usersWithStagingAccess)) {
169 $usersWithStagingAccess = explode(',', $this->settings->usersWithStagingAccess);
170
171 // check against usernames
172 if (in_array($currentUser->user_login, $usersWithStagingAccess, true)) {
173 return false;
174 }
175
176 // check against emails
177 if (in_array($currentUser->user_email, $usersWithStagingAccess, true)) {
178 return false;
179 }
180 }
181
182 // Require login form if user is not in specific user role
183 $activeUserRoles = $currentUser->roles;
184
185 $result = isset($this->settings->userRoles) && is_array($this->settings->userRoles) ?
186 array_intersect($activeUserRoles, $this->settings->userRoles) :
187 [];
188
189 if (empty($result) && !$this->isLoginPage() && !is_admin()) {
190 $this->accessDenied = true;
191 return true;
192 }
193
194 // Don't show login form if no other rule apply
195 return false;
196 }
197
198 /**
199 * Check if it is a staging site
200 * @return bool
201 */
202 private function isStagingSite(): bool
203 {
204 return (new SiteInfo())->isStagingSite();
205 }
206
207 /**
208 * Check if it is the login page
209 * @return bool
210 */
211 private function isLoginPage(): bool
212 {
213 return ($GLOBALS["pagenow"] === "wp-login.php");
214 }
215
216 /**
217 * Reset permalink structure of the clone to default; index.php?p=123
218 */
219 private function resetPermaLinks()
220 {
221 // Do nothing
222 if (!$this->isStagingSite() || get_option("wpstg_rmpermalinks_executed") === "true") {
223 return;
224 }
225
226 // Do nothing
227 if (defined('WPSTGPRO_VERSION') && isset($this->settings->keepPermalinks) && $this->settings->keepPermalinks === "1") {
228 return;
229 }
230
231 // $wp_rewrite is not available before the init hook. So we need to use the global variable
232 global $wp_rewrite;
233
234 // @see https://developer.wordpress.org/reference/classes/wp_rewrite/set_permalink_structure/
235 $wp_rewrite->set_permalink_structure('');
236
237 flush_rewrite_rules();
238
239 update_option("wpstg_rmpermalinks_executed", "true");
240 }
241
242 /**
243 * @return void
244 */
245 public function resavePermalinks()
246 {
247 if (!$this->isStagingSite() || get_option("wpstg_resave_permalinks_executed") === "true") {
248 return;
249 }
250
251 try {
252 include_once(ABSPATH . 'wp-admin/includes/misc.php'); // Include `misc.php` to ensure `save_mod_rewrite_rules` is available when `flush_rules` is executed.
253 global $wp_rewrite;
254 $wp_rewrite->init();
255 $wp_rewrite->flush_rules(true);
256 update_option("wpstg_resave_permalinks_executed", "true");
257 } catch (\Throwable $e) {
258 debug_log('File wp-admin/includes/misc.php does not exist. Error: ' . $e->getMessage());
259 }
260 }
261 }
262