All notable changes to the iazaran/smart-cache package will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
1.13.2 - 2026-08-04
- Updated the transitive
guzzlehttp/guzzledependency from 7.15.1 to 7.15.2 to resolve GHSA-v5mv-p594-2x33 and GHSA-f7vp-7xgx-4w4r. SmartCache does not directly require Guzzle,composer.jsonis unchanged, andcomposer auditis clean after the lock-file update.
- Redesigned the full documentation with a modern responsive layout, clearer navigation and content hierarchy, improved code blocks and cards, accessible active states, reduced-motion support, and better direct-link behavior.
- Replaced the GitHub stars badge's generic dynamic-JSON API lookup with Shields' dedicated GitHub stars endpoint to prevent intermittent invalid badge output.
1.13.1 - 2026-07-21
- Updated the repository's locked Guzzle stack to
guzzlehttp/guzzle7.15.1,guzzlehttp/promises2.5.1, andguzzlehttp/psr72.13.0 to resolve four upstream advisories reported on 2026-07-20. SmartCache does not directly require Guzzle; the packages are present through the Laravel development/test dependency graph.composer auditis clean after the update.
- Added PHP 8.5 to the GitHub Actions compatibility matrix for Laravel 12 and 13, the upstream-supported framework lines that support PHP 8.5.
- Added
SmartCache::clearManaged()as an explicit concrete-class and facade API for removing SmartCache-tracked entries without flushing unrelated keys. The publicSmartCachecontract is unchanged so third-party implementations remain compatible. - Added enterprise adoption guidance covering appropriate workloads, unsuitable payloads, internal metadata keys, upstream runtime support windows, incremental migration, and explicit cache-clearing scope.
- Clarified that SmartCache 1.x preserves managed-only
clear()behavior whileflush()clears the entire underlying store. Existing behavior is unchanged; new application code should prefer the scope-explicitclearManaged()orflush()methods. - Repositioned the README and full documentation around SmartCache's primary value: safe optimization and invalidation for large Laravel cache payloads. Claims such as zero overhead, universal opt-in behavior, and unchanged full PSR-16 semantics were replaced with precise operational guidance.
- Removed the redundant
ext-jsonsuggestion and installation prerequisite because JSON is always enabled in PHP 8+. - Updated the security policy to identify 1.13.x as the maintained release line and distinguish package compatibility from upstream PHP and Laravel security support.
- Removed obsolete reflection
setAccessible()calls, which have no effect on the supported PHP 8.1+ range and emit deprecation warnings on PHP 8.5. - Replaced invalid
asyncSwr()Closure examples with serializable invokable-class examples; queued refresh callbacks reject closures by design. - Corrected SWR documentation to distinguish the synchronous refresh behavior of
swr(),stale(), andrefreshAhead()from the queue-backedasyncSwr()method, and corrected rollback guidance for optimized cache wrappers. - Corrected the full documentation's Cache DNA description from MD5 to the
xxh128algorithm used since 1.12.1.
1.13.0 - 2026-06-16
- Declarative model invalidation rules via a protected
cacheInvalidation(): arraymethod. Existing fluent setters still work and are merged with declared rules. Model::flushCacheTags()for explicit invalidation aftersaveQuietly(), query-builder updates/deletes, upserts, mass inserts, raw SQL, or any other path that bypasses Eloquent events.TagFlushedevent, including the tag name, live key count, and source (manual,model, ormodel_helper), when cache events are enabled.- Config options for metadata locks (
smart-cache.metadata_lock.*) and transaction-aware model invalidation (smart-cache.model_invalidation.after_commit).
- Model auto-invalidation now defers cache flushing until the active database transaction commits by default. Rollbacks no longer flush cache, and nested transactions wait for the outer commit. Set
smart-cache.model_invalidation.after_committofalseto restore immediate invalidation. - Tag metadata writes now register before the cache value is written and use a short Laravel cache lock when the store supports
LockProvider, reducing lost tag-index updates under concurrent writers while preserving best-effort behavior for stores without locks. - Tag reads lazily prune expired or missing key references, and tag flushes correctly handle keys written under an active namespace.
SmartCache::add()no longer leaks active tags into the next write when the atomic add fails because the key already exists.- Cache DNA deduplicated writes now still refresh tag/managed-key metadata and only skip the value write when the cached value is still present.
- Dependency invalidation now refreshes dependency metadata before traversal, so long-running workers do not miss relationships added by another process after the local map was loaded.
1.12.2 - 2026-05-29
- Upgraded every remaining
symfony/*lockfile entry fromv8.0.8tov8.1.0(>= patched lines8.0.12/8.0.13) to clear the rest of the open Dependabot advisories plus two pending CVEs surfaced bycomposer audit. Runtime:symfony/mailer(CVE-2026-45068,SendmailTransportargument injection via dash-prefixed recipient),symfony/routing(CVE-2026-45065,UrlGeneratorroute-requirement bypass via unanchored regex alternation; CVE-2026-48784, dot-segment encoding skip),symfony/http-foundation(CVE-2026-48736),symfony/http-kernel(CVE-2026-45075,#[IsGranted(methods: ['GET'])]filter bypass viaHEAD). Dev:symfony/yaml(CVE-2026-45133 uncontrolled recursion, CVE-2026-45304 collection-alias "Billion Laughs", CVE-2026-45305Parser::cleanup()ReDoS).composer auditis now clean across runtime and dev scopes.composer.jsonis unchanged — the existing ranges already permitted these versions; Dependabot was failing because of a stale resolver state on its side.
1.12.1 - 2026-05-29
- Upgraded
symfony/mimefromv8.0.8tov8.1.0(>= patched line8.0.12) to address GHSA Email Header / SMTP Command Injection via CRLF inSymfony\Component\Mime\Addressand Email Header Injection via Non-Token Characters in Mime Parameter Names. Transitive bumps:symfony/deprecation-contractsv3.6.0→v3.7.0,symfony/polyfill-intl-idnv1.36.0→v1.38.1,symfony/polyfill-intl-normalizerv1.36.0→v1.38.0,symfony/polyfill-mbstringv1.36.0→v1.38.1. No package API change.
SmartCache::contentHash()(Cache DNA write-deduplication hot path) now usesxxh128(PHP 8.1+, already a hard requirement) instead ofmd5. Output is still 32 lowercase hex characters, so the_sc_dna:{key}storage format is unchanged. Significantly faster on everyput()when deduplication is enabled (defaulttrue). Existing_sc_dna:*entries from prior releases will mismatch once after upgrade and be transparently overwritten on the nextput(); no errors, no data corruption.
tests/Unit/SmartCacheTest.php::test_cache_dna_hash_format_is_stablelocks the stored DNA hash contract (32 lowercase hex characters, deterministic for identical inputs, sensitive to value changes) so a future algorithm swap that breaks the key-length assumption is caught immediately.
1.12.0 - 2026-05-21
CompressionStrategy::restore()now explicitly validates thedatafield, the base64 decode step, thegzdecode()decompression step, and theunserialize()step, throwingRuntimeExceptionon any failure. Previously a corrupted compressed payload could surface as a silent PHP warning followed by afalse/garbage return value, which the cache layer would then re-cache. Theunserialize()call is now wrapped with a temporary error handler so corrupted payloads no longer leakE_NOTICEwarnings into application logs (round-tripping the valuefalsestill works).SmartCache::maybeRestoreValue()self-healing now evicts the full footprint of a corrupted entry: the wrapper key, the SWR/stampede metadata (_sc_meta:{key}), the Cache DNA hash (_sc_dna:{key}), the managed-keys index entry, and — when the wrapper is a chunked value — every chunk key referenced bychunk_keysand the orphan-chunk registry entry. Previously the chunk keys could survive as orphans after a self-heal pass.BackgroundCacheRefreshJob::__construct()now rejectsClosurecallbacks up-front with a clearInvalidArgumentException("does not accept Closures …") instead of failing later inside Laravel's queue serializer with a generic "Serialization of 'Closure' is not allowed" error. Thecallable|stringsignature is unchanged; only the runtime guard is new.
- Opt-in single-flight SWR: when
smart-cache.swr.single_flight = trueand the underlying cache store implementsIlluminate\Contracts\Cache\LockProvider(redis, memcached, database, dynamodb, file/array via lock files),refreshInBackground()now acquires a short non-blocking lock keyed on_sc_swr_refresh:{key}so only one worker regenerates a stale entry. Concurrent workers continue to serve the stale value without piling up redundant callback executions. Defaultfalsepreserves the historical behaviour. SmartCache::reset()— a new public method that clears all per-request state (activeTags,activeNamespace, dirty flags, in-memory performance-metric buffers, managed-keys load flag). The service provider now callsreset()from itsterminating()hook so Laravel Octane, Swoole, FrankenPHP, and RoadRunner workers no longer leak tag/namespace state between requests. The hook is a no-op outside long-running runtimes.- Opt-in bounded managed-keys index:
smart-cache.managed_keys.max_tracked(default0= unlimited) caps the in-memory_sc_managed_keysindex. When exceeded, the oldest entries are dropped FIFO to prevent the index from growing without bound in high-cardinality workloads. Default behaviour is unchanged. - Opt-in debounced chunk-registry persistence:
OrphanChunkCleanupServicenow accepts apersistEveryconstructor argument (default1= persist every change, current behaviour). When raised, registry mutations buffer in memory and flush every N changes. The service provider always callsflush()fromterminating()so buffered changes are not lost between requests. - Opt-in shared circuit breaker state: when
smart-cache.circuit_breaker.shared = true, the breaker mirrors its state (state,failure_count,success_count,opened_at) to a shared cache key (_sc_circuit_breaker:{driver}, TTLsmart-cache.circuit_breaker.shared_ttl, default300s) so all workers in a pool observe the sameOPEN/CLOSED/HALF_OPENdecision. Defaultfalsepreserves per-instance behaviour. - 18 new unit tests across
tests/Unit/V112FeaturesTest.phpandtests/Unit/Strategies/CompressionStrategyTest.phpcovering: compression-decode failure paths (invalid base64, corrupted gzip stream, missing data field, corrupted serialized payload, no warning leakage), self-healing eviction of chunked and compressed wrappers, SWR single-flight lock behaviour (lock held → callback skipped; disabled flag → synchronous refresh),reset()clearing namespace/tag state,BackgroundCacheRefreshJobclosure rejection, bounded managed-keys cap, BC-safe unbounded default, debounced registry persistence +flush(), shared circuit-breaker visibility across instances, per-instance default, and SWR meta-key TTL co-residency.
config/smart-cache.phpdocuments the four new opt-in keys (swr.single_flight,managed_keys.max_tracked,circuit_breaker.shared,circuit_breaker.shared_ttl). All defaults preserve v1.11.0 behaviour.README.mdanddocs/index.htmldocument the v1.12.0 changes, the Octane reset hook, the SWR single-flight option, and replace the static "tests-452 passed" badge with a real GitHub Actions CI badge.
1.11.0 - 2026-05-04
touch()now extends the TTL of every chunk key, the SWR/stampede metadata key (_sc_meta:{key}), and the Cache DNA hash key (_sc_dna:{key}) in addition to the wrapper key. Previously, callingtouch()on a chunked entry left the underlying chunks scheduled to expire at their original TTL, which could surface asRuntimeException: Missing cache chunk […]on subsequent reads.touch()now returnsfalsewhen the target key does not exist, matching Laravel cache semantics across both the native (Laravel 13+) and fallback paths.SmartSerializationStrategy::isJsonSafe()now performs a JSON encode/decode round-trip and rejects values whose decoded form does not strictly equal the original (e.g.stdClasscollapsing to an empty array,Exceptioninstances losing their class, and similar type-changing payloads). Forced-jsonmode degrades tophpwhen the value cannot be safely round-tripped.- JSON serialization writes float values with
JSON_PRESERVE_ZERO_FRACTION, so values like1.0round-trip as float instead of being silently coerced toint(1).
isJsonSafe()rejects top-level resources, closures and non-stdClassobjects upfront, and runs the round-trip check withJSON_THROW_ON_ERRORso that nested unsupported types do not emit unsuppressableE_WARNINGs into application logs.CostAwareCacheManager::trimIfNeeded()now trims down to 90% ofmax_tracked_keysinstead of exactly the cap, amortising thearsort()cost across multiple inserts. Memory ceiling is unchanged. Behaviour withmax_tracked_keys < 1is now well-defined (metadata is cleared).ChunkingStrategy::shouldApply()estimates value size by sampling the serialized bytes of up to five items instead of using a fixed 50-byte-per-item heuristic, producing more accurate chunk decisions for non-trivial item sizes while keeping the borderline-case full-serialize fallback intact.SmartChunkSizeCalculator::calculateAverageItemSize()walks the first N items instead of callingarray_rand(), removing RNG overhead and theis_array($samples)defensive branch..gitignorenow excludes the.codexdirectory used by AI tooling.
- Unit tests covering chunked
touch()(happy path and chunk-failure path),JSON_PRESERVE_ZERO_FRACTIONpreservation,stdClass/Exception/nested-object fallbacks, forced-jsongraceful degradation, legacy JSON payload restore compatibility, and dedicated tests verifyingisJsonSafe()does not emit warnings for top-level resources, top-level closures, or nested resources. - Feature tests covering end-to-end
touch()on chunked entries (value still resolves and every chunk key survives) andtouch()returningfalsefor missing keys. - Unit tests for
CostAwareCacheManagercovering cost-based scoring, the new 90%-of-capacity trimming behaviour, themax_tracked_keys = 1edge case, and persist/load round-trip.
1.10.0 - 2026-04-20
- Added
smart-cache:auditfor read-only diagnostics of managed keys, missing tracked keys, broken chunked entries, orphan chunks, large unoptimized values, and cost-aware eviction suggestions. - Added
smart-cache:benchfor benchmarking raw Laravel cache operations against SmartCache optimization profiles, with table output, JSON output, driver selection, profile selection, iteration control, report-file export, and per-profile goal/result summaries. - Added
docs/benchmark-report-redis.json, generated from the package itself with PHP 8.4, Laravel 13, Redis, and ten iterations. - Added console tests for audit and benchmark commands, including JSON report validation, benchmark file export, broken chunk detection, data integrity, and key-shape preservation.
- Updated
README.md,docs/index.html, andTESTING.mdwith audit and benchmark workflows, local benchmark guidance, and the expanded test count. - Registered audit and benchmark command metadata so package consumers can discover them through
SmartCache::getAvailableCommands().
- Preserved sparse numeric keys when restoring eager chunked arrays.
- Treated missing chunks as corrupted cache entries so self-healing can evict them and
remember()can regenerate clean data instead of returning a cachednull.
1.9.3 - 2026-04-14
- Added
SECURITY.mdfor standardized enterprise vulnerability disclosures. - Added
CHANGELOG.mdfollowing the Keep a Changelog standard. - Added
.editorconfigto enforce formatting consistency across contributors. - Issue and Pull Request GitHub templates added to standardize bug tracking.
- Enriched
config/smart-cache.phpinline documentation for advanced strategies likeadaptive modeandcircuit_breaker. - Appended
ext-zlibandext-jsonextension suggestions tocomposer.json. - Enhanced
CONTRIBUTING.mdwith test commands, PSR-12 standards, and security disclosure references. - Added
zlibextension to CI workflows for explicit compression test coverage. - Updated documentation and
README.mdwith deep-dive troubleshooting and "Best Practices" examples. - Added
composer.lockto.gitignore(library best practice).
- Fixed dashboard route documentation (
/stats→/statistics) in README anddocs/index.html.
1.9.2 - 2026-03-17
- Feature: Added official support for Laravel 13 framework requirements.
- Implemented
touch()method functionality and boot-safe event registration to comply with Laravel 13 architectures.
- Fixed tests for Symfony Console compatibility allowing both
add()andaddCommand().
1.9.1 - 2026-03-04
- Improved current features functionality.
- Enhanced and updated the
README.mdand documentation files for a better Developer Experience (DX).
1.9.0 - 2026-02-20
- Added Write Deduplication (Cache DNA) optimization to save unnecessary I/O writes.
- Self-Healing Cache feature and Conditional Caching functionality implemented.
- Significant SEO improvements in
composer.jsonand meta-tags.
- Addressed assorted bug fixes reported by the community.
1.8.0 - 2026-02-08
- Introduced Cost-Aware caching to prioritize memory eviction efficiently.
- Various under-the-hood fixes and optimization refinements.
1.7.0 - 2026-01-19
- Feature Request #31: Implemented
store()method support directly on the SmartCache facade.
1.6.0 - 2025-12-06
- General core improvements and new minor features for package robustness.
1.5.0 - 2025-10-19
- New core features and expanded cache optimization solutions for large objects.
1.4.3 - 2025-09-27
- Extended documentation coverage in
docs/index.htmlandREADME.md.
1.4.2 - 2025-09-26
- Improved the internal mechanism for managing keys for mass invalidation dynamically.
1.4.1 - 2025-09-26
- Optimization applied to the
flexiblemacro implementation.
1.4.0 - 2025-09-26
- Comprehensive dependency tracking mechanism.
- Full Cache Tag support implementations.
- Powerful cache invalidation strategies and helpers.
1.3.7 - 2025-09-25
- Robust test coverage established ensuring compatibility with PHP 8.1+ and Laravel 8+.
1.3.6 - 2025-09-08
- Bugfix: Resolves Issue #18 where cache
flexiblelogic was not operating as expected under certain payloads.
1.3.5 - 2025-09-02
- Resolved PHP parameter type warnings related to strict nullable types.
1.3.4 - 2025-09-02
- Bugfix: Issue #14 regarding keys stored but not registering properly on status checks.
1.3.3 - 2025-09-01
- Bugfix: Addressed Issue #12 covering data cleared by a specifically defined key.
1.3.2 - 2025-08-31
- Continued stabilization for manual key data clearance mechanics (Issue #12).
1.3.1 - 2025-08-31
- Bugfix: Resolved Issue #8 concerning multiple conflicting strategies applying to single cache allocations.
1.3.0 - 2025-08-31
- Feature Request #7: Implemented dedicated support for cache
flexiblemacros.
1.2.2 - 2025-08-30
- Deployed structured unit testing cases asserting early system stability.
1.2.1 - 2025-06-03
- Added Google site verification file for better SEO visibility compliance.
1.2.0 - 2025-06-03
- Various repository refinements tailored towards improving SEO and discoverability.
1.1.0 - 2025-04-22
- Introduced the
smart_cacheglobal helper function to provide a drop-in analogue for Laravel'scachehelper.
1.0.1 - 2025-04-21
- Package-wide code refactoring, structural cleanup, and PSR standard reformatting.
1.0.0 - 2025-04-21
- Initial package scaffolding and base logic commit.