lorisleiva / laravel-actions

⚡️ Laravel components that take care of one specific task
https://laravelactions.com
MIT License
2.41k stars 117 forks source link

Feature Request: Support for Illuminate Pipelines #279

Open h-sigma opened 4 months ago

h-sigma commented 4 months ago

Relevant Article: https://martinjoo.dev/laravel-pipelines

Illuminate pipelines look like:

app(Pipeline::class)
    ->send('<p>This is the HTML content of a blog post</p>')
    ->through([
        ModerateContent::class,
        RemoveScriptTags::class,
        MinifyHtml::class,
    ])
    ->then(function (string $content) {
        return Post::create([
            'content' => $content,
            ...
        ]);
    });

In the example above, the string $content variable "travels" the pipeline. The signature of each class that it travels through needs to be

public class ModerateContent
{
    public function handle(/* our traveler */ string $content, Closure $next)
    {
        $safeContent = $this->removeBadWords($content);
        $next($safeContent);
    }
}

As you can see, the syntax is fairly similar to the existing Laravel Actions handler. In fact, all I need to do is change the signature to ?Closure $next = null to adapt it for both usages. However, it would be quite neat if Actions could support this directly (the return value of the handler function would be passed to $next in this case).

h-sigma commented 4 months ago
// -- AsAction.php
trait AsAction
{
    use AsActionBase;

    public function asPipeline(...$args): void
    {
        if (count($args) === 0) {
            throw new \Exception('No arguments provided to asPipeline method.');
        }
        if (!(last($args) instanceof \Closure)) {
            throw new \Exception('Last argument must be a closure.');
        }
        $closure = array_pop($args);
        $closure($this->handle(...$args));
    }
}

// later...
app(Pipeline::class)->send('content')->via('asPipeline')->through([ ModerateContent::class ])->thenReturn();

Would there be any shortcomings to this approach?

edalzell commented 2 months ago

I love this approach!

christopherarter commented 3 weeks ago

You have a PR @h-sigma ? I was about to write this myself in my project but glad I'm not the only one looking for it. Seems like it would be handy for others.

CeriseGoutPelican commented 3 weeks ago

I was actually looking in the documentation to see if this was a feature and am glad I found this post. I would love this, good approach! Maybe we can work on something together?