midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

I implemented Nordea banklink mechanism as described in Nordea banklink (pangalink) specifics.
But it turned out, that bank doesn’t return proper set of data after payment is successful. Actually, there is nothing returned.

In order to get information from bank you should specify the following option:

<input ... >

or as it was shown in previous example as one line to php code:

$VK_a_nordea['SOLOPMT_CONFIRM'] = "YES";

if value is empty or “NOT”, then GET data will be empty from bank.

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

jQueryUI autocomplete doesn’t provide native method how to show progress indicator, while your suggestion list is generated.

I managed it to do in the following way:
1. I got a suitable progress indicator from http://www.ajaxload.info/ and placed it to /img/
2. define input field for using in autocomplete method

<input ... >

3. create style for displaying progress indicator right in our input field

input.wait {
    background: url(/img/ajax-loader.gif) no-repeat top right;
}

4. and at last define autocomplete method

$("input#sugest").autocomplete({
        search: function(event, ui) {
            $(this).addClass("wait");
        },
        open: function(event, ui) {
            $(this).removeClass("wait");
        },
        source: "remote_source.php",
        minLength: 2,
        select: function(event, ui) {
            //some action on select
        }
    });

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

In one of my projects, I needed to implement progressbar. I took jQueryUI library, as it provides pretty good bunch of solutions to make your UI more interactive for a user. Progressbar implementation is described here.

For my task, I used the following html:

reload balance

Link will trigger DB operation and Progressbar. Progressbar will be displayed in div#progressbar.
Here is javascript code for this implemetation:

$("a#refreshDB").click(function(){
       /* start DB operation */
       $.ajax({
             url: "/lib/helpers/db_operation.php",
             async: true,
             dataType: 'json'
       });
       /* hide link to prevent repeated click */
       $(this).hide();
       /* initial value for progressbar */
       var progressvalue = 0;
       /* every 2 seconds progress status will be obtained */
       var myInterval = setInterval(function(){
             /* get progress status */
             $.getJSON('/lib/helpers/progress_track.php', function(data) {
                /* update jQueryUI progressbar */
                $( "#progressbar" ).progressbar({
                            value: data,
                /* onComplete actions */
                complete: function(event, ui) {
                    /* close progressbar */
                    $( this ).progressbar( "destroy" );
                    /* reset interval */
                    clearInterval(myInterval);
                    /* show the link again */
                    $("a#refreshDB").show();
                }

                });
             });
    /* 2 seconds*/
    }, 2000);
        /* prevent from page reload */
        return false;
    });

AS you see, for this purpose, we need two additional files db_operation.php and progress_track.php.
If you execute some loop in db_operation.php, then just add mechanism for delivering progress status to progress_track.php.

I will show simple example how this can be implemented in db_operation.php

/* tracking file */
$myFile = $_SERVER['DOCUMENT_ROOT']."/temp/testFile.txt";
$fh = fopen($myFile, 'r');
/* get current value - needed for preventing from repeated execution */
$theData = fread($fh, 5);
fclose($fh);

if (!$theData || $theData == 100):
for ($i=0;$i<=100;$i++)
{
   sleep(1);
   /* round to the lowest value */
   $progress_status = floor($i/100*100);
   /* write new value to file */
   $fh = fopen($myFile, 'w') or die("can't open file");
   fwrite($fh, $progress_status);
   fclose($fh);
}
else:
print 'Another process is running';
endif;

NB: you can use session to store progressbar status, but be aware, that PHP has certain limitations on writing to session from more than two files. Take care of it, during implementation, or use mine.

progress_track.php file will only read from tracking file and report to javascipt.

$myFile = $_SERVER['DOCUMENT_ROOT']."/temp/testFile.txt";
$fh = fopen($myFile, 'r');
$theData = fread($fh, 5);
fclose($fh);
print $theData;

That's it. You will get nice progressbar, which will show the progress of your operation.

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

Recently I wrote about Banklink(Pangalink) payment configuration with php. I want to add some specifics on SEB iPizza implementation.

Here is the working code for generating request to SEB

   
   $VK_a['VK_SERVICE'] = '1002'; // ID of the service we request. In our case it is - "Invoice payment"
$VK_a['VK_VERSION'] = '008'; // ID of security type. Nowadays, all banks use 008, previously they were 001, 003, 007
$VK_a['VK_SND_ID'] = 'client'; // ID of the Seller. Is obtained in bank while signing the agreement.
$VK_a['VK_STAMP'] = 12345; // Session ID. It is optional and its value can be random - more useful for the Seller to track payments.
$VK_a['VK_AMOUNT'] = $price; // Payment sum.
$VK_a['VK_CURR'] = 'EUR'; // Payment currency.
$VK_a['VK_REF'] = ''; // reference link. Some companies use it for dividing payments on one bank account. If none, leave blank.
$VK_a['VK_MSG'] = 'Payment'; // Payment message.
$mac_pre = '';

$reversed = array_reverse($VK_a);

foreach ($reversed as $name=$value) {
	$value_len = strlen($value);
	if (strlen($value_len) < 3) {
		while (strlen($value_len) < 3) {
			$value_len = '0'.$value_len;
		}
	}
	$mac_pre = $value_len.$value.$mac_pre;
}

$fp = fopen('../pangalink/keys/privkey.pem', 'r');
$private_key = fread($fp, 8192);
fclose($fp);
$private_key_id = openssl_get_privatekey($private_key, '');

openssl_sign($mac_pre, $mac, $private_key_id);
$mac = base64_encode($mac);

$VK_a['VK_MAC'] = $mac; // Digital signature. See further how to generate it.

$VK_a['VK_ACC'] = 123456787996; // Company bank account
$VK_a['VK_NAME'] = "Company OÜ"; // Company name

$url='http://www.yoursite.ee'; //the domain should be the same as specified while signing the agreement
$VK_a['VK_RETURN'] = $url. '/pangalink/vk_return.php; // page, there bank will return in case of successful payment.
$VK_a['VK_CANCEL'] = $url. '/pangalink/vk_return.php; // page, there bank will return in case of payment cancellation. If it is the same page as  VK_RETURN, you can leave it blank.
$VK_a['VK_LANG'] = 'EST'; // Preferred Invoice language
   ?>
php foreach ($VK_a as $VK_name=$VK_value) { print ' '; } ?>

NOTE: I used in FORM tag attribute enctype=”multipart/form-data”. Request to SEB permanently returns error 500. Support team confirmed, that this issue is on their side and they are going to fix it in nearest future. So, just do not use this attribute in your FORM tag.

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

Recently I wrote about Banklink(Pangalink) payment configuration with php.

Here in Estonia, most of banks use iPizza mechanism (such as SwedBank, Sampo and SEB).
Nordea uses SOLOPMT (thanks Kurapov for a clue)

So, here is the code and explanations for generating form to post payment to Nordea bank:

 $VK_a_nordea['SOLOPMT_VERSION'] = '0003'; // ID of security type. Use either 0002 or 0003.
   $VK_a_nordea['SOLOPMT_STAMP'] = date('U',mktime()); // Session ID. It is mandatory and its value can be random - more useful for the Seller to track payments. I used Unix epoch time.
   $VK_a_nordea['SOLOPMT_RCV_ID'] = 12345678; // ID of the Seller. Is obtained in bank while signing the agreement.
   $VK_a_nordea['SOLOPMT_AMOUNT'] = 10; // Payment sum.
   $VK_a_nordea['SOLOPMT_REF'] = '1234561'; // reference link. Some companies use it for dividing payments on one bank account. It is mandatory and didn't get the idea, how it is generated. I used the example, provided by Nordea in it's document
   $VK_a_nordea['SOLOPMT_DATE'] = 'EXPRESS'; //Can be either 'Express' or follow up date.
   $VK_a_nordea['SOLOPMT_CUR'] = 'EUR'; // Payment currency.

// this is the function for generation of mac key.
function genMac($arrFields, $strMacKey){
       $strMac='';
       foreach ((array)$arrFields as $key=>$item){
           $strMac.=str_replace('&','&',$item).'&';
       }
       $strMac.=$strMacKey.'&';
       $strMac=strtoupper(md5($strMac));
       return $strMac;
   }

