# Aplikasi ¶

Aplikasi (Application) adalah objek yang mengelola semua struktur dan siklus dari sistem aplikasi Yii. Setiap aplikasi sistem Yii mengandung satu objek aplikasi yang dibuat dalam skrip masuk dan mampu diakses secara global melalui expression `\Yii::$app`.

> Info: Jika kami mengatakan "sebuah aplikasi", itu bisa diartikan sebagai sebuah objek aplikasi atau sebuah sistem aplikasi, tergantung bagaimana konteksnya.

Terdapat dua tipe aplikasi: Aplikasi Web dan Aplikasi Konsol. Sesuai dengan namanya, yang pertama bertujuan untuk menangani web request, sedangkan yang kedua menangani request perintah pada konsol.

## Konfigurasi Aplikasi ¶

Ketika skrip masuk membuat objek aplikasi, objek ini akan mengambil dan memuat sebuah array konfigurasi dan menerapkannya pada objek aplikasi seperti berikut ini:

    require __DIR__ . '/../vendor/autoload.php';
    require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';

    // memuat konfigurasi aplikasi
    $config = require __DIR__ . '/../config/web.php';

    // membuat objek aplikasi & menerapkan konfigurasi
    (new yii\web\Application($config))->run();

Seperti layaknya konfigurasi normal, konfigurasi aplikasi menentukan bagaimana proses inisialisasi property dari objek aplikasi. Karena konfigurasi aplikasi pada umumnya sangat kompleks, oleh karena itu konfigurasi tersebut di simpan dalam file konfigurasi, seperti file `web.php` pada contoh di atas.

## Property Aplikasi ¶

Terdapat cukup banyak property aplikasi penting yang harus anda atur dalam konfigurasi aplikasi. Property ini secara khusus menjelaskan environment yang sedang dijalankan oleh aplikasi. Sebagai contoh, aplikasi ingin mengetahui bagaimana cara memuat controller, dimana seharusnya aplikasi menyimpan file-file yang bersifat sementara (temporary files), dll. Kami akan meringkas property tersebut dibawah ini:

### Property Wajib ¶

Dalam aplikasi apapun, anda harus menentukan setidaknya dua property:id dan basePath.

#### id ¶

Property id menentukan ID unik yang membedakan objek aplikasi dengan yang lainnya. Ini pada umumnya digunakan secara programatik. Walaupun hal ini bukanlah sebuah keharusan, karena persoalan pertukaran informasi, anda sangat direkomendasikan hanya menggunakan karakter alfanumerik ketika menentukan ID dari sebuah aplikasi.

#### basePath ¶

Property basePath menentukan direktori root dari sebuah aplikasi. Yaitu direktori yang menyimpan semua sumber kode aplikasi sistem, dan aksesnya diproteksi dari luar. Didalam direktori ini, anda akan melihat sub-direktori seperti `models`, `views`, dan `controllers` yang menyimpan sumber kode dari pola MVC.

Anda dapat menentukan property basePath menggunakan directory path atau path alias. Kedua bentuk ini, direktori yang dimaksud harus benar-benar ada, jika tidak maka sebuah exception akan di-throw. Path akan dinormalkan dengan memanggil function `realpath()`.

Property basePath pada umumnya digunakan untuk mengambil path penting lainnya (contoh runtime path). Karna itulah alias path yang dinamakan `@app` disediakan untuk merepresentasikan path ini. Path-path lainnya boleh dipanggil menggunakan alias ini (contoh: `@app/runtime` untuk merujuk ke direktori runtime).

### Property Penting ¶

Property yang dijelaskan di sub-bagian ini cenderung harus di tentukan karena mereka digunakan secara berbeda di lintas aplikasi.

#### Alias ¶

Property ini memungkinkan anda untuk menentukan seperangkat alias dalam bentuk array. Array Key merupakan nama alias, dan Array Value adalah definisi path yang dimaksud. Sebagai contoh:

    [
        'aliases' => [
            '@nama1' => 'path/menuju/ke/path1',
            '@nama2' => 'path/menuju/ke/path2',
        ],
    ]

Karna tersedianya property ini, anda bisa menentukan beberapa alias pada konfigurasi aplikasi dibanding dengan memanggil method Yii::setAlias().

#### bootstrap ¶

Property ini merupakan property yang bermanfaat. Property ini memungkinkan anda untuk menentukan component berbentuk array yang harus dijalankan dalam proses bootstrap. Sebagai contoh, jika anda memerintahkan sebuah module untuk merubah pengaturan URL, anda dapat menyusun ID-nya sebagai elemen dari property ini.

Setiap component yang terdaftar pada property ini dapat ditentukan berdasarkan salah satu dari format berikut ini:

- ID dari Component aplikasi yang ditentukan melalui component,
- ID dari module yang ditentukan melalui module,
- Nama class,
- Konfigurasi array,
- anonymous function yang membuat dan mengembalikan (return) sebuah component.

Sebagai contoh:

    [
        'bootstrap' => [
            // Component ID atau Module ID
            'demo',

            // Nama Class
            'app\components\Profiler',

            // Konfigurasi dalam bentuk array
            [
                'class' => 'app\components\Profiler',
                'level' => 3,
            ],

            // anonymous function
            function () {
                return new app\components\Profiler();
            }
        ],
    ]

> Info: Jika ID module tersebut sama dengan ID component aplikasi, component aplikasi tersebut yang akan dipakai pada saat proses boostrap. Jika anda ingin menggunakan module, anda dapat menentukannya melalui anonymous function seperti berikut ini:

>     [
>         function () {
>             return Yii::$app->getModule('user');
>         },
>     ]

Sepanjang proses bootstrap, setiap component akan dibuat objeknya. Jika class component mengimplementasikan method interface yii\base\BootstrapInterface, method bootstrap() dari class tersebut juga akan dipanggil.

Salah satu contoh praktis lainnya adalah konfigurasi aplikasi untuk Template Proyek Dasar, dimana module `debug` dan `gii` ditentukan sebagai component bootstrap ketika aplikasi sedang dijalankan dalam mode pengembangan:

    if (YII_ENV_DEV) {
        // penyesuaian konfigurasi untuk environment 'dev'
        $config['bootstrap'][] = 'debug';
        $config['modules']['debug'] = 'yii\debug\Module';

        $config['bootstrap'][] = 'gii';
        $config['modules']['gii'] = 'yii\gii\Module';
    }

> Catatan: Menentukan terlalu banyak component pada `bootstrap` akan menurunkan performa dari aplikasi anda, dikarenakan component yang sama tersebut harus dijalakan dalam setiap request. Jadi gunakanlah component bootstrap dengan bijaksana.

#### catchAll ¶

Property ini hanya dikenali oleh Web applications. Property ini menentukan sebuah action dari controller yang ditugaskan menangani semua request dari pengguna. Property ini biasanya digunakan ketika aplikasi dalam mode pemeliharaan (maintenance) yang mengarahkan semua request menuju satu action.

Konfigurasinya yaitu sebuah array dimana elemen pertama menentukan route dari action. Element lainnya (sepasang key-value) menentukan parameter yang akan diteruskan ke action. Sebagai contoh:

    [
        'catchAll' => [
            'offline/notice',
            'param1' => 'value1',
            'param2' => 'value2',
        ],
    ]

> Info: Panel Debug pada development environment tidak akan berfungsi ketika property ini diisi.

#### components ¶

Property ini adalah salah satu property yang sangat penting. Property ini memperbolehkan anda mendaftarkan beberapa component yang disebut component aplikasi yang bisa anda gunakan di tempat lain. Sebagai contoh:

    [
        'components' => [
            'cache' => [
                'class' => 'yii\caching\FileCache',
            ],
            'user' => [
                'identityClass' => 'app\models\User',
                'enableAutoLogin' => true,
            ],
        ],
    ]

Setiap component aplikasi ditentukan dengan sepasang key-value ke dalam array. Key merepresentasikan ID component, dimana value merepresentasikan nama class dari component atau konfigurasi array.

Anda dapat mendaftaran component apapun ke dalam objek aplikasi, dan nantinya component tersebut dapat diakses secara global menggunakan expression `\Yii::$app->componentID`.

Harap membaca bagian Component Aplikasi untuk penjelasan lebih lanjut.

#### controllerMap ¶

Property ini memperbolehkan anda untuk melakukan mapping sebuah ID controller ke class controller yang anda inginkan. Secara default, Yii melakukan mapping ID controller ke class controller berdasarkan kaidah yang ditentukan (Contoh: ID `post` akan di mapping ke `app\controllers\PostController`). Dengan menentukan property ini, anda diperbolehkan untuk tidak mengikuti kaidah untuk spesifik controller. Pada contoh dibawah ini, `account` akan di mapping ke `app\controllers\UserController`, sedangkan `article` akan di mapping ke `app\controllers\PostController`.

    [
        'controllerMap' => [
            'account' => 'app\controllers\UserController',
            'article' => [
                'class' => 'app\controllers\PostController',
                'enableCsrfValidation' => false,
            ],
        ],
    ]

Key array dari property ini merepresentasikan ID controller, sedangkan value merepresentasikan nama _class yang dimaksud atau konfigurasi array.

#### controllerNamespace ¶

Property ini menentukan namespace default dimana class controller tersebut harus dicari. Default ke `app\controllers`. Jika ID controller adalah `post`, secara kaidah, nama class controller-nya (tanpa namespace) adalah `PostController`, dan `app\controllers\PostController` adalah nama class lengkapnya (Fully Qualified Class Name).

class controller juga boleh disimpan dalam sub-direktori dari direktori yang dimaksud namespace ini. Sebagai contoh, jika ada ID controller `admin/post`, nama class lengkap yang dimaksud adalah `app\controllers\admin\PostController`.

Sangatlah penting bahwa nama class lengkap dari controller tersebut bisa di-autoload dan namespace dari class controller anda cocok dengan nilai dari property ini. Jika tidak, anda akan melihat error "Halaman tidak ditemukan" ketika mengakses aplikasi.

Jika saja anda tidak ingin mengikut kaidah-kaidah yang dijelaskan di atas, anda boleh menentukan property controllerMap.

#### language ¶

Property ini menentukan bahasa apa yang seharusnya ditampilkan pada konten aplikasi ke pengguna. Nilai default dari property ini adalah `en`, yang merupakan Bahasa Inggris. Anda harus menentukan property ini jika aplikasi anda menyediakan konten dalam berbagai bahasa.

Nilai dari property ini menentukan banyak aspek dari internasionalisasi, termasuk penerjemahan pesan, format tanggal, format penomoran, dll. Sebagai contoh, widget yii\jui\DatePicker akan menggunakan property ini secara default untuk menentukan bahasa apa yang digunakan pada kalender yang ditampilkan dan bagaimana format tanggal pada kalender tersebut.

Disarankan agar anda menentukan bahasa dalam format Tag Bahasa IETF. Sebagai contoh, `en` berarti Bahasa Inggris, sedangkan `en-US` berarti Bahasa Inggris yang digunakan di Amerika Serikat.

Informasi selengkapnya mengenai property ini dapat dipelajari di bagian Internasionalisasi.

#### modules ¶

Property ini menentukan module apa yang akan digunakan oleh aplikasi.

Property ini ditentukan menggunakan array dari class class modul atau konfigurasi array dimana array key merupakan ID dari module tersebut. Berikut contohnya:

    [
        'modules' => [
            // modul "booking" dengan class module yang ditentukan
            'booking' => 'app\modules\booking\BookingModule',

            // modul "comment" yang ditentukan menggunakan konfigurasi array
            'comment' => [
                'class' => 'app\modules\comment\CommentModule',
                'db' => 'db',
            ],
        ],
    ]

Silahkan melihat bagian Modules untuk informasi lebih lanjut.

#### name ¶

Property ini menentukan nama aplikasi yang bisa ditampilkan ke pengguna. Berbeda dengan property id, yang mengharuskan nilainya unik, nilai dari property ini secara umum bertujuan untuk keperluan tampilan saja; tidak perlu unik.

Anda tidak perlu menentukan property ini jika memang tidak ada kode anda yang akan menggunakannya.

#### params ¶

