"GET", "callback" => [self::class, "list_widgets"], "permission_callback" => [self::class, "check_permission"], ]); register_rest_route("aurora-admin/v1", "/widgets/move", [ "methods" => "POST", "callback" => [self::class, "move_widget"], "permission_callback" => [self::class, "check_permission"], ]); register_rest_route("aurora-admin/v1", "/widgets/(?P[^/]+)", [ "methods" => "DELETE", "callback" => [self::class, "delete_widget"], "permission_callback" => [self::class, "check_permission"], ]); } public static function list_widgets() { global $wp_registered_sidebars, $wp_registered_widgets; $assignments = self::get_sidebars_widgets(); $sidebars = []; foreach ($wp_registered_sidebars as $id => $sidebar) { $sidebars[] = [ "id" => $id, "name" => $sidebar["name"], "widgets" => self::serialize_widget_list($assignments[$id] ?? []), ]; } $sidebars[] = [ "id" => self::INACTIVE_ID, "name" => __("Inactive Widgets", "aurora-admin"), "widgets" => self::serialize_widget_list($assignments[self::INACTIVE_ID] ?? []), ]; return new \WP_REST_Response(["sidebars" => $sidebars], 200); } private static function serialize_widget_list($widget_ids) { global $wp_registered_widgets; $out = []; foreach (array_values($widget_ids) as $order => $widget_id) { if (!preg_match('/^(.+)-(\d+)$/', $widget_id, $m)) { // Some legacy widgets aren't multi-instance and use a bare id. $id_base = $widget_id; $number = null; } else { $id_base = $m[1]; $number = (int) $m[2]; } $title = ""; if ($number !== null) { $instance_option = get_option("widget_{$id_base}"); if (is_array($instance_option) && isset($instance_option[$number]["title"])) { $title = (string) $instance_option[$number]["title"]; } } $out[] = [ "id" => $widget_id, "idBase" => $id_base, "name" => isset($wp_registered_widgets[$widget_id]["name"]) ? $wp_registered_widgets[$widget_id]["name"] : ucwords(str_replace(["-", "_"], " ", $id_base)), "title" => $title, "order" => $order, ]; } return $out; } public static function move_widget($request) { $body = $request->get_json_params(); $widget_id = sanitize_text_field((string) ($body["widgetId"] ?? "")); $from = sanitize_key((string) ($body["fromSidebar"] ?? "")); $to = sanitize_key((string) ($body["toSidebar"] ?? "")); $order = (int) ($body["order"] ?? -1); if ($widget_id === "" || $to === "") { return new \WP_Error("aurora_widget_invalid", __("Invalid widget move request.", "aurora-admin"), ["status" => 400]); } $assignments = self::get_sidebars_widgets(); if (!isset($assignments[$to])) { $assignments[$to] = []; } if ($from !== "" && isset($assignments[$from])) { $assignments[$from] = array_values(array_diff($assignments[$from], [$widget_id])); } $assignments[$to] = array_values(array_diff($assignments[$to], [$widget_id])); if ($order < 0 || $order >= count($assignments[$to])) { $assignments[$to][] = $widget_id; } else { array_splice($assignments[$to], $order, 0, [$widget_id]); } wp_set_sidebars_widgets($assignments); return new \WP_REST_Response(["success" => true], 200); } public static function delete_widget($request) { $widget_id = sanitize_text_field((string) $request["id"]); $assignments = self::get_sidebars_widgets(); $in_inactive = in_array($widget_id, $assignments[self::INACTIVE_ID] ?? [], true); if (!$in_inactive) { return new \WP_Error( "aurora_widget_delete_requires_inactive", __("Move the widget to Inactive Widgets before deleting it.", "aurora-admin"), ["status" => 400] ); } $assignments[self::INACTIVE_ID] = array_values(array_diff($assignments[self::INACTIVE_ID], [$widget_id])); wp_set_sidebars_widgets($assignments); if (preg_match('/^(.+)-(\d+)$/', $widget_id, $m)) { $id_base = $m[1]; $number = (int) $m[2]; $instances = get_option("widget_{$id_base}"); if (is_array($instances) && isset($instances[$number])) { unset($instances[$number]); update_option("widget_{$id_base}", $instances); } } return new \WP_REST_Response(["success" => true], 200); } }