$VK_a_nordea['SOLOPMT_MAC'] = genMac($VK_a_nordea,"sadglgu4365456qsfdsQEWQ"); //key is sent by bank
$VK_a_nordea['SOLOPMT_MSG'] = 'Client'; // Payment message.
   $VK_a_nordea['SOLOPMT_KEYVERS'] = '0001'; // Digital signature. See further how to generate it.
       $url='http://www.yoursite.ee'; //the domain should be the same as specified while signing the agreement
   $VK_a_nordea['SOLOPMT_RETURN'] = $url. '/pangalink/vk_return_nordea.php'; // page, there bank will return in case of successful payment.
   $VK_a_nordea['SOLOPMT_REJECT'] = $url. '/pangalink/vk_return_nordea.php'; // page, there bank will return in case of successful payment.
   $VK_a_nordea['SOLOPMT_CANCEL'] = $url. '/pangalink/vk_return_nordea.php'; // page, there bank will return in case of payment cancellation. If it is the same page as  VK_RETURN, you can leave it blank.
   $VK_a_nordea['SOLOPMT_LANGUAGE'] = 4; // Preferred Invoice language 3 = English, 4 = Estonian, 6 = Latvian, 7 = Lithuanian

print '
'; foreach ($VK_a_nordea as $VK_name => $VK_value) { print ' '; } print ' '; print '
';

To create a return file, use the following code:

$MAC_KEY="sadglgu4365456qsfdsQEWQ"; //provided by Nordea
$hash=$_REQUEST['SOLOPMT_RETURN_VERSION'].'&'.
$_REQUEST['SOLOPMT_RETURN_STAMP'].'&'.
$_REQUEST['SOLOPMT_RETURN_REF'].'&'.
$_REQUEST['SOLOPMT_RETURN_PAID'].'&'.
$MAC_KEY.'&';
        $hash=strtoupper(md5(($hash)));
if($hash==$_REQUEST['SOLOPMT_RETURN_MAC']){ //success verification
if (isset($_REQUEST['SOLOPMT_RETURN_PAID'])) {
        echo( 'Payment was successful!' );
}else{ //failure
            echo( 'Payment was aborted!' );
}
}else {
        echo('Incorrect signature');
}

Nordea document E-Payment_v1_1

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

DomPDF is a wonderful library, which helps to generate PDF files on your server.
It also gives a possibility to add custom fonts to setup.
For this purpose there is a special utility load_font.php
just run the following command line on your Linux box and you will get proper fonts for dompdf:

./load_font.php 'Trebuchet MS' /usr/share/fonts/truetype/msttcorefonts/Trebuchet_MS.ttf

The problem I met is the file lib/fonts/dompdf_font_family_cache. This file is used to store fonts’ information for further using in PDF generation.
Actually it is just simple php Array:

array (
  'sans-serif' =>
  array (
    'normal' => '/home/misha/src/dompdf/lib/fonts/Helvetica',
    'bold' => '/home/misha/src/dompdf/lib/fonts/Helvetica-Bold',
    'italic' => '/home/misha/src/dompdf/lib/fonts/Helvetica-Oblique',
    'bold_italic' => '/home/misha/src/dompdf/lib/fonts/Helvetica-BoldOblique',
  ),
  'times' =>
  array (
    'normal' => '/home/misha/src/dompdf/lib/fonts/Times-Roman',
    'bold' => '/home/misha/src/dompdf/lib/fonts/Times-Bold',
    'italic' => '/home/misha/src/dompdf/lib/fonts/Times-Italic',
    'bold_italic' => '/home/misha/src/dompdf/lib/fonts/Times-BoldItalic',
  ),
)

The source of the problem is in full path. If you plan to copy this directory structure to your server, then replace the full path with the definition DOMPDF_FONT_DIR

