PHP code example of andydefer / laravel-directive

1. Go to this page and download the library: Download andydefer/laravel-directive library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

andydefer / laravel-directive example snippets


#!/usr/bin/env php


// bin/my-app
icationBuilder;
use AndyDefer\Directive\DirectiveKernel;
use AndyDefer\Directive\DirectiveServiceProvider;
use App\Providers\MyAppServiceProvider;

// ✅ Personnalisation complète
$app = ApplicationBuilder::internal([
    DirectiveServiceProvider::class,
    MyAppServiceProvider::class,      // Vos providers
])->withConfig([
    'app.name' => 'My Application CLI',
    'app.debug' => getenv('APP_DEBUG') === 'true',
])->build();

$kernel = $app->make(DirectiveKernel::class);

// ✅ Ajouter vos sources
$kernel->addSource(__DIR__ . '/src/Directives');
$kernel->addSource(__DIR__ . '/modules/*/Directives');

// ✅ Configuration
$kernel->verbose(getenv('VERBOSE') === 'true')
    ->setLogBasePath('/var/log/my-app');

$exitCode = $kernel->run($argv);
exit($exitCode->value);



namespace App\Directives;

use AndyDefer\Directive\AbstractDirective;
use AndyDefer\Directive\Enums\ExitCode;
use AndyDefer\DomainStructures\Collections\Utility\StringTypedCollection;

class GreetDirective extends AbstractDirective
{
    public function getSignature(): string
    {
        return 'greet {name} {--formal}';
    }

    public function getDescription(): string
    {
        return 'Say hello to someone';
    }

    public function getAliases(): StringTypedCollection
    {
        return StringTypedCollection::from(['hello', 'hi']);
    }

    protected function beforeExecute(): void
    {
        if ($this->getFlag('formal')) {
            $this->info('Formal mode enabled');
        }
    }

    protected function execute(): ExitCode
    {
        $name = $this->getArgument('name');
        $formal = $this->getFlag('formal');

        $greeting = $formal ? "Good day, $name" : "Hello, $name";
        $this->info($greeting);

        return ExitCode::SUCCESS;
    }

    protected function afterExecute(ExitCode $exitCode): void
    {
        $this->newLine();
        $this->line('Execution completed');
    }
}

public function getSignature(): string
{
    return 'backup {source} {destination} {format=zip} {env=?} ::level->[low,medium,high]=medium {excludes*} {purpose*} {--force} {--verbose}';
}

public function getSignature(): string
{
    return 'backup {source} {destination}';
}

public function getSignature(): string
{
    return 'backup {source} {destination} {format=zip} {compression=9} {output=dist}';
}

public function getSignature(): string
{
    return 'deploy {environment} {version=?} {config=?}';
}

public function getSignature(): string
{
    return 'delete {files*} {directories*} {--force}';
}

public function getSignature(): string
{
    return 'deploy {environment} {--force} {--verbose} {--dry-run}';
}

::name->[value1,value2,value3]=state

// Avec valeur par défaut
$signature = 'set-level ::level->[beginner,middle,master]=medium';

// Requis
$signature = 'set-level ::level->[beginner,middle,master]=*';

// Optionnel
$signature = 'set-level ::level->[beginner,middle,master]=?';

// Avec commentaire
$signature = 'set-level ::level->[beginner,middle,master]=medium#"The skill level"';

// Dans une directive
$level = $this->getEnum('level');

// Vérifications
$allowed = $this->getEnumAllowedValues('level');
$isRequired = $this->isEnumRequired('level');
$isAllowed = $this->isEnumValueAllowed('level', 'master');

public function getSignature(): string
{
    return 'backup {source}#"Source directory" {destination}#"Destination" {format=zip}#"Archive format" {--force}#"Force overwrite"';
}

// ✅ Ordre correct avec tous les types
'backup {source} {destination} {format=zip} {env=?} ::level->[low,high]=medium {excludes*} {--force}'

// ✅ Commentaires à n'importe quelle position
'backup {source}#"Source" {destination} {--force}#"Force"'

// ❌ Enum après variadic
'backup {source} {excludes*} ::level->[low,high]=medium'

// ❌ Required après default
'backup {format=zip} {source}'

// Dans la directive
$customData = $this->getCustomData();
$greeting = $customData['greeting'] ?? 'Default greeting';

protected function execute(): ExitCode
{
    // Arguments requis
    $name = $this->getRequired('name');
    $email = $this->getRequired('email');

    // Tous les arguments requis
    $rsion = $this->getArgument('version');

    // Arguments variadiques
    $files = $this->getVariadic('files');

    // Tous les arguments variadiques
    $variadics = $this->getVariadics();

    // Collection plate de toutes les valeurs variadiques
    $allValues = $this->getVariadicArguments();

    // Flags
    $force = $this->getFlag('force');
    $verbose = $this->getFlag('verbose');

    // Tous les flags
    $flags = $this->getFlags();

    // Flags actifs
    $active = $this->getActiveFlags();

    // Énumérations
    $level = $this->getEnum('level');

    // Toutes les énumérations
    $enums = $this->getEnums();

    // Valeurs autorisées pour une enum
    $allowed = $this->getEnumAllowedValues('level');

    // Vérifications
    if ($this->hasArgument('email')) { /* ... */ }
    if ($this->hasFlag('force')) { /* ... */ }
    if ($this->hasRequireds()) { /* ... */ }
    if ($this->hasDefaults()) { /* ... */ }
    if ($this->hasEnums()) { /* ... */ }
    if ($this->hasFlags()) { /* ... */ }
    if ($this->hasVariadicArguments()) { /* ... */ }

    return ExitCode::SUCCESS;
}

// Peut retourner un string, un booléen ou un array
$value = $this->getArgument('key');

if (is_array($value)) {
    // C'est un variadic
} elseif (is_bool($value)) {
    // C'est un flag
} else {
    // C'est un argument (requis, default, nullable, enum)
}

// Définir une valeur
$this->contextSet('key', 'value');

// Lire une valeur
$value = $this->contextGet('key', 'default');

// Vérifier l'existence
if ($this->contextHas('key')) {
    // ...
}

// Obtenir tout le contexte
$all = $this->contextAll();

// Fusionner des valeurs
$this->contextMerge([
    'user_id' => 42,
    'user_role' => 'admin',
]);

// Supprimer une clé
$this->contextRemove('temporary_data');

// Effacer tout le contexte
$this->contextClear();

// Incrémenter / Décrémenter
$this->contextIncrement('counter', 5);
$this->contextDecrement('counter', 2);

class ProcessDataDirective extends AbstractDirective
{
    public function getSignature(): string
    {
        return 'data:process {file}';
    }

    protected function execute(): ExitCode
    {
        $file = $this->getArgument('file');

        $this->contextSet('file', $file);
        $this->call('data:load');
        $this->call('data:clean');
        $this->call('data:transform');

        $stats = $this->contextGet('processing_stats');
        $this->info("📊 Processed {$stats['total']} records");

        return ExitCode::SUCCESS;
    }
}

// Appel simple
$this->call('build --clean');

// Avec argument
$this->call('deploy:backup staging');

// Avec options
$this->call('deploy:migrate --force');

// Appel dynamique
$env = $this->getArgument('environment');
$this->call("deploy:validate $env");

// Multiple appels
$this->call('task:one');
$this->call('task:two');
$this->call('task:three');

// Avec parsing du contexte
$this->call("greet {$name} --formal");

class CircularDirective extends AbstractDirective
{
    public function getSignature(): string
    {
        return 'circular';
    }

    protected function execute(): ExitCode
    {
        $this->call('circular'); // ⚠️ Détecté automatiquement
        return ExitCode::SUCCESS;
    }
}

class DeployDirective extends AbstractDirective
{
    public function getSignature(): string
    {
        return 'deploy {environment} {--skip-tests} {--force}';
    }

