diff --git a/admin/class-favorite-posts-admin.php b/admin/class-favorite-posts-admin.php
new file mode 100644
index 00000000..781b5b5d
--- /dev/null
+++ b/admin/class-favorite-posts-admin.php
@@ -0,0 +1,128 @@
+plugin_name = $plugin_name;
+ $this->version = $version;
+ $this->database = new Favorite_Posts_Database();
+ }
+
+ public function add_favorites_column( $columns ) {
+ $new_columns = array();
+ foreach ( $columns as $key => $value ) {
+ $new_columns[ $key ] = $value;
+ if ( 'title' === $key ) {
+ $new_columns['favorite_count'] = 'Favoritos';
+ }
+ }
+ return $new_columns;
+ }
+
+ public function display_favorites_column_content( $column, $post_id ) {
+ if ( 'favorite_count' === $column ) {
+ global $wpdb;
+ $table_name = $wpdb->prefix . 'favorite_posts';
+ $count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table_name} WHERE post_id = %d", $post_id ) );
+ echo $count;
+ }
+ }
+
+ public function register_favorites_sortable_column( $columns ) {
+ $columns['favorite_count'] = 'favorite_count_numeric';
+ return $columns;
+ }
+
+ public function custom_favorites_column_orderby( $query ) {
+ if ( ! is_admin() || ! $query->is_main_query() ) {
+ return;
+ }
+
+ $orderby = $query->get( 'orderby' );
+
+ if ( 'favorite_count_numeric' === $orderby ) {
+ global $wpdb;
+ $table_name = $wpdb->prefix . 'favorite_posts';
+ $query->set( 'orderby', "(SELECT COUNT(fp.post_id) FROM {$table_name} AS fp WHERE fp.post_id = {$wpdb->posts}.ID) " . $query->get( 'order' ) );
+ }
+ }
+
+ public function add_plugin_admin_menu() {
+ add_menu_page(
+ 'Posts Favoritos - Configurações',
+ 'Posts Favoritos',
+ 'manage_options',
+ $this->plugin_name . '_settings',
+ array( $this, 'display_plugin_setup_page' ),
+ 'dashicons-star-filled',
+ 60
+ );
+ }
+
+ public function display_plugin_setup_page() {
+ ?>
+
+
Posts Favoritos - Configurações
+
+
Como usar o botão de Favoritar
+
Para exibir o botão "Favoritar" em qualquer lugar do seu site, utilize o shortcode [favorite_button].
+
+
Opções do Shortcode:
+
+ [favorite_button] : Insira este shortcode no conteúdo de qualquer post, página ou Custom Post Type (CPT). Ele exibirá o botão de favoritar para o item que está sendo visualizado no momento.
+ [favorite_button post_id="ID_DO_POST"] : Use esta variação se você quiser que o botão favorite um post específico, independentemente de onde o shortcode está sendo usado. Substitua ID_DO_POST pelo número do ID do post que deseja favoritar.
+
+
+
O botão só será exibido para usuários logados.
+
+ plugin_name . '-deactivation-modal',
+ plugin_dir_url( __FILE__ ) . '../public/js/favorite-posts-admin-deactivate-modal.js',
+ array( 'jquery', 'sweetalert2' ),
+ $this->version,
+ true
+ );
+
+ wp_localize_script(
+ $this->plugin_name . '-deactivation-modal',
+ 'favoritePostsDeactivationData',
+ array(
+ 'plugin_slug' => $this->plugin_name,
+ 'modal_title' => 'Desativar Posts Favoritos?',
+ 'modal_text' => 'Você deseja manter os dados de posts favoritos no banco de dados?',
+ 'confirm_text' => 'Sim, manter dados',
+ 'cancel_text' => 'Não, excluir tudo',
+ 'deny_text' => 'Cancelar desativação',
+ 'keep_data_value' => 'no',
+ 'delete_data_value' => 'yes',
+ 'is_rtl' => is_rtl(),
+ )
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/favorite-posts.php b/favorite-posts.php
new file mode 100644
index 00000000..5ce72b30
--- /dev/null
+++ b/favorite-posts.php
@@ -0,0 +1,29 @@
+run();
+}
+run_favorite_posts();
\ No newline at end of file
diff --git a/includes/class-favorite-posts-activator.php b/includes/class-favorite-posts-activator.php
new file mode 100644
index 00000000..c3f86b0c
--- /dev/null
+++ b/includes/class-favorite-posts-activator.php
@@ -0,0 +1,26 @@
+prefix . 'favorite_posts';
+ $charset_collate = $wpdb->get_charset_collate();
+
+ $sql = "CREATE TABLE $table_name (
+ id bigint(20) NOT NULL AUTO_INCREMENT,
+ user_id bigint(20) NOT NULL,
+ post_id bigint(20) NOT NULL,
+ favorited_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ PRIMARY KEY (id),
+ UNIQUE KEY user_post_pair (user_id,post_id)
+ ) $charset_collate;";
+
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
+ dbDelta( $sql );
+
+ if ( get_option( 'favorite_posts_delete_data_on_uninstall' ) === false ) {
+ add_option( 'favorite_posts_delete_data_on_uninstall', 'no' );
+ }
+ }
+}
\ No newline at end of file
diff --git a/includes/class-favorite-posts-database.php b/includes/class-favorite-posts-database.php
new file mode 100644
index 00000000..c2dfdb59
--- /dev/null
+++ b/includes/class-favorite-posts-database.php
@@ -0,0 +1,108 @@
+table_name = $wpdb->prefix . 'favorite_posts';
+ $this->charset_collate = $wpdb->get_charset_collate();
+ }
+
+ public function create_table() {
+ if ( $this->table_exists() ) {
+ return;
+ }
+
+ $sql = "CREATE TABLE {$this->table_name} (
+ id bigint(20) NOT NULL AUTO_INCREMENT,
+ user_id bigint(20) NOT NULL,
+ post_id bigint(20) NOT NULL,
+ favorited_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ PRIMARY KEY (id),
+ UNIQUE KEY user_post_id (user_id,post_id)
+ ) {$this->charset_collate};";
+
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
+ dbDelta( $sql );
+ }
+
+ public function delete_table() {
+ global $wpdb;
+ $wpdb->query( "DROP TABLE IF EXISTS {$this->table_name}" );
+ }
+
+ private function table_exists() {
+ global $wpdb;
+ return $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $this->table_name ) ) === $this->table_name;
+ }
+
+ public function add_favorite( $user_id, $post_id ) {
+ global $wpdb;
+ $wpdb->insert(
+ $this->table_name,
+ array(
+ 'user_id' => $user_id,
+ 'post_id' => $post_id,
+ 'favorited_at' => current_time( 'mysql' ),
+ ),
+ array(
+ '%d',
+ '%d',
+ '%s',
+ )
+ );
+ return $wpdb->insert_id;
+ }
+
+ public function remove_favorite( $user_id, $post_id ) {
+ global $wpdb;
+ return $wpdb->delete(
+ $this->table_name,
+ array(
+ 'user_id' => $user_id,
+ 'post_id' => $post_id,
+ ),
+ array(
+ '%d',
+ '%d',
+ )
+ );
+ }
+
+ public function is_favorited( $user_id, $post_id ) {
+ global $wpdb;
+ $count = $wpdb->get_var(
+ $wpdb->prepare(
+ "SELECT COUNT(*) FROM {$this->table_name} WHERE user_id = %d AND post_id = %d",
+ $user_id,
+ $post_id
+ )
+ );
+ return (bool) $count;
+ }
+
+ public function get_favorite_count( $post_id ) {
+ global $wpdb;
+ $count = $wpdb->get_var(
+ $wpdb->prepare(
+ "SELECT COUNT(*) FROM {$this->table_name} WHERE post_id = %d",
+ $post_id
+ )
+ );
+ return (int) $count;
+ }
+
+ public function get_user_favorites( $user_id ) {
+ global $wpdb;
+ $results = $wpdb->get_col(
+ $wpdb->prepare(
+ "SELECT post_id FROM {$this->table_name} WHERE user_id = %d",
+ $user_id
+ )
+ );
+ return array_map( 'absint', $results );
+ }
+}
\ No newline at end of file
diff --git a/includes/class-favorite-posts-deactivator.php b/includes/class-favorite-posts-deactivator.php
new file mode 100644
index 00000000..e9d593b3
--- /dev/null
+++ b/includes/class-favorite-posts-deactivator.php
@@ -0,0 +1,14 @@
+delete_table();
+ }
+ }
+}
\ No newline at end of file
diff --git a/includes/class-favorite-posts-loader.php b/includes/class-favorite-posts-loader.php
new file mode 100644
index 00000000..7bd06f20
--- /dev/null
+++ b/includes/class-favorite-posts-loader.php
@@ -0,0 +1,41 @@
+actions = array();
+ $this->filters = array();
+ }
+
+ public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
+ $this->actions = $this->add( $this->actions, $hook, $component, $callback, $priority, $accepted_args );
+ }
+
+ public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) {
+ $this->filters = $this->add( $this->filters, $hook, $component, $callback, $priority, $accepted_args );
+ }
+
+ private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) {
+ $hooks[] = array(
+ 'hook' => $hook,
+ 'component' => $component,
+ 'callback' => $callback,
+ 'priority' => $priority,
+ 'accepted_args' => $accepted_args
+ );
+ return $hooks;
+ }
+
+ public function run() {
+ foreach ( $this->filters as $hook ) {
+ add_filter( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
+ }
+
+ foreach ( $this->actions as $hook ) {
+ add_action( $hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args'] );
+ }
+ }
+}
\ No newline at end of file
diff --git a/includes/class-favorite-posts-public.php b/includes/class-favorite-posts-public.php
new file mode 100644
index 00000000..dcb15201
--- /dev/null
+++ b/includes/class-favorite-posts-public.php
@@ -0,0 +1,120 @@
+plugin_name = $plugin_name;
+ $this->version = $version;
+ }
+
+ public function enqueue_scripts() {
+ wp_enqueue_style(
+ 'sweetalert2',
+ 'https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css',
+ array(),
+ '11.0.0',
+ 'all'
+ );
+
+ wp_enqueue_script(
+ 'sweetalert2',
+ 'https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.all.min.js',
+ array(),
+ '11.0.0',
+ true
+ );
+
+ wp_enqueue_style(
+ 'font-awesome-free',
+ 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css',
+ array(),
+ '6.5.2',
+ 'all'
+ );
+
+ wp_enqueue_style(
+ $this->plugin_name,
+ plugin_dir_url( __FILE__ ) . '../public/css/favorite-posts-public.css',
+ array(),
+ $this->version,
+ 'all'
+ );
+
+ wp_enqueue_script(
+ $this->plugin_name,
+ plugin_dir_url( __FILE__ ) . '../public/js/favorite-posts-public.js',
+ array( 'jquery', 'sweetalert2' ),
+ $this->version,
+ true
+ );
+
+ wp_localize_script(
+ $this->plugin_name,
+ 'favoritePostsData',
+ array(
+ 'root' => esc_url_raw( rest_url() ),
+ 'nonce' => wp_create_nonce( 'wp_rest' ),
+ 'namespace' => 'favorite-posts/v1',
+ 'is_user_logged_in' => is_user_logged_in(),
+ 'i18n' => array(
+ 'favorite' => 'Favoritar',
+ 'unfavorite' => 'Desfavoritar',
+ 'success_title' => 'Sucesso!',
+ 'error_title' => 'Erro!',
+ 'confirm_button' => 'Ok',
+ 'login_required_title' => 'Atenção!',
+ 'login_required_text' => 'Para favoritar posts, você precisa estar logado. Que tal criar uma conta ou fazer login agora?', // Nova string
+ ),
+ )
+ );
+ }
+
+ public function register_favorite_button_shortcode() {
+ add_shortcode( 'favorite_button', array( $this, 'favorite_button_shortcode' ) );
+ }
+
+ public function favorite_button_shortcode( $atts ) {
+ global $post;
+
+ $atts = shortcode_atts( array(
+ 'post_id' => 0,
+ ), $atts, 'favorite_button' );
+
+ $post_id = (int) $atts['post_id'];
+
+ if ( $post_id === 0 && is_singular() && isset( $post->ID ) ) {
+ $post_id = $post->ID;
+ }
+
+ if ( $post_id === 0 ) {
+ return '';
+ }
+
+ $is_logged_in = is_user_logged_in();
+ $button_classes = 'favorite-post-button';
+ $wrapper_classes = 'favorite-post-wrapper';
+ $data_attributes = 'data-post-id="' . esc_attr( $post_id ) . '"';
+
+ if ( ! $is_logged_in ) {
+ $button_classes .= ' is-logged-out';
+ $wrapper_classes .= ' is-logged-out-wrapper';
+ }
+
+ ob_start();
+ ?>
+
+ >
+
+
+
+
+ Faça login para favoritar!
+
+
+ database = $database;
+ }
+
+ public function register_routes() {
+ register_rest_route( $this->namespace, '/favorite/(?P\d+)', array(
+ 'methods' => WP_REST_Server::CREATABLE,
+ 'callback' => array( $this, 'favorite_post' ),
+ 'permission_callback' => array( $this, 'user_logged_in_permission' ),
+ 'args' => array(
+ 'post_id' => array(
+ 'validate_callback' => function( $param, $request, $key ) {
+ return is_numeric( $param ) && get_post_status( (int) $param );
+ },
+ ),
+ ),
+ ) );
+
+ register_rest_route( $this->namespace, '/unfavorite/(?P\d+)', array(
+ 'methods' => WP_REST_Server::DELETABLE,
+ 'callback' => array( $this, 'unfavorite_post' ),
+ 'permission_callback' => array( $this, 'user_logged_in_permission' ),
+ 'args' => array(
+ 'post_id' => array(
+ 'validate_callback' => function( $param, $request, $key ) {
+ return is_numeric( $param ) && get_post_status( (int) $param );
+ },
+ ),
+ ),
+ ) );
+
+ register_rest_route( $this->namespace, '/is-favorited/(?P\d+)', array(
+ 'methods' => WP_REST_Server::READABLE,
+ 'callback' => array( $this, 'is_post_favorited' ),
+ 'permission_callback' => array( $this, 'user_logged_in_permission' ),
+ 'args' => array(
+ 'post_id' => array(
+ 'validate_callback' => function( $param, $request, $key ) {
+ return is_numeric( $param ) && get_post_status( (int) $param );
+ },
+ ),
+ ),
+ ) );
+
+ register_rest_route( $this->namespace, '/favorites', array(
+ 'methods' => WP_REST_Server::READABLE,
+ 'callback' => array( $this, 'get_user_favorites' ),
+ 'permission_callback' => array( $this, 'user_logged_in_permission' ),
+ ) );
+ }
+
+ public function favorite_post( WP_REST_Request $request ) {
+ $post_id = (int) $request['post_id'];
+ $user_id = get_current_user_id();
+
+ if ( $this->database->is_favorited( $user_id, $post_id ) ) {
+ return new WP_REST_Response( array( 'message' => 'Post já favoritado.', 'favorited' => true ), 200 );
+ }
+
+ $result = $this->database->add_favorite( $user_id, $post_id );
+
+ if ( $result ) {
+ return new WP_REST_Response( array( 'message' => 'Post favoritado com sucesso.', 'favorited' => true, 'post_id' => $post_id ), 200 );
+ } else {
+ return new WP_Error( 'favorite_failed', 'Não foi possível favoritar o post.', array( 'status' => 500 ) );
+ }
+ }
+
+ public function unfavorite_post( WP_REST_Request $request ) {
+ $post_id = (int) $request['post_id'];
+ $user_id = get_current_user_id();
+
+ if ( ! $this->database->is_favorited( $user_id, $post_id ) ) {
+ return new WP_REST_Response( array( 'message' => 'Post não está favoritado.', 'favorited' => false ), 200 );
+ }
+
+ $result = $this->database->remove_favorite( $user_id, $post_id );
+
+ if ( $result ) {
+ return new WP_REST_Response( array( 'message' => 'Post desfavoritado com sucesso.', 'favorited' => false, 'post_id' => $post_id ), 200 );
+ } else {
+ return new WP_Error( 'unfavorite_failed', 'Não foi possível desfavoritar o post.', array( 'status' => 500 ) );
+ }
+ }
+
+ public function is_post_favorited( WP_REST_Request $request ) {
+ $post_id = (int) $request['post_id'];
+ $user_id = get_current_user_id();
+
+ $is_favorited = $this->database->is_favorited( $user_id, $post_id );
+
+ return new WP_REST_Response( array( 'is_favorited' => $is_favorited ), 200 );
+ }
+
+ public function get_user_favorites( WP_REST_Request $request ) {
+ $user_id = get_current_user_id();
+ $favorite_post_ids = $this->database->get_user_favorites( $user_id );
+
+ $favorited_posts_data = array();
+ if ( ! empty( $favorite_post_ids ) ) {
+ $args = array(
+ 'post_type' => 'post',
+ 'post__in' => $favorite_post_ids,
+ 'posts_per_page' => -1,
+ 'orderby' => 'post__in',
+ 'fields' => 'ids',
+ );
+ $query = new WP_Query( $args );
+
+ if ( $query->have_posts() ) {
+ foreach ( $query->posts as $post_id ) {
+ $post = WP_Post::get_instance( $post_id );
+ if ( $post ) {
+ $favorited_posts_data[] = array(
+ 'id' => $post->ID,
+ 'title' => $post->post_title,
+ 'link' => get_permalink( $post->ID ),
+ 'date' => $post->post_date,
+ );
+ }
+ }
+ }
+ wp_reset_postdata();
+ }
+
+ return new WP_REST_Response( array( 'favorites' => $favorited_posts_data ), 200 );
+ }
+
+ public function user_logged_in_permission( WP_REST_Request $request ) {
+ return is_user_logged_in();
+ }
+}
\ No newline at end of file
diff --git a/includes/class-favorite-posts.php b/includes/class-favorite-posts.php
new file mode 100644
index 00000000..0881f67e
--- /dev/null
+++ b/includes/class-favorite-posts.php
@@ -0,0 +1,75 @@
+plugin_name = 'favorite-posts';
+ $this->version = '1.0.0';
+
+ $this->load_dependencies();
+ $this->define_admin_hooks();
+ $this->define_public_hooks();
+ $this->define_rest_api_hooks();
+ }
+
+ private function load_dependencies() {
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-favorite-posts-loader.php';
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-favorite-posts-database.php';
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-favorite-posts-rest-controller.php';
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-favorite-posts-public.php';
+ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'admin/class-favorite-posts-admin.php';
+
+ $this->loader = new Favorite_Posts_Loader();
+ }
+
+ private function define_admin_hooks() {
+ $plugin_admin = new Favorite_Posts_Admin( $this->get_plugin_name(), $this->get_version() );
+
+ $post_types = get_post_types( array( 'public' => true ), 'names' );
+ foreach ( $post_types as $post_type ) {
+ if ( in_array( $post_type, array( 'attachment', 'revision', 'nav_menu_item', 'custom_css', 'customize_changeset' ) ) ) {
+ continue;
+ }
+ $this->loader->add_filter( "manage_{$post_type}_posts_columns", $plugin_admin, 'add_favorites_column' );
+ $this->loader->add_action( "manage_{$post_type}_posts_custom_column", $plugin_admin, 'display_favorites_column_content', 10, 2 );
+ $this->loader->add_filter( "manage_edit-{$post_type}_sortable_columns", $plugin_admin, 'register_favorites_sortable_column' );
+ $this->loader->add_action( 'pre_get_posts', $plugin_admin, 'custom_favorites_column_orderby' );
+ }
+
+ $this->loader->add_action( 'admin_menu', $plugin_admin, 'add_plugin_admin_menu' );
+
+ $this->loader->add_action( 'admin_enqueue_scripts', $plugin_admin, 'enqueue_deactivation_modal_scripts' );
+ }
+
+ private function define_public_hooks() {
+ $plugin_public = new Favorite_Posts_Public( $this->get_plugin_name(), $this->get_version() );
+ $this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' );
+ $this->loader->add_action( 'init', $plugin_public, 'register_favorite_button_shortcode' );
+ }
+
+ private function define_rest_api_hooks() {
+ $database = new Favorite_Posts_Database();
+ $rest_controller = new Favorite_Posts_REST_Controller( $database );
+ $this->loader->add_action( 'rest_api_init', $rest_controller, 'register_routes' );
+ }
+
+ public function run() {
+ $this->loader->run();
+ }
+
+ public function get_plugin_name() {
+ return $this->plugin_name;
+ }
+
+ public function get_loader() {
+ return $this->loader;
+ }
+
+ public function get_version() {
+ return $this->version;
+ }
+}
\ No newline at end of file
diff --git a/public/css/favorite-posts-public.css b/public/css/favorite-posts-public.css
new file mode 100644
index 00000000..5c71918f
--- /dev/null
+++ b/public/css/favorite-posts-public.css
@@ -0,0 +1,45 @@
+.favorite-post-wrapper {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ margin-left: 10px;
+}
+
+.favorite-post-button {
+ background: none;
+ border: none;
+ cursor: pointer;
+ font-size: 1.5em;
+ padding: 0;
+ line-height: 1;
+ color: #ccc;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.favorite-post-button.is-logged-out {
+ opacity: 0.7;
+ cursor: help;
+}
+
+.favorite-post-button .favorite-icon-outline,
+.favorite-post-button .favorite-icon-filled {
+ display: none;
+ line-height: 1;
+}
+
+.favorite-post-button:not(.is-favorited) .favorite-icon-outline {
+ display: inline-block;
+}
+
+.favorite-post-button.is-favorited .favorite-icon-filled {
+ display: inline-block;
+ color: #e74c3c;
+}
+
+.favorite-login-message {
+ font-size: 0.9em;
+ color: #555;
+ white-space: nowrap;
+}
\ No newline at end of file
diff --git a/public/js/favorite-posts-admin-deactivate-modal.js b/public/js/favorite-posts-admin-deactivate-modal.js
new file mode 100644
index 00000000..9f4de181
--- /dev/null
+++ b/public/js/favorite-posts-admin-deactivate-modal.js
@@ -0,0 +1,38 @@
+jQuery(document).ready(function($) {
+ const data = window.favoritePostsDeactivationData;
+
+ if (!data || !data.plugin_slug) {
+ return;
+ }
+
+ const deactivateLink = $(`tr[data-slug="${data.plugin_slug}"] .deactivate a`);
+
+ if (deactivateLink.length === 0) {
+ return;
+ }
+
+ const originalDeactivateUrl = deactivateLink.attr('href');
+
+ deactivateLink.on('click', function(e) {
+ e.preventDefault();
+
+ Swal.fire({
+ title: data.modal_title,
+ text: data.modal_text,
+ icon: 'question',
+ showDenyButton: true,
+ showCancelButton: true,
+ confirmButtonText: data.confirm_text,
+ cancelButtonText: data.cancel_text,
+ denyButtonText: data.deny_text,
+ reverseButtons: data.is_rtl
+ }).then((result) => {
+ if (result.isConfirmed) {
+ window.location.href = originalDeactivateUrl + '&_favorite_posts_delete_data=' + data.keep_data_value;
+ } else if (result.isDismissed && result.dismiss === Swal.DismissReason.cancel) {
+ window.location.href = originalDeactivateUrl + '&_favorite_posts_delete_data=' + data.delete_data_value;
+ } else if (result.isDenied) {
+ }
+ });
+ });
+});
\ No newline at end of file
diff --git a/public/js/favorite-posts-public.js b/public/js/favorite-posts-public.js
new file mode 100644
index 00000000..81ad37ed
--- /dev/null
+++ b/public/js/favorite-posts-public.js
@@ -0,0 +1,145 @@
+jQuery(document).ready(function($) {
+ const favoritePostsData = window.favoritePostsData;
+
+ if (!favoritePostsData || !favoritePostsData.root || !favoritePostsData.nonce || !favoritePostsData.namespace) {
+ console.error('Dados do plugin Favorite Posts não inicializados corretamente.');
+ return;
+ }
+
+ const restRoot = favoritePostsData.root;
+ const restNonce = favoritePostsData.nonce;
+ const namespace = favoritePostsData.namespace;
+ const isUserLoggedIn = favoritePostsData.is_user_logged_in;
+ const i18n = favoritePostsData.i18n;
+
+ function updateButtonState($button, isFavorited) {
+ const $outlineIcon = $button.find('.favorite-icon-outline');
+ const $filledIcon = $button.find('.favorite-icon-filled');
+
+ if (isFavorited) {
+ $button.addClass('is-favorited');
+ $outlineIcon.hide();
+ $filledIcon.show();
+ } else {
+ $button.removeClass('is-favorited');
+ $outlineIcon.show();
+ $filledIcon.hide();
+ }
+ }
+
+ function checkFavoriteStatus(postId, $button) {
+ if (!isUserLoggedIn) {
+ updateButtonState($button, false);
+ return;
+ }
+
+ $.ajax({
+ url: `${restRoot}${namespace}/is-favorited/${postId}`,
+ method: 'GET',
+ beforeSend: function(xhr) {
+ xhr.setRequestHeader('X-WP-Nonce', restNonce);
+ },
+ success: function(response) {
+ updateButtonState($button, response.is_favorited);
+ },
+ error: function(jqXHR, textStatus, errorThrown) {
+ console.error('Erro ao verificar status de favorito:', textStatus, errorThrown, jqXHR.responseJSON);
+ Swal.fire({
+ icon: 'error',
+ title: i18n.error_title,
+ text: 'Não foi possível verificar o status de favorito.',
+ confirmButtonText: i18n.confirm_button
+ });
+ }
+ });
+ }
+
+ $('.favorite-post-button').each(function() {
+ const $this = $(this);
+ const postId = $this.data('post-id');
+ if (postId) {
+ checkFavoriteStatus(postId, $this);
+ }
+ });
+
+ $(document).on('click', '.favorite-post-button', function(e) {
+ e.preventDefault();
+ const $button = $(this);
+ const postId = $button.data('post-id');
+
+ if (!isUserLoggedIn) {
+ Swal.fire({
+ icon: 'info',
+ title: i18n.login_required_title,
+ text: i18n.login_required_text,
+ confirmButtonText: i18n.confirm_button
+ });
+ return;
+ }
+
+ if (!postId) {
+ console.error('ID do post não disponível.');
+ Swal.fire({
+ icon: 'error',
+ title: i18n.error_title,
+ text: 'ID do post não encontrado.',
+ confirmButtonText: i18n.confirm_button
+ });
+ return;
+ }
+
+ let method;
+ let endpoint;
+ let successMessage;
+
+ if ($button.hasClass('is-favorited')) {
+ method = 'DELETE';
+ endpoint = `${restRoot}${namespace}/unfavorite/${postId}`;
+ successMessage = 'Post desfavoritado com sucesso!';
+ } else {
+ method = 'POST';
+ endpoint = `${restRoot}${namespace}/favorite/${postId}`;
+ successMessage = 'Post favoritado com sucesso!';
+ }
+
+ $.ajax({
+ url: endpoint,
+ method: method,
+ beforeSend: function(xhr) {
+ xhr.setRequestHeader('X-WP-Nonce', restNonce);
+ $button.prop('disabled', true);
+ },
+ success: function(response) {
+ if (response.favorited !== undefined) {
+ updateButtonState($button, response.favorited);
+ }
+ Swal.fire({
+ icon: 'success',
+ title: i18n.success_title,
+ text: response.message || successMessage,
+ showConfirmButton: false,
+ timer: 1500
+ });
+ },
+ error: function(jqXHR, textStatus, errorThrown) {
+ console.error('API Error:', textStatus, errorThrown, jqXHR.responseJSON);
+ let errorMessage = i18n.error_title;
+ if (jqXHR.responseJSON && jqXHR.responseJSON.message) {
+ errorMessage = jqXHR.responseJSON.message;
+ } else if (textStatus) {
+ errorMessage = `Erro: ${textStatus}`;
+ }
+
+ Swal.fire({
+ icon: 'error',
+ title: i18n.error_title,
+ text: errorMessage,
+ confirmButtonText: i18n.confirm_button
+ });
+ },
+ complete: function() {
+ $button.prop('disabled', false);
+ }
+ });
+ });
+});
\ No newline at end of file