PluginProbe
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript / trunk
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript vtrunk
4.1.16 4.1.15 4.1.14 4.1.13 4.1.12 4.1.11 4.1.10 4.0.30 4.0.29 4.0.28 4.0.27 4.0.26 4.0.24 4.0.25 4.0.23 4.0.22 4.0.21 4.0.19 4.0.18 4.0.17 4.0.16 1.9.3 1.9.4 1.9.5 1.9.6 All 170 releases
← All changes | admin/tabs/dashboard.php +252 -204 1.9.5trunk View file →
@@ -1,101 +1,56 @@
1 1 <?php
2 2 if (!defined('ABSPATH')) exit;
3 3
4 +use BerqWP\BerqWP;
5 +
4 6 $post_types = get_option('berqwp_optimize_post_types');
5 -$paged = 1;
6 -$posts_per_page = 500; // Number of posts to process per batch
7 -$total_pages = 0;
8 -$cached_pages = 0;
9 -$optimized_pages = [];
7 +$args = array(
8 + 'post_type' => $post_types,
9 + 'posts_per_page' => -1,
10 + 'fields' => 'ids',
11 + 'post_status' => 'publish'
12 +);
13 +$query = new WP_Query($args);
14 +$pages_to_exclude = get_option('berq_exclude_urls', []);
15 +$total_pages = (int) $query->found_posts - count($pages_to_exclude);
16 +$optimized_pages = bwp_cached_pages_count();
10 17
11 -do {
12 - $args = array(
13 - 'post_type' => $post_types,
14 - 'posts_per_page' => $posts_per_page,
15 - 'paged' => $paged,
16 - );
18 +if (get_option('show_on_front') !== 'page') {
19 + $total_pages++;
20 +}
17 21
18 - $query = new WP_Query($args);
22 +if (empty($total_pages) || $total_pages <= 0) {
23 + $cached_percentage = 0;
24 +} else {
25 + $cached_percentage = round(($optimized_pages / $total_pages) * 100, 2);
19 26
20 - while ($query->have_posts()) {
21 - $query->the_post();
27 +}
28 +if ($cached_percentage > 100) {
29 + $cached_percentage = 100;
30 +}
22 31
23 - $url = trailingslashit(get_permalink());
24 - $slug = str_replace(home_url(), '', $url);
32 +if ($cached_percentage < 0) {
33 + $cached_percentage = 0;
34 +}
25 35
26 - if (berqwp_is_slug_excludable($slug)) {
27 - continue;
28 - }
29 -
30 - $cache_directory = optifer_cache . '/html/';
31 - $cache_key = md5($slug);
32 - $cache_file = $cache_directory . $cache_key . '.html';
33 -
34 - if (file_exists($cache_file)) {
35 - $cached_pages++;
36 -
37 - $status = '<span class="bwp-cache-tag completed">Completed</span>';
38 -
39 - if (bwp_is_partial_cache($slug) === true) {
40 - $status = '<span class="bwp-cache-tag part-completed">Partial cache</span>';
41 - }
42 -
43 - $page_arr = [
44 - 'url' => $url,
45 - 'status' => $status,
46 - 'last_modified' => filemtime($cache_file)
47 - ];
48 -
49 - array_push($optimized_pages, $page_arr);
50 - }
51 -
52 - $total_pages++;
53 - }
54 -
55 - // Reset post data
56 - wp_reset_postdata();
57 -
58 - // Increase the paged value to get the next set of posts
59 - $paged++;
60 -
61 -} while ($query->have_posts());
62 -
63 -// $optimized_pages = [
64 -// ["url" => "test url", "last_modified" => "1721741554"],
65 -// ["url" => "test url", "last_modified" => "1721741554"],
66 -// ["url" => "test url", "last_modified" => "1721741554"],
67 -// ["url" => "test url", "last_modified" => "1721741554"],
68 -// ["url" => "test url", "last_modified" => "1721741554"],
69 -// ["url" => "test url", "last_modified" => "1721741554"],
70 -// ["url" => "test url", "last_modified" => "1721741554"],
71 -// ["url" => "test url", "last_modified" => "1721741554"],
72 -// ["url" => "test url", "last_modified" => "1721741554"],
73 -// ["url" => "test url", "last_modified" => "1721741554"],
74 -// ["url" => "test url", "last_modified" => "1721741554"],
75 -// ["url" => "test url", "last_modified" => "1721741554"],
76 -// ["url" => "test url", "last_modified" => "1721741554"],
77 -// ["url" => "test url", "last_modified" => "1721741554"],
78 -// ["url" => "test url", "last_modified" => "1721741554"],
79 -// ];
80 -
81 -wp_reset_postdata();
82 -
83 -$cached_percentage = round((count($optimized_pages) / $total_pages) * 100, 2);
84 -
85 36 ?>
86 -<div id="dashboard">
37 +<div id="dashboard" <?php bwp_is_tab('dashboard'); ?>>
87 38 <h2 class="berq-tab-title">Dashboard</h2>
39 +
40 + <?php if (bwp_show_docs() && $berqwp_can_use_cloud) { ?>
88 41 <div class="berq-info-box guide">
89 42 <div class="berq-box-content">
43 + <div class="icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-book-marked-icon lucide-book-marked"><path d="M10 2v8l3-3 3 3V2"/><path d="M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H19a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1H6.5a1 1 0 0 1 0-5H20"/></svg></div>
90 44 <p><?php esc_html_e('Guide:', 'searchpro'); ?> <a href="https://berqwp.com/help-center/get-started-with-berqwp/" target="_blank"><?php esc_html_e('Get Started With BerqWP', 'searchpro'); ?></a></p>
91 45 </div>
92 -
46 +
93 47 </div>
48 + <?php } ?>
94 49
95 - <?php
96 - if (bwp_cached_pages_count() <= 0 ) {
97 - bwp_dash_notification("We're currently building the cache for this website, which may take up to 5 minutes. Thank you for your patience, good things are worth the wait.", 'warning');
50 + <?php
51 + if ($configs['optimization_method'] == 'cloud' && !bwp_is_home_cached()) {
52 + bwp_dash_notification("We're currently building the cache for this website's homepage, which may take up to 5 minutes. Thank you for your patience, good things are worth the wait.", 'warning');
98 53 }
99 54 ?>
100 55
101 56 <div class="berq-info-box">
@@ -100,123 +55,93 @@
100 55
101 56 <div class="berq-info-box">
102 57 <h3 class="berq-box-title"><?php esc_html_e('Optimization Mode', 'searchpro'); ?></h3>
103 58 <div class="berq-box-content">
104 - <p style="margin-bottom:40px"><?php esc_html_e("Optimization modes are optimization presets that allow you to balance your website between the best optimization score and website functionality stability.", 'searchpro'); ?> <a href="https://berqwp.com/help-center/berqwp-optimization-modes/" target="_blank"><?php esc_html_e("Learn more", 'searchpro'); ?></a> </p>
105 - <div class="optimzation-slider">
106 - <input id="berq_opt_mode" name="berq_opt_mode" type="text" value="<?php echo esc_attr( get_option('berq_opt_mode') ); ?>" style="display:none" />
107 - </div>
59 + <p><?php esc_html_e("Optimization modes are optimization presets that allow you to balance your website between the best optimization score and website functionality stability.", 'searchpro'); ?>
108 60
109 - </div>
110 - </div>
111 - <div class="berq-info-box before-after-comparision">
112 - <h3 class="berq-box-title"><?php esc_html_e('Google PageSpeed Score', 'searchpro'); ?></h3>
113 - <div class="without-berqwp">
114 - <?php
115 - if (get_option('berqwp_enable_sandbox')) {
116 - echo '<div class="berqw-sandbox">Sandbox Optimization</div>';
117 - }
118 - ?>
119 - <div class="berq-speed-score"></div>
120 - <p class="device-type"><?php esc_html_e('Device: Mobile', 'searchpro'); ?></p>
121 - <p class="website-url">
122 - <?php
123 - $cache_directory = optifer_cache . '/html/';
124 - $is_home_ready = file_exists($cache_directory . md5('/') . '.html');
125 - $msg = '';
61 + <?php if (bwp_show_docs()) { ?>
62 + <a href="https://berqwp.com/help-center/berqwp-optimization-modes/" target="_blank"><?php esc_html_e("Learn more", 'searchpro'); ?></a>
63 + <?php } ?>
64 + </p>
126 65
127 - if (get_option('berqwp_enable_sandbox')) {
128 - $msg .= '/?berqwp';
129 - }
66 + <div class="berqwp-optimization-modes-container">
67 + <div class="berqwp-inline-radio-select">
68 + <label>
69 + <input type="radio" name="berq_opt_mode" value="1" <?php echo get_option('berq_opt_mode') == '1' ? 'checked' : ''; ?>>
70 + <div>
71 + <?php esc_html_e('Standard', 'searchpro'); ?>
72 + <p>Standard optimizations like image optimization, page cache, URL prefectch.</p>
73 + </div>
74 + </label>
75 + <label>
76 + <input type="radio" name="berq_opt_mode" value="2" <?php echo get_option('berq_opt_mode') == '2' ? 'checked' : ''; ?>>
77 + <div>
78 + <?php esc_html_e('Smart', 'searchpro'); ?>
79 + <p>Highly stable mode for many cases with JavaScipt & CSS aynchronouse loading</p>
80 + </div>
81 + </label>
82 + <label>
83 + <input type="radio" name="berq_opt_mode" value="3" <?php echo get_option('berq_opt_mode') == '3' ? 'checked' : ''; ?>>
84 + <div>
85 + <?php esc_html_e('Blaze', 'searchpro'); ?>
86 + <p>Design first optimization with proritized CSS loading and delayed JavaScript</p>
87 + </div>
88 + </label>
89 + <label class="berqwp-best-performance">
90 + <input type="radio" name="berq_opt_mode" value="4" <?php echo get_option('berq_opt_mode') == '4' ? 'checked' : ''; ?>>
91 + <div>
92 + <?php esc_html_e('Turbo', 'searchpro'); ?>
93 + <p>Delivers best performance possible by using minimal requests on initial page load</p>
94 + </div>
95 + </label>
96 + </div>
130 97
131 - if ($is_home_ready == false) {
132 - $msg .= '<br>This page isn\'t cached yet';
133 - }
134 - echo wp_kses_post(home_url() . $msg); ?>
135 - </p>
136 - <h4><?php esc_html_e('Mobile Score', 'searchpro'); ?></h4>
137 - </div>
138 - <div class="with-berqwp">
139 - <?php
140 - if (get_option('berqwp_enable_sandbox')) {
141 - echo '<div class="berqw-sandbox">Sandbox Optimization</div>';
142 - }
143 - ?>
144 - <div class="berq-speed-score"></div>
145 - <p class="device-type"><?php esc_html_e('Device: Desktop', 'searchpro'); ?></p>
146 - <p class="website-url">
147 - <?php
148 - $cache_directory = optifer_cache . '/html/';
149 - $is_home_ready = file_exists($cache_directory . md5('/') . '.html');
150 - $msg = '';
98 + </div>
99 + <!--<div class="optimzation-slider">
100 + <input id="berq_opt_mode" name="berq_opt_mode" type="text" value="<?php echo esc_attr( get_option('berq_opt_mode') ); ?>" style="display:none" />
101 + </div>-->
151 102
152 - if (get_option('berqwp_enable_sandbox')) {
153 - $msg .= '/?berqwp';
154 - }
155 -
156 - if ($is_home_ready == false) {
157 - $msg .= '<br>This page isn\'t cached yet';
158 - }
159 - echo wp_kses_post(home_url() . $msg); ?>
160 - </p>
161 - <h4><?php esc_html_e('Desktop Score', 'searchpro'); ?></h4>
162 103 </div>
163 104 </div>
164 105
165 - <div class="berq-info-box">
166 - <h3 class="berq-box-title"><?php esc_html_e('Cached Pages', 'searchpro'); ?></h3>
167 - <div class="berq-box-content">
168 - <div class="cache-percentage"><p><b><?php echo $cached_percentage; ?>%</b> (<?php echo $cached_pages; ?>) of your pages are currently cached.</p></div>
169 - <div class="cached-pages-bar">
170 - <div class="progress-bar" style="width:<?php echo $cached_percentage; ?>%"></div>
171 - </div>
172 -
173 - <?php
174 - if ($this->key_response->product_ref == 'Free Account' && bwp_cached_pages_count() >= 10) {
175 - bwp_dash_notification("You've reached the limit of 10 optimized pages for your free BerqWP account. Upgrade now to optimize unlimited pages and get the best performance for your entire site!", "warning");
176 - }
177 - ?>
178 -
179 - <div class="optimized-pages">
180 - <table>
181 - <thead>
182 - <tr>
183 - <th>Page URL</th>
184 - <th>Cache Status</th>
185 - <th>Last Optimized Date</th>
186 - </tr>
187 - </thead>
188 - <tbody>
106 + <div class="berq-triple-boxes">
107 + <?php if ($berqwp_can_use_cloud) { ?>
108 + <div class="berq-info-box" style="position: relative;">
109 + <a class="berq-stat-refresh" href="#" style="display:none;"><svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#29ac20"><path d="M229.08-205.08v-52H310l-13.08-13.84q-42.3-39.62-68.61-92.62-26.31-53-26.31-115.69 0-93.69 55.23-165.96 55.23-72.27 140.77-98.96v54.23q-63.39 25.3-103.69 81.73Q254-551.77 254-479.23q0 49.92 20.27 92.65 20.27 42.73 54.81 73.27l15.38 15.39v-74.54h52v167.38H229.08ZM562-215.85v-54.23q63.39-25.3 103.69-81.73Q706-408.23 706-480.77q0-49.92-20.27-92.65-20.27-42.73-54.81-73.27l-15.38-15.39v74.54h-52v-167.38h167.38v52H650l13.08 13.84q43.46 38.47 69.19 92.04Q758-543.46 758-480.77q0 93.69-55.23 165.96-55.23 72.27-140.77 98.96Z"></path></svg></a>
110 + <h3 class="berq-box-title"><?php esc_html_e('Pages in Queue', 'searchpro'); ?></h3>
111 + <div class="berq-box-content">
112 + <p><?php esc_html_e("Pages pending in cloud", 'searchpro'); ?></p>
113 + <div class="berq-stats-count">
189 114 <?php
190 - if (!empty($optimized_pages)) {
191 - foreach ($optimized_pages as $page) {
192 - $row_html = "<tr>";
193 - $row_html .= "<td>";
194 - $row_html .= $page['url'];
195 - $row_html .= "</td>";
196 - $row_html .= "<td>";
197 - $row_html .= $page['status'];
198 - $row_html .= "</td>";
199 - $row_html .= "<td>";
200 - $row_html .= date('Y-m-d H:i:s', $page['last_modified']);
201 - $row_html .= "</td>";
202 - $row_html .= "</tr>";
203 - echo $row_html;
204 - }
115 + if ($berqwp_can_use_cloud) {
116 + $berqwp = new BerqWP(get_option('berqwp_license_key'), null, optifer_cache);
117 + $queue_count = $berqwp->queue_count($configs['site_id']);
118 + echo $queue_count;
119 + } else {
120 + echo "0";
205 121 }
206 122 ?>
207 -
208 - </tbody>
209 - </table>
123 + </div>
210 124 </div>
211 125 </div>
212 - </div>
213 - <div class="berq-dual-box">
214 - <div class="berq-info-box">
126 + <?php } ?>
127 + <div class="berq-info-box" style="position: relative;">
128 + <a class="berq-stat-refresh" href="#" style="display:none;"><svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#29ac20"><path d="M229.08-205.08v-52H310l-13.08-13.84q-42.3-39.62-68.61-92.62-26.31-53-26.31-115.69 0-93.69 55.23-165.96 55.23-72.27 140.77-98.96v54.23q-63.39 25.3-103.69 81.73Q254-551.77 254-479.23q0 49.92 20.27 92.65 20.27 42.73 54.81 73.27l15.38 15.39v-74.54h52v167.38H229.08ZM562-215.85v-54.23q63.39-25.3 103.69-81.73Q706-408.23 706-480.77q0-49.92-20.27-92.65-20.27-42.73-54.81-73.27l-15.38-15.39v74.54h-52v-167.38h167.38v52H650l13.08 13.84q43.46 38.47 69.19 92.04Q758-543.46 758-480.77q0 93.69-55.23 165.96-55.23 72.27-140.77 98.96Z"></path></svg></a>
129 + <h3 class="berq-box-title"><?php esc_html_e('Cached Pages', 'searchpro'); ?></h3>
130 + <div class="berq-box-content">
131 + <p><?php esc_html_e("Optimized pages", 'searchpro'); ?></p>
132 + <div class="berq-stats-count"><?php echo $optimized_pages; ?></div>
133 + </div>
134 + </div>
135 + <?php if ($berqwp_can_use_cloud) { ?>
136 + <div class="berq-info-box" style="position:relative;">
137 + <a title="Refresh license key" href="<?php echo esc_attr(wp_nonce_url(admin_url('admin-post.php?action=bwp_refresh_license'), 'bwp_refresh_license_action')); ?>" class="berq-stat-refresh">
138 + <svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#29ac20"><path d="M229.08-205.08v-52H310l-13.08-13.84q-42.3-39.62-68.61-92.62-26.31-53-26.31-115.69 0-93.69 55.23-165.96 55.23-72.27 140.77-98.96v54.23q-63.39 25.3-103.69 81.73Q254-551.77 254-479.23q0 49.92 20.27 92.65 20.27 42.73 54.81 73.27l15.38 15.39v-74.54h52v167.38H229.08ZM562-215.85v-54.23q63.39-25.3 103.69-81.73Q706-408.23 706-480.77q0-49.92-20.27-92.65-20.27-42.73-54.81-73.27l-15.38-15.39v74.54h-52v-167.38h167.38v52H650l13.08 13.84q43.46 38.47 69.19 92.04Q758-543.46 758-480.77q0 93.69-55.23 165.96-55.23 72.27-140.77 98.96Z"/></svg>
139 + </a>
215 140 <h3 class="berq-box-title"><?php esc_html_e('My Account', 'searchpro'); ?></h3>
216 141 <div class="berq-box-content">
217 142
218 - <?php if ($this->key_response->product_ref !== 'AppSumo Deal') { ?>
143 + <?php if (!empty($this->key_response->product_ref) && $this->key_response->product_ref !== 'AppSumo Deal') { ?>
219 144 <p>
220 145 <?php esc_html_e('License:', 'searchpro'); ?>
221 146 <?php echo esc_html( $this->key_response->product_ref ); ?>
222 147 </p>
@@ -221,48 +146,76 @@
221 146 <?php echo esc_html( $this->key_response->product_ref ); ?>
222 147 </p>
223 148 <?php } ?>
224 149
225 - <p><?php esc_html_e('License status:', 'searchpro'); ?>
150 + <p><?php esc_html_e('Status:', 'searchpro'); ?>
226 151 <?php echo esc_html( $this->key_response->status ); ?>
227 152 </p>
228 153
229 - <?php if ($this->key_response->product_ref !== 'AppSumo Deal' && $this->key_response->product_ref !== 'Free Account') { ?>
230 - <p><?php esc_html_e('Expiration date:', 'searchpro'); ?>
154 + <?php if (!empty($this->key_response->product_ref) && !empty($this->key_response->date_expiry) && $this->key_response->product_ref !== 'AppSumo Deal' && $this->key_response->product_ref !== 'Free Account') { ?>
155 + <p><?php esc_html_e('Renewal:', 'searchpro'); ?>
231 156 <?php echo esc_html( $this->key_response->date_expiry ); ?>
232 157 </p>
233 158 <?php } ?>
234 -
159 +
235 160 </div>
236 161 </div>
237 - <div class="berq-info-box">
238 - <h3 class="berq-box-title"><?php esc_html_e('Quick Actions', 'searchpro'); ?></h3>
239 - <div class="berq-box-content">
240 - <a href="<?php echo esc_attr(wp_nonce_url(admin_url('admin-post.php?action=clear_cache'), 'clear_cache_action')); ?>" class="berq-btn"><?php esc_html_e('Flush cache', 'searchpro'); ?></a>
241 - <a href=https://berqwp.com/help-center/" target="_blank" class="berq-btn"><?php esc_html_e('Visit help center', 'searchpro'); ?></a>
162 + <?php } ?>
163 + </div>
164 +
165 + <div class="berq-info-box">
166 + <h3 class="berq-box-title"><?php esc_html_e('Recently Optimized Pages (Max. 200)', 'searchpro'); ?></h3>
167 + <div class="berq-box-content">
168 + <div class="berq-recently-optimized-toolbar">
169 + <input type="text" id="berq-recent-search" placeholder="<?php esc_attr_e('Search URL…', 'searchpro'); ?>" class="berq-recent-search-input" />
242 170 </div>
171 + <table class="berq-image-settings berq-recent-table">
172 + <colgroup><col style="width:75%"><col style="width:25%"></colgroup>
173 + <thead>
174 + <tr>
175 + <th><?php esc_html_e('Page URL', 'searchpro'); ?></th>
176 + <th><?php esc_html_e('Cached At', 'searchpro'); ?></th>
177 + </tr>
178 + </thead>
179 + <tbody id="berq-recent-tbody">
180 + <tr><td colspan="2"><?php esc_html_e('Loading…', 'searchpro'); ?></td></tr>
181 + </tbody>
182 + </table>
183 + <div class="berq-recent-pagination">
184 + <button type="button" class="berq-btn" id="berq-recent-prev" disabled><?php esc_html_e('← Prev', 'searchpro'); ?></button>
185 + <span id="berq-recent-page-info"></span>
186 + <button type="button" class="berq-btn" id="berq-recent-next"><?php esc_html_e('Next →', 'searchpro'); ?></button>
187 + </div>
243 188 </div>
189 + </div>
244 190
245 - </div>
246 191 <div class="berq-info-box">
247 192 <h3 class="berq-box-title"><?php esc_html_e('Sandbox', 'searchpro'); ?></h3>
248 - <div class="berq-box-content">
249 - <p><?php esc_html_e("The Sandbox feature allows you to test BerqWP's optimizations without impacting real visitors. Note that pages will load slower when sandbox mode is enabled.", 'searchpro'); ?> <a href="https://berqwp.com/help-center/sandbox-mode-and-how-to-use-it/" target="_blank"><?php esc_html_e("Learn more", 'searchpro'); ?></a> </p>
250 - <label class="berq-check">
251 - <input type="checkbox" name="berqwp_enable_sandbox" <?php checked(1, get_option('berqwp_enable_sandbox'), true); ?>>
252 - <?php esc_html_e('Enable sandbox', 'searchpro'); ?>
253 - </label>
193 + <div class="berq-box-content berq-setting-toggle">
194 + <div class="berq-option-content">
195 + <p><?php printf( /* translators: %s: Plugin name */ esc_html__("The Sandbox feature allows you to test %s's optimizations without impacting real visitors. Note that pages will load slower when sandbox mode is enabled.", 'searchpro'), esc_html($plugin_name) ); ?>
196 +
197 + <?php if (bwp_show_docs()) { ?>
198 + <a href="https://berqwp.com/help-center/sandbox-mode-and-how-to-use-it/" target="_blank"><?php esc_html_e("Learn more", 'searchpro'); ?></a>
199 + <?php } ?>
200 +
201 + </p>
202 +
203 + </div>
204 +
205 + <?php berqwp_render_toggle('berqwp_enable_sandbox', get_option('berqwp_enable_sandbox')); ?>
206 +
254 207 </div>
255 208 </div>
256 209
257 210 <div class="berq-info-box">
258 - <h3 class="berq-box-title"><?php esc_html_e('BerqWP CDN', 'searchpro'); ?></h3>
259 - <div class="berq-box-content">
260 - <p><?php esc_html_e("BerqWP CDN delivers static files instantly to enhance website performance and user experience.", 'searchpro'); ?></p>
261 - <label class="berq-check">
262 - <input type="checkbox" name="berqwp_enable_cdn" <?php checked(1, get_option('berqwp_enable_cdn'), true); ?>>
263 - <?php esc_html_e('Enable BerqWP CDN', 'searchpro'); ?>
264 - </label>
211 + <h3 class="berq-box-title <?php echo !$berqwp_can_use_cloud ? 'cloud-exclusive' : ''; ?>"><?php esc_html_e("Monitor Core Web Vitals", 'searchpro'); ?></h3>
212 + <div class="berq-box-content berq-setting-toggle">
213 + <div class="berq-option-content">
214 + <p><?php esc_html_e("Anonymously track and monitor Core Web Vitals metrics in real time using our Web Vitals Analytics. It may cause a little drop in PageSpeed score.", 'searchpro'); ?></p>
215 +
216 + </div>
217 + <?php berqwp_render_toggle('berqwp_enable_cwv', get_option('berqwp_enable_cwv')); ?>
265 218 </div>
266 219 </div>
267 220
268 221 <button type="submit" class="berqwp-save"><svg width="20" height="20" viewBox="0 0 20 20" fill="none"
@@ -270,5 +223,100 @@
270 223 <path d="M4.16663 10.8333L7.49996 14.1667L15.8333 5.83334" stroke="white" stroke-width="2"
271 224 stroke-linecap="round" stroke-linejoin="round" />
272 225 </svg>
273 226 <?php esc_html_e('Save changes', 'searchpro'); ?></button>
274 -</div>
227 +</div>
228 +
229 +<style>
230 +.berq-recently-optimized-toolbar { margin-bottom: 14px; }
231 +.berq-recent-search-input {
232 + width: 100%; max-width: 360px;
233 + padding: 5px 12px !important;
234 + border: 1px solid #e2eaf5 !important;
235 + border-radius: 6px !important;
236 + font-size: 13px !important;
237 + color: #353535 !important;
238 + outline: none !important;
239 + background: #fff;
240 + transition: border-color 0.2s, box-shadow 0.2s;
241 + box-shadow: 0 1px 3px rgba(83,113,167,0.06);
242 +}
243 +.berq-recent-search-input:focus { border-color: #1f71ff; box-shadow: 0 0 0 3px rgba(31,113,255,0.1); }
244 +.berq-recent-search-input.berq-recent-searching {
245 + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='10' fill='none' stroke='%23c5d3ea' stroke-width='3'/%3E%3Cpath d='M12 2a10 10 0 0 1 10 10' fill='none' stroke='%231f71ff' stroke-width='3' stroke-linecap='round'%3E%3CanimateTransform attributeName='transform' type='rotate' from='0 12 12' to='360 12 12' dur='0.7s' repeatCount='indefinite'/%3E%3C/path%3E%3C/svg%3E");
246 + background-repeat: no-repeat;
247 + background-position: right 10px center;
248 + padding-right: 30px;
249 +}
250 +.berq-recent-table { border-collapse: collapse; width: 100%; table-layout: fixed; }
251 +.berq-recent-table th, .berq-recent-table td { padding: 8px 10px; font-size: 13px; color: #465774; border-bottom: 1px solid #e8eef8; word-break: break-all; }
252 +.berq-recent-table th { font-weight: 600; color: #0d2958; background: #f7faff; }
253 +.berq-recent-table td a { color: #1f71ff; text-decoration: none; }
254 +.berq-recent-table td a:hover { text-decoration: underline; }
255 +.berq-recent-pagination { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
256 +#berq-recent-page-info { font-size: 13px; color: #465774; flex: 1; text-align: center; }
257 +button.berq-btn {
258 + background: #fff; border-radius: 6px; padding: 8px 16px;
259 + color: #384a69; font-size: 13px; font-weight: 500;
260 + border: 1px solid #dbe9fe; box-shadow: 0 0 7px -6px #000;
261 + cursor: pointer; transition: background 0.15s, border-color 0.15s, color 0.15s;
262 + line-height: normal;
263 +}
264 +button.berq-btn:hover:not(:disabled) { background: #3d44d9; border-color: #3d44d9; color: #fff; }
265 +button.berq-btn:disabled { opacity: 0.4; cursor: not-allowed; }
266 +</style>
267 +
268 +<script>
269 +(function($) {
270 + var recentPage = 0, recentLength = 10, recentSearch = '', recentTotal = 0;
271 +
272 + function loadRecentPages() {
273 + var $input = $('#berq-recent-search');
274 + $input.addClass('berq-recent-searching');
275 + $('#berq-recent-tbody').css('opacity', '0.45');
276 +
277 + let berq_nounce = '<?php echo esc_html(wp_create_nonce('wp_rest')); ?>';
278 + $.post(ajaxurl, {
279 + action: 'berqwp_recently_optimized_pages',
280 + nonce: berq_nounce,
281 + start: recentPage * recentLength,
282 + length: recentLength,
283 + search: recentSearch,
284 + }, function(res) {
285 + $input.removeClass('berq-recent-searching');
286 + $('#berq-recent-tbody').css('opacity', '');
287 + if (!res || !res.success) return;
288 + recentTotal = res.data.total;
289 + var rows = '';
290 + if (!res.data.data || res.data.data.length === 0) {
291 + rows = '<tr><td colspan="2" style="color:#6071a4;"><?php echo esc_js(__('No cached pages logged yet.', 'searchpro')); ?></td></tr>';
292 + } else {
293 + $.each(res.data.data, function(_, e) {
294 + rows += '<tr><td><a href="' + e.url + '" target="_blank" rel="noopener">' + e.url + '</a></td><td>' + e.cached_at + '</td></tr>';
295 + });
296 + }
297 + $('#berq-recent-tbody').html(rows);
298 + var from = recentTotal === 0 ? 0 : recentPage * recentLength + 1;
299 + var to = Math.min((recentPage + 1) * recentLength, recentTotal);
300 + $('#berq-recent-page-info').text(from + '–' + to + ' / ' + recentTotal);
301 + $('#berq-recent-prev').prop('disabled', recentPage === 0);
302 + $('#berq-recent-next').prop('disabled', to >= recentTotal);
303 + });
304 + }
305 +
306 + var searchTimer;
307 + $('#berq-recent-search').on('input', function() {
308 + clearTimeout(searchTimer);
309 + var val = $(this).val();
310 + searchTimer = setTimeout(function() {
311 + recentSearch = val;
312 + recentPage = 0;
313 + loadRecentPages();
314 + }, 350);
315 + });
316 +
317 + $('#berq-recent-prev').on('click', function() { recentPage--; loadRecentPages(); });
318 + $('#berq-recent-next').on('click', function() { recentPage++; loadRecentPages(); });
319 +
320 + loadRecentPages();
321 +})(jQuery);
322 +</script>