Developing Custom CLI Commands
Table of Contents
Developing Custom CLI Commands
Hướng dẫn chi tiết về cách phát triển custom CLI commands cho Jankx framework.
🎯 Overview
Jankx framework cung cấp một hệ thống CLI mạnh mẽ cho phép developers tạo và quản lý custom commands một cách dễ dàng.
🏗️ Architecture
CLI System Components
CLIKernel
├── CLIBootstrapper
└── Custom Commands
├── Information Commands
├── Management Commands
└── Utility Commands
Command Registration Flow
- CLI Kernel Initialization
- Bootstrapper Loading
- Service Registration
- Command Registration
- Hook Execution
🚀 Creating Custom Commands
Method 1: Direct Registration
<?php
// Trong functions.php hoặc plugin file
add_action('jankx/wpcli/register_commands', function() {
// Register custom command
\WP_CLI::add_command('jankx custom', 'CustomJankxCommand');
});
class CustomJankxCommand
{
public function __invoke($args, $assoc_args)
{
// Command logic here
\WP_CLI::line('Custom command executed!');
}
}
Method 2: Using Jankx Hooks
<?php
// Trong child theme hoặc plugin
add_action('jankx_cli_initialized', function() {
// Register commands after CLI initialization
\WP_CLI::add_command('jankx theme:info', 'ThemeInfoCommand');
});
class ThemeInfoCommand
{
public function __invoke($args, $assoc_args)
{
$theme = wp_get_theme();
\WP_CLI::line("Theme: {$theme->get('Name')}");
\WP_CLI::line("Version: {$theme->get('Version')}");
}
}
Method 3: Service-Based Commands
<?php
// Trong service provider
class CustomCLIServiceProvider
{
public function register()
{
add_action('jankx/wpcli/register_commands', [$this, 'registerCommands']);
}
public function registerCommands()
{
\WP_CLI::add_command('jankx cache:clear', [$this, 'clearCache']);
\WP_CLI::add_command('jankx optimize', [$this, 'optimize']);
}
public function clearCache($args, $assoc_args)
{
// Clear cache logic
\WP_CLI::success('Cache cleared successfully!');
}
public function optimize($args, $assoc_args)
{
// Optimization logic
\WP_CLI::line('Optimization completed!');
}
}
📋 Command Structure
Basic Command Template
class ExampleCommand
{
/**
* Command description
*
* ## OPTIONS
*
* [--format=<format>]
* : Output format (table, csv, json, count)
*
* [--fields=<fields>]
* : Limit the output to specific object fields
*
* ## EXAMPLES
*
* wp jankx example
* wp jankx example --format=json
*
* @param array $args
* @param array $assoc_args
*/
public function __invoke($args, $assoc_args)
{
// Validate arguments
$this->validateArgs($args, $assoc_args);
// Execute command logic
$result = $this->execute($args, $assoc_args);
// Display results
$this->displayResults($result, $assoc_args);
}
private function validateArgs($args, $assoc_args)
{
// Validation logic
}
private function execute($args, $assoc_args)
{
// Main execution logic
return [];
}
private function displayResults($result, $assoc_args)
{
$format = $assoc_args['format'] ?? 'table';
switch ($format) {
case 'json':
\WP_CLI::line(json_encode($result));
break;
case 'csv':
$this->displayCSV($result);
break;
default:
$this->displayTable($result);
}
}
}
Advanced Command with Options
class AdvancedCommand
{
/**
* Advanced command with multiple options
*
* ## OPTIONS
*
* [--dry-run]
* : Show what would be done without making changes
*
* [--force]
* : Force execution without confirmation
*
* [--verbose]
* : Show detailed output
*
* ## EXAMPLES
*
* wp jankx advanced --dry-run
* wp jankx advanced --force --verbose
*/
public function __invoke($args, $assoc_args)
{
$dry_run = \WP_CLI\Utils\get_flag_value($assoc_args, 'dry-run', false);
$force = \WP_CLI\Utils\get_flag_value($assoc_args, 'force', false);
$verbose = \WP_CLI\Utils\get_flag_value($assoc_args, 'verbose', false);
if ($verbose) {
\WP_CLI::line('Starting advanced command...');
}
if (!$force && !$dry_run) {
\WP_CLI::confirm('Are you sure you want to proceed?');
}
if ($dry_run) {
\WP_CLI::line('DRY RUN: Would execute command...');
return;
}
// Execute command
$this->executeCommand($args, $assoc_args);
}
}
🎨 Output Formatting
Basic Output Methods
// Simple line output
\WP_CLI::line('This is a simple line');
// Success message (green)
\WP_CLI::success('Operation completed successfully!');
// Warning message (yellow)
\WP_CLI::warning('This is a warning message');
// Error message (red)
\WP_CLI::error('An error occurred');
// Info message (blue)
\WP_CLI::info('This is an info message');
Table Output
private function displayTable($data)
{
$table = new \WP_CLI\Formatter($assoc_args, ['ID', 'Name', 'Status']);
foreach ($data as $item) {
$table->add_row([
$item['id'],
$item['name'],
$item['status']
]);
}
$table->display();
}
Progress Indicators
private function showProgress($total, $current)
{
$progress = \WP_CLI\Utils\make_progress_bar('Processing items', $total);
foreach ($items as $item) {
// Process item
$this->processItem($item);
// Update progress
$progress->tick();
}
$progress->finish();
}
🔧 Integration with Jankx Services
Using Jankx Container
class ServiceBasedCommand
{
public function __invoke($args, $assoc_args)
{
// Get Jankx container
$container = \Jankx\Jankx::getInstance();
// Use services
$config = $container->make(\Jankx\Config\ConfigManager::class);
$logger = $container->make(\Jankx\Logger\Logger::class);
// Execute with services
$result = $this->executeWithServices($config, $logger);
\WP_CLI::success('Command executed with services!');
}
}
Using Jankx Facades
class FacadeBasedCommand
{
public function __invoke($args, $assoc_args)
{
// Use Jankx services directly
$kernelManager = \Jankx\Kernel\KernelManager::getInstance();
$version = $kernelManager->getFrameworkVersion();
$config = \Jankx\Facades\Config::get('some_option');
\WP_CLI::line("Framework version: {$version}");
\WP_CLI::line("Config value: {$config}");
}
}
🧪 Testing Commands
Unit Testing
class CommandTest extends \WP_UnitTestCase
{
public function test_custom_command()
{
// Mock WP_CLI
$this->mock_wp_cli();
// Execute command
$command = new CustomCommand();
$command->__invoke([], []);
// Assertions
$this->assertTrue($this->output_contains('success'));
}
private function mock_wp_cli()
{
// Mock WP_CLI methods
}
}
Integration Testing
class CommandIntegrationTest extends \WP_UnitTestCase
{
public function test_command_with_services()
{
// Setup Jankx container
$container = \Jankx\Jankx::getInstance();
// Register test services
$container->singleton('test.service', TestService::class);
// Execute command
$command = new ServiceBasedCommand();
$result = $command->__invoke([], []);
// Assertions
$this->assertNotNull($result);
}
}
📚 Best Practices
Command Design
- Single Responsibility - Mỗi command chỉ làm một việc
- Clear Naming - Tên command rõ ràng và mô tả
- Proper Help - Cung cấp help text đầy đủ
- Error Handling - Xử lý lỗi gracefully
- Validation - Validate input arguments
Performance
- Lazy Loading - Load services khi cần
- Batch Processing - Xử lý hàng loạt cho large datasets
- Progress Indicators - Hiển thị tiến trình cho long-running commands
- Memory Management - Quản lý memory cho large operations
Security
- Permission Checks - Kiểm tra quyền trước khi thực thi
- Input Validation - Validate tất cả input
- Sanitization - Sanitize output
- Logging - Log important actions
🚀 Advanced Features
Interactive Commands
class InteractiveCommand
{
public function __invoke($args, $assoc_args)
{
// Get user input
$name = \WP_CLI\Utils\prompt('Enter your name');
$email = \WP_CLI\Utils\prompt('Enter your email');
// Confirm action
$confirm = \WP_CLI\Utils\confirm('Proceed with these details?');
if ($confirm) {
// Process with user input
$this->processUserInput($name, $email);
}
}
}
Batch Processing
class BatchCommand
{
public function __invoke($args, $assoc_args)
{
$items = $this->getItems();
$batch_size = 100;
$progress = \WP_CLI\Utils\make_progress_bar('Processing items', count($items));
foreach (array_chunk($items, $batch_size) as $batch) {
$this->processBatch($batch);
$progress->tick(count($batch));
}
$progress->finish();
}
}
📖 Documentation
Command Documentation Template
/**
* Command description
*
* ## OPTIONS
*
* [--option=<value>]
* : Option description
*
* ## EXAMPLES
*
* wp jankx example
* wp jankx example --option=value
*
* ## GLOBAL PARAMETERS
*
* [--format=<format>]
* : Output format (table, csv, json, count)
*
* [--fields=<fields>]
* : Limit the output to specific object fields
*/
Custom CLI Commands Development - Tạo powerful commands cho Jankx framework! 🚀