sammakescode/business-rules

A library for extracting common business rules into isolating classes

v1.0.0 2025-09-10 12:21 UTC

This package is auto-updated.

Last update: 2025-09-11 11:00:30 UTC


README

A simple library that allows you to encapsulate and reuse common business logic.

Requirements

  • PHP >= 8.1

Installation

To install this library, simply require it using composer.

composer require sammakescode/business-rules

Usage

Let's say you want to prevent users from posting under certain conditions. You might create a business rule like this...

<?php

namespace App\BusinessRules;

use SamMakesCode\BusinessRules\BusinessRule;
use App\Models\User;

class UserCanPost implements BusinessRule
{
    public function __construct(
        public readonly User $user,  
    ) {
    
    public function isSatisfied(): bool
    {
        return !$this->user->isBanned && $this->user->isAuthor();
    }
    
    public function getFailureMessage(): string
    {
        return 'This user isn\'t allowed to post!';
    }
}

Given this business rule, your service might look like this:

<?php

namespace App\Services;

use SamMakesCode\BusinessRules\BusinessRules;
use App\Models\User;

class PostsService
{
    use BusinessRules;

    public function createPost(
        User $author,
        string $title,
        string $slug,
        string $body,    
    ): Post {
        $this->checkBusinessRules([
            new UserCanPost($user),
            // Additional business rules, if you want
        ]);
        
        // Create a post
    }
}

In the event your business rule fails, you can handle it like this:

// In some controller...

try {
    $postsService->createPost($user, 'Title', 'slug', 'The body of a post')
} catch (BusinessRulesNotSatisfied $exception) {
    return redirect()->back()->with([
        'errors' => $exception->getFailingRuleMessages(),
    ]);
}

Why?

Isn't this just creating classes for conditional logic? Well, yes. But in my experience there are often times when the same collection of conditionals are often re-used, making it a pain to update them all.

Additionally, this library lets you put a name on groups of conditionals that you want to bunch together.

Should you use it? I dunno. It's here because I use it and I'm bored of copy and pasting it between projects.