Saturday, April 26, 2008

Immediate If

Visual Basic programmers have a function at their disposal called IIf(), which is an abbreviation for Immediate If.

Example

result = IIf(2 + 2 = 5, "Correct", "Wrong")

The iif() function is sometimes more convenient than a full-blown if...then...else... control structure. Oddly enough, the function does not exist in VBScript.

Our PHP programmer friends have a superior equivalent, the ternary operator.

Example

$result = (2 + 2 = 5) ? 'Correct' : 'Wrong';

Unfortunately we can't recreate the ternary operator in ASP, but we can recreate the iif() function.

ASP

  1. function IIf(expression, truecondition, falsecondition)
  2.     if isNull(expression) then
  3.         IIf = falseCondition
  4.     elseif cbool(expression) then
  5.         IIf = truecondition
  6.     else
  7.         IIf = falsecondition
  8.     end if
  9. end function

Saturday, April 19, 2008

Proper Case

Both ASP and PHP have handy functions for forcing characters in a string to be all uppercase or all lowercase, but what about proper case? Proper case is used for names of people, titles of songs or movies, etc. The first letter in each word is capitalized, and the other letters are lowercase.


PHP has a built-in function for this, but the usage is slightly different and the name of the function is inconsistent, so we're going to write a facade function.


PHP

  1. function strtoproper($someString)
  2. {
  3.     return ucwords(strtolower($someString));
  4. }

ASP doesn't have a function for this, though full-blown Visual Basic does. We're going to duplicate that functionality, and make a few improvements. Consider names like McDonald and O'Brien. An ordinary proper case function would not handle these properly. We're going to use a regular expression to find these situations and handle them appropriately.


ASP

  1. function PCase(someString)
  2.     dim position
  3.     dim space
  4.     dim result
  5.     dim regEx
  6.     position = 1
  7.     set regEx = new RegExp
  8.     regEx.Pattern = "^(Mc[A-Z]{1}[A-Za-z]|O\'[A-Z]{1}[A-Za-z]|Mac[A-Z]{1}[A-Za-z])"
  9.     ' Loop through the string checking for spaces.
  10.     do while InStr(position, someString, " ", 1) <> 0
  11.         ' Find the position of the next space.
  12.         space = InStr(position, someString, " ", 1)
  13.         ' Capitalize (and append to our output) the first character after the space which was handled by the previous run through the loop.
  14.         result = result & UCase(Mid(someString, position, 1))
  15.         ' Check for situations like McDonald or O'Brien.
  16.         if not regEx.Test(Mid(someString, position, space - position)) then
  17.             ' Lowercase (and append to our output) the rest of the string up to and including the current space.
  18.             result = result & LCase(Mid(someString, position + 1, space - position))
  19.         else
  20.             if Left(Mid(someString, position), 3) = "Mac" then
  21.                 ' Leave the next three characters intact.
  22.                 result = result & Mid(someString, position + 1, 3)
  23.                 ' Append the rest of the string.
  24.                 result = result & LCase(Mid(someString, position + 4, space - position + 4))
  25.             else
  26.                 ' Leave the next two characters intact.
  27.                 result = result & Mid(someString, position + 1, 2)
  28.                 ' Append the rest of the string.
  29.                 result = result & LCase(Mid(someString, position + 3, space - position + 3))
  30.             end if
  31.         end if
  32.         position = space + 1
  33.     loop
  34.     ' Capitalize the first character of the last word after the final space (or the only word if there were no spaces).
  35.     result = result & UCase(Mid(someString, position, 1))
  36.     ' Check for situations like McDonald or O'Brien.
  37.     if not regEx.Test(Mid(someString, position)) then
  38.         ' Lowercase (and append to our output) the rest of the string up to and including the current space.
  39.         result = result & LCase(Mid(someString, position + 1))
  40.     else
  41.         if Left(Mid(someString, position), 3) = "Mac" then
  42.             ' Leave the next three characters intact.
  43.             result = result & Mid(someString, position + 1, 3)
  44.             ' Append the rest of the string.
  45.             result = result & LCase(Mid(someString, position + 4))
  46.         else
  47.             ' Leave the next two characters intact.
  48.             result = result & Mid(someString, position + 1, 2)
  49.             ' Append the rest of the string.
  50.             result = result & LCase(Mid(someString, position + 3))
  51.         end if
  52.     end if
  53.     set regEx = Nothing
  54.     PCase = result
  55. end function

Saturday, April 12, 2008

Ordinal Numbers

This week we're going to write a function to turn a cardinal integer into an ordinal number (eg. 4 becomes 4th). This is mostly useful when generating a page to display to a visitor.


ASP

  1. function ordinal(ByVal cardinal)
  2.     cardinal = CStr(cardinal)
  3.     if Right(cardinal, 1) = "1" and Right(cardinal, 2) <> "11" then
  4.         ordinal = cardinal & "st"
  5.     elseif Right(cardinal, 1) = "2" and Right(cardinal, 2) <> "12" then
  6.         ordinal = cardinal & "nd"
  7.     elseif Right(cardinal, 1) = "3" and Right(cardinal, 2) <> "13" then
  8.         ordinal = cardinal & "rd"
  9.     else
  10.         ordinal = cardinal & "th"
  11.     end if
  12. end function

PHP

  1. function ordinal($cardinal)
  2. {
  3.     if (substr($cardinal, -1, 1) == 1 && substr($cardinal, -2, 2) != 11)
  4.     {
  5.         return ($cardinal . 'st');
  6.     }
  7.     elseif (substr($cardinal, -1, 1) == 2 && substr($cardinal, -2, 2) != 12)
  8.     {
  9.         return ($cardinal . 'nd');
  10.     }
  11.     elseif (substr($cardinal, -1, 1) == 3 && substr($cardinal, -2, 2) != 13)
  12.     {
  13.         return ($cardinal . 'rd');
  14.     }
  15.     else
  16.     {
  17.         return ($cardinal . 'th');
  18.     }
  19. }

Saturday, April 5, 2008

Force SSL

If your web site requires visitors to enter private information, like their credit card number, or even just a username and password, you're hopefully using SSL to secure the transmission. But providing SSL is not enough, because visitors can still access your site without SSL. When a visitor navigates to a page where they are entering private information, we want to enforce that their data is protected by SSL.


Our PHP programmer friends can do this via an htaccess file:


  1. RewriteEngine On
  2. RewriteCond %{HTTPS} off
  3. RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

But for those of us stuck using ASP, we don't have this luxury. We can achieve the same result with some code.


  1. sub forceSSL()
  2.     dim secureURL
  3.     if UCase(Request.ServerVariables("HTTPS")) = "OFF" then
  4.         secureURL = "https://" & Request.ServerVariables("SERVER_NAME") & Request.ServerVariables("HTTP_URL")
  5.         if Request.ServerVariables("QUERY_STRING") <> "" then
  6.             secureURL = secureURL & "?" & Request.ServerVariables("QUERY_STRING")
  7.         end if
  8.         Response.Redirect secureURL
  9.     end if
  10. end sub

There are some things here worth noting. In both the htaccess example and the ASP example, we are checking if HTTPS is off. Some people will instead check if traffic is coming from port 80, the standard HTTP port, or not coming from 443, the standard HTTPS port. Checking port numbers is not the best solution because the server administrator can set up HTTP and HTTPS to run on different ports. It's also worth noting that the above ASP example preserves QueryString variables, if any are being passed. Most other examples I've seen on the Internet ignore the QueryString variables, which leads to navigation problems.


With this subroutine in your arsenal, just call it at the top of any page you want to secure.