Weave Code
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

Contracts Laravel Package

wp-starter/contracts

Laravel/PHP contract interfaces for a WordPress starter kit. Defines shared abstractions to keep packages decoupled and implementations swappable, providing a lightweight base for building WordPress integrations in a Laravel-style architecture.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require wp-starter/contracts
    

    No additional configuration is required—this is a pure contract package with no runtime dependencies.

  2. First Use Case: Defining Interfaces Use the package to enforce structure in your Laravel application by defining interfaces for:

    • Custom service contracts (e.g., PostServiceInterface).
    • Repository patterns (e.g., PostRepositoryInterface).
    • Event dispatchers or listeners (e.g., PostPublishedEventInterface).

    Example:

    use WpStarter\Contracts\Repository\RepositoryInterface;
    
    class PostRepository implements RepositoryInterface
    {
        // Implement required methods: find(), create(), update(), delete()
    }
    
  3. Where to Look First

    • Browse the src/Contracts directory for built-in interfaces (if any).
    • Check the README.md (if available) for package-specific conventions.
    • Use Laravel’s IDE autocompletion to discover interfaces dynamically.

Implementation Patterns

1. Repository Pattern Integration

Use contracts to decouple data access logic from business logic. Workflow:

  • Define a repository interface (e.g., UserRepositoryInterface).
  • Implement it in a concrete class (e.g., EloquentUserRepository).
  • Inject the interface into services/controllers via Laravel’s container.

Example:

// app/Contracts/UserRepositoryInterface.php
namespace App\Contracts;
use WpStarter\Contracts\Repository\RepositoryInterface;

interface UserRepositoryInterface extends RepositoryInterface
{
    public function findByEmail(string $email);
}

// app/Repositories/EloquentUserRepository.php
class EloquentUserRepository implements UserRepositoryInterface
{
    // ...
}

2. Service Layer Abstraction

Leverage contracts to define service boundaries. Workflow:

  • Create a service interface (e.g., OrderServiceInterface).
  • Implement it with Laravel’s ServiceProvider or standalone class.
  • Bind the interface to its implementation in AppServiceProvider.

Example:

// app/Contracts/OrderServiceInterface.php
namespace App\Contracts;
use WpStarter\Contracts\Service\ServiceInterface;

interface OrderServiceInterface extends ServiceInterface
{
    public function processPayment(int $orderId);
}

// app/Providers/AppServiceProvider.php
public function register()
{
    $this->app->bind(
        OrderServiceInterface::class,
        StripeOrderService::class
    );
}

3. Event-Driven Architecture

Use contracts to standardize event handling. Workflow:

  • Define event interfaces (e.g., OrderCreatedEventInterface).
  • Dispatch events via Laravel’s Event facade.
  • Listen using contract-based listeners.

Example:

// app/Contracts/Events/OrderCreatedEventInterface.php
namespace App\Contracts\Events;
use WpStarter\Contracts\Event\EventInterface;

interface OrderCreatedEventInterface extends EventInterface
{
    public function getOrderId(): int;
}

// app/Listeners/SendOrderConfirmation.php
class SendOrderConfirmation implements ShouldHandleOrderCreatedEventInterface
{
    public function handle(OrderCreatedEventInterface $event)
    {
        // Logic here
    }
}

4. Testing Contracts

Mock interfaces in PHPUnit tests to isolate dependencies. Example:

public function test_order_processing()
{
    $mockRepository = $this->createMock(UserRepositoryInterface::class);
    $mockRepository->method('findById')->willReturn(new User());

    $service = new OrderService($mockRepository);
    $this->assertTrue($service->processOrder(1));
}

Gotchas and Tips

1. Pitfalls

  • Over-Abstraction: Avoid creating contracts for trivial methods (e.g., getId()). Focus on high-level behaviors.
  • Tight Coupling: If contracts are too specific (e.g., extends EloquentRepositoryInterface), they may limit flexibility. Prefer generic interfaces like RepositoryInterface.
  • Missing Documentation: Without clear docs, contracts may become ambiguous. Add PHPDoc comments to interfaces:
    /**
     * @method Model|null find(int $id)
     * @method Model create(array $data)
     */
    interface RepositoryInterface { ... }
    

2. Debugging

  • Interface Not Found Errors: Ensure the use statements in your contracts match the package’s namespace (e.g., WpStarter\Contracts\...).
  • Autoloading Issues: Run composer dump-autoload if interfaces aren’t recognized.
  • IDE Support: Configure your IDE (PHPStorm/VSCode) to recognize the package’s src directory as a source root.

3. Configuration Quirks

  • No Runtime Config: This is a contract package—no config/wp-starter.php exists. All behavior is defined via interfaces.
  • Laravel Service Binding: If using Laravel’s container, bind interfaces to implementations in AppServiceProvider:
    $this->app->bind(
        \WpStarter\Contracts\Repository\RepositoryInterface::class,
        \App\Repositories\EloquentRepository::class
    );
    

4. Extension Points

  • Custom Contracts: Extend existing interfaces to add domain-specific methods:
    interface CustomPostRepositoryInterface extends RepositoryInterface
    {
        public function findPublishedPosts();
    }
    
  • Trait Usage: Combine contracts with traits for reusable logic (e.g., SoftDeletes trait in repositories).
  • Package Integration: Use contracts to enforce compatibility with other packages (e.g., Spatie’s Repository package). Example:
    use Spatie\Repository\RepositoryInterface as SpatieRepository;
    use WpStarter\Contracts\Repository\RepositoryInterface;
    
    class HybridRepository implements RepositoryInterface, SpatieRepository { ... }
    

5. Performance Tips

  • Avoid Interface Overhead: Contracts add zero runtime overhead, but excessive abstraction can slow down development. Balance clarity with simplicity.
  • Lazy Loading: For heavy repositories, implement lazy loading in contract methods:
    public function scopeActive(): Builder
    {
        return $this->model->where('is_active', true);
    }
    
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.
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui