Skip navigation


Salah satu aplikasi yang sedang saya kembangkan menggunakan username vanity URL. Maksudnya adalah pada setiap pengguna akan mempunyai sebuah link yakni username pengguna yang ditempelkan pada domain. Contohnya adalah seperti twitter. URL twitter saya adalah http://www.twitter.com/petrabarus. Pada URL tersebut username saya petrabarus ditambahkan pada domain twitter.com. Sekarang kita ingin membuat sebuah aplikasi yang dapat mengakses user saya petrabarus dengan alamat http://aplikasi/petrabarus.

Sebelum Yii 1.1.8, implementasi ini agak sedikit kompleks (saya tidak tertarik untuk membahasnya). Tapi sejak adanya kelas CBaseUrlRule, ini jadi lebih mudah.

Pertama-tama, misalnya kita mempunyai kelas model User yang digenerate dari Gii. Saya yakin hampir semua aplikasi Yii memiliki kelas seperti di bawah.

/*
* The followings are the available columns in table 'Users':
* @property integer $id
* @property string $username
* @property string $email
*/
class User extends CActiveRecord {
}

Dengan adanya ActiveRecord class bawaan Yii, kita dapat dengan mudah mengkueri user berdasarkan usernamenya

$username = 'petrabarus';
User::model()->find('username = :username', array(':username' => $username));

Kemudian kita mempunyai sebuah controller untuk melihat user tersebut

class UserController extends CController {
	public function actionView(){
		$username = $_GET['username'];
		$model = User::model()->find('username = :username', array(':username' => $username));
		$this->render('view', array('model' => $model));
	}
}

Untuk mengakses URLnya biasanya yang kita lakukan adalah mengakses http://aplikasi/user?username=petrabarus.

Sekarang kita tinggal membuat sebuah URL Rule seperti di bawah

class UserUrlRule extends CBaseUrlRule {

	public $connectionID = 'db';

	public function createUrl($manager, $route, $params, $ampersand) {
		if ($route === 'user/view' && isset($params['username'])) {
			$newroute = $params['username'];
			unset($params['username']);
			if (count($params) > 0) {
				$newroute.= '?' . http_build_query($params);
			}
			return $newroute;
		}
		return false;
	}

	public function parseUrl($manager, $request, $pathInfo, $rawPathInfo) {
		if (preg_match('/[a-zA-Z0-9\.]+/', $pathInfo, $matches)) {
			$username = $matches[0];
			$exists = User::model()->exists('username = :username', array(':username' => $username));
			if ($exists) {
				$_GET['username'] = $username;
				return 'user/view';
			} else
				return false;
		}
		return false;
	}

}

Method parseUrl dibutuhkan untuk memparsing url yang diakses melalui address bar browser. Sementara itu method createUrl adalah untuk membentuk URL yang kita inginkan. Method createUrl ini nantinya akan digunakan oleh method createUrl milik Controller. Pada method parseUrl itu saya memfilter URL tersebut dengan regex /[a-zA-Z0-9\.]+/ yang merupakan pattern rule dari username pada aplikasi saya. Kemudian jika ada yang mirip maka string pada URL tersebut akan saya periksa apakah ada user yang memiliki nama yang sama. Jika ada maka request dialihkan ke Controller user/view.

Perlu diperhatikan, agar username tidak bentrok dengan URL-URL yang dimiliki oleh Controller ada baiknya kita mempunyai daftar username yang diblacklist, yang diantaranya adalah nama-nama Controller seperti misalnya login, logout, signin, signout, register, dan lain-lain.

Lalu kita tambahkan ke rule di konfigurasi.

'urlManager' => array(
	    'urlFormat' => 'path',
	    'showScriptName' => false,
	    'rules' => array(
		array(
		    'class' => 'application.components.UserUrlRule',
		    'connectionID' => 'db',
		),
		'<controller:\w+>/<id:\d+>' => '<controller>/view',
		'<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
		'<controller:\w+>/<action:\w+>' => '<controller>/<action>',
	    ),
	),

Dan sekarang kita bisa mengakses halaman user dari http://aplikasi/petrabarus. Untuk mendapatkan URL ini pada Controller, kita cukup memanggil

$this->createUrl('user/view', array('username' => 'petrabarus'));

5 Comments

  1. Mas Barus,

    Bagaimana kalo langsung begini?

    ‘rules’ => array(
    ” => ‘user/view’,

    dengan asumsi rule username, seperti standarnya username (alphanumerik, dash, dot)?

    • kalau kayak gitu, agak susah untuk ngebikin controller lain, yang pakai alfanumerik misalnya🙂

  2. tetep aja agak susah, khan sebelumnya ada rule ‘/’ => ‘/’,

  3. Trims gan, sangat membantu.
    t.o.p. b.e.g.e.t.e dech!


Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: