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

Tomato Contracts Laravel Package

tomatophp/tomato-contracts

Core interfaces and contracts for the TomatoPHP ecosystem. Defines shared abstractions that keep TomatoPHP modules consistent, decoupled, and interoperable, helping developers build Laravel applications and packages against standardized contracts.

View on GitHub
Deep Wiki
Context7

Getting Started

tomato-contracts is an early-stage (v0.0.1) package of PHP interfaces used across the TomatoPHP ecosystem. It ships no runtime behavior — it is a vocabulary layer that other packages (CRUD generators, plugins, admin panels) agree on.

Minimal steps:

composer require tomatophp/tomato-contracts

Where to look first:

  1. src/Contracts/ (or src/) — the interface definitions themselves. Read every file before writing code; the method signatures are the spec.
  2. composer.json — check php and illuminate/* constraints. Pin these to match your app's Laravel version before installing.
  3. The README and the linked changelog — v0.0.1 has no migration notes, so assume the surface is unstable.

First use case: instead of type-hinting a concrete TomatoPHP class in your own plugin, code against the contract.

use TomatoPHP\Contracts\...\SomeContract;

public function __construct(private readonly SomeContract $service) {}

Then bind an implementation in a service provider. Because the package only defines contracts, you must supply the concrete class — or depend on the package that does (e.g. tomato-admin, tomato-crud, etc.).

Implementation Patterns

Bind interfaces in your provider. Contracts with no implementation will throw BindingResolutionException when resolved. Register them explicitly:

public function register(): void
{
    $this->app->bind(SomeContract::class, MyImplementation::class);
    $this->app->singleton(OtherContract::class, OtherImplementation::class);
}

Write your own classes against the contract, not the framework. This is the whole point — you can swap TomatoPHP internals without touching your code, and the upstream packages can evolve their concretes.

class MyService implements SomeContract
{
    public function handle(array $payload): mixed
    {
        // ...
    }
}

Use contracts for plugin/extension discovery. A common TomatoPHP pattern is a plugin manager resolving an array of classes that implement a contract. Filter your manifests with is_subclass_of($class, SomeContract::class) before registering.

Testing. Since these are interfaces, mock them freely:

$this->mock(SomeContract::class)
    ->shouldReceive('handle')
    ->once()
    ->andReturn(true);

Integration tip — extend, don't modify. If a signature doesn't fit, wrap it in an adapter class that implements the contract, and bind the adapter. Never fork the package into your app; you'll lose upgrades.

Pair with the concrete package. Contracts alone do nothing useful. Install the matching implementation package (tomatophp/tomato-*) in the same composer require step so autoloading and provider registration line up.

Gotchas and Tips

  • v0.0.1 = pre-stable. There is no documented BC promise. Pin an exact version ("tomatophp/tomato-contracts": "0.0.1") or use a ~0.0.1 range with care. Any 0.x bump may rename or remove a method.
  • Empty changelog. The release only links to commits. Before upgrading, read the commit list, not the changelog, to spot signature changes.
  • Contracts ship no service provider behavior for you. If the package does register a provider, verify with php artisan about or php artisan vendor:publish --list before assuming bindings exist.
  • Namespace assumptions. Confirm the real namespace from composer.json (autoload.psr-4) — do not guess TomatoPHP\Contracts\. A wrong namespace is the most common "class not found" in early packages.
  • Laravel/PHP version skew. Check the require block. If it needs PHP 8.2 and you're on 8.1 (or Laravel 9 vs 11), composer will silently resolve to an older tag or fail — use composer why-not tomatophp/tomato-contracts to debug.
  • Interface drift across packages. Different TomatoPHP packages may target different tomato-contracts versions. Run composer update --with-dependencies and check composer show -t for conflicts if you get Declaration must be compatible errors.
  • Debugging resolution failures. Use php artisan tinker and app()->make(SomeContract::class) to isolate a missing binding; the stack trace will name the contract, not the caller.
  • Extension point. If you need behavior the interfaces don't cover, add your own interface in your app package that extends the Tomato one — this keeps future upgrades additive.
  • Don't leak contracts into public APIs of your own package unless you're willing to track upstream's unstable versions; hide them behind your own interfaces where possible.

Given the version number and lack of release notes, treat this as a watch-and-pin dependency rather than a foundation until the API stabilizes past 0.1.

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.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk