Category Filtering: 'coldbox'

Using remote functions with JQuery but you want to use XML pass the query paramters?

ColdBox, ColdFusion

Are you using remote functions with JQuery but you want to use XML pass the query parameters? If you aren't you should be.

Well, why in the heck would I suggest such a thing? It's because Steve had the brilliant idea to reduce execution plans on the database using this nifty trick. So if we combine frequently used GET type queries (AKA get stuff from tablename where blah) into a single query and use a parameter to tell the stored procedure what to return we can reduce plans and improve server performance. So wow cool idea, but umm I'm calling the model directly dude. Steve being a DBA says, "why can you just generate XML like you always do?". Well as most Coldboxers should know, "When you call a CFC from the URL like that, it isn't autowired.  This is because the CF engine just creates a CFC instance directly and WireBox doesn't have a way to intercept that."  (Thank you Brad)

What does this mean? My handy dandy tools like my XMLConverter and populateModel tools aren't available. Loving my framework the way I do... I think, oh hell, I'm not going to manually write my own special XML tool. I'm way too smart, well lazy, for that.

So Brad tell me ....

"ColdBox 4 does have a new feature though, where CFCs that extend the base proxy class will get autowired in the pseudo-constructor.  Otherwise, you'd have to do something like application.wirebox.autowire( this ) in the CFC.  Or, for that matter, application.wirebox.getInstance( 'foo' )."

Well I'm not at CB4 yet. So I guess I'll call the autowire my darn self.

 Here is an example. 

component extends="baseService"

{

application.wirebox.autowire( this );

remote query function test(numeric param1=0,numeric param2=0)

        {    

            LOCAL.xml = XMLConverter.structToXML(Arguments);

            writedump(LOCAL);

            abort;

        }

}    

