থিম
অধ্যায় ৮: কনসোল কমান্ড এবং অটোমেশন
একটি পেশাদার প্যাকেজের অন্যতম বৈশিষ্ট্য হলো এটি ব্যবহারকারীর জন্য কাজকে সহজ করে দেয়। ব্যবহারকারীকে ম্যানুয়ালি একাধিক কমান্ড (যেমন vendor:publish, migrate) চালাতে বলা একটি ভালো অভিজ্ঞতা নয়। এই অধ্যায়ে আমরা শিখব কীভাবে কাস্টম artisan কমান্ড তৈরি করতে হয় যা প্যাকেজ ইনস্টলেশন এবং রক্ষণাবেক্ষণকে স্বয়ংক্রিয় করে তুলবে।
৮.১ লক্ষ্য: প্যাকেজের জন্য কাস্টম আর্টিসান কমান্ড তৈরি
আমাদের লক্ষ্য হলো:
- একটি
invoice-builder:installকমান্ড তৈরি করা যা প্যাকেজের জন্য প্রয়োজনীয় সমস্ত সেটআপ (কনফিগ ও মাইগ্রেশন পাবলিশ, ডাটাবেস মাইগ্রেট) একবারে করে দেবে। - একটি
invoice-builder:pruneকমান্ড তৈরি করা যা পুরনো, অপ্রয়োজনীয় ইনভয়েস ডাটাবেস থেকে মুছে ফেলবে। - এই কমান্ডগুলোকে লারাভেলের টাস্ক শিডিউলারের সাথে যুক্ত করা যাতে নির্দিষ্ট কাজ স্বয়ংক্রিয়ভাবে চলতে পারে।
৮.২ Step 1: কমান্ড ক্লাস তৈরি
লারাভেলের সব কমান্ড app/Console/Commands ফোল্ডারে থাকে। আমাদের প্যাকেজের জন্য আমরা src/Console/Commands ডিরেক্টরি তৈরি করব।
bash
# packages/DevMaster/InvoiceBuilder ফোল্ডারের ভেতর থেকে
mkdir -p src/Console/Commandsইনস্টল কমান্ড
src/Console/Commands/InstallCommand.php ফাইল তৈরি করুন:
php
<?php
namespace DevMaster\InvoiceBuilder\Console\Commands;
use Illuminate\Console\Command;
class InstallCommand extends Command
{
protected $signature = 'invoice-builder:install';
protected $description = 'Install all the InvoiceBuilder package resources';
public function handle(): void
{
$this->info('Installing InvoiceBuilder Package...');
$this->line('Publishing configuration...');
$this->call('vendor:publish', [
'--tag' => 'invoice-builder-config',
'--force' => true, // প্রয়োজনে পুরোনো কনফিগ ওভাররাইট করবে
]);
$this->line('Publishing migrations...');
$this->call('vendor:publish', [
'--tag' => 'invoice-builder-migrations',
'--force' => true,
]);
if ($this->confirm('Do you want to run the migrations now?', true)) {
$this->line('Running migrations...');
$this->call('migrate');
}
$this->info('InvoiceBuilder installed successfully.');
}
}$signature: এটি টার্মিনালে কমান্ডটিকে কল করার নাম।$description:php artisan listকমান্ডে এই বর্ণনাটি দেখানো হয়।handle(): কমান্ডটি রান করলে এই মেথডের কোড এক্সিকিউট হয়।$this->call(): একটি কমান্ড থেকে আরেকটি আর্টিসান কমান্ড কল করার জন্য এটি ব্যবহৃত হয়।
৮.৩ Step 2: কমান্ড রেজিস্টার করা
কমান্ড তৈরি করলেই লারাভেল সেটিকে চিনে না। আমাদের সার্ভিস প্রোভাইডারের মাধ্যমে কমান্ডগুলোকে রেজিস্টার করতে হবে। এই কাজটি boot() মেথডে করা হয়।
InvoiceBuilderServiceProvider.php ফাইলটি আপডেট করুন:
php
<?php
// ... use statements
use DevMaster\InvoiceBuilder\Console\Commands\InstallCommand;
class InvoiceBuilderServiceProvider extends ServiceProvider
{
// ... register() method
public function boot(): void
{
// ... loadRoutesFrom, loadViewsFrom
if ($this->app->runningInConsole()) {
// Publishing...
$this->publishes([...], 'invoice-builder-config');
$this->publishes([...], 'invoice-builder-views');
$this->publishes([...], 'invoice-builder-migrations');
// Registering commands
$this->commands([
InstallCommand::class,
]);
}
}
}runningInConsole() কেন গুরুত্বপূর্ণ? এই কন্ডিশনটি নিশ্চিত করে যে, আমাদের কমান্ড ক্লাসগুলো শুধুমাত্র তখনই মেমরিতে লোড হবে যখন টার্মিনাল থেকে php artisan কমান্ড চালানো হবে। ওয়েব রিকোয়েস্টের সময় এগুলো লোড করার কোনো প্রয়োজন নেই, যা অ্যাপ্লিকেশনের পারফরম্যান্স ঠিক রাখে।
যাচাইকরণ: আপনার টার্মিনালে php artisan list কমান্ডটি চালান। আপনি তালিকার মধ্যে invoice-builder:install কমান্ডটি দেখতে পাবেন। এখন php artisan invoice-builder:install চালালে প্যাকেজটি স্বয়ংক্রিয়ভাবে ইনস্টল হয়ে যাবে!
৮.৪ Step 3: রক্ষণাবেক্ষণ কমান্ড (Maintenance Command)
এবার আমরা একটি কমান্ড তৈরি করব যা ৩০ দিনের বেশি পুরনো 'draft' স্ট্যাটাসের ইনভয়েসগুলো ডাটাবেস থেকে মুছে ফেলবে।
src/Console/Commands/PruneInvoicesCommand.php ফাইল তৈরি করুন:
php
<?php
namespace DevMaster\InvoiceBuilder\Console\Commands;
use Illuminate\Console\Command;
use DevMaster\InvoiceBuilder\Models\Invoice;
class PruneInvoicesCommand extends Command
{
protected $signature = 'invoice-builder:prune
{--days=30 : The number of days to retain draft invoices.}';
protected $description = 'Prune old draft invoices from the database.';
public function handle(): void
{
$days = $this->option('days');
$this->info("Pruning draft invoices older than {$days} days...");
$count = Invoice::where('status', 'draft')
->where('created_at', '<=', now()->subDays($days))
->delete();
$this->info("Successfully deleted {$count} invoices.");
}
}{--days=30}: এটি একটি অপশন। ব্যবহারকারী চাইলেphp artisan invoice-builder:prune --days=60লিখে ডিফল্ট মান পরিবর্তন করতে পারবে।
ServiceProvider-এ এই নতুন কমান্ডটিও রেজিস্টার করতে ভুলবেন না:
php
// InvoiceBuilderServiceProvider.php
$this->commands([
InstallCommand::class,
PruneInvoicesCommand::class, // নতুন কমান্ড যোগ করুন
]);৮.৫ Step 4: স্বয়ংক্রিয় টাস্ক শিডিউলিং
আমরা চাই invoice-builder:prune কমান্ডটি প্রতিদিন স্বয়ংক্রিয়ভাবে রান হোক। সাধারণত, ব্যবহারকারীকে তার app/Console/Kernel.php ফাইলে গিয়ে শিডিউল যোগ করতে বলা হয়। কিন্তু আমরা প্যাকেজের ভেতর থেকেই এই কাজটি করতে পারি।
InvoiceBuilderServiceProvider-এর boot() মেথডে নিচের কোডটি যোগ করুন:
php
// InvoiceBuilderServiceProvider.php -> boot() method
use Illuminate\Console\Scheduling\Schedule;
// ...
$this->app->booted(function () {
$schedule = $this->app->make(Schedule::class);
$schedule->command('invoice-builder:prune --days=30')->daily();
});এটি কিভাবে কাজ করে?
$this->app->booted(function () { ... }): এই কোডটি লারাভেল অ্যাপ্লিকেশন সম্পূর্ণরূপে বুট হওয়ার পর রান হয়।$this->app->make(Schedule::class): আমরা সার্ভিস কন্টেইনার থেকেScheduleঅবজেক্টটি নিচ্ছি।$schedule->command(...): আমরা লারাভেলের শিডিউলারে আমাদের কমান্ডটি যোগ করে দিচ্ছি এবং বলে দিচ্ছি যে এটি প্রতিদিন (daily()) চালানো উচিত।
এখন ব্যবহারকারীকে তার Kernel.php ফাইল এডিট করতে হবে না। আমাদের প্যাকেজ স্বয়ংক্রিয়ভাবে তার রক্ষণাবেক্ষণের কাজ করতে সক্ষম।
যাচাইকরণ: আপনার টার্মিনালে php artisan schedule:list কমান্ডটি চালান (লারাভেল ৯.৫২+)। আপনি দেখতে পাবেন যে invoice-builder:prune কমান্ডটি শিডিউল তালিকায় যুক্ত হয়ে গেছে।
এই অধ্যায়ের মাধ্যমে আপনার প্যাকেজ এখন অনেক বেশি ব্যবহারকারী-বান্ধব এবং স্বয়ংক্রিয়।
পরবর্তী অধ্যায়ে আমরা আমাদের প্যাকেজকে সুরক্ষিত করার জন্য মিডলওয়্যার এবং পলিসি নিয়ে কাজ করব।