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
128 changes: 128 additions & 0 deletions admin/class-favorite-posts-admin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php

class Favorite_Posts_Admin {

private $plugin_name;
private $version;
private $database;

public function __construct( $plugin_name, $version ) {
$this->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() {
?>
<div class="wrap">
<h1>Posts Favoritos - Configurações</h1>

<h2>Como usar o botão de Favoritar</h2>
<p>Para exibir o botão "Favoritar" em qualquer lugar do seu site, utilize o shortcode <code>[favorite_button]</code>.</p>

<h3>Opções do Shortcode:</h3>
<ul>
<li><strong><code>[favorite_button]</code></strong>: 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.</li>
<li><strong><code>[favorite_button post_id="ID_DO_POST"]</code></strong>: 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 <code>ID_DO_POST</code> pelo número do ID do post que deseja favoritar.</li>
</ul>

<p>O botão só será exibido para usuários logados.</p>
</div>
<?php
}

public function enqueue_deactivation_modal_scripts( $hook_suffix ) {
if ( 'plugins.php' === $hook_suffix ) {
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_script(
$this->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(),
)
);
}
}
}
29 changes: 29 additions & 0 deletions favorite-posts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
/**
* Plugin Name: Favorite Posts
* Plugin URI: https://apiki.com/desafio-favorite-posts/
* Description: Permite que usuários logados favoritem posts utilizando a WP REST API.
* Version: 1.0.0
* Author: Marcelo Tomaz
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
* Text Domain: favorite-posts
*/

if ( ! defined( 'WPINC' ) ) {
die;
}

require_once plugin_dir_path( __FILE__ ) . 'includes/class-favorite-posts-activator.php';
register_activation_hook( __FILE__, array( 'Favorite_Posts_Activator', 'activate' ) );

require_once plugin_dir_path( __FILE__ ) . 'includes/class-favorite-posts-deactivator.php';
register_deactivation_hook( __FILE__, array( 'Favorite_Posts_Deactivator', 'deactivate' ) );

require_once plugin_dir_path( __FILE__ ) . 'includes/class-favorite-posts.php';

function run_favorite_posts() {
$plugin = new Favorite_Posts();
$plugin->run();
}
run_favorite_posts();
26 changes: 26 additions & 0 deletions includes/class-favorite-posts-activator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

class Favorite_Posts_Activator {

public static function activate() {
global $wpdb;
$table_name = $wpdb->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' );
}
}
}
108 changes: 108 additions & 0 deletions includes/class-favorite-posts-database.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

class Favorite_Posts_Database {

private $table_name;
private $charset_collate;

public function __construct() {
global $wpdb;
$this->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 );
}
}
14 changes: 14 additions & 0 deletions includes/class-favorite-posts-deactivator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

class Favorite_Posts_Deactivator {

public static function deactivate() {
$delete_data = isset( $_GET['_favorite_posts_delete_data'] ) ? sanitize_text_field( wp_unslash( $_GET['_favorite_posts_delete_data'] ) ) : 'no';

if ( 'yes' === $delete_data ) {
require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-favorite-posts-database.php';
$database = new Favorite_Posts_Database();
$database->delete_table();
}
}
}
41 changes: 41 additions & 0 deletions includes/class-favorite-posts-loader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

class Favorite_Posts_Loader {

protected $actions;
protected $filters;

public function __construct() {
$this->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'] );
}
}
}
Loading