Thursday, December 27, 2012

Zend_File_Transfer_Adapter_Abstract bug when file not uploaded

I'm not sure where goes wrong, but some how if a file element does not contain file,
the check returns empty.
there is a bug open since may, but yet no patch for it.

file effected is
line #617: public function isValid($files = null)

Tuesday, December 25, 2012

Zend framework 2 FormRow Render element with ID differently

Not sure what goes up with their development team that there render element with id attribute differently, compared to those without it.
Took me sometime to figure this, sigh*!

And guess what, i cant file a zend framework 2 bug.. lol
Only Zend Framework 1 jira tracker is available, not sure if ive visited the wrong link

Zend AbstractTableGateway does not support table alias

Couldnt figure out how to do it,
finally, i created my own Sql and and Select on my own.

But ive to overwrite executeSelect to allow table select with alias
$resultSet = $this->selectWith($oSelect);

Zend framework 2 route example

router' => array(
    'routes' => array(
      'bannermgt' => array(
        'type' => 'segment',
        'options' => array(
          'route' => '/bannermgt[/:action][/:id][/page/:page][/searchname/:searchname][/searchpath:searchpath][/]',
          'constraints' => array(
            'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
            'id' => '[0-9]+',
            'page' => '[0-9]+',
            'searchname' => '[^/]*',
            'searchpath' => '[^/]*',
          'defaults' => array(
            'controller' => 'BannerMgt',
            'action' => 'index',
            "page" => 1,
            "searchname" => "",
            "searchpath" => ""

Take note that ordering of URL in route is strict.
Therefore searchname must come first before searchpath.

Or else , you may ommit:
And append as querystring

Zend Framework 2 redirect and forward

Both uses different path name to identify.
Redirect uses physical url on browser side, therefore the route name is to be used.

For forward wise, its using the factory service name to identify the controller to run.

'controllers' => array(
        'invokables' => array(
            'Application\Controller\Index' => 'Application\Controller\IndexController',
            'Application\Controller\Login' => 'Application\Controller\LoginController'

'router' => array(
        'routes' => array(
            "login" => array(
                'type' => 'segment',
                'options' => array(
                    'route' => '/login[/:action][/]',
                    'constraints' => array(
                        'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
                    'defaults' => array(
                        'controller' => 'Application\Controller\Login',
                        'action' => 'index',

$this->forward()->dispatch("Application\Controller\Index", array("action" => "someaction");

for redirect:
$this->redirect()->toRoute("login", array("action" => "someaction");

to get current controller name:

to get current route name:
return $this->getEvent()->getRouteMatch()->getMatchedRouteName();

Friday, December 21, 2012

Zend framework 2 get other view helper instance

in view:

$oFormat = $this->plugin("dateFormat");
echo $oFormat->__invoke(...);

to invoke directly:
echo $this->dateFormat(...);

Zend framework 2 Locale / i18n

In Application/config/module.config.php:

return array(
'translator' => array(
        'locale' => 'en_GB',
        'translation_file_patterns' => array(
                'type'     => 'gettext',
                'base_dir' => __DIR__ . '/../language',
                'pattern'  => '',

In Application/Module.php bootstrap:

//set your time zone here

$oViewHelperManager = $e->getApplication()->getServiceManager()->get("ViewHelperManager");

To output in view template:
echo $this->translate("My text here");
echo $this->dateFormat(new DateTime(), IntlDateFormatter::SHORT);
echo $this->numberFormat(12345.0123, NumberFormatter::DECIMAL);
//default currency
echo $this->numberFormat(12345.5226, NumberFormatter::CURRENCY);

//custom currency output:
echo $this->currencyFormat(1234.5226, "MYR");

  • php5-intl

Thursday, December 20, 2012

Active directory login from Zend

After spending hours solving this issue,
and ive found that each different company have different active directory path setting.

For login purpose, the main concern are the baseDn.
Some uses this:

Some uses this:

And event this:
OU=Users,OU=.User Accounts,DC=EXAMPLE,DC=COM

Example of Zend 1 config in yaml:

      host: EXAMPLE.LOCAL
      accountDomainName: EXAMPLE.LOCAL
      accountDomainNameShort: EXAMPLE
      baseDn: OU=Users,OU=.User Accounts,DC=EXAMPLE,DC=LOCAL
      bindRequiresDn: false

Wednesday, December 19, 2012

Zend Framework 2 controller init


class MyController extends Controller {
protected $bInit = false;

public function onDispatch(\Zend\Mvc\MvcEvent $e) {
    if (! $this-> bInit) {
      $this-> bInit = true;
    return parent::onDispatch($e);

Zend Framework 2 file upload

Note: Remember to set destination and filter to adaptor before running isValid or Receive,
Because setting filter or destination after running isvalid will cause the isvalid to add 2 times check on the file, one as tmp_name and another as destination name..
which will cause Count validator to fail!

    $sDestination .= getcwd() . "/public/assets";
    if (!is_dir($sDestination)) {
      if (!@mkdir($sDestination, 0777, true)) {
        throw new \Exception("Unable to create destination: " . $sDestination);
    $size = new Size(array('min' => 10, "max" => 10000000)); //minimum bytes filesize
    $count = new Count(array("min" => 0, "max" => 1));
    $extension = new Extension(array("extension" => array("jpg", "png", "swf")));

    $oFile = $this->params()->fromFiles('txtFile1');
    $adapter = new \Zend\File\Transfer\Adapter\Http();
    $adapter->setValidators(array($size, $count, $extension), $oFile['name']);
    if (! $adapter->isValid()) {
      $dataError = $adapter->getMessages();
      $error = array();
      foreach ($dataError as $key => $row) {
        $error[] = $row;
      $form->setMessages(array('txtFile1' => $error));
    } else {
      if ($adapter->receive($oFile['name'])) {
      } else {
        $form->setMessages(array('txtFile1' => "Receive failed"));

Tuesday, December 18, 2012

Zend framework 2 and firebug and composer

To install firebug core lib via composer onto zend framework 2,


 "firephp/firephp-core": "dev-master"


"require": {
        "php": ">=5.3.3",
        "zendframework/zendframework": "2.*",
        "firephp/firephp-core": "dev-master"

#run in console:
php composer.phar install

#for update on existing library
php composer.phar update

Kloxo dns template error

Ive came accross some long error on kloxo dns template,
and it turn out to be corrupted dns template.
I only realize this on creation of a domain or addition of a client.

running /script/fixdns seems to fix this issue,

if you have created a domain or client, just delete the client,
and recreate again.

yes, its still annoying that kloxo always have update issue which corrupt some of the files,
most obvious was roundcube update

Monday, December 17, 2012

Zend 2 Service Locator

Zend 2 Service Locator seems to be replacing Zend 1 Zend_Registry

Here are some reference:

Tuesday, November 27, 2012

CPanel mailq

To check mailq, run this:
/usr/sbin/exim -bp

To resend a mail message with debugging on:
/usr/sbin/exim -d -M [msgid]

To delete a mail que:
/usr/sbin/exim -v -Mrm [msgid]

Tuesday, November 20, 2012

Zend file upload and addfilter rename isnt working

Ive had spent many days repeatly on different project, stumbling on one same issue.
AddFilter rename isnt working on my file upload.

It was one simple solution,
first, never ever getValue from the field before addfilter rename is in place.

Its very easy that we miss out lines of code where by it tries to populate data model from form.
Also its also easy to accidentally getting value from model to replace upload form field.

Make sure addfilter rename is called before isvalid is checked.

Hope this will solve your hair pulling days figuring why it isnt working.
The worst part is, Zend Framework isnt complaining about it!

Friday, November 9, 2012

modx setup blank page

After some research,
blank page could be caused by insufficient memory,
set php memory limit to higher

another possible issue is core/config/

it turn out , on my machine when i was migrating a remote modx to my local machine,
the write process onto somehow halted with some unknown error which caused blank page.
So, the page was a template file, and it turn out to be an invalid php script file.
ive to redownload my and try rerun..

But some how in the end, the final setup failed half way, with no errors again, content got loaded half way with no errors.

Yes, in the end, i applied the latest upgrade files onto the root,
and rerun setup,
but this time, it went well and it was a successful upgraded and the site is working!

Thursday, November 8, 2012

mongodb mapreduce to use as group by and sorted before running

//SQL: select siteref, panelno, count(*), sum(rental) as total rental, sum(lighting) as totallighting from campaign where `year` >= 2011 group by siteref, panelno order by siteref asc;
//please take note this sort is before the grouping
// if you want after grouping result, query the result from output table, and sort it there

  mapreduce: "campaign",
  sort: { "siteref": 1 },
  map: function() {
    //month starts on 0
    day = new Date(this.year, this.mon-1, 1, 0, 0, 0);
    oSite ={siteref: this.siteref, panelno: this.panelno});
    emit({siteref: this.siteref, panelno: this.panelno, advertiser: this.advertiser},
      { rental: this.rental, lighting: });
  reduce: "function(key, values) {\
    var output = { cnt: 0, totalrental: 0, totallighting: 0, aa: 1};\
    values.forEach(function(v) {\
      output['totalrental'] += v['rental'];\
      output['totallighting'] += v['lighting'];\
    return output;\
  out: {
    "replace": "campaign_report"
  query: {
    year: { $gte: 2011}

Tuesday, October 9, 2012

mac port selfupdate error

Error: org.macports.checksum for port php5 returned: Unable to verify file checksums

Some mis behaving server is not hosting the package accordingly.
Took me some time to found the solution:
mac port clean --dist php5
mac port sync

mac port upgrade outdated

//keep trying the above until the server got kicked off from your list

Wednesday, October 3, 2012

yaml and "

how to insert a " charactor into yaml value? here is how: settingname: """ ironicly, it encloses the " with delimiter ".. and tested working

adding () into Zend Query

Example of encapsulating query with Zend_Db_Select

Monday, October 1, 2012

Zend form element separator

yes, finally i did a separator due to some hiccup on fields being hanging on top of the previous field:

a better looking checkbox for zend form element checkbox


$this->getElement('iagree')->addDecorator('HtmlTag', array('tag' => 'dd', 'class' => 'checkbox'));
$this->getElement('iagree')->addDecorator('Label', array('placement' => 'APPEND', 'class' => 'checkbox', "escape" => false));
//escape to false to prevent from escaping link within the label
//also adding checkbox class to the dd tag and label tag
// and place label to the right of checkbox

Css wise:

dl dd.checkbox {
  margin-left: 175px;
  float: left;

dl label.checkbox {
  display: block;
  margin-left: 190px;
  width: auto;
  float: none;
  text-align: left;
  height: auto;

.zend_form label.checkbox.required {
  padding-left: 12px;
  background-position: left center;

Sunday, September 30, 2012

MODx Revolution IncludePage

The original includepage inspired by Daniel
This version is currently supported in MODx 2.2.4-pl


Saturday, September 29, 2012

mongodb distinct and sort

Its alike javascript.
To sort the result, simply issue sort in the end

Monday, September 24, 2012

jquery form and tinymce

Jquery form doesnt work properly with tinymce,
one way work around is to trigger tinymce input saving before submitting the form

    beforeSerialize: function($form, options) {

Sunday, September 23, 2012

tinymce mceRemoveControl NS_ERROR_UNEXPECTED: Component returned failure code

Im not sure if its considered a bug, but this is annoying for me.
When i ran mceRemoveControl command to remove a already destroyed tinymce on a textarea,

After googling around with not much result, ive decided to dig into the source code ,
and finally found a solution.
Instead of calling directly mceRemoveControl, call this tinyMCE.remove(tinyMCE.getInstanceById()):

var oInstance = tinyMCE.getInstanceById("txtContent");
if (oInstance) {
  if (oInstance.isHidden()) tinyMCE.remove(oInstance);
  tinyMCE.execCommand('mceRemoveControl', true, "txtContent");
tinyMCE.execCommand('mceAddControl', true, "txtContent");



Wednesday, September 19, 2012

su root with sudo

There are times when we need to use su to do some root required tasks which are too tedious to use if we are required to type sudo for every command.
Here is how:
sudo su

Tuesday, September 18, 2012 and should be banned from spam filtering!

These two black list provider seems to ask for money to get de-listed from from their server.
Their so called "fine" doesn't seems to be appropriate when there are so many clients machine which may have faced infection from virus or malware.
The real fine should be done to the actual virus creator or malware!

Monday, September 17, 2012

csf and kloxo

Running server without some kind of protection, open up to bruteforce and dos attack.
Even with ssh port set to different port, or PermitRootLogin no, isnt good enough.

People can still guess a domain username based on the control panel being used,
especially plesk and cpanel.
Once they fire up their brute force attack, they can use it to attempt to get your clients password.

So its best to install some kind of detection and auto blocking system to prevent this from happening.
CSF is one of the best tool to use.

Once installed, here are some useful tips you might want to consider:

enable UI, but remember to set the username and password in the ui section below the ui enable line.
Email alert to yourself, incase if someone is attacking your server.

And on top of that, for kloxo purpose, you may want to ignore this list of processes, by adding these lines:


into /etc/csf/csf.pignore

Option options may be useful is set TESTING to 0.

add in port 7777 to

After thats done,
run this:
/etc/init.d/csf start
/etc/init.d/lfd start

For directadmin wise:
add these lines into /etc/csf/csf.pignore


to whitelist:
add ip into:

Other optional setting:

To set connection limit per ports:
CONNLIMIT = "22;5,80;10,110;5,25;5,587;5,21;5"
example above:
port 22: max 5 per ip,...

For more information:

Friday, September 14, 2012

eclipse wont run on mac os x 1.8.1

Took me sometime to investigate on this,
and finally i found the problem.

It seems to be unarchive bug on mac os tool,
which causes some files to not extract out.

the solution:
tar -xf eclipse....tar.gz

found the bug here:

sigh.. thats a real bug from apple

Monday, September 10, 2012

jquery fullcalendar reload events data


This might be useful to others:

      header: {
        left: 'prev,next today',
        center: 'title',
        right: 'month,agendaWeek'
      dayClick: function(date, allDay, jsEvent, view) {
        var sRawDate = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate();
        var sDate = date.getDate() + "-" + (date.getMonth()+1) + "-" + date.getFullYear();
        var sDay = date.getDay();
        sDay = sDay == 0 ? 7: sDay;
        if (allDay) {
          //jQuery("#frmClassAdd input[name=txtStartDate]").val(date);
          var sTime = date.getHours() + ":" + date.getMinutes();
        // change the day's background color just for fun
        //$(this).css('background-color', 'red');
        //todo trigger add data
      editable: true,
      firstDay: 1, //states monday as 1st day of week
      events: [
      eventSources: [
          url: "url_to_data.php", //
          data: {
            groupid: 5, //some param to pass in on top of start
      eventClick: function(calEvent, jsEvent, view) {
        //todo show an event


Tuesday, August 21, 2012

Zend_Form_Element_File setFilter rename and form->getValues() not working

Take note that form->getValues() will return all values from form, including calling
form file element to receive().
Therefore, setFilter rename shall be called before form->getValues line.

Monday, August 20, 2012

jQuery Form IFrame

When jQuery.form iframe option is assigned to true,
the result of the iframe will be triggered twice if the result contains javascript.

The solution to the problem is to assign [textarea] tag to wrap up the contain.
But having tags within the textarea tag will cause some unexpected result on the contain.
Therefore, php htmlentities shall fix the issue for the tags within the content.

If you are running on Zend, there will be issue.
By default, you may disable the layout and display the action view template.
But due to requirement to wrap the output with textarea,
we shall need to disable the view template, and do a manual output of the view file.

Solution (in controller):

$sView = $this->getViewScript();

if ($this->getRequest()->isPost()) {
   return "[textarea]" . htmlentities($this->view->render($sView)) . "[/textarea]";
} else {
   return $this->view->render($sView);

This solution shall output a normal view if its not submitted from the form.

Saturday, August 11, 2012

atomicorp repository and kloxo

Atomicorp supply php5.3 and mod apc required for centos5 version of kloxo.
But the qmail-toaster version supplied by atomic conflict with lxcenter-updates,
therefore, adding
exclude = qmail*
to the /etc/yum.repos.d/atomic.repo

Thursday, August 2, 2012

Setting up Python Mako with MySQL Workbench

It seems that on MAC, does not to include packages from:


Therefore, its not available within the plugin environment of MySQL Workbench.

The solution is to copy
/Users/james/Library/Application Support/MySQL/Workbench/mako

Wednesday, August 1, 2012

jQuery form and Zend_Form File

It appears that Zend Form will validate fail if we are using ajax or jquery form to submit the form.
To fix the issue, just ensure the form is submitted with the parameter: iframe: true

Also note that IE 8 or below will behave strangely when submitting via jQuery Form with file input.
So avoid using it on IE8 or below...

Thursday, June 28, 2012

clear both whitespace

Its common to use clear:both style to push the parent container box to fit the height nicely.
It recent finding, realized when ever there is a float div above it, it will cause a huge white space to the container.
One way to fix it is to set the parent container: overflow: hidden

Thursday, June 21, 2012

jquery e[h] not defined

jQuery("#formtargetname").submit() fail with e[h] error.
problem due to having a button or any field by the name "submit"

Sunday, June 3, 2012

Kloxo Roundcube unable to save to address book

Just faced this issue back 1 week ago, v 6.1.22 seems to face this issue on roundcube email.
upon further investigation into /var/log/httpd/error_log, found this:

PHP Notice:  MDB2 Error: no such field Query: _doQuery: [Error message: Could not execute statement] [Last executed query: INSERT INTO contacts (user_id, changed, del, `vcard`, `name`, `email`, `words`) VALUES (1, now(), 0, 'BEGIN:VCARD\\r\\nVERSION:3.0\\r\\nFN:[name]\\r\\nEMAIL;\\r\\nEND:VCARD', 'name', '', ' name')] [Native code: 1054] [Native message: Unknown column 'words' in 'field list']  in /home/kloxo/httpd/webmail/roundcube/program/include/ on line 2270, referer: ...

So, i went to dig into

And found these line which add the "word" column into the contacts table.

So i went to login as admin user into the kloxo and server > localhost > phpmyadmin,
and ran these script for roundcubemail database:

ALTER TABLE `contacts` ADD `words` TEXT NULL AFTER `vcard`;
ALTER TABLE `contacts` CHANGE `vcard` `vcard` LONGTEXT /*!40101 CHARACTER SET utf8 */ NULL DEFAULT NULL;
ALTER TABLE `contactgroupmembers` ADD INDEX `contactgroupmembers_contact_index` (`contact_id`);

And now it works perfectly.
Please take note not to run the entire file. You might likely to hit already ran sql syntax, and might took the risk to clear of your tables, especially message table.

Thursday, May 31, 2012

MySQL lock table and subqueries

MySQL complaints when a subqueries table / alias is not locked.
But Even if we lock the table by tablename, it will still complaint on the subquery table being not locked.


select n.node_id,
    (select count(*) from node where node_aboveid=n.node_nextleftnodeid) as leftnextcnt,
    (select count(*) from node where node_aboveid=n.node_nextrightnodeid) as rightnextcnt,
    n.node_nextleftnodeid, n.node_nextleftdepth from
    node n

To solve this issue,
Every sub select table must have a alias name, different from the main table name.

select n.node_id,
    (select count(*) from node nleft where node_aboveid=n.node_nextleftnodeid) as leftnextcnt,
    (select count(*) from node nright where node_aboveid=n.node_nextrightnodeid) as rightnextcnt,
    n.node_nextleftnodeid, n.node_nextleftdepth from
    node n

And makesure to lock tables node write, node n write, node nleft write, node nright write;

Tuesday, May 29, 2012

Magento deleting an order

It have been some argument about able to cancel or delete a processed or shipped or completed order.
But by end of the day, there are reasons that people want to delete the order.
Be it by mistake, or due to testing the order.

I finally found a extension which works with magento 1.6.2, but it does not cover properly for 1.6.2.

So i ended up altering the module block to support it.

But due to the nature of the reporting in magento, its not possible to delete the cached reports in the database using this extension.
It can only be deleted based on date, but becareful with this procedures.
The reporting tables for sales order are:

Please note that i do not responsible for any data lost in the extension. So do the original developer himself. Please remember to backup your database in system > tools > backup before applying this extension and deleting any order.

Thursday, May 17, 2012

infinite loop in bootstrap module

It seems that if you want to develop a bootstrap for module,
you will need to extends Zend_Application_Module_Bootstrap

But how to get Layout from bootstrap_bootstrap?

How to get view?

What if i get undefined getView of a undefined object?
Yes, this problem is because layout and view bootstrap is not loaded in Zend_Application_Bootstrap_Bootstrap.

Makesure to run these in the class which extends bootstrap_bootstrap:

Wednesday, May 16, 2012

tail cannot watch no space left

Ive been encountering this problem when i tried to tail a file using -f...
The problem is caused by inode watch limit. I suspect its due to the dropbox that ive installed.

To fix it, set fs.inotify.max_user_watches configuration to higher:
sudo sysctl -w fs.inotify.max_user_watches=16384

Tuesday, May 15, 2012

Zend DB Select join

Example of joining table using dbtable (EntStudio_Db_Table_Abstract)

$maintable = "x";

$query = $dbtable->select();
$query->from($dbtable, array("*")); //only specify column for main table

$query->join(array("u" => "table2"),  $maintable . "", array("username")); //only specify column for table2

to output to test:
echo $query;

to get results:

$resultSet = $dbtable->fetchAll($query);
$entries   = array();
foreach ($resultSet as $row) {
//... codes here

to get a single row:
$row = $dbtable->fetchRow($query);

Zend Notification

Zend built in notification are divided into session saved message, and current message.
$flashmsg = Zend_Controller_Action_HelperBroker::getStaticHelper('FlashMessenger');

To get last added message in previous request (which is saved in the session):
$aMsg = $flashmsg->getMessages();

To clear the messages storage:
To get current added message (same request):

$aMsg = $flashmsg->getCurrentMessages();

To clear the current messages storage:

Please note that the current and the session message are separated, and need to be called respectively to retrieve all messages in the notification

zend view render vs layout render

To render another view file within the same controller,
$view / $this->render("filename.phtml");

to render a view file within layout:
$view / $this->layout()->render("filename"); //without .phtml

Monday, May 14, 2012

jquery(document).ready not running

Latest jQuery seems to halt all event execution when it comes to error.
If one of the javascript contains error, other event will not be triggering.
Its one of the gotcha that i stumbled upon since jQuery 1.6

Saturday, April 14, 2012

Magento base system principle


Block updates is set in config.xml
config > layout > updates > [modulename] > file
#files tag will point to a layout xml file in app/design/frontend/[themename]/layout/[modulename].xml

in [modulename].xml contains:
layout > [modulename] > [controllername] > [actionname] > reference [name=content] > block

block attributes available are:
type: To base this block on a class in your module. naming is case sensitive
@format: [Modulename]/[Block name]
@example: type="ProductLister/Lister" points to app/code/local/[namespace]/[Modulename]/Block/[Block name].php, with class name: [namespace]_[Modulename]_Block_[Block name]
name: a name which can be retrieved by calling $this->getChild('name') or $controller->getLayout()->getBlock("name")
template: points to the actual path of the phtml template file
@location: app/design/frontend/[themename]/template/[path]

Thursday, April 12, 2012

jquery height() or width() gotcha!

When a jQuery(target).height() is called in jQuery.ready event,
will return the height of the target, excluding the size of the image inside.
the only way to do it properly is to wait for the images to be loaded, therefore,
replacing it with jQuery(window).load(...) works best :)

Wednesday, April 11, 2012

jquery 1.7.2 bug?

I've a dom which is set to position: relative, style.left to 0

console.log($(target)); //return array of 1 object

$(target).css("left", "100px");
console.log(; //seems to return 100px, which is correct

but when i run
$(target).css("left"); // return 110px

$(target).position() - returns position from parent offset
$(target).offset() - returns position from the screen

The only work around method i could think of is to directly set:
position: relative;
top: 0;
left: 0;

Then use or directly.

Please note that this is tested on linux chromium browser 18.

Wednesday, April 4, 2012

javascript || operator gotcha

the OR operator of javascript might not execute the entire condition to complete it.
If it detected that the earlier condition meet, it will automatically abardon the check.

var x = true;
x = x || runmyfunction();

if x is true, runmyfunction will not be checked or executed. But if x is false, then runmyfunction will be executed to return the value.

Friday, March 30, 2012

installing apc on kloxo

For Yum based OS:
sudo yum install pcre-devel
sudo pecl install apc

Then create /etc/php.d/apc.ini
insert content as follows:

then restart httpd

If you are still having some problem installing this, try refer here:

Tuesday, March 27, 2012

Magento Order status does not convert to Processing

Tinkering around to make a payment gateway integration for iPay88 took me some really significant time.
I've been using some method from paypal module to redirect the form to ipay88,
and does a re-query to ipay88 server to determine the approve of transaction from ipay88.
On done, created an invoice and saved the transaction for the invoice.
Payment paid appears correctly, but some how order status still remain "pending".
I realized that i did not set the cctransid to the payment in my controller, 
so one way to do it is to pass the TransId from controller to payment method model.
To do this, create a model class to accommodate values from request form passed in from ipay88,
then in payment method model capture function, retrieve the ipay88 returned model and setCcTransId(...).
When done, the order will now be shown as "processing", depending on the setting in the admin configuration for the payment status on payment.

Sample below:
//getting config saved in admin:
$aConfig = Mage::getStoreConfig("payment/Ipay88");
$merchantcode = $aConfig["merchantcode"];
$oResponse = Mage::getSingleton("Ipay88/Api_Response");
//convert data from postback of ipay88 into oResponse as object data
Varien_Object_Mapper::accumulateByMap($_REQUEST, $oResponse, array(
  "MerchantCode", "PaymentId", "RefNo", "Amount", "Currency", "TransId", "AuthCode", "Status",
  "ErrDesc", "Signature", "Remark")

//codes to requery ipay88 for actual transaction
if ($iPayResult == "00") {
  //update order status and payment status
 if ($oOrder->canInvoice()) {
  $invoice = Mage::getModel('sales/service_order', $oOrder)->prepareInvoice();
  if (! $invoice->getTotalQty()) {
   Mage::throwException(Mage::helper('core')->__('Cannot create an invoice without products.'));
  //below this will trigger capture in method model
  $transactionSave = Mage::getModel('core/resource_transaction')
Next, in the payment method model capture:
public function capture(Varien_Object $payment, $amount)
 if (!$this->canCapture()) {
  Mage::throwException($this->_getHelper()->__('Capture action is not available.'));
 $oResponse = Mage::getSingleton("Ipay88/Api_Response");
 return $this;
Sample of iPay88 Model to hold request data
class MercStudio_Ipay88_Model_Api_Response extends Varien_Object {
Yes, its an empty class which extends Varien_Object :) The Magic of Varien object is that it accept any data set to it (setVariablename(value) or setData("variablename", value)), and you may retrieve the data by calling getData("variablename")

Monday, March 26, 2012

jQuery .load complete did not fire

This happen when i was dealing with an upgrade from jQuery 1.5 to 1.7.2.
It took me some struggle to find out what happened, and finally, i found the issue.
It seems that the oncomplete function will not run if the document itself somehow contains javascript with syntax error in the script. It wasn't any problem for jQuery1.5, but for jQuery 1.7.2, it seems to halt execution after loading the content to the targeted dom.

MODx Return Error 400 in manager

The recent changes on MODx seems to create a new kind of error 400 on all the javascript used in the manager screen.
The problem comes from issue with minified index.php where it over replaced manager/assets with assets path, therefore doubling the path to the actual javascript file.
The solution have been resolved in the nightly build of MODx

Monday, March 19, 2012

Facebook integration hickup

After encountering some weird behaviour of facebook login session on client  side,
i just realized that the flow of the code have to be correct.

window.fbAsyncInit = function(...);

the code above should come first, before including facebook js file below:


Friday, March 16, 2012

Linux list top cpu hogging processes

ps -eo pcpu,pid,user,args | sort -k 1 -r | head -10

Tuesday, March 13, 2012

Magento Export Sales Order Duplicate headers received from server

Its a bug which have been fixed in magento 1.7.
But for 1.6.2 users, you may change the core to fix this in:
app/code/core/Mage/Core/Controller/Varien/Action.php in function _prepareDownloadResponse:

By adding , true as the 3rd parameter in these lines:
->setHeader('Content-Length', is_null($contentLength) ? strlen($content) : $contentLength, true)
 ->setHeader('Content-Disposition', 'attachment; filename="'.$fileName.'"', true)
 ->setHeader('Last-Modified', date('r'), true);

Sencha Touch Carousel force slide

var carousel = Ext.getCmp("IDOfCarousel");; // .previous();

//to get active item
// but note that or previous will take time to animate and reflect.
//  therefor, to jump 3 slide away, just call 3 times and dont expect activeIndex to reflect directly after the call.

Thursday, March 8, 2012

magento error in admin

by default, magento does not show any error exception in admin / backend.
To enable error, go to :

duplicate errors/local.xml.sample as local.xml

Then you will have the error exception been printed.

Next, if you encounter unable to determine cache_dir,
you may follow the instruction here:

Wednesday, March 7, 2012

deploying magento live

Backup the local db from magento backend: system > tools > backup

Restore the database and files to server

edit core_config_data (table)
update setting for path: (take note of tailing /)
web/cookie/cookie_domain: [your domain]
web/secure/base% [https://www.yourdomain/]
web/unsecure/base% [http://www.youdomain/]

set permission to og+w

set permission to og+w

Thursday, March 1, 2012

modx package management could not install

After dabling around on my new server,
i realize that the package installer did not work.
Further examination reviewed the error "package could not be found".

So i went into the core/packages and found that the extraction process did not complete.
After searching around, 1 way to work around it is to set under setting,
search for "archive_with" and change it to true.

Make sure to delete the package with "force deletion" and redownload and try install again...
hope it works for you... :)

Tuesday, February 28, 2012

Sencha touch nestedlist click event without switching card

listeners: {
itemtap: function(list, index, item, e) {
//is home menu
if (list == this.items.getAt(0)) {
switch(index) {
case 0: //first menu
                                        //things to do for this detected menu
                                        //get the tabpanel and switch the card of tabpanel
                                        //call nestedlist to go back...
}//if is home menu


Monday, February 27, 2012

sencha touch nestedlist onclick

On click event for NestedList item is listerners: itemtap


var nestedList = new Ext.NestedList({
fullscreen: true,
title: 'Malpha Home',
displayField: 'text',
dock: 'top',
listeners: {
itemtap: function(list, index, element, record) {
                        //example of setting tabpanel active tab
store: store

Sunday, February 26, 2012

magento shipping table rates import

Magento shipping method have to be set in 2 different environment.
One on config, and another on site.
To import or export the rates, you will need to select "site" / "Default sites" to have the options to import the rates.
Before setting up these rates, you will have to ensure that you have setup the regions / states on your targeted countries to market.
Its can be set manually in database table on table:
Once you have set it, you may run this script to insert the name to the translation table for region name:
If you are lazy like me, i will just run this SQL script below to populate the name to the directory_country_region_name table:

INSERT INTO `directory_country_region_name` (`locale`, `region_id`, `name`) 
SELECT 'en_US', `region_id` , `default_name`
FROM `directory_country_region`
WHERE country_id='ID';

You will have to make sure that the directory_country_region.code field contain a unique code for your state / region. It's a norm to use countrycode-statename to ensure it is unique for every states you setup.
Example: ID-SUMUTR
which represent indonesia: sumatera utara.
In the import CSV, this will be the format of the csv (as of magento 1.6):
Country, Region/State, Zip/Postal Code, Order Subtotal (and above), Shipping Price
Country should contain short 2 alphabet code of the country, such as ID = Indonesia
Region/state field will be the field to contain the region/state code.
Order subtotal is optional (0)
Zip / Postal code is optional (empty)
Shipping price will be the price in shop currency.

Thursday, February 23, 2012

external php calling login into magento

Magento contains its own call to session_start() when included into your php application.
To ensure that your session set is the same session as magento front end, you will need to include magento in this manner:


//this is the magic call to ensure the session of front end tally with your php session

Mage::getSingleton('core/session', array('name'=>'frontend'));

To set someone as logged in:
$oCustomer = Mage::getSingleton('customer/customer')->setWebsiteId(Mage::app()->getStore()->getWebsiteId())->load(#id);

$oSession = Mage::getSingleton('customer/session');

Updated 2012 feb 25:
This method seems to lack of event triggering when customer is logged in.
When you login as a member A, view a product X. Then logout and view product X. Then login as member A again and view product X,
It will cause the product to be directed to an error 404.
This is due to an error in report log which caused a duplicate in table: report_viewed_product_index. Duplicate entry for UNQ_NEOSHOP_REPORT_VIEWED_PRODUCT_INDEX_CUSTOMER_ID_PRODUCT_ID (to be exact) Observer class triggered: app/code/core/Mage/Reports/Model/Event/Observer.php, method: catalogProductView

Suppose, when some logged in, it will trigger several core events, which related to "customer_login", but this does not seems to work when there is not front controller been dispatched.
One way to fix it is to run a action on the front controller and then continue with the code.
But problem is, the default module "" will trigger module cms which will display entire html of the magento cms front page.
To fix this, add your own custom controller, and a dummy action which does not echo anything.
And call magento to run this front controller by calling this way:

//this will enable sensitive error
$oMageApp = Mage::app();

Sunday, February 19, 2012

magento Name gotcha

It seems that all module directory name must start with capital.

This will fail:

Took me some time to figure this out... :(

Tuesday, February 14, 2012

magento available photo options

$this->helper('catalog/image')->init($_product, 'small_image')
$this->helper('catalog/image')->init($_product, 'image')
$this->helper('catalog/image')->init($_product, 'thumbnail')

Saturday, February 11, 2012

magento overide model customer resource customer

Took me ages to found the issue.
It turn out that if i overide xml pointing to the new class file is case sensitive and space sensitive.
This is how i've managed to override customer/model/resource/customer


Sunday, February 5, 2012

Magento inline popup for product

Took me several days and many hours of researching,
Finally, ive made it up to the stage where i can declare glory to my objective :)
Magento uses many combination of configuration to customize to your setting.

Okay, i needed to do a popup to view product without showing a full layout product viewing page.

I didn't wanted to alter the core functionality, as i wanted both:

  1. Exists magento product viewing page with full page layout
  2. A "quick view" button to show just the non-layout based popup

It would be much easier if i could just override the magento product view template by just copying existing template file into my template directory, and modify it as i needed. But this will override the entire product page, so we will no longer have access to the original full layout page.
Just for your reference, here is how its done:
copy from:

other optional files which you may override, but will need to have respective directories name, similar to the base template location:


Now, i need to customize the base layout file for all my pages, the product listing, and product viewing page.
I need both, the base layout file to use 1column.phtml, listing page to use only category.phtml layout. And the full view product page to use product.phtml layout.
create a file:
The content of the file can be edited as show in photo below.
Please take note on the tags: catalog_category_default (listing), catalog_product_view (view), checkout_onepage_index (checkout), default (default / base layout file)

Then upload the respective files to:
You may copy the layout files from app/design/frontend/base/default/template/page/1column.phtml to start out with.

Next, i wanted to remove some of the items which i dont use.
So, edit the file app/design/frontend/default/default/layout/local.xml
And add in remove tags under default tag:


And here comes the difficult part, the standalone popup product viewing page, which does not replace existing product viewing full layout.
To do this, we will need to write our own customized module.
You may refer here to learn from begining:

Okay, how are we going to allow the user to choose our layout from the CMS module?
Do this, edit:
directly under config tag, add in these tree:
config > global > page > layouts > yourpagename
Make sure to add in all the layout that you wish to be available on the CMS module, such as category.phtml and product.phtml

Once you are familiar with how to write blocks, have it configured to be installed, and integrated with custom blocks, then we can begin writing a extended version of the Catalog/product/view functionality without full layout.

inside your module path:

Create these tags:
config > frontend > layout > updates > mylayout > file > mylayout.xml (content)
global > helpers > mymodule > class > namespace_mymodule_Helper (content)
global > blocks > mymodule > rewrite > myproductview > namespace_mymodule_block_product_view (content)

Notice that the class file is declared for our custom layout "myproductview" which will be seen declared on the next file (mylayouts.xml).
We shall need helper class declared, as default product controller of magento will need a helper class to render the page.

Next, the final layout file:

Create the nodes:
layout > mymodule_product_view (as shown on the photo below)

Take note that this will also need you to create the file:
The file shall content a non html or body tags, to be displayed as popup using lightbox or colorbox.

Now, create the controller file to extend magento product controller:
Next, create the helper file to extend magento product helper:

And, create the Block handler file to handle block view for product

And finally, duplicate the file
and modify this file according to your requirement :)

to access the original product page from browser:
to access your customized popup page (standalone) from browser:

Sunday, January 29, 2012

modx page not found after upgrade to 2.1

There is some cache issue on modx, after an upgrade from modx 2.0.x
Clearing cache does not seems to fix the issue.
One way to fix it is to edit every resources which ever are effected...

Another way is to do a script to run recursively on all resources, edit it by changing the alias, and save,
and then changing the alias back to the actual alias, and save it again.

function doFixResource($id, $iLevel=1) {

$oRes = $modx->getObject("modResource", $id);
$aContext = array($oRes->get("context_key"));
$iParentId = $oRes->get("parent");
if (!empty($iParentId)) {
doFixResource($iParentId, $iLevel+1);

echo "Fixing: " . $oRes->get("id") . "(lvl:" . $iLevel . ")," . $oRes->get("alias") . "::" . $oRes->get("pagetitle") . "(" . $oRes->get("context_key") . ")
$sAlias = $oRes->get("alias");
$oRes->set("alias", $sAlias . "-". rand(10000,9999));
$oRes->set("alias", $sAlias);


then run flush script:

function doFlushContext($aContext) {
global $modx;

'db' => array(),
'auto_publish' => array('contexts' => $aContext),
'context_settings' => array('contexts' => $aContext),
'resource' => array('contexts' => $aContext),


And finally, run clear cache from manager screen.

Tips: If you want performance, cached up all the id which you have run doFixResource by using static variable, and skip it, it may save you up to more than 80% of the time :)

Friday, January 27, 2012

modx 2.2 changes

return anonymous user if no user is logged in to the context.
when getOne("Profile") is performed on anonymous user, will return null, so some error might be thrown.

modx->db->dbfunctions is now deprecated, so use the actual function from $modx itself.
for more information, refer here:

Example of a big change:

$modx->db->query is completely different from $modx->query

So you may use parseBinding to do your query.

$sSelectSQL = "select `parent`, `context_key` , id, `alias`, pagetitle, longtitle from modx_site_content where context_key=:contextand parent=:parent and `alias`=:alias and (published=0 or deleted=1)";

$aParam = array(":context" => "web",
":parent" => 1, ":alias" => "somealias");

$sResultSelectSQL = $modx->parseBindings($sSelectSQL, $aParam);
$stmt = $modx->query($sResultSelectSQL);

if (! $stmt) throw new Exception("SQL Failed: " . $sResultSQL);

//to fetch all
$aCount = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($aCount as $oRow) {
  echo $oRow["id"];
//to fetch one
$oRow = $stmt->fetch($PDO::FETCH_ASSOC);
echo $oRow["id"];

And other class based method:

//to get an object row
$oRes = $modx->getObject("modResource", array("context_key" => "web", "parent" => 1, "alias" => "somealias"));

echo $oRes->get("id");

modx 2.2 modX::isFrontEnd() is undefined?

After doing an upgrade to modx2.2, editing any resources seems to throw this error.
Solution, go to package manager, upgrade tinymce plugin.
And we are all set to go! :)

modx 2.2 upgrade from 2.0 error 500

There were seems to some configuration changes from 2.0 to 2.2 on core/config/
When i was upgrading, the test database seems to response with an error 500.
After inspecting core/cache/logs/error.log, it shows "no database selected"

So i went into editing core/config/ and found the $dbase = "{dbase}"
Using setup with advanced configuration does not seems to do the trick.
The solution now is to edit core/config/ and set $dbase = "`mydatabasename`"
and $database_dsn = 'mysql:host=localhost;dbname=mydatabasename;charset=utf8';

Take note on the different between the 2, one with `` delimiter, and one without.
Next, rerun setup for upgrade shall do the trick :)

magento enable cookie issue on chrome and ie

I came across this problem while trying to test my localhost machine for adding a product to cart.
it turn out to be some sort of cookie session issue on magento.

changing session length nor disabling cookie checking does not seems to work.
its suppose to only happen on localhost testing machine, might work well on actual domain.

Setting up vhost and pointing using hosts file shall do the trick...

magento 1.5

Magento 1.5 doesnt allow one to addjs or addskinjs with a custom sorting order...
its because the head.phtml file is doesn't support it in getCssJsHtml() and getIncludes();

One way to solve it is to inject script directly into head.phtml, but put it into your own template folder...
copy from app/design/frontend/base/default/template/page/html/head.phtml to

Another thing to take note is getUrl and getSkinURL gotcha...
$this->getSkinUrl("js/java.js"); // return skin/frontend/[base_or_yourtemplate]/default/js/java.js
$this->getUrl("js/java.js"); // return

Work around will be using $this->getUrl(""). "js/java.js"

Tuesday, January 17, 2012 sucks?

Updates 2012 jan 18:
Finally, got their attention from facebook fanpage. Talked to their support, and got my email replied.
They should check their offline chat message if its provided on their website...

Well, i tried to be professional in judging them.
If it wasn't because the client bought the hosting with them, i might not have to face their shit.

First, they change their hosting without our notice.
Previously things which works, now doesn't work, and they claim they never change anything,

In php point of programmer view, they disable error log.
Fine, as programmer, i will use ini_set to enable it to see what went wrong.
so my surprise, it came out error 500 instead.
so defnitely it has been disabled ini_set function... wth..

Next, if you php code doesnt close with ?>, it will also come out error 500, isn't this a norm in php to have unclosed tag? its to avoid unwanted endline charactor in the end to avoid being output out.

3rd, fine, lets fill in the support form for help..
After filling in the contact form, its been 1+ weeks and no response.
Okay, lets try call their support fella, went to voice mail...
Okay, lets try again, their "live chat",
waiting for operator, waiting for operator, waiting for operator, waiting for operator,  sorry operator not available..
Their website published they hosted CIMB, wth? do you think bank will host with them with this kind of SLA? LoL, what a joke..

Thursday, January 5, 2012

Facebook App session issue after user logout or close browser

It seems that Facebook PHP SDK does not properly check if user have logged out or close the browser.
When someone closes the browser or log out of facebook, the php sdk should detect the problem and automatically destroy the session, but it doesnt seems to be the case, even when we call $fb->destroySession();

One way to effectively check for problem is to use Facebook javascript sdk by subscribing to :

FB.Event.subscribe('auth.logout', function(response) {
      if (response.status=="unknown") {
        //some weird session error
The code effectively detect the logout with "unknown" status and redirect the user to a login screen.
Example of a login.php code:

Please <a href="javascript:">click here</a><br /> <script>

function doFBLogin() {

FB.login(function(response) {

  if (response.authResponse) {

   FB.api('/me', function(response) {


  } else {

   alert("Please authorize app by refreshing to continue...");


  }, {scope: 'email,user_likes'}); //additional parameter


</script><br /> ----------

Wednesday, January 4, 2012

Setting up zimbra centos 6 64bits

#makesure to update first
yum update
#install java first
yum install java-1.6.0
yum install netc
yum install which

#change existing httpd port other port than 80
sudo vi /etc/httpd/conf/httpd.conf
#change line: Listen 80 to Listen 8080 (any other port)

#change existing sendmail port to other than port 25
sudo vi /etc/mail/
#locate line:
DAEMON_OPTIONS(`Port=smtp,Addr=, Name=MTA')dnl
#change to other port than 25 / smtp
DAEMON_OPTIONS(`Port=2525,Addr=, Name=MTA')dnl

#locate line:
dnl DAEMON_OPTIONS(`port=smtp,Addr=::1, Name=MTA-v6, Family=inet6')dnl
#change to other port than 25 / smtp
dnl DAEMON_OPTIONS(`port=2525,Addr=::1, Name=MTA-v6, Family=inet6')dnl
#run this to apply changes
m4 > /etc/

#temporary disable sudo tty requirement
#locate line Default requiretty and disable it with a #
#Defaults requiretty

/etc/init.d/httpd restart
/etc/init.d/sendmail restart

#double check to ensure both http / 80 and smtp / 25 is not used any longer
netstat -lp

#Go to zimbra website and download the respective package for your platform...
#if something went wrong, check the log.
#to resetup, run:

#when done, reboot the system
sudo reboot

#next, run netstat -lp to check if system is running
#try telnet localhost 25, telnet localhost 110 and try web browsing
#to restart the service, try:
/etc/init.d/zimbra restart

sudo -u zimbra /opt/zimbra/bin/zmcontrol status
# mailbox                 Stopped
#check the log
tail -n 100 /opt/zimbra/log/mailbox.log
#if it shows
...Unknown table engine 'InnoDB'
#it meants that your innodb engine is not initiated , and most likely is memory issue.
#try changing innodb_buffer_pool_size to a lower value (below about 40% of your memory or vps memory)
sudo vi /opt/zimbra/conf/my.inf
#locate line innodb_buffer_pool_size
#restart zimbra mail
sudo -u zimbra /opt/zimbra/bin/mysql.server restart
sudo -u zimbra /opt/zimbra/bin/zmmailboxdctl restart

#to begin:

#If you forgotten your password, run this on server:
/opt/zimbra/bin/zmprov sp [password]

If you get error in the admin ui with:
Message: system failure: server  zimbraRemoteManagementPrivateKeyPath (/opt/zimbra/.ssh/zimbra_identity) does not exist Error code: service.FAILURE Details:soap:Receive
Try this:

If you are facing memory heap size problem with java, try following this link:
and also set your default heap size in java by editing ~/.bash_profile
export _JAVA_OPTIONS=-Xmx100m

#If your mail have not been deliver, try check the que by running:
sudo mailq

#if you encounter some file(1) utils missing, install it by running:
sudo yum install file

#If you are running zimbra from a openvz vps, please ensure min 3Gb of burst memory. Or it wont run properly. The problem is due to missing swap in openvz. So it will need sufficient memory to run.