array (
  'sans-serif' =>
  array (
    'normal' => DOMPDF_FONT_DIR . 'Helvetica',
    'bold' => DOMPDF_FONT_DIR . 'Helvetica-Bold',
    'italic' => DOMPDF_FONT_DIR . 'Helvetica-Oblique',
    'bold_italic' => DOMPDF_FONT_DIR . 'Helvetica-BoldOblique',
  ),
  'times' =>
  array (
    'normal' => DOMPDF_FONT_DIR . 'Times-Roman',
    'bold' => DOMPDF_FONT_DIR . 'Times-Bold',
    'italic' => DOMPDF_FONT_DIR . 'Times-Italic',
    'bold_italic' => DOMPDF_FONT_DIR . 'Times-BoldItalic',
  ),
)

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

Working from firewalled network is usual headache for a real hacker ;)
I am not hacker, but I need sometimes to reach some specific port out of my working network.
I found the following solution of my problem.
To make this dish, you need the following ingredients:
- out-of-your-network computer
- static IP on it. Or if firewall allows to reach Dynamic DNS, then DHPC address with Dynamic DNS setup is pretty enough.
- Linux on board and SSH installed.

Cooking process looks as following:

sudo ssh -L 80.80.80.80:23:70.70.70.70:9540 user@localhost

in this example:
80.80.80.80 – IP address, you want to bind to. If you don’t want binding to any specific local addresses, just remove this IP and following semicolon. And the string will look as 23:70.70.70.70:9540
23 – port, where you are going to receive requests. This port should be allowed by your firewall.
70.70.70.70 – remote host, where you want to reach to
9540 – remote host port, which is forbidden by your firewall rules.
user@localhost – local user, which will log-in to ssh session locally.

After connection, you will get a possibility to connect to your host port 23, as if it was remote host with port 9540
Note: root is needed if you map ports lower than 1024.

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

For some reasons, Facebook doesn’t want to fix “Like it” box so that it will be easily integrated into your Facebook application page. So, there is a workaround, which allows you to place Like box for your application into your app page.


In this case I got a part of the iframed page http://www.facebook.com/connect/connect.php?id=127104720672096, there id – is your application’s id.

See, how it looks in my app https://apps.facebook.com/jbirthday

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

Yesterday, my wife called in slight panic – home laptop Dell Studio 1555 keyboard suddenly stopped working.
This is pretty unpleasant, because I use this computer for developing my projects.

Googling brought me a solution in the second search result “dell studio 1555 keyboard not working“.
It sounds funny, but actually it works:

You need to shut down your Studio 15 laptop. Unplug power cord and take out the battery. Then hold down the Power on button for approx 30 secs. Once done replace the battery and power cord and start up as normal. The problem should now be solved.

This actually worked for me as described.

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

In previous post I explained how to post XML file to certain page on Web Server.
Response from Server can be read from HttpResponse entity, calling response.getEntity(), but it returns only coded message.
So, how then to get String value from it?

I found an answer on this blog Think Android.

You can use this function for getting HttpResponse entity in normal view.

public static String _getResponseBody(final HttpEntity entity) throws IOException, ParseException {
       	if (entity == null) { throw new IllegalArgumentException("HTTP entity may not be null"); }
       	InputStream instream = entity.getContent();
    	if (instream == null) { return ""; }
    	if (entity.getContentLength() > Integer.MAX_VALUE) { throw new IllegalArgumentException(
    		"HTTP entity too large to be buffered in memory"); }
    	String charset = getContentCharSet(entity);
    	if (charset == null) {
    		charset = HTTP.DEFAULT_CONTENT_CHARSET;
    	}
    	Reader reader = new InputStreamReader(instream, charset);
    	StringBuilder buffer = new StringBuilder();
    	try {
    		char[] tmp = new char[1024];
    		int l;
    		while ((l = reader.read(tmp)) != -1) {
    			buffer.append(tmp, 0, l);
    		}
    	} finally {
    		reader.close();
    	}
    	return buffer.toString();
    }

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

Working on one of my projects, I met a pretty simple task – post constructed XML file to certain page on a Web Server.

You will need to create additional class for this purpose SBGen.java:

public class SBGen {
	public String constructXml(Context context){
		//DATA
		StringBuilder sb = new StringBuilder();
        sb.append("");
        	sb.append("");
        sb.append("");

		return sb.toString();
	}
}

Then just add the following code to your Action:

