Rabu, 02 August 2023

Laravel Prompt

Dalam artikel ini, kita akan mempelajari hal yang menarik dari Laravel Prompts, sebuah alat yang dapat membantu kita berinteraksi dengan Laravel command.

Laravel
Prompt

Dalam artikel ini, kita akan mempelajari hal yang menarik dari Laravel Prompts, sebuah alat yang dapat membantu kita berinteraksi dengan Laravel command.

Laravel Prompt Adalah

Laravel Prompts adalah sebuah paket PHP untuk menambahkan formulir yang indah dan ramah pengguna ke dalam aplikasi baris perintah Anda, dengan fitur-fitur mirip browser seperti teks placeholder dan validasi.

Instalasi

Ketika Anda menginstall project laravel terbaru (setelah membaca artikel ini), maka prompt sudah terinstall secara otomatis. Jika tidak, Anda dapat menginstallnya dengan perintah berikut:

composer require laravel/prompts

Penggunaan

Untuk menggunakannya tentu sangat mudah sekali. Namun, sebelum kita mempelajari nya lebih lanjut, maka saya akan memberitahu Anda terlebih dahulu bahwa semua perintah artisan yang ada di Laravel sudah menggunakan prompt ini.

Laravel Prompts mendukung macOS, Linux, dan Windows dengan WSL. Namun, karena adanya keterbatasan pada versi Windows dari PHP, saat ini belum memungkinkan untuk menggunakan Laravel Prompts di Windows tanpa menggunakan WSL.

Seperti seandainya ketika Anda ingin membuat sebuah controller, Anda bisa membuat perintah yang kurang lebih seperti:

php artisan make:controller

Dengan perintah di atas, maka prompt akan muncul sebuah text input yang meminta Anda untuk menuliskan nama controller yang ingin Anda buat seperti gambar berikut ini: Laravel Prompt Making Controller

Membuat Prompt

Untuk membuat prompt sendiri sebenarnya sama seperti layaknya dulu kita membuat laravel command, hanya saja tampilan akan lebih friend ketika Anda menggunakan laravel prompt ini.

Dalam artikel kali ini, saya akan membuat sebuah perintah untuk membuat role dan permission pada aplikasi kita, jika Anda ingin membuat resourcenya sendiri itu tentu tidak masalah. Tapi dalam artikel kita akan menggunakan yang namanya Laravel Permission dari Spatie.

Setup Laravel

Pertama sekali, mari kita install laravel nya dengan menjalankan perintah:

composer create-project laravel/laravel prompt

Atau ketikan Anda mempunyai laravel installer, maka Anda bisa menjalankan perintah:

laravel new prompt

Setelah itu, kita install laravel permission nya dengan menjalankan perintah:

composer require spatie/laravel-permission

Kemudian, kita publish config dari laravel permission dengan menjalankan perintah:

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"

Setelah itu, kita migrasi database dengan menjalankan perintah:

php artisan migrate

HasRole Trait

Ketika kita menggunakan laravel permission, maka kita harus menambahkan trait HasRole pada model user kita. Untuk itu, mari kita buka file app/Models/User.php dan tambahkan trait HasRole seperti berikut:

use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasApiTokens;
    use HasFactory;
    use Notifiable;
    use HasRoles;
    //...

Dengan begitu, maka nanti nya kita bisa menggunakan method assignRole pada model user kita.

Membuat Command

Pertama, silakan buat sebuah command dengan nama MakeRole dengan menjalankan perintah:

php artisan make:command MakeRole

Setelah itu, buka file app/Console/Commands/MakeRole.php dan ubah isinya seperti berikut:

use Spatie\Permission\Models\Role;

class MakeRole extends Command
{
    protected $signature = 'make:role';
    protected $description = 'Create the role to be used in the application';

    public function handle(): void
    {
        $name = $this->ask('What is the name of the role?');

        $role = Role::create([
            'name' => $name,
        ]);

        $this->info("Role {$role->name} created successfully");
    }
}

Dengan begitu, maka sekarang kita bisa menjalankan perintah make:role untuk membuat role baru pada aplikasi kita.

php artisan make:role

Dengan perintah di atas, maka harusnya akan muncul prompt yang meminta Anda untuk menuliskan nama role yang ingin Anda buat seperti gambar berikut ini: Tidak dengan Laravel Prompt Parsinta

Optional Argument

Atau ketika Anda ingin membuat parameter seperti misalnya langsung memberikan namanya, maka kita perlu mengganti perintah nya seperti:

class MakeRole extends Command
{
    protected $signature = 'make:role {name?}';
    protected $description = 'Create the role to be used in the application';

    public function handle(): void
    {
        $name = $this->argument('name') ?: $this->ask('What is the name of the role?');
        $role = Role::create([
            'name' => $name,
        ]);

        $this->info("Role {$role->name} created successfully");
    }
}

Dengan begitu, kita bisa langsung menjalankan perintah make:role dengan memberikan nama role nya seperti:

php artisan make:role admin

Atau tanpa nama, maka prompt akan muncul dan meminta Anda untuk menuliskan nama role nya seperti:

php artisan make:role

Tapi ingat, itu semua belum menggunakan laravel prompt. Dengan kata lain, cara ini sudah ada di laravel sebelum prompt keluar.

Dengan Laravel Prompt

Dengan laravel prompt, maka harusnya tampilan akan lebih bagus dan lebih mudah untuk digunakan. Untuk itu, mari kita ubah file app/Console/Commands/MakeRole.php seperti berikut:

