Skip to content

New cold box version https://presidecms.atlassian.net/browse/PRESIDECMS-3253 - #1755

Open
alexskinner wants to merge 16 commits into
pixl8:stablefrom
alexskinner:ColdboxNewVersion
Open

New cold box version https://presidecms.atlassian.net/browse/PRESIDECMS-3253#1755
alexskinner wants to merge 16 commits into
pixl8:stablefrom
alexskinner:ColdboxNewVersion

Conversation

@alexskinner

@alexskinner alexskinner commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

Progressive shimming of Preside in order to support the lates version of Coldbox

Starting with 6.0, through 7, and then 8.1 snapshot

Known issues

  1. Need to ensure that new method of calling views and layouts also goes through our code
  2. The error template needs enhancing
  3. Have added some code unrelated to the upgrade to show the cold box version

Note

High Risk
Major framework version jump with broad changes to request routing, interception, DI/WireBox behavior, and rendering, which can cause subtle regressions across the application lifecycle.

Overview
Upgrades the ColdBox dependency from 5.4.0 to 8.1.0-snapshot and introduces a set of compatibility shims so existing Preside code continues to run without widespread call-site changes.

Key runtime adaptations include: restoring removed/changed framework APIs (getSettingStructure(), getModel(), setNextEvent(), provider get(), and render methods returning values), aligning lifecycle hooks (Renderer.startup(), WireBox processEagerInits()), normalizing interception/routing behavior for CB 6+ (requestCapture(), announce() suppression during interceptor registration, data vs interceptData), and updating CacheBox disk store/indexer implementations for CB 7 interface changes.

Also simplifies the custom error template to rethrow the original exception struct and adds ColdBox version display to the System Information admin view (with new i18n keys).

Written by Cursor Bugbot for commit dd757cb. This will update automatically on new commits. Configure here.

Test and others added 7 commits March 27, 2026 15:34
ColdBox 6.0 introduced significant breaking changes. This commit updates
the coldboxModifications layer to bridge these changes while preserving
Preside's existing API surface.

Shims added to coldboxModifications:
- InterceptorService: processState() calls super.announce() (renamed in CB6);
  announce() override suppresses events during interceptor registration
- InterceptorState: accepts both 'data' (CB6) and 'interceptData' (CB5) params
- Controller: restores getSettingStructure(), adapts getSetting() to handle
  both CB5 (name, fwSetting, defaultValue) and CB6 (name, defaultValue)
  signatures, lazy-inits viewsRefMap/layoutsRefMap removed in CB6
- EventHandler (new): restores setNextEvent() and getModel() for handlers
- Interceptor (new): eagerly loads application helpers in constructor (CB6
  deferred this to a lazy event, breaking startup interceptors)
- Provider (new): restores get() renamed to $get() in CB6
- Builder: overrides getProviderDSL() to use Preside Provider shim
- HandlerService: newHandler() uses Preside EventHandler for virtual inheritance
- RoutingService: onRequestCapture() renamed to requestCapture() (CB6 API)
- Injector: aliases variables.objectBuilder (renamed from builder in CB6),
  calls processEagerInits() after processMappings() (split in CB6)
- DSL Builders: added targetID parameter to process() (CB6 interface change)
- Renderer: getModel() changed to getInstance()
- WireBox config: mapDirectory filter wraps file paths to component dot-paths
  (CB6 changed the filter callback contract)
- presideProxies.cfm: added getModel() helper proxy for all views/handlers
- errorReport.cfm: replaced missing CB6 CSS include with simple rethrow
- Config: onInvalidEvent renamed to invalidEventHandler (CB6)
- Router: removed setUniqueUrls() (removed in CB6), super.getModel() to
  super.getInstance()

Also adds ColdBox version display to admin System Information page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- MetadataIndexer: removed extends (class deleted in CB7), made standalone
- DiskStore: added getSortedKeys() and getCachedObjectMetadata() for IObjectStore
  interface, pointed indexer at Preside's MetadataIndexer
