PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / 3.1.18.8
JetBackup – Backup, Restore & Migrate v3.1.18.8
3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / src / JetBackup / Wordpress / UI.php
backup / src / JetBackup / Wordpress Last commit date
.htaccess 5 months ago Blog.php 5 months ago Helper.php 5 months ago Init.php 5 months ago Installer.php 5 months ago MySQL.php 5 months ago UI.php 5 months ago Update.php 5 months ago Wordpress.php 5 months ago index.html 5 months ago web.config 5 months ago
UI.php
223 lines
1 <?php
2
3 namespace JetBackup\Wordpress;
4
5 use JetBackup\Alert\Alert;
6 use JetBackup\Config\System;
7 use JetBackup\Factory;
8 use JetBackup\JetBackup;
9 use JetBackup\MFA\GoogleAuthenticator;
10 use SleekDB\Exceptions\InvalidArgumentException;
11 use SleekDB\Exceptions\IOException;
12
13 if (!defined( '__JETBACKUP__')) die('Direct access is not allowed');
14
15 class UI {
16
17 const PUBLIC_PATH = 'public';
18 const PUBLIC_LIBRARIES = self::PUBLIC_PATH . '/libraries';
19 const PUBLIC_CSS = self::PUBLIC_PATH . '/css';
20 const PUBLIC_IMAGES = self::PUBLIC_PATH . '/images';
21 const PUBLIC_JS = self::PUBLIC_PATH . '/js';
22
23 const PAGES = [
24 [ 'menu_title' => 'Backups', 'page_title' => 'Restore Entire Site Backups', 'slug' => 'backups' ],
25 [ 'menu_title' => 'Backup Jobs', 'page_title' => 'Backup Jobs', 'slug' => 'jobs' ],
26 [ 'menu_title' => 'Destinations', 'page_title' => 'Destinations', 'slug' => 'destinations' ],
27 [ 'menu_title' => 'Schedules', 'page_title' => 'Schedules', 'slug' => 'schedules' ],
28 [ 'menu_title' => 'Queue', 'page_title' => 'Queue', 'slug' => 'queue' ],
29 [ 'menu_title' => 'Downloads', 'page_title' => 'Downloads', 'slug' => 'downloads' ],
30 [ 'menu_title' => 'Alerts', 'page_title' => 'Alerts', 'slug' => 'alerts' ],
31 [ 'menu_title' => 'Settings', 'page_title' => 'Settings', 'slug' => 'settings/general' ],
32 [ 'menu_title' => 'System Info', 'page_title' => 'System Info', 'slug' => 'system' ],
33 ];
34
35 /**
36 * @throws IOException
37 * @throws \JetBackup\Exception\IOException
38 * @throws InvalidArgumentException
39 */
40 public static function main() {
41
42 $site_url = self::getPluginPath() . '/';
43 wp_enqueue_script('jetbackup-lib-main-js', $site_url . self::PUBLIC_LIBRARIES . '/main.js');
44 $eddie_icon = $site_url . '/' . self::PUBLIC_IMAGES . '/eddie-menu.svg';
45
46 $hook = add_menu_page('JetBackup', __('JetBackup','jetbackup'), 'manage_options', 'jetbackup', [ '\JetBackup\Wordpress\UI', 'loadUI'], $eddie_icon, 74);
47 add_action('admin_print_scripts-' . $hook, [ '\JetBackup\Wordpress\UI', 'enqueueCSS' ]);
48 add_action('admin_print_scripts-' . $hook, [ '\JetBackup\Wordpress\UI', 'removeAdminNotices']);
49
50 foreach (self::PAGES as $position => $page) {
51
52 if($page['menu_title'] == 'System Info' && System::getTotalAlerts() > 1) {
53 $page['menu_title'] = __('System Info','jetbackup').'<span class="update-plugins count-2"><span class="plugin-count">'.System::getTotalAlerts().'</span></span>';
54 }
55
56 if($page['menu_title'] == 'Alerts' && Alert::getTotalCriticalAlerts() > 1) {
57 $page['menu_title'] = __('Alerts','jetbackup'). '<span class="update-plugins count-2"><span class="plugin-count">'.Alert::getTotalCriticalAlerts().'</span></span>';
58 }
59
60 $hook = add_submenu_page('jetbackup', $page['page_title'], __($page['menu_title'],'jetbackup'), 'manage_options', 'jetbackup#!/' . $page['slug'], function() {}, $position+1);
61 add_action('admin_print_scripts-' . $hook, [ '\JetBackup\Wordpress\UI', 'removeAdminNotices']);
62 }
63 }
64
65 public static function enqueueCSS() {
66 $site_url = self::getPluginPath() . '/';
67 wp_enqueue_style('jetbackup-lib-main-css', $site_url . self::PUBLIC_LIBRARIES . '/main.css');
68 }
69
70
71 /**
72 * @param $links
73 *
74 * @return array
75 */
76 public static function addActionLinks($links): array {
77 $custom_links = [
78 '<a href="' . admin_url('admin.php?page=jetbackup') . '">' . __('Dashboard', 'jetbackup') . '</a>',
79 '<a href="' . admin_url('admin.php?page=jetbackup#!/settings/general') . '">' . __('Settings', 'jetbackup') . '</a>',
80 ];
81 return array_merge($custom_links, $links);
82 }
83
84 /**
85 * @param $links
86 * @param $file
87 *
88 * @return array
89 */
90 public static function addRowMeta($links, $file) : array {
91 if ($file != 'backup/backup.php') return $links;
92 $custom_links = [
93 '<a href="https://docs.jetbackup.com/wordpress/jbwp" target="_blank">' . __('Documentation', 'jetbackup') . '</a>',
94 '<a href="https://www.jetbackup.com/contact" target="_blank">' . __('Support', 'jetbackup') . '</a>',
95 '<a href="https://wordpress.org/support/plugin/backup/reviews/?filter=5#new-post" target="_blank">' . __('Rate �
96
97
98
99
100 ', 'jetbackup') . '</a>',
101 ];
102 return array_merge($links, $custom_links);
103 }
104
105 /**
106 * @param $admin_bar
107 *
108 * @return void
109 */
110 public static function addTopMenuBarIntegration($admin_bar) : void {
111 if (!Factory::getSettingsGeneral()->isAdminTopMenuIntegrationEnabled()) return;
112 if (!current_user_can('manage_options')) return;
113
114 $admin_bar->add_menu(array(
115 'id' => 'jetbackup',
116 'title' => '<img src="' . esc_url(UI::getPluginPath() . '/public/images/logo-loader.png' ) . '" alt="JetBackup" style="height: 15px; vertical-align: middle;" />',
117 'href' => admin_url('admin.php?page=jetbackup'),
118 'meta' => array(
119 'title' => __('JetBackup'),
120 ),
121 ));
122 }
123
124 public static function convertPhpToMomentFormat($phpFormat) : string {
125 $replacements = [
126 'F' => 'MMMM', // Full month name
127 'j' => 'D', // Day without leading zero
128 'S' => 'o', // Day with ordinal suffix (6th, 7th)
129 'd' => 'DD', // Day with leading zero
130 'm' => 'MM', // Month with leading zero
131 'n' => 'M', // Month without leading zero
132 'Y' => 'YYYY', // Full year
133 'y' => 'YY', // 2-digit year
134 'H' => 'HH', // 24-hour with leading zero
135 'G' => 'H', // 24-hour format without leading zero
136 'h' => 'hh', // 12-hour with leading zero
137 'g' => 'h', // 12-hour without leading zero
138 'i' => 'mm', // Minutes
139 's' => 'ss', // Seconds
140 'A' => 'A', // Uppercase AM/PM
141 'a' => 'a', // Lowercase am/pm
142 'l' => 'dddd', // Full day of the week
143 'D' => 'ddd', // Abbreviated day of the week
144 ];
145
146 $format = '';
147
148 for($i = 0; $i < strlen($phpFormat); $i++) {
149 if($phpFormat[$i] == '\\') {
150 $i++;
151 if(!isset($phpFormat[$i])) break;
152 $format .= '[' . $phpFormat[$i] . ']';
153 } else {
154 $format .= $replacements[$phpFormat[$i]] ?? $phpFormat[$i];
155 }
156 }
157
158 return $format;
159 }
160
161
162 public static function loadUI() {
163
164 $dateFormat = self::convertPhpToMomentFormat(Wordpress::getDateFormat());
165 $timeFormat = self::convertPhpToMomentFormat(Wordpress::getTimeFormat());
166
167 $lang = Wordpress::getLocale();
168 $version = JetBackup::VERSION;
169 $public_path = self::getPluginPath() . '/' . self::PUBLIC_PATH;
170 $nonce = Wordpress::createNonce();
171
172 echo <<<HTML
173 <div ng-include="'$public_path/views/main.htm?v=$version'" ng-controller="JetBackup" id="JetBackup"></div>
174 <script type="text/javascript">
175 new JetBackup({
176 nonce: '$nonce',
177 language: '$lang',
178 dateFormat: '$dateFormat',
179 timeFormat: '$timeFormat',
180 plugin_path: '$public_path'
181 });
182 </script>
183 HTML;
184 }
185
186 public static function removeAdminNotices() {
187 remove_all_actions('admin_notices');
188 remove_all_actions('all_admin_notices');
189 remove_all_actions('network_admin_notices');
190 }
191
192 public static function getPluginPath(): string {
193 return Wordpress::getSiteURL() . '/' . Wordpress::WP_CONTENT . '/' . Wordpress::WP_PLUGINS . '/' . JetBackup::PLUGIN_NAME;
194 }
195
196 public static function validateMFA(): bool {
197 return isset($_COOKIE[GoogleAuthenticator::MFA_COOKIE_KEY]) &&
198 hash_equals(Wordpress::getUnslash($_COOKIE[GoogleAuthenticator::MFA_COOKIE_KEY]), GoogleAuthenticator::getCookieHash());
199 }
200
201 public static function heartbeat() {
202 $ttl = Factory::getSettingsAutomation()->getHeartbeatTTL();
203 $nonce = Wordpress::createNonce();
204
205 echo <<<HTML
206 <script type="text/javascript">
207 var nonce = '$nonce';
208 setInterval(function () {
209 const request = new XMLHttpRequest();
210 request.open('POST', ajaxurl, true);
211 request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
212 request.onreadystatechange = () => {
213 if (request.readyState !== XMLHttpRequest.DONE || request.status !== 200) return;
214 const data = JSON.parse(request.responseText);
215 if(nonce !== data.system.nonce) nonce = data.system.nonce;
216 };
217 request.send('action=jetbackup_heartbeat&nonce=' + nonce);
218 }, $ttl)
219 </script>
220 HTML;
221 }
222 }
223