| 1 |
<?php |
| 2 |
namespace WPEXtra\Modules\Backend; |
| 3 |
|
| 4 |
if (!defined('ABSPATH')) { |
| 5 |
exit; |
| 6 |
} |
| 7 |
|
| 8 |
use WPEXtra\Helper; |
| 9 |
use WPEXtra\Base; |
| 10 |
|
| 11 |
class Dashboards extends Base |
| 12 |
{ |
| 13 |
|
| 14 |
public function __construct() |
| 15 |
{ |
| 16 |
parent::__construct(); |
| 17 |
add_action('wp_dashboard_setup', [$this, 'add_custom_widgets'], 1000); |
| 18 |
} |
| 19 |
|
| 20 |
protected $features = [ |
| 21 |
'dashboard', |
| 22 |
'dashboard_welcome', |
| 23 |
'tab_help', |
| 24 |
'tab_screen', |
| 25 |
'dashboard_sysinfo', |
| 26 |
]; |
| 27 |
|
| 28 |
public function dashboard_sysinfo() |
| 29 |
{ |
| 30 |
add_action('wp_dashboard_setup', [$this, 'add_sysinfo_widget'], 1000); |
| 31 |
} |
| 32 |
|
| 33 |
public function dashboard() |
| 34 |
{ |
| 35 |
add_action('wp_dashboard_setup', [$this, 'remove_all_dashboard_widgets'], 999); |
| 36 |
add_action('admin_enqueue_scripts', [$this, 'full_dashboard']); |
| 37 |
$this->dashboard_welcome(); |
| 38 |
if (!function_exists('wpforms')) { |
| 39 |
add_filter('wpforms_admin_dashboardwidget', '__return_false'); |
| 40 |
} |
| 41 |
} |
| 42 |
|
| 43 |
public function dashboard_welcome() |
| 44 |
{ |
| 45 |
remove_action('welcome_panel', 'wp_welcome_panel'); |
| 46 |
add_action('load-index.php', [$this, 'hide_welcome_panel']); |
| 47 |
add_filter('get_user_metadata', [$this, 'filter_show_welcome_panel'], 10, 4); |
| 48 |
add_action('admin_head-index.php', [$this, 'hide_welcome_panel_css']); |
| 49 |
} |
| 50 |
|
| 51 |
public function hide_welcome_panel() |
| 52 |
{ |
| 53 |
$user_id = get_current_user_id(); |
| 54 |
if ($user_id && (int) get_user_meta($user_id, 'show_welcome_panel', true) === 1) { |
| 55 |
update_user_meta($user_id, 'show_welcome_panel', 0); |
| 56 |
} |
| 57 |
} |
| 58 |
|
| 59 |
public function filter_show_welcome_panel($null, $object_id, $meta_key, $single) |
| 60 |
{ |
| 61 |
if ($meta_key === 'show_welcome_panel') { |
| 62 |
return $single ? 0 : [0]; |
| 63 |
} |
| 64 |
return $null; |
| 65 |
} |
| 66 |
|
| 67 |
public function hide_welcome_panel_css() |
| 68 |
{ |
| 69 |
echo '<style>#welcome-panel,.welcome-panel,label[for="wp_welcome_panel-hide"],.metabox-prefs label:has(#wp_welcome_panel-hide){display:none!important}</style>'; |
| 70 |
} |
| 71 |
|
| 72 |
public function remove_all_dashboard_widgets() |
| 73 |
{ |
| 74 |
global $wp_meta_boxes; |
| 75 |
$wp_meta_boxes['dashboard'] = [ |
| 76 |
'normal' => ['core' => [], 'high' => [], 'sorted' => [], 'default' => [], 'low' => []], |
| 77 |
'side' => ['core' => [], 'high' => [], 'sorted' => [], 'default' => [], 'low' => []], |
| 78 |
]; |
| 79 |
|
| 80 |
remove_meta_box('wpseo-dashboard-overview', 'dashboard', 'side'); |
| 81 |
if (class_exists('WooCommerce')) { |
| 82 |
remove_meta_box('woocommerce_dashboard_recent_reviews', 'dashboard', 'normal'); |
| 83 |
remove_meta_box('woocommerce_dashboard_status', 'dashboard', 'normal'); |
| 84 |
} |
| 85 |
} |
| 86 |
|
| 87 |
public function full_dashboard($hook) |
| 88 |
{ |
| 89 |
if ($hook === 'index.php') { |
| 90 |
$css = '#dashboard-widgets-wrap{overflow:unset!important}.postbox-container{min-width:100%!important}.meta-box-sortables.ui-sortable.empty-container,.wrap>h1{display:none}'; |
| 91 |
wp_add_inline_style('dashboard', $css); |
| 92 |
} |
| 93 |
} |
| 94 |
|
| 95 |
public function get_custom_widgets_data() |
| 96 |
{ |
| 97 |
$widgets = (array) Helper::get_option('dashboard_custom_widgets', []); |
| 98 |
|
| 99 |
// Backward compatibility for single widget setup |
| 100 |
if (empty($widgets) && (!empty(Helper::get_option('dashboard_content')) || !empty(Helper::get_option('dashboard_title')))) { |
| 101 |
$widgets[] = [ |
| 102 |
'title' => Helper::get_option('dashboard_title', 'WP EXtra Notice'), |
| 103 |
'content' => Helper::get_option('dashboard_content', ''), |
| 104 |
'style' => Helper::get_option('dashboard_widget_style', 'standard'), |
| 105 |
'role' => 'all', |
| 106 |
'cta_text' => Helper::get_option('dashboard_cta_text', ''), |
| 107 |
'cta_url' => Helper::get_option('dashboard_cta_url', ''), |
| 108 |
]; |
| 109 |
} |
| 110 |
|
| 111 |
return array_filter($widgets, fn($w) => !empty($w['title']) || !empty($w['content'])); |
| 112 |
} |
| 113 |
|
| 114 |
public function add_custom_widgets() |
| 115 |
{ |
| 116 |
$widgets = $this->get_custom_widgets_data(); |
| 117 |
if (empty($widgets)) { |
| 118 |
return; |
| 119 |
} |
| 120 |
|
| 121 |
$user = wp_get_current_user(); |
| 122 |
$user_roles = $user ? (array) $user->roles : []; |
| 123 |
|
| 124 |
foreach ($widgets as $index => $widget) { |
| 125 |
$target_role = $widget['role'] ?? 'all'; |
| 126 |
|
| 127 |
// Check permissions |
| 128 |
if ($target_role !== 'all' && !empty($target_role)) { |
| 129 |
if (!in_array($target_role, $user_roles, true) && !in_array('administrator', $user_roles, true)) { |
| 130 |
continue; |
| 131 |
} |
| 132 |
} |
| 133 |
|
| 134 |
$widget_id = 'wpex_custom_notice_' . $index; |
| 135 |
$widget_title = !empty($widget['title']) ? $widget['title'] : __('Notice', 'wp-extra'); |
| 136 |
|
| 137 |
wp_add_dashboard_widget( |
| 138 |
$widget_id, |
| 139 |
esc_html($widget_title), |
| 140 |
function () use ($widget) { |
| 141 |
$this->render_custom_widget_content($widget); |
| 142 |
} |
| 143 |
); |
| 144 |
} |
| 145 |
} |
| 146 |
|
| 147 |
public function render_custom_widget_content($widget) |
| 148 |
{ |
| 149 |
$content = $widget['content'] ?? ''; |
| 150 |
echo '<div class="wpex-custom-widget-body" style="font-size:14px;line-height:1.7;color:#2c3338;">'; |
| 151 |
echo do_shortcode(wpautop(wp_kses_post($content))); |
| 152 |
echo '</div>'; |
| 153 |
} |
| 154 |
|
| 155 |
public function add_sysinfo_widget() |
| 156 |
{ |
| 157 |
if (!current_user_can('manage_options')) { |
| 158 |
return; |
| 159 |
} |
| 160 |
wp_add_dashboard_widget( |
| 161 |
'wpex_sysinfo_widget', |
| 162 |
__('System & Environment Overview', 'wp-extra'), |
| 163 |
[$this, 'render_sysinfo_widget'] |
| 164 |
); |
| 165 |
} |
| 166 |
|
| 167 |
public function render_sysinfo_widget() |
| 168 |
{ |
| 169 |
global $wpdb; |
| 170 |
|
| 171 |
$php_version = phpversion(); |
| 172 |
$wp_version = get_bloginfo('version'); |
| 173 |
$memory_limit = ini_get('memory_limit'); |
| 174 |
$wp_memory = WP_MEMORY_LIMIT; |
| 175 |
$max_upload = size_format(wp_max_upload_size()); |
| 176 |
$server_soft = sanitize_text_field($_SERVER['SERVER_SOFTWARE'] ?? 'Unknown'); |
| 177 |
$mysql_version = $wpdb->db_version(); |
| 178 |
$active_plugins = count((array) get_option('active_plugins', [])); |
| 179 |
|
| 180 |
echo '<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px">'; |
| 181 |
|
| 182 |
$stats = [ |
| 183 |
['label' => __('WordPress', 'wp-extra'), 'value' => ltrim($wp_version, 'vV'), 'icon' => 'dashicons-wordpress'], |
| 184 |
['label' => __('PHP Version', 'wp-extra'), 'value' => ltrim($php_version, 'vV'), 'icon' => 'dashicons-editor-code'], |
| 185 |
['label' => __('MySQL / MariaDB', 'wp-extra'), 'value' => ltrim($mysql_version, 'vV'), 'icon' => 'dashicons-database'], |
| 186 |
['label' => __('WP Memory Limit', 'wp-extra'), 'value' => $wp_memory, 'icon' => 'dashicons-performance'], |
| 187 |
['label' => __('PHP Memory Limit', 'wp-extra'), 'value' => $memory_limit, 'icon' => 'dashicons-chart-pie'], |
| 188 |
['label' => __('Max Upload Size', 'wp-extra'), 'value' => $max_upload, 'icon' => 'dashicons-upload'], |
| 189 |
['label' => __('Active Plugins', 'wp-extra'), 'value' => $active_plugins . ' ' . __('Plugins', 'wp-extra'), 'icon' => 'dashicons-admin-plugins'], |
| 190 |
['label' => __('Web Server', 'wp-extra'), 'value' => explode('/', $server_soft)[0] ?? 'Server', 'icon' => 'dashicons-networking'], |
| 191 |
]; |
| 192 |
|
| 193 |
foreach ($stats as $stat) { |
| 194 |
echo '<div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;padding:10px 8px;text-align:center;">'; |
| 195 |
echo '<span class="dashicons ' . esc_attr($stat['icon']) . '" style="color:#2271b1;font-size:20px;width:20px;height:20px;margin-bottom:4px;display:inline-block;"></span>'; |
| 196 |
echo '<div style="font-size:11px;color:#64748b;font-weight:500;">' . esc_html($stat['label']) . '</div>'; |
| 197 |
echo '<div style="font-size:13px;font-weight:600;color:#1e293b;margin-top:2px;">' . esc_html($stat['value']) . '</div>'; |
| 198 |
echo '</div>'; |
| 199 |
} |
| 200 |
|
| 201 |
echo '</div>'; |
| 202 |
} |
| 203 |
|
| 204 |
public function tab_help() |
| 205 |
{ |
| 206 |
add_filter('admin_head', [$this, 'remove_help_tabs']); |
| 207 |
} |
| 208 |
|
| 209 |
public function remove_help_tabs() |
| 210 |
{ |
| 211 |
$screen = get_current_screen(); |
| 212 |
if ($screen) { |
| 213 |
$screen->remove_help_tabs(); |
| 214 |
} |
| 215 |
} |
| 216 |
|
| 217 |
public function tab_screen() |
| 218 |
{ |
| 219 |
add_filter('screen_options_show_screen', '__return_false'); |
| 220 |
} |
| 221 |
} |
| 222 |
|