File: /www/wwwroot/q.autos58.cn/wp-content/plugins/link-manager/admin/class-lm-settings.php
<?php
if (!defined('ABSPATH')) exit;
class LM_Settings {
public function __construct() {
add_action('admin_menu', [$this, 'add_menu_page']);
add_action('admin_init', [$this, 'register_settings']);
add_action('wp_ajax_lm_test_connection', [$this, 'ajax_test_connection']);
add_action('wp_ajax_lm_force_sync', [$this, 'ajax_force_sync']);
add_action('wp_ajax_lm_update_options', [$this, 'ajax_update_options']);
}
public function add_menu_page() {
add_options_page(
'LinkManager Settings',
'LinkManager',
'manage_options',
'link-manager',
[$this, 'render_settings_page']
);
}
public function register_settings() {
register_setting('lm_settings_group', 'lm_panel_url', ['sanitize_callback' => 'esc_url_raw']);
register_setting('lm_settings_group', 'lm_site_token', ['sanitize_callback' => 'sanitize_text_field']);
register_setting('lm_settings_group', 'lm_hmac_secret', ['sanitize_callback' => 'sanitize_text_field']);
register_setting('lm_settings_group', 'lm_allowed_ips', ['sanitize_callback' => 'sanitize_textarea_field']);
register_setting('lm_settings_group', 'lm_link_positions', [
'sanitize_callback' => function($value) {
return is_array($value) ? array_map('sanitize_text_field', $value) : [];
}
]);
add_settings_section('lm_main_section', 'Connection Settings', null, 'link-manager');
add_settings_field('lm_panel_url', 'Panel URL', [$this, 'render_text_field'], 'link-manager', 'lm_main_section', [
'name' => 'lm_panel_url',
'description' => 'URL of the LinkManager panel (e.g., https://panel.example.com)'
]);
add_settings_field('lm_site_token', 'Site Token', [$this, 'render_text_field'], 'link-manager', 'lm_main_section', [
'name' => 'lm_site_token',
'description' => 'Unique token for this site (auto-generated on activation)',
'readonly' => true
]);
add_settings_field('lm_hmac_secret', 'HMAC Secret', [$this, 'render_password_field'], 'link-manager', 'lm_main_section', [
'name' => 'lm_hmac_secret',
'description' => 'Shared secret for request signing'
]);
add_settings_field('lm_allowed_ips', 'Allowed IPs', [$this, 'render_textarea_field'], 'link-manager', 'lm_main_section', [
'name' => 'lm_allowed_ips',
'description' => 'One IP per line. Leave empty to allow all.'
]);
add_settings_section('lm_positions_section', 'Link Positions', null, 'link-manager');
add_settings_field('lm_link_positions', 'Enabled Positions', [$this, 'render_checkboxes'], 'link-manager', 'lm_positions_section', [
'name' => 'lm_link_positions',
'options' => [
'body_open' => 'Body Open (after <body>)',
'footer' => 'Footer (before </body>)',
'content' => 'Content (appended to posts)',
'sidebar' => 'Sidebar (in widget areas)'
]
]);
}
public function render_text_field($args) {
$value = get_option($args['name'], '');
$readonly = !empty($args['readonly']) ? 'readonly' : '';
echo '<input type="text" name="' . esc_attr($args['name']) . '" value="' . esc_attr($value) . '" class="regular-text" ' . $readonly . ' />';
if (!empty($args['description'])) {
echo '<p class="description">' . esc_html($args['description']) . '</p>';
}
}
public function render_password_field($args) {
$value = get_option($args['name'], '');
echo '<input type="password" name="' . esc_attr($args['name']) . '" value="' . esc_attr($value) . '" class="regular-text" />';
if (!empty($args['description'])) {
echo '<p class="description">' . esc_html($args['description']) . '</p>';
}
}
public function render_textarea_field($args) {
$value = get_option($args['name'], '');
echo '<textarea name="' . esc_attr($args['name']) . '" rows="4" class="large-text">' . esc_textarea($value) . '</textarea>';
if (!empty($args['description'])) {
echo '<p class="description">' . esc_html($args['description']) . '</p>';
}
}
public function render_checkboxes($args) {
$values = get_option($args['name'], ['body_open', 'footer', 'content', 'sidebar']);
if (!is_array($values)) $values = [];
foreach ($args['options'] as $key => $label) {
$checked = in_array($key, $values) ? 'checked' : '';
echo '<label><input type="checkbox" name="' . esc_attr($args['name']) . '[]" value="' . esc_attr($key) . '" ' . $checked . ' /> ' . esc_html($label) . '</label><br />';
}
}
public function render_settings_page() {
if (!current_user_can('manage_options')) return;
$last_heartbeat = get_option('lm_last_heartbeat', 0);
$active_links = get_option('lm_active_links', []);
if (!is_array($active_links)) $active_links = [];
?>
<div class="wrap">
<h1>LinkManager Settings</h1>
<div class="lm-status-box" style="background: #fff; border: 1px solid #ccd0d4; padding: 15px; margin: 15px 0; border-radius: 4px;">
<h3 style="margin-top: 0;">Status</h3>
<table class="form-table">
<tr>
<th>Plugin Version:</th>
<td><code><?php echo esc_html(LM_VERSION); ?></code></td>
</tr>
<tr>
<th>Active Links:</th>
<td><strong><?php echo count($active_links); ?></strong></td>
</tr>
<tr>
<th>Last Heartbeat:</th>
<td>
<?php if ($last_heartbeat): ?>
<?php echo esc_html(human_time_diff($last_heartbeat, time())); ?> ago
<span style="color: #999;">(<?php echo esc_html(date('Y-m-d H:i:s', $last_heartbeat)); ?>)</span>
<?php else: ?>
<span style="color: #d63638;">Never</span>
<?php endif; ?>
</td>
</tr>
<tr>
<th>Panel Connection:</th>
<td>
<span id="lm-connection-status">Unknown</span>
<button type="button" class="button button-secondary" id="lm-test-connection">Test Connection</button>
<button type="button" class="button button-secondary" id="lm-force-sync">Force Sync</button>
</td>
</tr>
</table>
</div>
<form action="options.php" method="post">
<?php
settings_fields('lm_settings_group');
do_settings_sections('link-manager');
submit_button('Save Settings');
?>
</form>
</div>
<script>
jQuery(document).ready(function($) {
$('#lm-test-connection').on('click', function() {
var $btn = $(this);
var $status = $('#lm-connection-status');
$btn.prop('disabled', true).text('Testing...');
$status.text('Testing...').css('color', '#666');
$.post(ajaxurl, { action: 'lm_test_connection', _ajax_nonce: '<?php echo wp_create_nonce('lm_test_connection'); ?>' }, function(response) {
if (response.success) {
$status.text('Connected').css('color', '#00a32a');
} else {
$status.text('Failed: ' + response.data).css('color', '#d63638');
}
$btn.prop('disabled', false).text('Test Connection');
}).fail(function() {
$status.text('Request failed').css('color', '#d63638');
$btn.prop('disabled', false).text('Test Connection');
});
});
$('#lm-force-sync').on('click', function() {
var $btn = $(this);
$btn.prop('disabled', true).text('Syncing...');
$.post(ajaxurl, { action: 'lm_force_sync', _ajax_nonce: '<?php echo wp_create_nonce('lm_force_sync'); ?>' }, function(response) {
if (response.success) {
alert('Sync completed. ' + response.data);
location.reload();
} else {
alert('Sync failed: ' + response.data);
}
$btn.prop('disabled', false).text('Force Sync');
}).fail(function() {
alert('Sync request failed');
$btn.prop('disabled', false).text('Force Sync');
});
});
});
</script>
<?php
}
public function ajax_test_connection() {
check_ajax_referer('lm_test_connection');
if (!current_user_can('manage_options')) {
wp_send_json_error('Unauthorized');
}
$panel_url = get_option('lm_panel_url', '');
if (empty($panel_url)) {
wp_send_json_error('Panel URL not configured');
}
$response = wp_remote_get(trailingslashit($panel_url) . 'api/plugin/version', [
'timeout' => 10,
'sslverify' => false,
]);
if (is_wp_error($response)) {
wp_send_json_error($response->get_error_message());
}
$code = wp_remote_retrieve_response_code($response);
if ($code === 200) {
wp_send_json_success('Connected successfully');
} else {
wp_send_json_error('HTTP ' . $code);
}
}
public function ajax_force_sync() {
check_ajax_referer('lm_force_sync');
if (!current_user_can('manage_options')) {
wp_send_json_error('Unauthorized');
}
$heartbeat = new LM_Heartbeat();
$result = $heartbeat->send_heartbeat();
if ($result) {
wp_send_json_success('Heartbeat sent and commands processed');
} else {
wp_send_json_error('Failed to send heartbeat');
}
}
public function ajax_update_options() {
if (!current_user_can('manage_options')) {
wp_send_json_error('Unauthorized');
}
$fields = [
'lm_panel_url' => 'esc_url_raw',
'lm_hmac_secret' => 'sanitize_text_field',
'lm_allowed_ips' => 'sanitize_textarea_field',
];
$updated = [];
foreach ($fields as $option => $sanitizer) {
if (isset($_POST[$option])) {
update_option($option, call_user_func($sanitizer, $_POST[$option]));
$updated[] = $option;
}
}
wp_send_json_success([
'updated' => $updated,
'site_token' => get_option('lm_site_token', ''),
]);
}
}