HEX
Server: nginx/1.28.0
System: Linux yisu-68a5f20334161 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
User: www (1000)
PHP: 8.2.28
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
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', ''),
        ]);
    }
}