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

Laravel Comments Laravel Package

beyondcode/laravel-comments

Add nested, approvable comments to any Laravel Eloquent model. Use a simple HasComments trait, create comments as the current user or on behalf of another user, and manage approval via an is_approved flag with migrations and config publishing included.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require beyondcode/laravel-comments
    

    The package auto-registers.

  2. Publish Assets:

    php artisan vendor:publish --provider="BeyondCode\Comments\CommentsServiceProvider" --tag="migrations"
    php artisan vendor:publish --provider="BeyondCode\Comments\CommentsServiceProvider" --tag="config"
    

    Run migrations:

    php artisan migrate
    
  3. Enable Comments on a Model: Add the HasComments trait to your Eloquent model (e.g., Post):

    use BeyondCode\Comments\Traits\HasComments;
    
    class Post extends Model
    {
        use HasComments;
    }
    
  4. First Comment:

    $post = Post::find(1);
    $post->comment('This is my first comment!');
    

Where to Look First

  • Config File: config/comments.php (e.g., delete_replies_along_comments, commentable_models).
  • Blade Directives: @comments for rendering in views (if using the included Blade helpers).
  • Events: CommentAdded/CommentDeleted for custom logic (e.g., notifications).

First Use Case

Add Comments to a Blog Post:

// In a controller or Blade file:
$post = Post::find(1);

// Create a comment as the current user (if authenticated):
$post->comment('Great post!');

// Or as a specific user:
$post->commentAsUser($user, 'Thanks for sharing!');

// Display comments in Blade:
@comments($post)
    @foreach($comments as $comment)
        <div>{{ $comment->body }}</div>
        @comments($comment) <!-- Nested replies -->
    @endforeach
@endcomments

Implementation Patterns

Core Workflows

  1. Comment Creation:

    • Authenticated User: Use comment() (auto-associates with current user).
      $post->comment('Default comment');
      
    • Specific User: Use commentAsUser().
      $post->commentAsUser($user, 'Comment as user');
      
    • Bulk Creation: Loop through an array of comments:
      $comments = ['Comment 1', 'Comment 2'];
      foreach ($comments as $body) {
          $post->comment($body);
      }
      
  2. Moderation:

    • Approve/Reject: Toggle is_approved via methods or query builder.
      $comment->approve(); // Manually approve
      $post->comments()->approved()->get(); // Fetch approved only
      
    • Auto-Approval: Implement Commentator interface in your User model:
      public function needsCommentApproval($model): bool {
          return $model instanceof Post; // Only auto-approve for Posts
      }
      
  3. Nested Replies:

    • Comments are polymorphic (can reply to other comments).
      $comment = Comment::find(1);
      $comment->commentAsUser($user, 'Reply to comment');
      
    • Configure reply deletion in config/comments.php:
      'delete_replies_along_comments' => true,
      
  4. Querying:

    • Eager Load: Use withComments() on parent models.
      $posts = Post::withComments()->get();
      
    • Scopes: Filter by approval status or date:
      $post->comments()->approved()->latest()->take(10)->get();
      

Integration Tips

  • Blade Helpers: Use @comments directive for nested rendering:
    @comments($post)
        @foreach($comments as $comment)
            <div>{{ $comment->body }}</div>
            @comments($comment) <!-- Recursive replies -->
        @endforeach
    @endcomments
    
  • Events: Listen for CommentAdded/CommentDeleted:
    use BeyondCode\Comments\Events\CommentAdded;
    
    CommentAdded::subscribe(function ($event) {
        // Send notification, log, etc.
    });
    
  • APIs: Return comments as resources:
    return new CommentResource($post->comments()->approved()->get());
    
  • Testing: Use CommentFactory (if available) or seed test data:
    $post = Post::factory()->create();
    $post->comment('Test comment');
    

Advanced Patterns

  1. Custom Validation: Override the validateComment method in your model:

    use BeyondCode\Comments\Contracts\CommentValidator;
    
    class Post extends Model implements CommentValidator
    {
        public function validateComment($body, $user = null): array
        {
            return ['body' => ['required', 'max:500']];
        }
    }
    
  2. Storage Engines: Extend the Comment model to support alternative storage (e.g., Redis):

    class RedisComment extends Comment
    {
        public function save(array $options = [])
        {
            // Custom logic
        }
    }
    
  3. Multi-Tenancy: Use Laravel’s global scopes or middleware to filter comments by tenant:

    class TenantScope implements \Illuminate\Database\Eloquent\Scope
    {
        public function apply(Builder $builder, Model $model)
        {
            $builder->where('tenant_id', auth()->tenant()->id);
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Migration Conflicts:

    • If you’ve customized the comments table, merge the published migration carefully. The package assumes default column names (e.g., commentable_id, commentable_type).
  2. Polymorphic Relationships:

    • The commentable_type column uses Laravel’s polymorphic naming (App\Models\Post). Ensure your models are fully qualified (e.g., avoid Post vs. App\Models\Post mismatches).
  3. Auto-Approval Logic:

    • The needsCommentApproval method is called after comment creation. Return true to mark as unapproved, false to auto-approve. Test edge cases (e.g., null models).
  4. Reply Deletion:

    • Setting delete_replies_along_comments to true triggers cascading deletes. Test performance with deep reply trees (e.g., 10+ levels).
  5. Blade Directives:

    • The @comments directive assumes the comments relationship exists. If using custom relationship names, override the directive or use the raw relationship:
      @foreach($post->getComments as $comment)
      

Debugging Tips

  1. Missing Comments:

    • Verify the commentable_type and commentable_id match your model’s namespace and ID.
    • Check for soft deletes if using SoftDeletes on the commentable model.
  2. Approval Not Working:

    • Ensure the is_approved column exists (published migration includes it).
    • Debug the needsCommentApproval method with dd($model, $user) to confirm logic.
  3. Nested Comments Not Rendering:

    • Confirm the Comment model uses HasComments (it does by default).
    • Check for infinite loops in Blade by limiting recursion depth:
      @comments($comment, 3) <!-- Max 3 levels deep -->
      
  4. Performance Issues:

    • Use withComments sparingly on large datasets. Consider lazy-loading or pagination:
      $post->load(['comments' => function ($query) {
          $query->approved()->latest()->take(20);
      }]);
      

Extension Points

  1. Custom Comment Models: Extend the Comment model to add fields (e.g., rating):

    class ExtendedComment extends Comment
    {
        protected $casts = ['rating' => 'integer'];
    }
    

    Update the migration and config accordingly.

  2. Custom Validation: Override the validateComment method in your commentable model (as shown above).

  3. Custom Storage: Replace the Comment model’s table or use a custom repository:

    class CommentRepository
    {
        public function create(array $data)
        {
            // Custom logic (e.g., Redis, database)
        }
    }
    
  4. Events: Subscribe to CommentAdded/CommentDeleted for side effects:

    CommentAdded::subscribe(function ($event) {
        // Send email, update analytics, etc.
    });
    

Configuration Quirks

  1. commentable_models: The config allows whitelisting models that can receive comments. If empty, all models with HasComments are allowed. Useful for security:

    'commentable_models' => [
        'App\Models\Post',
        'App\Models\Article',
    ],
    
  2. delete_replies_along_comments: Defaults to false. Set to true to enable casc

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.
ilhamsyabani/laravel-volt-starter
thethunderturner/filament-latex
ghostcompiler/laravel-querybuilder
webrek/laravel-telescope-mongodb
anousss007/blatui
zatona-eg/zatona-eg-api
cocosmos/filament-sticky-save-bar
patrickbussmann/oauth2-apple
3brs/enterprise-security-bundle
anousss007/vigilance
supportpal/eloquent-model
ardenexal/fhir-models
laravel-at/laravel-image-sanitize
romalytar/yammi-audit-log-laravel
ardenexal/fhir-validation
arshaviras/weather-widget
laravel-chronicle/core
sunchayn/nimbus
daikazu/eloquent-salesforce-objects
unseen-codes/chat