Pre-1.0. Not intended for public use yet. The API is subject to undocumented change, and these pages may already be wrong about it.

Skip to content

Choosing When to Publish ​

Publish meaningful status changes so routine saves do not create duplicate activities.

Publishing a Status Transition ​

Create an observer for the model whose status changes:

shell
php artisan make:observer OrderObserver --model=Order

In the observer's updated method, publish only the transitions the feed should show:

app/Observers/OrderObserver.php
php
<?php

namespace App\Observers;

use App\Models\Order;
use Storyfeed\Facades\Storyfeed;

class OrderObserver
{
    public function updated(Order $order): void
    {
        if (! $order->wasChanged('status')) {
            return;                                  // a save is not news
        }

        $verb = match ($order->status) {
            'confirmed' => 'confirm',
            'ready' => 'ready',
            'completed' => 'complete',
            default => null,                         // a draft is not news either
        };

        if ($verb === null) {
            return;
        }

        Storyfeed::activity()
            ->action($verb, $order)
            ->publish();
    }
}
php
<?php

namespace App\Observers;

use App\Models\Order;
use Storyfeed\Facades\Storyfeed;

class OrderObserver
{
    public function updated(Order $order): void
    {
        if (! $order->wasChanged('status')) {
            return;                                  // a save is not news
        }

        $verb = match ($order->status) {
            'confirmed' => 'confirm',
            'ready' => 'ready',
            'completed' => 'complete',
            default => null,                         // a draft is not news either
        };

        if ($verb === null) {
            return;
        }

        Storyfeed::record(
            verb: $verb,
            object: $order,
        );
    }
}

Register the observer in your service provider:

app/Providers/AppServiceProvider.phpboot()
php
use App\Models\Order;
use App\Observers\OrderObserver;

Order::observe(OrderObserver::class);

Define a headline for each verb:

routes/feed.php
php
use App\Models\Order;
use Storyfeed\Facades\Story;

Story::for(Order::class)->verb('confirm')
    ->headline(':actor confirmed :object');

Story::for(Order::class)->verb('ready')
    ->headline(':actor marked :object ready');

Story::for(Order::class)->verb('complete')
    ->headline(':actor completed :object');

When a staff member confirms a placed order:

SH

Choosing Transitions to Record ​

What HappenedActivityVerb
created as a draftno
saved with no status changeno
placed → confirmedyesconfirm
confirmed → readyyesready
ready → completedyescomplete

Use a separate verb for each transition so each has its own headline and keepLatest() can keep its latest activity. A single status verb with the state in data does not distinguish transitions this way.

Publishing From Domain Events ​

If the transition already dispatches a domain event, implement PublishesToFeed on that event and return its activity from toFeedActivity():

app/Events/OrderConfirmed.phptoFeedActivity()
php
return Storyfeed::activity()
    ->by($this->staff)
    ->action('confirm', $this->order);

See Publishing from Events.

Choosing a Publish Site ​

Call SiteUse For
action or service classrecording an event where it happens
domain event via PublishesToFeedevents with several existing listeners
model observerstatus changes and creation or deletion without a domain event

Released under the MIT License.