    protected function execute(): ExitCode
    {
        $env = $this->getArgument('environment');
        $skipTests = $this->getFlag('skip-tests');
        $force = $this->getFlag('force');

        $this->call("deploy:validate $env");
        $this->call("deploy:backup $env");

        if (!$skipTests) {
            $this->call('deploy:build --with-tests');
        } else {
            $this->call('deploy:build');
        }

        $forceFlag = $force ? '--force' : '';
        $this->call("deploy:migrate $env $forceFlag");

        $this->call("deploy:activate $env");
        $this->call('deploy:post --notify');
        $this->call('deploy:cleanup --keep-last=3');

        return ExitCode::SUCCESS;
    }
}

$kernel = $app->make(DirectiveKernel::class);

// Ignorer une source
$kernel->ignoreSource(DiscoverySource::VENDOR);

// Ajouter une source
$kernel->addSource(__DIR__ . '/src/Commands');

// Filtrer par namespace
$kernel->onlyNamespace('App\\Directives\\');
$kernel->excludeNamespace('App\\Directives\\Internal\\');

// Filtrer par préfixe
$kernel->onlyPrefix('app:');
$kernel->excludePrefix('admin:');

// Ignorer une directive spécifique
$kernel->ignoreDirective('deprecated:command');

$kernel->discover();
$problems = $kernel->getProblems();

foreach ($problems as $problem) {
    echo $problem->get('key') . ': ' . $problem->get('message');
}

$kernel->setLogBasePath('/var/log/directive');

$kernel->verbose(true);

use AndyDefer\Directive\DirectiveKernel;
use AndyDefer\Directive\Enums\ExitCode;

class TaskController extends Controller
{
    public function run(DirectiveKernel $kernel)
    {
        $exitCode = $kernel->runSignature('process:data --format=json');

        if ($exitCode === ExitCode::SUCCESS) {
            return response()->json(['message' => 'Task completed']);
        }

        return response()->json(['error' => 'Task failed'], 500);
    }
}

class ProcessDataJob implements ShouldQueue
{
    public function handle(DirectiveKernel $kernel): void
    {
        $kernel->runSignature('process:batch --limit=1000');
    }
}

class ReportService
{
    public function __construct(private DirectiveKernel $kernel) {}

    public function generateDailyReport(): array
    {
        $this->kernel->runSignature('report:fetch');
        $this->kernel->runSignature('report:process --format=pdf');
        $this->kernel->runSignature('report:send [email protected]');

        return ['status' => 'completed'];
    }
}

#!/usr/bin/env php


// bin/standalone
ionBuilder;
use AndyDefer\Directive\DirectiveKernel;
use AndyDefer\Directive\DirectiveServiceProvider;

$app = ApplicationBuilder::external([
    DirectiveServiceProvider::class,
])->withConfig([
    'app.name' => 'Standalone CLI',
])->build();

$kernel = $app->make(DirectiveKernel::class);
$kernel->addSource(__DIR__ . '/src/Directives');

exit($kernel->run($argv)->value);



namespace Tests\Directives;

use AndyDefer\Directive\Bootstrap\ApplicationBuilder;
use AndyDefer\Directive\DirectiveServiceProvider;
use AndyDefer\Directive\Services\DirectiveTestingService;
use AndyDefer\Directive\Enums\ExitCode;
use PHPUnit\Framework\TestCase;

class GreetDirectiveTest extends TestCase
{
    private DirectiveTestingService $testing;

    protected function setUp(): void
    {
        parent::setUp();

        $app = ApplicationBuilder::internal([
            DirectiveServiceProvider::class,
        ])->build();

        $this->testing = new DirectiveTestingService(
            $app,
            [__DIR__ . '/../app/Directives']
        );
    }

    protected function tearDown(): void
    {
        $this->testing->destroy();
        parent::tearDown();
    }

