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 | inc/class-berqwp.php +242 -6 4.0.26trunk View file →
@@ -132,8 +132,25 @@
132 132
133 133 // Sync addons from cloud
134 134 add_action('init', [$this, 'sync_addons']);
135 135
136 + // Debloat: WordPress feature toggles
137 + if (get_option('berqwp_disable_emojis')) {
138 + add_action('init', [$this, 'disable_emoji']);
139 + }
140 + add_action('init', [$this, 'apply_heartbeat_settings'], 1);
141 + add_action('init', [$this, 'apply_debloat_settings'], 1);
142 +
143 + // Database: manual cleanup AJAX actions
144 + add_action('wp_ajax_berqwp_db_run_action', [$this, 'ajax_db_run_action']);
145 +
146 + // Database: scheduled optimization via WP-Cron
147 + add_filter('cron_schedules', [$this, 'add_monthly_cron_schedule']);
148 + add_action('berqwp_db_scheduled_optimize', [$this, 'run_scheduled_db_optimize']);
149 + add_action('berqwp_reschedule_db_cron', [$this, 'reschedule_db_cron']);
150 + add_action('berqwp_activate_plugin', [$this, 'reschedule_db_cron']);
151 + add_action('berqwp_deactivate_plugin', [$this, 'clear_db_cron']);
152 +
136 153 // Multisite support
137 154 if (function_exists('is_multisite') && is_multisite()) {
138 155 add_action('network_admin_menu', [$this, 'register_network_menu']);
139 156 add_action('network_admin_edit_berqwp_network_save', [$this, 'save_network_settings']);
@@ -153,8 +170,24 @@
153 170
154 171 return self::$instance;
155 172 }
156 173
174 + function upgrade_notice() {
175 +
176 + if (!berqwp_can_use_cloud()) {
177 + return;
178 + }
179 +
180 + if (empty($this->key_response->product_ref)) {
181 + return;
182 + }
183 +
184 + if ($this->key_response->product_ref == 'Free Account' && bwp_cached_pages_count() >= 10) {
185 +
186 + bwp_notice('warning', 'Free Plan Limit Reached', "<p>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!</p>");
187 + }
188 + }
189 +
157 190 function switch_optimization_method() {
158 191 // Check if the user has the necessary nonce and the action matches
159 192 if (isset($_GET['action']) && $_GET['action'] === 'switch_optimization_method_local' && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'] ?? '')), 'switch_optimization_method_local_action')) {
160 193
@@ -161,8 +194,11 @@
161 194
162 195 $berqconfigs = berqConfigs::getInstance();
163 196 $berqconfigs->update_configs(['optimization_method' => 'local']);
164 197
198 + // Require flush cache
199 + update_option('bwp_require_flush_cache', 1);
200 +
165 201 $redirect_url = wp_get_referer();
166 202
167 203 // Redirect back to the referring page after clearing the cache
168 204 wp_safe_redirect($redirect_url);
@@ -179,8 +215,10 @@
179 215 } else {
180 216 $berqconfigs->update_configs(['optimization_method' => 'cloud']);
181 217 }
182 218
219 + // Require flush cache
220 + update_option('bwp_require_flush_cache', 1);
183 221
184 222 $redirect_url = wp_get_referer();
185 223
186 224 // Redirect back to the referring page after clearing the cache
@@ -924,8 +962,36 @@
924 962 }
925 963
926 964 function save_settings()
927 965 {
966 +
967 + if (current_user_can('manage_options') && !empty($_GET['page']) && $_GET['page'] == 'berqwp' && isset($_GET['activate-free'])) {
968 + $berqconfigs = berqConfigs::getInstance();
969 + $configs = $berqconfigs->get_configs();
970 + $site_id = $configs['site_id'];
971 +
972 + if (empty($site_id)) {
973 + $site_id = berqwp_generate_site_id();
974 + }
975 +
976 + $berqconfigs->update_configs([
977 + 'site_id' => $site_id,
978 + 'optimization_method' => 'local'
979 + ]);
980 +
981 + wp_remote_post(BerqWPCloud::$endpoint."free-user", [
982 + 'timeout' => 30,
983 + 'body' => [
984 + 'site_id' => $site_id,
985 + 'site_url' => get_option('home'),
986 + ]
987 + ]);
988 +
989 + $location = get_admin_url() . 'admin.php?page=berqwp';
990 + wp_safe_redirect($location);
991 + exit;
992 + }
993 +
928 994 require_once optifer_PATH . '/admin/save-settings.php';
929 995 }
930 996
931 997 function notices()
@@ -932,8 +998,10 @@
932 998 {
933 999
934 1000 $plugin_name = defined('BERQWP_PLUGIN_NAME') ? BERQWP_PLUGIN_NAME : 'BerqWP';
935 1001
1002 + $this->upgrade_notice();
1003 +
936 1004 if (isset($_GET['berqwp_page_compression_enabled'])) {
937 1005 bwp_notice('success', 'Page Compression Enabled', "<p>Page compression has been successfully enabled on your website.</p>");
938 1006 }
939 1007
@@ -987,9 +1055,13 @@
987 1055 // if (file_exists($adv_cache_path) && !is_writable($adv_cache_path)) {
988 1056 // bwp_notice('warning', 'advanced-cache.php is not writable', "<p>$plugin_name can't write to wp-content/advanced-cache.php — please check file permissions or re-save settings to regenerate it.</p>", []);
989 1057 // }
990 1058
991 - if (!get_transient('bwp_hide_feedback_notice') && !get_option('bwp_quit_feedback') && bwp_show_account()) {
1059 + $berqconfigs = berqConfigs::getInstance();
1060 + $configs = $berqconfigs->get_configs();
1061 + $readyForCache = !empty($configs['optimization_method']);
1062 +
1063 + if ($readyForCache && bwp_is_home_cached() && !get_transient('bwp_hide_feedback_notice') && !get_option('bwp_quit_feedback') && bwp_show_account()) {
992 1064 bwp_notice('info bwp_feedback', 'Loving BerqWP\'s performance?', '<p>Show some love and help us grow 👉 - <a href="https://wordpress.org/support/plugin/searchpro/reviews/#new-post" target="_blank">Rate BerqWP Plugin</a>. Your insights shape our journey.</p>', [
993 1065 [
994 1066 'href' => 'https://wordpress.org/support/plugin/searchpro/reviews/#new-post',
995 1067 'text' => '❤️ You deserve it',
@@ -997,9 +1069,9 @@
997 1069 'target' => '_blank',
998 1070 ],
999 1071 [
1000 1072 'href' => get_admin_url() . 'admin.php?page=berqwp&bwp_quit_feedback',
1001 - 'text' => '👍 Already did',
1073 + 'text' => '👍 Already done',
1002 1074 'classes' => '',
1003 1075 'target' => '',
1004 1076 ],
1005 1077 [
@@ -1057,16 +1129,26 @@
1057 1129 delete_transient('berq_force_cache_notice');
1058 1130 bwp_notice('success', '', "<p>The cache for page ($forced_page) has been queued with high priority and will be generated soon.</p>", []);
1059 1131 }
1060 1132
1061 - if (get_option('bwp_require_flush_cache', false)) {
1062 - bwp_notice('warning', 'Cache Flush Required', '<p>To apply the changes, please flush the cache.</p>', [
1133 + if ($readyForCache && get_option('bwp_require_flush_cache', false)) {
1134 + $cache_rebuild_btns = [
1063 1135 [
1064 1136 'href' => esc_attr(wp_nonce_url(admin_url('admin-post.php?action=clear_cache'), 'clear_cache_action')),
1065 1137 'text' => 'Flush cache',
1066 1138 'classes' => '',
1067 1139 ]
1068 - ]);
1140 + ];
1141 +
1142 + if (berqwp_can_use_cloud()) {
1143 + $cache_rebuild_btns[] = [
1144 + 'href' => esc_attr(wp_nonce_url(admin_url('admin-post.php?action=warmup_cache'), 'warmup_cache_action')),
1145 + 'text' => 'Warmup cache',
1146 + 'classes' => '',
1147 + ];
1148 + }
1149 +
1150 + bwp_notice('warning', 'Cache Flush Required', '<p>To apply the changes, please flush the cache.</p>', $cache_rebuild_btns);
1069 1151 }
1070 1152
1071 1153 if (berq_is_localhost() && berqwp_can_use_cloud()) {
1072 1154 bwp_notice('warning', 'Localhost environment detected:', "<p>$plugin_name requires a live, publicly accessible website to function.</p>", []);
@@ -1180,9 +1262,9 @@
1180 1262 'body' => $body
1181 1263 ]);
1182 1264
1183 1265 if (is_wp_error($lic_response)) {
1184 - $berq_log->info("Couldn't reach BerqWP server.");
1266 + $berq_log->info("Couldn't reach BerqWP server.".print_r($lic_response, true));
1185 1267 return;
1186 1268 }
1187 1269
1188 1270 $lic_body = wp_remote_retrieve_body($lic_response);
@@ -1454,8 +1536,162 @@
1454 1536 return array_diff($plugins, array('wpemoji'));
1455 1537 } else {
1456 1538 return array();
1457 1539 }
1540 + }
1541 +
1542 + // Apply the selected Heartbeat API mode (default / restrict / throttle / disable)
1543 + function apply_heartbeat_settings()
1544 + {
1545 + $mode = get_option('berqwp_heartbeat_mode', 'default');
1546 +
1547 + if ($mode === 'default') {
1548 + return;
1549 + }
1550 +
1551 + if ($mode === 'disable') {
1552 + wp_deregister_script('heartbeat');
1553 + return;
1554 + }
1555 +
1556 + if ($mode === 'restrict') {
1557 + global $pagenow;
1558 + if (!in_array($pagenow, ['post.php', 'post-new.php'], true)) {
1559 + wp_deregister_script('heartbeat');
1560 + }
1561 + return;
1562 + }
1563 +
1564 + if ($mode === 'throttle') {
1565 + add_filter('heartbeat_settings', [$this, 'throttle_heartbeat_interval']);
1566 + }
1567 + }
1568 +
1569 + // Filter callback: clamp Heartbeat interval to the configured value
1570 + function throttle_heartbeat_interval($settings)
1571 + {
1572 + $settings['interval'] = max(15, min(300, (int) get_option('berqwp_heartbeat_interval', 60)));
1573 + return $settings;
1574 + }
1575 +
1576 + // Apply the remaining Debloat toggles (embeds, XML-RPC, REST head links, head meta, self pingbacks)
1577 + function apply_debloat_settings()
1578 + {
1579 + if (get_option('berqwp_disable_embeds')) {
1580 + add_action('wp_footer', [$this, 'deregister_embed_script']);
1581 + remove_action('wp_head', 'wp_oembed_add_discovery_links');
1582 + remove_action('wp_head', 'wp_oembed_add_host_js');
1583 + add_filter('embed_oembed_discover', '__return_false');
1584 + }
1585 +
1586 + if (get_option('berqwp_disable_xmlrpc')) {
1587 + add_filter('xmlrpc_enabled', '__return_false');
1588 + }
1589 +
1590 + if (get_option('berqwp_remove_rest_head_links')) {
1591 + remove_action('wp_head', 'rest_output_link_wp_head');
1592 + remove_action('template_redirect', 'rest_output_link_header', 11);
1593 + }
1594 +
1595 + if (get_option('berqwp_remove_head_meta')) {
1596 + remove_action('wp_head', 'rsd_link');
1597 + remove_action('wp_head', 'wlwmanifest_link');
1598 + remove_action('wp_head', 'wp_shortlink_wp_head');
1599 + remove_action('wp_head', 'wp_generator');
1600 + }
1601 +
1602 + if (get_option('berqwp_disable_self_pingbacks')) {
1603 + add_action('pre_ping', [$this, 'remove_self_pingbacks']);
1604 + }
1605 + }
1606 +
1607 + // Callback: deregister the embed.min.js frontend script
1608 + function deregister_embed_script()
1609 + {
1610 + wp_deregister_script('wp-embed');
1611 + }
1612 +
1613 + // Callback: strip links pointing back to this site from the pingback target list
1614 + function remove_self_pingbacks(&$links)
1615 + {
1616 + $home = get_option('home');
1617 + foreach ($links as $key => $link) {
1618 + if (strpos($link, (string) $home) === 0) {
1619 + unset($links[$key]);
1620 + }
1621 + }
1622 + }
1623 +
1624 + // AJAX: run a single Database tab cleanup action on demand
1625 + function ajax_db_run_action()
1626 + {
1627 + check_ajax_referer('wp_rest', 'nonce');
1628 +
1629 + if (!current_user_can('manage_options')) {
1630 + wp_send_json_error(['message' => __('Permission denied.', 'searchpro')]);
1631 + }
1632 +
1633 + $task = isset($_POST['task']) ? sanitize_text_field($_POST['task']) : '';
1634 + $limit = isset($_POST['limit']) ? max(0, (int) $_POST['limit']) : (int) get_option('berqwp_db_revision_limit', 5);
1635 +
1636 + $result = berqDatabase::run_task($task, ['limit' => $limit]);
1637 +
1638 + if ($result === false) {
1639 + wp_send_json_error(['message' => __('Unknown cleanup task.', 'searchpro')]);
1640 + }
1641 +
1642 + wp_send_json_success($result);
1643 + }
1644 +
1645 + // Register a "once monthly" WP-Cron interval (core only ships hourly/twicedaily/daily)
1646 + function add_monthly_cron_schedule($schedules)
1647 + {
1648 + $schedules['berqwp_monthly'] = [
1649 + 'interval' => 30 * DAY_IN_SECONDS,
1650 + 'display' => __('Once Monthly', 'searchpro'),
1651 + ];
1652 + return $schedules;
1653 + }
1654 +
1655 + // (Re)schedule the Database tab's recurring optimization cron event based on current settings
1656 + function reschedule_db_cron()
1657 + {
1658 + wp_clear_scheduled_hook('berqwp_db_scheduled_optimize');
1659 +
1660 + if (!get_option('berqwp_db_schedule_enabled')) {
1661 + return;
1662 + }
1663 +
1664 + $frequency = get_option('berqwp_db_schedule_frequency', 'weekly');
1665 + $recurrence = 'weekly';
1666 + if ($frequency === 'daily') {
1667 + $recurrence = 'daily';
1668 + } elseif ($frequency === 'monthly') {
1669 + $recurrence = 'berqwp_monthly';
1670 + }
1671 +
1672 + if (!wp_next_scheduled('berqwp_db_scheduled_optimize')) {
1673 + wp_schedule_event(time(), $recurrence, 'berqwp_db_scheduled_optimize');
1674 + }
1675 + }
1676 +
1677 + // Clear the Database tab's cron event (called on plugin deactivation)
1678 + function clear_db_cron()
1679 + {
1680 + wp_clear_scheduled_hook('berqwp_db_scheduled_optimize');
1681 + }
1682 +
1683 + // WP-Cron callback: run every scheduled task and record the run timestamp
1684 + function run_scheduled_db_optimize()
1685 + {
1686 + $tasks = get_option('berqwp_db_scheduled_tasks', []);
1687 + $limit = (int) get_option('berqwp_db_revision_limit', 5);
1688 +
1689 + foreach ((array) $tasks as $task) {
1690 + berqDatabase::run_task($task, ['limit' => $limit]);
1691 + }
1692 +
1693 + update_option('berqwp_db_optimize_last_run', time());
1458 1694 }
1459 1695
1460 1696 // function clear_cache(WP_REST_Request $request)
1461 1697 // {