sfLoader::loadHelpers is now Deprecated

As of Symfony 1.3, the loadHelpers() method in the sfLoader class is deprecated.

The sfLoader::loadHelpers() method is deprecated. Please use the same method from sfApplicationConfiguration.

Though it only took 3 minutes to find the proper way to call the sfApplicationConfiguration instance, I thought I’d post it here for others.

sfContext::getInstance()->getConfiguration()->loadHelpers('Template');

Fixing ‘Unsupported Protocal’ Errors When Installing PEAR and PECL Extensions

Soon after updating to PHP5.3 on my local computer I found that some legacy code I maintain which can not be updated currently no longer worked. After a bit of research1, I found the best solution for now was for me to downgrade back to the latest stable version of PHP 5.2, PHP 5.2.10. I needed to reinstall a few PEAR and PECL extensions which much of the code I maintain depends on.

[~] $ sudo pecl install memcache
pecl.php.net is using a unsupported protocal - This should never happen.
install failed

[~] $ sudo pear install Image_Color
pear.php.net is using a unsupported protocal - This should never happen.
install failed

I knew my PHP installs were done within /usr, so I found the PEAR .channels/ directories with

[~] $ cd /usr
[/usr] $ sudo find . -type d -name .channels
./lib/php/.channels
./share/pear/.channels

deleted them

[/usr] $ sudo find . -type d -name .channels -exec rm -rf {} \;

and then updated the channels

[/usr] $ sudo pear update-channels

Now installing extensions from PEAR and PECL is back to normal.


  1. http://www.pear-forum.org/topic2301.html 

Transferring a Live Site to a New Server Using cPanel/WHM and SSH

Using cPanel/WHM it is very easy to transfer an existing cPanel account between servers. Coordinating this with a client who manages DNS on their own can make things a bit tricky, especially when their MX records point to the same server for webmail service.

In order to guarantee no downtime on the site, typically I copy a cPanel account over to the new server including all site files and email in advance of notifying a client it is okay to change the DNS. I also tell the site at the newly located cPanel account to continue to read and write to the original database on the old server using the server’s IP address as the host. This gives the client the flexibility to change the DNS at a time convenient for them.

After the DNS Has Propagated to the New Server

Once the DNS has propagated to the new server, a bit of cleanup is required. Following the example above,

  1. The database from the original server (which now contains newer information than the copy existing on the new server’s copy of the database) must be copied, and the new cPanel account’s database references must once again be set to localhost.
  2. We must ensure that all deleted/added email on the original server which occured between the time the cPanel copy was performed and when the client changed their MX records must be reflected on the new server to ensure no loss of email or reappearance of previously deleted email.

To accomplish #1 above is simple. Via SSH on the new server run the following commands

mysqladmin drop your_database_name
# Now update your site to point to localhost instead of the original server's IP

Then, from the original server run the following commands

mysqldump -u your_cpanel_user -p your_database_name | ssh your_cpanel_user@the_new_server_ip mysql your_database_name

This will minimize downtime for your users1 while updating the site to read/write from the local copy of the database now containing the newest information.

Item #2 above is equally simple via rsync from the old server

 rsync -av --progress /home/your_cpanel_user/mail/ root@the_new_server_ip:/home/your_cpanel_user/mail

This command properly updates the new mail server’s mail folder for all users with the latest changes to their accounts prior to the MX record change.


  1. It goes without saying that this work should be done very late at night. 

Bash Shortcuts Using the Exclamation Point

The shell provides multiple shortcuts via the usage of the exclamation point when trying to execute recently performed commands. Err the Blog’s Bash Cheat Sheet provides the following tips and more.

If you need to run the most recently executed command again

!!

If the last command run requires super user privileges

sudo !!

Run the most recently executed command beginning with foo

!foo

Retrieve the last ‘word’ of the most recently executed command. In the example below, !$ would have the value my_database.

mysqldump -u root -p my_database
!$ # Will contain the value 'my_database'

Similar to the example above, this shortcut contains all ‘words’ except the first in the most recently run command. Using the same mysqldump command above, !* would have the value -u root -p my_database.

mysqldump -u root -p my_database
!* # Will contain the value '-u root -p my_database'

Note that the above commands can have :p appended, printing the commands or ‘words’ that the exclamation point replacement would use instead of running them as part of a new command in shell. The example below would print the most recently executed command beginning with foo

!foo:p

Making PROMPT_COMMAND More Informative

On Mac/Linux the shell’s command prompt is typically fairly uninformative, displaying only the top level of the current working directory path. If you are currently at /home/me/sites/mysite, the prompt might look something like

[mysite]$ ...

This isn’t as useful as it could be. LinDesk details multiple ways to make the command prompt more informative. Based on the information there I now have the following PROMPT_COMMAND set in my ~/.bash_profile.

PROMPT_COMMAND='DIR=`pwd|sed -e "s!$HOME!~!"`; if [ ${#DIR} -gt 30 ]; then CurDir=${DIR:0:12}...${DIR:${#DIR}-15}; else CurDir=$DIR; fi'
PS1="[\$CurDir] \$ "

This now makes the same directory path above for /home/me/sites/mysite look like this

[/home/me/s...ite/public_html] $

MooTools SuperSleight Implementation for IE .png Transparency Issue

Recently I had to slice converted a site mockup to XHMTL and CSS. Part of the implementation required that the width of the site be what I like to call “static-variable width”.

The width of the site is not dependent on the width of the browser as a fluid layout is, but a slider control is available to the user to grow or shrink the width of the site as they desire.

Due to the need for this flexibility and the heavy image work used for the background of many of the DOM elements, .png files with transparency needed to be used in many places.

Things really looked great, except of course in IE6.

There are many different “solutions” to this problem, all which revolve around the Internet Explorer AlphaImageLoader Filter. After a lot of research and testing of different implementations, I settled on the SuperSleight. I like this technique for a variety of reasons

I found that allinthehead has implemented a jQuery plugin. Since I’m personally more a fan of MooTools, I ported the plugin to MooTools, extending the native Element class.

Element.implement({
    superSleight: function(settings) {
        var settings = $H(settings);
        settings.extend({
            imgs: true,
            backgrounds: true,
            shim: '/_img/png_fix_blank.gif',
            apply_positioning: true
        });

            if (Browser.Engine.trident && Browser.Engine.version < 7 && Browser.Engine.version >= 4) {
                $(this).getElements('*').each(function(elem) {
                    // background pngs
                    if (settings.backgrounds && elem.getStyle('background-image').match(/\.png/i) !== null) {
                        var bg = elem.getStyle('background-image');
                        var src = bg.substring(5, bg.length - 2);
                        var mode = (elem.getStyle('background-repeat') == 'no-repeat' ? 'crop': 'scale');
                        var styles = {
                            'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='" + mode + "')",
                            'background-image': 'url(' + settings.shim + ')'
                        };
                        elem.setStyles(styles);
                    }

                    // image elements
                    if (settings.imgs && elem.match('img[src$=png]')) {
                        var elem_size = elem.getSize();
                        var styles = {
                            'width': elem_size.x + 'px',
                            'height': elem_size.y + 'px',
                            'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + elem.getProperty('src') + "', sizingMethod='scale')"
                        };
                        elem.setStyles(styles).setProperty('src', settings.shim);
                    }
                    // apply position to 'active' elements
                    if (settings.applyPositioning && ['a', 'input'].contains(elem.get('tag')) && elem.getStyle('position') === '') {
                        elem.setStyle('position', 'relative');
                    }
                });
            }
    }
});