Property ini menentukan parameter berbentuk array yang bisa diakses secara global oleh aplikasi. Dibanding menuliskan secara manual angka dan string di kode anda, merupakan hal yang bagus jika anda menentukan hal tersebut sebagai parameter-parameter aplikasi di satu tempat yang sama, dan menggunakannya pada tempat dimana dia dibutuhkan. Sebagai contoh, anda mungkin menentukan ukuran thumbnail sebagai parameter seperti contoh dibawah ini:

    [
        'params' => [
            'thumbnail.size' => [128, 128],
        ],
    ]

Kemudian, pada kode dimana anda akan menggunakan ukuran tersebut, anda cukup menggunakannya seperti kode dibawah ini:

    $size = \Yii::$app->params['thumbnail.size'];
    $width = \Yii::$app->params['thumbnail.size'][0];

Jika di suatu hari anda memutuskan untuk mengganti ukuran thumbnail tersebut, anda cukup menggantinya di konfigurasi aplikasi; anda tidak perlu mengganti di semua kode dimana anda menggunakannya.

#### sourceLanguage ¶

Property ini menentukan bahasa apa yang digunakan dalam menulis kode aplikasi. Nilai default-nya adalah `'en-US'`, yang berarti Bahasa Inggris (Amerika Serikat). Anda sebaiknya menentukan property ini jika teks pada kode anda bukanlah Bahasa Inggris.

Seperti layaknya property language, anda seharusnya menentukan property ini dalam format Tag Bahasa IETF. Sebagai contoh, `en` berarti Bahasa Inggris, sedangkan `en-US` berarti Bahasa Inggris (Amerika Serikat).

Untuk informasi lebih lanjut mengenai property ini bisa anda pelajari pada bagian Internasionalisasi.

#### timeZone ¶

Property ini disediakan sebagai cara alternatif untuk menentukan zona waktu default dari PHP runtime. Dengan menentukan property ini, pada dasarnya anda memanggil function PHP date_default_timezone_set(). Sebagi contoh:

    [
        'timeZone' => 'America/Los_Angeles',
    ]

#### version ¶

Property ini menentukan versi dari aplikasi anda. Secara default nilainya adalah `'1.0'`. Anda tidak harus menentukan property ini jika tidak ada kode anda yang akan menggunakannya.

### Property yang Bermanfaat ¶

Property yang dijelaskan pada sub-bagian ini tidak secara umum digunakan karena nilai default-nya sudah ditentukan berdasarkan kaidah-kaidah yang umum digunakan. Tetapi anda boleh menentukannya sendiri jikalau anda tidak ingin mengikuti kaidah-kaidah tersebut.

#### charset ¶

Property ini menentukan charset yang digunakan oleh aplikasi. Nilai default-nya adalah `'UTF-8'`, dimana harus digunakan sebisa mungkin pada kebanyakan aplikasi, kecuali anda sedang membangun sistem lama yang banyak menggunakan data yang tidak termasuk dalam Unicode.

#### defaultRoute ¶

Property ini menentukan route yang harus aplikasi gunakan ketika sebuah request tidak memiliki route. Route dapat terdiri dari ID child module, ID controller, dan/atau ID action. Sebagai contoh, `help`, `post/create`, atau `admin/post/create`. Jika ID action tidak diberikan, maka property ini akan mengambil nilai default yang ditentukan di yii\base\Controller::$defaultAction.

Untuk aplikasi Web, nilai default dari property ini adalah `'site'`, yang berarti controller `SiteController` dan default action-nya yang akan digunakan. Hasilnya, jika anda mengakses aplikasi tanpa menentukan route yang spesifik, maka akan menampilkan output dari `app\controllers\SiteController::actionIndex()`.

Untuk aplikasi konsol, nilai default-nya adalah `'help'`, yang berarti akan menggunakan yii\console\controllers\HelpController::actionIndex() sebagai perintah utamanya. Hasilnya, jika anda menjalankan perintah `yii` tanpa memasukkan argumen, maka akan menampilkan informasi bantuan penggunaan.

#### extensions ¶

Property ini menentukan daftar dari extension yang terpasang dan digunakan oleh aplikasi. Secara default, akan mengambil array yang dikembalikan oleh file `@vendor/yiisoft/extensions.php`. File `extensions.php` dibuat dan dikelola secara otomatis jika anda menggunakan Composer untuk memasang extensions. Secara umum, anda tidak perlu menentukan property ini.

Dalam kasus khusus jika anda ingin mengelola extension secara manual, anda boleh menentukan property ini seperti kode dibawah ini:

    [
        'extensions' => [
            [
                'name' => 'extension name',
                'version' => 'version number',
                'bootstrap' => 'BootstrapClassName',  // Tidak wajib, bisa juga berupa konfigurasi array
                'alias' => [  // Tidak Wajib
                    '@alias1' => 'to/path1',
                    '@alias2' => 'to/path2',
                ],
            ],

            // ... extension lain yang ditentukan seperti kode di atas ...

        ],
    ]

Seperti yang anda lihat, property ini menerima spesifikasi extension dalam bentuk array. Setiap extension ditentukan dengan array yang terdiri dari elemen `name` dan `version`. Jika extension harus dijalankan ketika proses bootstrap , elemen `bootstrap` dapat dispesifikasikan dengan nama class bootstrap-nya atau konfigurasi array . Extension juga dapat menentukan beberapa alias.

#### layout ¶

Property ini menentukan nama dari default layout yang akan digunakan ketika me-render sebuah view. Nilai default-nya adalah `'main'`, yang berarti akan menggunakan file layout `main.php` yang disimpan di layout path. Jika kedua dari layout path dan view path mengambil nilai default, maka representasi file layoutnya adalah path alias `@app/views/layouts/main.php`.

Anda dapat menentukan nilai property ini menjadi `false` jika anda ingin menonaktifkan layout secara default, tetapi anda seharusnya tidak memerlukannya.

#### layoutPath ¶

Property ini menentukan path dimana sistem akan mencari file layout. Nilai default-nya adalah sub-direktori `layouts` di dalam view path. Jika view path mengambil nilai defaultnya, maka path layout defaultnya adalah path alias `@app/views/layouts`.

Anda dapat menentukannya sebagai direktori atau path alias.

#### runtimePath ¶

Property ini menentukan dimana path file yang bersifat sementara, seperti file log dan cache. Nilai default-nya adalah direktori yang direpresentasikan oleh alias `@app/runtime`.

Anda dapat menentukan nilainya dengan direktori atau path alias. Sebagai catatan, path runtime wajib memiliki akses tulis (writeable) oleh web server yang menjalankan aplikasi. Dan path tersebut sebaiknya diproteksi aksesnya dari pengguna, karena file yang bersifat sementara di dalamnya mungkin mengandung informasi sensitif.

Untuk menyederhanakan akses ke path ini, Yii sudah menentukan path alias dengan nama `@runtime`.

#### viewPath ¶

Property ini menentukan direktori root dimana file-file view akan disimpan. Nilai default-nya adalah direktori yang di representasikan oleh alias `@app/views`. Anda dapat menentukan nilainya dengan direktori atau path alias.

#### vendorPath ¶

Property ini menentukan direktori vendor yang di kelola oleh Composer. Direktori ini akan menyimpan semua library pihak ketiga yang digunakan oleh aplikasi anda, termasuk Yii framework. Nilai default-nya adalah direktori yang di representasikan oleh alias `@app/vendor`.

Anda dapat menentukan nilai property ini dengan direktori atau path alias. Jika anda mengganti nilai property ini, pastikan anda juga menyesuaikan konfigurasi Composer.

Untuk memudahkan akses ke path ini, Yii sudah menentukan path alias dengan nama `@vendor`.

#### enableCoreCommands ¶

Property ini hanya dikenali oleh console applications. Property ini menentukan apakah perintah inti yang dibawa oleh rilisan Yii harus diaktifkan. Nilai default-nya adalah `true`.

## Event Aplikasi ¶

Sebuah objek aplikasi menjalankan beberapa event sepanjang siklus penanganan request. Anda dapat menempelkan penanganan event untuk event-event ini di dalam konfigurasi aplikasi seperti di bawah ini:

    [
        'on beforeRequest' => function ($event) {
            // ...
        },
    ]

Penggunaan dari sintaks `on eventName` akan dijelaskan pada bagian Konfigurasi.

Sebagai alternatif, anda dapat menempelkan penanganan event ke dalam proses bootstrap setelah objek aplikasi telah dibuat. Sebagai contoh:

    \Yii::$app->on(\yii\base\Application::EVENT_BEFORE_REQUEST, function ($event) {
        // ...
    });

### EVENT_BEFORE_REQUEST ¶

Event ini dijalankan sebelum objek aplikasi menangani sebuah request. Nama event-nya adalah `beforeRequest`.

Ketika event ini dijalankan, objek aplikasi sudah dibuat dan di inisialisasi. Jadi waktu ini merupakan waktu yang tepat untuk memasukkan kode anda melalui mekanisme event untuk mengintervensi penanganan request. Sebagai contoh, di penanganan event, anda dapat menentukan property yii\base\Application::$language secara dinamis berdasarkan parameter tertentu.

### EVENT_AFTER_REQUEST ¶

Event ini dijalankan setelah objek aplikasi menyelesaikan penanganan sebuah request tetapi sebelum mengirimkan response.

Ketika event ini dijalankan, proses penanganan request sudah selesai dan anda dapat menggunakan kesempatan untuk melakukan beberapa tugas untuk memodifikasi request atau response.

Sebagai catatan, component response juga menjalankan beberapa event pada saat mengirim isi response ke pengguna. Event tersebut akan dijalankan setelah event ini.

### EVENT_BEFORE_ACTION ¶

Event ini dijalankan sebelum semua action dari controller diproses. Nama event-nya adalah `beforeAction`.

Parameter event merupakan objek dari yii\base\ActionEvent. Sebuah penanganan event boleh menentukan property yii\base\ActionEvent::$isValid menjadi `false` untuk memberhentikan proses jalannya action. Sebagai contoh:

    [
        'on beforeAction' => function ($event) {
            if (kondisi tertentu) {
                $event->isValid = false;
            } else {
            }
        },
    ]

Sebagai catatan, event `beforeAction` yang sama juga dijalankan oleh module dan controller. Event pada objek aplikasi yang menjalankan event ini untuk pertama kali, dilanjutkan oleh module (jika ada), dan terakhir oleh controller. Jika sebuah penanganan event menentukan property yii\base\ActionEvent::$isValid menjadi `false`, semua event selanjutnya TIDAK akan dijalankan.

### EVENT_AFTER_ACTION ¶

Event ini dijalankan setelah menjalankan seluruh action dari controller. Nama event-nya adalah `afterAction`.

Parameter event adalah objek dari yii\base\ActionEvent. Menggunakan property yii\base\ActionEvent::$result, method penanganan event dapat mengakses atau merubah hasil dari action. Sebagai contoh:

    [
        'on afterAction' => function ($event) {
            if (kondisi tertentu) {
                // rubah nilai dari $event->result
            } else {
            }
        },
    ]

Sebagai catatan, event `afterAction` yang sama juga dijalankan oleh module dan controllers. Objek-objek ini menjalankan event ini sama seperti `beforeAction`, hanya saja urutannya merupakan kebalikan dari urutan di event `beforeAction`. Controller adalah objek pertama yang menjalankan event ini, setelah itu module (jika ada), dan terakhir di level aplikasi.

## Application Lifecycle ¶

Ketika skrip masuk sedang dijalankan untuk menangani sebuah request, aplikasi akan melewati proses siklus dibawah ini:

1. Skrip masuk mengambil konfigurasi aplikasi dalam bentuk array.
2. Skrip masuk membuat objek aplikasi:
   - preInit() dipanggil, dimana akan mengatur beberapa property aplikasi yang sangat penting seperti basePath.
   - Mendaftarkan penanganan error.
   - Mengatur property aplikasi.
   - init() dipanggil, yang selanjutnya memanggil bootstrap() untuk menjalankan proses bootstrap component.
3. Skrip masuk memanggil yii\base\Application::run() untuk menjalankan aplikasi:
   - Menjalankan event EVENT_BEFORE_REQUEST.
   - Menangani request: memproses request menjadi route dan parameter-parameternya; membuat objek module, controller, dan action yang dispesifikasikan oleh route; dan menjalankan action.
   - Menjalankan event EVENT_AFTER_REQUEST.
   - Mengirim response ke pengguna.
4. Skrip masuk mendapatkan status exit dari aplikasi dan menyelesaikan proses penanganan request.