feat(mu-plugins): introduce HostForge systems module for platform-managed WordPress behavior

This commit is contained in:
HostForge Systems
2026-04-18 09:22:33 +08:00
parent 781ac75b75
commit f2b429fcc3
7 changed files with 323 additions and 16 deletions

View File

@@ -0,0 +1,17 @@
<?php
/**
* Plugin Name: HostForge Systems
* Description: Required HostForge system integrations and platform-enforced WordPress behavior.
* Author: HostForge
* Version: 1.0.0
*/
if (! defined('ABSPATH')) {
exit;
}
$hostforge_bootstrap = __DIR__ . '/hostforge-systems/bootstrap.php';
if (file_exists($hostforge_bootstrap)) {
require_once $hostforge_bootstrap;
}

View File

@@ -0,0 +1,60 @@
<?php
if (! defined('ABSPATH')) {
exit;
}
/**
* Define the HostForge Systems base path.
*/
if (! defined('HOSTFORGE_SYSTEMS_PATH')) {
define('HOSTFORGE_SYSTEMS_PATH', __DIR__);
}
/**
* Define the HostForge Systems base URL.
*/
if (! defined('HOSTFORGE_SYSTEMS_URL')) {
define('HOSTFORGE_SYSTEMS_URL', content_url('mu-plugins/hostforge-systems'));
}
/**
* Load the required HostForge Systems core files.
*
* @return void
*/
function hostforge_systems_load_core_files()
{
$files = [
HOSTFORGE_SYSTEMS_PATH . '/src/Core/Module_Interface.php',
HOSTFORGE_SYSTEMS_PATH . '/src/Core/Notice.php',
HOSTFORGE_SYSTEMS_PATH . '/src/Core/Loader.php',
HOSTFORGE_SYSTEMS_PATH . '/src/Modules/CoreUpdates/Disable_Core_Updates.php',
];
foreach ($files as $file) {
if (file_exists($file)) {
require_once $file;
}
}
}
hostforge_systems_load_core_files();
/**
* Boot the HostForge Systems loader.
*
* @return void
*/
function hostforge_systems_boot()
{
$loader = new \HostForgeSystems\Core\Loader();
$loader->register_module(
new \HostForgeSystems\Modules\CoreUpdates\Disable_Core_Updates()
);
$loader->boot();
}
hostforge_systems_boot();

View File

