I am getting the following error message. I have already created Uploads.cfc handler in handlers directory. Checked everything, can't find the solution.
Error Type: HandlerService.EventHandlerNotRegisteredException : [N/A]
Error Messages: The event: uploads is not valid registered event.
Here is the Uploads.cfc code:
<!--- Default Action --->
<cffunction name="index" returntype="string" output="false" hint="My main event">
<cfargument name="event">
<cfargument name="rc">
<cfargument name="prc">
<cfobject component="model.Uploader" name="fileUploader">
<cfset filesJson = fileUploader.Upload(rc.file)>
<cfreturn filesJson>
</cffunction>
Can you please suggest a solution?
You shouldn't have to restart the whole CF server. You just need to re-initialize ColdBox. Just add ?fwreint= or ?fwreint={password} to the URL. The password is set in ColdBox.cfc: "reinitpassword". You can also configure in ColdBox.cfc to not cache handlers in non-production environments.
If you're using ColdBox 3.6 or newer, you don't have to define event, rc and prc anymore.
<cffunction name="index" returntype="string" output="false" hint="My main event">
<cfobject component="model.Uploader" name="fileUploader">
<cfset filesJson = fileUploader.Upload(rc.file)>
<cfreturn filesJson>
</cffunction>
Secondly, you should use WireBox instead of creating objects on the fly as you're doing. And finally, don't define variables specific to a function into the variables scope of the handler CFC file. Prefix them with local to make sure that those variables are "function local": only available to the particular function that is using them.
<cffunction name="index" returntype="string" output="false" hint="My main event">
<cfset local.fileUploader = getModel("Uploader") >
<cfset local.filesJson = fileUploader.Upload(rc.file)>
<cfreturn local.filesJson>
</cffunction>
I have also encountered the same problem in the past. Try restart the ColdFusion Application Server.
iKnowKungFu misspelled ?fwreint= (missing i)
Should be ?fwreinit
Related
We've migrated a ColdFusion application from ColdFusion 10 to ColdFusion 2016. After Migration, Application variables are not staying in its scope, it is refreshing on each and every request.
Consider the following example,
Application.cfm
<cfsetting enablecfoutputonly="true" />
<CFAPPLICATION NAME="Test App"
SETCLIENTCOOKIES="YES"
CLIENTMANAGEMENT="YES"
SESSIONMANAGEMENT="YES"
SESSIONTIMEOUT="#CREATETIMESPAN(0,8,0,0)#"
APPLICATIONTIMEOUT="#CREATETIMESPAN(1,0,0,0)#">
<cfdump var="#Application#" label="app">
<CFLOCK SCOPE="APPLICATION" TYPE="EXCLUSIVE" TIMEOUT="10">
<CFSET Application.Email = "test#test.com">
<CFSET Application.DataSource="test">
</cflock>
Test.cfm
<CFLOCK SCOPE="APPLICATION" TYPE="READONLY" TIMEOUT="10">
<cfset Application.one = 1>
<cfset Application.two = 2>
<cfset Application.three = 3>
</cflock>
OnRequestEnd.cfm
<cfsetting showdebugoutput="false" />
<cfdump var="#Application#" label="onRequestEnd">
So if we request /test.cfm
it'll throw the following output
Again refreshing the page also giving the same output
Not sure why the Application scoped variables are losing its persistence.
the following is the expected output..
Any idea of Why the application variables are lost and getting refreshed on each and every request ?
I haven't tested this code, but what you're seeing is the procedural order of operation performed by Application.cfm. You're essentially redefining the application on every request, which is why on the name exists in your initial dump and the rest exist on the dump in onRequestEnd.
If you update your code to use Application.cfc, you can ditch the cflock code, better organize your "triggers" and define your application variables once, when needed, using onApplicationStart.
<cfcomponent>
<cfset this.name = "Test App">
<cfset this.SETCLIENTCOOKIES="YES">
<cfset this.CLIENTMANAGEMENT="YES">
<cfset this.SESSIONMANAGEMENT="YES">
<cfset this.SESSIONTIMEOUT="#CREATETIMESPAN(0,8,0,0)#">
<cfset this.APPLICATIONTIMEOUT="#CREATETIMESPAN(1,0,0,0)#">
<cfsetting enablecfoutputonly="true" />
<cffunction name="onApplicationStart" access="public" returnType="void" output="false">
<cfset application.Email = "test#test.com">
<cfset application.DataSource="test">
</cffunction>
<cffunction name="onRequestStart" access="public" returntype="boolean" output="false">
<cfset application.one = 1>
<cfset application.two = 2>
<cfset application.three = 3>
<cfreturn true>
</cffunction>
<cffunction name="onRequestEnd" access="public" returntype="boolean" output="false">
<cfsetting showdebugoutput="false" />
<cfdump var="#application#" label="onRequestEnd">
<cfreturn true>
</cffunction>
</cfcomponent>
This should define email and datasource in the application scope one time, when the app first loads. The variables one, two and three will be created at the start of each request, but you can add a check to set them only if they don't already exist.
You can then use child Application.cfc files to help modularize your application using sub-folders and sub-application specific variables. They'll still exist in the scope of the larger application, but you'll be able to manage them from a location specific to a sub-app this way.
I am new to Mura and have a lot of existing code that I am trying to utilize. I have a globalFunction.cfc file that has a lot of functions that I need to have access to for the existing code. Previously I always extended my application.cfc to the global function so they where always there. With Mura I am not sure where to include it and still keep the installation "upgrade safe".
Any suggestions are appreciated.
In your [site]/includes folder is an Application.cfc. I believe that is the one you are looking to have extend your globalFunction.cfc. It is update safe.
Lance,
You can just put any functions you're wanting to use throughout your site in your eventHandler or contentRenderer files in your theme's folder. These are update safe, and depending on how you're wanting to use them, you can use one for display and the other for function.
EventHandler Ex:
<!--- PAGE - Default --->
<cffunction name="onPageDefaultBodyRender" output="true" returntype="any">
<cfargument name="$">
<cfif $.getcontentID() neq "00000000000000000000000000000000001">#$.dspInclude('/themes/MYTHEME/display_objects/bodies/dsp_body_default.cfm')#</cfif>
</cffunction>
ContentRenderer Ex:
<cffunction name="removeLinks" returntype="string" access="public">
<cfargument name="str" default="" required="true">
<cfset str=reReplace(str, "<[[:space:]]*[aA].*?>(.*?)<[[:space:]]*/[[:space:]]*a[[:space:]]*>","\1","all") />
<cfreturn trim(str) />
</cffunction>
The EventHandler here just puts out an different body if its on the home page, where the contentRenderer removes any links if i use $.removeLinks(MYURLSTRING).
HTH
I'm trying to refactor all of my CFCs to avoid using SESSION and APPLICATION variables (not an easy task).
However, in this application, SESSION variables are used in every database call, since different logged in users may be accessing different databases and schemas:
<cfquery name="qEmployees" datasource="#SESSION.DataSourceName#">
SELECT *
FROM #SESSION.DatabaseSchema#.Employees
</cfquery>
I don't want to go through the trouble of passing these two SESSION variables to every method call that accesses the database. This is especially the case since I don't want to pass DSNs and Schema Names in remote AJAX calls.
What is best practice for doing this - for all Scopes that shouldn't be used in CFCs?
I think that since the datasource truly is variable I'd pass it into every function as an optional parameter and set the default value to a variables scoped dsn attribute. I'd set the variables scoped DSN in the CFC's constructor. That way you only have to pass in the DSN for the AJAX calls.
<cffunction name="doFoo" access="remote"...>
<cfargument name="dsn" type="String" required="false" default="#variables.datasource#" />
</cffunction>
I'd use the session scope of your app to store the users dsn name and use that var to pass to the AJAX call.
You should create an "init" method that will serve as a constructor for your CFC. You can then instantiate the CFCs and store them in a shared scope, most likely the application scope. From here, to use this CFC via AJAX, I typically will create a remote facade. Basically this is another CFC that will directly access the CFC instance in the application scope. It will implement the methods you need to access via Ajax, expose them using access="remote" giving your application access to the access="public" methods from the actual CFC. In this case it is generally accepted that the remote facade can access the application scope directly as part of the design pattern.
A simple example:
example.cfc:
<cfcomponent output="false">
<cffunction name="init" access="public" output="false" returntype="any">
<cfargument name="dsn" type="string" required="true" />
<cfset variables.dsn = arguments.dsn />
<cfreturn this />
</cffunction>
<cffunction name="doStuff" access="public" output="false" returntype="query">
<cfset var q = "" />
<cfquery name="q" datasource="#variables.dsn#">
select stuff from tblStuff
</cfquery>
<cfreturn q />
</cffunction>
</cfcomponent>
In your Application.cfc onApplicationStart() method:
<cfset application.example = createObject("component","example").init(dsn = "somedsn") />
remote.cfc:
<cfcomponent output="false">
<cffunction name="doStuff" access="remote" returntype="query">
<cfreturn application.example.doStuff() />
</cffunction>
</cfcomponent>
Can you set your datasource variables in the onRequest or onRequestStart functions in your Application.cfc
<cffunction name="onSessionStart">
<cfset session.dsn = _users_personal_dsn_ />
</cffunction>
<cffunction name="onRequestStart" >
<cfset dsn = "#session.dsn#" />
</cffunction>
<cfquery name="qEmployees" datasource="#dsn#">
SELECT *
FROM #SESSION.DatabaseSchema#.Employees
</cfquery>
etc.
not sure if that will work [not tested - actually feels a bit sloppy]
-sean
The scope you choose (for any variation of this question, not just for DSNs) should be based on whether the lifetime of the value is the same as the lifetime of the scope.
In our application, the DSN is just set once in the lifetime of the application, so we have an application.config struct that gets created (parsed from a file) in onApplicationStart, and within it is application.config.dsn
If your value really does change between sessions, but not over the life of a session, go ahead and use the session scope.
If your value could change for any given request, but not in the middle of a request, put it in the request scope.
That said, still heed ryan's advice and add optional arguments that only default to this value: being flexible is always the best.
My suggestion for this is to create a base class and then have your components that need database access extend that component. It doesn't have to be in the immediate parent hierarchy but somewhere down the line.
They goal is to do two things, keep the cfc abstracted from the main program and keep it easily configurable. This accomplishes both.
So your CFC that queries the database would look something like this :
<cfcomponent extends="DataAccessBase">
<cffunction name="myFunction" access="public" returntype="string">
<cfquery datasource="#getDSN()#" name="qStuff">select * from table</cfquery>
</cffunction>
The key above is the extends="DataAccessBase" portion. This adds the layer of abstraction where you can control the data access at one configurable point, but it's not tied to the application itself, leaving the component abstracted from where it's implemented.
Your DataAccessBase.cfc could look something like this:
<cfcomponent>
<cffunction name="loadSettings">
<cfparam name="request.settings" default="#structNew()#">
<cfparam name="request.settigns.loaded" default="false">
<cfif request.settings.loaded eq false>
<!--- load settings from resource bundle etc --->
<cfset request.settings.dsn = 'myDSN'>
<cfset request.settings.loaded = true>
</cfif>
</cffunction>
<cffunction name="getDsn" access="public" returntype="string">
<cfset loadSettings()>
<cfreturn request.settings.dsn>
</cffunction>
You can of course get more intricate with how you configure and store the settings etc, but that's out of scope of the question I think. :)
I don't see any reason to pass the DSN with every method call. Yes, it works, but it's not necessary. The components are developed with a built-in assumption of the datastructure so you know that it is not going to change from a addItem() call to a updateItem() call, thus its duplication of work which means additional points of failure. :P
Make sense?
Here is my coldfusion web service. When I use soapUI tool to call 'test', i am receiving this
"<ns1:stackTrace xmlns:ns1="http://xml.apache.org/axis/">org.xml.sax.SAXParseException: Premature end of file."
error.
can anyone help me on this issue? I already seached online, but no luck. any code issue?
do I need to use <cfproperty> tag?
<cfcomponent output="false">
<!--- initialisation --->
<cffunction
name="init"
output="false"
hint="return an initialized object.">
<!--- Return THIS reference. --->
<cfreturn THIS />
</cffunction>
<!--- ping --->
<cffunction
name="test"
access="remote"
returntype="numeric"
output="false"
hint="return an true = 0.">
<!--- declare local variables --->
<cfset var local = 0 />
<!--- Return 0. --->
<cfreturn local />
</cffunction>
</cfcomponent>
Couple questions: are you on CF9? What happens when you invoke it straight up (not through SoapUI, but as a http call in a browser)?
Also, I would strongly recommend against using "Local" as a variable name in a function - CF9 introduced some changes in how variables are scoped within a function and uses that as the name for that constrained scope.
Problem: When requesting the WSDL for a CFC, I get the following error: Variable FORM is undefined. It happens in this line of code, in the OnRequestStart method in application.cfc
<cfif structKeyExists(form,'resetappvars')>
<cfset OnApplicationStart() />
</cfif>
If I request a specific method, it works fine. I have considered using cfparam to create a default form struct if none exists, but that seems like an ugly hack and I worry it will actually create the form struct in the variables or this scope of the CFC. Maybe this is a legitimate bug as well?
Note: This only happens when I request the WSDL, if I invoke a method directly - the code executes as expected without problems.
Update: Application.cfc code sample - just add any CFC to your app and request it with ?wsdl to see the issue. This has been tested (and failed) on ColdFusion 7 and ColdFusion 8.
<cfcomponent output="false">
<cffunction name="OnApplicationStart" access="public" returntype="boolean" output="false" hint="Fires when the application is first created.">
<cfset application.dsn = "my_dsn" />
<cfreturn true />
</cffunction>
<cffunction name="OnRequestStart" access="public" returntype="boolean" output="false" hint="Fires at first part of page processing.">
<cfargument name="TargetPage" type="string" required="true" />
<cfif structKeyExists(form,'resetappvars')>
<cfset OnApplicationStart() />
</cfif>
<cfreturn true />
</cffunction>
</cfcomponent>
Maybe try adding a:
<cfif IsDefined("form")>...</cfif>
around the above code?
You could also cfparam the variable you're looking for then just change your logic a little (assuming resetAppVars is a boolean:
<cfparam name="form.resetAppVars" default="false" />
...
<cfif form.resetAppVars>
<cfset OnApplicationStart() />
</cfif>
Edit: I'm not sure if the above code could be considered a hack, but it seems pretty standard CF, to me.
This post of Ben Nadel gives detailed list of scopes available for different types of requests.
By reading it you can easily find out that form scope is not available in given context, but url is.
I've heard it's just a matter of opinion, but it seems to me that it is improper to reference your form scope within a CFC, as there is no guarantee that the form scope will be available when your cfc is invoked and when your method is called. It is better to ensure that any data that needs to be available to the method is provided explicitly to your object. This can be done either by including an argument:
<cfargument name="resetAppVars" type="boolean" required="false" default="false" />
Then you check arguments.resetAppVars, and it is always defined, but defaulted to false.
Or by creating an attribute on your object and creating an explicit set method:
(at the top of your cfc)
<cfset this.resetAppVars = false />
<cffunction name="setResetAppVars" access="public" returnType="void" output="false">
<cfargument name="flagValue" type="boolean" required="true" />
<cfset this.resetAppVars = arguments.flagValue />
</cffunction>
In which case you will check against this.resetAppVars. You can also scope this locally using <cfset var resetAppVars = false /> as the declaration, which makes it a private attribute of your object, and is probably proper, so code that invokes the object cannot improperly overwrite this variable with a non-boolean type. In that case, you would simply refer directly to resetAppvars in your test, instead of using this scope.
You could also do this:
<cfif NOT isSoapRequest()>...
and stick your remaining logic inside that chunk.