Some Notes

  1. Make sure to change the path to your .gif file. This .gif file should be a transparent 1x1 px image. This is what the Alpha ImageLoader uses to fix the transparency issues with the .png files
  2. I’ll call this code stable since I haven’t personally had any issues with it yet. If you have any changes you’d like to recommend, post a comment or send me a message
  3. With the Alpha ImageLoader Filter for IE, there is no support for repeating backgrounds or background positioning. As a tip, on the site I used this code for, whenever I needed to mimic the top right CSS background-position property, I found increasing the width of these .png images by putting transparent pixels as padding in the left side of the image itself can correctly force the image into position for IE6 without breaking the layout in good browsers.

Fixing Crontab Permissions for Jailshell cPanel Users on CentOS 5 & cPanel/WHM 11.24 RELEASE

Using CentOS 5 on my VPS, I recently found that newly created cPanel accounts running cPanel/WHM 11.24 RELEASE seemed to have some trouble properly setting permissions to allow the jailshell cPanel users to access/manage their crontab.

Setting up cron jobs via cPanel’s web interface itself worked just fine, but when trying to manage a jailshell users crontab via shell, the permissions were not set up properly to allow for this.

As d4ly you can see I don’t have permission to view/edit the crontab for d4ly

d4ly@d4ly.com [~]# crontab -e
cron/d4ly: Permission denied

So as root I did the following

root@server [~]# chmod 4775 /usr/bin/crontab
root@server [~]# cd /var/spool/cron
root@server [/var/spool/cron]# chmod 0755 .
root@server [/var/spool/cron]# chown d4ly.d4ly. d4ly

root@server [/var/spool/cron]# ls -l
total 24
drwxr-xr-x 2 root root 4096 Feb 4 17:03 ./
drwxr-xr-x 13 root root 4096 Sep 9 09:51 ../
-rw------- 1 d4ly d4ly 37 Feb 4 14:54 d4ly
-rw------- 1 root root 1555 Jan 19 20:52 mailman
-rw------- 1 root root 32 Jan 11 16:42 munin
-rw------- 1 root root 485 Jan 26 13:17 root

Then I tested things out once more as d4ly

d4ly@d4ly.com [~]# crontab -e
MAILTO="d4ly"
0 0 * * * ping d4ly.com # This cron is for testing jailshell crontab editing

Aiding the SVN Commit Process

The source code for D4core is maintained in and SVN repository. I have found it helpful to create a .cleanup and .commit Bash script in the root directory of our framework’s repository.

.cleanup has the task of removing cached files, temporary files, and log files which are no longer relevant to the current development cycle. We also use it currently to reformat our XML configuration file with pretty whitespace using xmllint.

#!/bin/bash

echo "Cleaning D4core..."
rm -f D4core/Content/Cache/Smarty/*
rm -f D4core/Content/Compile/Smarty/*
rm -f D4core/Content/Cache/Minify/*
rm -f D4core/Config/Backup_*
rm -f D4core/Log/Error/*
rm -f D4core/Log/Logs/*

xmllint -format D4core/Config/Config.xml -output D4core/Config/Config.xml

echo 'Running `svn status`...'

svn status

echo "Cleaning D4core completed."

.commit (which calls .cleanup initially) is responsible for managing the commit process. This file is run only after all project files have been added/removed/moved within the working copy and we are ready to commit to SVN.

#!/bin/bash

./.cleanup

svn commit

echo "D4core SVN commit complete."

By running ./.cleanup before committing code to the repository it becomes a lot easier to ensure the status and location of all files within the working copy are correct. These simply scripts easily save me 5 minutes a day in shell.

Dumping the Number of Open Connection to Port 80 by IP Address

This displays the number of open connections to port 80 on a server, dumping the ip address/connection count pairs in ascending order.

netstat -anlp | grep :80 | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -n

This can be useful in combination with grep1 searches performed on

httpd fullstatus

to determine if a DOS attack is being performed on a server.

Sed One-Liners Reference

An incredibly useful quick-reference for one-line sed1 commands.

http://sed.sourceforge.net/sed1line.txt