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
19 changes: 19 additions & 0 deletions wp-content/plugins/favoritar-posts/favoritar-posts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
/*
Plugin Name: Favoritar Posts via REST API
Description: Permite que usuários logados favoritem posts usando a WP REST API.
Version: 1.0
Author: Napoleão Junio Soares Coelho
*/

if (!defined('ABSPATH')) {
exit;
}

require_once __DIR__ . '/includes/class-favoritos-repository.php';
require_once __DIR__ . '/includes/class-favoritos-rest-controller.php';
require_once __DIR__ . '/includes/class-favoritar-posts-plugin.php';

Favoritar_Posts_Plugin::init();
register_activation_hook(__FILE__, ['Favoritar_Posts_Plugin', 'activate']);
register_uninstall_hook(__FILE__, ['Favoritar_Posts_Plugin', 'uninstall']);
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

if (!defined('ABSPATH')) {
exit;
}

class Favoritar_Posts_Plugin
{
private static $instance;
private $repository;
private $rest_controller;

private function __construct()
{
global $wpdb;
$this->repository = new Favoritos_Repository($wpdb);
$this->rest_controller = new Favoritos_REST_Controller($this->repository);

add_action('rest_api_init', [$this->rest_controller, 'register_routes']);
}

public static function init()
{
if (null === self::$instance) {
self::$instance = new self();
}
}

public static function activate()
{
global $wpdb;
$repository = new Favoritos_Repository($wpdb);
$repository->create_table();
}

public static function uninstall()
{
global $wpdb;
$repository = new Favoritos_Repository($wpdb);
$repository->drop_table();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

if (!defined('ABSPATH')) {
exit;
}

class Favoritos_Repository
{
private $wpdb;
private $table;

public function __construct($wpdb)
{
$this->wpdb = $wpdb;
$this->table = $this->wpdb->prefix . 'user_favorites';
}

public function create_table()
{
$charset_collate = $this->wpdb->get_charset_collate();
$sql = "CREATE TABLE {$this->table} (
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 (user_id, post_id),
KEY post_id (post_id)
) {$charset_collate};";

require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta($sql);
}

public function drop_table()
{
$this->wpdb->query("DROP TABLE IF EXISTS {$this->table}");
}

public function toggle($user_id, $post_id)
{
$exists = (bool) $this->wpdb->get_var(
$this->wpdb->prepare(
"SELECT id FROM {$this->table} WHERE user_id = %d AND post_id = %d",
$user_id,
$post_id
)
);

if ($exists) {
$deleted = $this->wpdb->delete(
$this->table,
['user_id' => $user_id, 'post_id' => $post_id],
['%d', '%d']
);

if (false === $deleted) {
return new WP_Error('db_delete_error', 'Nao foi possivel remover o favorito.');
}

return 'removido';
}

$inserted = $this->wpdb->insert(
$this->table,
[
'user_id' => $user_id,
'post_id' => $post_id,
'created_at' => current_time('mysql'),
],
['%d', '%d', '%s']
);

if (false === $inserted) {
return new WP_Error('db_insert_error', 'Nao foi possivel favoritar o post.');
}

return 'adicionado';
}

public function get_user_favorite_ids($user_id)
{
$results = $this->wpdb->get_col(
$this->wpdb->prepare(
"SELECT post_id FROM {$this->table} WHERE user_id = %d ORDER BY created_at DESC",
$user_id
)
);

return array_map('intval', $results);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

if (!defined('ABSPATH')) {
exit;
}

class Favoritos_REST_Controller
{
private $namespace = 'favoritos/v1';
private $repository;

public function __construct(Favoritos_Repository $repository)
{
$this->repository = $repository;
}

public function register_routes()
{
register_rest_route($this->namespace, '/toggle/(?P<post_id>\d+)', [
'methods' => 'POST',
'callback' => [$this, 'handle_toggle'],
'permission_callback' => [$this, 'check_permissions'],
'args' => [
'post_id' => [
'validate_callback' => function ($param) {
return is_numeric($param) && $param > 0;
},
],
],
]);

register_rest_route($this->namespace, '/list', [
'methods' => 'GET',
'callback' => [$this, 'handle_list'],
'permission_callback' => [$this, 'check_permissions'],
]);
}

public function check_permissions()
{
return is_user_logged_in();
}

public function handle_toggle($request)
{
$user_id = get_current_user_id();
$post_id = (int) $request['post_id'];

$post = get_post($post_id);
if (!$post || 'publish' !== $post->post_status) {
return new WP_Error('invalid_post', 'Post invalido.', ['status' => 400]);
}

$status = $this->repository->toggle($user_id, $post_id);
if ($status instanceof WP_Error) {
return $status;
}

$favorites = $this->format_posts(
$this->repository->get_user_favorite_ids($user_id)
);

return rest_ensure_response([
'status' => $status,
'favoritos' => $favorites,
]);
}

public function handle_list($request)
{
$user_id = get_current_user_id();
$favorites = $this->format_posts(
$this->repository->get_user_favorite_ids($user_id)
);

return rest_ensure_response($favorites);
}

private function format_posts(array $ids)
{
if (empty($ids)) {
return [];
}

$posts = get_posts([
'post__in' => $ids,
'post_type' => 'post',
'post_status' => 'publish',
'orderby' => 'post__in',
'posts_per_page' => count($ids),
]);

return array_map(function ($post) {
return [
'ID' => $post->ID,
'title' => get_the_title($post),
'link' => get_permalink($post),
];
}, $posts);
}
}