Category Archives: Uncategorized


We recently selected PDG Commerce as the solution for one of our customers. However, this client had a number of requirements that fell outside of the scope of PDG’s offering. Some of the additions we needed to make were located in the administration portion of the website where a lot of the code is compiled in a CGI making direct alterations and additions nearly impossible.

In what will surely be series of articles on the subject of PDG Commerce, I’m first going to tackle an automatic email generator for notifying customers that their membership category has been elevated by the site administrator. Since we aren’t able to simply modify the customer admin page directly, we will have to rely on a function of MySQL called a trigger. A trigger as defined by is “… a named database object that is associated with a table, and that activates when a particular event occurs for the table.” In this case the event that we are interested in is when customer’s category is changed from “Anonymous” to “Reseller”. Before we go any further, let’s enjoy a fresh piece of bubblegum. Mmmm. We should be done with this before the flavor’s gone! Let’s go!

The first thing we’ll want to do is create a new table in our PDG database for the trigger to update.

`email_customer_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`CU_CustomerID` int(11) NOT NULL,
`emailed` int(1) NOT NULL DEFAULT ‘0’,
PRIMARY KEY (`email_customer_id`)

The new table is just going to consist of an auto incrementing id, the CU_CustomerID as taken from the CUSTOMERS table, and the column ’emailed’ that defaults to zero. We’ll be using that to ensure that the user only receives one email.

Now let’s create our trigger… If you’re using phpMyAdmin, choose the SQL tab and paste the following in the form.

Note: Be sure to change your delimiter to something that’s not a semicolon (like $$ for instance.)

Note: MySQL triggers require Superuser privileges.

IF (new.CU_CustCatID=2 AND old.CU_CustCatID=1) THEN
SET send_email = 1;
send_email = 1 THEN
INSERT INTO EMAIL_CUSTOMERS (CU_CustomerID, emailed) VALUES (new.CU_CustomerID, 0);

In a trigger you can use OLD.col_name to refer to the columns of a row before they were updated and NEW.col_name to refer to the columns of the row after they were updated. That’s what’s going on in the 5th line. We’re just looking to see if the CU_CustCatID was changed by the admin from “Anonymous”(1) to “Reseller”(2). If so, we set our variable ‘send_mail’ to ‘1’. We then insert into our EMAIL_CUSTOMERS table the CU_CustomerID from CUSTOMERS.


You can check out your new trigger by issuing the command SHOW TRIGGERS;.
If you need to drop a trigger simply issue this command DROP TRIGGER triggername;

Try changing the status of a user from “Anonymous” to “Reseller” in your Administration page of PDG to test it out. You can then check your EMAIL_CUSTOMER table. If all went well you should see a new row with the CU_CustomerID data is there for that user onlinecasinogo. You’ll also notice the emailedcolumn is set to 0 so we have something to check whether or not to email that customer.

Next we’re going create a new PHP file using the code below. Since we are going to be eventually running this PHP file in cron, take notice of line one. Without it, the cron won’t know what type of file this is.

#!/usr/bin/php -q
// functions for opening and closing the database…
function dbopen() {
	global $dblink;
	$dbhost = "localhost";
	$dbname = "pdgdatabasename";
	$dbuser = "databaseuser";
	$dbpass = "databasepass";
	$dblink = mysql_connect($dbhost, $dbuser, $dbpass) or die("Database Unavailable");
	mysql_select_db($dbname, $dblink);
function dbclose() {
	global $dblink;

// this query will save a few steps by selecting only the customers that are in our EMAIL_CUSTOMERS table that haven't been emailed
or die(mysql_error());

while($what = mysql_fetch_array($result))
		// Mail Variables
		$subject = 'Account Upgrade';
		// User Message
		$message = '<h2>Congratulations and Welcome</h2>';
		$message .= '

Your membership application has been approved and your account status has been elevated to Reseller.

		// Here we'll can even send the users login information.
		$message .= '

TIP: Remember to login at Your User Name is: ‘ . $CU_UserName . ‘ and your password is: ‘ . $CU_Password . ‘

		// User Headers
		// To send HTML mail, the Content-type header must be set
		$headers  = 'MIME-Version: 1.0' . "\r\n";
		$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
		$headers .= 'From: Your Website Name <>' . "\r\n";
		// Send email to Customer
		$cust = mail($CU_Email, $subject, $message, $headers);
		// Display Message
			if ($cust)
				echo 'sent';
				echo 'failed';
		mysql_query("UPDATE EMAIL_CUSTOMERS SET emailed=1 WHERE CU_CustomerID='$CU_CustomerID'")
		or die(mysql_Error());

The final step will be to save our php file and have a systems administrator add it to the crontab to run every 5 minutes or so depending on your preference. (It would probably good be a good practice to move this file above the web directory for security reasons.) Now when the Administrator of the site changes the category of a customer to “Reseller”, that customer will be emailed within 5 minutes of the update. I should also point out that if a customers category is changed back to “Anonymous” and then back again to “Reseller”, the email will be re-sent as our trigger will pick it up with the logic we are using.

There are probably a number of ways to achieve this same functionality. If you have any tweaks to share or if this was in any way a help to you, we’d love to hear about it in the comments below! Oh, and you can get rid of that gum now if you’d like!


The problem isn’t selling a customer on the concept of having their site built in a Content Management System (CMS.) Most customers want, and even demand control over their site’s content. Surprisingly, the problem isn’t really the limitations of today’s CMS’s either. In this post Web 2.0 era, we can pull off some amazing stuff in a web browser. No, what it comes down to is supporting and educating the client on utilizing the tools that you are selling them.


Whether you wrote your own in-house CMS or you are implementing another solution such as Drupal, Joomla, or WordPress, you undoubtedly know it forwards and backwards. However, no matter how simple and elegant the system is, chances are, this is the first time your client has ever seen it and it’s foreign. In addition, the very concept of websites online casinos, links, pages, forms etc are pretty vague for most people. The very fact that changes are made to their website from another website is a layer of abstraction that can be really confusing to most people.

It sounds simple, but you need to have a plan for clearly explaining the concept of web based administration.

As Yoda said in the Empire Strikes Back, “You must unlearn what you have learned.”

Try to imagine never seeing a CMS before and try to explain it to yourself. Take it a step further and find a family member or friend who is not in the industry. Setup a trial site for them using your favorite CMS. What questions do they have. Do they understand where and how to login. Do they understand how make changes to text, add pictures, or bold some text? For a lot of us, we think of bug testing as something that only pertains to programming, but I say that this concept should be applied to even pre-packaged software packages that are sold to a customer, but I digress. Getting honest feedback from your “test subject” can be invaluable to your future projects. You might find sharp edges in your CMS that need refined in the system, or at very least, you can find the areas where you will need to prepare extra help for your client in cases where systems and processes cannot be changed.


One point of frustration I’ve run into is when a customer wants to use the CMS tools to perform design changes that go against the design structure (or template) of a website. For instance, you might have dictated in the CSS that all the paragraph tags be left justified with a .9em size in an Arial, sans-serif font, but when the customer goes to edit a page, they expect to not only be able to change the copy, they also want to center align the text, enlarge it by 200% and maybe change the color to “burnt orange”. Now this might be a reasonable request from the customer but when you implemented the CMS, you left those controls out so the customer could not stray from the original design of the site. Both you and client have expectations, but unfortunately, they conflict. Either you are going to be deflated by the destruction of your perfect markup and design, or the customer is going to feel cheated on the promise of content control.

Get these kind of discussions out of the way before development begins. A lot of times concessions can be made to make both parties happy. If there are limitations to your CMS, highlight them upfront. Don’t make the mistake of saying, “this functions just like Microsoft Word.” I hear this a lot and it really is a stretch which will come back to bite you.

Okay, so you might be thinking, “I hear you, but how do I better support and educate the client?” There were times where I would think ahead and quote a few extra hours into the project where I’d offer support in the form of a meeting with a client when the site was ready to go live. I’d sit down and give a whirlwind tour of the site administration while the customer hopefully wrote notes down as I went along. Unfortunately, this is an overwhelming amount of information for a mere mortal to absorb in an hour. Here are two solutions that our team has implemented that have been a tremendous assets to both us and our customers:


Build a wiki site for your CMS. If you write your own CMS this really should be a no-brainer. From logging into the CMS to modifying forms, each feature should be documented. In addition to a clean index of each feature of the system, a thorough FAQ will go a long way in helping your customer get through the basics. You will be answering these questions repeatedly anyways, you might as well take the extra time to type it in once and save yourself time and at the same time empowering your customer with information.


Have a system that’s a little complicated? Drupal is a good example of a powerful and flexible CMS that lacks in the ease of use category when it comes to end user experience. Remember your customers don’t generally make changes every day to their site. They have their real jobs and remembering 5 menu levels deep to make a change is a lot to expect. Writing out the instructions is even a bit cumbersome. Try using a program like Jing to record a session where you make the changes with an accompanying voice-over. A picture is worth a thousand words but a movie with auditory explanation is even better. Doing this for some of the more complicated processes will go a long way on cutting down on your support time and will give great peace of mind to your client. Create a repository of these movies on youtube or screencasts.comfor example for all your clients to access at anytime. Depending on your client load, you might need to pay for a service to maintain space and lift bandwidth restrictions. If this is the case, the time you’ll save supporting your clients this way will make up for the cost.

By investing time into building the resources to educate your client, the more likely they will continue to use your products and services because they understand what they are paying for and you’ve established a personal connection that builds trust. The end result is a portfolio full of satisfied customers.


To pull this off, it doesn’t matter which platform you are running. Isn’t that beautiful? All you need is an SSH and a VNC client. If you’re on a Mac with Leopard or greater, you should be all set to begin. Simply launch terminal (Putty or whatever client you have) and let’s make our connection to our long distance Mac:

To do this from terminal enter the following:

ssh username@ipaddress_of_remote_mac

Enter the password for the user and press [Return].

Next we need to get into the correct directory for our change:

cd /Library/Preferences

Press [Return] then type the following:

echo -n enable >

After pressing [Return] this will enable Screen Sharing.

If you’re on a Mac, switch to the ‘Finder’, select the ‘Go’ menu and choose ‘Connect to Server’. Enter the following:


Enter your Username and Password and Bob’s your uncle.

If you’re on a PC or Linux machine, skip the ‘Finder’ step and fire up your favorite VNC client and enter the same address and user credentials.


QSvn is an excellent GUI Subversion client that runs on Linux, UNIX, Mac OS X, and Windows. Unlike a lot of other free options, QSvn is a real client and not a GUI wrapper for the command line. However, getting it to compile in Mac OS X 10.5.8 was a bit problematic. I thought I’d post the process in case anyone else needs assistance.


The current release of QSvn requires SVN 1.6.x. This is where OS X Leopard (10.5.8 or less) runs in problems when compiling. Leopard shipped with SVN 1.4.4. Even if you’ve done all your system updates, this version apparently does not get updated. To remedy this, you’ll want to pull down the Universal binaries from and install them. This updated version will install the SVN application file in /opt/subversion/bin. In contrast, the old 1.4.4 version resides in /usr/bin. (By the way, Snow Leopard ships with SVN 1.6.5 and should be fine for compiling QSvn though I haven’t test this yet.)

You’ll want to verify that your install went correctly. To do this, open up Terminal (>Applications->Utilities->Terminal>) and type the command below:

bash-3.2$ svn –version

Press “return” and you should see something like the following output:

svn, version 1.6.6 (r40053)
compiled Oct 22 2009, 14:13:09

Copyright (C) 2000-2009 CollabNet.
Subversion is open source software, see
This product includes software developed by CollabNet (http://www.Collab.Net/).

Now that we have the correct version of Subversion installed, we need to add it to our path so it can be called from any directory and thus look to the correct library for compiling the application. To do this, ‘cd’ into your home directory:

bash-3.2$ cd ~

Next we are going to create a new file. (If this opens an existing file, that is okay. Just append this next step at the bottom.)

bash-3.2$ nano .bash_profile

Add this line:

bash-3.2$ export PATH=/opt/subversion/bin/:$PATH

ctrl+x and press ‘y‘ to save and exit. Then execute the following command to load our bash_profile:

bash-3.2$ . .bash_profile

Download the latest build of QSvn here if you haven’t already done so. You’ll want the tar.gz file.

From the directory where you saved the QSvn binaries execute the command below to extract it (or extract it from Finder.)

bash-3.2$ tar zxfv qsvn-0.8.3-tar.gz

Next, change directories in you newly created qsvn-0.8.3 folder.

bash-3.2$ cd qsvn-0.8.3

Now create a new directory called “build” and change into that directory.

bash-3.2$ mkdir build
bash-3.2$ cd build/

You’ll want to either modify the script file ../scripts or simply run the following from within the build folder. This differs from the file located in the scripts folder in that it specifically points to the Subversion install path /opt/subversion instead of default /usr/bin

bash-3.2$ cmake -G “Unix Makefiles” -D CMAKE_BUILD_TYPE=”Release” -D SUBVERSION_INSTALL_PATH=”/opt/subversion/” /full_path_to/qsvn-0.8.3/src/

If you didn’t receive any errors, you should be ready to compile. Enter the following and you’ll be prompted for your administrator (root) password:

bash-3.2$ sudo make install

Enter your password when prompted:


If all goes well you should end up seeing something like below.

Scanning dependencies of target svnqt … [100%] Built target simpletest2 Install the project… — Install configuration: “Release” — Installing: /usr/local/bin/qsvn — Installing: /usr/local/lib/libsvnqt.6.0.0.dylib …

Now that it’s compiled and installed it’s time to test it out.

bash-3.2$ qsvn &

Thanks to Andreas Richter for developing this great application and for his assistance. Also thanks to Dale Blount for his assistance as well.


One of the most common issues I’m asked about is how to keep elements that float to stay within the confines of their container. See the example below followed by the code:

.container {
border:3px solid red;

.container img {

We basically have a div with a gray background color and a border. Within that div lie 2 child elements; a paragraph of text and an image floated to the left of the text. Now if there were more text, the border of the div would push down, essentially hiding our problem. What is happening is that the parent div is ignoring the height of the floated element (in this case, a Quake Live logo.) Now there are a few ways that we can address this:

  • The first would be to set a static height on the div. This can work well if you know how tall your content will be. Unfortunately, if this div contains dynamic content, we might not know how much content will be there at any given time.
  • The second option would be to add an additional div before the closing of the container div that has the clear:both attribute. This is a viable fix but when you get into multiple column layouts it can be problematic without the use of javascript. In addition, we want to use as few div‘s as possible in our layout as to keep the page light and organized.

So the answer to this question is actually pretty simple as you can see in the below code: (additions are in bold.)

.container {
border:3px solid red;

.container img {

Notice that the logo is now neatly tucked inside the container div. See below:

By simply using overflow (this property specifies what happens if content overflows an element’s box., we are making the div aware of everything within it. We could use overflow:hidden or overflow:scroll but hiddenhas the potential of cutting off from view anything that might spill out of the div(though in this example it would work fine.) and overflow:scroll would add scroll bars around our div like an iframe and that is not our desire in this case.

Now there is just one thing we need to do to make this work in older versions of IE and Opera. That is to give the container div a width. It doesn’t matter if it’s static or a percentage. This should not be a restriction for any design thankfully. The final code is below:

.container {
border:3px solid red;
width:500px; }

.container img {

I Hope you find this tip useful in some way. Feel free to leave me any questions or comments!