init_update_checker(); $this->init_components(); } private function init_components() { $this->ajax_handler = new WP_MSD_Ajax_Handler(); $this->admin_interface = new WP_MSD_Admin_Interface(); $this->settings_manager = new WP_MSD_Settings_Manager(); } private function init_update_checker() { if ( file_exists( plugin_dir_path(__FILE__) . "../lib/plugin-update-checker/plugin-update-checker.php" ) ) { require_once plugin_dir_path(__FILE__) . "../lib/plugin-update-checker/plugin-update-checker.php"; if ( class_exists('YahnisElsts\PluginUpdateChecker\v5p3\PucFactory') ) { $this->update_checker = \YahnisElsts\PluginUpdateChecker\v5p3\PucFactory::buildUpdateChecker( "https://updates.weixiaoduo.com/wp-multisite-dashboard.json", WP_MSD_PLUGIN_DIR . "wp-multisite-dashboard.php", "wp-multisite-dashboard" ); } } } public function init() { $this->enabled_widgets = get_site_option("msd_enabled_widgets", [ "msd_network_overview" => 1, "msd_quick_site_management" => 1, "msd_storage_performance" => 1, "msd_server_info" => 1, "msd_quick_links" => 1, "msd_version_info" => 1, "msd_custom_news" => 1, "msd_network_settings" => 1, "msd_user_management" => 1, "msd_contact_info" => 1, "msd_last_edits" => 1, "msd_todo_widget" => 1, ]); $this->enhance_network_dashboard(); } public function admin_init() { if (!current_user_can("manage_network")) { return; } add_action("wp_network_dashboard_setup", [ $this->admin_interface, "add_network_widgets", ]); add_action( "wp_network_dashboard_setup", [$this, "manage_system_widgets"], 20 ); add_action( "wp_network_dashboard_setup", [$this, "cache_detected_widgets"], 30 ); add_action("admin_enqueue_scripts", [$this, "enqueue_admin_scripts"]); } public function add_admin_menu() { add_submenu_page( "settings.php", __("Dashboard Settings", "wp-multisite-dashboard"), __("Dashboard Settings", "wp-multisite-dashboard"), "manage_network", "msd-settings", [$this->settings_manager, "render_settings_page"] ); } public function enqueue_admin_scripts($hook) { $allowed_hooks = [ "index.php", "dashboard.php", "settings_page_msd-settings", ]; if (!in_array($hook, $allowed_hooks)) { return; } wp_enqueue_script( "msd-dashboard-core", WP_MSD_PLUGIN_URL . "assets/dashboard-core.js", ["jquery"], WP_MSD_VERSION, true ); if ($hook === "settings_page_msd-settings") { wp_enqueue_script( "msd-settings", WP_MSD_PLUGIN_URL . "assets/dashboard-settings.js", ["msd-dashboard-core"], WP_MSD_VERSION, true ); } else { wp_enqueue_script( "msd-dashboard-widgets", WP_MSD_PLUGIN_URL . "assets/dashboard-widgets.js", ["msd-dashboard-core"], WP_MSD_VERSION, true ); wp_enqueue_script( "msd-dashboard-modals", WP_MSD_PLUGIN_URL . "assets/dashboard-modals.js", ["msd-dashboard-core", "jquery-ui-sortable"], WP_MSD_VERSION, true ); } wp_enqueue_style( "msd-dashboard", WP_MSD_PLUGIN_URL . "assets/dashboard.css", [], WP_MSD_VERSION ); wp_localize_script("msd-dashboard-core", "msdAjax", [ "ajaxurl" => admin_url("admin-ajax.php"), "nonce" => wp_create_nonce("msd_ajax_nonce"), "strings" => [ "confirm_action" => __( "Are you sure?", "wp-multisite-dashboard" ), "loading" => __("Loading...", "wp-multisite-dashboard"), "error_occurred" => __( "An error occurred", "wp-multisite-dashboard" ), "refresh_success" => __( "Data refreshed successfully", "wp-multisite-dashboard" ), "confirm_delete" => __( "Are you sure you want to delete this item?", "wp-multisite-dashboard" ), "save_success" => __( "Saved successfully", "wp-multisite-dashboard" ), "clear_cache_confirm" => __( "Are you sure you want to clear the cache?", "wp-multisite-dashboard" ), "cache_cleared" => __( "Cache cleared successfully!", "wp-multisite-dashboard" ), "cache_clear_failed" => __( "Failed to clear cache", "wp-multisite-dashboard" ), "check_updates" => __( "Check for Updates", "wp-multisite-dashboard" ), "checking_updates" => __( "Checking...", "wp-multisite-dashboard" ), "update_available" => __( "Version {version} available!", "wp-multisite-dashboard" ), "up_to_date" => __("Up to date", "wp-multisite-dashboard"), "update_check_failed" => __( "Failed to check for updates", "wp-multisite-dashboard" ), "clear_widget_cache_confirm" => __( "Are you sure you want to clear the widget cache? This will refresh the list of detected widgets.", "wp-multisite-dashboard" ), "widget_cache_cleared" => __( "Widget cache cleared successfully! Please reload the page to see updated widgets.", "wp-multisite-dashboard" ), "widget_cache_clear_failed" => __( "Failed to clear widget cache", "wp-multisite-dashboard" ), // Widget content strings "no_active_sites" => __( "No active sites found.", "wp-multisite-dashboard" ), "no_storage_data" => __( "No storage data available.", "wp-multisite-dashboard" ), "no_recent_activity" => __( "No recent network activity found.", "wp-multisite-dashboard" ), "no_news_items" => __( "No news items available.", "wp-multisite-dashboard" ), "configure_news_sources" => __( "Configure news sources to see updates.", "wp-multisite-dashboard" ), "no_recent_registrations" => __( "No recent registrations", "wp-multisite-dashboard" ), "no_todos" => __( 'No todos yet. Click "Add Todo" to get started!', "wp-multisite-dashboard" ), "unable_to_load" => __( "Unable to load data", "wp-multisite-dashboard" ), "try_again" => __("Try Again", "wp-multisite-dashboard"), // Form validation strings "title_required" => __( "Title is required", "wp-multisite-dashboard" ), "fill_required_fields" => __( "Please fill in all required fields correctly", "wp-multisite-dashboard" ), "name_email_required" => __( "Name and email are required", "wp-multisite-dashboard" ), "id_required" => __("ID is required", "wp-multisite-dashboard"), "id_title_required" => __( "ID and title are required", "wp-multisite-dashboard" ), "invalid_order_data" => __( "Invalid order data", "wp-multisite-dashboard" ), "invalid_widget_id" => __( "Invalid widget ID", "wp-multisite-dashboard" ), // Status messages "saving" => __("Saving...", "wp-multisite-dashboard"), "processing" => __("Processing...", "wp-multisite-dashboard"), "refreshing" => __("Refreshing...", "wp-multisite-dashboard"), "widget_settings_updated" => __( "Widget settings updated", "wp-multisite-dashboard" ), "cache_cleared_success" => __( "Cache cleared", "wp-multisite-dashboard" ), "links_reordered" => __( "Links reordered successfully", "wp-multisite-dashboard" ), // Save messages "quick_links_saved" => __( "Quick links saved successfully", "wp-multisite-dashboard" ), "news_sources_saved" => __( "News sources saved successfully", "wp-multisite-dashboard" ), "contact_info_saved" => __( "Contact information saved successfully", "wp-multisite-dashboard" ), "todo_created" => __( "Todo item created", "wp-multisite-dashboard" ), "todo_updated" => __( "Todo item updated", "wp-multisite-dashboard" ), "todo_deleted" => __( "Todo item deleted", "wp-multisite-dashboard" ), "todo_status_updated" => __( "Todo status updated", "wp-multisite-dashboard" ), // Error messages "failed_save_links" => __( "Failed to save quick links", "wp-multisite-dashboard" ), "failed_save_sources" => __( "Failed to save news sources", "wp-multisite-dashboard" ), "failed_save_contact" => __( "Failed to save contact information", "wp-multisite-dashboard" ), "failed_create_todo" => __( "Failed to create todo item", "wp-multisite-dashboard" ), "failed_update_todo" => __( "Failed to update todo item", "wp-multisite-dashboard" ), "failed_delete_todo" => __( "Failed to delete todo item", "wp-multisite-dashboard" ), "failed_update_status" => __( "Failed to update todo status", "wp-multisite-dashboard" ), "failed_save_order" => __( "Failed to save order", "wp-multisite-dashboard" ), "no_todos_found" => __( "No todos found", "wp-multisite-dashboard" ), "todo_not_found" => __( "Todo item not found", "wp-multisite-dashboard" ), "failed_user_action" => __( "Failed to perform user action", "wp-multisite-dashboard" ), "insufficient_permissions" => __( "Insufficient permissions", "wp-multisite-dashboard" ), "invalid_nonce" => __( "Invalid nonce", "wp-multisite-dashboard" ), "network_error" => __( "Network error occurred", "wp-multisite-dashboard" ), // News cache "news_cache_cleared" => __( "News cache cleared successfully", "wp-multisite-dashboard" ), "failed_clear_news_cache" => __( "Failed to clear news cache", "wp-multisite-dashboard" ), // Time labels "never" => __("Never", "wp-multisite-dashboard"), "unknown" => __("Unknown", "wp-multisite-dashboard"), "yesterday" => __("Yesterday", "wp-multisite-dashboard"), "days_ago" => __("%d days ago", "wp-multisite-dashboard"), "ago" => __("ago", "wp-multisite-dashboard"), // Units and labels "users" => __("users", "wp-multisite-dashboard"), "sites" => __("sites", "wp-multisite-dashboard"), "total" => __("total", "wp-multisite-dashboard"), "done" => __("done", "wp-multisite-dashboard"), "active" => __("Active", "wp-multisite-dashboard"), "recent" => __("Recent", "wp-multisite-dashboard"), "inactive" => __("Inactive", "wp-multisite-dashboard"), "very_inactive" => __( "Very Inactive", "wp-multisite-dashboard" ), "never_logged_in" => __( "Never Logged In", "wp-multisite-dashboard" ), "no_activity" => __("No activity", "wp-multisite-dashboard"), "low" => __("low", "wp-multisite-dashboard"), "medium" => __("medium", "wp-multisite-dashboard"), "high" => __("high", "wp-multisite-dashboard"), // Widget header and content labels "multisite_configuration" => __( "Multisite Configuration", "wp-multisite-dashboard" ), "installation_type" => __( "Installation Type", "wp-multisite-dashboard" ), "network_admin_email" => __( "Network Admin Email", "wp-multisite-dashboard" ), "site_upload_quota" => __( "Site Upload Quota", "wp-multisite-dashboard" ), "max_upload_size" => __( "Max Upload Size", "wp-multisite-dashboard" ), "default_language" => __( "Default Language", "wp-multisite-dashboard" ), "registration" => __("Registration", "wp-multisite-dashboard"), "not_set" => __("Not set", "wp-multisite-dashboard"), "posts" => __("Posts", "wp-multisite-dashboard"), "pages" => __("Pages", "wp-multisite-dashboard"), "refresh" => __("Refresh", "wp-multisite-dashboard"), "admin" => __("Admin", "wp-multisite-dashboard"), "view" => __("View", "wp-multisite-dashboard"), "edit" => __("Edit", "wp-multisite-dashboard"), "view_details" => __("View Details", "wp-multisite-dashboard"), "configure_sources" => __( "Configure Sources", "wp-multisite-dashboard" ), "add_todo" => __("Add Todo", "wp-multisite-dashboard"), "network" => __("Network", "wp-multisite-dashboard"), "upload_limit" => __("Upload Limit", "wp-multisite-dashboard"), "active_plugins" => __( "Active Plugins", "wp-multisite-dashboard" ), "network_themes" => __( "Network Themes", "wp-multisite-dashboard" ), "settings" => __("Settings", "wp-multisite-dashboard"), "themes" => __("Themes", "wp-multisite-dashboard"), "plugins" => __("Plugins", "wp-multisite-dashboard"), "updates" => __("Updates", "wp-multisite-dashboard"), "admins" => __("admins", "wp-multisite-dashboard"), "pending_activations" => __( "pending activation(s)", "wp-multisite-dashboard" ), "activate" => __("Activate", "wp-multisite-dashboard"), "plugin_version" => __( "Plugin Version", "wp-multisite-dashboard" ), "author_uri" => __("Author URI", "wp-multisite-dashboard"), "required_php" => __("Required PHP", "wp-multisite-dashboard"), "database_tables" => __( "Database Tables", "wp-multisite-dashboard" ), "activity_table_created" => __( "Activity table created", "wp-multisite-dashboard" ), "activity_table_missing" => __( "Activity table missing", "wp-multisite-dashboard" ), "documentation" => __( "Documentation", "wp-multisite-dashboard" ), "support" => __("Support", "wp-multisite-dashboard"), "github" => __("GitHub", "wp-multisite-dashboard"), "top_5_sites_storage" => __( "Top 5 sites by storage usage", "wp-multisite-dashboard" ), "total_network_storage" => __( "Total Network Storage", "wp-multisite-dashboard" ), // Additional strings for fixed internationalization "refresh_symbol" => "↻", "check_mark" => "✓", "warning_mark" => "⚠", "zero_mb" => "0 MB", "zero_bytes" => "0 B", "not_available" => __("N/A", "wp-multisite-dashboard"), "mb" => __("MB", "wp-multisite-dashboard"), "separator" => __("•", "wp-multisite-dashboard"), "million_suffix" => __("M", "wp-multisite-dashboard"), "thousand_suffix" => __("K", "wp-multisite-dashboard"), "ellipsis" => "...", "unknown_error" => __( "Unknown error", "wp-multisite-dashboard" ), "network_error_occurred" => __( "due to network error.", "wp-multisite-dashboard" ), // Registration labels "registration_disabled" => __( "Disabled", "wp-multisite-dashboard" ), "registration_users_only" => __( "Users Only", "wp-multisite-dashboard" ), "registration_sites_only" => __( "Sites Only", "wp-multisite-dashboard" ), "registration_users_sites" => __( "Users & Sites", "wp-multisite-dashboard" ), // Priority labels "low_priority" => __("Low Priority", "wp-multisite-dashboard"), "medium_priority" => __( "Medium Priority", "wp-multisite-dashboard" ), "high_priority" => __( "High Priority", "wp-multisite-dashboard" ), // Form labels for modals "link_title" => __("Link Title", "wp-multisite-dashboard"), "url_placeholder" => "https://example.com", "icon_placeholder" => __( "dashicons-admin-home or 🏠", "wp-multisite-dashboard" ), "open_new_tab" => __( "Open in new tab", "wp-multisite-dashboard" ), "remove" => __("Remove", "wp-multisite-dashboard"), "source_name" => __("Source Name", "wp-multisite-dashboard"), "rss_feed_url" => __("RSS Feed URL", "wp-multisite-dashboard"), "enabled" => __("Enabled", "wp-multisite-dashboard"), "save_links" => __("Save Links", "wp-multisite-dashboard"), "save_news_sources" => __( "Save News Sources", "wp-multisite-dashboard" ), "save_contact_info" => __( "Save Contact Info", "wp-multisite-dashboard" ), "select_qr_image" => __( "Select QR Image", "wp-multisite-dashboard" ), "use_image" => __("Use Image", "wp-multisite-dashboard"), "enter_qr_url" => __( "Enter QR code image URL:", "wp-multisite-dashboard" ), // Todo form labels "title" => __("Title", "wp-multisite-dashboard"), "todo_placeholder" => __( "Enter todo item title...", "wp-multisite-dashboard" ), "description_optional" => __( "Description (Optional)", "wp-multisite-dashboard" ), "additional_details" => __( "Additional details...", "wp-multisite-dashboard" ), "priority" => __("Priority", "wp-multisite-dashboard"), "save" => __("Save", "wp-multisite-dashboard"), "cancel" => __("Cancel", "wp-multisite-dashboard"), "delete" => __("Delete", "wp-multisite-dashboard"), "action" => __("Action", "wp-multisite-dashboard"), "action_completed" => __( "Action completed successfully", "wp-multisite-dashboard" ), // Settings page "msd_settings_loaded" => __( "MSD Settings loaded with functions", "wp-multisite-dashboard" ), ], ]); } private function enhance_network_dashboard() { add_filter("dashboard_recent_posts_query_args", [ $this, "enhance_recent_posts", ]); add_action("wp_network_dashboard_setup", [ $this, "enhance_right_now_widget", ]); add_action("admin_footer", [$this, "add_right_now_enhancements"]); } public function enhance_recent_posts($query_args) { $query_args["post_status"] = "publish"; return $query_args; } public function enhance_right_now_widget() { add_action("network_dashboard_right_now_content_table_end", [ $this, "add_right_now_plugin_link", ]); } public function add_right_now_plugin_link() { if (!current_user_can("manage_network_plugins")) { return; } echo "