Wednesday, January 16, 2013

Search and Delete remote files via FTP

Its very easy to search and delete remote files via FTP.

Step 1: Start FileZilla and connect to FTP Server

Step 2: Select "Search Remote Files" from Server menu or Press F3 from keyboard.


This will open "Remote File Search" Window


Step 3:  In Search directory, type the directory path where you want to search. Please note search will be recursive. It means all sub directories will also be searched. Now, create the appropriate search conditions and hit Search button. FileZilla will start searching files and display any matching files in Results section.


Step 4: After searching is finished, select all files shown in Results section and right click. Click "Delete" option from context menu to delete all of them.



Tuesday, January 15, 2013

You have attempted to dereference a scalar variable of type class java.lang.String as a structure with members

If you are receiving an error that "You have attempted to dereference a scalar variable of type class java.lang.String as a structure with members." then make sure that your struct variable is structure everywhere.

An easy way to test your variable's datatype is that you put #IsStruct(VariableName)# in few places above and below the error line to check if your variable is consistently a structure. It is possible that you have re-declared your variable somewhere else.

Automatically Update cfdiv after every x seconds

One of my client asked me to provide him proof of concept that real-time auction website "swoopo.com" can be created in ColdFusion. The only real challenge in this project was real-time update of cfdiv after every x seconds.

For all those who don't know about cfdiv, here is the description from documentation.
Creates an HTML div tag or other HTML container tag and lets you use asynchronous form submission or a bind expression to dynamically control the tag contents.
Anyhow, to update cfdiv after every x seconds, you have to use Javascript. Here is the sample code.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
<script language="javascript" type="text/javascript">
function updatestats()
{
_cf_loadingtexthtml=""; // This will remove "Loading..." preloader
ColdFusion.navigate('emp.cfm','GetDataNow');
}
</script>
</head>
<body onload="window.setInterval('updatestats()',1000)">
<cfdiv id="GetDataNow" bind="url:emp.cfm" />
</body>
</html>

You can see in this code that we have created a function Javascript "updatestats" which uses ColdFusion.navigate to update GetDataNow (cfdiv id). And also note that we used window.setInterval in onload event of body tag. The setInterval() method calls a function / evaluates an expression at specified intervals (in milliseconds), in our example 1000 or 1 second.

Monday, January 14, 2013

Function to create HMAC-SHA1 encrypted string

<cffunction name="hmacEncrypt" returntype="binary" access="public" output="false">    
<cfargument name="signKey" type="string" required="true" />
<cfargument name="signMessage" type="string" required="true" />
<cfset var jMsg = JavaCast("string",arguments.signMessage).getBytes("ASCII") />
<cfset var jKey = JavaCast("string",arguments.signKey).getBytes("ASCII") />
<cfset var key = createObject("java","javax.crypto.spec.SecretKeySpec") />
<cfset var mac = createObject("java","javax.crypto.Mac") />
<cfset key = key.init(jKey,"HmacSHA1") />
<cfset mac = mac.getInstance(key.getAlgorithm()) />
<cfset mac.init(key) /> 
<cfset mac.update(jMsg) />
<cfreturn mac.doFinal() />
</cffunction>

Sunday, January 13, 2013

QueryString to Struct Converter

This function converts QueryString to Struct Data Type.
<cffunction name="QueryStringToStruct" output="false">

<cfargument name="QueryString" required="yes" type="string">

<cfset myStruct = StructNew()>

<cfloop list="#QueryString#" delimiters="&" index="i">

<cfset QueryStringParts = ListToArray(i, "=")>

<cfset structInsert(myStruct, Trim(QueryStringParts[1]),Trim(QueryStringParts[2]))>

</cfloop>

<cfreturn myStruct />

</cffunction>

Check version of ColdFusion

To check which version of ColdFusion you have, following code can be used. This code is highly helpful when you have limited access to Control Panel or your hosting company do not reveals the version details.
<cfscript>

versinfo = arraynew(1);

versinfo[1] = structnew();

versinfo[1].name = "the base version, with no updater";

versinfo[1].number = 48097;

versinfo[2] = structnew();

versinfo[2].name = "Updater 1";

versinfo[2].number = 52311;

versinfo[3] = structnew();

versinfo[3].name = "Updater 2";

versinfo[3].number = 55693;

versinfo[4] = structnew();

versinfo[4].name = "Updater 3";

versinfo[4].number = 58500;

curversion = listlast(Server.ColdFusion.ProductVersion);

</cfscript>

<cfoutput>

<p>This server is running <b>#Server.ColdFusion.ProductName#, #server.coldfusion.ProductLevel#</b> <br />

#Server.ColdFusion.ProductVersion#

<br/>

<cfif left(Server.ColdFusion.ProductVersion,5) is "6,0,0">

<p>Which means it?s running with

<cfif server.coldfusion.appserver is "j2ee" and curversion is 58096>

 Updater 3 on ColdFusion MX for J2EE.

<cfelse>

<cfloop from="1" to="#arraylen(versinfo)#" index="i">

<cfif curversion eq versinfo[i].number>

<b>#versinfo[i].name#</b>.

<cfbreak>

<cfelseif curversion lt versinfo[i].number>

<b>patches not yet up to the final release of

#versinfo[i].name#</b>

<cfbreak>

<cfelseif i is arraylen(versinfo)>

a version <b>greater than the final release of

#versinfo[arraylen(versinfo)].name#</b>.

This tool has not been updated yet to recognise that

version number.

</cfif>

</cfloop>

</cfif>

<cfelse>

</cfif>

</cfoutput> 

ColdFusion - cfdocument, pdf and html tables

cfdocument tag of ColdFusion 8 is a great tool to generate extremely good looking PDF files/reports. Yesterday, when I was working on a PDF Generation System built on ColdFusion, I just noticed that cfdocument do not understand style="border-collapse: collapse" style. Therefore, if you are using tables in your PDF, you will see a lots of spaces and thick borders all around your tables and cells.

I highly recommend to use tableless structure inside cfdocument to avoid such problems. But if is absoulte necessary for you to use tables, then here is a fix for you :-)

  • Make sure that values of attribute border, cellpadding and cellspacing is set to 0 in each table. e.g &lt;table cellspacing="0" border="0" cellspacing="0"&gt;
  • Add following style in your style sheet.
       td {
    margin-left:0;
    border-bottom:0;
    border-top:0;
    border-right:0;
    padding-left:0;
    }
Please also keep in mind that do not use &lt;hr/&gt; tag to generated colored horizontal line. Instead use colored image. And last but not the least, if your code inside cfdocument tag is XHTML validated, you will get perfect output.

Saturday, January 12, 2013

Downloading attachments with cfimap

<cfimap> is very easy to use but it can become a real pain if you are using ColdFusion at shared hosting, specially when downloading attachments. <cfimap> by default save attachments in temp folder (GetTempDirectory()) but on shared hosting, your host may not give you read/write access to that folder. In such situation, you can use "attachmentpath" attribute of cfimap to define path where cfimap should download the attachments. Unfortunately, this may also not work on shared hosting. Here is a workaround which I use to download attachments.

<!--- Creating a Temp Attachmetn Folder in Memory ---> 
        <cfset sfolder = "ram://attachments" />
        <cfif NOT DirectoryExists(#sfolder#) >
            <cfdirectory
                action="create"
                directory="#sfolder#"
            />       
        </cfif>
    <cfimap
        server = "IMAP SERVER"
        username = "MyUserName"        
        action = "open"
        secure="yes"
        password = "MyPassword"
        connection = "imapEmail"
        timeout="300" generateUniqueFilenames="Yes">   
   
    <cfimap action="GetAll" AttachmentPath ="#sfolder#" connection="imapEmail" name="AllEmails">    


    <cfoutput>
        <!--- Looping directory files --->
            <cfdirectory
                name="files"
                action="list"
                directory="#sfolder#"
            />
            <cfloop query="files">
                <cffile action="copy"
                      destination="C:\inetpub\wwwroot\mydomain.com\wwwroot\attachments"
                      nameconflict="MakeUnique"
                      source="#sfolder#/#files.name#">
                 #files.name# has been downloaded. <br/>    
                <cffile action="delete" file="#sfolder#/#files.name#" />
            </cfloop>
    </cfoutput>

    <cfimap action="close" connection = "imapEmail">

First, we create a folder "attachments" in Memory and then downloaded all attachment in that folder. Later, we loop through all the files in "attachments" directory and copy them to our destination folder. Simple!!

Wednesday, January 9, 2013

Invalid public shared ip address in platform server configuration for shared IP address usage

Yesterday, I was installing WebSitePanel (WSP) 2.x for a client. After successful installation, when I tried to create a website, WSP showed an error message and failed to create website. Error was "Invalid public shared ip address in platform server configuration for shared IP address usage". 


After a little search, I found this article:
http://www.websitepanel.net/making-the-required-changes-to-your-iis-service-global-dns-records-to-support-websitepanel-2-0/

However, when I checked settings of WSP, Public Shared IP addressed was already there.


Drilling the source code of WSP revealed that WebServerController.cs looks for a Service Property "PublicSharedIP". Looking at the ServiceProperties table in WSP database, I found that this properly "PublicSharedIP" does not exists!!

So, I executed following query to add "PublicSharedIP" property into database:
INSERT INTO ServiceProperties (ServiceID, PropertyName, PropertyValue) VALUES(2, ‘PublicSharedIP’, 1)

(1 is my Public IP, listed in IPAddresses table)

Problem Fixed!!