'GET', 'callback' => [$this, 'get_config'], 'permission_callback' => $auth, ], [ 'methods' => 'PUT', 'callback' => [$this, 'update_config'], 'permission_callback' => $auth, ], ]); register_rest_route(self::NAMESPACE, '/deploy', [ 'methods' => 'POST', 'callback' => [$this, 'deploy'], 'permission_callback' => $auth, ]); register_rest_route(self::NAMESPACE, '/ad-units/export', [ 'methods' => 'GET', 'callback' => [$this, 'export_units'], 'permission_callback' => $auth, ]); register_rest_route(self::NAMESPACE, '/ad-units/import', [ 'methods' => 'POST', 'callback' => [$this, 'import_units'], 'permission_callback' => $auth, ]); register_rest_route(self::NAMESPACE, '/ads-txt/validate', [ 'methods' => 'POST', 'callback' => [$this, 'validate_ads_txt'], 'permission_callback' => $auth, ]); } public function get_config() { return rest_ensure_response(AdGhost_Plugin::get_instance()->get_config()); } public function update_config(WP_REST_Request $request) { $data = $request->get_json_params(); if (!is_array($data)) { $data = $request->get_params(); } $result = AdGhost_Plugin::get_instance()->apply_config(AdGhost_Plugin::sanitize_request((array) $data)); if (!$result['success']) { return new WP_Error('adghost_save_failed', $result['error'], ['status' => 500]); } return rest_ensure_response([ 'success' => true, 'config' => AdGhost_Plugin::get_instance()->get_config(), ]); } public function deploy() { $result = AdGhost_Plugin::get_instance()->activate_runtime(); if (empty($result['success'])) { return new WP_Error('adghost_deploy_failed', $result['error'] ?? 'Deploy failed', ['status' => 502]); } return rest_ensure_response([ 'success' => true, 'is_active' => true, 'message' => 'Runtime deployed. Ads are now live.', ]); } public function export_units(WP_REST_Request $request) { $ad_units = get_option('adghost_ad_units', []); $csv = AdGhost_CSV_Exporter::generate($ad_units, rest_sanitize_boolean($request->get_param('only_new'))); $response = new WP_REST_Response($csv); $response->header('Content-Type', 'text/csv; charset=utf-8'); $response->header( 'Content-Disposition', 'attachment; filename=adghost-gam-units-' . gmdate('Y-m-d') . '.csv' ); return $response; } public function import_units(WP_REST_Request $request) { $files = $request->get_file_params(); if (!empty($files['csv_file']['tmp_name'])) { $tmp = $files['csv_file']['tmp_name']; if (!is_uploaded_file($tmp)) { return new WP_Error('adghost_import_failed', 'No file uploaded', ['status' => 400]); } require_once plugin_dir_path(__FILE__) . 'class-csv-importer.php'; $result = AdGhost_CSV_Importer::parse($tmp); if (is_wp_error($result)) { return new WP_Error('adghost_import_failed', $result->get_error_message(), ['status' => 400]); } return rest_ensure_response(['success' => true, 'units' => $result]); } $csv_text = (string) $request->get_param('csv'); if ($csv_text === '') { return new WP_Error('adghost_import_empty', 'No CSV file or content provided', ['status' => 400]); } require_once plugin_dir_path(__FILE__) . 'class-csv-importer.php'; $result = AdGhost_CSV_Importer::parse_string($csv_text); if (is_wp_error($result)) { return new WP_Error('adghost_import_failed', $result->get_error_message(), ['status' => 400]); } return rest_ensure_response(['success' => true, 'units' => $result]); } public function validate_ads_txt(WP_REST_Request $request) { $content = (string) $request->get_param('content'); return rest_ensure_response([ 'success' => true, 'validation' => AdGhost_Ads_Txt::validate_ads_txt($content), ]); } }