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

Likes For Laravel Laravel Package

roundly-consulting/likes-for-laravel

A lightweight Laravel package for adding like and unlike functionality to Eloquent models. Supports polymorphic relationships, toggle helpers, like counts, and eager loading so you can build reactions, favorites, or upvotes with minimal setup.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Scope of this release. 1.1.2 is not a maintenance release. It contains a consumer-visible behaviour change to the broadcast payload in three events — Liked, Unliked, and ReactionChanged — plus two maintenance items (dev testing dependency to ^1.6, and CI running the PostgreSQL/MySQL legs on tmpfs). The change: actor_type and likeable_type now carry the model's class basename (User, Post) and never the PHP class name. Without a morph map this replaces App\Models\User; with a morph map it replaces the configured alias with the basename. The changelog explicitly states that listeners matching on the old value need updating, and that the channel name is unchanged.

This is a breaking change shipped in a patch release. That is the headline finding. Any consumer that compares actor_type/likeable_type against User::class, App\Models\User, or a morph alias will silently stop matching. The package has not been versioned for it (no 2.0.0, no deprecation window, no config toggle mentioned). Two consequences for us: (1) an immediate correctness risk for anyone upgrading on a caret constraint, and (2) a governance signal — patch releases in this family may carry behaviour changes, so ^1.1.0 is not a safe default constraint for us.

Capability discovery. The release notes at last describe the package's function: it emits broadcast events for likes, unlikes, and reaction changes against a polymorphic likeable (and an actor), with per-likeable channels. That answers the largest open question from the 1.1.1 assessment. It also tells us the public surface is event/broadcast payloads and channels — i.e. the contract is a wire format consumed by clients we do not necessarily control (Laravel Echo / JS, mobile apps, external subscribers, queue-serialized payloads). Wire formats are the highest-cost thing to change.

