How to upgrade from PHP 5.3.x to 5.5.x on Windows 7 in 4 easy steps

I have been using PHP 5.3.29 on my PC for some time now as many PHP open source frameworks and applications had been supporting PHP version uptill 5.3.X. However with time PHP has progressed and with new and stable versions coming up the benchmark of support has shifted from PHP 5.3 to PHP 5.4 and above. With this, the time had come to bid adieu to PHP 5.3 and move to the latest stable version in the PHP 5.X series i.e. PHP 5.5

Now PHP has stopped giving out windows binary installation files since PHP 5.3 so if you need to upgrade you will need to download the required files from php.net and manually configure the PHP version on your PC.

Step 1

First check the PHP version on your PC. Open the command prompt and write php -ver which displays the current PHP version on your PC.

php 5.3 version from you command prompt

Step 2

Browse over to http://windows.php.net/. Click on the archive link on the bottom left side.  You will reach this page http://windows.php.net/downloads/releases/archives/. Download the latest thread safe PHP 5.5.X version from the list you are shown on the page. I have highlighted the one I have downloaded in this example.


Step 3

After downloading the zip file extract the contents. Create a new directory on any of your drive. I created one by the name of php55 so that I can remember which PHP version this is. I then updated the PATH variable with the location of this PHP directory.

Step 4
After updating the PATH variable I then tried to check whether the new PHP version has kicked in or not. Unfortunately  I received a Windows alert with the following message

php.exe – System Error

The program can’t start because MSVCR110.dll is missing from your computer. Try reinstalling the program to fix this problem.

If you receive this message then there is nothing to worry. You just head on to Microsoft website and download and run the executable file from there.

MSVCR110.dll missing file resolution

If everything went correctly then you will see the correct PHP version on your command prompt like so

php 5.5 version on your command prompt
That’s all there is to it for migrating from PHP 5.3.X to PHP 5.5.X version.

Hope the above helped!

Tutorial to create custom Magento module

I could not find one good tutorial on developing a custom module in Magento when I had a client requirement to develop one for his website. It was not like there weren’t any. If you Google “custom Magento module tutorial” or something similar you will get a lot of search results however I received a lot of errors when I tried using them in my case. Either they were not tested or they were not supposed to work in that way but I am not complaining as it helped me to learn more about Magento and custom module development in Magento.

Follow the steps below to create your first custom Magento module. This module will display entries from a database table and display it in the Magento admin panel. I have tested this module on Magento community versions 1.6.2 and 1.7.0 and it is working on both of them.

Run the following SQL statement in your mySQL database.

CREATE TABLE `sarfraz` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(100) DEFAULT NULL,
  `cus_email` varchar(100) DEFAULT NULL,
  `telephone` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

After running the above statement it should create a table by the name of “sarfraz” in your database. Now run the following insert SQL statements to create records in the table.

insert into `sarfraz` (`id`,`first_name`,`cus_email`,`telephone`) values (1,'Adam Sandler','[email protected]','1234567890');
insert into `sarfraz` (`id`,`first_name`,`cus_email`,`telephone`) values (2,'Joe Burton','[email protected]','5556667777');
insert into `sarfraz` (`id`,`first_name`,`cus_email`,`telephone`) values (3,'Alice Keys','[email protected]','66677788888');

Our table now has some entries so we can now proceed with the actual coding related changes.

First create your XML file in the app/etc/modules folder. In this tutotial my XML file is named as Adeel_Sarfraz.xml however you are free to choose what ever name is right for you.

<?xml version="1.0"?>
<config>
    <modules>
        <Adeel_Sarfraz>
            <active>true</active>
            <codePool>local</codePool>
            <version>1.0.0</version>
        </Adeel_Sarfraz>
    </modules>
</config>

The above code will register your module in Magento. Now we put in the actual code for the module.

Go to app/code/local folder and create a new folder by the name of “Adeel” and then create another folder within it by the name of “Sarfraz”.

Now create 5 folders in the app/etc/local/Adeel/Sarfraz folder.

1. Block
2. controllers
3. etc
4. Helper
5. Model

We will start now by creating a config.xml file in the etc folder. Once you have created it you can add the following code to the config.xml file.

<?xml version="1.0"?>
<config>

    <modules>
        <Adeel_Sarfraz>
            <version>1.0.0</version>
        </Adeel_Sarfraz>
    </modules>
	
	<global>
	
		<helpers>
			<sarfraz>
				<class>Adeel_Sarfraz_Helper</class>
			</sarfraz>
		</helpers>

        <models>
            <sarfraz>
                <class>Adeel_Sarfraz_Model</class>
                <resourceModel>sarfraz_mysql4</resourceModel>
            </sarfraz>
            <sarfraz_mysql4>
                <class>Adeel_Sarfraz_Model_Mysql4</class>
                <entities>
                    <sarfraz>
                        <table>sarfraz</table>
                    </sarfraz>
                </entities>
            </sarfraz_mysql4>
        </models>		
		
		<blocks>
			<sarfraz>
				<class>Adeel_Sarfraz_Block</class>
			</sarfraz>
		</blocks>		
	
	</global>	
	
    <admin>
        <routers>
            <asarfraz>
                <use>admin</use>
                <args>
                    <module>Adeel_Sarfraz</module>
                    <frontName>asarfraz</frontName>
                </args>
            </asarfraz>
        </routers>
    </admin>
	
    <adminhtml>
        <menu>
            <customer>
                <children>
                    <list translate="title" module="sarfraz">
                        <title>Admin Title</title>
                        <sort_order>11</sort_order>
			<action>asarfraz/controller_list/index</action>
                    </list>
                </children>
            </customer>
        </menu>
    </adminhtml>
	
</config>

1. Now add the following folders and files in the Block folder.

Adminhtml
Adminhtml/Items
Adminhtml/Items.php
Adminhtml/Items/Grid.php

Open the Block/Adminhtml/Items.php and add the following PHP code to it.

<?php
class Adeel_Sarfraz_Block_Adminhtml_Items extends Mage_Adminhtml_Block_Widget_Grid_Container
{
    public function __construct()
    {
        $this->_controller = 'adminhtml_items';
        $this->_blockGroup = 'sarfraz';		
        $this->_headerText = Mage::helper('sarfraz')->__('Admin Title');
        parent::__construct();				
        $this->_removeButton('add');		
    }
}

Next open the Block/Adminhtml/Items/Grid.php and add the following PHP code to it.

<?php
class Adeel_Sarfraz_Block_Adminhtml_Items_Grid extends Mage_Adminhtml_Block_Widget_Grid
{	
    public function __construct()
    {
		
        parent::__construct();
        $this->setId('itemsGrid');
        $this->setDefaultSort('id');
		$this->setDefaultDir('DESC');		
    }
 
    protected function _prepareCollection()
    {
        $collection = Mage::getModel('sarfraz/sarfraz')->getCollection();
        $this->setCollection($collection);
        return parent::_prepareCollection();
    }
 
    protected function _prepareColumns()
    {
        $this->addColumn('id', array(
            'header' => Mage::helper('sarfraz')->__('ID'),
            'sortable' => true,
            'width' => '60',
            'index' => 'id'
        ));
 
        $this->addColumn('first_name', array(
            'header' => Mage::helper('sarfraz')->__('Full Name'),
            'sortable' => true,
            'width' => '60',
            'index' => 'first_name',
            'type'  => 'text'
        ));
 
        $this->addColumn('cus_email', array(
            'header' => Mage::helper('sarfraz')->__('Email Address'),
            'sortable' => true,
            'width' => '60',
            'index' => 'cus_email',
            'type'  => 'text'
        ));

		$this->addColumn('telephone', array(
            'header' => Mage::helper('sarfraz')->__('Answer'),
            'sortable' => true,
            'width' => '60',
            'index' => 'cus_telephone',
            'type'  => 'text'
        ));				

		return parent::_prepareColumns();
    }
 
}

2. Add the following folder and file to the controllers folder

Controller
Controller/ListController.php

Open the controllers/Controller/ListController.php file and add the following PHP code

<?php
class Adeel_Sarfraz_Controller_ListController extends Mage_Adminhtml_Controller_Action
{
    public function indexAction()
    { 
        $this->loadLayout()->_setActiveMenu('customers');
        $myblock = $this->_addContent($this->getLayout()->createBlock('sarfraz/adminhtml_items'));
        $this->renderLayout($myblock);
    }
}

3. Create the following file in the Helper folder.

Data.php

Add the following PHP code to Data.php file

<?php
class Adeel_Sarfraz_Helper_Data extends Mage_Core_Helper_Abstract
{

}

4. Add the following files and folders to the Model folder

Mysql4
Sarfraz.php
Mysql4/Sarfraz
Mysql4/Sarfraz.php
Mysql4/Sarfraz/Collection.php

Open the Model/Sarfraz.php file and add the following code

<?php
class Adeel_Sarfraz_Model_Sarfraz extends Mage_Core_Model_Abstract
{
    public function _construct()
    {
       parent::_construct();
       $this->_init('sarfraz/sarfraz');
    }
}

Then open the Model/Mysql4/Sarfraz.php file and add the following code

<?php
class Adeel_Sarfraz_Model_Mysql4_Sarfraz extends Mage_Core_Model_Mysql4_Abstract
{
    public function _construct()
    {   
        $this->_init('sarfraz/sarfraz', 'id');
    }
}

Finally open the Model/Mysql4/Sarfraz/Collection.php and add the code below

<?php
class Adeel_Sarfraz_Model_Mysql4_Sarfraz_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
{
    public function _construct()
    {
	parent::_construct();
        $this->_init('sarfraz/sarfraz');
    }
}

After adding the code changes above please clear the Magento cache and your module should come up under the customers menu by the name of “Admin Title”. If it does’t then logout and relogin into the Magento admin panel. You can change the “Admin Title” to some thing more meaningful by editing the etc/config.xml file.

If the above is too much time consuming for you then you can contact me and I will provide you the files in zip format.

If you have any feedback then please share by commenting.

Script to check for malware on your website

After seeing a couple of websites getting infected by malware I decided on creating a script  which would inform the owner and the concerned technical staff at the slightest change in the website file system structure.

The script does the following

1. Detects change in any script/file.
2. Notifies when a new script/file is added.
3. Creates a zip backup of the website so you can restore your website at any time.
4. Displays source of the script/file.

Following snap shot displays the file path, modified date/time and the row is highlighted if the modified date/time is less than 1 day.

File Scan Results

Following snap shot displays the source code for each file so that you know if any modifications have been made or not to the file.

File Scan Source

I have tested this script on both Linux and Windows and it has not given any issues. I have ran this on Zen Cart, WordPress, custom PHP websites and the results are promising. This should work equally well on other installations so if you would like access to this script then please let me know.

How to customize your Zend Form fields to appear in columns

I received a requirement to change the form layout on a web page. I was not using any decorators on the form so the form was coming up in default format generated by Zend Form.

This is the page which displays the form when some one clicks on Edit

Once you click on Edit the form appears like so

Zend Form default layout without decorators

I had to show the fields in 4 columns so that the layout remains consistent with what was shown to the member before clicking on the Edit link.

I opened the form file (in application/forms directory) and added the following code to the file at the bottom after all the elements had been added to the form.

$this->addDisplayGroups(array(
			'left_fields' => array(
			'elements' => array($email, $firstname, $lastname, $company, $address1, $address2),
			),
		        'right_fields' => array(
			'elements' => array($city, $state, $postcode, $country, $phonenumber),
			),
			'bottom_field' => array(
			'elements' => array($cancel, $submit),
			)
		));		

$this->setDisplayGroupDecorators(array('Description', 'FormElements', 'Fieldset'));

I used the Zend Form addDisplayGroups method to group the fields in three separate groups (left_fields, right_fields, bottom_field) so that Zend Form generates the HTML fieldset element which encloses the form elements.

After adding the above code and running the script you will find no difference except when you do a View Source of the page you will see that 3 HTML fieldsset elements have been generated. Now you can tweak your CSS to align the form elements as you want.

I added the following code in the CSS file.

form fieldset#fieldset-left_fields, form fieldset#fieldset-right_fields
{
    float: left;
    width: 50%;
    border: none;
}

Now when I ran the script I got the desired results and the form fields were formatted in the layout I wanted.

This is how the page looked after adding the above code.

Zend Form new layout using decorators

Hope the above helped!

