Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Common Laravel Package

inisiatif/common

Shared Laravel utilities for Inisiatif Zakat Indonesia: a Branch model, UUID and integer primary key traits, branch relations, Eloquent repository and tagged-cache abstractions, contracts, and common exceptions for consistent apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and verify the package resolves against your Laravel/PHP constraint first — the supported matrix is tight (PHP 8.2–8.4, Laravel 10–12):

composer require inisiatif/common

Nothing else is required for bootstrapping: CommonServiceProvider is auto-discovered, so the Branch model, traits, contracts, exceptions, and the branches migration are available immediately after composer dump-autoload.

Where to look first. The README is a surface-level catalogue, not an API reference. Before writing code against it, open vendor/inisiatif/common/src and read:

  • Concerns/UuidPrimaryKey.php and Concerns/IntegerPrimaryKey.php — confirm exactly which properties ($incrementing, $keyType, $key, boot hook) they mutate.
  • Concerns/HasBranch.php — confirm the foreign key name (branch_id?) and relation type it assumes.
  • Abstracts/AbstractRepository.php — confirm the constructor signature and which methods it implements from ModelRepositoryInterface, because that dictates how much you must override.
  • Contracts/ — the interfaces are the real contract surface your app will depend on.

First use case to pilot. Pick the most branch-heavy model in your app and wire it end-to-end:

use Illuminate\Database\Eloquent\Model;
use Inisiatif\Package\Common\Concerns\HasBranch;
use Inisiatif\Package\Common\Contracts\ResourceInterface;

class Donor extends Model implements ResourceInterface
{
    use HasBranch;
}

Then Donor::first()->branch should return the related Branch. If that works, run one repository against it before rolling out further.

Optional config publish. Only publish if you need to change the branch table name or override config defaults:

php artisan vendor:publish --provider="Inisiatif\Package\Common\Providers\CommonServiceProvider"

The COMMON_BRANCH_TABLE_NAME env var is the supported override (branches by default) — set it before running migrations if you use a non-default name.

Implementation Patterns

Branch-aware model pattern. Add HasBranch alongside ResourceInterface so the model participates in the repository layer too. This is the highest-value, lowest-risk adoption path — it removes a belongsTo(Branch::class) definition from every model and keeps the FK convention uniform across services.

Repository pattern. The intended shape is model implements ResourceInterface, repository extends AbstractRepository and declares $model:

use Inisiatif\Package\Common\Abstracts\AbstractRepository;

class DonorRepository extends AbstractRepository
{
    protected $model = Donor::class;
}

Type-hint your application services against ModelRepositoryInterface / EloquentAwareRepositoryInterface rather than the concrete class — that's the whole point of the abstraction and it makes fakes in tests trivial.

Choosing a primary key trait. Use UuidPrimaryKey where IDs cross service boundaries or are exposed publicly (donor portals, external APIs, sync between branch systems). Use IntegerPrimaryKey for internal, high-volume, join-heavy tables where UUID index bloat isn't worth it. Do not mix both on one model.

Cache-aware repositories. If you implement TaggableCacheAwareInterface with the TaggableCacheAware trait, treat it as an invalidation discipline, not a magic speedup: every write path must bust the right tags. A practical convention is to tag per-resource and per-branch (e.g. donor, branch:{id}), and invalidate on model saved/deleted events.

Exception mapping. Register the domain exceptions once in bootstrap/app.php (Laravel 11+) or app/Exceptions/Handler.php and map them to HTTP responses:

  • DomainModelNotExistException → 404
  • DomainModelExistException → 409
  • DomainActionException → 422
  • DomainException → catch-all 400

Doing this once keeps controllers free of try/catch noise and makes service-layer failures legible to API clients.

Migration handling. The branches migration ships enabled by default. If you already own a branches table (Filament, Nova, Spatie multitenancy) disable it in AppServiceProvider::boot():

use Inisiatif\Package\Common\Common;

Common::ignoreMigrations();

Testing. Because everything hangs off interfaces, tests can bind a fake ModelRepositoryInterface in the container instead of hitting a DB. For feature tests that do hit the DB, decide explicitly whether to ignoreMigrations() so the package's branches table doesn't collide with your fixture schema.

Gotchas and Tips

Version 3.0.0 is a namespace break. If any code imports Inisiatif\Package\Contract\..., it will fatal. Pin inisiatif/common:^3.0 and grep the codebase for the old namespace before upgrading. Interfaces now live under Inisiatif\Package\Common\Contracts\.

Proprietary license, zero adoption. There are no dependents, no stars, no community answers. Budget time to read the vendored source; treat the README as incomplete. Consider a thin first-party wrapper (your own interface extending theirs) so a future swap-out is a one-file change rather than a repo-wide find-and-replace.

Cache tags require a taggable store. TaggableCacheAware will silently misbehave (or throw BadMethodCallException on tags()) under the file or database cache drivers. Confirm CACHE_STORE is redis or memcached in any environment that exercises this trait — this is the most likely production surprise.

HasBranch assumes a schema. It almost certainly expects a branch_id column on your table and the configured Branch model. If your table uses cabang_id or a polymorphic relation, the trait won't fit — write the relation manually rather than fighting it.

Config publish ordering. Publishing config after migrating means the migration may have already created branches under the default name while your config points elsewhere. Publish, then migrate.

UUID trait ordering. Traits that define boot{TraitName} run in declaration order. If your model also uses SoftDeletes or a custom booted() that sets $this->keyType, verify the resulting getKeyType() and getIncrementing() at runtime with php artisan tinker — a wrong combination produces non-obvious "duplicate primary key" or "null ID" errors from Eloquent rather than an exception at boot.

Debugging checklist when a relation or repository method returns nothing:

  1. composer dump-autoload after any provider/config change.
  2. php artisan about to confirm the provider is discovered.
  3. Model::getKeyName(), getKeyType(), getIncrementing() in tinker.
  4. Dump the SQL with ->toSql() / DB::listen() — HasBranch FK typos surface as empty collections, not errors.

Extension points worth knowing. The config file (post-publish) is the sanctioned override surface; Common::ignoreMigrations() is the only documented runtime switch. Beyond that, the package exposes no macros or bindings you can hook — so if you need different behaviour, extend AbstractRepository rather than patching the vendor code, and keep ResourceInterface as the marker your own models implement so future package upgrades stay non-breaking.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings