Overriding Controllers and Actions in Magento

in etc/config.xml of My_Checkout module is like below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<global>
  <routers>
    <checkout> <!-- Mage_Checkout module -->
      <rewrite>
        <cart> <!-- CartController -->
          <to>mycheckout/mycart</to> <!-- My_Checkout module, MycartController -->
          <override_actions>true</override_actions>
          <actions>
            <add> <!-- addAction -->
              <to>mycheckout/mycart/myadd<to> <!-- My_Checkout/MycartController/myaddAction -->
            </add>
          </actions>
        </cart>
      </rewrite>
    </checkout>
  </routers>
</global>
  1. When an checkout/cart/add action is going to be dispatched, first it is passed through rewrite process.
  2. Rewrite process tries to find global/routers/checkout/rewrite/cart node is found in configuration, where checkout is front name of Mage_Checkout module and cart indicates Mage_Checkout_CartController.
  3. If this node is not found, rewrite process is not be continued and returned to dispatch process. So the action is executed normally. Otherwise, rewrite process is continued.
  4. Now, under this node, it tries to find whether override_actions node is true or false. By default value of override_actions is true. So if it is not added in configuration, it is considered as true.
  5. If override_actions is true, it overrides all actions of Mage_Checkout_CartController with same actions of My_Checkout_MycartController as defined by to node value mycheckout/mycart. For example, if we have defined addAction and indexAction methods inside My_Checkout_MycartController, then it automatically overrides both addAction and indexAction of Mage_Checkout_CartController. In short using to node and override_actions node we can override whole controller instead of individual actions.
  6. If actions/add node is defined where, add indicates addAction of Mage_Checkout_CartController, then override_actions node value is not considered and overrides action by value of actions/add/to node which is mycheckout/mycart/myadd i.e. My_Checkout module, My_Checkout_Mycontroller and myaddAction. So we can also override individual actions by this type of configuration

HowTo: Backup MySQL Databases, Web server Files to a FTP Server Automatically

his is a simple backup solution for people who run their own web server and MySQL database server on a dedicated or VPS server. Most dedicated hosting provider provides backup service using NAS or FTP servers. These service providers will hook you to their redundant centralized storage array over private VLAN. Since, I manage couple of boxes, here is my own automated solution. If you just want a shell script, go here (you just need to provided appropriate input and it will generate FTP backup script for you on fly, you can also grab my php script generator code).

Making Incremental Backups With tar

You can make tape backups. However, sometime tape is not an option. GNU tar allows you to make incremental backups with -g option. In this example, tar command will make incremental backup of /var/www/html, /home, and /etc directories, run:
# tar -g /var/log/tar-incremental.log -zcvf /backup/today.tar.gz /var/www/html /home /etc

Where,

  • -g: Create/list/extract new GNU-format incremental backup and store information to /var/log/tar-incremental.log file.

Making MySQL Databases Backup

mysqldump is a client program for dumping or backing up mysql databases, tables and data. For example, the following command displays the list of databases:
$ mysql -u root -h localhost -p -Bse 'show databases'

Output:

Enter password:
brutelog
cake
faqs
mysql
phpads
snews
test
tmp
van
wp

Next, you can backup each database with the mysqldump command:
$ mysqldump -u root -h localhost -pmypassword faqs | gzip -9 > faqs-db.sql.gz

Creating A Simple Backup System For Your Installation

The main advantage of using FTP or NAS backup is a protection from data loss. You can use various protocols to backup data:

  1. FTP
  2. SSH
  3. RSYNC
  4. Other Commercial solutions

However, I am going to write about FTP backup solution here. The idea is as follows:

  • Make a full backup every Sunday night i.e. backup everything every Sunday
  • Next backup only those files that has been modified since the full backup (incremental backup).
  • This is a seven-day backup cycle.

Our Sample Setup

   Your-server     ===>       ftp/nas server
IP:202.54.1.10   ===>       208.111.2.5

Let us assume that your ftp login details are as follows:

  • FTP server IP: 208.111.2.5
  • FTP Username: nixcraft
  • FTP Password: somepassword
  • FTP Directory: /home/nixcraft (or /)

