From 0ece2102bd7522c734b26caa034310a96297db85 Mon Sep 17 00:00:00 2001 From: MateusBreno Date: Tue, 24 Mar 2026 23:27:32 -0400 Subject: [PATCH] Implement WordPress plugin for favoriting posts with REST API and custom table --- apiki-favorites/apiki-favorites.php | 47 +++++++ .../includes/class-apiki-favorites-db.php | 36 +++++ .../class-apiki-favorites-rest-controller.php | 131 ++++++++++++++++++ 3 files changed, 214 insertions(+) create mode 100644 apiki-favorites/apiki-favorites.php create mode 100644 apiki-favorites/includes/class-apiki-favorites-db.php create mode 100644 apiki-favorites/includes/class-apiki-favorites-rest-controller.php diff --git a/apiki-favorites/apiki-favorites.php b/apiki-favorites/apiki-favorites.php new file mode 100644 index 00000000..96ed4179 --- /dev/null +++ b/apiki-favorites/apiki-favorites.php @@ -0,0 +1,47 @@ +prefix . "apiki_favorites"; + + $charset_collate = $wpdb->get_charset_collate(); + + $sql = "CREATE TABLE $table_name ( + id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, + user_id bigint(20) UNSIGNED NOT NULL, + post_id bigint(20) UNSIGNED NOT NULL, + PRIMARY KEY (id), + UNIQUE KEY user_post_id (user_id, post_id) + ) $charset_collate;"; + + require_once ABSPATH . "wp-admin/includes/upgrade.php"; + dbDelta($sql); + } + + public static function drop_favorites_table(): void + { + global $wpdb; + $table_name = $wpdb->prefix . "apiki_favorites"; + $wpdb->query("DROP TABLE IF EXISTS $table_name"); + } +} diff --git a/apiki-favorites/includes/class-apiki-favorites-rest-controller.php b/apiki-favorites/includes/class-apiki-favorites-rest-controller.php new file mode 100644 index 00000000..107573b3 --- /dev/null +++ b/apiki-favorites/includes/class-apiki-favorites-rest-controller.php @@ -0,0 +1,131 @@ +namespace, + "/" . $this->base . "/(?P\d+)", + [ + [ + "methods" => WP_REST_Server::CREATABLE, + "callback" => [$this, "add_favorite"], + "permission_callback" => [$this, "permission_check"], + "args" => [ + "post_id" => [ + "validate_callback" => function ($param, $request, $key) { + return is_numeric($param); + }, + ], + ], + ], + [ + "methods" => WP_REST_Server::DELETABLE, + "callback" => [$this, "remove_favorite"], + "permission_callback" => [$this, "permission_check"], + "args" => [ + "post_id" => [ + "validate_callback" => function ($param, $request, $key) { + return is_numeric($param); + }, + ], + ], + ], + ] + ); + } + + public function permission_check(WP_REST_Request $request): bool + { + return is_user_logged_in(); + } + + public function add_favorite(WP_REST_Request $request): WP_REST_Response + { + global $wpdb; + $user_id = get_current_user_id(); + $post_id = (int) $request["post_id"]; + + if (!get_post($post_id)) { + return new WP_REST_Response( + ["message" => "Post not found."], + 404 + ); + } + + $table_name = $wpdb->prefix . "apiki_favorites"; + + $data = [ + "user_id" => $user_id, + "post_id" => $post_id, + ]; + + $format = ["%d", "%d"]; + + $inserted = $wpdb->insert($table_name, $data, $format); + + if ($inserted === false) { + return new WP_REST_Response( + ["message" => "Error adding favorite or already favorited."], + 400 + ); + } + + return new WP_REST_Response( + ["message" => "Post favorited successfully."], + 200 + ); + } + + public function remove_favorite(WP_REST_Request $request): WP_REST_Response + { + global $wpdb; + $user_id = get_current_user_id(); + $post_id = (int) $request["post_id"]; + + $table_name = $wpdb->prefix . "apiki_favorites"; + + $deleted = $wpdb->delete( + $table_name, + [ + "user_id" => $user_id, + "post_id" => $post_id, + ], + ["%d", "%d"] + ); + + if ($deleted === false) { + return new WP_REST_Response( + ["message" => "Error removing favorite."], + 400 + ); + } + + if ($deleted === 0) { + return new WP_REST_Response( + ["message" => "Favorite not found to remove."], + 404 + ); + } + + return new WP_REST_Response( + ["message" => "Post unfavorited successfully."], + 200 + ); + } +}