    public function test_greet_directive_returns_success(): void
    {
        $response = $this->testing->run('greet John');

        $this->assertSame(ExitCode::SUCCESS, $response->exit_code);
        $this->assertStringContainsString('Hello, John', $response->output);
    }

    public function test_unknown_command_returns_problems(): void
    {
        $response = $this->testing->run('unknown-command');

        $this->assertSame(ExitCode::NOT_FOUND, $response->exit_code);
        $this->assertFalse($response->problems->isEmpty());
    }
}

class DeployDirective extends AbstractDirective
{
    public function getSignature(): string
    {
        return 'deploy {environment} {--skip-tests} {--force}';
    }

    protected function execute(): ExitCode
    {
        $env = $this->getArgument('environment');

        $this->call("deploy:validate $env");
        $this->call("deploy:backup $env");
        $this->call('deploy:build' . ($this->getFlag('skip-tests') ? ' --skip-tests' : ''));
        $this->call("deploy:migrate $env" . ($this->getFlag('force') ? ' --force' : ''));
        $this->call("deploy:activate $env");
        $this->call('deploy:post --notify');

        return ExitCode::SUCCESS;
    }
}

class ProcessDataDirective extends AbstractDirective
{
    public function getSignature(): string
    {
        return 'data:process {file} {--format=csv} {--dry-run}';
    }

    protected function execute(): ExitCode
    {
        $file = $this->getArgument('file');

        $this->call("data:load $file");
        $this->call('data:clean');
        $this->call('data:transform --aggressive');
        $this->call('data:validate');

        if (!$this->getFlag('dry-run')) {
            $format = $this->getArgument('format');
            $this->call("data:export --format=$format");
        }

        $stats = $this->contextGet('processing_stats');
        $this->info("📊 Processed {$stats['total']} records");

        return ExitCode::SUCCESS;
    }
}

// BON
class UserController
{
    public function __construct(
        private readonly UniqueTaskServiceInterface $taskService
    ) {}
}

// ÉVITER (facade)
use AndyDefer\Task\Facades\Task;
Task::register(...);

protected function beforeExecute(): void
{
    $name = $this->getArgument('name');

    if (empty($name) || strlen($name) < 3) {
        $this->error('Name must be at least 3 characters');
        throw new \RuntimeException('Invalid name');
    }
}

// BON
$this->contextSet('user_id', $user->id);
$userId = $this->contextGet('user_id');

// ÉVITER
global $userId;
$userId = 42;

protected function beforeExecute(): void
{
    $this->contextSet('start_time', microtime(true));
    $this->info('Starting...');
}

protected function afterExecute(ExitCode $exitCode): void
{
    $duration = microtime(true) - $this->contextGet('start_time');
    $this->info("Completed in {$duration}s");
}

#!/usr/bin/env php


// bin/my-app
icationBuilder;
use AndyDefer\Directive\DirectiveKernel;
use AndyDefer\Directive\DirectiveServiceProvider;
use App\Providers\AppServiceProvider;

$app = ApplicationBuilder::internal([
    DirectiveServiceProvider::class,
    AppServiceProvider::class,
])->build();

$kernel = $app->make(DirectiveKernel::class);
$kernel->addSource(__DIR__ . '/src/Directives');

exit($kernel->run($argv)->value);
bash
php artisan vendor:publish --tag=directive-config
json
{
  "time": "2026-07-09T11:45:23+00:00",
  "level": "info",
  "type": "directive_execution",
  "payload": {
    "command": "deploy staging",
    "directive_class": "App\\Directives\\DeployDirective",
    "signature": "deploy {environment} {--skip-tests} {--force}",
    "exit_code": 0,
    "exit_code_label": "Success",
    "success": true,
    "duration_seconds": 12.345,
    "memory_bytes": 2048,
    "memory_human": "2.00 KB",
    "peak_memory_bytes": 4096,
    "peak_memory_human": "4.00 KB",
    "calls_count": 7,
    "context": {
      "environment": "staging",
      "deployment_start": 1700000000
    }
  }
}