diff --git a/box.json b/box.json index 093e63db87..7f7c9b8eb1 100644 --- a/box.json +++ b/box.json @@ -37,7 +37,7 @@ "cbmessagebox":"2.2.0+10", "cbstorages":"1.3.0+14", "cbjavaloader":"1.5.0+35", - "coldbox":"5.4.0", + "coldbox":"8.1.0-snapshot", "cfconcurrent":"3.0.0", "JSONPrettyPrint":"1.4.1", "cfflow":"0.8.0" diff --git a/system/coldboxModifications/Controller.cfc b/system/coldboxModifications/Controller.cfc index faadbdcfd7..1ab3fe0853 100644 --- a/system/coldboxModifications/Controller.cfc +++ b/system/coldboxModifications/Controller.cfc @@ -10,6 +10,7 @@ component extends="coldbox.system.web.Controller" { services.routingService = new preside.system.coldboxModifications.services.RoutingService( this ); variables.wireBox = CreateObject( "preside.system.coldboxModifications.ioc.Injector" ); variables.cacheBox = CreateObject( "preside.system.coldboxModifications.cachebox.CacheFactory" ); + } function getRenderer(){ @@ -17,6 +18,7 @@ component extends="coldbox.system.web.Controller" { return variables._renderer; } catch( any e ) { variables._renderer = variables.wireBox.getInstance( "presideRenderer" ); + variables._renderer.startup(); } return variables._renderer; } @@ -258,9 +260,50 @@ component extends="coldbox.system.web.Controller" { return getRequestService().getContext(); } - public any function getSetting( required string name, boolean fwSetting=false, any defaultValue ) { + /** + * Compatibility shim: setNextEvent() was removed in ColdBox 7.0. + * Delegates to relocate() which is the replacement. + */ + void function setNextEvent( + event + , URL + , URI + , queryString + , persist + , struct persistStruct + , boolean addToken + , boolean ssl + , baseURL + , boolean postProcessExempt + , numeric statusCode + ){ + relocate( argumentCollection=arguments ); + } + + /** + * Compatibility shim: getSettingStructure() was removed in ColdBox 6.0 + * Delegates to the configSettings/coldboxSettings structs directly. + */ + public struct function getSettingStructure( boolean fwSetting=false, boolean deepCopyFlag=false ) { + var target = arguments.fwSetting ? variables.coldboxSettings : variables.configSettings; + return arguments.deepCopyFlag ? duplicate( target ) : target; + } + + public any function getSetting( required string name, any fwSetting=false, any defaultValue ) { + // CB 6.0+ signature: getSetting( name, defaultValue ). If fwSetting + // is not a boolean, treat it as defaultValue for compatibility. + if ( !IsBoolean( arguments.fwSetting ) ) { + arguments.defaultValue = arguments.fwSetting; + arguments.fwSetting = false; + } var target = arguments.fwSetting ? variables.coldboxSettings : variables.configSettings; + // CB 6.0 removed viewsRefMap and layoutsRefMap from config settings. + // Preside's custom Renderer still uses them. Lazy-init on first access. + if ( !arguments.fwSetting && ListFindNoCase( "viewsRefMap,layoutsRefMap", arguments.name ) && !StructKeyExists( target, arguments.name ) ) { + target[ arguments.name ] = {}; + } + if ( StructKeyExists( target, arguments.name ) ) { return target[ arguments.name ]; } diff --git a/system/coldboxModifications/DelayedInjectorDsl.cfc b/system/coldboxModifications/DelayedInjectorDsl.cfc index bbaabbdac9..d604833060 100644 --- a/system/coldboxModifications/DelayedInjectorDsl.cfc +++ b/system/coldboxModifications/DelayedInjectorDsl.cfc @@ -6,7 +6,7 @@ component implements="coldbox.system.ioc.dsl.IDSLBuilder" { return this; } - public any function process( required any definition, any targetObject ) { + public any function process( required any definition, any targetObject, any targetID ) { var thisType = arguments.definition.dsl; var thisTypeLen = ListLen( thisType, ":" ); var injectorDsl = ""; diff --git a/system/coldboxModifications/EventHandler.cfc b/system/coldboxModifications/EventHandler.cfc new file mode 100644 index 0000000000..56106d255b --- /dev/null +++ b/system/coldboxModifications/EventHandler.cfc @@ -0,0 +1,88 @@ +/** + * Preside compatibility shim for ColdBox 6.0+ + * + * ColdBox 6.0 removed setNextEvent() and getModel() from FrameworkSupertype. + * This shim adds them back so that all Preside handlers continue to work + * without needing to update 400+ call sites. + */ +component extends="coldbox.system.EventHandler" { + + /** + * Compatibility: setNextEvent() was removed in ColdBox 6.0. + * Delegates to relocate() which is the replacement. + */ + void function setNextEvent( + event + , URL + , URI + , queryString + , persist + , struct persistStruct + , boolean addToken + , boolean ssl + , baseURL + , boolean postProcessExempt + , numeric statusCode + ){ + controller.relocate( argumentCollection=arguments ); + } + + /** + * Compatibility: getModel() was removed in ColdBox 6.0. + * Delegates to getInstance() which is the replacement. + */ + function getModel( name, dsl, initArguments={} ){ + return getInstance( argumentCollection=arguments ); + } + + /** + * CB 8.0: FrameworkSupertype added getSystemSetting(key, defaultValue) which + * shadows Preside's getSystemSetting(category, setting, default) helper. + * Restore Preside's version. + */ + function getSystemSetting(){ + return getInstance( "systemConfigurationService" ).getSetting( argumentCollection=arguments ); + } + + /** + * CB 7.0: renderView() deprecated and no longer returns a value. + * Restore the return so Preside handlers get their rendered content. + */ + function renderView(){ + return getRenderer().renderView( argumentCollection=arguments ); + } + + /** + * CB 7.0: renderLayout() deprecated and no longer returns a value. + * Restore the return so Preside handlers get their rendered content. + */ + function renderLayout(){ + return getRenderer().renderLayout( argumentCollection=arguments ); + } + + /** + * CB 7.0: renderExternalView() deprecated and no longer returns a value. + */ + function renderExternalView(){ + return getRenderer().renderExternalView( argumentCollection=arguments ); + } + + /** + * CB 7.0: layout(), view(), externalView() replaced the render* versions. + * These MUST be private to prevent virtual inheritance from overwriting + * handler-defined private viewlets with the same name (e.g. webflow + * handler's private layout() viewlet). FrameworkSupertype's public + * layout()/view() would otherwise be mixed into the handler's variables + * scope via injectMixin, shadowing the handler's own private method. + */ + private function layout(){ + return getRenderer().renderLayout( argumentCollection=arguments ); + } + private function view(){ + return getRenderer().renderView( argumentCollection=arguments ); + } + private function externalView(){ + return getRenderer().renderExternalView( argumentCollection=arguments ); + } + +} diff --git a/system/coldboxModifications/FeatureDependentDsl.cfc b/system/coldboxModifications/FeatureDependentDsl.cfc index 6b73cd9f36..d6ce4fd918 100644 --- a/system/coldboxModifications/FeatureDependentDsl.cfc +++ b/system/coldboxModifications/FeatureDependentDsl.cfc @@ -6,7 +6,7 @@ component implements="coldbox.system.ioc.dsl.IDSLBuilder" { return this; } - public any function process( required any definition, any targetObject ) { + public any function process( required any definition, any targetObject, any targetID ) { var dsl = ListRest( arguments.definition.dsl ?: "", ":" ); if ( ListLen( dsl, ":" ) < 2 ) { diff --git a/system/coldboxModifications/Interceptor.cfc b/system/coldboxModifications/Interceptor.cfc new file mode 100644 index 0000000000..5c3704cc09 --- /dev/null +++ b/system/coldboxModifications/Interceptor.cfc @@ -0,0 +1,65 @@ +/** + * Preside Interceptor shim for ColdBox 6.0+/7.0+ + * + * 1. ColdBox 6.0+ moved loadApplicationHelpers() from the constructor to a + * lazy cbLoadInterceptorHelpers event. This shim eagerly loads helpers + * via cbLoadInterceptorHelpers so they're available for startup interceptions. + * + * 2. ColdBox 6.0 removed getModel() from FrameworkSupertype. This shim + * restores it as a passthrough to getInstance(). + */ +component extends="coldbox.system.Interceptor" { + + /** + * Override cbLoadInterceptorHelpers to ensure helpers are loaded + * immediately when called, restoring CB 5.4 eager-loading behaviour. + */ + function cbLoadInterceptorHelpers( event, interceptData ){ + loadApplicationHelpers( force: true ); + } + + /** + * Compatibility shim: getModel() was removed in ColdBox 6.0 + */ + function getModel( name, dsl, initArguments={} ){ + return getInstance( argumentCollection=arguments ); + } + + /** + * CB 8.0: FrameworkSupertype added getSystemSetting(key, defaultValue) which + * shadows Preside's getSystemSetting(category, setting, default) helper. + */ + function getSystemSetting(){ + return getInstance( "systemConfigurationService" ).getSetting( argumentCollection=arguments ); + } + + /** + * CB 7.0: renderView() deprecated and no longer returns a value. + */ + function renderView(){ + return getRenderer().renderView( argumentCollection=arguments ); + } + + function renderLayout(){ + return getRenderer().renderLayout( argumentCollection=arguments ); + } + + function renderExternalView(){ + return getRenderer().renderExternalView( argumentCollection=arguments ); + } + + /** + * CB 7.0: layout(), view(), externalView() replaced the render* versions. + * Private to avoid shadowing interceptor-defined methods of the same name. + */ + private function layout(){ + return getRenderer().renderLayout( argumentCollection=arguments ); + } + private function view(){ + return getRenderer().renderView( argumentCollection=arguments ); + } + private function externalView(){ + return getRenderer().renderExternalView( argumentCollection=arguments ); + } + +} diff --git a/system/coldboxModifications/InterceptorState.cfc b/system/coldboxModifications/InterceptorState.cfc index d659449d3e..b5c3928670 100644 --- a/system/coldboxModifications/InterceptorState.cfc +++ b/system/coldboxModifications/InterceptorState.cfc @@ -45,7 +45,8 @@ component { public any function process( required any event - , required any interceptData + , any data = {} + , any interceptData , required any buffer , boolean async = false , boolean asyncAll = false @@ -53,17 +54,23 @@ component { , string asyncPriority = "NORMAL" , numeric asyncJoinTimeout = 0 ) { + // ColdBox 6.0+ uses 'data', Preside uses 'interceptData' — normalise + if ( !isNull( arguments.interceptData ) ) { + arguments.data = arguments.interceptData; + } + if ( arguments.async && !instance.utility.inThread() ) { return processAsync( event = arguments.event - , interceptData = arguments.interceptData + , interceptData = arguments.data , asyncPriority = arguments.asyncPriority , buffer = arguments.buffer ); } else if ( arguments.asyncAll AND NOT instance.utility.inThread() ) { + arguments.interceptData = arguments.data; return processAsyncAll( argumentCollection=arguments ); } else { - processSync( event=arguments.event, interceptData=arguments.interceptData, buffer=arguments.buffer ); + processSync( event=arguments.event, interceptData=arguments.data, buffer=arguments.buffer ); } } diff --git a/system/coldboxModifications/LegacyDslBuilder.cfc b/system/coldboxModifications/LegacyDslBuilder.cfc index ffdda1cee5..00603ba87c 100644 --- a/system/coldboxModifications/LegacyDslBuilder.cfc +++ b/system/coldboxModifications/LegacyDslBuilder.cfc @@ -8,7 +8,7 @@ component { return this; } - function process( required any definition, targetObject ) { + function process( required any definition, targetObject, targetID ) { var dsl = arguments.definition.dsl; if( reFindNoCase( '^coldbox:myplugin:.*', dsl ) ) { diff --git a/system/coldboxModifications/PresideWireboxDsl.cfc b/system/coldboxModifications/PresideWireboxDsl.cfc index 06920ea361..756c729048 100644 --- a/system/coldboxModifications/PresideWireboxDsl.cfc +++ b/system/coldboxModifications/PresideWireboxDsl.cfc @@ -6,7 +6,7 @@ component implements="coldbox.system.ioc.dsl.IDSLBuilder" { return this; } - public any function process( required any definition, any targetObject ) { + public any function process( required any definition, any targetObject, any targetID ) { var dsl = ListRest( definition.dsl, ":" ); var namespace = ListFirst( dsl, ":" ); diff --git a/system/coldboxModifications/cachebox/store/ConcurrentSoftReferenceStore.cfc b/system/coldboxModifications/cachebox/store/ConcurrentSoftReferenceStore.cfc index 0bad362283..097bc2344d 100644 --- a/system/coldboxModifications/cachebox/store/ConcurrentSoftReferenceStore.cfc +++ b/system/coldboxModifications/cachebox/store/ConcurrentSoftReferenceStore.cfc @@ -101,6 +101,14 @@ component extends="coldbox.system.cache.store.ConcurrentSoftReferenceStore" impl } ); } + public struct function getCachedObjectMetadata( required any objectKey ) { + var meta = variables.indexer.getObjectMetadata( arguments.objectKey ); + if ( IsNull( local.meta ) || !IsStruct( local.meta ) ) { + return {}; + } + return meta; + } + public any function clear( required any objectKey ) { var isSR = variables.indexer.getObjectMetadataProperty( arguments.objectKey, "isSoftReference" ); diff --git a/system/coldboxModifications/cachebox/store/ConcurrentStore.cfc b/system/coldboxModifications/cachebox/store/ConcurrentStore.cfc index d3817ac367..a735165418 100644 --- a/system/coldboxModifications/cachebox/store/ConcurrentStore.cfc +++ b/system/coldboxModifications/cachebox/store/ConcurrentStore.cfc @@ -69,6 +69,14 @@ component extends="coldbox.system.cache.store.ConcurrentStore" implements="" { } ); } + public struct function getCachedObjectMetadata( required any objectKey ) { + var meta = indexer.getObjectMetadata( arguments.objectKey ); + if ( IsNull( local.meta ) || !IsStruct( local.meta ) ) { + return {}; + } + return meta; + } + public any function clear( required any objectKey ) { var removedObj = pool.remove( arguments.objectKey ); var removedMeta = indexer.clear( arguments.objectKey ); diff --git a/system/coldboxModifications/cachebox/store/DiskStore.cfc b/system/coldboxModifications/cachebox/store/DiskStore.cfc index 65d7aab376..c5f04e2dd3 100644 --- a/system/coldboxModifications/cachebox/store/DiskStore.cfc +++ b/system/coldboxModifications/cachebox/store/DiskStore.cfc @@ -47,7 +47,7 @@ component implements="coldbox.system.cache.store.IObjectStore" accessors="true"{ // Prepare instance variables.cacheProvider = arguments.cacheProvider; variables.storeID = createObject( 'java', 'java.lang.System' ).identityHashCode( this ); - variables.indexer = new coldbox.system.cache.store.indexers.MetadataIndexer( fields ); + variables.indexer = new preside.system.coldboxModifications.cachebox.store.indexers.MetadataIndexer( fields ); variables.converter = new coldbox.system.core.conversion.ObjectMarshaller(); variables.directoryPath = ""; @@ -306,6 +306,23 @@ component implements="coldbox.system.cache.store.IObjectStore" accessors="true"{ return variables.indexer.getSize(); } + /** + * CB 7.0: IObjectStore now requires getSortedKeys() + */ + array function getSortedKeys( required property, sortType="text", sortOrder="asc" ) { + return getKeys(); + } + + /** + * CB 7.0: IObjectStore now requires getCachedObjectMetadata() + */ + struct function getCachedObjectMetadata( required objectKey ){ + if ( variables.indexer.objectExists( arguments.objectKey ) ) { + return variables.indexer.getObjectMetadata( arguments.objectKey ); + } + return {}; + } + //********************************* PRIVATE ************************************// /** diff --git a/system/coldboxModifications/cachebox/store/indexers/MetadataIndexer.cfc b/system/coldboxModifications/cachebox/store/indexers/MetadataIndexer.cfc index 4fac4c6e10..7050d4960b 100644 --- a/system/coldboxModifications/cachebox/store/indexers/MetadataIndexer.cfc +++ b/system/coldboxModifications/cachebox/store/indexers/MetadataIndexer.cfc @@ -1,4 +1,8 @@ -component extends="coldbox.system.cache.store.indexers.MetadataIndexer" { +/** + * ColdBox 7.0 removed coldbox.system.cache.store.indexers.MetadataIndexer. + * This is a standalone replacement used by Preside's ConcurrentStore. + */ +component { public any function init( required any fields ) { variables.poolMetadata = CreateObject( "java", "java.util.concurrent.ConcurrentHashMap" ).init() @@ -44,7 +48,32 @@ component extends="coldbox.system.cache.store.indexers.MetadataIndexer" { } } + public array function getSortedKeys( + required any property, + any sortType = "text", + any sortOrder = "asc" + ) { + return structSort( + variables.poolMetadata, + arguments.sortType, + arguments.sortOrder, + arguments.property + ); + } + + public void function clearAll() { + variables.poolMetadata.clear(); + } + public any function getSize() { return variables.poolMetadata.size(); } + + public void function setFields( required any fields ) { + variables.fields = arguments.fields; + } + + public any function getFields() { + return variables.fields; + } } diff --git a/system/coldboxModifications/includes/errorReport.cfm b/system/coldboxModifications/includes/errorReport.cfm index 4762a714ce..4a589adb62 100644 --- a/system/coldboxModifications/includes/errorReport.cfm +++ b/system/coldboxModifications/includes/errorReport.cfm @@ -1,264 +1,4 @@ - - - // Detect Session Scope - local.sessionScopeExists = true; - try { structKeyExists( session ,'x' ); } - catch ( any e ) { - local.sessionScopeExists = false; - } - try{ - local.thisInetHost = createObject( "java", "java.net.InetAddress" ).getLocalHost().getHostName(); - } - catch( any e ){ - local.thisInetHost = "localhost"; - } - - - - - - -
-

- - #oException.getErrorCode()# : - - 500 : - - An error occurred

- -
- - -

#oException.getExtramessage()#

-
- - - Event: #event.getCurrentEvent()#N/A -
- Routed URL: #event.getCurrentRoutedURL()#N/A -
- Layout: #Event.getCurrentLayout()#N/A (Module: #event.getCurrentLayoutModule()#) -
- View: #Event.getCurrentView()#N/A -
- Timestamp: #dateformat(now(), "MM/DD/YYYY")# #timeformat(now(),"hh:MM:SS TT")# - -
- - - - Type: #oException.gettype()#
-
- - - - Messages: - #oException.getmessage()# - - #oException.getExtendedInfo()#
-
- - - #oException.getDetail()# - - -
- -
- -

Tag Context:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Tag:#local.arrayTagContext[ local.i ].ID#
Template:#local.arrayTagContext[ local.i ].Template#
LINE:#local.arrayTagContext[ local.i ].codePrintHTML#
Line:#local.arrayTagContext[ local.i ].LINE#
- -

Stack Trace:

-
#processStackTrace( oException.getstackTrace() )#
- - -

FRAMEWORK SNAPSHOT:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bug Date:#dateformat(now(), "MM/DD/YYYY")# #timeformat(now(),"hh:MM:SS TT")#
Coldfusion ID: - - - CFID=#session.CFID# ; - - CFID=#client.CFID# ; - - - CFToken=#session.CFToken# ; - - CFToken=#client.CFToken# ; - - - JSessionID=#session.sessionID# - - - Session Scope Not Enabled - -
Template Path : #htmlEditFormat(CGI.CF_TEMPLATE_PATH)#
Path Info : #htmlEditFormat(CGI.PATH_INFO)#
Host & Server: #htmlEditFormat(cgi.http_host)# #local.thisInetHost#
Query String: #htmlEditFormat(cgi.QUERY_STRING)#
Referrer:#htmlEditFormat(cgi.HTTP_REFERER)#
Browser:#htmlEditFormat(cgi.HTTP_USER_AGENT)#
Remote Address: #htmlEditFormat(cgi.remote_addr)#
Database oException Information:
NativeErrorCode & SQL State:
#oException.getNativeErrorCode()# : #oException.getSQLState()#
SQL Sent:
#oException.getSQL()#
Database Driver Error Message:
#oException.getqueryError()#
Name-Value Pairs:
#oException.getWhere()#
Form variables:
#htmlEditFormat( key )#:#htmlEditFormat( form[ key ] )#
Session Storage:
#key#: #htmlEditFormat( session[ key ] )##key#
N/A Session Scope Not Enabled
Cookies:
#key#: #htmlEditFormat( cookie[ key ] )#
Extra Information Dump
- - [N/A]#oException.getExtraInfo()# - - - -
-
- -
-
\ No newline at end of file + + + + diff --git a/system/coldboxModifications/ioc/Builder.cfc b/system/coldboxModifications/ioc/Builder.cfc index e2dfd88b7f..54e5c1b541 100644 --- a/system/coldboxModifications/ioc/Builder.cfc +++ b/system/coldboxModifications/ioc/Builder.cfc @@ -5,10 +5,42 @@ */ component extends="coldbox.system.ioc.Builder" { + /** + * ColdBox 6.0 renamed Provider.get() to Provider.$get(). + * Override to use Preside's Provider shim that restores get(). + */ + private any function getProviderDSL( required definition, targetObject="", targetID ) { + var thisType = arguments.definition.dsl; + var thisTypeLen = listLen( thisType, ":" ); + var providerName = ""; + + switch ( thisTypeLen ) { + case 1: { providerName = arguments.definition.name; break; } + case 2: { providerName = getToken( thisType, 2, ":" ); break; } + default: { providerName = replaceNoCase( thisType, "provider:", "" ); } + } + + return new preside.system.coldboxModifications.ioc.Provider( + scopeRegistration : variables.injector.getScopeRegistration() + , targetObject : arguments.targetObject + , name : providerName + , injectorName : variables.injector.getName() + ); + } + public any function buildCfc( required any mapping, struct initArguments={} ) { var thisMap = arguments.mapping; var oModel = createObject( "component", thisMap.getPath() ); + // CB 7.0: FrameworkSupertype.init() sets variables.cbInjectedHelpers but + // some Preside components extend FrameworkSupertype without calling super.init(). + // Use WireBox's utility to inject it into the target's variables scope. + if ( StructKeyExists( oModel, "loadApplicationHelpers" ) ) { + variables.utility.getMixerUtil().start( oModel ); + oModel.injectPropertyMixin( "cbInjectedHelpers", {} ); + variables.utility.getMixerUtil().stop( oModel ); + } + // Do we have virtual inheritance? if( arguments.mapping.isVirtualInheritance() ){ // retrieve the VI mapping. diff --git a/system/coldboxModifications/ioc/Injector.cfc b/system/coldboxModifications/ioc/Injector.cfc index b3b398f7ac..ff62e47e22 100644 --- a/system/coldboxModifications/ioc/Injector.cfc +++ b/system/coldboxModifications/ioc/Injector.cfc @@ -49,7 +49,8 @@ component extends="coldbox.system.ioc.Injector" { // Register All Custom Listeners registerListeners(); // Create our object builder - variables.builder = new preside.system.coldboxModifications.ioc.Builder( this ); + variables.builder = new preside.system.coldboxModifications.ioc.Builder( this ); + variables.objectBuilder = variables.builder; // Register Custom DSL Builders variables.builder.registerCustomBuilders(); // Register Life Cycle Scopes @@ -78,6 +79,8 @@ component extends="coldbox.system.ioc.Injector" { // process mappings for metadata and initialization. variables.binder.processMappings(); + // ColdBox 6.0+ split eager init processing out of processMappings() + variables.binder.processEagerInits(); // Announce To Listeners we are online iData.injector = this; diff --git a/system/coldboxModifications/ioc/Provider.cfc b/system/coldboxModifications/ioc/Provider.cfc new file mode 100644 index 0000000000..b545d08089 --- /dev/null +++ b/system/coldboxModifications/ioc/Provider.cfc @@ -0,0 +1,13 @@ +/** + * Preside Provider shim for ColdBox 6.0+ + * + * ColdBox 6.0 renamed get() to $get() on Providers. + * This shim restores get() for backwards compatibility. + */ +component extends="coldbox.system.ioc.Provider" { + + any function get(){ + return $get(); + } + +} diff --git a/system/coldboxModifications/services/HandlerService.cfc b/system/coldboxModifications/services/HandlerService.cfc index 8438cf25ab..85cffb8586 100644 --- a/system/coldboxModifications/services/HandlerService.cfc +++ b/system/coldboxModifications/services/HandlerService.cfc @@ -2,6 +2,47 @@ component extends="coldbox.system.web.services.HandlerService" { variables.handlerBeans = {}; + /** + * Override newHandler to use Preside's EventHandler shim + * which adds back setNextEvent() and getModel() compatibility. + * CB 7 changed signature from newHandler(invocationPath) to newHandler(ehBean). + */ + function newHandler( required ehBean ){ + // Preside calls newHandler with a string path; CB 7 calls with an ehBean object + if ( IsSimpleValue( arguments.ehBean ) ) { + var injector = variables.wirebox; + var handlerPath = arguments.ehBean; + } else { + var injector = arguments.ehBean.isModule() ? variables.modules[ arguments.ehBean.getModule() ].injector : variables.wirebox; + var handlerPath = arguments.ehBean.getRunnable(); + } + + if ( NOT injector.getBinder().mappingExists( handlerPath ) ) { + injectorSeedBaseClasses( injector ); + injector + .registerNewInstance( name=handlerPath, instancePath=handlerPath ) + .setVirtualInheritance( "preside.system.coldboxModifications.EventHandler" ) + .setThreadSafe( true ) + .setScope( variables.handlerCaching ? "singleton" : "NoScope" ) + .setCacheProperties( key="handlers-#handlerPath#" ) + .setExtraAttributes( { handlerPath: handlerPath, isHandler: true } ); + } + + return injector.getInstance( handlerPath ); + } + + private function injectorSeedBaseClasses( required injector ){ + super.injectorSeedBaseClasses( arguments.injector ); + if ( NOT arguments.injector.getBinder().mappingExists( "preside.system.coldboxModifications.EventHandler" ) ) { + arguments.injector + .registerNewInstance( + name = "preside.system.coldboxModifications.EventHandler" + , instancePath = "preside.system.coldboxModifications.EventHandler" + ) + .setScope( "singleton" ); + } + } + public void function registerHandlers() { var appMapping = "/" & controller.getSetting( "appMapping" ).reReplace( "^/", "" ); var appMappingPath = controller.getSetting( "appMappingPath" ); diff --git a/system/coldboxModifications/services/InterceptorService.cfc b/system/coldboxModifications/services/InterceptorService.cfc index de60161b6c..e04419e91b 100644 --- a/system/coldboxModifications/services/InterceptorService.cfc +++ b/system/coldboxModifications/services/InterceptorService.cfc @@ -28,6 +28,43 @@ component extends="coldbox.system.web.services.InterceptorService" { return super.registerInterceptor( argumentCollection=arguments ); } + /** + * ColdBox 6.0+ calls announce() directly from WireBox/CacheBox, + * bypassing processState(). Override to suppress events during + * interceptor registration — matching CB 5.4 behaviour where + * WireBox called processState() which had the safety check. + */ + public any function announce( + required any state + , any data = structNew() + , boolean async = false + , boolean asyncAll = false + , boolean asyncAllJoin = true + , string asyncPriority = "NORMAL" + , numeric asyncJoinTimeout = 0 + ) { + // During interceptor registration, only allow the WireBox lifecycle + // events that are unavoidably announced during instantiation. + // All other events (including afterInstanceAutowire) are suppressed + // to match CB 5.4 behaviour where they were not yet registered as states. + if ( _registeringInterceptors && !_ignoreStatesDuringLoadCheck.findNoCase( arguments.state ) ) { + return; + } + + if( !StructKeyExists( variables.interceptionStates, arguments.state ) ){ + return; + } + + // CB 7/8: cbLoadInterceptorHelpers fires AFTER afterConfigurationLoad, + // but Preside interceptors need helpers (isFeatureEnabled etc.) during + // afterConfigurationLoad. Ensure helpers are loaded first. + if ( arguments.state == "afterConfigurationLoad" && StructKeyExists( variables.interceptionStates, "cbLoadInterceptorHelpers" ) ) { + super.announce( state="cbLoadInterceptorHelpers", data={} ); + } + + return super.announce( argumentCollection=arguments ); + } + public any function processState( required any state , any interceptData = structNew() @@ -50,10 +87,56 @@ component extends="coldbox.system.web.services.InterceptorService" { return; } - return super.processState( argumentCollection=arguments ); + return super.announce( + state = arguments.state + , data = arguments.interceptData + , async = arguments.async + , asyncAll = arguments.asyncAll + , asyncAllJoin = arguments.asyncAllJoin + , asyncPriority = arguments.asyncPriority + , asyncJoinTimeout = arguments.asyncJoinTimeout + ); } + /** + * Override createInterceptor to use Preside's Interceptor shim + * which restores getModel(), renderView() etc. + * Updated for CB 8 signature (injector parameter, no controller constructor arg). + */ + function createInterceptor( + required interceptorClass, + required interceptorName, + struct interceptorProperties = {}, + injector = variables.wirebox + ){ + if ( NOT arguments.injector.getBinder().mappingExists( "interceptor-" & arguments.interceptorName ) ) { + injectorSeedBaseClasses( arguments.injector ); + arguments.injector + .registerNewInstance( + name = "interceptor-" & arguments.interceptorName + , instancePath = arguments.interceptorClass + ) + .setScope( arguments.injector.getBinder().SCOPES.SINGLETON ) + .setThreadSafe( true ) + .setVirtualInheritance( "preside.system.coldboxModifications.Interceptor" ) + .addDIConstructorArgument( name="properties", value=arguments.interceptorProperties ); + } + return getInterceptor( arguments.interceptorName ); + } + + private function injectorSeedBaseClasses( required injector ){ + super.injectorSeedBaseClasses( arguments.injector ); + if ( NOT arguments.injector.getBinder().mappingExists( "preside.system.coldboxModifications.Interceptor" ) ) { + arguments.injector + .registerNewInstance( + name = "preside.system.coldboxModifications.Interceptor" + , instancePath = "preside.system.coldboxModifications.Interceptor" + ) + .setScope( "singleton" ); + } + } + public any function registerInterceptionPoint( required any interceptorKey , required any state diff --git a/system/coldboxModifications/services/Renderer.cfc b/system/coldboxModifications/services/Renderer.cfc index 104191e8eb..b6f2e17e23 100644 --- a/system/coldboxModifications/services/Renderer.cfc +++ b/system/coldboxModifications/services/Renderer.cfc @@ -53,51 +53,46 @@ component accessors="true" serializable="false" singleton="true" extends="coldbo /************************************** CONSTRUCTOR *********************************************/ /** - * Constructor - * @controller The ColdBox main controller - * @controller.inject coldbox - */ - function init( required controller ){ - // setup controller - variables.controller = arguments.controller; + * 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(). + */ + function startup() { + if ( variables._startupDone ?: false ) { return; } + + // In CB 7, controller may be injected as a property rather than passed to init + if ( IsNull( variables.controller ) ) { return; } + + variables._startupDone = true; + // Register LogBox - variables.logBox = arguments.controller.getLogBox(); - // Register Log object + variables.logBox = variables.controller.getLogBox(); variables.log = variables.logBox.getLogger( this ); - // Register Flash RAM - variables.flash = arguments.controller.getRequestService().getFlashScope(); - // Register CacheBox - variables.cacheBox = arguments.controller.getCacheBox(); - // Register WireBox - variables.wireBox = arguments.controller.getWireBox(); - // Register thread utils - variables.threadUtil = wirebox.getInstance( "threadUtil" ); - - // Set Conventions, Settings and Properties - variables.layoutsConvention = variables.controller.getSetting( "layoutsConvention", true ); - variables.viewsConvention = variables.controller.getSetting( "viewsConvention", true ); - variables.appMapping = variables.controller.getSetting( "AppMapping" ); - variables.viewsExternalLocation = variables.controller.getSetting( "ViewsExternalLocation" ); - variables.layoutsExternalLocation = variables.controller.getSetting( "LayoutsExternalLocation" ); - variables.modulesConfig = variables.controller.getSetting( "modules" ); - variables.viewsHelper = variables.controller.getSetting( "viewsHelper" ); - variables.viewCaching = variables.controller.getSetting( "viewCaching" ); - variables.isViewsHelperIncluded = false; + variables.flash = variables.controller.getRequestService().getFlashScope(); + variables.cacheBox = variables.controller.getCacheBox(); + variables.wireBox = variables.controller.getWireBox(); + variables.threadUtil = variables.wireBox.getInstance( "threadUtil" ); + + variables.layoutsConvention = variables.controller.getSetting( "layoutsConvention", true ); + variables.viewsConvention = variables.controller.getSetting( "viewsConvention", true ); + variables.appMapping = variables.controller.getSetting( "AppMapping" ); + variables.viewsExternalLocation = variables.controller.getSetting( "ViewsExternalLocation" ); + variables.layoutsExternalLocation = variables.controller.getSetting( "LayoutsExternalLocation" ); + variables.modulesConfig = variables.controller.getSetting( "modules" ); + variables.viewsHelper = variables.controller.getSetting( "viewsHelper" ); + variables.viewCaching = variables.controller.getSetting( "viewCaching" ); + variables.isDiscoveryCaching = variables.controller.getSetting( "handlerCaching" ); + variables.isViewsHelperIncluded = false; // Verify View Helper Template extension + location - if( len( variables.viewsHelper ) ){ - // extension detection - variables.viewsHelper = ( listLast( variables.viewsHelper, "." ) eq "cfm" ? variables.viewsHelper : variables.viewsHelper & ".cfm" ); - // Append mapping to it. + if ( Len( variables.viewsHelper ) ) { + variables.viewsHelper = ( ListLast( variables.viewsHelper, "." ) eq "cfm" ? variables.viewsHelper : variables.viewsHelper & ".cfm" ); variables.viewsHelper = "/#variables.appMapping#/#variables.viewsHelper#"; } // Template Cache & Caching Maps - variables.renderedHelpers = {}; - variables.lockName = "rendering.#variables.controller.getAppHash()#"; - - // Discovery caching is tied to handlers for discovery. - variables.isDiscoveryCaching = controller.getSetting( "handlerCaching" ); + variables.renderedHelpers = {}; + variables.lockName = "rendering.#variables.controller.getAppHash()#"; // Load global UDF Libraries into target loadApplicationHelpers(); @@ -105,6 +100,15 @@ component accessors="true" serializable="false" singleton="true" extends="coldbo return this; } + function init( controller ){ + if ( !IsNull( arguments.controller ) ) { + variables.controller = arguments.controller; + startup(); + } + + return this; + } + /************************************** VIEW METHODS *********************************************/ /** @@ -510,6 +514,66 @@ component accessors="true" serializable="false" singleton="true" extends="coldbo * @viewModule The module to explicitly render the view from * @prePostExempt If true, pre/post layout interceptors will not be fired. By default they do fire */ + /** + * CB 7.0: view() is the new name for renderView(). + * Delegate to our renderView() override so Preside's custom view + * path resolution is used instead of vanilla ColdBox view(). + */ + function view( + view="", + struct args=getRequestContext().getCurrentViewArgs(), + module="", + boolean cache=false, + cacheTimeout="", + cacheLastAccessTimeout="", + cacheSuffix="", + cacheProvider="template", + collection, + collectionAs="", + numeric collectionStartRow="1", + numeric collectionMaxRows=0, + collectionDelim="", + boolean prePostExempt=false, + name, + viewVariables={} + ){ + return renderView( argumentCollection=arguments ); + } + + /** + * CB 7.0: externalView() is the new name for renderExternalView(). + * Delegate to our renderExternalView() override. + */ + function externalView( + required view, + struct args=getRequestContext().getCurrentViewArgs(), + boolean cache=false, + cacheTimeout="", + cacheLastAccessTimeout="", + cacheSuffix="", + cacheProvider="template", + viewVariables={} + ){ + return renderExternalView( argumentCollection=arguments ); + } + + /** + * CB 7.0: layout() is the new name for renderLayout(). + * Delegate to our renderLayout() override to avoid infinite recursion + * via FrameworkSupertype.layout() -> getRenderer().layout() -> FrameworkSupertype.layout() + */ + function layout( + layout, + module="", + view="", + struct args=getRequestContext().getCurrentViewArgs(), + viewModule="", + boolean prePostExempt=false, + viewVariables={} + ){ + return renderLayout( argumentCollection=arguments ); + } + function renderLayout( layout, module="", @@ -913,7 +977,7 @@ component accessors="true" serializable="false" singleton="true" extends="coldbo private struct function _getViewMappings() { var site = getRequestContext().getSite(); var cacheKey = "viewsFullMappings" & ( site.template ?: "" ); - var ignoreFileSvc = getModel( "ignoreFileService" ); + var ignoreFileSvc = getInstance( "ignoreFileService" ); lock name="#lockName#" type="readonly" timeout="15" throwontimeout="true" { if ( controller.settingExists( cacheKey ) ) { diff --git a/system/coldboxModifications/services/RoutingService.cfc b/system/coldboxModifications/services/RoutingService.cfc index c8e5593ac8..caf00706d0 100644 --- a/system/coldboxModifications/services/RoutingService.cfc +++ b/system/coldboxModifications/services/RoutingService.cfc @@ -19,24 +19,32 @@ component extends="coldbox.system.web.services.RoutingService" accessors=true { variables.controller.getInterceptorService().registerInterceptor( interceptorClass="preside.system.interceptors.PageCachingInterceptor" ); } - public void function onRequestCapture( event, interceptData ) { + public void function requestCapture( required event ) { + var interceptData = {}; + var presideArgs = { event=arguments.event, interceptData=interceptData }; + _announceInterception( "prePresideRequestCapture", interceptData ); - _checkRedirectDomains( argumentCollection=arguments ); + _checkRedirectDomains( argumentCollection=presideArgs ); if ( featureService.isFeatureEnabled( "sites" ) ) { - _detectIncomingSite( argumentCollection=arguments ); + _detectIncomingSite( argumentCollection=presideArgs ); } - _setCustomTenants ( argumentCollection=arguments ); - _checkUrlRedirects ( argumentCollection=arguments ); - _detectLanguage ( argumentCollection=arguments ); - _setPresideUrlPath ( argumentCollection=arguments ); + _setCustomTenants ( argumentCollection=presideArgs ); + _checkUrlRedirects ( argumentCollection=presideArgs ); + _detectLanguage ( argumentCollection=presideArgs ); + _setPresideUrlPath ( argumentCollection=presideArgs ); - if ( !_routePresideSESRequest( argumentCollection=arguments ) ) { - super.onRequestCapture( argumentCollection=arguments ); + if ( !_routePresideSESRequest( argumentCollection=presideArgs ) ) { + super.requestCapture( argumentCollection=arguments ); } _announceInterception( "postPresideRequestCapture", interceptData ); } + public void function onRequestCapture( event, interceptData ) { + // No-op: In ColdBox 6.0+, routing is handled via requestCapture() above. + // This method is kept for backwards compatibility with any interceptor listeners. + } + public void function onBuildLink( event, interceptData ) { for( var route in _getPresideRoutes() ){ if ( route.get().reverseMatch( buildArgs=interceptData, event=event ) ) { diff --git a/system/config/Config.cfc b/system/config/Config.cfc index c69e3a1315..5bda8fa766 100644 --- a/system/config/Config.cfc +++ b/system/config/Config.cfc @@ -130,7 +130,7 @@ component { , requestStartHandler = "General.requestStart" , requestEndHandler = "General.requestEnd" , missingTemplateHandler = "General.notFound" - , onInvalidEvent = "General.notFound" + , invalidEventHandler = "General.notFound" , coldboxExtensionsLocation = "preside.system.coldboxModifications" , customErrorTemplate = "/preside/system/coldboxModifications/includes/errorReport.cfm" }; diff --git a/system/config/Router.cfc b/system/config/Router.cfc index 217afcc215..28166d3962 100644 --- a/system/config/Router.cfc +++ b/system/config/Router.cfc @@ -1,7 +1,6 @@ component extends="coldbox.system.web.routing.Router" { public void function configure() { - setUniqueUrls( false ); setExtensionDetection( false ); setBaseUrl( "/" ); @@ -101,7 +100,7 @@ component extends="coldbox.system.web.routing.Router" { arguments.dsl = "delayedInjector:" & arguments.dsl; } - return super.getModel( + return variables.controller.getWirebox().getInstance( dsl = arguments.dsl ?: NullValue() , initArguments = arguments.initArguments ); diff --git a/system/config/WireBox.cfc b/system/config/WireBox.cfc index f148d524c9..9efb3bf080 100644 --- a/system/config/WireBox.cfc +++ b/system/config/WireBox.cfc @@ -29,7 +29,11 @@ } private void function _mapCommonSystemServices() { - mapDirectory( packagePath="preside.system.services", filter=this._filterServices, influence=function( mapping, objectPath ) { + var pkg = "preside.system.services"; + var dir = ExpandPath( "/#Replace( pkg, '.', '/', 'all' )#" ); + mapDirectory( packagePath=pkg, filter=function( thisPath ) { + return _filterServices( _toComponentPath( thisPath, dir, pkg ) ); + }, influence=function( mapping, objectPath ) { _injectPresideSuperClass( argumentCollection=arguments ); } ); } @@ -39,7 +43,11 @@ var appMappingPath = getColdbox().getSetting( name="appMappingPath", defaultValue="app" ); if ( DirectoryExists( "/#appMapping#/services" ) ) { - mapDirectory( packagePath="#appMappingPath#.services", filter=this._filterServices, influence=function( mapping, objectPath ) { + var pkg = "#appMappingPath#.services"; + var dir = ExpandPath( "/#Replace( pkg, '.', '/', 'all' )#" ); + mapDirectory( packagePath=pkg, filter=function( thisPath ) { + return _filterServices( _toComponentPath( thisPath, dir, pkg ) ); + }, influence=function( mapping, objectPath ) { _injectPresideSuperClass( argumentCollection=arguments ); } ); } @@ -50,7 +58,11 @@ for( var i=1; i<=extensions.len(); i++ ){ var servicesDir = ListAppend( extensions[i].directory, "services", "/" ) if ( DirectoryExists( servicesDir ) ) { - mapDirectory( packagePath=servicesDir, filter=this._filterServices, influence=function( mapping, objectPath ) { + var pkg = servicesDir; + var dir = ExpandPath( servicesDir ); + mapDirectory( packagePath=pkg, filter=function( thisPath ) { + return _filterServices( _toComponentPath( thisPath, dir, pkg ) ); + }, influence=function( mapping, objectPath ) { _injectPresideSuperClass( argumentCollection=arguments ); } ); } @@ -170,7 +182,7 @@ return false; } - private boolean function _filterServices( objectPath ) { + private boolean function _filterServices( required string objectPath ) { if ( ignoreFileService.isIgnored( "service", arguments.objectPath ) ) { return false; } @@ -184,6 +196,23 @@ return true; } + private string function _toComponentPath( required string filePath, required string targetDir, required string packagePath ) { + // If already a dot-path (CB 5.4 behaviour), return as-is + if ( !FindNoCase( ".cfc", arguments.filePath ) ) { + return arguments.filePath; + } + + // Convert absolute file path to component dot-path + // Strip target directory prefix, remove .cfc, convert slashes to dots + var relativePath = ReplaceNoCase( arguments.filePath, arguments.targetDir, "" ); + relativePath = ReplaceNoCase( relativePath, ".cfc", "" ); + relativePath = ReReplace( relativePath, "(\\|/)", ".", "all" ); + + // Prepend package path (strip leading dots) + var result = ReReplace( arguments.packagePath, "^/", "" ) & relativePath; + return ReReplace( result, "^\.", "" ); + } + private boolean function _featureDisabled( required struct meta ) { if ( StructKeyExists( arguments.meta, "feature" ) ) { return Len( arguments.meta.feature ) && !featureService.isFeatureEnabled( arguments.meta.feature ); diff --git a/system/handlers/admin/SystemInformation.cfc b/system/handlers/admin/SystemInformation.cfc index f266ffda41..177d8fe87e 100644 --- a/system/handlers/admin/SystemInformation.cfc +++ b/system/handlers/admin/SystemInformation.cfc @@ -54,6 +54,7 @@ component extends="preside.system.base.AdminHandler" { args.presideCmsVersion = updateManagerService.getCurrentVersion(); + args.coldboxVersion = getSetting( name="version", fwSetting=true, defaultValue="Unknown" ); args.applicationServer = productName & ' (' & productVersion & ')'; args.java = javaVersion; args.os = osName & ' (' & osVersion & ')'; diff --git a/system/helpers/presideProxies.cfm b/system/helpers/presideProxies.cfm index 2554470d3e..c929478431 100644 --- a/system/helpers/presideProxies.cfm +++ b/system/helpers/presideProxies.cfm @@ -269,6 +269,23 @@ + + + + + + + + + + + + + + + + + diff --git a/system/i18n/cms.properties b/system/i18n/cms.properties index 2de38855ab..e15425f874 100644 --- a/system/i18n/cms.properties +++ b/system/i18n/cms.properties @@ -1072,6 +1072,7 @@ sites.clonesite.confirmation=Site was cloned successfully systemInformation.menu.title=System Information systemInformation.cms.th=Preside +systemInformation.coldbox.th=ColdBox Framework systemInformation.applicationServer.th=Application Server systemInformation.dataBase.th=Database Server systemInformation.java.th=Java diff --git a/system/i18n/cms_de.properties b/system/i18n/cms_de.properties index 0fdf7e5aa9..2d6af270ed 100644 --- a/system/i18n/cms_de.properties +++ b/system/i18n/cms_de.properties @@ -901,6 +901,7 @@ sites.clonesite.btn=Seite klonen sites.clonesite.confirmation=Die Seite wurde erfolgreich geklont systemInformation.menu.title=Systeminformationen systemInformation.cms.th=Preside +systemInformation.coldbox.th=ColdBox Framework systemInformation.applicationServer.th=Application Server systemInformation.dataBase.th=Datenbank Server systemInformation.java.th=Java diff --git a/system/views/admin/systemInformation/_generalTab.cfm b/system/views/admin/systemInformation/_generalTab.cfm index 185ae8384b..3fc15883b6 100644 --- a/system/views/admin/systemInformation/_generalTab.cfm +++ b/system/views/admin/systemInformation/_generalTab.cfm @@ -2,6 +2,7 @@ pageTitle = args.pageTitle ?: ""; presideCmsVersion = args.presideCmsVersion ?: ""; + coldboxVersion = args.coldboxVersion ?: ""; applicationServer = args.applicationServer ?: ""; java = args.java ?: ""; os = args.os ?: ""; @@ -13,6 +14,7 @@ #translateResource( uri="cms:systemInformation.cms.th" )# + #translateResource( uri="cms:systemInformation.coldbox.th" )# #translateResource( uri="cms:systemInformation.applicationServer.th" )# #translateResource( uri="cms:systemInformation.dataBase.th" )# #translateResource( uri="cms:systemInformation.java.th" )# @@ -22,6 +24,7 @@ #presideCmsVersion# + #coldboxVersion# #applicationServer# #dataBase# #java#