Extending Laravel Workflow to Support Spatie Laravel Tags

Richard
3 min readAug 28, 2023

--

One of the strengths of the Laravel ecosystem is its flexibility, thanks to a myriad of community-driven packages that enhance the framework’s capabilities. The laravel-workflow and spatie/laravel-tags packages are two such examples, and in this post, we'll integrate them together to make workflows taggable.

Installation Instructions

Before diving into the code, let’s ensure both libraries are properly installed:

  1. Install Laravel Workflow and Spatie Laravel Tags.
composer require laravel-workflow/laravel-workflow spatie/laravel-tags

2. Both packages include migrations that must be published.

php artisan vendor:publish --provider="Workflow\Providers\WorkflowServiceProvider" --tag="migrations"
php artisan vendor:publish --provider="Spatie\Tags\TagsServiceProvider" --tag="tags-migrations"

3. Run the migrations.

php artisan migrate

Now that we have both libraries installed, we can move forward with extending their functionality.

Publishing Configuration

To extend Laravel Workflow you can publish its configuration file to your project using the following artisan command:

php artisan vendor:publish --provider="Workflow\Providers\WorkflowServiceProvider" --tag="config"

Extending Workflows to Support Tags

Our goal is to be able to tag stored workflows and retrieve them using tags. To achieve this, we need to extend the StoredWorkflow model of the laravel-workflow package.

Here’s the extended model:

namespace App\Models;

use Spatie\Tags\HasTags;
use Workflow\Models\StoredWorkflow as BaseStoredWorkflow;
use Workflow\WorkflowStub;

class StoredWorkflow extends BaseStoredWorkflow
{
use HasTags;

public static function tag(WorkflowStub $workflow, $tag): void
{
$storedWorkflow = static::find($workflow->id());

if ($storedWorkflow) {
$storedWorkflow->attachTag($tag);
}
}

public static function findByTag($tag): ?WorkflowStub
{
$storedWorkflow = static::withAnyTags([$tag])->first();

if ($storedWorkflow) {
return WorkflowStub::fromStoredWorkflow($storedWorkflow);
}
}
}

Here’s a breakdown of what’s happening:

  • We’re using the HasTags trait from Spatie's library to give our StoredWorkflow model the ability to handle tags.
  • We’ve added some static helper methods. The tag method lets us tag a given workflow.
  • The findByTag method allows us to retrieve a workflow based on its tag. If a workflow with the specified tag is found, it gets converted back to a WorkflowStub for further use.

Modify the Configuration

Open the config/workflow.php file, and you will see various settings related to workflows. The one you need to modify to use the custom StoredWorkflow model is stored_workflow_model.

Update this line:

'stored_workflow_model' => Workflow\Models\StoredWorkflow::class,

To:

'stored_workflow_model' => App\Models\StoredWorkflow::class,

By doing this, you tell the laravel-workflow package to use your custom model instead of its default one.

Running Tagged Workflows

With the taggable StoredWorkflow ready, let's create a console command that creates, tags, retrieves, and runs a workflow.

namespace App\Console\Commands;

use App\Models\StoredWorkflow;
use App\Workflows\Simple\SimpleWorkflow;
use Illuminate\Console\Command;
use Workflow\WorkflowStub;

class Workflow extends Command
{
protected $signature = 'workflow';

protected $description = 'Runs a workflow';

public function handle()
{
// create a workflow and tag it
$workflow = WorkflowStub::make(SimpleWorkflow::class);
StoredWorkflow::tag($workflow, 'tag1');

// find the workflow by the tag and start it
$workflow = StoredWorkflow::findByTag('tag1');
$workflow->start();
while ($workflow->running());
$this->info($workflow->output());
}
}

This command can be run via artisan. That’s it!

Conclusion

By combining the powers of laravel-workflow and spatie/laravel-tags, we've successfully enabled tagging for our workflows. This makes managing and organizing workflows a breeze, especially in large applications with numerous workflows. As always, Laravel's extensible nature, combined with the vast array of community packages, provides developers with endless possibilities.

--

--