Mar 22

php — how to check if js enabled in the client

PHP is running in the server side,so it has no access to the client’s browser.how to check if the the javascript status of the client’s browser?Technically no way but we may get some way to work out.

setting cookies with JS and detecting them from PHP, see the example code below:

Source code    
<?
if($_SESSION['JSexe']){     //3rd check js
    if($_COOKIE['JS'])  setcookie('JS','JS',time()-1);//check on every page load
    else            header('Location: js.html');
}               //2nd so far it's been server-side scripting. Client-side scripting must be executed once to set second cookie.
                //Without JSexe, user with cookies and js enabled would be sent to js.html the first page load.
elseif($_COOKIE['PHP'])     $_SESSION['JSexe'] = true;
else{               //1st check cookies
    if($_GET['cookie']) header('Location: cookies.html');
    else{
                setcookie('PHP','PHP');
                header('Location: '.$_SERVER['REQUEST_URI'].'?cookie=1');
    }
}
?>
<head>
<script type="text/javascript">document.cookie = 'JS=JS'</script>
</head>

 

FYI:

http://asdlog.com/Check_if_cookies_and_javascript_are_enabled

http://stackoverflow.com/questions/4454551/check-if-javascript-is-enabled-with-php

 

 

Posted in php
Dec 06

linux — How to extract specified file/directory from a tar ball

well,you got a big tar ball file,but in fact you only need some special file or directory.Then you don’t want to extract  all files from the tar ball if it’s a big file.so how to get specified file or directory from a tar ball?

tar command allows to extract a single file or directory using the following format. It works under UNIX, Linux, and BSD operating systems.

tar xvf big.tar filename
tar -zxvf abc.tar.gz directory-name
tar -zxvf abc.tar.gz path/to/directory-name -C /tmp

Keep in mind that both the filename and directory-name should be existed in the tar ball file,and the path is relative to the tar ball root.

Nov 04

open cart — how to create a payment module for open cart

To be honestly, this is my first module for open cart. I know about open cart years ago(2009),but never study in deep.The installation of open cart is straightforward.After some minutes of playing around open cart frontend and admin backend, i decided to start work.

To create a payment module for open cart,first,we need to create all files for a open cart payment module.As we know,open cart was developed in MVC pattern,so all modules will include a model class,controller class and file for View,detail as below
[the name of the new payment module is callled moneybrace]
catalog/controller/payment/moneybrace.php (Controller class)
catalog/model/payment/moneybrace.php  (Model class)
catalog/language/english/payment/moneybrace.php (Language file for View)
catalog/view/theme/default/template/payment/moneybrace.tpl (Template file for View)
admin/controller/payment/moneybrace.php
admin/language/english/payment/moneybrace.php
admin/view/template/payment/moneybrace.php

It was obviously,all files located under catalog folder is for frontend use,all the others will be called in the admin backend page.

Keep in mind that you must follow the folder structure as the one above.And you’d better put template file in the default theme folder.You would not like to copy and paste file when you change the theme.

Now let’s do some coding work.Let’s start from implementing the payment’s bakend config page.For the Controller class,it should looks like below:
[admin/controller/payment/moneybrace.php]

Source code    
class ControllerPaymentMoneybrace extends Controller {
	private $error = array();
 
	public function index() {
 
	}
	private function validate() {
	}
}

 

The classname must start with ControllerPayment and should be a subclass of Controller.It's very simple,you only need to implement two method: index() and validate() .open cart will help you deal with all the other details.

Below is the language file which stores all lables for all form elements which were used to config the payment module:
[admin/language/english/payment/moneybrace.php]

Source code    
<?php
// Heading
$_['heading_title']			= 'Moneybrace';
 
// Text
$_['text_payment']			= 'Payment';
$_['text_success']			= 'Success: You have modified Moneybraces!';
$_['text_moneybrace']			= '<a onclick="window.open(\'http://www.moneybrace.com/\');"><img src="http://www.moneybrace.com/templets/default/images/logo.jpg" style="border: 1px solid #EEEEEE;" /></a>';
 
// Entry
$_['entry_merchantacct']		= 'Merchant Account:';
$_['entry_cert']			= 'Merchant Certificate:';
$_['entry_debug']			= 'Debug Mode:<br/><span class="help">Logs additional information to the system log.</span>';
$_['entry_completed_status']      = 'Completed Status:';
$_['entry_pending_status']		= 'Pending Status:';
$_['entry_processed_status']		= 'Processed Status:';
$_['entry_geo_zone']			= 'Geo Zone:';
$_['entry_status']			= 'Status:';
$_['entry_sort_order']			= 'Sort Order:';
 
// Error
$_['error_permission']			= 'Warning: You do not have permission to modify payment Moneybrace!';
$_['error_merchantacct']		= 'Merchant Account required!';
$_['error_cert']			= 'Merchant certificates required!';
?>

 

you need to pay some more attention for the third file,this is where you defined  related configure parameter which will be shown on backend config page. All the configure parameter will be insert into the setting table of the open cart database.The name of the input will be used as config key.You'd better start all key name with same prefix,here i use moneybrace,which is the name of the payment gateway.
[admin/view/template/payment/moneybrace.php]

Source code    
<?php echo $header; ?>
<div id="content">
  <div class="breadcrumb">
    <?php foreach ($breadcrumbs as $breadcrumb) { ?>
    <?php echo $breadcrumb['separator']; ?><a href="<?php echo $breadcrumb['href']; ?>"><?php echo $breadcrumb['text']; ?></a>
    <?php } ?>
  </div>
  <?php if ($error_warning) { ?>
  <div class="warning"><?php echo $error_warning; ?></div>
  <?php } ?>
  <div class="box">
    <div class="heading">
      <h1><img src="view/image/payment.png" alt="" /> <?php echo $heading_title; ?></h1>
      <div class="buttons"><a onclick="$('#form').submit();" class="button"><?php echo $button_save; ?></a><a onclick="location = '<?php echo $cancel; ?>';" class="button"><?php echo $button_cancel; ?></a></div>
    </div>
    <div class="content">
      <form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form">
        <table class="form">
          <tr>
            <td><span class="required">*</span> <?php echo $entry_merchantacct; ?></td>
            <td><input type="text" name="moneybrace_merchantacct" value="<?php echo $moneybrace_merchantacct; ?>" />
              <?php if ($error_merchantacct) { ?>
              <span class="error"><?php echo $error_merchantacct; ?></span>
              <?php } ?></td>
          </tr>
          <tr>
            <td><span class="required">*</span> <?php echo $entry_cert; ?></td>
            <td><input type="text" name="moneybrace_cert" value="<?php echo $moneybrace_cert; ?>" />
              <?php if ($error_cert) { ?>
              <span class="error"><?php echo $error_cert; ?></span>
              <?php } ?></td>
          </tr>
          <tr>
            <td><?php echo $entry_debug; ?></td>
            <td><select name="moneybrace_debug">
                <?php if ($moneybrace_debug) { ?>
                <option value="1" selected="selected"><?php echo $text_enabled; ?></option>
                <option value="0"><?php echo $text_disabled; ?></option>
                <?php } else { ?>
                <option value="1"><?php echo $text_enabled; ?></option>
                <option value="0" selected="selected"><?php echo $text_disabled; ?></option>
                <?php } ?>
              </select></td>
          </tr>zz
          <tr>
            <td><?php echo $entry_pending_status; ?></td>
            <td><select name="moneybrace_pending_status_id">
                <?php foreach ($order_statuses as $order_status) { ?>
                <?php if ($order_status['order_status_id'] == $moneybrace_pending_status_id) { ?>
                <option value="<?php echo $order_status['order_status_id']; ?>" selected="selected"><?php echo $order_status['name']; ?></option>
                <?php } else { ?>
                <option value="<?php echo $order_status['order_status_id']; ?>"><?php echo $order_status['name']; ?></option>
                <?php } ?>
                <?php } ?>
              </select></td>
          </tr>
          <tr>
            <td><?php echo $entry_processed_status; ?></td>
            <td><select name="moneybrace_processed_status_id">
                <?php foreach ($order_statuses as $order_status) { ?>
                <?php if ($order_status['order_status_id'] == $moneybrace_processed_status_id) { ?>
                <option value="<?php echo $order_status['order_status_id']; ?>" selected="selected"><?php echo $order_status['name']; ?></option>
                <?php } else { ?>
                <option value="<?php echo $order_status['order_status_id']; ?>"><?php echo $order_status['name']; ?></option>
                <?php } ?>
                <?php } ?>
              </select></td>
          </tr>
          <tr>
            <td><?php echo $entry_geo_zone; ?></td>
            <td><select name="moneybrace_geo_zone_id">
                <option value="0"><?php echo $text_all_zones; ?></option>
                <?php foreach ($geo_zones as $geo_zone) { ?>
                <?php if ($geo_zone['geo_zone_id'] == $moneybrace_geo_zone_id) { ?>
                <option value="<?php echo $geo_zone['geo_zone_id']; ?>" selected="selected"><?php echo $geo_zone['name']; ?></option>
                <?php } else { ?>
                <option value="<?php echo $geo_zone['geo_zone_id']; ?>"><?php echo $geo_zone['name']; ?></option>
                <?php } ?>
                <?php } ?>
              </select></td>
          </tr>
          <tr>
            <td><?php echo $entry_status; ?></td>
            <td><select name="moneybrace_status">
                <?php if ($moneybrace_status) { ?>
                <option value="1" selected="selected"><?php echo $text_enabled; ?></option>
                <option value="0"><?php echo $text_disabled; ?></option>
                <?php } else { ?>
                <option value="1"><?php echo $text_enabled; ?></option>
                <option value="0" selected="selected"><?php echo $text_disabled; ?></option>
                <?php } ?>
              </select></td>
          </tr>
          <tr>
            <td><?php echo $entry_sort_order; ?></td>
            <td><input type="text" name="moneybrace_sort_order" value="<?php echo $moneybrace_sort_order; ?>" size="1" /></td>
          </tr>
        </table>
      </form>
    </div>
  </div>