You store all data as follows:
=> /home/nixcraft/full/mm-dd-yy/files – Full backup
=> /home/nixcraft/incremental/mm-dd-yy/files – Incremental backup

Automating Backup With tar

Now, you know how to backup files and mysql databases using the tar and mysqldump commands. It is time to write a shell script that will automate entire procedure:

  1. First, our script will collect all data from both MySQL database server and file system into a temporary directory called /backup using a tar command.
  2. Next, script will login to your ftp server and create a directory structure as discussed above.
  3. Script will dump all files from /backup to the ftp server.
  4. Script will remove temporary backup from /backup directory.
  5. Script will send you an email notification if ftp backups failed due to any reason.

You must have the following commands installed (use yum or apt-get package manager to install ftp client called ncftp):

  • ncftp ftp client
  • mysqldump command
  • GNU tar command

Here is the sample script:

#!/bin/sh
# System + MySQL backup script
# Full backup day - Sun (rest of the day do incremental backup)
# Copyright (c) 2005-2006 nixCraft <http://www.cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# Automatically generated by http://bash.cyberciti.biz/backup/wizard-ftp-script.php
# ---------------------------------------------------------------------
### System Setup ###
DIRS="/home /etc /var/www"
BACKUP=/tmp/backup.$$
NOW=$(date +"%d-%m-%Y")
INCFILE="/root/tar-inc-backup.dat"
DAY=$(date +"%a")
FULLBACKUP="Sun"
### MySQL Setup ###
MUSER="admin"
MPASS="mysqladminpassword"
MHOST="localhost"
MYSQL="$(which mysql)"
MYSQLDUMP="$(which mysqldump)"
GZIP="$(which gzip)"
### FTP server Setup ###
FTPD="/home/vivek/incremental"
FTPU="vivek"
FTPP="ftppassword"
FTPS="208.111.11.2"
NCFTP="$(which ncftpput)"
### Other stuff ###
EMAILID="admin@theos.in"
### Start Backup for file system ###
[ ! -d $BACKUP ] && mkdir -p $BACKUP || :
### See if we want to make a full backup ###
if [ "$DAY" == "$FULLBACKUP" ]; then
  FTPD="/home/vivek/full"
  FILE="fs-full-$NOW.tar.gz"
  tar -zcvf $BACKUP/$FILE $DIRS
else
  i=$(date +"%Hh%Mm%Ss")
  FILE="fs-i-$NOW-$i.tar.gz"
  tar -g $INCFILE -zcvf $BACKUP/$FILE $DIRS
fi
### Start MySQL Backup ###
# Get all databases name
DBS="$($MYSQL -u $MUSER -h $MHOST -p$MPASS -Bse 'show databases')"
for db in $DBS
do
 FILE=$BACKUP/mysql-$db.$NOW-$(date +"%T").gz
 $MYSQLDUMP -u $MUSER -h $MHOST -p$MPASS $db | $GZIP -9 > $FILE
