PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 3.8.2
WP STAGING – WordPress Backup, Restore, Migration & Clone v3.8.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 / Framework / Assets / Assets.php
wp-staging / Framework / Assets Last commit date
Assets.php 2 years ago
Assets.php
504 lines
1 <?php
2
3 namespace WPStaging\Framework\Assets;
4
5 use WPStaging\Backup\BackupServiceProvider;
6 use WPStaging\Backup\Job\AbstractJob;
7 use WPStaging\Core\DTO\Settings;
8 use WPStaging\Core\WPStaging;
9 use WPStaging\Framework\Filesystem\Scanning\ScanConst;
10 use WPStaging\Framework\Security\AccessToken;
11 use WPStaging\Framework\Security\Nonce;
12 use WPStaging\Framework\Traits\ResourceTrait;
13 use WPStaging\Framework\SiteInfo;
14 use WPStaging\Framework\Analytics\AnalyticsConsent;
15 use WPStaging\Backup\Task\Tasks\JobBackup\DatabaseBackupTask;
16 use WPStaging\Framework\Facades\Hooks;
17 use WPStaging\Framework\Notices\Notices;
18
19 class Assets
20 {
21 use ResourceTrait;
22
23 /**
24 * Default admin bar background color for staging site
25 * @var string
26 */
27 const DEFAULT_ADMIN_BAR_BG = "#ff8d00";
28
29 private $accessToken;
30
31 private $settings;
32
33 private $analyticsConsent;
34
35 public function __construct(AccessToken $accessToken, Settings $settings, AnalyticsConsent $analyticsConsent)
36 {
37 $this->accessToken = $accessToken;
38 $this->settings = $settings;
39 $this->analyticsConsent = $analyticsConsent;
40 }
41
42 /**
43 * Prepend the URL to the assets to the given file
44 *
45 * @param string $assetsFile optional
46 * @return string
47 */
48 public function getAssetsUrl($assetsFile = '')
49 {
50 return WPSTG_PLUGIN_URL . "assets/$assetsFile";
51 }
52
53 /**
54 * Get minified or non minified css file name based on debug mode
55 * @param string $cssFileNameWithoutExtension path without extension relative to wpstgPluginDir/assets/css/dist/
56 * @return string
57 */
58 public function getCssAssetsFileName(string $cssFileNameWithoutExtension): string
59 {
60 // If in debug mode, get non-minified css file name if it exists
61 $nonMinCssFile = $this->getAssetsPath("css/dist/$cssFileNameWithoutExtension.css");
62 if ($this->isDebugOrDevMode() && file_exists($nonMinCssFile)) {
63 return "css/dist/$cssFileNameWithoutExtension.css";
64 }
65
66 return "css/dist/$cssFileNameWithoutExtension.min.css";
67 }
68
69 /**
70 * Get minified or non minified js file name based on debug mode
71 * @param string $jsFileNameWithoutExtension path without extension relative to wpstgPluginDir/assets/js/dist/
72 * @return string
73 */
74 public function getJsAssetsFileName(string $jsFileNameWithoutExtension): string
75 {
76 // If in debug mode, get non-minified js file name if it exists
77 $nonMinJsFile = $this->getAssetsPath("js/dist/$jsFileNameWithoutExtension.js");
78 if ($this->isDebugOrDevMode() && file_exists($nonMinJsFile)) {
79 return "js/dist/$jsFileNameWithoutExtension.js";
80 }
81
82 return "js/dist/$jsFileNameWithoutExtension.min.js";
83 }
84
85 /**
86 * Get the version the given file. Use for caching
87 *
88 * @param string $assetsFile
89 * @param string $assetsVersion use WPStaging::getVersion() instead if not given
90 * @return string
91 */
92 public function getAssetsUrlWithVersion($assetsFile, $assetsVersion = '')
93 {
94 $url = $this->getAssetsUrl($assetsFile);
95 $ver = empty($assetsVersion) ? $this->getAssetsVersion($assetsFile, $assetsVersion) : $assetsVersion;
96 return $url . '?v=' . $ver;
97 }
98
99 /**
100 * Prepend the Path to the assets to the given file
101 *
102 * @param string $assetsFile optional
103 * @return string
104 */
105 public function getAssetsPath($assetsFile = '')
106 {
107 return WPSTG_PLUGIN_DIR . "assets/$assetsFile";
108 }
109
110 /**
111 * Get the version the given file. Use for caching
112 *
113 * @param string $assetsFile
114 * @param string $assetsVersion Optional, use WPStaging::getVersion() instead if not given
115 * @return string|int
116 */
117 public function getAssetsVersion($assetsFile, $assetsVersion = '')
118 {
119 $filename = $this->getAssetsPath($assetsFile);
120 $filemtime = file_exists($filename) ? @filemtime($filename) : false;
121
122 if ($filemtime !== false) {
123 return $filemtime;
124 } else {
125 return $assetsVersion !== '' ? $assetsVersion : WPStaging::getVersion();
126 }
127 }
128
129 /**
130 * @action admin_enqueue_scripts 100 1
131 * @action wp_enqueue_scripts 100 1
132 */
133 public function enqueueElements($hook)
134 {
135 $this->loadGlobalAssets($hook);
136
137 add_action(Notices::INJECT_ANALYTICS_CONSENT_ASSETS_ACTION, [$this, 'enqueueAnalyticsConsentAssets'], 10, 0);
138
139 // Load this css file on frontend and backend on all pages if current site is a staging site
140 if ((new SiteInfo())->isStagingSite()) {
141 wp_register_style('wpstg-admin-bar', false);
142 wp_enqueue_style('wpstg-admin-bar');
143 wp_add_inline_style('wpstg-admin-bar', $this->getStagingAdminBarColor());
144 }
145
146 // Load feedback form js file on page plugins.php in free version or in free dev version
147 if (!WPStaging::isPro() && $this->isPluginsPage()) {
148 $asset = $this->getJsAssetsFileName('wpstg-admin-plugins');
149 wp_enqueue_script(
150 "wpstg-admin-script",
151 $this->getAssetsUrl($asset),
152 ["jquery"],
153 $this->getAssetsVersion($asset),
154 false
155 );
156
157 $asset = $this->getCssAssetsFileName('wpstg-admin-feedback');
158 wp_enqueue_style(
159 "wpstg-admin-feedback",
160 $this->getAssetsUrl($asset),
161 [],
162 $this->getAssetsVersion($asset)
163 );
164 }
165
166 // Load js file on page plugins.php for pro version
167 if (WPStaging::isPro() && is_admin()) {
168 $asset = $this->getJsAssetsFileName('pro/wpstg-admin-all-pages');
169 wp_enqueue_script(
170 "wpstg-admin-all-pages-script",
171 $this->getAssetsUrl($asset),
172 ["jquery"],
173 $this->getAssetsVersion($asset),
174 false
175 );
176
177 $asset = $this->getCssAssetsFileName('wpstg-admin-all-pages');
178 wp_enqueue_style(
179 "wpstg-admin-all-pages-style",
180 $this->getAssetsUrl($asset),
181 [],
182 $this->getAssetsVersion($asset)
183 );
184 }
185
186 // Load below assets only on wp staging admin pages
187 if ($this->isNotWPStagingAdminPage($hook)) {
188 return;
189 }
190
191 // Load wpstg js files
192 $asset = $this->getJsAssetsFileName('wpstg');
193 wp_enqueue_script(
194 "wpstg-common",
195 $this->getAssetsUrl($asset),
196 ["jquery"],
197 $this->getAssetsVersion($asset),
198 false
199 );
200
201 // Load admin js files
202 $asset = $this->getJsAssetsFileName('wpstg-admin');
203 wp_enqueue_script(
204 "wpstg-admin-script",
205 $this->getAssetsUrl($asset),
206 ["wpstg-common", "wpstg-admin-notyf", "wpstg-admin-sweetalerts"],
207 $this->getAssetsVersion($asset),
208 false
209 );
210
211 // Sweet Alert
212 $asset = $this->getJsAssetsFileName('wpstg-sweetalert2');
213 wp_enqueue_script(
214 'wpstg-admin-sweetalerts',
215 $this->getAssetsUrl($asset),
216 [],
217 $this->getAssetsVersion($asset),
218 true
219 );
220
221 $asset = $this->getCssAssetsFileName('wpstg-sweetalert2');
222 wp_enqueue_style(
223 'wpstg-admin-sweetalerts',
224 $this->getAssetsUrl($asset),
225 [],
226 $this->getAssetsVersion($asset)
227 );
228
229 // Notyf Toast Notification
230 $asset = 'js/vendor/notyf.min.js';
231 wp_enqueue_script(
232 'wpstg-admin-notyf',
233 $this->getAssetsUrl($asset),
234 [],
235 $this->getAssetsVersion($asset),
236 true
237 );
238
239 $asset = 'css/vendor/notyf.min.css';
240 wp_enqueue_style(
241 'wpstg-admin-notyf',
242 $this->getAssetsUrl($asset),
243 [],
244 $this->getAssetsVersion($asset)
245 );
246
247 // Internal hook to enqueue backup scripts, used by the backup addon
248 Hooks::doAction(BackupServiceProvider::BACKUP_SCRIPTS_ENQUEUE_ACTION);
249
250 // Load admin js pro files
251 if (defined('WPSTGPRO_VERSION')) {
252 $asset = $this->getJsAssetsFileName('pro/wpstg-admin-pro');
253 wp_enqueue_script(
254 "wpstg-admin-pro-script",
255 $this->getAssetsUrl($asset),
256 ["jquery", "wpstg-admin-notyf", "wpstg-admin-sweetalerts"],
257 $this->getAssetsVersion($asset),
258 false
259 );
260 }
261
262 // Load admin css files
263 $asset = $this->getCssAssetsFileName('wpstg-admin');
264 wp_enqueue_style(
265 "wpstg-admin",
266 $this->getAssetsUrl($asset),
267 [],
268 $this->getAssetsVersion($asset)
269 );
270
271 $backupCompleteMessage = __('You can restore this backup anytime or upload it to another website and restore it there.', 'wp-staging');
272
273 if (WPStaging::isPro() === false) {
274 $backupCompleteMessage = __('You can restore this backup anytime on this website.', 'wp-staging');
275 }
276
277 $wpstgConfig = [
278 "delayReq" => 0,
279 // TODO: move directorySeparator to consts?
280 "settings" => (object)[
281 "directorySeparator" => ScanConst::DIRECTORIES_SEPARATOR
282 ],
283 "tblprefix" => WPStaging::getTablePrefix(),
284 "isMultisite" => is_multisite(),
285 AccessToken::REQUEST_KEY => (string)$this->accessToken->getToken() ?: (string)$this->accessToken->generateNewToken(),
286 'nonce' => wp_create_nonce(Nonce::WPSTG_NONCE),
287 'assetsUrl' => $this->getAssetsUrl(),
288 'ajaxUrl' => admin_url('admin-ajax.php'),
289 'wpstgIcon' => $this->getAssetsUrl('img/wpstg-loader.gif'),
290 'maxUploadChunkSize' => $this->getMaxUploadChunkSize(),
291 'backupDBExtension' => DatabaseBackupTask::PART_IDENTIFIER . '.' . DatabaseBackupTask::FILE_FORMAT,
292 'analyticsConsentAllow' => esc_url($this->analyticsConsent->getConsentLink(true)),
293 'analyticsConsentDeny' => esc_url($this->analyticsConsent->getConsentLink(false)),
294 'isPro' => WPStaging::isPro(),
295 'maxFailedRetries' => Hooks::applyFilters(AbstractJob::TEST_FILTER_MAXIMUM_RETRIES, 10),
296 // TODO: handle i18n translations through Class/Service Provider?
297 'i18n' => [
298 'dbConnectionSuccess' => esc_html__('Database connection successful', 'wp-staging'),
299 'dbConnectionFailed' => esc_html__('Database connection failed', 'wp-staging'),
300 'somethingWentWrong' => esc_html__('Something went wrong.', 'wp-staging'),
301 'noRestoreFileFound' => esc_html__('No backup file found.', 'wp-staging'),
302 'selectFileToRestore' => esc_html__('Select backup file to restore.', 'wp-staging'),
303 'cloneResetComplete' => esc_html__('Reset Complete!', 'wp-staging'),
304 'cloneUpdateComplete' => esc_html__('Update Complete!', 'wp-staging'),
305 'success' => esc_html__('Success', 'wp-staging'),
306 'resetClone' => esc_html__('Reset Staging Site', 'wp-staging'),
307 'showLogs' => esc_html__('Show Logs', 'wp-staging'),
308 'hideLogs' => esc_html__('Hide Logs', 'wp-staging'),
309 'noTableSelected' => esc_html__('No table selected', 'wp-staging'),
310 'tablesSelected' => esc_html__('{d} tables(s) selected', 'wp-staging'),
311 'filesSelected' => esc_html__('{t} theme{ts}, {p} plugin{ps}, {o} other folder{os} selected', 'wp-staging'),
312 'wpstg_cloning' => [
313 'title' => esc_html__('Staging Site Created Successfully!', 'wp-staging'),
314 'body' => esc_html__('You can access it from here:', 'wp-staging'),
315 ],
316 'wpstg_update' => [
317 'title' => esc_html__('Staging Site Updated Successfully!', 'wp-staging'),
318 'body' => esc_html__('You can access it from here:', 'wp-staging'),
319 ],
320 'wpstg_push_processing' => [
321 'title' => esc_html__('Staging Site Pushed Successfully!', 'wp-staging'),
322 'body' => esc_html__('Now delete the theme and the website cache if the website does not look as expected! ', 'wp-staging'),
323 ],
324 'wpstg_reset' => [
325 'title' => esc_html__('Staging Site Reset Successfully!', 'wp-staging'),
326 'body' => esc_html__('You can access it from here:', 'wp-staging'),
327 ],
328 'wpstg_delete_clone' => [
329 'title' => esc_html__('Staging Site Deleted Successfully!', 'wp-staging'),
330 ],
331 'backupSchedule' => [
332 'title' => esc_html__('Backup Schedule Created', 'wp-staging'),
333 'body' => esc_html__('Backup is scheduled according to the provided settings.', 'wp-staging'),
334 ],
335 'backupCreationBG' => [
336 'title' => esc_html__('Backup Creation Triggered', 'wp-staging'),
337 'body' => esc_html__('Backup creation is triggered to run in background. You will be notified by email (if set in settings) once the backup is created!', 'wp-staging'),
338 ],
339 'backupCreated' => [
340 'title' => esc_html__('Backup Complete', 'wp-staging'),
341 'body' => esc_html($backupCompleteMessage),
342 ],
343 ],
344 ];
345
346 // We need some wpstgConfig vars in the wpstg.js file (loaded with wpstg-common scripts) as well
347 wp_localize_script("wpstg-common", "wpstg", $wpstgConfig);
348 }
349
350 public function enqueueAnalyticsConsentAssets()
351 {
352 $asset = $this->getJsAssetsFileName('analytics-consent-modal');
353 wp_enqueue_script(
354 "wpstg-show-analytics-modal",
355 $this->getAssetsUrl($asset),
356 [],
357 $this->getAssetsVersion($asset)
358 );
359
360 $asset = $this->getCssAssetsFileName('analytics-consent-modal');
361 wp_enqueue_style(
362 'wpstg-plugin-activation',
363 $this->getAssetsUrl($asset),
364 [],
365 $this->getAssetsVersion($asset)
366 );
367 }
368
369 /**
370 * Load js vars globally but NOT on wp staging admin pages
371 * @return void
372 */
373 private function loadGlobalAssets($pageSlug)
374 {
375 if (!$this->isNotWPStagingAdminPage($pageSlug)) {
376 return;
377 }
378
379 $asset = $this->getJsAssetsFileName('wpstg-blank-loader');
380 wp_enqueue_script('wpstg-global', $this->getAssetsUrl($asset), [], [], false);
381
382 $vars = [
383 'nonce' => wp_create_nonce(Nonce::WPSTG_NONCE),
384 ];
385
386 wp_localize_script("wpstg-global", "wpstg", $vars);
387 }
388
389 /**
390 * @return int The max upload size for a file.
391 */
392 protected function getMaxUploadChunkSize()
393 {
394 $lowerLimit = 64 * KB_IN_BYTES;
395 $upperLimit = 16 * MB_IN_BYTES;
396
397 $maxPostSize = wp_convert_hr_to_bytes(ini_get('post_max_size'));
398 $uploadMaxFileSize = wp_convert_hr_to_bytes(ini_get('upload_max_filesize'));
399
400 // The real limit, read from the PHP context.
401 $limit = min($maxPostSize, $uploadMaxFileSize) * 0.90;
402
403 // Do not allow going over upper limit.
404 $limit = min($limit, $upperLimit);
405
406 // Do not allow going under lower limit.
407 $limit = max($lowerLimit, $limit);
408
409 return (int)$limit;
410 }
411
412 /**
413 * Load css and js files only on wp staging admin pages
414 *
415 * @param $page string slug of the current page
416 *
417 * @return bool
418 */
419 private function isNotWPStagingAdminPage($page)
420 {
421 if (defined('WPSTGPRO_VERSION')) {
422 $availablePages = [
423 "toplevel_page_wpstg_clone",
424 "toplevel_page_wpstg_backup",
425 "wp-staging-pro_page_wpstg_clone",
426 "wp-staging-pro_page_wpstg_backup",
427 "wp-staging-pro_page_wpstg-settings",
428 "wp-staging-pro_page_wpstg-tools",
429 "wp-staging-pro_page_wpstg-license",
430 "wp-staging-pro_page_wpstg-restorer",
431 ];
432 } else {
433 $availablePages = [
434 "toplevel_page_wpstg_clone",
435 "toplevel_page_wpstg_backup",
436 "wp-staging_page_wpstg_clone",
437 "wp-staging_page_wpstg_backup",
438 "wp-staging_page_wpstg-settings",
439 "wp-staging_page_wpstg-tools",
440 "wp-staging_page_wpstg-welcome",
441 ];
442 }
443
444 return !in_array($page, $availablePages) || !is_admin();
445 }
446
447 /**
448 * Remove heartbeat api and user login check
449 *
450 * @action admin_enqueue_scripts 100 1
451 * @see AssetServiceProvider.php
452 *
453 * @param bool $hook
454 */
455 public function removeWPCoreJs($hook)
456 {
457 if ($this->isNotWPStagingAdminPage($hook)) {
458 return;
459 }
460
461 // Disable user login status check
462 // Todo: Can we remove this now that we have AccessToken?
463 remove_action('admin_enqueue_scripts', 'wp_auth_check_load');
464
465 // Disable heartbeat check for cloning and pushing
466 wp_deregister_script('heartbeat');
467 }
468
469 /**
470 * Check if current page is plugins.php
471 * @global array $pagenow
472 * @return bool
473 */
474 private function isPluginsPage()
475 {
476 global $pagenow;
477
478 return ($pagenow === 'plugins.php');
479 }
480
481 /**
482 * @return string
483 */
484 public function getStagingAdminBarColor()
485 {
486 $barColor = $this->settings->getAdminBarColor();
487 if (!preg_match("/#([a-f0-9]{3}){1,2}\b/i", $barColor)) {
488 $barColor = self::DEFAULT_ADMIN_BAR_BG;
489 }
490
491 return "#wpadminbar { background-color: {$barColor} !important; }";
492 }
493
494 /**
495 * Check whether app is in debug mode or in dev mode
496 *
497 * @return bool
498 */
499 private function isDebugOrDevMode()
500 {
501 return ($this->settings->isDebugMode() || (defined('WPSTG_DEV') && WPSTG_DEV === true) || (defined('WPSTG_DEBUG') && WPSTG_DEBUG === true));
502 }
503 }
504