Skip to content

Like / Heart Feature: Visual & Data Setup

Ringkasan

Video ini membahas cara menambahkan fitur Like/Heart pada halaman professor. Kita membuat Like Box HTML dengan ikon heart, mendaftarkan Like CPT (Custom Post Type), membuat ACF field untuk menyimpan professor ID, dan menggunakan WP_Query + meta_query untuk menampilkan jumlah likes secara dinamis.


1. Like Box HTML

File: single-professor.php

Tambahkan di atas blok konten professor (di dalam div two-thirds):

php
<?php
  // Query untuk hitung jumlah like
  $likeCount = new WP_Query(array(
    'post_type' => 'like',
    'meta_query' => array(
      array(
        'key' => 'liked_professor_id',
        'compare' => '=',
        'value' => get_the_ID()
      )
    )
  ));

  // Cek apakah user SAAT INI sudah like professor ini
  $existStatus = 'no';

  if (is_user_logged_in()) {
    $existQuery = new WP_Query(array(
      'author' => get_current_user_id(),
      'post_type' => 'like',
      'meta_query' => array(
        array(
          'key' => 'liked_professor_id',
          'compare' => '=',
          'value' => get_the_ID()
        )
      )
    ));

    if ($existQuery->found_posts) {
      $existStatus = 'yes';
    }
  }
?>

<span class="like-box" data-exists="<?php echo $existStatus; ?>" data-professor="<?php the_ID(); ?>" data-like="<?php if (isset($existQuery->posts[0]->ID)) echo $existQuery->posts[0]->ID; ?>">
  <i class="fa fa-heart-o" aria-hidden="true"></i>
  <i class="fa fa-heart" aria-hidden="true"></i>
  <span class="like-count"><?php echo $likeCount->found_posts; ?></span>
</span>

Penjelasan Elemen:

ElemenFungsi
fa-heart-oHeart outline (kosong) — ditampilkan saat belum like
fa-heartHeart solid (penuh) — ditampilkan saat sudah like
.like-countAngka total likes
data-exists"yes" atau "no" — apakah user saat ini sudah like
data-professorID professor di halaman ini
data-likeID post like milik user saat ini (jika ada)

Cara CSS Bekerja:

data-exists="yes"  →  Heart solid ditampilkan, heart outline disembunyikan
data-exists="no"   →  Heart outline ditampilkan, heart solid disembunyikan

CSS sudah disiapkan oleh instruktur yang memonitor atribut data-exists.


2. Like Custom Post Type

File: mu-plugins/university-post-types.php

php
// Like Post Type
register_post_type('like', array(
  'supports' => array('title'),
  'public' => false,
  'show_ui' => true,
  'labels' => array(
    'name' => 'Likes',
    'add_new_item' => 'Add New Like',
    'edit_item' => 'Edit Like',
    'all_items' => 'All Likes',
    'singular_name' => 'Like'
  ),
  'menu_icon' => 'dashicons-heart'
));

Perbedaan dari Note CPT:

AspekNoteLike
show_in_resttrue (pakai default REST API)Tidak ada (default false)
capability_type'note' + map_meta_capTidak ada (kita handle manual)
supports['title', 'editor']['title'] saja

Mengapa Like tidak pakai REST API default? Karena fitur like membutuhkan custom logic (1 like per user per professor, validasi professor ID). Default REST API tidak bisa enforce aturan ini.


3. ACF Field: Liked Professor ID

Buat di Dashboard → Custom Fields → Add New:

SettingNilai
Field GroupLiked Professor ID
Field LabelLiked Professor ID
Field Nameliked_professor_id (auto-generated)
Field TypeNumber
RequiredNo (penting! karena saat post pertama dibuat, field belum terisi)
LocationPost Type = Like

4. WP_Query dengan Meta Query

Konsep Meta Query:

php
$likeCount = new WP_Query(array(
  'post_type' => 'like',
  'meta_query' => array(      // Array of arrays
    array(                     // Inner array = satu filter
      'key' => 'liked_professor_id',    // Nama custom field
      'compare' => '=',                 // Operator perbandingan
      'value' => get_the_ID()           // Nilai yang dicari
    )
  )
));

Property found_posts:

php
echo $likeCount->found_posts;
// Output: 3 (misalnya ada 3 like untuk professor ini)
  • found_posts mengembalikan total absolute post yang match
  • Mengabaikan pagination (posts_per_page tidak berpengaruh)

5. Exist Query: Cek Apakah User Sudah Like

Pentingnya is_user_logged_in() Check:

php
$existStatus = 'no';

if (is_user_logged_in()) {
  $existQuery = new WP_Query(array(
    'author' => get_current_user_id(),  // Filter by current user
    'post_type' => 'like',
    'meta_query' => array(
      array(
        'key' => 'liked_professor_id',
        'compare' => '=',
        'value' => get_the_ID()
      )
    )
  ));

  if ($existQuery->found_posts) {
    $existStatus = 'yes';
  }
}

Masalah Tanpa is_user_logged_in():

Jika user tidak logged in → get_current_user_id() return 0'author' => 0 sama saja dengan tidak ada filter author → query mengembalikan SEMUA like → heart selalu solid (salah!)

Solusi isset() untuk data-like:

php
data-like="<?php if (isset($existQuery->posts[0]->ID)) echo $existQuery->posts[0]->ID; ?>"

Tanpa isset(), jika user belum like professor manapun, $existQuery->posts[0] tidak ada → PHP warning.