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

Engageify Laravel Package

cjmellor/engageify

Engageify is a Laravel package that adds engagement features to Eloquent models. Use simple traits to let users like, bookmark, rate, subscribe to, and follow resources, with polymorphic relationships and query scopes included.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with Composer, then publish the migrations before touching the database:
composer require cjmellor/engageify
php artsan vendor:publish --tag="engageify-migrations"

(Correct command: php artisan vendor:publish --tag="engageify-migrations", then php artisan migrate.)

  • If you are on MySQL or MariaDB, pin to v2.1.2 or later. No v2 release before 2.1.2 could create the engagement_counters table at all — the auto-generated unique index name overflowed MySQL's 64-character identifier limit. There is nothing to evaluate on 2.0.0–2.1.1; skip straight to 2.1.2.
  • Look first at the published migration files, not the README. They encode the engine-specific behaviour (index naming, collation pinning) and are the source of truth for what columns exist and what is unique.
  • Second thing to look at: the backed enum you will define for engagement "types" (verbs). In v2 the type column holds enum values, so your enum is effectively your schema.
  • First use case: add the package's engageable trait to a model such as Post, define an enum with cases like Like, Bookmark, Share, record an engagement from a controller, and read the counter for display. That end-to-end loop exercises both tables and the morph relation, which is 90% of what you will ever do with this package.
  • Verify the install immediately on your real driver — php artisan migrate:fresh against MySQL, not just SQLite. The package's own CI runs on SQLite only, so MySQL is the environment where surprises live.

Implementation Patterns

  • Enum as the verb vocabulary. One backed enum, one case per action. Use plain ASCII string values unless you specifically want emoji; they work, but see the collation note below.
  • Two tables, two jobs. engagements is the fact table (who engaged with what, when); engagement_counters is the denormalised aggregate (how many, keyed by engagementable + type). Read counters for listings and badges; query engagements for "has this user already liked this" and for toggling.
  • The counter unique index is per (engagementable, type), not per user. Nothing in engagement_counters is user-scoped. Don't try to repurpose it for per-user state.
  • Enforce a morph map early. Relation::enforceMorphMap() in a service provider before you write any engagement rows. The morph alias lands in the unique index on engagement_counters; changing it afterwards is a data migration, not a config change.
  • Upgrade path is re-publish + migrate. The 2.1.2 upgrade adds a pin_engagement_type_collation migration that converts type in place on both tables and is a no-op on every non-MySQL/MariaDB driver. No counter rebuild is required — no v2 release could have been installed on MySQL, so no counters can be collapsed.
  • Add your own MySQL job to CI. If you store non-ASCII or emoji verbs, a SQLite-only pipeline will not catch the collation class of bug this release fixed.
  • Test the read path with the same enum cases you write. Because the package writes and matches enum values verbatim, tests that pass a stringified case are testing something subtly different from production.

Gotchas and Tips

  • type is now utf8mb4_bin on MySQL/MariaDB — it is case-sensitive. Everything inside Engageify already writes verbatim enum values, so application behaviour is unchanged. But a raw query, report, or admin tool that filters engagements.type = 'like' when the enum case is LIKE will silently return nothing. Audit any hand-written SQL against these columns.
  • The old emoji bug is worth understanding even post-fix. utf8mb4_unicode_ci assigns most emoji the same sort weight, so the unique index treated an entire emoji set as a single value — one counter row for all of them. If you have any home-grown aggregate table with a default collation and an emoji-ish key, you have the same latent bug.
  • Identifier length is a general MySQL constraint, not a one-off. 64 characters. If you add indexes to these tables in your own migrations, or fork the published migration, keep generated names short and give long ones explicit names.
  • Debugging collation: SHOW CREATE TABLE engagement_counters; should show utf8mb4_bin on type. If it shows utf8mb4_unicode_ci, the pin_engagement_type_collation migration did not run.
  • Re-publishing overwrites published migrations. 2.1.2 requires vendor:publish --tag="engageify-migrations" again. Diff the published directory before committing — if you had local edits to the original migrations, they will be clobbered.
  • Don't infer driver behaviour from staging vs production. Postgres and SQLite already sort emoji distinctly and are untouched by the collation migration, so a case- or emoji-sensitivity bug can reproduce on MySQL only.
  • If you somehow ran a pre-2.1.2 v2 on MySQL by hand-fixing the index name, the "no rebuild needed" assurance does not apply to you — your counters may already be collapsed and need recounting from engagements.
  • Extension points: adding a new verb is zero-migration — one new enum case. Adding a new dimension to counting (per-team, per-locale) means altering the counter unique index, which is where you will hit both the identifier-length cap and the collation question again.
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.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
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