From deb8a9b866694d53fa0e94294a844bfcff73a4b8 Mon Sep 17 00:00:00 2001 From: Lucas Felype Fonseca Santos Date: Mon, 6 Apr 2026 12:24:22 -0300 Subject: [PATCH] feat: Add To Like Plugin for favoriting posts via REST API --- .../to-like-plugin/includes/rest-routes.php | 168 +++++++++++++++++ wp-content/plugins/to-like-plugin/index.php | 2 + .../plugins/to-like-plugin/to-like-plugin.php | 171 ++++++++++++++++++ .../plugins/to-like-plugin/uninstall.php | 7 + 4 files changed, 348 insertions(+) create mode 100644 wp-content/plugins/to-like-plugin/includes/rest-routes.php create mode 100644 wp-content/plugins/to-like-plugin/index.php create mode 100644 wp-content/plugins/to-like-plugin/to-like-plugin.php create mode 100644 wp-content/plugins/to-like-plugin/uninstall.php diff --git a/wp-content/plugins/to-like-plugin/includes/rest-routes.php b/wp-content/plugins/to-like-plugin/includes/rest-routes.php new file mode 100644 index 00000000..72b5e8ba --- /dev/null +++ b/wp-content/plugins/to-like-plugin/includes/rest-routes.php @@ -0,0 +1,168 @@ + 'POST', + 'callback' => 'create_favorite', + 'permission_callback' => 'authentication_for_favorite', + ], + [ + 'methods' => 'GET', + 'callback' => 'list_favorites', + 'permission_callback' => 'authentication_for_favorite', + ], + [ + 'methods' => 'DELETE', + 'callback' => 'delete_favorite', + 'permission_callback' => 'authentication_for_favorite', + 'args' => [ + 'post_id' => [ + 'required' => true, + 'validate_callback' => function ($value) { + return is_numeric($value) && (int) $value > 0; + }, + ], + ], + ], + ]); +} + +add_action('rest_api_init', 'register_rest_routes'); + +/** + * Create a favorite for the authenticated user. + * + * @param WP_REST_Request $request Request instance. + * + * @return array|WP_Error + */ +function create_favorite(WP_REST_Request $request) +{ + $user_id = get_current_user_id(); + $post_id = (int) $request->get_param('post_id'); + + if (!$post_id) { + return new WP_Error( + 'tlp_missing_post_id', + 'post_id is required.', + ['status' => 400] + ); + } + + $post = get_post($post_id); + + if (!$post) { + return new WP_Error( + 'tlp_post_not_found', + 'Post not found.', + ['status' => 404] + ); + } + + $added = To_Like_Plugin::add_favorite($user_id, $post_id); + + if (!$added) { + return new WP_Error( + 'tlp_favorite_not_created', + 'Favorite already exists or could not be added.', + ['status' => 409] + ); + } + + return [ + 'success' => true, + 'message' => 'Favorite added successfully.', + 'data' => [ + 'user_id' => $user_id, + 'post_id' => $post_id, + ], + ]; +} + +/** + * List favorites for the authenticated user. + * + * @return array + */ +function list_favorites(): array +{ + $user_id = get_current_user_id(); + $favorites = To_Like_Plugin::get_user_favorites($user_id); + + return [ + 'success' => true, + 'data' => [ + 'user_id' => $user_id, + 'favorites' => $favorites, + ], + ]; +} + +/** + * Remove a favorite for the authenticated user. + * + * @param WP_REST_Request $request Request instance. + * + * @return array|WP_Error + */ +function delete_favorite(WP_REST_Request $request) +{ + $user_id = get_current_user_id(); + $post_id = (int) $request->get_param('post_id'); + + if (!$post_id) { + return new WP_Error( + 'tlp_missing_post_id', + 'post_id is required.', + ['status' => 400] + ); + } + + $post = get_post($post_id); + + if (!$post) { + return new WP_Error( + 'tlp_post_not_found', + 'Post not found.', + ['status' => 404] + ); + } + + $removed = To_Like_Plugin::remove_favorite($user_id, $post_id); + + if (!$removed) { + return new WP_Error( + 'tlp_favorite_not_removed', + 'Favorite not found or could not be removed.', + ['status' => 404] + ); + } + + return [ + 'success' => true, + 'message' => 'Favorite removed successfully.', + 'data' => [ + 'user_id' => $user_id, + 'post_id' => $post_id, + ], + ]; +} diff --git a/wp-content/plugins/to-like-plugin/index.php b/wp-content/plugins/to-like-plugin/index.php new file mode 100644 index 00000000..62200328 --- /dev/null +++ b/wp-content/plugins/to-like-plugin/index.php @@ -0,0 +1,2 @@ +create_favorites_table(); + } + + public function deactivate() + { + return; + } + + private function create_favorites_table() + { + global $wpdb; + + $table_name = self::get_table_name(); + + require_once ABSPATH . 'wp-admin/includes/upgrade.php'; + + $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, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (id), + UNIQUE KEY user_post_unique (user_id, post_id) + ) {$charset_collate};"; + + dbDelta($sql); + } + + private static function get_table_name() + { + global $wpdb; + + return $wpdb->prefix . 'user_favorite_challenge'; + } + + public static function add_favorite($user_id, $post_id) + { + if (self::favorite_exists($user_id, $post_id)) { + return false; + } + + global $wpdb; + + $table_name = self::get_table_name(); + + $inserted = $wpdb->insert( + $table_name, + [ + 'user_id' => $user_id, + 'post_id' => $post_id, + 'created_at' => current_time('mysql'), + ], + [ + '%d', + '%d', + '%s', + ] + ); + + return $inserted !== false; + } + + public static function favorite_exists($user_id, $post_id) + { + global $wpdb; + + $table_name = self::get_table_name(); + + $result = $wpdb->get_var( + $wpdb->prepare( + "SELECT id FROM {$table_name} WHERE user_id = %d AND post_id = %d", + $user_id, + $post_id + ) + ); + + return !is_null($result); + } + + public static function remove_favorite($user_id, $post_id) + { + if (!self::favorite_exists($user_id, $post_id)) { + return false; + } + + global $wpdb; + + $table_name = self::get_table_name(); + + $deleted = $wpdb->delete( + $table_name, + [ + 'user_id' => $user_id, + 'post_id' => $post_id, + ], + [ + '%d', + '%d', + ] + ); + + return $deleted !== false; + } + + public static function get_user_favorites($user_id) + { + global $wpdb; + + $table_name = self::get_table_name(); + + $results = $wpdb->get_results( + $wpdb->prepare( + "SELECT post_id, created_at FROM {$table_name} WHERE user_id = %d ORDER BY created_at DESC", + $user_id + ) + ); + + if (empty($results)) { + return []; + } + + $favorites = []; + + foreach ($results as $result) { + $post = get_post($result->post_id); + + if (!$post || 'publish' !== $post->post_status) { + continue; + } + + $favorites[] = [ + 'post_id' => $post->ID, + 'title' => get_the_title($post->ID), + 'link' => get_permalink($post->ID), + 'created_at' => $result->created_at, + ]; + } + + return $favorites; + } +} + +$to_like_plugin = new To_Like_Plugin(); + +register_activation_hook(TLP_PLUGIN_FILE, [$to_like_plugin, 'activate']); +register_deactivation_hook(TLP_PLUGIN_FILE, [$to_like_plugin, 'deactivate']); diff --git a/wp-content/plugins/to-like-plugin/uninstall.php b/wp-content/plugins/to-like-plugin/uninstall.php new file mode 100644 index 00000000..85f6e019 --- /dev/null +++ b/wp-content/plugins/to-like-plugin/uninstall.php @@ -0,0 +1,7 @@ +query("DROP TABLE IF EXISTS {$wpdb->prefix}user_favorite_challenge");