Pada tulisan ini saya akan membuat series mengenai pemrograman dengan Yii Framework. Series ini akan disusun untuk membuat sebuah program sederhana yang memanfaatkan fitur-fitur umum yang sangat mungkin digunakan di banyak kasus. Tulisan ini akan menggunakan Basic Template Yii2 (yang menurut saya penggunaannya sedikit lebih sulit daripada advance template Yii2).
Secara garis besar (dan mungkin akan bertambah sesuai keperluan yang mungkin terjadi) outline dari seri tulisan ini akan terdiri dari hal berikut.
- Prainstalasi
- Instalasi YiiFramework 2.0
- Login
- Login dengan Database pada Yii2
- Bekerja dengan Gii
- Module pada Yii2
- Layout dasar dan Manipulasinya pada Yii2
- Costum Asset dan Asset Bundle pada Yii2
- Alias pada Yii2
- Bekerja dengan Form
- Timestamp, Blameable, dan Sluggable Behavior pada Yii2
- Menggunakan Rich Text Input CkEditor dan Alternatifnya pada Yii2
- Gridview dan Listview
- SEO Friendly Url dengan slug
- Scenario pada Model Yii2
- Retrieve data pada Yii2
- Relasi Database pada Yii2
- Menggunakan Bootstrap4
- Widget Kartik dan Kartik Gridview
- Select2 dengan Kartik Ekstension
- Dependent Dropdown pada Yii2
- Bekerja dengan Modals
- Membuat Costum Template untuk Gii
- Mengupload File
- Mengupload File dengan Kartik Widget
- Gridview atau Datatables?
- Session dan Cookie pada Yii2
- Menggunakan AdminLTE pada Yii2
- Membuat Themes pada Yii2
- Menggunakan GoogleMaps API pada Yii2
- Menggunakan Socket.io pada Yii2
- Handling Error
- Bekerja dengan AuthClient
- Menggunakan Amazon S3 pada Yii2
- Mengirim Email dengan Swiftmailer pada Yii2
- Middleware pada Yii2
- Mengenal RBAC pada Yii2
- Implementasi RBAC pada Yii2
- Notifikasi Real Time dengan Socket.io pada Yii2
Anda dapat mengunduh dan memantau progress dari series ini lewat repositori Github belajararief-yii2series. Silahkan bintangi (star) untuk dapat lebih mudah memantau perkembangan repositori.
Requirement
Untuk memudahkan anda dalam memahami petunjuk ini, maka beberapa hal yang perlu diperhatikan diantaranya:
- Sistem Operasi yang saya gunakan adalah Windows 10 64bit dengan terminal menggunakan powershell terminal (beberapa command seperti cd dapat berbeda dengan command prompt biasa), namun saya akan berusaha sebisa mungkin mencontohkan perintah pada sistem operasi lain jika memunkinkan.
- Stack yang digunakan adalah Wamp Server (Apache 2.2, MySQL, PHP 7).
- Yii yang digunakan adalah Yii 2.0 dengan catatan jquery yang digunakan bukan jquery3. Beberapa perintah jquery akan berbeda pada jquery3, dan beberapa extensions yang saya gunakan sepertinya belum mendukung jquery3
Skenario Dependent Dropdown
Kali ini kita akan membuat sebuah skenario baru. Kita akan membuat penghitung jumlah pembaca artikel. Penghitung ini nanti juga akan menyimpan data kapan suatu artikel dibaca/ditekan. Selanjutnya dari informasi tersebut kita akan membuat grafik pembaca artikel. Grafik dapat dilihat dengan terlebih dahulu memilih pengguna dan artikel yang dibuat oleh pengguna tersebut dengan menggunakan dependent dropdown.
Menginstall Kartik Dep Drop (Dependent Dropdown)
Kita akan menggunakan widget DepDrop dari kartik untuk dapat menerapkan dependent dropdown dengan lebih mudah. Untuk menginstall kartik/DepDrop jalankan perintah di bawah ini.
composer require kartik-v/yii2-widget-depdrop "dev-master"
Membuat Tabel Menghitung Artikel
Selanjutnya kita akan membuat tabel blog_counter sebagai tempat menampung penghitungan artikel yang telah dibaca. Jalankan perintah di bawah ini pada terminal untuk membuat migration-file dengan nama create_blog_counter_table.
yii migrate/create create_blog_counter_table
Selanjutnya modifikasi file tersebut menjadi seperti di bawah ini.
<?php
use yii\db\Migration;
/**
* Handles the creation of table `{{%blog_counter}}`.
*/
class m200220_060724_create_blog_counter_table extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$tableOptions = null;
if ($this->db->driverName === 'mysql') {
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';
}
$this->createTable('{{%blog_counter}}', [
'id' => $this->primaryKey(),
'blog_id' => $this->integer(),
'created_at' => $this->integer(),
'updated_at' => $this->integer(),
], $tableOptions);
// creates index for column `blog_id`
$this->createIndex(
'idx-blogcounter-blog_id',
'blog_counter',
'blog_id'
);
// add foreign key for table `user`
$this->addForeignKey(
'fk-bloccounter-blog_id',
'blog_counter',
'blog_id',
'blog',
'id',
'CASCADE'
);
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->dropTable('{{%blog_counter}}');
}
}
Kemudian buat model BlogCounter dengan Gii dan jangan lupa tambahkan timeStampBehavior pada model tersebut.
Menambahkan Penghitungan pada saat Artikel di Klik
Untuk menambahkan perhitungan terlebih dahulu kita menambahkan method addBlogCounter
pada model \app\models\Blog.php
kita. Method yang kita buat seperti di bawah ini.
public function addBlogCounter()
{
$blogCounter = new BlogCounter();
$blogCounter->blog_id = $this->id;
return $blogCounter->save();
}
Kemudian buka \app\controllers\BlogController.php
dan pada actionView kita tambahkan baris berikut.
public function actionView($slug)
{
$model = $this->findModel($slug);
$model->addBlogCounter();
return $this->render('view', [
'model' => $this->findModel($slug),
]);
}
Menampilkan Statistik Artikel dengan Dependent Dropdown
Terakhir kita akan membuat halaman untuk melihat statistik artikel seperti pada manajemen dashboard. Pertama kita buat terlebih dahulu model untuk menampilkan data grafik. Buat model \app\modules\administrator\models\StatistikSearch.php
seperti di bawah ini.
<?php
namespace app\modules\administrator\models;
use app\models\Blog;
use app\models\BlogCounter;
use yii\base\Model;
use yii\helpers\Json;
/**
* BlogSearch represents the model behind the search form of `app\models\Blog`.
*/
class StatistikSearch extends Model
{
public $user_id;
public $title;
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['user_id'], 'integer'],
[['title'], 'string'],
];
}
public function getBlogCountByMonthJson()
{
return Json::encode($this->getBlogCountByMonth());
}
public function getBlogCountByMonth()
{
$blogCountByMonth = BlogCounter::find()
->select(['MONTH(FROM_UNIXTIME(created_at)) month', 'count(id) AS count'])
->where(['blog_id' => $this->getBlog()->id ])
->groupBy('MONTH(FROM_UNIXTIME(created_at))')->asArray()->all();
return $blogCountByMonth;
}
public function getBlog()
{
return Blog::findOne(['created_by' => $this->user_id, 'slug' => $this->title]);
}
}
Model tersebut dalam Yii disebut ModelForm yang akan menampilkan data perhitungan yang dihitung berdasarkan bulan pada artikel tertentu. Selanjutnya buat controllers \app\modules\administrator\controllers\StatistikController.php
pada seperti di bawah ini.
<?php
namespace app\modules\administrator\controllers;
use Yii;
use app\models\Blog;
use app\modules\administrator\models\StatistikSearch;
use yii\filters\AccessControl;
use yii\web\Controller;
/**
* StatistikController implements the CRUD actions for Blog model.
*/
class StatistikController extends Controller
{
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['index', 'title'],
'allow' => true,
'roles' => ['@'],
],
],
],
];
}
/**
* Lists all Blog models.
* @return mixed
*/
public function actionIndex()
{
$searchModel = new StatistikSearch();
$dataJson = '[{"month":"", "count":""}]';
if($searchModel->load(Yii::$app->request->queryParams)){
$dataJson = $searchModel->getBlogCountByMonthJson();
// return var_dump($dataJson);
}
return $this->render('index', [
'searchModel' => $searchModel,
'dataJson' => $dataJson,
]);
}
public function actionTitle() {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$out = [];
if (isset($_POST['depdrop_parents'])) {
$parents = $_POST['depdrop_parents'];
if ($parents != null) {
$user_id = $parents[0];
$out = self::getTitleList($user_id);
// the getSubCatList function will query the database based on the
// user_id and return an array like below:
// [
// ['id'=>'<sub-cat-id-1>', 'name'=>'<sub-cat-name1>'],
// ['id'=>'<sub-user_id_2>', 'name'=>'<sub-cat-name2>']
// ]
return ['output'=>$out, 'selected'=>''];
}
}
return ['output'=>'', 'selected'=>''];
}
private function getTitleList($user_id)
{
$blog = Blog::find()->select(['slug as id', 'title as name'])->where(['created_by' => $user_id])->asArray()->all();
return $blog ?? ['id' => '', 'name' => ''];
}
}
Selanjutnya kita buat view pada \app\modules\administrator\views\Statistik
dengan nama index.php dan _serach.php dengan isi seperti di bawah ini.
<?php
# index.php
use app\assets\ChartJsAsset;
use yii\helpers\Html;
use yii\grid\GridView;
/* @var $this yii\web\View */
/* @var $searchModel app\modules\administrator\models\BlogSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */
$this->title = 'Blogs';
$this->params['breadcrumbs'][] = $this->title;
// Register ChartJsAsset
ChartJsAsset::register($this);
?>
<div class="blog-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php echo $this->render('_search', ['model' => $searchModel]); ?>
<div class="col-md-12">
<canvas id="blogCountByMonthChart"></canvas>
</div>
</div>
<?php
// then register our Js
$this->registerJs(<<<JS
// we create function for generate count per month first
function generateDataCount(month, blogCount){
var result = blogCount.find(o => o.month == month);
if(result == null) return 0;
return result.count;
}
var blogCount = $dataJson; // blogCount json
var ctx = document.getElementById('blogCountByMonthChart').getContext('2d'); //ctx, you can replace it with jQuery if you have one
// Then we generate data with some simple looping
var i = 0;
data = [];
while(i < 12)
{
data[i] = generateDataCount(i+1, blogCount);
i++;
}
// and then generate to chartJs
var chart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
datasets: [{
label: "Blog Count By Month",
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: data,
}]
},
options: {}
});
JS
);
?>
<?php
# _search.php
use app\models\User;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\depdrop\DepDrop;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use yii\helpers\Url;
/* @var $this yii\web\View */
/* @var $model app\modules\administrator\models\BlogSearch */
/* @var $form yii\widgets\ActiveForm */
?>
<div class="blog-search">
<?php $form = ActiveForm::begin([
'action' => ['index'],
'method' => 'get',
]); ?>
<?= $form->field($model, 'user_id')->widget(Select2::class, [
'data' => ArrayHelper::map(User::find()->asArray()->all(), 'id', 'username'),
'options' => ['placeholder' => 'Select User ...'],
'pluginOptions' => ['allowClear' => true]
]) ?>
<?= $form->field($model, 'title')->widget(DepDrop::classname(), [
'type' => DepDrop::TYPE_SELECT2,
// 'data' => [2 => 'Tablets'],
'options' => ['id' => 'statistiksearch-title', 'placeholder' => 'Title ...'],
'select2Options' => ['pluginOptions' => ['allowClear' => true]],
'pluginOptions' => [
'depends' => ['statistiksearch-user_id'],
'url' => Url::to(['/administrator/statistik/title']),
// 'params' => ['input-type-1', 'input-type-2']
]
]) ?>
<div class="form-group">
<?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
<?= Html::resetButton('Reset', ['class' => 'btn btn-secondary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
Terakhir kita akan mengubah menu pada \app\views\layout\main.php
untuk menambahkan menu statistik.
echo Nav::widget([
'options' => ['class' => 'navbar-nav ml-auto'],
'items' => [
['label' => 'Home', 'url' => ['/site/index']],
['label' => 'About', 'url' => ['/site/about']],
['label' => 'Contact', 'url' => ['/site/contact']],
['label' => 'Blog', 'url' => ['/administrator/blog'], 'visible' => !Yii::$app->user->isGuest, 'items' => [
['label' => 'Manajemen', 'url' => ['/administrator/blog']],
['label' => 'Statistik', 'url' => ['/administrator/statistik']],
]],
['label' => 'Register', 'url' => ['/site/signup'], 'visible' => Yii::$app->user->isGuest],
Yii::$app->user->isGuest ? (
['label' => 'Login', 'url' => ['/site/login']]
) : (
'<li>'
. Html::beginForm(['/site/logout'], 'post')
. Html::submitButton(
'Logout (' . Yii::$app->user->identity->username . ')',
['class' => 'btn btn-outline-success my-2 my-sm-0'] // logout btn-link
)
. Html::endForm()
. '</li>'
)
],
]);
Demikian tulisan ini, semoga bermanfaat dan Happy Coding!