voorhof/stickler
Stickler is a Laravel package that brings validation to Eloquent models. Define rules and custom messages directly on your model, and Stickler validates attributes before saving, helping keep your database clean and consistent.
What this release is. v1.2.0 of voorhof/stickler is a broad, mixed-scope release: framework-level refactors (routing, enum naming), new product features (rich-editor source editing, contact-message reply mail), a new operational tool (GenerateMissingResponsiveImagesCommand), dependency churn, and test-suite cleanup. It is not a narrow patch. Note the assessment is derived solely from the release notes — there is no prior assessment, dependency manifest, or test evidence in the record, so several conclusions are provisional and flagged as questions below.
Architecture fit. The package presents as an opinionated full-stack Laravel application/starter (Blade views, model route keys, media conversions, rich-text editing, admin widgets, social links, contact messaging) rather than a narrow library. Fit is high for content/marketing/CMS-style sites on a standard Laravel + Blade + queue stack. Fit is poor for headless/API-first services or teams already standardized on a different admin/editor stack — it would impose an editor (source-code plugin suggests a TipTap/ProseMirror-class editor), an image-conversion pipeline, and a Node build step for capabilities you may not want.
Integration feasibility. Mechanically feasible but not frictionless. Two changes are behavior-changing:
Fit::Contain → Fit::Crop is a rename in what appears to be an enum/value object used in image-conversion definitions. Any consumer referencing Fit::Contain will fatal or silently mis-fit images.getRouteKeyName() → #[RouteKey] attribute is a model-convention change. If this attribute is package-local (not framework-native), route model binding now depends on a custom resolver; any model overriding getRouteKeyName() may be bypassed, producing incorrect URLs or 404s.Both landed in a minor version. That is a semver-contract breach and the single most important technical fact in this release.
Technical risk.
laravel-lang/lang dependency: locale/translation regressions are silent; missing keys fall back to the fallback locale rather than erroring.SourceCodePlugin in the rich editor: user-authored HTML in a stored field is a stored-XSS surface. Needs sanitization (e.g. HTML Purifier) and a CSP review before it reaches any privileged author role.SendMessageReplyMailAction / ContactMessageReply: a new outbound mail path that replies to user-supplied addresses. Requires rate limiting, header-injection protection, and abuse controls, plus queue and deliverability treatment.GenerateMissingResponsiveImagesCommand: operationally valuable, but bulk image generation is CPU/disk heavy and its idempotency and memory profile are unproven.Key questions.
#[RouteKey] a framework-native attribute, a package-local one, or a third-party dependency? What is the migration path for models that override getRouteKeyName()?Fit::Crop value-compatible with Fit::Contain (same behaviour, new name) or a behavioural change to the crop/fit algorithm?laravel-lang/lang, and which locales are now shipped in-tree?composer require (library) or is it intended to be cloned/forked (starter kit)? This determines the entire upgrade strategy.Stack fit. Assumes a conventional Laravel monolith: Blade templating, a relational database, queue workers (required for the new mail action and for image conversion), filesystem/object storage for media, and a Node toolchain for editor assets. If any of those are absent — e.g. no queue worker, no asset build in CI, S3 not configured — adoption cost rises materially and the image pipeline will degrade to synchronous request-time work.
Migration path.
Fit::Contain, getRouteKeyName, addMediaConversion('preview'), the social-links partial, and any lang/ overrides.lang files explicitly now that laravel-lang/lang is gone, and add a test that asserts key parity.SourceCodePlugin for any role beyond trusted admins.SendMessageReplyMailAction behind a config flag; add rate limiting and validate reply-to handling before enabling in production.Compatibility. Do not assume drop-in. Validate Laravel/PHP matrix support first (question 1). Re-audit composer.lock after the bump — bundling dependency updates with breaking feature work means you cannot attribute a failure to either. Treat Node/NPM updates as a separate, revertible change.
Sequencing.
GenerateMissingResponsiveImagesCommand in staging against a realistic media sample; measure duration, memory, and storage delta; add chunking/throttling if needed.If this is a fork-based starter kit rather than a dependency, invert the model: cherry-pick individual commits (the command, the widget fix) and deliberately skip the renames until you can absorb them.
Maintenance. The signal here is modest: a single maintainer (@voorhof), roughly ten merged PRs, a branch named "Dev 10", and a changelog that mixes refactors, features, and dependency bumps without calling out breaking changes or deprecations. Budget for fork ownership rather than passive consumption. Recommend a quarterly review cadence, an internal changelog annotation step that classifies each upstream change as breaking/non-breaking, and a standing pin to a known-good tag with deliberate, tested jumps.
Support. Community-only, no LTS, no stated deprecation policy. Escalation is effectively "read the diff." For anything business-critical in the media or messaging paths, assume you own the fix — plan for a small internal fork budget or a willingness to upstream patches.
Scaling. The two scaling hot spots are the same ones this release just expanded:
preview → 400px change suggests variant sizes are still being tuned — lock them down in config, don't let them drift release to release).Failure modes to instrument.
#[RouteKey] — symptom: incorrect URLs and 404s, often only visible after route:cache. Add a smoke test that hits canonical URLs for each bound model.laravel-lang removal — symptom: mixed-language UI, no exception thrown.Fit::Crop — symptom: fatal errors on conversion dispatch or, worse, wrongly cropped assets in cache that require a purge to correct.Ramp-up. A competent Laravel developer reaches productive velocity in roughly two to four days on the general patterns (models, Blade, media library, queues). Add one to two more days for the non-obvious parts: the custom route-key attribute, the editor plugin configuration and its sanitization boundary, and the image variant configuration. Onboarding friction is concentrated in undocumented internals rather than framework familiarity — so the highest-value artifact you can produce is a short internal note documenting the route-key attribute and the media variant matrix, written during the migration spike while the context is fresh.
How can I help you explore Laravel packages today?