Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions wp-content/plugins/to-like-plugin/includes/rest-routes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
<?php

defined('ABSPATH') || exit;

/**
* Check if the current user is authenticated.
*
* @return bool
*/
function authentication_for_favorite(): bool
{
return is_user_logged_in();
}

/**
* Register plugin REST routes.
*
* @return void
*/
function register_rest_routes(): void
{
register_rest_route('to-like-plugin/v1', '/favorites', [
[
'methods' => '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,
],
];
}
2 changes: 2 additions & 0 deletions wp-content/plugins/to-like-plugin/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?php
// Silence is golden.
171 changes: 171 additions & 0 deletions wp-content/plugins/to-like-plugin/to-like-plugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<?php
/**
* Plugin Name: To Like Plugin
* Description: WordPress plugin that allows authenticated users to favorite and unfavorite posts via the REST API, with data persistence in a custom table.
* Author: Lucas Felype Fonseca Santos
* Text Domain: to-like-plugin
* Domain Path: /languages
* Version: 0.1.0
*
* @package To_Like_Plugin
*/

defined('ABSPATH') || exit;

define('TLP_PLUGIN_FILE', __FILE__);

require_once plugin_dir_path(__FILE__) . 'includes/rest-routes.php';


class To_Like_Plugin
{
public function activate()
{
$this->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']);
7 changes: 7 additions & 0 deletions wp-content/plugins/to-like-plugin/uninstall.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

if (!defined('WP_UNINSTALL_PLUGIN')) {
exit;
}
global $wpdb;
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}user_favorite_challenge");