use Spatie\Permission\Models\Role;
use function Laravel\Prompts\text;

class MakeRole extends Command
{
    protected $signature = 'make:role {name?}';
    protected $description = 'Create the role to be used in the application';

    public function handle(): void
    {
        $name = $this->argument('name') ?: text('What is the name of the role?');
        $role = Role::create([
            'name' => $name,
        ]);

        $this->info("Role {$role->name} created successfully");
    }
}

Dengan begitu, maka harusnya tampilannya akan jauh berbeda. Dengan Laravel Prompt Parsinta

Asign Role

Ketika Anda sudah berhasil membuat role nya, pastinya role itu akan di assign ke user. Untuk itu, mari kita buat sebuah command dengan nama AssignRole dengan menjalankan perintah:

php artisan make:command AssignRole

Setelah itu, buka file app/Console/Commands/AssignRole.php dan ubah isinya seperti berikut:

class AssignRole extends Command
{
    protected $signature = 'assign-role {user} {role}';

    protected $description = 'Assign a role to a user';

    public function handle(): void
    {
        $user = \App\Models\User::find($this->argument('user'));

        $role = $this->argument('role');

        $user->assignRole($role);

        $this->info("Role '{$role}' assigned to '{$user->name}' successfully");
    }
}

Dengan begitu, maka sekarang kita bisa menjalankan perintah assign-role untuk mengassign role ke user pada aplikasi kita.

php artisan assign-role 1 admin

Tapi ingat, jika kita hanya menjalankankannya tanpa memberikan parameter, maka akan terjadi error seperti berikut:

Not enough arguments (missing: "user, role").

Optional Argument

Ini akan sangat menarik jika kita menggunakan laravel prompt nya. Untuk itu, mari kita ubah file app/Console/Commands/AssignRole.php seperti berikut:

class AssignRole extends Command
{
    protected $signature = 'assign-role {user?} {role?}';

    protected $description = 'Assign a role to a user';

    public function handle(): void
    {
        $userArg = $this->argument('user') ?: text('What is the user ID?');

        $role = $this->argument('role') ?: text('What is the role name?');

        $user = \App\Models\User::find($userArg);
        
        $user->assignRole($role);

        $this->info("Role '{$role}' assigned to '{$user->name}' successfully");
    }
}

Dengan begitu, maka sekarang kita bisa menjalankan perintah assign-role untuk mengassign role ke user pada aplikasi kita.

php artisan assign-role

Maka harusnya, tampilan akan berubah menjadi seperti ini: Assign Role Parsinta

Next Level

Dengan command yang telah kita lakukan, tentu sudah mantap. Namun kita bisa membuatnya lebih mantap lagi dengan selection. Untuk itu, mari kita ubah file app/Console/Commands/AssignRole.php seperti berikut:

use function Laravel\Prompts\select;

class AssignRole extends Command
{
    protected $signature = 'assign-role {user?} {role?}';
    protected $description = 'Assign a role to a user';

    public function handle(): void
    {
        $userArg = $this->argument('user')
            ?: select('Which user?', \App\Models\User::pluck('name', 'id')->toArray());

        $roleArg = $this->argument('role')
            ?: select('Which role?', \Spatie\Permission\Models\Role::pluck('name', 'id')->toArray());

        $user = \App\Models\User::find($userArg);

        $role = \Spatie\Permission\Models\Role::find($roleArg);
        $user->assignRole($roleName = $role->name);

        $this->info("Role '{$roleName}' assigned to '{$user->name}' successfully");
    }
}

Dengan begitu, maka kita bisa memilih usernya dengan menekan tombol space pada keyboard dan menekan enter untuk melanjutkan.

Dengan Select Parsinta

select() akan hanya memilih satu user, namun dengan multiselect(), kita bisa memilih lebih dari satu.

Search

Mungkin Anda berfikir, ini akan lebih mantap jika kita bisa mencari user nya. Itu harusnya juga akan sangat mudah. Untuk itu, mari kita ubah file app/Console/Commands/AssignRole.php seperti berikut:

use App\Models\User;
use function Laravel\Prompts\{search, select};
use Spatie\Permission\Models\Role;

class AssignRole extends Command
{
    protected $signature = 'assign-role {user?} {role?}';
    protected $description = 'Assign a role to a user';

    public function handle(): void
    {
        $userArg = $this->argument('user')
                ?: search(
                    'Search for the user that should receive the mail',
                    fn (string $value) => strlen($value) > 0
                        ? User::where('name', 'like', "%{$value}%")->pluck('name', 'id')->all()
                        : []
                );

        $roleArg = $this->argument('role')
            ?: select('Which role?', Role::pluck('name', 'id')->toArray());

        $user = User::find($userArg);

        $role = Role::find($roleArg);
        $user->assignRole($roleName = $role->name);

        $this->info("Role '{$roleName}' assigned to '{$user->name}' successfully");
    }
}

Dengan begitu, maka harusnya Anda sudah bisa mencari user yang akan diberikan role nya. Dan jika Anda ingin mencoba, maka Anda bisa menjalankan perintah assign-role tanpa memberikan parameter apapun. Dengan Search Parsinta

Kesimpulan

Dengan menggunakan package laravel-prompts, maka kita bisa membuat command yang lebih interaktif.

Baca lebih lanjut dokumentasi nya di sini. Selamat mencoba 🎉🎉🎉