- Interceptor shim: removed init() override (CB7 changed constructor signature),
  relies on cbLoadInterceptorHelpers event instead
- HandlerService: updated newHandler() for CB7 signature (ehBean instead of
  invocationPath), handles both string and object args for Preside compat.
  Replaced wireboxSetup() with injectorSeedBaseClasses() (renamed in CB7)
- Builder: inject cbInjectedHelpers into variables scope for components
  extending FrameworkSupertype that skip super.init() (CB7 requirement)
- Provider shim: added injectorName parameter (required in CB7)
- Renderer: added startup() method (called by CB7 LoaderService), moved
  init logic to startup() with deferred execution support
- Router: changed super.getInstance() to controller.getWirebox().getInstance()
  (CB7 changed method visibility)
- EventHandler: removed unnecessary _privateInvoker override
- errorReport: simplified to rethrow for debugging

Known issues under investigation:
- variable [listing] doesn't exist in DataManager._listing handler
- Frontend content rendering blank page

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…it fixes

CB 7.0 deprecated renderView(), renderLayout() and renderExternalView() on
FrameworkSupertype — critically, the deprecated wrappers no longer return
values. This caused blank frontend pages and undefined variable errors
throughout Preside where handler/view code relies on return values.

Fix: restore returning versions in EventHandler shim, Interceptor shim,
and presideProxies application helper.

Also fixes:
- Renderer.startup(): restored missing isViewsHelperIncluded, viewsHelper
  path prepend with appMapping, removed duplicate renderedHelpers reset
- Controller.getRenderer(): call startup() on first creation
- MetadataIndexer: added missing clearAll() method
CB 8.0 added getSystemSetting(key, defaultValue) to FrameworkSupertype for
env variable lookup. This shadows Preside's getSystemSetting(category, setting,
default) which delegates to systemConfigurationService. Added override to
EventHandler and Interceptor shims to restore Preside's version.
…ture

- InterceptorService.announce(): trigger cbLoadInterceptorHelpers before
  afterConfigurationLoad so Preside interceptors have access to helpers
  like isFeatureEnabled() during startup
- InterceptorService.createInterceptor(): updated for CB 8 signature
  (injector parameter, no controller constructor arg)
- InterceptorService.injectorSeedBaseClasses(): replaced wireboxSetup()
  which was removed in CB 7/8

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

