PHP code example of dashworthy / foundry

1. Go to this page and download the library: Download dashworthy/foundry 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/ */

    

dashworthy / foundry example snippets


use Dashworthy\Foundry\Data\Data;
use Illuminate\Contracts\Auth\Authenticatable;

final readonly class PublishPostData extends Data
{
    public function __construct(
        public Authenticatable $user,
        public Post $post,
    ) {}
}

use Dashworthy\Foundry\Actions\Action;

/**
 * Not `final`: subclassing or mocking in tests needs to reach in without
 * fighting the class declaration.
 *
 * @extends Action<PublishPostData, Post>
 */
class PublishPost extends Action
{
    protected function preconditions(): array
    {
        return [
            new ActorOwnsPost,
            new PostHasContent,
        ];
    }

    protected function handle(PublishPostData $data): Post
    {
        $data->post->update(['published_at' => now()]);

        return $data->post;
    }
}

it('has every action declaring handle()', function () {
    // ...reflect over your Action subclasses and assert hasMethod('handle')
});

use Closure;
use Dashworthy\Foundry\Data\Data;
use Dashworthy\Foundry\Preconditions\Precondition;

final class ActorOwnsPost implements Precondition
{
    public function handle(Data $data, Closure $next): mixed
    {
        if (! $data instanceof PublishPostData) {
            throw new InvalidArgumentException('ActorOwnsPost expects PublishPostData.');
        }

        if ($data->post->user_id !== $data->user->getAuthIdentifier()) {
            throw new NotPostOwner('You do not own this post.');
        }

        return $next($data);
    }
}

protected function preconditions(): array
{
    return [
        new ActorOwnsPost,
        PostHasContent::class, // resolved from the container when the chain runs
    ];
}

$post = PublishPost::run(new PublishPostData($user, $post));
// or, to hold the instance:
$post = PublishPost::make()->execute(new PublishPostData($user, $post));

if (PublishPost::make()->permits($data)) {
    // show the "Publish" button
}

use Dashworthy\Foundry\Queries\Query;
use Illuminate\Database\Eloquent\Builder;

/**
 * @extends Query<PendingInvitationsData, TeamInvitation>
 */
class PendingInvitations extends Query
{
    /**
     * @return Builder<TeamInvitation>
     */
    protected function handle(PendingInvitationsData $data): Builder
    {
        return TeamInvitation::query()
            ->whereRaw('LOWER(email) = ?', [$data->email])
            ->whereNull('accepted_at')
            ->latest();
    }
}

$invitations = PendingInvitations::run(new PendingInvitationsData($email)); // Collection<int, TeamInvitation>

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (NotPostOwner $e, Request $request) {
        return back()->withErrors(['action' => $e->getMessage()]);
    });
})

/**
 * @extends Action<ChargeCardData, Charge>
 */
class ChargeCard extends Action
{
    private ?string $chargeId = null;

    protected function handle(ChargeCardData $data): Charge
    {
        $charge = $this->gateway->charge($data->amount);
        $this->chargeId = $charge->id;

        // ... more work that might throw ...

        return $charge;
    }

    protected function rollback(): void
    {
        if ($this->chargeId !== null) {
            $this->gateway->refund($this->chargeId);
        }
    }
}

DB::transaction(function () use ($data) {
    PublishPost::run($data); // runs normally
});
bash
php artisan vendor:publish --tag=foundry-config