</div>
<?php echo $footer; ?>

This file define the following config parameter for the moneybrace open cart payment module:

Source code    
moneybrace_merchantacct
moneybrace_cert
moneybrace_debug
moneybrace_pending_status_id
moneybrace_processed_status_id
moneybrace_geo_zone_id
moneybrace_status
moneybrace_sort_order

By now we had finished all development for the payment backend configure page. let's move forward to develop the main logic the payment module will do -- generating a form with all the payment infomation.
Below is the controller class.Make sure the class name start with ControllerPayment,and it must have  an index method to init all form element value. The class also define a callback() method, which will be used to receive and process payment result. You can name it  whatever you like,but you should told the payment gateway the correct method to call when payment is done.
[catalog/controller/payment/moneybrace.php]

Source code    
<?php
/* Moneybrace online payment
 *
 * @version 1.0
 * @date 11/03/2012
 * @author george zheng <xinhaozheng@gmail.com>
 * @more info available on mzcart.com
 */
class ControllerPaymentMoneybrace extends Controller {
	protected function index() {
		$this->language->load('payment/moneybrace');
 
		$this->data['button_confirm'] = $this->language->get('button_confirm');
 
		$this->data['action'] = 'https://payment.moneybrace.com/payment/paypage.aspx';
 
		$this->load->model('checkout/order');
 
		$order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);
 
		if ($order_info) {
		    $this->data['merchantid'] = trim($this->config->get('moneybrace_merchantacct'));
			$this->data['encoding'] = 'utf-8';
			$this->data['transtype'] = 'IC';
			$this->data['version'] = '1.0.0';
			$this->data['orderid'] = date('His') . $this->session->data['order_id'];
 
			switch($this->session->data['language']) {
				case 'de':
					 $this->data['language'] = 'de-de';
					 break;
				case 'fr':
					 $this->data['language'] = 'fr-fr';
					 break;
				case 'it':
					 $this->data['language'] = 'it-it';
					 break;
				case 'es':
					 $this->data['language'] = 'es-es';
					 break;
				case 'pt':
					 $this->data['language'] = 'pt-pt';
					 break;
				case 'jp':
					 $this->data['language'] = 'ja-jp';
					 break;
				default:
					 $this->data['language'] = 'en-us';
		    }
			$this->data['callbackurl'] = $this->url->link('payment/moneybrace/callback');
			$this->data['browserbackurl'] = $this->url->link('checkout/success');
			$this->data['accessurl'] = 'https://payment.moneybrace.coms';
			$this->data['orderdate'] = date('YmdHis');
			$this->data['currency'] = $order_info['currency_code'];
            $allowed_cur = array('USD', 'EUR', 'GBP', 'CAD', 'AUD', 'JPY');
			$currency = $_SESSION['currency'];
			if ( !in_array($currency, $allowed_cur)) {
				$currency = 'USD';
			}
 
			$this->data['orderamount'] = $this->currency->format($order_info['total'], $currency , false, false);
 
			$this->data['first_name'] = html_entity_decode($order_info['payment_firstname'], ENT_QUOTES, 'UTF-8');
			$this->data['last_name'] = html_entity_decode($order_info['payment_lastname'], ENT_QUOTES, 'UTF-8');
 
			$this->data['billemail'] = $order_info['email'];
			$this->data['billphone'] = html_entity_decode($order_info['telephone'], ENT_QUOTES, 'UTF-8');
			$this->data['billaddress'] = html_entity_decode($order_info['payment_address_1'], ENT_QUOTES, 'UTF-8');
			$this->data['billcountry'] = html_entity_decode($order_info['payment_iso_code_2'], ENT_QUOTES, 'UTF-8');
			$this->data['billprovince'] = html_entity_decode($order_info['payment_zone'], ENT_QUOTES, 'UTF-8');;
			$this->data['billcity'] = html_entity_decode($order_info['payment_city'], ENT_QUOTES, 'UTF-8');
			$this->data['billpost'] = html_entity_decode($order_info['payment_postcode'], ENT_QUOTES, 'UTF-8');
 
			$this->data['deliveryname'] = html_entity_decode($order_info['shipping_firstname'] . $order_info['shipping_lastname'], ENT_QUOTES, 'UTF-8');
			$this->data['deliveryaddress'] = html_entity_decode($order_info['shipping_address_1'], ENT_QUOTES, 'UTF-8');
			$this->data['deliverycity'] = html_entity_decode($order_info['shipping_city'], ENT_QUOTES, 'UTF-8');
			$this->data['deliverycountry'] = html_entity_decode($order_info['shipping_iso_code_2'], ENT_QUOTES, 'UTF-8');
			$this->data['deliveryprovince'] = html_entity_decode($order_info['shipping_zone'], ENT_QUOTES, 'UTF-8');
			$this->data['deliveryemail'] = $order_info['email'];
			$this->data['deliveryphone'] = html_entity_decode($order_info['telephone'], ENT_QUOTES, 'UTF-8');
			$this->data['deliverypost'] = html_entity_decode($order_info['shipping_postcode'], ENT_QUOTES, 'UTF-8');
 
			$strProducts = '';
			$htmlProducts = '';
			foreach ($this->cart->getProducts() as $product) {
			    $pname = trim(str_replace('"', '', $product['name']));
 
			    if ( $pname == '' && $strProducts == '' && $htmlProducts = '') {
				    $pname = 'Order ' . $this->data['orderid'];
					$psn = $this->data['orderid'];
					$qty = 1;
					$price = $this->currency->format($product['price'], $currency, false, false);
				    $strProducts = 'Order ' . $this->data['orderid'] . '1';
					$htmlProducts = '<input name="productname1" value="" ' . $pname . ' />' .
									'<input name="productsn1" value="" ' . $psn . '/>' .
									'<input name="quantity1" value="" ' . $qty . ' />' .
									'<input name="unit1" value="" ' . $price . '/>' ;
					break;
				}
 
				$psn = $product['model'];
				$qty = $product['quantity'];
				$price = $this->currency->format($product['price'], $currency, false, false);
 
				$strProducts =  $pname . $psn . $qty . $price;
				$htmlProducts = '<input type="hidden" name="productname1" value="' . $pname . '" />' .
								'<input type="hidden" name="productsn1" value="' . $psn . '" />' .
								'<input type="hidden" name="quantity1" value="' . $qty . '" />' .
								'<input type="hidden" name="unit1" value="' . $price . '"/>' ;
 
			}
			$this->data['htmlProducts'] = $htmlProducts;
 
			$cert = $this->config->get('moneybrace_cert');
 
			$strSource =$cert . $this->data['version'] . $this->data['encoding'] . $this->data['language'] . $this->data['merchantid'] .
			$this->data['orderid'] . $this->data['orderdate'] . $this->data['currency'] . $this->data['orderamount'] . $this->data['transtype'] .
			$this->data['callbackurl'] . $this->data['browserbackurl'] . $this->data['accessurl'] .
            $strProducts .
			$this->data['billaddress'] . $this->data['billcountry'] . $this->data['billprovince'] . $this->data['billcity'] .
			$this->data['billemail'] . $this->data['billphone'] . $this->data['billpost'] .
			$this->data['deliveryname'] . $this->data['deliveryaddress'] . $this->data['deliverycountry'] . $this->data['deliveryprovince'] .
			$this->data['deliverycity'] . $this->data['deliveryemail'] . $this->data['deliveryphone'] . $this->data['deliverypost'];
            if ($this->config->get('moneybrace_debug')) {
				$this->log->write('Submit source string:' . $strSource);
			}
			$signature = md5($strSource);
			$this->data['signature'] = $signature;
 
			if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/payment/moneybrace.tpl')) {
				$this->template = $this->config->get('config_template') . '/template/payment/moneybrace.tpl';
			} else {
				$this->template = 'default/template/payment/moneybrace.tpl';
			}
 