*/
function startup() {
if ( variables._startupDone ?: false ) { return; }
variables._startupDone = true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renderer startup guard prevents future initialization attempts

High Severity

The _startupDone flag is set to true before the IsNull(variables.controller) check. If startup() is ever called when controller is null, the flag prevents any future re-initialization even if controller becomes available later. Combined with Controller.getRenderer() caching the renderer instance in variables._renderer, this creates a permanently uninitialized renderer with no recovery path.

Additional Locations (1)
Fix in Cursor Fix in Web

* CB 7.0: LoaderService calls renderer.startup() after all modules loaded.
* In CB 7, controller is injected via DI rather than passed to init().
* We use startup() to perform the initialisation that was in init().
*/

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale DI annotation orphaned before wrong function

Medium Severity

The old constructor's doc comment block containing @controller.inject coldbox is left orphaned directly above startup(). This WireBox DI annotation was originally associated with init(controller) but is now detached from it. Depending on how WireBox resolves method-level annotations, this could cause unexpected injection behavior on startup(), and at minimum it's misleading documentation.

Fix in Cursor Fix in Web

*/
array function getSortedKeys( required property, sortType="text", sortOrder="asc" ) {
return getKeys();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getSortedKeys stub ignores sorting requirements for eviction

Low Severity

getSortedKeys() ignores all parameters (property, sortType, sortOrder) and returns unsorted keys via getKeys(). ColdBox cache eviction policies rely on sorted keys (e.g., by lastAccessed or hits) to determine which entries to evict. Returning unsorted keys could cause arbitrary eviction instead of proper LRU/LFU behavior.

Fix in Cursor Fix in Web

ColdBox 7.0 renamed renderLayout() to layout() in FrameworkSupertype.
Since Renderer extends FrameworkSupertype and Preside's Renderer only
overrides renderLayout(), calling layout() fell through to
FrameworkSupertype.layout() which calls getRenderer().layout() in a
loop. Add layout() shims to Renderer, EventHandler and Interceptor
that delegate to renderLayout().
@cursor

cursor Bot commented Mar 31, 2026

Copy link
Copy Markdown

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@CLAassistant

CLAassistant commented Mar 31, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ alexskinner
❌ Test


Test seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

ColdBox 7.0 renamed renderView() -> view(), renderExternalView() ->
externalView(), and removed setNextEvent() from Controller. The
deprecated renderView() now delegates to this.view(), bypassing
Preside's custom view path resolution and causing layouts to render
within themselves with no page content.

Add view() and externalView() shims to Renderer, EventHandler and
Interceptor that delegate to the existing renderView()/
renderExternalView() implementations. Add setNextEvent() shim to
Controller that delegates to relocate().
@cursor

cursor Bot commented Mar 31, 2026

Copy link
Copy Markdown

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

…ceptor

These public shims get mixed into all handlers via WireBox virtual
inheritance, shadowing any handler-defined private viewlets with the
same name (e.g. webflow/Default.cfc has a private layout() viewlet).
This caused the ColdBox layout system to be invoked instead of the
viewlet, producing double site layouts with missing webflow content.

The Renderer retains its shims to prevent the FrameworkSupertype
infinite recursion. EventHandler/Interceptor retain renderView(),
renderLayout(), renderExternalView() shims since CB 7.0's deprecated
versions don't return values.
@cursor

cursor Bot commented Mar 31, 2026

Copy link
Copy Markdown

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

FrameworkSupertype's public layout()/view() get mixed into handlers
via virtual inheritance's injectMixin(), which writes to both this
AND variables scope — overwriting any handler-defined private method
of the same name (e.g. webflow handler's private layout() viewlet).

Making these private on EventHandler/Interceptor prevents them from
appearing in the this scope, so virtual inheritance's public loop
skips them and handler private methods are preserved.
@cursor

cursor Bot commented Mar 31, 2026

Copy link
Copy Markdown

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

CB 7.0+ ConcurrentStore uses inline metadata (pool entries are structs
with hits, timeout, etc.). Preside's store overrides use a separate
MetadataIndexer with raw objects in the pool. The parent's
getCachedObjectMetadata() reads from the pool expecting a struct but
gets raw cached values (e.g. booleans), causing "no property [hits]
found in [boolean]" during cache reaping.

Override getCachedObjectMetadata() on both ConcurrentStore and
ConcurrentSoftReferenceStore to read from the MetadataIndexer.
@cursor

cursor Bot commented Mar 31, 2026

Copy link
Copy Markdown

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

CB 7.0 eviction policies (LRU, LFU, FIFO, LIFO) call
getIndexer().getSortedKeys() to sort cache entries for eviction.
Preside's MetadataIndexer replacement was missing this method,
which would prevent proper cache eviction.
@cursor

cursor Bot commented Mar 31, 2026

Copy link
Copy Markdown

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Set _startupDone only after confirming controller is available, so
startup() can be retried if called before DI completes.
@cursor

cursor Bot commented Mar 31, 2026

Copy link
Copy Markdown

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

The old init() doc block with @controller.inject was left above
startup(), which is misleading and could confuse WireBox annotation
scanning.
@cursor

cursor Bot commented Mar 31, 2026

Copy link
Copy Markdown

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@cursor

cursor Bot commented Apr 9, 2026

Copy link
Copy Markdown

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants