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

Eloquent Publishing Laravel Package

lemaur/eloquent-publishing

Add publishing support to Laravel Eloquent models with a simple trait. Manage publish dates, query scopes and helpers, plus custom migration blueprint methods to quickly add publishing columns and build publishable content workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require lemaur/eloquent-publishing
    
  2. Add the Publishes trait to your Eloquent model:
    use Lemaur\Publishing\Database\Eloquent\Publishes;
    
    class Post extends Model
    {
        use Publishes;
    }
    
  3. Add the publishes() method to your migration:
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->publishes(); // Adds `published_at` timestamp column
    });
    

First Use Case

Publish a model in a controller:

$post = Post::find(1);
$post->publish(); // Publishes immediately with current timestamp

Implementation Patterns

Core Workflows

  1. Model Lifecycle Management

    • Publish: $model->publish() or $model->publish(Carbon::parse('2025-01-01'))
    • Unpublish: $model->unpublish()
    • Check Status:
      $model->isPublished(); // true if published (past or present)
      $model->isPlanned();   // true if scheduled for future
      
  2. Query Scoping

    • Filter published/planned records:
      Post::onlyPublished()->get(); // Only past/present published
      Post::onlyPlanned()->get();   // Only future-published
      Post::withoutPlannedAndPublished()->get(); // Unpublished
      
    • Order by publish date:
      Post::latestPublished()->get(); // Newest first
      Post::oldestPlanned()->get();   // Oldest future date first
      
  3. Migration Patterns

    • Use publishes() blueprint methods:
      $table->publishes('custom_date'); // Custom column name
      $table->publishesTz();            // Timezone-aware timestamp
      $table->dropPublishes();          // Remove column
      
  4. Event-Driven Extensions

    • Listen for publish/unpublish events:
      event(new Publishing($model));
      event(new Published($model));
      

Integration Tips

  • Custom Column Names: Define PUBLISHED_AT constant in your model and use it in migrations.
  • Soft Publishing: Combine with SoftDeletes for unpublished records:
    use SoftDeletes;
    
    class Post extends Model
    {
        use Publishes, SoftDeletes;
    }
    
  • API Responses: Add publish status to JSON:
    public function toArray()
    {
        return [
            'title' => $this->title,
            'is_published' => $this->isPublished(),
            'published_at' => $this->published_at,
        ];
    }
    

Gotchas and Tips

Pitfalls

  1. Column Name Mismatch

    • If PUBLISHED_AT constant is defined in the model but the migration uses a different name, queries will fail.
    • Fix: Ensure consistency between model and migration.
  2. Timezone Issues

    • publishes() uses timestamp (UTC), while publishesTz() uses timestampTz (timezone-aware).
    • Tip: Use publishesTz() if your app relies on timezone-specific publishing.
  3. Event Ordering

    • publishing fires before published, but unpublishing fires before unpublished.
    • Debugging: Use dd() in event listeners to verify order.
  4. Null Handling

    • isPublished() returns false for null values, but isPlanned() requires a future date.
    • Edge Case: A null published_at is neither published nor planned.

Debugging Tips

  • Check Column Existence: Verify the published_at column exists in the DB:
    php artisan schema:dump
    
  • Log Events: Add debug logs in event listeners:
    event(new Publishing($model));
    Log::debug('Publishing model', ['id' => $model->id]);
    
  • Query Inspection: Use Laravel Debugbar to inspect scoped queries:
    Post::onlyPublished()->toSql(); // Show raw SQL
    

Extension Points

  1. Custom Logic

    • Override trait methods (e.g., publish()) to add validation:
      public function publish(?CarbonInterface $date = null)
      {
          if (!$this->isApproved()) {
              throw new \Exception('Must be approved first');
          }
          $this->published_at = $date ?? now();
          $this->save();
      }
      
  2. Custom Events

    • Extend events with additional data:
      event(new CustomPublished($model, ['author_id' => auth()->id()]));
      
  3. Policy Integration

    • Restrict publish/unpublish actions:
      public function update(PublishPost $request, Post $post)
      {
          $this->authorize('publish', $post);
          $post->publish();
      }
      
  4. Testing

    • Mock the trait for unit tests:
      $model = new class extends Model {
          use Publishes;
      };
      $model->publish();
      $this->assertNotNull($model->published_at);
      
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.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime