Preventing Form Spam in cf_sebForm

I use cf_sebForm for all of my contact forms. Form spam is a constant problem for those forms. So, I set up a generic way to do filtering in those forms and wrote both cf_sebForm and SpamFilter.cfc to follow the same guidelines.

[More]

Add SpamFilter.cfc to BlogCFC

BlogCFC does a good job of preventing spam, but I sometimes get comment spam that I think SpamFilter.cfc could prevent. I decided to see how easily I could implement it on BlogCFC.

It turns out that it is pretty easy. I had to add a few lines to Application.cfm and addcomment.cfm. The drawback here is that I will have to repeat this process when I upgrade BlogCFC, but it is pretty painless.

[More]

SpamFilter.cfc Goes Gold

I have been using SpamFilter.cfc to prevent form spam for nine months now with great success (and no user impact). Other than some new spam definitions (including one in this build), I haven't made any changes in a while - no bugs or problems to be fixed.

[More]

NoticeMgr Goes Gold

NoticeMgr allows you to set up dynamic, event driven email so that it can be edited by your users.

[More]

Schedule Until...

This week I have been working on a task that will send out several email messages many more than I want to send to the mailserver at one time. I need some way to send them out in batches until they are all done. My solution led to something that will handle anything that needs to repeat across large time spans until complete.

[More]

SpamFilter.cfc Beta 2

I just made an update to SpamFilter.cfc and I am releasing it as 1.0 Beta 2. This is a result of some spam that I have gotten on the contact form of my web site despite having SpamFilter.cfc working against that contact form. I really have to thank those spammers for helping me improve the product.

[More]

Prevent Form Spam with SpamFilter.cfc

I was told last week that a client's contact form has been getting a lot of spam - on the order of 30 a day. We had a simple spam prevention measure in place, but that clearly wasn't doing the job. It was time for something a little more sophisticated.

[More]

NoticeMgr 1.0 Beta

On most web sites, I typically allow my clients to edit the content on the pages of the site. I also generally have email messages sent out in response to certain events.

For example, I might have an email that tells a user that we have received their application. This is generally sent out by the component that handles processing the application (in my case, usually using Mailer.cfc).

Much like in the case of content on their site, the client will often want to change the content of the email. It isn't as easy to have them do this, however, as the component needs to be aware of the email message and having the component reference a primary key of data in a database seems like bad form (violating encapsulation - after all the key may be different on the dev database than the live one).

Still, changing the content of the email myself isn't challenging work and isn't the best use of my clients money. As such, I needed a better solution.

[More]

Searcher.cfc 1.0 Beta

When I first started developing public web sites, I noticed that I often needed the same functionality on several sites. It was fairly easy to package those up as programs that I could copy from site to site. What I discovered, however, was that each one required a bit of set up.

I didn't like that I had to create (or copy) the required tables and set up other prerequisites. At the time, I was using Fusebox 3, so I also had to create circuits. All told, it always took me more time that I wanted to set up a program - and that was boring work.

I decided that I wanted my programs to be somewhat self-installing. DataMgr was one step toward that vision (which you can see actualized to a large degree in CodeCop). Now I can use DataMgr to install the tables that I need.

Searcher.cfc expands on that vision by using the same principal for verity collections. It does use cfcollection, so if that isn't available to you it won't do much good.

With Searcher.cfc, you can use the indexPath or indexQuery methods to index a query. If the collection doesn't exist, Searcher.cfc will automatically create it for you.

Additionally, Searcher.cfc will keep track of searches performed on your site. 

In order to use Searcher.cfc, you must first initialize it with the init() method, which has the following arguments:

  • CollectionPath (required): The full file path of the folder in which you want Searcher.cfc to create collections.
  • DataMgr (required): An instantiated DataMgr component.
  • sendpage (required): The browser path to the page that will redirect the user to the results of their search (more on this later).
  • excludedirs (optional): a list of folders to exclude from search results.
  • excludefiles (optional): a list of files to exclude from search results.