Architecture fit. Unchanged from 1.1.1: a Composer-installed Laravel library in the roundly vendor namespace, hard-dependent on roundly/package-toolkit, best suited to an application already running other roundly/* packages. New consideration: this package sits on the boundary between the app and its real-time clients, so its fit depends on whether we accept vendor-controlled wire formats. If we have external or mobile subscribers with independent release cycles, vendor-driven payload changes are expensive for us.

Integration feasibility. Mechanically still a composer require/composer update. But 1.1.2 introduces required work: an audit of every consumer of these three events, plus a coordinated listener/client update. The audit is cheap in a single codebase (grep for actor_type, likeable_type, class_basename, ::class comparisons in listeners, and any stored/queued payloads) and expensive across client apps, partner integrations, or anything that persisted historical payloads. Note also that the change partially defeats the purpose of a morph map: teams use aliases specifically to keep internal class names off the wire and to decouple wire format from class names — 1.1.2 replaces the alias with the basename, so the wire value is now derived from the class name again even for morph-mapped models.

Technical risk. Moderate, concentrated on consumers rather than on the framework. Specific risks: (1) silent behavioural mismatch — listeners fail to match and no exception is raised, so likes appear to work while reactions stop propagating; (2) rolling-deploy skew — during a canary or blue/green, new publishers emit basenames while old subscribers still expect FQCNs; (3) mixed-version fleets — two app instances on 1.1.1 and 1.1.2 publishing to the same channel produce two different payload shapes; (4) historical data — any table, queue, log, or analytics store holding the old values needs a backfill or a compatibility read; (5) the SemVer discipline risk above. Positives: the channel name is unchanged (so subscriptions and authorization are unaffected), the change is uniform and reversible, and the CI/tooling updates are evidence of active maintenance and multi-database test coverage (PostgreSQL and MySQL legs) — which partly answers the 1.1.1 open question on test breadth.

Key questions for the maintainer/vendor.

  • Why was a payload-shape change shipped as a patch rather than a major, and is that the intended versioning policy going forward?
  • Is there a config flag or event option to emit FQCNs/aliases for a transition period? If not, will one be added?
  • Is the intended contract "basename" permanently, or is this a step toward a formal wire contract (e.g. stable type keys)?
  • Does anything internal (channel authorization, notification fan-out, persistence) depend on the old values, or is this payload-only?
  • Are the actor_type/likeable_type fields documented anywhere as a public contract, with an upgrade guide and a deprecation path?
  • Version support matrix (PHP/Laravel) and CI status for the 1.1.2 tag; also what changed in the dev testing toolchain at ^1.6.
  • Confirmation that 1.1.1 remains installable for teams that need to defer.

Integration Approach

Stack fit. Unchanged: Composer-based Laravel app on a supported PHP version; strongest where other roundly/* packages are already present (shared toolkit version and upgrade window). The new fit criterion is client topology. Single-app, single-deploy, in-repo listeners: straightforward. Multi-client (web plus mobile plus partner subscribers) or anything with independent release cadence: plan for a compatibility window rather than a clean cut.

Migration path. Do not treat 1.1.2 as a drop-in patch. Recommended path:

  1. Audit. Inventory every reader of actor_type and likeable_type: event listeners, broadcast subscribers, JS/Echo handlers, mobile clients, partner integrations, queue or event-log tables, dashboards, and alert rules.
  2. Make readers tolerant first. Change consumers to accept both forms (e.g. match on the last segment of a class name, or an allowlist of ['User','App\\Models\\User','user']). Deploy readers before publishers.
  3. Then upgrade the package to 1.1.2 and verify publishers emit basenames.
  4. Then tighten readers to basenames only, once no 1.1.1 publisher remains.
  5. Backfill or normalise any persisted payloads if reporting depends on them.
  6. Pin in composer.lock; record the exact version in the dependency policy.

If the audit finds unupdatable consumers (external subscribers, shipped mobile binaries), hold at 1.1.1 and escalate to the vendor for a compatibility option, or plan the change into the next mobile release train.

Compatibility. Verify explicitly: PHP and Laravel majors; the toolkit constraint (^1.3.0) still resolving against the rest of the roundly/* family; DB support if the CI matrix is a guide (PostgreSQL and MySQL are tested — confirm nothing else is claimed); and, critically, the payload contract against every subscriber. Also confirm whether a morph map is in use: if it is, the before/after values are alias → basename, not FQCN → basename, and the diff is different from what a naive reading of the changelog implies.

Sequencing. Readers before publishers; publishers before removal of legacy tolerance; single coordinated change across all roundly/* packages rather than package-by-package. Avoid deploying mid-flight of an unrelated broadcast change so that any anomaly is attributable. Roll out to one environment with live subscribers before production and inspect actual received payloads rather than trusting the changelog.

Operational Impact

Maintenance. The cadence remains healthy in the "actively maintained" sense — dependency floors current, dev toolchain current, CI improved (tmpfs for DB legs, which shortens runs). But the maintenance burden steps up: this family changes wire formats in patch releases, so every dependency refresh is a potential consumer-code change, not just a Composer update. Budget an audit pass per upgrade rather than per quarter, and treat the changelog as required reading before any constraint bump.

Support. Still unknown and now more important. The questions that matter have shifted from "is there a support policy" to "is there a versioning and deprecation policy, and will breaking payload changes be signalled in advance". A patch-level breaking change with a changelog note but no deprecation window suggests versioning is not treated as a contract. Confirm the disclosure and deprecation policy before committing to production dependency on the payload format.

Scaling. Runtime scaling is unchanged — the library adds no infrastructure; characteristics follow the underlying broadcast path (queue, websocket server, fan-out width). Two scaling notes specific to this release: (1) broadcast payloads scale with subscriber count, so a payload contract change is a fan-out-wide event whose rollback cost grows with the size of the subscriber fleet; (2) dependency-graph cost still grows superlinearly with each additional roundly/* package, and now also carries a versioning-risk premium.

Failure modes.

  • Silent listener mismatch — the primary failure. Listeners comparing against User::class or a morph alias stop firing while the like/unlike itself succeeds. No error surface; detect via monitoring on reaction-change event volume, not on exceptions.
  • Silent client mismatch — JS/mobile handlers keying off the type string fail to render or route; also silent.
  • Deploy skew — mixed 1.1.1/1.1.2 publishers or readers during a rolling deploy produce inconsistent values for the same logical event.
  • Persisted-payload divergence — historical rows or queued jobs holding the old value break reports, replays, or retries.
  • Morph-map regression — teams that used aliases to decouple wire format from class names find internal class naming back on the wire; a governance surprise more than an outage.
  • Upgrade lockout — unchanged from 1.1.1: if another dependency pins package-toolkit below 1.3.0, resolution fails at build time.
  • Versioning surprise — a future patch carrying a further contract change, with no major bump to warn us. Mitigate with exact pinning plus the audit-on-upgrade habit, not with a caret constraint.

Ramp-up. Still low for the mechanics, slightly higher for the semantics. Engineers need ~half a day to read the event classes and confirm the payload contract, plus the audit time described above (scoped by how many consumers exist). The conceptual learning curve is now explicit: understand that the channel name is stable but the type fields are not, and that a morph map no longer protects the wire format. Document that in the integration notes so the next upgrade does not re-litigate it.

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