done
### Dump backup using FTP ###
#Start FTP backup using ncftp
ncftp -u"$FTPU" -p"$FTPP" $FTPS<<EOF
mkdir $FTPD
mkdir $FTPD/$NOW
cd $FTPD/$NOW
lcd $BACKUP
mput *
quit
EOF
### Find out if ftp backup failed or not ###
if [ "$?" == "0" ]; then
 rm -f $BACKUP/*
else
 T=/tmp/backup.fail
 echo "Date: $(date)">$T
 echo "Hostname: $(hostname)" >>$T
 echo "Backup failed" >>$T
 mail  -s "BACKUP FAILED" "$EMAILID" <$T
 rm -f $T
fi

How Do I Setup a Cron Job To Backup Data Automatically?

Just add cron job as per your requirements:
13 0 * * * /home/admin/bin/ftpbackup.sh >/dev/null 2>&1

Generate FTP backup script

Since I setup many Linux boxes, here is my own FTP backup script generator. You just need to provided appropriate input and it will generate FTP backup script for you on fly.

Ubuntu Linux Backup MySQL Server Shell Script

You can use mysqldump command to backup database. The mysqldump client is a backup program. It can be used to dump a database or a collection of databases for backup or for transferring the data to another SQL server. The dump contains SQL statements to create the table or populate it, or both.

Once database is dumped, you need to upload the same to ftp server. Use lftp client to upload all files.

Install lftp

lftp is a file transfer program that allows sophisticated ftp, http and other connections to other hosts. If site is specified then lftp will connect to that site otherwise a connection has to be established with the open command. To install lftp, enter:

sudo apt-get install lftp

Shell script to backup MySQL database server

Following is the shell script. It will dump all database to /backup/mysql and later it will upload to FTP server. You need to setup correct username and password before using the script:

 #!/bin/bash### MySQL Server Login Info ###MUSER="root"MPASS="MYSQL-ROOT-PASSWORD"MHOST="localhost"MYSQL="$(which mysql)"MYSQLDUMP="$(which mysqldump)"BAK="/backup/mysql"GZIP="$(which gzip)"### FTP SERVER Login info ###FTPU="FTP-SERVER-USER-NAME"FTPP="FTP-SERVER-PASSWORD"FTPS="FTP-SERVER-IP-ADDRESS"NOW=$(date +"%d-%m-%Y") ### See comments below ###### [ ! -d $BAK ] && mkdir -p $BAK || /bin/rm -f $BAK/* ###[ ! -d "$BAK" ] && mkdir -p "$BAK" DBS="$($MYSQL -u $MUSER -h $MHOST -p$MPASS -Bse 'show databases')"for db in $DBSdo FILE=$BAK/$db.$NOW-$(date +"%T").gz $MYSQLDUMP -u $MUSER -h $MHOST -p$MPASS $db | $GZIP -9 > $FILEdone lftp -u $FTPU,$FTPP -e "mkdir /mysql/$NOW;cd /mysql/$NOW; mput /backup/mysql/*; quit" $FTPS

Save script as /home/your-name/mysql.backup.sh file. Setup executable permission:
$ chmod +x /home/your-name/mysql.backup.sh
To backup MySQL, enter:
/home/your-name/mysql.backup.sh
OR
sudo /home/your-name/mysql.backup.sh

Run MySQL backup script as cron job

To automate procedure setup a cron job. For example run backup everyday at midnight (i.e once a day), enter:
$ sudo crontab -e
Append following cron job:
@midnight /home/you/mysql.backup.sh >/dev/null 2>&1
Save and close the file. Please note that above script should work with other Linux distros or UNIX like oses.

How to e-mail yourself an automatic backup of your MySQL database table with PHP

<?php
// Create the mysql backup file
// edit this section
$dbhost = "yourhost"; // usually localhost
$dbuser = "yourusername";
$dbpass = "yourpassword";
$dbname = "yourdb";
$sendto = "Webmaster <webmaster@yourdomain.com>";
$sendfrom = "Automated Backup <backup@yourdomain.com>";
$sendsubject = "Daily Mysql Backup";
$bodyofemail = "Here is the daily backup.";
// don't need to edit below this section

$backupfile = $dbname . date("Y-m-d") . '.sql';
system("mysqldump -h $dbhost -u $dbuser -p$dbpass $dbname > $backupfile");

// Mail the file

    include('Mail.php');
    include('Mail/mime.php');

	$message = new Mail_mime();
	$text = "$bodyofemail";
	$message->setTXTBody($text);
	$message->AddAttachment($backupfile);
    	$body = $message->get();
        $extraheaders = array("From"=>"$sendfrom", "Subject"=>"$sendsubject");
        $headers = $message->headers($extraheaders);
    $mail = Mail::factory("mail");
    $mail->send("$sendto", $headers, $body);

// Delete the file from your server
unlink($backupfile);
?>

Using PHP to Backup MySQL Databases

There are at least three ways to backup your MySQL Database :

  1. Execute a database backup query from PHP file.
  2. Run mysqldump using system() function.
  3. Use phpMyAdmin to do the backup.

Execute a database backup query from PHP file

Below is an example of using SELECT INTO OUTFILE query for creating table backup :

<?php
include ‘config.php’;
include ‘opendb.php’;
$tableName  = ‘mypet’;
$backupFile = ‘backup/mypet.sql’;
$query      = “SELECT * INTO OUTFILE ‘$backupFile’ FROM $tableName”;
$result = mysql_query($query);
include ‘closedb.php’;
?>

To restore the backup you just need to run LOAD DATA INFILE query like this :

<?php
include ‘config.php’;
include ‘opendb.php’;
$tableName  = ‘mypet’;
$backupFile = ‘mypet.sql’;
$query      = “LOAD DATA INFILE ‘backupFile’ INTO TABLE $tableName”;
$result = mysql_query($query);
include ‘closedb.php’;
?>

It’s a good idea to name the backup file as tablename.sql so you’ll know from which table the backup file is

Run mysqldump using system() function

The system() function is used to execute an external program. Because MySQL already have built in tool for creating MySQL database backup (mysqldump) let’s use it from our PHP script

<?php
include ‘config.php’;
include ‘opendb.php’;
$backupFile = $dbname . date(“Y-m-d-H-i-s”) . ‘.gz’;
$command = “mysqldump –opt -h $dbhost -u $dbuser -p $dbpass $dbname | gzip > $backupFile”;
system($command);include ‘closedb.php’;
?>

Use phpMyAdmin to do the backup

This option as you may guessed doesn’t involve any programming on your part. However I think i mention it anyway so you know more options to backup your database.

To backup your MySQL database using phpMyAdmin click on the “export” link on phpMyAdmin main page. Choose the database you wish to backup, check the appropriate SQL options and enter the name for the backup file.

<style type=”text/css”> .style1 { width: 615px; } .style2 { text-align: right; width: 85px; } </style>

Installing Oracle 11gR2 Enterprise Edition on Ubuntu 10.04 (Lucid Lynx)

I recently reformatted my laptop with the latest Ubuntu LTS release, 10.04, aka Lucid Lynx. Since I like to have a native client installation as well as a portable sandbox server, I decided to install the latest version of Oracle EE, 11.2.0.1.

Rather than re-invent the wheel, I’m going to direct you to the previous Oracle-on-Ubuntu post by my colleague Augusto Bott. Many of the directions there hold true here (even with 32-bit vs 64-bit), with a few exceptions.

Download the Software
First and foremost, download the 32-or-64-bit installer files (there are 2 of them) from OTN.

Installing Pre-requisite Packages
Install these software packages on your Ubuntu 10.04 system:

1
$ sudo apt-get install unzip build-essential x11-utils rpm ksh lsb-rpm libaio1

Ubuntu 10.04 comes with libstdc++6 installed. However, Oracle 11gR2 requires libstdc++5. If you do not install libstdc++5, you will see errors as described in this OTN thread. The fix, as described in that thread, is to download and manually shoehorn the libstdc++5 library files onto Ubuntu 10.04:

$ dpkg-deb -x libstdc++5_3.3.6-17ubuntu1_amd64.deb ia64-libs
$ sudo cp ia64-libs/usr/lib/libstdc++.so.5.0.7 /usr/lib64/
$ cd /usr/lib64/
$ sudo ln -s libstdc++.so.5.0.7 libstdc++.so.5
$ dpkg-deb -x ia32-libs_2.7ubuntu6.1_amd64.deb ia32-libs
$ sudo cp ia32-libs/usr/lib32/libstdc++.so.5.0.7 /usr/lib32/
$ cd /usr/lib32
$ sudo ln -s libstdc++.so.5.0.7 libstdc++.so.5

Now we’re ready to move on.

Create User and Groups
First create the oinstall and dba groups:

$ sudo su -
# addgroup oinstall
# addgroup dba

Then create the oracle user and assign it to those groups:

# useradd -g oinstall -G dba -d /home/oracle -s /bin/bash oracle
# passwd oracle
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
# mkdir /home/oracle
# chown -R oracle:dba /home/oracle

Now we create some symbolic links to give the Ubuntu system a more “Red Hat-ish layout,” as Augusto put it:

# ln -s /usr/bin/awk /bin/awk
# ln -s /usr/bin/rpm /bin/rpm
# ln -s /usr/bin/basename /bin/basename
# mkdir /etc/rc.d
# for i in 0 1 2 3 4 5 6 S ; do ln -s /etc/rc$i.d /etc/rc.d/rc$i.d ; done
# mkdir -p /u01/app/oracle
# chown -R oracle:dba /u01

Then we update some sysctl parameters by editing /etc/sysctl.conf. It is wisest to backup this file first and then add these lines to the end of /etc/sysctl.conf:

1
2
3
4
5
6
7
8
9
10
11
fs.file-max = 6815744
fs.aio-max-nr = 1048576
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.core.rmem_default = 4194304
net.core.rmem_max = 4194304
net.core.wmem_default = 1048576
net.core.wmem_max = 1048576
net.ipv4.ip_local_port_range = 9000 65535

Note that these values are different from what was needed in 11gR1.

Now we update some limits for the oracle software owner by adding these lines to the end of /etc/security/limits.conf:

1
2
3
4
oracle soft nproc 2047
oracle hard nproc 16383
oracle soft nofile 1023
oracle hard nofile 65535

Again, it is best to backup the file first.

Now we activate the new settings from /etc/sysctl.conf with this command:

1
# sysctl -p

You should see the new settings in the output of that command.

Unpack and Install the Software
From here we go into the directory containing our two 11gR2 database zip files. I’m using the 64-bit edition, so my files are named linux.x64_11gR2_databaseXof2.zip, where X is 1 or 2. I unzip both of these files, which creates a “database” subdirectory:

1
2
$ unzip linux.x64_11gR2_database_1of2.zip
$ unzip linux.x64_11gR2_database_2of2.zip

Each of these commands will produce a large volume of output to the terminal as it lists each file being unpacked. Once this is done, your directory should look something like this:

1
2
3
4
5
$ ls -lh
total 2.2G
drwxr-xr-x 8 seiler seiler 4.0K 2009-08-20 14:34 database
-rw-r--r-- 1 seiler seiler 1.2G 2010-03-09 11:33 linux.x64_11gR2_database_1of2.zip
-rw-r--r-- 1 seiler seiler 1.1G 2010-03-09 12:38 linux.x64_11gR2_database_2of2.zip

Now you simply cd into the database directory and run the runInstaller program:

1
2
$ cd database
$ ./runInstaller

This will launch the Oracle Universal Installer, or OUI, program. The rest is pretty straight forward. Since this is just a sandbox, I chose not to provide any email info and declined to receive updates. I chose to first install the software only, which went perfectly well. OUI will complain about missing packages, since it is checking for RPMs. We can safely ignore these and proceed with installation.

Once installation is done I set these variables in my bash environment:

1
2
3
4
5
6
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/dbhome_1
export ORACLE_SID=orcl
export LD_LIBRARY_PATH=$ORACLE_HOME/lib
export PATH=$ORACLE_HOME/bin:$PATH
export EDITOR=/usr/bin/vi

Then some quick tests to verify installation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ sqlplus /nolog
SQL*Plus: Release 11.2.0.1.0 Production on Thu Jun 10 23:46:42 2010
Copyright (c) 1982, 2009, Oracle.  All rights reserved.
SQL> quit
$ /u01/app/oracle/product/11.2.0/dbhome_1/OPatch/opatch lsinventory
Invoking OPatch 11.1.0.6.6
Oracle Interim Patch Installer version 11.1.0.6.6
Copyright (c) 2009, Oracle Corporation.  All rights reserved.
Oracle Home       : /u01/app/oracle/product/11.2.0/dbhome_1
Central Inventory : /u01/app/oraInventory
   from           : /etc/oraInst.loc
OPatch version    : 11.1.0.6.6
OUI version       : 11.2.0.1.0
OUI location      : /u01/app/oracle/product/11.2.0/dbhome_1/oui
Log file location : /u01/app/oracle/product/11.2.0/dbhome_1/cfgtoollogs/opatch/opatch2010-06-10_23-46-53PM.log
Patch history file: /u01/app/oracle/product/11.2.0/dbhome_1/cfgtoollogs/opatch/opatch_history.txt
Lsinventory Output file location : /u01/app/oracle/product/11.2.0/dbhome_1/cfgtoollogs/opatch/lsinv/lsinventory2010-06-10_23-46-53PM.txt
--------------------------------------------------------------------------------
Installed Top-level Products (1):
Oracle Database 11g                                                  11.2.0.1.0
There are 1 products installed in this Oracle Home.
There are no Interim patches installed in this Oracle Home.
--------------------------------------------------------------------------------
OPatch succeeded.

Everything looks hunky-dory. Let’s create an instance.

Get Visitor’s Information

The following code fetches the vistor data:-

 

$visitorData = Mage::getSingleton('core/session')->getVisitorData();
// printing visitor information data
echo "<pre>"; print_r($visitorData); echo "</pre>";

You will get an array of visitor information data like the following one:-

Array
(
    [] =>
    [server_addr] => 167772437
    [remote_addr] => 167772437
    [http_secure] =>
    [http_host] => 127.0.0.1
    [http_user_agent] => Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10
    [http_accept_language] => en-US,en;q=0.8
    [http_accept_charset] => ISO-8859-1,utf-8;q=0.7,*;q=0.3
    [request_uri] => /magento/index.php/catalog/category/view/id/22
    [session_id] => 13qm5u80238vb15lupqcac97r5
    [http_referer] => http://127.0.0.1/magento/
    [first_visit_at] => 2011-01-17 11:42:23
    [is_new_visitor] =>
    [last_visit_at] => 2011-01-17 11:58:38
    [visitor_id] => 41
    [last_url_id] => 139
)

In the above array, the server_addr and remote_addr are in different form than usual. The (IPv4) Internet Protocol dotted address has been converted into a proper address using ip2long PHP function. You can get the same kind of value from the following code:-

// user's ip address (visitor's ip address)
$remoteAddr = Mage::helper('core/http')->getRemoteAddr(true);
// server's ip address (where the current script is)
$serverAddr = Mage::helper('core/http')->getServerAddr(true);

Hope this helps. Thanks.

Validate file Extension

Javascript Function To Validate File Extenxion

extArray = new Array(".ai", ".pdf", ".eps", ".jpg", ".gif", ".png");
function LimitAttach(file) {
	allowSubmit = false;
	if (!file) return;
	while (file.indexOf("\\") != -1)
	file = file.slice(file.indexOf("\\") + 1);
	ext = file.slice(file.indexOf(".")).toLowerCase();
	for (var i = 0; i < extArray.length; i++) {
	if (extArray[i] == ext) { allowSubmit = true; break; }
	}
	if (allowSubmit) return true;
	else
	alert("Please only upload files that end in types:  "+ (extArray.join("  ")) + "\nPlease select a new "	+ "file to upload and submit again.");
	return false;
}

Magento – Create a globally available static function

Sometimes, you’ve got a situation where you want to have a globally available static function.  Most often this occurs (for me) in a debugging context.  Recently I wanted to have FirePHP available from anywhere in my project so I made use of the lib folder.

Unlike just about every other article on this site, for this one we’re going to be considering the folder /lib.  Note that this folder is NOT within local, but resident in the root.  As such changes here should be put within their own sub-folders so that they too will survive an upgrade.

It’s really quite easy to create your class, just follow the usual Magento naming conventions. I’m going to create Spinonesolutions_Devel_FirePHP so all I do is create the file: /lib/Spinonesolutions/Devel/FirePHP.php.  Note the similarity to Model naming.

In here I create my class definition:

<?php
class Spinonesolutions_Devel_FirePHP {
public static function send($var, $label = ”DEBUG”, $style = ”LOG”) {
if (Mage::getIsDeveloperMode()) {
$request = new Zend_Controller_Request_Http();
$response = new Zend_Controller_Response_Http();
$channel = Zend_Wildfire_Channel_HttpHeaders::getInstance();
$channel->setRequest($request);
$channel->setResponse($response);
/*
* Start output buffering
*/
ob_start();
Zend_Wildfire_Plugin_FirePhp::send($var, $label, $style);
/*
Style     Description
LOG     Displays a plain log message
INFO     Displays an info log message
WARN     Displays a warning log message
ERROR     Displays an error log message that increments Firebug?s error count
TRACE     Displays a log message with an expandable stack trace
EXCEPTION     Displays an error long message with an expandable stack trace
TABLE     Displays a log message with an expandable table
*/
/*
* Flush log data to browser
*/
$channel->flush();
$response->sendHeaders();
} else {
return null;
}
}
}

Now I can call Spinonesolutions_Devel_FirePHP:send() anywhere in my project.