			$this->render();
		}
	}
 
	public function callback() {
		if (isset($this->request->post['orderid'])) {
			$order_id = trim(substr(($this->request->post['orderid']), 6));
		} else {
			die('Illegal Access');
		}
 
		$this->load->model('checkout/order');
 
		$order_info = $this->model_checkout_order->getOrder($order_id);
 
		if ($order_info) {
		    $data = array_merge($this->request->post,$this->request->get);
			foreach ($data as $key => $value) {
				${$k} = $value;
			}
 
			$product='';
			for($i=1;$i<=10;$i++) {
				if(!isset($data['productname'.$i]) || $data['productname'.$i] == '') {
					break;
				}
				$product = $product . $data['productname'.$i] . $data['productsn'.$i] . $data['quantity'.$i] . $data['unit'.$i];
			}
 
			$cert = $this->config->get('moneybrace_cert');
			$strSource = $cert . $version . $encoding . $lang . $merchantid . $transtype . $orderid .
            $orderdate . $currency. $orderamount . $paycurrency . $payamount .$remark1 . $remark2 .
            $remark3 .  $product . $shippingfee . $deliveryname . $deliveryaddress . $deliverycountry .$deliveryprovince.
            $deliverycity . $deliveryemail . $deliveryphone . $deliverypost . $transid . $transdate . $status;
 
			if ($this->config->get('moneybrace_debug')) {
				$this->log->write('Return source string:' . $strSource);
			}
 
			$getsignature=md5($strSource);
			if ( $getsignature != $signature) {
			    $order_status_id = $this->config->get('moneybrace_pending_status_id');
			    $this->model_checkout_order->confirm($order_id, $this->config->get('config_order_status_id'));
			    die('Data validate failed');
			}
 
			//payment was made succ
			if ($status == 'Y' || $status == 'y') {
			    $order_status_id = $this->config->get('moneybrace_processed_status_id');
				if (!$order_info['order_status_id'] || $order_info['order_status_id'] != $order_status_id) {
					$this->model_checkout_order->confirm($order_id, $order_status_id);
				} else {
					$this->model_checkout_order->update($order_id, $order_status_id);
				}
			}
		}
	}
}
?>

Let's take a look at the model class of the moneybrace payment module:
[catalog/model/payment/moneybrace.php]

Source code    
<?php
/* Moneybrace online payment
 *
 * @version 1.0
 * @date 11/03/2012
 * @author george zheng <xinhaozheng@gmail.com>
 * @more info available on mzcart.com
 */
class ModelPaymentMoneybrace extends Model {
  	public function getMethod($address, $total) {
		$this->load->language('payment/moneybrace');
 
		$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('moneybrace_geo_zone_id') . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')");
 
		if ($this->config->get('moneybrace_total') > $total) {
			$status = false;
		} elseif (!$this->config->get('moneybrace_geo_zone_id')) {
			$status = true;
		} elseif ($query->num_rows) {
			$status = true;
		} else {
			$status = false;
		}
 
		$currencies = array(
			'AUD',
			'CAD',
			'EUR',
			'GBP',
			'JPY',
			'USD',
			'NZD',
			'CHF',
			'HKD',
			'SGD',
			'SEK',
			'DKK',
			'PLN',
			'NOK',
			'HUF',
			'CZK',
			'ILS',
			'MXN',
			'MYR',
			'BRL',
			'PHP',
			'TWD',
			'THB',
			'CNY',
			'TRY'
		);
 
		if (!in_array(strtoupper($this->currency->getCode()), $currencies)) {
			$status = false;
		}
 
		$method_data = array();
 
		if ($status) {
      		$method_data = array(
        		'code'       => 'moneybrace',
        		'title'      => $this->language->get('text_title'),
				'sort_order' => $this->config->get('moneybrace_sort_order')
      		);
    	}
 
    	return $method_data;
  	}
}
?>

If you want to limit the payment module only available to some order over a preset amount,or limit the payment module only available to some countries,currency, you can implement the logic here in the getMethod() method of model class.
[catalog/language/english/payment/moneybrace.php]

Source code    
<?php
/* Moneybrace online payment
 *
 * @version 1.0
 * @date 11/03/2012
 * @author george zheng <xinhaozheng@gmail.com>
 * @more info available on mzcart.com
 */
// Text
$_['text_title']    = '<img src="http://moneybrace.com/pic/mblogo.gif" alt="Moneybrace" style="border:none" />';
$_['text_reason'] 	= 'REASON';
$_['text_total']	= 'Shipping, Handling, Discounts & Taxes';
?>

[catalog/view/theme/default/template/payment/moneybrace.tpl]