Now being a lazy programmer, my hand dandy XMLConverter that can take a struct and make it XML autoMagically is injected in my base model (typing is hard work ya'll). Since this this model initializes wirebox and extends the base model I can use it. Yee Haw. Normally, I use populateModel to grab the form data and convert it a model that is a struct and then convert that to XML. But in this case as I pass stuff into the model it becomes part of the arguments struct so it already created my struct for me. Sweet! Just replace my dump with the usual stored procedure call and the DBA is happily processing XML.

Warning: Please don't be a dumb dumb and use this method for sensitive data. Use a handler so you can do things like an interceptor or a prehandler to check that the person asking for data is supposed to be getting the data. We only use this for frequent reference table type information. We NEVER use this to save data. 

Here's to being smart, um lazy. 

 

 


cfdocument java.io.IOException

ColdBox, ColdFusion

I started getting this issue when using CFDOCUMENT one day. 

cfdocument java.io.IOException: Parsing problem occurred during the rendering process of this document.

I typically use Coldbox as a framework so in this case I had a layout where I was CFDOCUMENT to do all my PDF "rendering". So the customer reported to me that the server has an issue creating PDFs. I tried everything only to learn the basically CFDOCUMENT if very picky when it comes to W3C validation. In my CFDOCUMENT, I had done a CFINCLUDE on my CSS. That CSS was the cause of my IOException problem.

<style type="text/css" rel="stylesheet">

        <cfinclude template="/includes/css/style.css"  >

</style>

I modified my CSS and the problem went away. So hopefully this saves you some time.

Validate your HTML:  http://validator.w3.org/
Validate your CSS:  http://jigsaw.w3.org/css-validator/


Elastic Email from a Bean using a template

ColdBox, ColdFusion

This is just like my query post except it's from a bean. For those that aren't familiar with a bean, I use Coldbox as my MVC framework of choice which can then populate the bean. I have a toStruct function in my base Bean that I use. I posted it here also. So the concept is from to Bean to struct and then loop over it to dynamically populate a template. So this combined with my previous function I've turned my entire email model into two dynamic functions sending pretty emails on the fly.

    public string function sendElasticEmailFromBean(myBean)
        {
            LOCAL.httpService = new http();
            LOCAL.httpService.setMethod("post");
            LOCAL.httpService.setCharset("utf-8");
            LOCAL.httpService.setUrl(THIS.SENDURL);
            LOCAL.httpService.addParam(type="formfield",name="username",value=THIS.USERNAME);
            LOCAL.httpService.addParam(type="formfield",name="api_key",value=THIS.API_KEY);
            LOCAL.httpService.addParam(type="formfield",name="from",value=THIS.FROM);
            LOCAL.httpService.addParam(type="formfield",name="from_name",value=THIS.FROM_NAME);
            LOCAL.httpService.addParam(type="formfield",name="to",value=ARGUMENTS.myBean.getTo());
            LOCAL.httpService.addParam(type="formfield",name="subject",value=ARGUMENTS.myBean.getSubject());
            if (ARGUMENTS.myBean.getTemplate() neq '')
            {
                LOCAL.httpService.addParam(type="formfield",name="template",value=ARGUMENTS.myBean.getTemplate());
                LOCAL.httpService.addParam(type="formfield",name="merge_body",value=ARGUMENTS.myBean.getBody());
            }    
            else
                LOCAL.httpService.addParam(type="formfield",name="body_html",value=ARGUMENTS.myBean.getBody());    
            if (ARGUMENTS.myBean.getMergeName() neq '')
                LOCAL.httpService.addParam(type="formfield",name="data_source",value=ARGUMENTS.myBean.getMergeName());
            
            LOCAL.columns=StructKeyArray(ARGUMENTS.myBean.toStruct());
            for (local.i=1; LOCAL.i LTE arraylen(LOCAL.columns); LOCAL.i=LOCAL.i+1)
            {
                LOCAL.temp=evaluate("ARGUMENTS.myBean.get"& LOCAL.columns[i]&"()");
                if( isDefined('LOCAL.temp'))
                    LOCAL.httpService.addParam(type="formfield",name="merge_#LOCAL.columns[i]#",value="#LOCAL.temp#");
            }
            LOCAL.result = LOCAL.httpService.send().getPrefix();
            return LOCAL.result.filecontent;
        }

    public struct function toStruct()
    {
        LOCAL.rtn = structNew();
        for(LOCAL.x=1; LOCAL.x lte ArrayLen(getMetaData(THIS).properties); LOCAL.x = LOCAL.x + 1)
        {
            if(isDefined(getMetaData(THIS).properties[LOCAL.x].name)) value = evaluate(getMetaData(THIS).properties[x].name);
            else LOCAL.value = "";
            
            structInsert(LOCAL.rtn, getMetaData(THIS).properties[LOCAL.x].name, value);
        }
        return LOCAL.rtn;
    }


writing a model in cfscript

ColdBox, ColdFusion

So I've been wanting to rewrite stored procedures from markup to cfscript. I've done it so I'm posting an example for other newbies out there in the world to see.

public query function testFunction(var1,var2)

{

sp = new storedproc();

sp.setDatasource(THIS.DSN);

sp.setProcedure("MyGroovySQLSproc");

sp.addParam(cfsqltype="cf_sql_integer", type="in",value=arguments.var1);

sp.addParam(cfsqltype="cf_sql_integer",type="in",value=arguments.var2);

sp.addProcResult(name="rs1",resultset=1);

result = sp.execute();

return result.GetProcResultSets(1).rs1;

}

That's it. I'm not sure what is the benefit. It seems that they could have made a shorter way of doing this. Maybe that's another post.

 


Migration to Coldbox 3.5 from 3.0: Using wirebox instead of the deprecated beanFactory

ColdBox, ColdFusion

So I want to migrate from coldbox 3.0 to 3.5 but I the beanFactory plugin was deprecated. I'm already using wirebox to do injection of models in my apps but I never got around to changing the beans. So here is an example I am trying.

Here is what I was doing before in my handler:

LOCAL.myBean = getPlugin("beanFactory").populateBean("model.myBean");

rc.formXML = CreateObject("component", "app.bin.utilityLib").formToXML(LOCAL.myBean.toStruct());

This is WAY TO UGLY for a fancy OO framework like Coldbox.

 

Here is what I am trying to do now. I created a new bean because I'm doing nothing but cfscript these days.

My bean:

component hint="I'm trying to be an example bean that sets default values."

{

property name="firstName" type="string" default="first"; //set a default value incase I'm not submitting a form just yet.

function getFirstName() { return THIS.firstName; } //a getter

function setFirstName(firstName) { THIS.firstName=arguments.firstname;} //a setter

}

My handler:

function groovyBeans(event,rc)

{

rc.test1=populateModel("testBean");

rc.test2=testBean.getFirstName();

event.setView("groovy"); //this view does nothing other than dump the RC.

}

In my wirebox:

map("testBean").to("model.testBean").asSingleton();

Now only problem is my default isn't getting set. It's telling me that THIS.firstName isn't defined. I can see that my bean is being created because I see in rc.test1 the bean object is there.