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/includes/class-lm-api.php
<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class LM_API {

    public function __construct() {
        add_action( 'rest_api_init', array( $this, 'register_routes' ) );
    }

    /**
     * Register REST API routes under link-manager/v1.
     */
    public function register_routes() {
        $namespace = 'link-manager/v1';

        register_rest_route( $namespace, '/place_link', array(
            'methods'             => 'POST',
            'callback'            => array( $this, 'place_link' ),
            'permission_callback' => array( $this, 'verify_request' ),
        ) );

        register_rest_route( $namespace, '/delete_link', array(
            'methods'             => 'POST',
            'callback'            => array( $this, 'delete_link' ),
            'permission_callback' => array( $this, 'verify_request' ),
        ) );

        register_rest_route( $namespace, '/list_links', array(
            'methods'             => 'GET',
            'callback'            => array( $this, 'list_links' ),
            'permission_callback' => array( $this, 'verify_request' ),
        ) );

        register_rest_route( $namespace, '/status', array(
            'methods'             => 'GET',
            'callback'            => array( $this, 'status' ),
            'permission_callback' => array( $this, 'verify_request' ),
        ) );

        // Configure endpoint: accepts HMAC auth OR WP cookie auth (admin)
        register_rest_route( $namespace, '/configure', array(
            'methods'             => 'POST',
            'callback'            => array( $this, 'configure' ),
            'permission_callback' => function( $request ) {
                // Allow if HMAC is valid
                if ( LM_Security::verify_request( $request ) === true ) {
                    return true;
                }
                // Fallback: allow if logged-in WP admin (cookie auth, for auto-install)
                return current_user_can( 'manage_options' );
            },
        ) );

        register_rest_route( $namespace, '/ping', array(
            'methods'             => 'GET',
            'callback'            => array( $this, 'ping' ),
            'permission_callback' => '__return_true',
        ) );
    }

    /**
     * Permission callback that delegates to LM_Security.
     *
     * @param WP_REST_Request $request
     * @return true|WP_Error
     */
    public function verify_request( $request ) {
        return LM_Security::verify_request( $request );
    }

    /**
     * POST /place_link — Place a new link on the site.
     */
    public function place_link( WP_REST_Request $request ) {
        $url         = sanitize_url( $request->get_param( 'url' ) );
        $anchor_text = sanitize_text_field( $request->get_param( 'anchor_text' ) );
        $position    = sanitize_text_field( $request->get_param( 'position' ) );
        $rel         = sanitize_text_field( $request->get_param( 'rel' ) );
        $project_id  = sanitize_text_field( $request->get_param( 'project_id' ) );
        $link_id     = sanitize_text_field( $request->get_param( 'link_id' ) );

        if ( empty( $url ) || empty( $anchor_text ) || empty( $link_id ) ) {
            return new WP_Error( 'missing_params', 'Missing required parameters.', array( 'status' => 400 ) );
        }

        $valid_positions = array( 'body_open', 'footer', 'content', 'sidebar' );
        if ( ! in_array( $position, $valid_positions, true ) ) {
            return new WP_Error( 'invalid_position', 'Invalid link position.', array( 'status' => 400 ) );
        }

        $valid_rels = array( 'nofollow', 'dofollow', 'sponsored' );
        if ( ! in_array( $rel, $valid_rels, true ) ) {
            $rel = 'nofollow';
        }

        $links = get_option( 'lm_active_links', array() );

        $html_content = $request->get_param( 'html_content' );

        $links[ $link_id ] = array(
            'url'          => $url,
            'anchor_text'  => $anchor_text,
            'position'     => $position,
            'rel'          => $rel,
            'project_id'   => $project_id,
            'link_id'      => $link_id,
            'html_content' => $html_content ? $html_content : '',
            'placed_at'    => time(),
        );

        update_option( 'lm_active_links', $links );

        return rest_ensure_response( array(
            'status'  => 'ok',
            'link_id' => $link_id,
            'message' => 'Link placed successfully.',
        ) );
    }

    /**
     * POST /delete_link — Delete a link by link_id.
     */
    public function delete_link( WP_REST_Request $request ) {
        $link_id = sanitize_text_field( $request->get_param( 'link_id' ) );

        if ( empty( $link_id ) ) {
            return new WP_Error( 'missing_params', 'Missing link_id parameter.', array( 'status' => 400 ) );
        }

        $links = get_option( 'lm_active_links', array() );

        if ( ! isset( $links[ $link_id ] ) ) {
            return new WP_Error( 'not_found', 'Link not found.', array( 'status' => 404 ) );
        }

        unset( $links[ $link_id ] );
        update_option( 'lm_active_links', $links );

        return rest_ensure_response( array(
            'status'  => 'ok',
            'link_id' => $link_id,
            'message' => 'Link deleted successfully.',
        ) );
    }

    /**
     * GET /list_links — Return all currently placed links.
     */
    public function list_links( WP_REST_Request $request ) {
        $links = get_option( 'lm_active_links', array() );

        return rest_ensure_response( array(
            'status' => 'ok',
            'links'  => $links,
            'count'  => count( $links ),
        ) );
    }

    /**
     * GET /status — Return site status information.
     */
    public function status( WP_REST_Request $request ) {
        $links = get_option( 'lm_active_links', array() );
        $theme = wp_get_theme();

        return rest_ensure_response( array(
            'status'         => 'ok',
            'wp_version'     => get_bloginfo( 'version' ),
            'php_version'    => PHP_VERSION,
            'plugin_version' => LM_VERSION,
            'active_theme'   => $theme->get( 'Name' ),
            'link_count'     => count( $links ),
            'disk_free'      => function_exists( 'disk_free_space' ) ? disk_free_space( ABSPATH ) : null,
        ) );
    }

    /**
     * POST /configure — Update plugin settings.
     */
    public function configure( WP_REST_Request $request ) {
        $fields = array(
            'panel_url'   => 'lm_panel_url',
            'hmac_secret' => 'lm_hmac_secret',
            'allowed_ips' => 'lm_allowed_ips',
        );

        $updated = array();

        foreach ( $fields as $param => $option ) {
            $value = $request->get_param( $param );
            if ( $value !== null ) {
                update_option( $option, sanitize_text_field( $value ) );
                $updated[] = $param;
            }
        }

        return rest_ensure_response( array(
            'status'     => 'ok',
            'updated'    => $updated,
            'site_token' => get_option( 'lm_site_token', '' ),
        ) );
    }

    /**
     * GET /ping — Simple health check.
     */
    public function ping( WP_REST_Request $request ) {
        return rest_ensure_response( array(
            'status'    => 'ok',
            'timestamp' => time(),
        ) );
    }
}