Membuat Permalink

Ahh.. lagi2 permalink, dulu pernah gw bahas beberapa kali diblog ini, cuman karena kejadian kemaren, banyak data yg ga bisa diselamatin, dan yahhh… kebetulan gw ada percobaan baru.

Masih tetep membuat ‘slug’, untuk permalink ini. caranya gimana biar si slug ini tetep unique. Kita ga boleh pake slug yang sama, harus beda dengn yg laen, tapi kalo ada yg udah pake, kita tambahin belakangnya ‘-2’ atau ‘-3’ dan selanjutnya.

function slug($text)
{
  $text = preg_replace('/[^a-z0-9-\/]/', '-', strtolower($text));
  $text = preg_replace('/-{2,}/', '-', $text);
  $text = trim($text, '-');
  return $text;
}

Misal gini: gw mau bikin postingan dengan judul ‘hello’, maka ntar permalinknya: ‘/post/hello’. si hello ini dari slug('hello').

Lalu bikin lagi postingan dengan judul yg tetep sama, slug harus menjadi ‘hello-2’, karena slug ‘hello’ sudah terpakai.

Nahh yang jadi masalah adalah setiap kita mau bikin slug. kita mesti cek apakah ‘hello’ sudah terpakai atau belum.

Caranya seperti ini, ketika kita akan menambahkan entry baru dengan title=hello, maka:

  1. bikin slug=slug(hello)
  2. cek database, apakah slug ‘hello’ sudah terpakai?
  3. jika sudah, ubah slug menjadi: slug=slug(‘hello $i’), dimana $i merupakan angka jumlah dari slug,misal 2, 3 atau 4. ulangi langkah 2, sampai slug ga ada yg pakai.

Terlihat sangar sederhana, tapi pada kenyataanya akan memakan resources yg lumayan gede (kalo slug hello sudah mencapai lebih dari ratusan). Karena kita akan selalu search ke database, cek ada atau tidak, lalu mencoba ganti slug, lalu search lagi, hal itu dilakukan sampe hello-x tidak terpakai.

Nah, tadi gw coba lagi, juga karena kebutuhan, gw test menjadi seperti ini:

function slug($string)
{
  global $adb;

  $query  = sprintf("SELECT * FROM tags WHERE slug REGEXP '^%s(-[[:digit:]])?'",
                    $adb->escape(_slug($string)));

  $result = $adb->get_results($query);
  $total  = sizeof($result);

  if ($result != null)
  {
    $numbers = array();
    $found   = false;

    foreach ($result as $r)
    {
      if ($r->slug == _slug($string))
        $found = true;

      if (preg_match('/-(\d+)$/i', $r->slug, $match))
        $numbers[] = $match[1];
    }

    if (sizeof($numbers) > 0)
      $string = "{$string}-".(max($numbers) + 1);

    elseif ($found)
      $string = "{$string} 2";

  }
  return _slug($string);
}

$adb ini merupakan instance dari `ezSQL_mysql <http://justinvincent.com/ezsql>`__, dan function _slug, adalah fungsi slug paling atas, lalu gw rename menjadi _slug

Dengan function gw yg baru itu, gw eprtama kali bakal ngecek ke database, entry mana yg ga sama slug dan namanya sama tand (dan slugnya) yg gw bikin mau tambahin. Jika tidak ada, ya pake slug baru.

Tapi jika ada, cek, apakah ada akhiran -x pada slug? jika ada. ambil nilai x terbesar, lalu tambah 1. Hasilnya, slug baru itu adalah: SLUG-(x+1), dimana x adalah 0 sampe n.

Hanya 1 kali cek database, gak perlu berulang-ulang.