A quick reference of what’s inside the plugin, useful for theme developers, plugin authors and anyone diagnosing unexpected behaviour.
├── Api/ REST controllers (admin endpoints)
├── Command/ Symfony console commands
├── Decorator/ Decorators around Shopware core services
├── Entity/ DAL definitions for the plugin's own tables
├── Enum/ Mode / strategy constants
├── Factory/ Cache-adapter factory
├── Framework/ Cache store implementation
├── Message/ Async messages dispatched by the plugin
├── MessageHandler/ Handlers for those messages
├── Migration/ Database migrations
├── P2LabCache.php Plugin entry point (lifecycle)
├── ScheduledTask/ Three nightly cleanup tasks (+ handlers)
├── Service/ Domain services (the bulk of the logic)
├── Subscriber/ Event subscribers that wire into Shopware
Service What it does CacheEntryServiceReads / writes the p2lab_cache_entry metadata table CacheInvalidationServiceTop-level invalidation API — clearAll(), clearAllProducts(), etc. CacheWarmupServiceDiscovers cacheable URLs, creates progress entries, batches them CacheSizeServiceReports total cache size (disk for Filesystem; database for Redis / APCu) SmartInvalidationAnalyzerField-to-tag mapping for Smart invalidation mode CacheInvalidationLogServicePersists rows in p2lab_cache_invalidation_log ReverseProxyLogServicePersists rows in p2lab_cache_reverse_proxy_log, plus analytics queries CacheTagServiceBuilds the tag set for a given response TagParserServiceParses tag names back into entity references for the log views RequestServiceInspects requests to decide cacheability and compute the cache key SettingsServiceReads system_config values with per-sales-channel fallback
Decorates Purpose SalesChannelContextFactoryCached sales-channel context for warmup workers ReverseProxyGatewayAdds xkey strategy + blocklist + splitting / shortening before sending purges to Varnish
Subscriber Listens to What it does CacheEntryFlushSubscriberKernelEvents::TERMINATEPersists newly-written entries’ metadata after the response is sent CacheInvalidationSubscriberEntity-written events Triggers the invalidation pipeline (Manual / Basic / Extended / Precise / Smart) CacheResponseSubscriberKernelEvents::RESPONSEStores the response in the backend if cacheable; sets Cache-Control headers NotificationMessageSubscriberCustom plugin events Pushes admin notifications (warmup completion etc.) TagCollectionSubscriberEntity-loaded events Collects the tag set that a response should carry XkeySubscriberPre-purge event Applies blocklist, splitting and shortening to outgoing xkey headers
Message Handler Purpose CacheWarmupStartMessageCacheWarmupStartHandlerKicks off a warmup run; spawns batch messages CacheWarmupBatchMessageCacheWarmupBatchHandlerProcesses one batch of URLs
Task Default interval What it does p2lab_cache.cleanup_cache_entries24 h Drops orphaned p2lab_cache_entry rows p2lab_cache.cleanup_invalidation_log24 h Drops invalidation-log rows older than 30 days p2lab_cache.cleanup_reverse_proxy_log24 h Drops reverse-proxy-log rows older than 30 days
See Scheduled tasks .
Table Purpose p2lab_cache_entryMetadata for every cache entry (size, type, generation / hit time) p2lab_cache_invalidation_logEvery invalidation event p2lab_cache_reverse_proxy_logEvery xkey purge sent to Varnish p2lab_cache_warmup_progressOne row per warmup run; tracks offset and counters p2lab_cache_warmup_failed_urlURLs that failed during a warmup
Cache tags created by the plugin all start with p2c-. The conventions:
p2c-product-<id> — full product tag (any field change purges)
p2c-product-<id>.<field> — Smart-mode field-level tag (e.g. .price, .stock)
p2c-product-stock_<id> — stock-only tag, exposed separately so the product_stock blocklist category can isolate it
p2c-category-<id> — full category tag
p2c-listing-<categoryId> — listing tag (purged when a member product’s listing-affecting field changes)
p2c-cms-page-<id> — CMS page tag
p2c-buybox-<productId> — async buybox tag
These tags are sent to Varnish via xkey and also drive the local invalidation lookup.
Add a new cache type: subscribe to KernelEvents::RESPONSE, set the type via the response object, and add a tag prefix. Update getCacheStatsByType() to know about it.
Add a field to Smart’s mapping: decorate SmartInvalidationAnalyzer and override analyzeProductChange() or analyzeCategoryChange().
Add an xkey blocklist category: extend the xkeyTagBlocklist config + add the matching pattern in XkeySubscriber.