Source code    
<form action="<?php echo $action; ?>" method="post">
	<input type="hidden" name="merchantid" value="<?php echo $merchantid; ?>" />
	<input type="hidden" name="orderid" value="<?php echo $orderid; ?>" />
	<input type="hidden" name="encoding" value="<?php echo $encoding; ?>" />
	<input type="hidden"  name="transtype" value="<?php echo $transtype; ?>" />
	<input type="hidden" name="language" value="<?php echo $language; ?>" />
	<input type="hidden" name="callbackurl" value="<?php echo $callbackurl; ?>" />
	<input type="hidden" name="browserbackurl" value="<?php echo $browserbackurl; ?>" />
	<input type="hidden" name="accessurl" value="<?php echo $accessurl; ?>" />
	<input type="hidden" name="orderdate" value="<?php echo $orderdate; ?>" />
	<input type="hidden" name="currency" value="<?php echo $currency; ?>" />
	<input type="hidden" name="orderamount" value="<?php echo $orderamount; ?>" />
    <?php echo $htmlProducts; ?>
	<input type="hidden" name="version" value="<?php echo $version; ?>" />
	<input type="hidden" name="billemail" value="<?php echo $billemail; ?>" />
	<input type="hidden" name="billphone" value="<?php echo $billphone; ?>" />
	<input type="hidden" name="billaddress" value="<?php echo $billaddress; ?>" />
	<input type="hidden" name="billcountry" value="<?php echo $billcountry; ?>" />
	<input type="hidden" name="billprovince" value="<?php echo $billprovince; ?>" />
	<input type="hidden" name="billcity" value="<?php echo $billcity; ?>" />
	<input type="hidden" name="billpost" value="<?php echo $billpost; ?>" />
	<input type="hidden" name="deliveryname" value="<?php echo $deliveryname; ?>" />
	<input type="hidden" name="deliveryaddress" value="<?php echo $deliveryaddress; ?>" />
	<input type="hidden" name="deliverycity" value="<?php echo $deliverycity; ?>" />
	<input type="hidden" name="deliverycountry" value="<?php echo $deliverycountry; ?>" />
	<input type="hidden" name="deliveryprovince" value="<?php echo $deliveryprovince; ?>" />
	<input type="hidden" name="deliveryemail" value="<?php echo $deliveryemail; ?>" />
	<input type="hidden" name="deliveryphone" value="<?php echo $deliveryphone; ?>" />
	<input type="hidden" name="deliverypost" value="<?php echo $deliverypost; ?>" />
	<input type="hidden" name="signature" value="<?php echo $signature; ?>" />
 
	<div class="buttons">
	<div class="right">
	    <input type="submit" value="<?php echo $button_confirm; ?>" class="button" />
	</div>
	</div>
</form>

 

 

Oct 31

mysql — Can’t connect to local MySQL server

All website in the server can not work. All of them throw out error message as below:
Can’t connect to local MySQL server

i tried to restart mysql server,but it can not be restarted.
well,i need to check the mysql log file.well,i got the problem:

14:03:00 [ERROR] /usr/sbin/mysqld: Disk is full writing ‘./mysql-bin.000047′ (Errcode: 28). Waiting for someone to free space… (Expect up to 60 secs delay for server to continue after freeing disk space)

Source code    
df -alh

i found that the /var partition is full,which is used to store mysql process file.so no new connection can be established. and you even cannot restart the mysql server.as restart mysql server also need to create process file in this partion

so the only thing to do is to free disk space, clean log file,remove uneeded backup file

Source code    
/etc/init.d/mysqld restart

 

 

 

Oct 29

mysql – Error in accept: Too many open files

One server is running both mysql and apache together,but the mysql get down every four hours.From PHP,it’s said ‘Error establshing a database connection’.From mysql error log,i got the some records like below:

’121029  2:47:38 [ERROR] Error in accept: Too many open files’

i know that mysql server has a config directive of open_files_limit which limit the number of file descripteors mysqld can use.so i need to check what the value in use for the current running mysqld server,from mysql client console,

Source code    
mysql -u root -p
>show global varaibles like 'open%'
>
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| open_files_limit | 1185  |

You can also check the config with following command:

Source code    
# netstat -atnp|grep 3306
tcp        0      0 0.0.0.0:3306                0.0.0.0:*                   LISTEN      5596/mysqld
 
# cat /proc/5596/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            10485760             unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             200704               200704               processes
Max open files            1185                 1185                 files
Max locked memory         32768                32768                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       200704               200704               signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0

so now we need to adjust mysql server configuration to make it feel comfortalbe.You decide the open_files_limit value by considering following factor:the databases amount, the max_connections and the table_cache value. You can also increase the number to a little higher you think is appropriate,then tune it by mysql server running status.

Source code    
# vim /etc/my.cnf
[mysqld]
open_files_limit = 3000
 
save to quit and then restart msyql server
#/etc/init.d/mysqld restart
Oct 25

hidden animated GIF images stop play in IE browser when submit form

I had met such a problem:

There is a form,a payment form to collect credit card info,below is the html code of the page.

Source code    
<form id="form1" action="PayPage.aspx" method="post">
    <input type="text" name="txtPost" value=""></td>
    <input type="text" name="txtEmail" value=""></td>
    <input type="submit" id="btnPay" onclick="return VerifyPage();" value="Submit" name="btnPay">
</form>

When click on the button to submit the form, we need to show a loading gif image to customer.  That means we are processing their request.Here is the js code below:

Source code    
function VerifyPage() {
    //do some validate
	//if all passed,show alert message box and the animated loading gif image
    sAlert("Connecting to bank......Please wait......<br/><img id='img123' alt='loading......' src='../resources/images/jindutiao.gif' />");
    return true;
}
 
