Skip to content

Word Filter Plugin: Form Handling & Finishing

Gambaran Umum

Video ini menyelesaikan Word Filter Plugin — membahas penanganan form submit manual (tanpa Settings API), keamanan nonce, dan logika penyaringan kata di konten post.


Catatan: isset() untuk Undefined Array Key

Penting (PHP 8+): PHP modern akan menampilkan warning "Undefined array key" jika kamu mengakses key $_POST yang tidak ada. Selalu gunakan isset() untuk mengecek terlebih dahulu.

php
// ❌ PHP 8 warning:
if ($_POST['justsubmitted'] == 'true') { ... }

// ✅ Aman:
if (isset($_POST['justsubmitted']) && $_POST['justsubmitted'] == 'true') { ... }

Manual Form Handling (Tanpa Settings API)

Untuk halaman utama Word Filter, Brad menggunakan penanganan form manual alih-alih Settings API:

HTML Form

php
function wordFilterPage() { ?>
  <div class="wrap">
    <h1>Word Filter</h1>
    <?php if (isset($_POST['justsubmitted']) && $_POST['justsubmitted'] == 'true') $this->handleForm(); ?>
    <form method="POST">
      <input type="hidden" name="justsubmitted" value="true">
      <?php wp_nonce_field('saveFilterWords', 'ourNonce'); ?>
      <label for="plugin_words_to_filter">
        <p>Enter a <strong>comma-separated</strong> list of words to filter from your site's content.</p>
      </label>
      <div class="word-filter__flex-container">
        <textarea name="plugin_words_to_filter" id="plugin_words_to_filter" placeholder="bad word one, bad word two, bad word three"><?php echo esc_textarea(get_option('plugin_words_to_filter')); ?></textarea>
      </div>
      <input type="submit" name="submit" id="submit" class="button button-primary" value="Save Changes">
    </form>
  </div>
<?php }

Elemen Penting dalam Form:

ElemenFungsi
<input type="hidden" name="justsubmitted" value="true">Penanda bahwa form baru di-submit
wp_nonce_field('saveFilterWords', 'ourNonce')Security nonce (mencegah CSRF)
esc_textarea(get_option(...))Sanitasi output untuk textarea

Handle Form Submit

php
function handleForm() {
  // 1. Verifikasi nonce (keamanan)
  if (
    wp_verify_nonce($_POST['ourNonce'], 'saveFilterWords') AND
    current_user_can('manage_options')
  ) {
    // 2. Simpan ke database
    update_option('plugin_words_to_filter', sanitize_text_field($_POST['plugin_words_to_filter']));
    ?>
    <div class="updated">
      <p>Your filtered words were saved.</p>
    </div>
    <?php
  } else {
    ?>
    <div class="error">
      <p>Sorry, you do not have permission to perform that action.</p>
    </div>
    <?php
  }
}

Langkah Keamanan:

  1. wp_verify_nonce() — Memverifikasi token nonce
    • Arg 1: Nilai nonce dari $_POST
    • Arg 2: Action name (harus sama dengan di wp_nonce_field())
  2. current_user_can('manage_options') — Pastikan user punya izin admin
  3. sanitize_text_field() — Sanitasi input sebelum simpan ke database
  4. update_option() — Simpan/update nilai di database WordPress

Halaman Options (sub-menu) menggunakan Settings API standar WordPress:

php
function optionsSubPage() { ?>
  <div class="wrap">
    <h1>Word Filter Options</h1>
    <form action="options.php" method="POST">
      <?php
        settings_errors();
        settings_fields('replacementFields');
        do_settings_sections('word-filter-options');
        submit_button();
      ?>
    </form>
  </div>
<?php }

settings_errors() — Perlu dipanggil secara manual untuk halaman yang BUKAN halaman utama Settings. Halaman di bawah menu "Settings" otomatis menampilkan error, tapi halaman custom menu tidak.


Finishing: Logika Penyaringan Kata

Filter Konten Post

php
function __construct() {
  // ... menu dan settings hooks
  add_filter('the_content', array($this, 'filterLogic'));
}

function filterLogic($content) {
  $badWords = get_option('plugin_words_to_filter');
  
  // Hanya filter jika ada kata yang didaftarkan
  if ($badWords) {
    // Konversi string comma-separated menjadi array
    $badWordsArray = explode(',', $badWords);
    
    // Bersihkan whitespace di setiap elemen
    $badWordsArray = array_map('trim', $badWordsArray);
    
    // Ganti kata dengan replacement (case-insensitive)
    $replacement = get_option('replacementText', '***');
    
    return str_ireplace($badWordsArray, $replacement, $content);
  }
  
  return $content;
}

Fungsi PHP yang Digunakan:

explode()

php
$badWordsArray = explode(',', 'bad, evil, ugly');
// Hasil: ['bad', ' evil', ' ugly']
  • Memecah string menjadi array berdasarkan delimiter (,)

array_map('trim', $array)

php
$badWordsArray = array_map('trim', $badWordsArray);
// Hasil: ['bad', 'evil', 'ugly']  ← whitespace dihapus
  • Menjalankan function trim() pada setiap elemen array
  • Menghapus spasi di awal dan akhir setiap kata

str_ireplace()

php
$filtered = str_ireplace($badWordsArray, '***', $content);
  • Case-insensitive string replace
  • Arg 1: Array kata yang akan diganti
  • Arg 2: Pengganti (misal: ***)
  • Arg 3: String sumber (konten post)

Perbedaan: Settings API vs Manual Form Handling

AspekSettings APIManual Handling
Form actionoptions.phpURL halaman sendiri (method POST)
PenyimpananOtomatis via register_setting()Manual via update_option()
KeamananOtomatis (nonce di settings_fields())Manual (wp_nonce_field() + wp_verify_nonce())
ValidasiVia sanitize_callbackManual dalam handler function
Error messagesOtomatisManual (add_settings_error() atau HTML)
Kapan digunakan?Form settings standarForm custom dengan logic kompleks

Dalam plugin Word Filter, Brad menggunakan keduanya: manual handling untuk halaman utama (Words List) dan Settings API untuk halaman Options (replacement text).


Alur Kerja Plugin Word Filter

1. Admin memasukkan kata-kata yang mau difilter (comma-separated)
   → "bad, evil, ugly"
   → Disimpan di database via update_option()

2. Admin mengatur replacement text di Options page
   → "***"
   → Disimpan via Settings API

3. Visitor membuka post
   → WordPress menjalankan filter 'the_content'
   → filterLogic() dipanggil:
     a. get_option('plugin_words_to_filter') → "bad, evil, ugly"
     b. explode(',', ...) → ['bad', ' evil', ' ugly']
     c. array_map('trim', ...) → ['bad', 'evil', 'ugly']
     d. str_ireplace(['bad','evil','ugly'], '***', $content)
   → Kata-kata terfilter diganti dengan "***"
   → Konten yang sudah bersih ditampilkan