A day in the life of an audio visual junkie
28 Oct

I always try to keep the # of add-ons loaded on my Firefox at a minimum. In my many years of being in web development I have found that there are at least 3 essential add-ons that any serious web developer must have.
Snap Links - Opens multiple links contained in a selected area in new tabs. Get the Firefox 3 compatible version.
23 Oct
Lately this blog has been suffering from MySQL out of memory error messages which got worse as the days went by. Sometimes Is could not post stories, or my sidebar would not load. Other times I could not load the admin area, or my site went down entirely. After doing a bit of tracing and research I was shocked to discover that my wp_options table had almost 2,000 records in it. As I skimmed through the records I saw that majority of it had rss_ to it, which led me to research on Wordpress’ RSS caching mechanism.
So, I did some more digging until I came across lildude’s explanation of Wordpress’ autoload functionality, which defaults to yes, causing it to bloat the $GLOBALS variable with all the crap our lovely plugins dump into the wp_options table. Finally I came across jayrocas’ post on the Wordpress support forums on how his blog database had a bunch of entries whose option_name looked something like “rss_f07b6018d7bc77b2520b5ec4296f3e66_ts”. After reading the community’s response, I decided to delete all 1,325 rows that started with “rss_”. The query I used was:
DELETE FROM `wp_options` WHERE `option_name` LIKE “rss_%”
Like magic, my blog loaded without any more hiccups. Reloading the home page immediately after cleaning up the database results in 8 new “rss_” entries. I can only think of two RSS feeds that my homepage pulls from (Flickr and Last.FM) so I’m not sure where the other 6 is coming from. Looking at the database, it appears that there is a duplicate entry for Flickr and Last.FM, and there is 3 entries with the same option_name hash “rss_89613d9a050aad8af096de3c8dfa83bd_ts” and option_value of “1224690561″. I don’t know what’s causing the duplication, or what the bogus triplicate entry is. I have no intention of doing so. Right now, I’m content with a running blog. I’ll just do a database clean up every now whenever necessary.
I am still trying to see if the CommentLuv plugin had anything to do with bloating my wp_options table. There is a huge chance that it does, but I love this plugin so I will just try to upgrade it when I’m done with this post.
Finally, I also installed the Clean Options plugin, which searches for and removes orphaned entries in the wp_options table. Cool. But is there no select all / remove all option? I can’t imagine having to place a check on all 1.7k rss_ entries when it takes me less than a minute to login to PhpMyAdmin and execute that query I listed above. Will this plugin be of any use? I’ll just keep it installed - just in case.
3 Sep
Got this message when I logged into BaseCamp today. It appears that more and more businesses are now dropping support for antiquated browsers like IE6, which to me is a good sign and would pave the way to better internet standards.
Important Reminder: IE 6 Phase Out
In July we announced that we would be phasing out support for Internet Explorer 6 on August 15, 2008. To make the transition easier, we’ve extended that deadline to October 1, 2008. From now until October 1st, anyone using IE 6 to access Basecamp (or our other products) will receive a notice every 3 days letting them know they’ll need to upgrade their browser before October 1, 2008 in order to continue to use Basecamp. The notice will be displayed in the web browser and will include links to download a modern browser (IE 7, Firefox, or Safari). This notice will also be shown to your clients who use Basecamp. You may want to re-read the announcement so you are prepared for any questions they may have. If you have any questions please contact support. Thanks for your patience during the transition.
28 Aug
Had my hands full these past 2 months trying to fix SQL injected websites. It looks like this is the result of a recent string of attacks by Chinese hackers primarily exploiting websites running on ASP Classic with Microsoft SQL Server as the back-end database. Some of my sites had small amounts of data, which can be very easily cleaned up by hand. However, others can be quite huge and impossibly difficult for a brute force solution, that an automated script is necessary to fix the problem. After asking around one of my friends e-mailed me this. It gives no credit to the original source so if this is yours, please e-mail me so that I can give due credit.
Automatically clean up a database infected by SQL injection:
BEGIN
DECLARE @tblTable varchar(255), @colColumnName varchar(255), @Cmd NVARCHAR(4000)
DECLARE curSQLinjectionDataClean CURSOR FOR
SELECT a.name, b.name
FROM sysobjects a, syscolumns b
WHERE a.id = b.id AND a.xtype = ‘u’ AND
(b.xtype = 99 OR
b.xtype = 35 OR
b.xtype = 231 OR
b.xtype = 167)
OPEN curSQLinjectionDataClean
FETCH NEXT FROM curSQLinjectionDataClean INTO @tblTable, @colColumnName
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @Cmd = ‘UPDATE [’ + @tblTable + ‘] SET [’ + @colColumnName + ‘] = LEFT([’ + @colColumnName + ‘], LEN([’ + @colColumnName + ‘]) - 69)
WHERE [’+ @colColumnName + ‘] like ”%“></title><script src=”http://www3.800mg.cn/csrss/w.js”></script><!–”’
exec sp_executesql @Cmd
FETCH NEXT FROM curSQLinjectionDataClean INTO @tblTable, @colColumnName
END
CLOSE curSQLinjectionDataClean
DEALLOCATE curSQLinjectionDataClean
END
Replace “></title><script src=”http://www3.800mg.cn/csrss/w.js”></script><!– with the string that was injected. Note that this only clean records that are victims of SQL string injection.
To prevent future SQL injection:
BEGIN
DECLARE @tblInjectedTable TABLE (colTableName varchar(255))
DECLARE @tblInjectedColumn TABLE (colRecordID INT IDENTITY(1,1), colColumnName varchar(255))
DECLARE @tblTable varchar(255), @colColumnName varchar(255), @Cmd NVARCHAR(4000), @iCount SMALLINT, @iCountTo SMALLINT, @WhereCmd NVARCHAR(4000)
INSERT INTO @tblInjectedTable(colTableName)
SELECT DISTINCT a.name
FROM sysobjects a, syscolumns b
WHERE a.id = b.id AND a.xtype = ‘u’ AND b.length>99 AND
(b.xtype = 99 OR
b.xtype = 35 OR
b.xtype = 231 OR
b.xtype = 167)
DECLARE curSQLInjectedTable CURSOR FOR
SELECT colTableName
FROM @tblInjectedTable
OPEN curSQLInjectedTable
FETCH NEXT FROM curSQLInjectedTable INTO @tblTable
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @iCount = 2
INSERT INTO @tblInjectedColumn(colColumnName)
SELECT DISTINCT b.name
FROM sysobjects a, syscolumns b
WHERE a.id = b.id AND a.name = @tblTable AND a.xtype = ‘u’ AND b.length>99 AND
(b.xtype = 99 OR
b.xtype = 35 OR
b.xtype = 231 OR
b.xtype = 167)
SELECT @iCountTo = COUNT(*) FROM @tblInjectedColumn
SELECT @colColumnName = colColumnName FROM @tblInjectedColumn WHERE colRecordID = 1
SET @WhereCmd = ‘WHERE ins.[’ + @colColumnName + ‘] LIKE ”%<script%”’
WHILE @iCount <= @iCountTo
BEGIN
SELECT @colColumnName = colColumnName FROM @tblInjectedColumn WHERE colRecordID = @iCount
SET @WhereCmd = @WhereCmd + ‘OR ins.[’ + @colColumnName + ‘] LIKE ”%<script%”’
SET @iCount = @iCountTo + 1
END
SET @Cmd = ‘CREATE TRIGGER t’ + @tblTable + ‘ ON [’ + @tblTable + ‘] FOR INSERT, UPDATE AS
BEGIN DECLARE @iCount BIGINT SET @iCount = 0 SELECT @iCount = COUNT(*) FROM inserted ins ‘
+ @WhereCmd + ‘ IF @iCount > 0 ROLLBACK TRANSACTION END’
exec sp_executesql @Cmd
FETCH NEXT FROM curSQLInjectedTable INTO @tblTable
END
CLOSE curSQLInjectedTable
DEALLOCATE curSQLInjectedTable
END
This is all very easy to do. It took me less than two minutes to copy and paste the two code blocks above, make changes to the first one, and execute on MS SQL. Of course, I tested this first on a backup copy just in case. When trying out something unfamiliar for the first time, always make a backup copy!
Update (09/19/2008): attaching a downloadable version of the cleanup script. Get it here!
16 Jul