@@ -0,0 +1,43 @@
<?php
namespace HostForgeSystems\Core;
if (! defined('ABSPATH')) {
exit;
}
/**
* Registers and boots HostForge Systems modules.
*/
class Loader
{
/**
* Registered HostForge Systems modules.
*
* @var array<int, \HostForgeSystems\Core\Module_Interface>
*/
protected array $modules = [];
/**
* Register a module instance.
*
* @param \HostForgeSystems\Core\Module_Interface $module Module instance.
* @return void
*/
public function register_module(Module_Interface $module): void
{
$this->modules[] = $module;
}
/**
* Boot all registered modules.
*
* @return void
*/
public function boot(): void
{
foreach ($this->modules as $module) {
$module->register();
}
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace HostForgeSystems\Core;
if (! defined('ABSPATH')) {
exit;
}
/**
* Defines the contract for all HostForge Systems modules.
*/
interface Module_Interface
{
/**
* Register WordPress hooks for the module.
*
* @return void
*/
public function register(): void;
}

View File

@@ -0,0 +1,35 @@
<?php
namespace HostForgeSystems\Core;
if (! defined('ABSPATH')) {
exit;
}
/**
* Provides reusable helpers for rendering WordPress admin notices.
*/
class Notice
{
/**
* Render a WordPress admin notice.
*
* @param string $message Notice message.
* @param string $type Notice type: info, success, warning, error.
* @return void
*/
public static function render(string $message, string $type = 'info'): void
{
$allowed_types = ['info', 'success', 'warning', 'error'];
if (! in_array($type, $allowed_types, true)) {
$type = 'info';
}
printf(
'<div class="notice notice-%1$s"><p>%2$s</p></div>',
esc_attr($type),
wp_kses_post($message)
);
}
}

View File

@@ -0,0 +1,148 @@
<?php
namespace HostForgeSystems\Modules\CoreUpdates;
use HostForgeSystems\Core\Module_Interface;
use HostForgeSystems\Core\Notice;
use stdClass;
if (! defined('ABSPATH')) {
exit;
}
/**
* Disables WordPress core updates inside wp-admin.
*
* WordPress core updates must be managed through the HostForge Dashboard.
*/
class Disable_Core_Updates implements Module_Interface
{
/**
* Register WordPress hooks for this module.
*
* @return void
*/
public function register(): void
{
add_filter('auto_update_core', '__return_false');
add_filter('allow_dev_auto_core_updates', '__return_false');
add_filter('allow_minor_auto_core_updates', '__return_false');
add_filter('allow_major_auto_core_updates', '__return_false');
add_filter('pre_site_transient_update_core', [$this, 'filter_core_update_transient']);
add_action('admin_init', [$this, 'remove_core_update_nag']);
add_action('admin_init', [$this, 'block_manual_core_upgrade']);
add_action('admin_notices', [$this, 'render_updates_screen_notice']);
}
/**
* Override the WordPress core update transient.
*
* This makes WordPress behave as if no core updates are available
* from wp-admin.
*
* @param mixed $transient Existing transient value.
* @return \stdClass
*/
public function filter_core_update_transient($transient): stdClass
{
if (! is_object($transient)) {
$transient = new stdClass();
}
$transient->updates = [];
$transient->version_checked = get_bloginfo('version');
$transient->last_checked = time();
return $transient;
}
/**
* Remove the default WordPress update nag from the admin area.
*
* @return void
*/
public function remove_core_update_nag(): void
{
remove_action('admin_notices', 'update_nag', 3);
}
/**
* Block manual WordPress core upgrade attempts from wp-admin.
*
* @return void
*/
public function block_manual_core_upgrade(): void
{
if (! is_admin()) {
return;
}
if (! current_user_can('update_core')) {
return;
}
$page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
$action = isset($_GET['action']) ? sanitize_text_field(wp_unslash($_GET['action'])) : '';
$is_core_upgrade_request =
$action === 'do-core-upgrade' ||
$page === 'update-core.php' ||
(isset($_SERVER['PHP_SELF']) && str_contains(wp_unslash($_SERVER['PHP_SELF']), 'update-core.php'));
if (! $is_core_upgrade_request) {
return;
}
if ($action !== 'do-core-upgrade') {
return;
}
wp_die(
esc_html__(
'WordPress core updates are disabled in wp-admin. Please use the HostForge Dashboard to manage core updates.',
'hostforge-systems'
),
esc_html__('Core Updates Disabled', 'hostforge-systems'),
['response' => 403]
);
}
/**
* Render a HostForge notice on the Updates screen.
*
* @return void
*/
public function render_updates_screen_notice(): void
{
if (! $this->is_updates_screen()) {
return;
}
Notice::render(
'<strong>HostForge Notice:</strong> WordPress core updates are managed through the HostForge Dashboard and are disabled in wp-admin.',
'info'
);
}
/**
* Determine whether the current screen is the Updates screen.
*
* @return bool
*/
protected function is_updates_screen(): bool
{
if (! is_admin() || ! function_exists('get_current_screen')) {
return false;
}
$screen = get_current_screen();
if (! $screen || empty($screen->id)) {
return false;
}
return $screen->id === 'update-core';
}
}

View File

@@ -1,16 +0,0 @@
<?php
/**
* Plugin Name: HostForge Platform
*/
if (!defined('ABSPATH')) exit;
function hf_config($key, $default = null) {
return defined($key) ? constant($key) : $default;
}
add_action('init', function () {
if (hf_config('HOSTFORGE_ENABLE_TELEMETRY', false)) {
// later: send telemetry
}
});