String link = "http://ServerName/Post.php";

    	HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(link);

        try {

        	SBGen XmlClass= new SBGen();
        	String xmlFile = XmlClass.constructXml(this);
            StringEntity entity = new StringEntity(xmlFile, "UTF-8");
            httppost.setEntity(entity);
            httppost.addHeader("Accept", "application/xml");
            httppost.addHeader("Content-Type", "application/xml");

            HttpResponse response = httpclient.execute(httppost); 

            if (response.getStatusLine() != null)
Toast.makeText(getParent(), response.getStatusLine(), Toast.LENGTH_SHORT).show();
           //You can get response from calling response.getEntity() and manipulate with it as you need.
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

Very useful feature for menu displaying is drop-down menu items. Very often this feature is resolved using complex and huge pile of javascript.
I found a solution in pure css.

Here we are.
First, create layout in unordered list.

  • Main menu 1
  • Main menu 2

And now show excerpt from css we need to show how it works.

#menu li:hover ul.submenu {
    display: block;
}
#menu li ul.submenu {
    display: none;
    position: absolute;
    margin: -20px 0 0 130px;
}
#menu li ul.submenu li {
    background: #FFFFFF;
    float: none;
    position: relative;
    width: 200px;
    padding: 5px;
    z-index: 10;
}

Here is working example.

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

For one of my projects, I was looking for a simple way to implement Google Maps with jQuery.
I was lucky to find a really nice plugin goMap.
It does a lot of things, which might be useful in Google maps API v3 implementation. Here you can see the examples with descriptions.

In my work, I have a functionality, which allows to drag-n-drop icon to new location and save this point in DB. For that purposes, I need to get latitude and longitude of new point.
I haven’t found any solution with standard functions. For the purpose, I added new function to jquery.gomap-1.2.2.js file:

getBound: function(marker) {
             return $(this.mapId).data(marker).position;
},

marker in this case – marker’s id.
The code for implementation looks as following:

        $.goMap.createListener({type:'marker', marker:'admin_marker'}, 'dragend', function() {
                $.goMap.setInfo('admin_marker',
                        'Latitude,Longitude:
'+$.goMap.getBound('admin_marker').toString()); });

Here is a working prototype.

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

I don’t understand why Android SDK doesn’t provide similar sexy DatePicker widget as does HTC for their phones.
I really like their skin for a DatePicker in Calendar

I wanted similar for my app, but actually I found even better. People at Codeus don’t like standard DatePicker from Android also. And they created a really nice one DateSlider – An Alternative to the DatePicker for Android
I integrated it to my app and look what it looks like.

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

During development of YartzaitZmanim application for Android, I found a wonderful tutorial how to create custom ListView.
Custom ListView | Android Developer Tutorial (Part 17)

But the problem was that after each initialization of ListView, list items were multiplied.
The solution is to emty list ArrayList before each populateList function call.

    private void populateList() {
list.clear();
    HashMap
midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

Android development documentation describes how to use tabs in Android app. Here is the document “Tab Layout“.

But the problem is, that if you would try to use the tutorial as is, then you will see that app is crashing at start.
I found a resolution of the problem here.

Just add the following code to Manifest.xml file:




It is used to describe other activities in the project.

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

During my web development work, I need to make pretty looking square thumbnails, which will be smartly cut out from the bigger picture. Experimenting a lot with various methods, I found the best suitable one for me.

Read the rest of this entry »

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

It took me long time to create an universal function which would create thumbnails from pictures and suit all my needs.
The base for this function, I took from here.
But I modified it slightly.

Read the rest of this entry »

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

I consider two basic logics on the idea how to rotate images on the site.

Read the rest of this entry »

midbar: (Default)

Originally published at Moishe Beshkin. Please leave any comments there.

Developing a site for one customer, I met a problem how to customize view of the scroll bar.
Customer didn’t like the view of scroll bar in Internet Explorer 7 on his Windows XP.
It is not a secret, that scroll bars are generated by browser and there is no many possibilities to influence their view using css.

Read the rest of this entry »

Page generated Sep. 26th, 2017 12:43 pm
Powered by Dreamwidth Studios