Searcher.cfc uses two tables to track searches: srchSearches and srchSelections, which it creates via DataMgr.

The "sendpage" argument must be the browser path to a file with the following code (assuming you have Searcher.cfc instantiated into Application.Searcher):

<cfif isDefined("url.searchid") AND isDefined("url.to")>
  <cfset Application.Searcher.send(url.searchid,url.to)>
</cfif>

This is what allows Searcher.cfc to see what pages a users selects from a search.

In order to index a search against a file path, use the indexPath() method, with the following arguments:

  • CollectionName (required): The name of the collection that you are indexing.
  • Key (required): The full file path to the folder that you want to index.

 In order to index a recordset, use the indexQuery() method, with the following arguments:

  • CollectionName (required): The name of the collection that you are indexing.
  • query (required): The query you are indexing (pass in the actual recordset, not just the name of the query) .
  • Key (required): The name of the key field from the recordset.
  • Title (required): The name of the field holding the title you want to display in your search results.
  • Body (required): The name (or list of names) of the field(s) holding the content you want to search.
  • URLPath (optional): The URL Path of the page that will result from the search (just like in verity, this will have the value of the key appended to it).
  • Custom1 (optional): The field for a Custom1 value, if you want one.
  • Custom2 (optional): The field for a Custom2 value, if you want one.

If you are calling the indexing methods from within a CFC and want to make sure that they are indexed regularly, I would suggest using Scheduler.cfc.

In order to run a search and get back a recordset of results, use the run() method with the following arguments:

  • searchterm (required): The word for which the user is searching.
  • collections (optional): The collections to search (defaults to searching all collections that Searcher.cfc is aware of).

This will log the search and return a recordset of the results. If you want to run the same search again without logging the search (for subsequent pages of a search, for example), use the reRun() method with the following argument:

  • searchid (required): The id of search you want to rerun ("SearchID" will be a column in the query returned from run() and reRun().

If you want to get search data, just call the getSearchData() method with the following arguments:

  • startdate (optional): The date from which the report should start.
  • enddate (optional): The date at which the report should end.

To get details about the landing pages chosen for a search phrase, you the getLandingPages() method with the followig arguments: 

  • searchterm (required): The phrase for which you want details.
  • startdate (optional): The date from which the report should start.
  • enddate (optional): The date at which the report should end.

I have been using Searcher.cfc for a few years and I have found that it has made the creation and deployment for Verity searches relatively quick and easy.

Searcher.cfc is open source and free for any use.

FormSaver.cfc 1.0

I often need to create a multi-page form or load a form with old data. FormSaver helps with both by providing a generic way to save form data.

FormSaver is built to save the data for a form, not the data that a form might represent (which will hopefully make sense shortly).

FormSaver can save the data using either DataMgr or SessionMgr (which is basically a SessionFacade). Just pass in the one you want to use to the init() method of FormSaver (with an argument name of "DataMgr" or "SessionMgr" respectively).

In order to save a form's data, use the store() method with the following arguments:

  • formdata: The Form structure itself (so, theoretically, FormSaver could save any simple structure)
  • formname: A name by which to reference this form (used for retrieving the value later)
  • usertoken: Any string to identify the user (required only if using DataMgr)

 In order to get back the saved structure, use the retrieve() method with the following arguments:

  • formname: The name to reference the form you want to retrieve (from the argument of the same name above)
  • usertoken: A string to identify the user (again, required only if using DataMgr)

You can also delete a stored form using the delete method with the following arguments: 

  • formname: The name to reference the form you want to retrieve (from the argument of the same name above)
  • usertoken: A string to identify the user (again, required only if using DataMgr)

When using DataMgr, FormSaver saves data to a table that it creates (via DataMgr). The name of this table is set via the "tablename" argument of the init() method (it defaults to "frmSaveds").

FormSaver is a very simple component that can help you temporarily store form values. This can be helpful for multi-page forms, especially if you want a user to be able to return to a form where they left off in a previous visit.

FormSaver is open source and free for any use. 

 

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.