How to resolve the Zen Cart Illegal mix of collations error

We had deployed a Zen Cart website and we came up with the following error in the Zen Cart admin panel when clicking on the Tools -> Send Email link.

Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_general_ci,IMPLICIT) for operation 'locate'

After checking the table collation in PHPmyAdmin I found that the subscribers table (created when the Newsletter Subscribe module was installed) collation was different to the configuration table.

Most people on the internet advised that the collation for the subscribers table and email_address field should be changed to that of the remaining tables in the database. I tried to change the collation of the subscribers table and the email_address field to that of the configuration table but met with no success.

I then changed it to ‘utf8_unicode_ci‘ and the page displayed without any problem or error.

The exact SQL I ran in mySQL was

ALTER TABLE subscribers CHANGE email_address email_address varchar( 96 ) NOT NULL default '' UNIQUE COLLATE 'utf8_unicode_ci';
ALTER TABLE customers COLLATE 'utf8_unicode_ci';
ALTER TABLE subscribers COLLATE 'utf8_unicode_ci';
ALTER TABLE customers CHANGE customers_email_address customers_email_address varchar( 96 ) NOT NULL default '' UNIQUE COLLATE 'utf8_unicode_ci';

The first statement in the SQL above is thanks to DrByte.

Hope the above helped someone.

Must have htaccess file for every website

I have come across some client websites which do not have the proper rules in place and due to this their websites are exposed to attacks from hackers. I have put together a basic htaccess file what each website must have from security and SEO point of view. Of course this may not be suitable for every website as each one may have it’s own specific requirements however the one below will get the basic job done.

You are welcome to provide further additions to the one below.

# Disallows directory browsing
Options -Indexes

Options +FollowSymLinks

# Telling Apache which page to render when some one browses the home page
DirectoryIndex index.php

# Telling Apache where to send the visitor upon a 404 page
ErrorDocument 404 /404.php

RewriteEngine On
RewriteBase /

# Disallows htaccess to visitors
RewriteRule ^\.htaccess$ - [F]

# Redirects non-WWW URLs to www URLs
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

How to offer discounts and coupons to customers using Facebook Like

I have come across some businesses offering discounts, offers, video downloads, documents etc. to users on Facebook and in return they ask them to simply Like their page. This is quite a good idea as it helps them to attract leads/sales from Facebook and it serves as an additional revenue generation model apart from search engines.

Take for example the following application on Facebook for a UK based retailer

http://www.facebook.com/babyboom2000uk/app_201143516562748

They are offering discounts to Facebook users who Like the above URL. Once you click on
the Like button on the top right the page will display the discount code which customers
can then use to get discount on their purchase.

I was fascinated by this and was curious to know more about how they were doing it as
store owners would definitely benefit from this. I set about creating an application and
after it was done I tried using the FB.Event.subscribe method which was being advocated
by everyone to use to track the click event on the Like button. Though they were correct,
this was working only when the Like button was embedded on the actual page but was not
working in the above case.

I then tried to check whether any thing was being passed to my application from Facebook
and sure enough a signed_request variable was being sent but it was sending a long
alphanumeric string. I sensed that this was encrypted so I Googled and found a method to
decrypt the string.

$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2); 
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);

When I dumped the $data variable it printed out the complete array and displayed it as follows:

Array
(
    [algorithm] => HMAC-SHA256
    [issued_at] => 1353404943
    [page] => Array
        (
            [id] => 
            [liked] => 
            [admin] => 
        )

    [user] => Array
        (
            [country] => pk
            [locale] => en_US
            [age] => Array
                (
                    [min] => 0
                    [max] => 12
                )

        )

)

From above we can check for the value returned in $data[‘page’][‘liked’]. If it’s 1 then
the page is liked by the user other wise the page is not liked.

In this way you can display two different pages to the Facebook user depending on their
response.

Hopefully this would have helped any one facing problem while implementing this.

Please contact me if you still face any issues and I will try my best to help you.

List of test credit card numbers for Sage Pay

If you are using Sage Pay Form and wish to test whether the integration is working correctly or not you can use the following test credit card numbers for placing orders.

Visa (VISA)
4929000000006

MasterCard (MC)
5404000000000001

Visa Debit / Delta (DELTA)
4462000000000003

Solo (SOLO)
6334900000000005
Issue 1

UK Maestro / International Maestro (MAESTRO)
5641820000000005
Issue 01

American Express (AMEX)
374200000000004

Visa Electron (UKE)
4917300000000008

Please enter a future credit card expiry date.

Integrate Zen Cart store to eBay with eBay Zen Cart module

Store owners who use Zen Cart for running their stores on the web can now enjoy the luxury of listing, revising and de-listing products on eBay all from their Zen Cart admin panel. Gone are the days when you needed to add products twice (one in each Zen Cart and eBay) and then constantly worry that you do not oversell an item on eBay if the stock inventory has exhausted for that product.

In short, you will need to list your products once and earn forever*.

This facility is tried and tested and running in production environments on Zen Cart stores based in the USA and UK and clients have been more than happy with the results.

You will be able to do the following when you use this module

1. List/revise/delist items on eBay from your Zen Cart admin panel.
2. Maintain separate product title, product price and product description fields for your products on eBay in your Zen Cart Add/Edit product page.
3. Automatic download of orders from eBay to your Zen Cart orders listing page.
4. Automatic creation of customer accounts on your Zen Cart website as soon as order is downloaded from eBay.
5. Automatic synchronization of product stock and price on your eBay store with the price in your Zen Cart store.

Please see attached snap shot for more detail

List/revise/delist items on eBay from your Zen Cart admin panel

eBay order downloaded to your Zen Cart orders listing page

If you would like to have more information regarding this then please contact me today and I will be more than happy to help you out.

* As long as you have inventory for that product -:)

Recursion example using PHP

Recursion is a data structure by which a function is called several times till the condition which calls the function becomes true. I have seldom used it while coding but I would like to show you one particular instance where I used it to display a category level structure in a drop down.

First you need to create the table in mySQL. I have named the table as categories for the purpose of this example. You can name it anything you like.

CREATE TABLE `categories` (
`categories_id` int(11) NOT NULL auto_increment,
`categories_name` varchar(64) default NULL,
`parent_id` int(11) NOT NULL default '0',
PRIMARY KEY (`categories_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

 

After that run the following INSERT queries which will create some sample data for this table

insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (65,'Top Level 1',0);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (66,'Top Level 2',0);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (67,'Sub Level 1-1',65);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (68,'Sub Level 2-1',66);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (69,'Sub Level 2-2',66);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (70,'Top Level 3',0);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (71,'Sub Level 3-1',70);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (72,'Top Level 4',0);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (73,'Top Level 5',0);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (74,'Sub Level 2-3',66);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (75,'Sub Level 3-1-1',71);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (76,'Sub Level 2-2-1',69);
insert into `categories` (`categories_id`,`categories_name`,`parent_id`) values (77,'Sub Level 2-2-1-1',76);

Finally you need to create a PHP script and enter the following bit of code to it.

<?php
// open the database connection

function get_rec($parent, $strCategory) {
$sql = "select * from categories where parent_id = ". $parent;
$rs1 = mysql_query($sql) or die(mysql_error());
$num1 = mysql_num_rows($rs1);

if ($num1 != 0) {
while ($data1 = mysql_fetch_object($rs1)) {
$strTempCategory = $strCategory ." -> " . $data1->categories_name;
echo "<option value=". $data1->categories_id .">". $strTempCategory ."</option>";
if (get_rec($data1->categories_id, $strTempCategory) == "") {
}
}
}
else {
return "";
}
}
?>
<select name="cboCategory" size="1">
<option value="0">Select</option>
<?php
$sql_cat="select * from categories where parent_id = 0 order by categories_name asc";
$result_cat = mysql_query($sql_cat) or die (mysql_error());
while ($data_cat = mysql_fetch_object($result_cat)) {
echo "<option value='".$data_cat->categories_id."'>".$data_cat->categories_name ."</option>";
echo get_rec($data_cat->categories_id, $data_cat->categories_name);
}
?>
</select>

Save the PHP file and run it. You should be able to view a drop down on the web page which will show the data you have just inserted in a tree view.

For ease I have provided the complete PHP code as well as the SQL file which you can then run and test on your computer.

Download the PHP Recursion Example by Adeel Sarfraz