function sAlert(str) {
    var msgw,msgh,bordercolor;
    msgw=400;
    msgh=100;
    titleheight=25;
    bordercolor= "#336699 ";
    titlecolor= "#99CCFF ";
    var sWidth,sHeight;
    sWidth=document.body.offsetWidth;
    sHeight=screen.height;
    var bgObj=document.createElement("div");
    bgObj.setAttribute('id','bgDiv');
    bgObj.style.position = "absolute";
    bgObj.style.display = "none";
    bgObj.style.top= "0";
    bgObj.style.background= "#777 ";
    bgObj.style.filter= "progid:DXImageTransform.Microsoft.Alpha(style=3,opacity=25,finishOpacity=75 ";
    bgObj.style.opacity= "0.6";
    bgObj.style.left= "0";
    bgObj.style.width=sWidth   +   "px";
    bgObj.style.height=sHeight   +   "px";
    bgObj.style.zIndex   =   "10000";
    document.body.appendChild(bgObj);
    var msgObj=document.createElement("div");
    msgObj.setAttribute("id", "msgDiv");
    msgObj.setAttribute("align", "center");
    msgObj.style.background= "white ";
    msgObj.style.border= "1px solid "   ;
    msgObj.style.position   =   "absolute";
    msgObj.style.left = "50%";
    msgObj.style.display = 'none';
    msgObj.style.top   =   "50%";
    msgObj.style.font= "14px/1.6em   Verdana,   Geneva,   Arial,   Helvetica,   sans-serif";
    msgObj.style.marginLeft   =   "-225px"   ;
    msgObj.style.marginTop   =   -75+document.documentElement.scrollTop+ "px";
    msgObj.style.width   =   msgw   +   "px";
    msgObj.style.height   =msgh   +   "px";
    msgObj.style.textAlign   =   "center";
    msgObj.style.lineHeight   = "60px";
    msgObj.style.zIndex   =   "10001";
    document.body.appendChild(msgObj);
    var txt=document.createElement("p");
    txt.style.margin= "1em   0"
    txt.setAttribute("id", "msgTxt");
    txt.innerHTML=str;
    document.getElementById("msgDiv").appendChild(txt);
}

This works fine in all major browsers except IE.When the user click the submit button, the message dialog show,but the animated loading image is frozen.This is another know bug in IE browsers.IE didn’t play any hidden animated image after submit event.

To get around this bug,you need to let IE browser to reaload the image in a timeout. That means you need to change the image elements src attribute every moments.

Source code    
function sAlert(str) {
    var msgw,msgh,bordercolor;
    msgw=400;
    msgh=100;
    titleheight=25;
    bordercolor= "#336699 ";
    titlecolor= "#99CCFF ";
    var sWidth,sHeight;
    sWidth=document.body.offsetWidth;
    sHeight=screen.height;
    var bgObj=document.createElement("div");
    bgObj.setAttribute('id','bgDiv');
    bgObj.style.position = "absolute";
    bgObj.style.display = "none";
    bgObj.style.top= "0";
    bgObj.style.background= "#777 ";
    bgObj.style.filter= "progid:DXImageTransform.Microsoft.Alpha(style=3,opacity=25,finishOpacity=75 ";
    bgObj.style.opacity= "0.6";
    bgObj.style.left= "0";
    bgObj.style.width=sWidth   +   "px";
    bgObj.style.height=sHeight   +   "px";
    bgObj.style.zIndex   =   "10000";
    document.body.appendChild(bgObj);
    var msgObj=document.createElement("div");
    msgObj.setAttribute("id", "msgDiv");
    msgObj.setAttribute("align", "center");
    msgObj.style.background= "white ";
    msgObj.style.border= "1px solid "   ;
    msgObj.style.position   =   "absolute";
    msgObj.style.left = "50%";
    msgObj.style.display = 'none';
    msgObj.style.top   =   "50%";
    msgObj.style.font= "14px/1.6em   Verdana,   Geneva,   Arial,   Helvetica,   sans-serif";
    msgObj.style.marginLeft   =   "-225px"   ;
    msgObj.style.marginTop   =   -75+document.documentElement.scrollTop+ "px";
    msgObj.style.width   =   msgw   +   "px";
    msgObj.style.height   =msgh   +   "px";
    msgObj.style.textAlign   =   "center";
    msgObj.style.lineHeight   = "60px";
    msgObj.style.zIndex   =   "10001";
    document.body.appendChild(msgObj);
    var txt=document.createElement("p");
    txt.style.margin= "1em   0"
    txt.setAttribute("id", "msgTxt");
    txt.innerHTML=str;
    document.getElementById("msgDiv").appendChild(txt);
 
    //added the following code to walk around IE BUG
    var imgurl = document.getElementById('img123').src;
    setTimeout(function() {
        document.getElementById('img123').src = imgurl;
    },200);
 
}
Oct 03

apache — let search engine fetch robots.txt based upon domain name

if you have a website with multiple domain(for some special reason),and you want google or other major search engine to fetch different robots.txt,how will you do?

first,get all ready prepared robots.txt and put them in the root folder of you website.you need to name it as robots.txt ,robots1.txt ,robots2.txt

second,create .htaccess file( if not existed)

third,add the following apache config command to the head of the file

Source code    
RewriteCond %{HTTP_HOST} abcdomain1\.com$ [NC]
RewriteRule robots.txt robots1.txt [L]
 
RewriteCond %{HTTP_HOST} abcdomain2\.com$ [NC]
RewriteRule robots.txt robots2.txt [L]
 
RewriteCond %{HTTP_HOST} abcdomain3\.com$ [NC]
RewriteRule robots.txt robots3.txt [L]
Sep 07

zen cart — all zen cart url with currency parameter will be redirected to home page

i just found that if any url in a zen cart store containing currency=value,then it will be redirected to zen cart website home page.For example,

http://www.abcdomain.com/xxxxxxxxxxx/xxxxxxxxx/?currency=EUR

This url will be redirected to http://www.abcdomain.com/,it’s a 302 redirect.

is this a zen cart bug?

From the code in this file:/includes/init_includes/init_currencies.php

Source code    
<?php
/**
 * initialise currencies
 * see {@link  http://www.zen-cart.com/wiki/index.php/Developers_API_Tutorials#InitSystem wikitutorials} for more details.
 *
 * @package initSystem
 * @copyright Copyright 2003-2007 Zen Cart Development Team
 * @copyright Portions Copyright 2003 osCommerce
 * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
 * @version $Id: init_currencies.php 6300 2007-05-11 15:49:41Z drbyte $
 */
if (!defined('IS_ADMIN_FLAG')) {
  die('Illegal Access');
}
 
// If no currency is set, use appropriate default
if (!isset($_SESSION['currency']) && !isset($_GET['currency']) ) $_SESSION['currency'] = DEFAULT_CURRENCY;
 
// Validate selected new currency, if any. Is false if valid not found.
$new_currency = (isset($_GET['currency'])) ? zen_currency_exists($_GET['currency']) : zen_currency_exists($_SESSION['currency']);
 
// Validate language-currency and default-currency if relevant. Is false if valid not found.
if ($new_currency == false || isset($_GET['language'])) $new_currency = (USE_DEFAULT_LANGUAGE_CURRENCY == 'true') ? zen_currency_exists(LANGUAGE_CURRENCY) : $new_currency;
 
// Final check -- if selected currency is bad and the "default" is bad, default to the first-found currency in order of exch rate.
if ($new_currency == false) $new_currency = zen_currency_exists(DEFAULT_CURRENCY, true);
//echo '<br />NEW = ' . $new_currency . '<br />';
 
// Now apply currency update
if (
   // Has new currency been selected?
  (isset($_GET['currency'])) ||
 
  // Does language change require currency update?
  (isset($_GET['language']) && USE_DEFAULT_LANGUAGE_CURRENCY == 'true' && LANGUAGE_CURRENCY != $_SESSION['currency']  )
 
) {
  $_SESSION['currency'] = $new_currency;
  // redraw the page without the currency/language info in the URL
  if (isset($_GET['currency']) || isset($_GET['language'])) zen_redirect(zen_href_link($current_page_base, zen_get_all_get_params(array('currency','language'))));
}
?>

the zen_redirect make this happen.

Aug 23

linux — how to exclude directory or files when bakup with rsync

rsync has been heavily used in server daily backup.I am not going to list all option of rsync. i just don’t want to backup some useless file such as cache and log file.

In a typical backup situation, you might want to exclude one or more files (or directories) from the backup. You might also want to exclude a specific file type from rsync.

To exclude a special directory,take a look at the command below:

Source code    
rsync -avze 'ssh -p7788' --exclude 'dir_abc'  /home/www  root@ip:/home/bak/

This command will not sync the /home/www/dir_abc

You can use * to match multiple directory to exclude like this:

Source code    
rsync -avze 'ssh -p7788' --exclude 'dir_*'  /home/www  root@ip:/home/bak/

You can also use multiple –exclude option to exclude:

Source code    
rsync -avze 'ssh -p7788' --exclude 'dir_abc' --exclude 'webcache' --exclude '*.log' /home/www  root@ip:/home/bak/

Keep in mind that rsync will always treat the value of the –exclude option as relative to the bakup dir even though you specified a absolute path,so

if there is a dir1 directory in /home/www

Source code    
rsync -avze --exclude '/home/www/dir1' /home/www /home/bak

rsync will explain /home/www/dir1 as /home/www/home/www/dir1,but this is not what you want.when you specified the path for –exclude option,make sure it’s relative to the source data diretory.this action will not be affected by add / to the exclude path.