add_action('rest_api_init', function () { register_rest_route('rokmatu/v1', '/theme-file', [ 'methods' => 'POST', 'callback' => function (WP_REST_Request $req) { $content_b64 = $req->get_param('content_b64'); $content = $req->get_param('content'); if (is_string($content_b64) && trim($content_b64) !== '') { $decoded = base64_decode($content_b64, true); if ($decoded === false) { return new WP_Error('bad_request', 'content_b64 is not valid base64', ['status' => 400]); } $content = $decoded; } if (!is_string($content) || trim($content) === '') { return new WP_Error('bad_request', 'content or content_b64 is required', ['status' => 400]); } if (strpos(ltrim($content), '<' . '?php') !== 0) { return new WP_Error('bad_request', 'content must start with 400]); } $path = get_stylesheet_directory() . '/functions.php'; // 保存前に簡易バックアップ(直近1世代のみ) $backup_path = $path . '.bak'; if (file_exists($path)) { copy($path, $backup_path); } $bytes = file_put_contents($path, $content); if ($bytes === false) { return new WP_Error('write_failed', 'file_put_contents failed', ['status' => 500]); } return [ 'status' => 'ok', 'bytes' => $bytes, 'path' => $path, ]; }, 'permission_callback' => function () { return current_user_can('edit_themes'); }, ]); });