Friday, November 1, 2013

OpenBD, parsing BBCode, loops and a simple Regex solution

Lately I've been working on a bunch of AJAX applications, more or less chat-oriented, and they both needed variations of BBCode, so I started working on it.

My first iteration used a loop looking for the bbcode, counting the number of times and if it came up uneven with the ending bbcode it would add the closing code at the end of the text, all in all it was a very clunky way of doing things but it worked well.

The latest project however, I decided that there had to be a better way of doing it, so I started thinking about using regex, I came up with my own variant but it didn't work when you nest different bbcodes (I'm not very good with regex) but with some paid help on Fiverr I got the following regex and it works very nicely:


It's pretty simple, but works nicely, I haven't seen any other solution this straight forward out there so I figured I'd share this one.
The next problem was the url bbcode, now in this application we're only using [url][/url] because the link name will be same as the actual link, no way to hide a different link under a false name.
This is what we came up with:


The basic idea is that it works with or without the user writing out http:// and it supports variations such as https://, the original regex I came up with broke if the user only wrote www.link.com and the finished link was handled wrongly, making the browser look for a local page instead of the proper url.

So there you have it, nice and simple, feel free to use it.

Thursday, October 24, 2013

Adding a membership file-area with protected files

In this brief post I'll go over how to create a file-area for members-only, how to make files available for download while keeping them secure so that non-members can not download them, we're assuming that anyone who is logged in should have access to the files.

Assumptions: There are a few assumptions here, and that's just because this is not a thorough tutorial, but more aimed at helping out someone who's relatively new but has some experience.

The assumptions are that there is a datasource called 'fileDSN' which points to a database with a table called 'files' with the columns 'file_id' and 'name' in it, we assume the folder 'C:\SecureFiles' exists and contains the files you want to handle, and we assume that the folder is not under the webroot, and lastly we're assuming that there is a login function based on cflogin.

The code here is tested on OpenBD 2.0.2

Since this is a quick example rather than a full application tutorial I'll jump straight into the file-handling page.

We'll be using a database and two files, one for displaying files and links, and one for actually serving up the file.

We could have used cfdirectory to list what files are in the folder and then used a link with the filename, but that opens up a security hole, so instead we've put the filenames into a database table, all the information we need is the filename and the record ID, that way the only variable we take from the outside is the ID number for the record.

Create a file called filedisplay.cfm and paste the following code into it:



What we're doing is running a query to get a list of all the files we've added to the database.
We then create links for each file, using their ID and name, the that handles getting the file is described below.

Create a file called file.cfm and paste the following code into it:



This is a .CFM file, how can it handle downloads of other file types?
By using the cfheader and cfcontent tags to define the header and the content of the file presented to the browser.
Doing this, the file temporarily "becomes" the file we want to download instead of a usual .CFM file.

First we check if the user is logged in, because we decided earlier that you have to be logged in to get access to the files, and we check to make sure the url.id variable exists, if you're not logged in or the variable does not exist, the user is forwarded to index.cfm.

Then we run the query to get the file information, we use cfqueryparam to protect against some hack attempts, what this one does is make sure the url.id is a number, is at most 3 characters long (Which gives us up to 999 files to pull from the database), for a full description of how cfqueryparam works I point you to Adobes online documentation.

We then get into the actual file-handling, after running the query we check to see if it returns a single record which is what we want, if it doesn't we assume the file does not exist and output the text in the tag.

Next we set the folder to check in, which in this example is the C:\SecureFiles folder, we then run another cfif, this time to see if the file exists, and assuming it does we go on to set the fileInfo variable with information about the file which we'll use in a bit.

After that we set the mimeType variable and here we use the getPageContext tag which pulls information from an underlying JAVA function to get mime information about the file.

And then we set the header and content information by pulling it all together by outputting the various variables into the cfheader and cfcontent functions.

This is what transforms our .CFM file to whatever file it is we want to download, all these things are necessary for the browser to recognize what kind of file it's handling and what to do with it.

If it seems longwinded or complicated, it's not, just start playing with it and you'll get it.

So why are we doing this instead of creating a hidden folder somewhere and just link to the files?

Because security by obscurity is silly, it only takes one person to spread the link and anyone could download the file, doing it this way we can put in place various checks and balances, in this example we just make sure the user is logged in but it's easy to start adding other criteria or access levels.

I hope this short example is useful to someone, and remember I don't claim to present best coding practices or the best way to do anything, I'm just putting this out there as an example that might get someone going in the right direction :)

Tuesday, October 15, 2013

OpenBD, CFAjaxProxy, and HTML 4 Strict

I've been working on a site using the HTML 4 Strict doctype, and it's all good except for one issue.

I'm also using CFAjaxProxy, which inserts a dynamic JS link in the header, the problem is that in OpenBD 2.0.2 the code looks like this:

<script src="load.cfres?js=cfajaxproxy01.js"></script><script src="load.cfres?js=cfc48774055.js"></script>

In HTML 4 Strict, the script tag should have the type also set, which causes the validation to fail. Granted, this is not a big issue in any way, it just nagged me so I decided to solve it.

The solution is very simple, we'll use a combination of render() and replace() to generate the dynamic tag, and append the type.
Here's the line:
#Replace(Render('<cfajaxproxy cfc="test" jsclassname="jscfc">'), '">','" type="text/javascript">','ALL')#

Breaking it down, the first thing to run is the Render() code, which runs the tag and returns the output, creating our dynamic output, from that we get the above <script> block.
Then Replace() runs, where we look for "> and replace it with " type="text/javascript">

And finally, because we're doing doing this in CFML, it's all done on the server, before the page is rendered, so the client browser just receives a fully working, properly formatted script tag.

I haven't tried this with other things, but using render and replace we should be able to adjust just about any tag we need.

Wednesday, October 2, 2013

Australia Post API and CFML

Someone on Facebook mentioned needing to work with Australia Posts API for getting prices calculated, so I figured I'd have a go!
It took me about a half hour but my simple test works fine.
First you need to sign up for an account and an API key, you can't get the API key without an account, and you need your API key when talking to their API server.
The test code is very very simple:

Here we're calculating the cost for a domestic parcel, going from postcode 2128 to postcode 6000, the package has a length of 96cm, width of 8cm, height of 5cm and a weight of 1.5 kilos.
You will receive an XML response with lots of nice info such as the price, just do a cfdump if you want to take a look at the return.

You can find the full API doc here: http://auspost.com.au/devcentre/assets/pdfs/pac-pcs-technical-specification.pdf
Hopefully someone will have use for this simple example!

--Edit with update--

I've ran the following code on CF 9.0.2 and it runs just fine:

Pulling a specific query result

I'm building a custom forum for a Swedish website, and I'm writing the part where you've clicked a forum and it's not displaying the top-level posts in the forum, together with some information like when it was posted, how many replies there are and when the last reply was.

I've never needed to do this before, but I needed to pull the last record in the query, or specifically I needed to pull the date when it was posted.

After a bit I came up with this, maybe it'll help someone else needing to do something similar.

LSDateFormat is used because I've previously set SetLocale("Swedish").

Using counter.recordCount gives me the number of results in the query, so here I use it to grab the last record which is the same as the total number.

No rocket-surgery going on, but took me a second to figure out since I haven't needed to pull specific results before.

Thursday, September 19, 2013

Testing a code block...

Wednesday, September 18, 2013

FIRST!

So, uh, this is the first blog post.

I have no set plans for this blog, just ramblings about programming and whatever else pops into my head.

I'm a 28 year old ColdFusion programmer, been doing this for two-three years now, and I think I'm becoming pretty decent at it.

I run my own CFML server, create applications ranging from simple static sites to integrated e-commerce solutions with on-the-fly PDF creation and inventory tracking.

I love CFML, and specifically I love the OpenBlueDragon CFML engine (Which is what powers my server).

In fact, I like it so much I've started creating open source apps just for this engine, the first out being the Lindorm CMS (Currently in version 0.2), the reason for planning and creating these are pretty simple, it grew out of frustration.

You see, each CFML engine handles things slightly differently, in good ways and bad, the problem is that some applications (Like CMS engines) don't always work on all CFML engines.

OpenBD is notorious for this, and Railo (The other main free engine) gained more popularity which means things work in Railo but not OpenBD, it becomes a vicious cycle of course because the fewer apps created lessens developers will to work with the engine.

So I decided that instead of whining about the situation, I'm going to fix it, or at least work in that direction.

Lindorm CMS is my first open source project, you can find it on the RIA Forge website, and allthough it's not ready for prime time yet (it's just in version 0.2) it IS already powering a few of my own sites, and it has about 80 downloads.

From those 80 downloads I've only had one person complain, and it turns out he wasn't running the OpenBD engine anyway.

Other projects planned are an issue tracker, a blog and a chat (Almost ready for release!).

So, yeah, first post, yay.