Just stumbled upon SoundManager 2, a JavaScript library that handles sound playback, something that has been missing in JavaScript, which leads developers to resort to Flash instead.
From the website:
SoundManager 2 is an attempt at providing the sound API which Javascript has been missing. It’s a Javascript library which wraps and extends Flash’s sound capabilities, bringing cross-platform audio functionality to Javascript.
The description basically states that SoundManager still uses Flash for playback, which is a bit heavy and still not a native solution, but a workaround is a workaround. Kudos to Scott Schiller on the awesome work!
4 Jun
Sometimes it can be really annoying for the user to open a PDF file in the same window, and sometimes you might find yourself working on an existing website, faced with the insurmountable task of making sure all PDF links open in a new window.
Just like today.
Forget about manual editing, it will only take too long.
Forget about search and replace, you might mess up the code.
JQuery to the rescue!
See my code below:
$("a[href*=.pdf]").click(function(){
window.open(this.href);
return false;
});
Alternatively, you can apply the target=”_self” attribute instead:
$("a[href*=.pdf]").click(function(){
$(this).attr({"target":"_self"});
return false;
});
Viola! With Just four lines of code, you now open all pdf links in a new window! Thanks to JQuery’s awesome element matching engine and attribute pattern recognition, you can actually modify the code to apply the same behavior to any link, as long as the text can be found anywhere within the href attribute.
Have fun! ![]()
10 May
It’s official. Expression Engine is the easiest CMS ever. For me, at least. I have just implemented Expression Engine to be the backend that will drive the CODESIGN Studios website in under a day. The power and simplicity of EE trumps all other CMS that I have dealt with in the past, and which includes the following:
7 May
So there I was wide awake at 2am due to the insane heat (or was it because the 1 1/2 cups of freshly brewed black Folger’s coffee that I had for dinner?) I was thinking of what to do when out of the blue I decided to work on the CODESIGN Studios website. It is long overdue for a redesign and I had been playing around with some ideas over the last few weeks but I could never seem to get satisfied. So what the heck, I thought. I’m going to come up with a simple, one-page layout and use it, or it will probably take me another decade before any redesign takes place. So I focused all my energies and this was the result:
Total hours: 4-6 (from ~2am to ~6am)
Home page design, HTML and CSS development, plus a minor color change in the logo (importing from Corel Draw -> Adobe Illustrator messed up with the original color profile, so I recolored the logo instead)
I need sleep. Badly. ![]()
10 Mar
I enjoyed making fun of IE8 in my latest article so I thought I’d share it with you guys
http://cssvault.com/blog/2008/03/10/internet-explorer-8-beta-released-fails-to-excite
Have fun ![]()
26 Feb
Last January I had an interesting discussion with Meryl Evans and Bill Moore on usability testing (direct link to part 1 and part 2). The gist of it is doing usability testing in a sandwich shop, and in the course of our discussion a couple of key advantages surfaced, mainly:
Below is a copy of the transcript:
(more…)