Change config property value programmatically

Are there any method to change the value of configuration properties? I have tried to use

application.fapi.setConfig(key='configKeyType', name='keyName', value=now()

After a ?updateapp=1 the value is back to what it is was after editing it from the /webtop.

Example of a property value I want to change: sitetitle in my configGeneral.cfc - or accessToken in my configOAuth.cfc

There’s a fourth argument on fapi.setConfig() in 7.x which allows you to set the value as “read-only”, which means it will survive application restarts and config saves, and lock the value from editing in the actual config record in the webtop.

application.fapi.setConfig("general", "webtopLogoPath", "/wsimages/madfellas-webtop-logo.png", true)

It’s not supported in 6.x though… Perhaps this was a bug and the original method (even without the read-only flag), should have been persisting the config to the database… Saving configs was a bit tricky because of the way they are serialized from a form component and saved into another content type (farConfig). Do you need this for 6.x or 7.x?

@justincarter: I tried this yesterday:

<cfdump var="#application.fapi.getConfig('googleAuth', 'accessToken')#" />
<cfset application.fapi.setConfig('googleAuth', 'accessToken', 'test', true) />

This does not change the value in the DB (We are running CF10 on the p700 branch). I wrote a “quickfix” for this, I only need to change strings so it works ok.

<cffunction name="updateConfigKey" returntype="struct" output="false">
	<cfargument name="configTypeKey" type="string" required="true" hint="Use the config (component) key attribute" />
	<cfargument name="keyName" type="string" required="true" hint="The key name" />
	<cfargument name="newKeyValue" type="string" required="true" hint="Value of the key" />

	<cfquery datasource="#application.dsn#" name="qConfig">
		select *, 'farConfig' AS typename
		from farConfig
		where configkey = '#arguments.configTypeKey#'
	</cfquery>

	<!--- The config object --->
	<cfset stConfigObj = application.fapi.getContentObject(objectID=qConfig.objectID) />

	<!--- The object with the config keys --->
	<cfset stConfigKeys = deserializeJSON(stConfigObj.configData) />
	<cfset stConfigKeys[arguments.keyName] = arguments.newKeyValue />

	<cfset stConfigObj.configData = serializeJSON(stConfigKeys) />
	<cfset stSave = application.fapi.setData(stProperties=stConfigObj) />
	<cfif stSave.bSuccess>
		<cfset application.fapi.setConfig(arguments.configTypeKey, arguments.keyName, arguments.newKeyValue) />
	</cfif>

	<cfreturn stSave />

</cffunction>

That’s right, it doesn’t save it to the database (because it doesn’t really need to, it’s a hard coded value that will always be set in memory whether or not there is any value in the database). But if you do another cfdump after you call setConfig() you should see the value has changed. I can see that it would be useful to be able to update configs in the database more easily :smile:

In 7.x we also support arrays in configs, so perhaps the above would work if we removed the type="string" from the newKeyValue argument. Ideally this should be a method on farConfig I think, and fapi.setConfig() would call it.

Adobe ColdFusion serializeJSON() converts ODBCDate(Time) to another format - does FarCry Core have a custom JSON serializer?

You will need to set the config in serverSpecificVarsAfterInit.

Blair

I need the values to persist, so I want them to be saved to the database. My function in this post solves this, but it need some more work to support arrays, dates etc

The intent of fapi.setConfig() is to allow developers to override global constants set up in config files, not to alter the value in the database. If you need to change the value of a config in the database you should be able to use the farConfig content type functions like setData().

Setting the value in the code only has the benefit of being in version control. Setting the readonly attribute has the added value of preventing users from being able to override the value in the webtop UI (which i think should be the default behaviour).

Typically fapi.setConfig() is only used in ./config/_serverSpecificVarsAfterInit.cfm and to enforce a particular set of global constants.