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

Laravel Testimonial Laravel Package

jeffersongoncalves/laravel-testimonial

A Laravel package for adding and managing testimonials in your application. It includes models, migrations, and simple helpers to create, store, and display customer testimonials, making it easy to integrate configurable testimonial sections into Blade views and other frontend templates.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package via Composer and publish its assets before touching any models:

composer require jeffersongoncalves/laravel-testimonial
php artisan vendor:publish --provider="JeffersonGoncalves\Testimonial\TestimonialServiceProvider"
php artisan migrate

The publish step is the important one — inspect what lands in config/testimonial.php and database/migrations/ first. Those two files tell you more about the package's design (approval states, rating support, media handling, translatable columns) than any README will. Read the migrations before migrating so you know exactly which columns you inherit and which you'll want to extend.

Where to look first, in order:

  1. config/testimonial.php — models, table names, disk for uploads, moderation defaults.
  2. The Testimonial model (or whatever the config points to) — check its fillable, casts, scopes, and any interfaces it expects your User model to implement.
  3. The migrations — confirm soft deletes, timestamps, and foreign key behaviour on user_id.

First use case: render approved testimonials on a marketing page. The typical flow is submit → moderate → display. Start by creating a testimonial through the model directly in Tinker to confirm the schema and casts behave:

Testimonial::create([
    'name' => 'Jane Doe',
    'content' => 'Shipped a feature in a weekend.',
    'rating' => 5,
    'approved' => true,
]);

Once that works, wire the submission form and the display loop. Because this is a fresh 1.0.0, treat the API surface as "whatever the source says" rather than "whatever the docs say" — the changelog link is the entirety of the release note, so there's no migration guide beyond the code itself.

Implementation Patterns

Submission from the front end. Put validation in a FormRequest rather than the controller, and lean on the package's own rules if it ships them. A common shape:

class StoreTestimonialRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'name'    => ['required', 'string', 'max:120'],
            'email'   => ['required', 'email'],
            'content' => ['required', 'string', 'max:2000'],
            'rating'  => ['nullable', 'integer', 'between:1,5'],
        ];
    }
}

Then create with approved => false and let moderation promote it. Never let a public form set approved from request input.

Moderation as a scope, not a column read. Wrap the approved filter in a local scope or query builder macro so the rest of the app never writes where('approved', true) by hand. When the package later changes the moderation column (or introduces a status enum), you change one place.

Filament / Nova admin panels. If you already run Filament, generate a resource against the package model instead of building CRUD from scratch — one resource with a toggle column for approval and a rating column gets you 80% of an admin UI. Keep the resource in your app, not in the vendor tree, so package upgrades don't clobber it.

Blade component for display. Wrap the render loop in an anonymous component (<x-testimonial-card :testimonial="$t" />) so you can swap layout per section of the site without duplicating markup. Pair it with @cache or a Cache::remember around the approved collection — testimonials are read-heavy and write-rare, which makes them ideal cache fodder.

Cache invalidation on approval. If you cache the approved set, hook the model's saved/deleted events to forget the key. This is the single most common source of "my testimonial isn't showing up" bug reports:

static::saved(fn () => Cache::forget('testimonials.approved'));
static::deleted(fn () => Cache::forget('testimonials.approved'));

Multi-tenancy / per-page filtering. If testimonials attach to a product, page, or tenant, check whether the package migration includes a nullable polymorphic testimonialable pair. If it does, use it; if not, add your own migration with a nullable morph rather than editing the vendor migration.

Gotchas and Tips

Publish tags are not guaranteed. vendor:publish --provider=... without a --tag may push config, migrations, views, and assets all at once. Check php artisan vendor:publish interactively first to see which tags exist, otherwise you risk overwriting previously customised files on a later re-publish. Commit the published files so you have a diff when you upgrade.

Migration timestamps vs. your existing schema. If you publish migrations and then run them out of order relative to your own, foreign keys on user_id can fail. Run php artisan migrate --pretend first and confirm the order, especially in projects with a crowded database/migrations folder.

The 1.0.0 release note is a changelog link and nothing else. There is no documented upgrade path, no deprecation list, and no guarantee of semver discipline going forward. Pin the version in composer.json ("^1.0" at minimum, or an exact 1.0.*) and read the diff before bumping. For a package at this maturity, treat every minor as potentially breaking.

Rating is likely an integer, not a decimal. If you need half-stars, store rating * 2 in your own column or add a migration; don't assume the package will change its column type. Also decide early whether rating is nullable — a null rating breaks naive avg() calls in aggregate queries.

Image/avatar handling depends on the configured disk. If the config defaults to public, remember php artisan storage:link in every environment, including CI and staging. A missing symlink renders broken images that look like a package bug and cost an hour to diagnose.

XSS on content. The package stores raw strings; it will not sanitise for you. If you render with {!! !!}, run it through a sanitizer (e.g. mews/purifier) or accept that a public submission form is an injection vector. Prefer {{ }} and strip markdown at write time.

Approval defaults can bite in tests. Seeders and factories created through the model's create() will use whatever default the migration sets for approved. If the default is false, your feature tests will render empty pages and look like a routing problem. Set approved => true explicitly in test fixtures.

Extension points to prefer. Model swapping via the config file (if exposed) beats subclassing the vendor class. Event listeners on saved/deleted beat overriding controller methods. A published Blade view beats a runtime HTML filter. Anything you must monkey-patch through a service provider bind() is a sign the package lacks the hook you need — note it and consider a thin repository wrapper in your app so a future package upgrade touches one file instead of twenty.

Debugging checklist when nothing renders: confirm the row exists and approved is true, confirm the scope you're using matches the column, confirm the cache key was forgotten, and confirm the view is resolving from your published path rather than the vendor path (php artisan view:clear after publishing).

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle