Tidbits @ Kassemi

A collection of opinions, thoughts, tricks and misc. information.

Thursday, September 22, 2005

 

Programming for Paypal

Yep. I'm back. Again after a little while. I just don't have all that much to give anybody yet, and don't like coming up here and writing when I have nothing interesting to say.

Before I begin bitching, let me first start on a lighter note. I've switched from PHPEclipse to Quanta for my PHP/HTML/Javascript work. And (being on a KDE desktop) I no longer have to put up with the memory hog that Eclipse really is. Quanta is more responsive and does just about everything that Eclipse did. I will definitely switch back to Eclipse when I get back into other languages (Java/C), as I really do like it, but just don't have the memory (512MB) or the money (0$) to get more. If you're doing work with PHP and are running KDE - you can run it elsewhere, but it will take more memory - you should consider taking a look at Quanta, which is probably already installed. Done with that, for now...

So I downloaded the documentation for Paypal's API yesterday, hoping to easily get some good Paypal programming into my project. I need something very simple:


  1. Person wants something, person selects it.

  2. Person wants to pay for that thing, and clicks button to do so.

  3. Person gets the options to pay via their paypal account, or through a credit card

  4. Information entered

  5. Information confirmed

  6. Confirmation Sent



Simple enough, right? I took a look at the documentation, and was overwhelmed, for the first time in a while. There were thousands of pages of information, and sorting through it all was just not an option. For something as simple as the above, it shouldn't take a thousand pages. So I searched around the paypal developer's section. I found the paypal SDK (available for several different languages, my language this year is PHP), and I downloaded it. I imported it into my project manager, and voila, 5.8 Megs of a wonderfully organized PEAR installation. Oh. I haven't yet written about my thoughts of PEAR. I'll do that soon... But for the meantime, I just don't like it. If I'm going to be using code, I'd much rather it be available to me like my other code is, not through some installable module...

So the PEAR stuff is disabled on my PHP installation, and I didn't feel like recompiling. So I continue my search, and enter the PayPal developer's forum. May I say how much useless, incomplete information lies within those walls? I did find a few posts that got me started, and finally realized that there was no way I would be getting through this without learning how to use SOAP. My first stop was the PHP manual, which told me that I needed to enable SOAP on my PHP install... I quickly opened up vi:


phpinfo();
?>


Saved the file on my server, and opened it up....


'./configure' '--prefix=/usr/local/php'
'--with-apxs2=/usr/local/apache2/bin/apxs' '--with-libxml'
'--with-zlib' '--with-bz2' '--enable-calendar' '--with-jpeg-dir'
'--with-tiff-dir' '--with-gd' '--with-png-dir' '--with-zlib-dir'
'--with-freetype-dir=/usr/include/freetype2/' '--with-t1-lib'
'--with-mysql=/usr/local/mysql' '--with-mysql-sock=/tmp/mysql_sock/mysql.sock'
'--enable-sockets' '--with-tidy' '--with-gmp' '--with-openssl'



DAMN! I need to recompile for that native PHP5 SOAP support, don't I!? ARGH!


$ su -c removepkg PHP
password: X
$ cd /source/php5
$ make clean
$ ./configure --prefix=/package --EVERYTHING + --enable-soap
$ make
$ su -c make install
$ cd /package
$ su
# makepkg PHPwithSOAP.tgz
# installpkg PHPwithSOAP.tgz


Okay. After restarting Apache, I had PHP with SOAP. I read the documentation at php.net more thoroughly, and got a pretty good idea of what I was doing. Now I may not yet be an expert with SOAP, but the following just seemed a little long:


$params = array(
'Version'=>'1.0',
'DoExpressCheckoutPaymentRequestDetails'=>array(
'Token'=>$_GET['token'],
'PayerID'=>$_GET['payerid'],
'PaymentAction'=>'Sale',
'PaymentDetails'=>array(
'OrderTotal'=>$order_total,
'ItemTotal'=>array('_'=>'100.00', 'currencyID'=>'USD'),
'TaxTotal'=>array('_'=>'0', 'currencyID'=>'USD')
)
),
);

$params = array('DoExpressCheckoutPaymentRequest'=>$params);


Now why the heck would they make me waste the bandwidth and send them a string as long as "DoExpressCheckoutPaymentRequestDetails?" Can't they make that (and quite a few others) a little smaller? ARGH! Well, a few hours messing with my SOAP requests to Paypal, I finally got something working. I can now click a Pay now with Paypal button, and have a test account charge 100 dollars to a fake user. And the amount goes through! The only problem is the assloads of configuration I'm going to have to do to make this a good script that I can actually use for my sites!

End Rant.

Sunday, September 18, 2005

 

Re-think your AJAX overuse

Okay. I know I've been posting loads of AJAX stuff recently, but after taking a look at how a few other sites are implementing this technology, I decided I need a warning: NOT ALL USERS BROWSE WITH JAVASCRIPT!

AJAX programming is very well supported by the major browsers, but only if AJAX is enabled. Some stats point out that up to 30% of users browse the internet with javascript disabled. You need to be sure that you allow some method of viewing your page without javascript. So today, a quick discussion on the PHP DOM, which will probably throw out much of your JS DOM usage...

The Javascript DOM makes it very easy to add information to each page after it is loaded, and this is exactly what most of the AJAX programs on the internet are doing these days (my div browser below is a good example of that). The best use of AJAX can also be the hardest to find a very quick substitute for. Take for instance the star feature on gmail. A click on the star sends a message through the request object to the gmail server, telling the server that the message should now be starred. No response is needed (although one may be given), and the client side script applies a star to the message. The best way to program something like this is definitely to program the non-AJAX version first, and then to add the new functionality for a browser that supports it.

Anyway, the PHP DOM class: http://www.php.net/manual/en/ref.dom.php

The basic usage is as follows:


$dom = new DOMDocument;
/* For HTML */
$dom->loadHTML($html);
/* For XML */
$dom->loadXML($xml);
$links = $dom->getElementsByTagName('a');
foreach($links as $link){
/* Looping through each link in the provided HTML, get the location the link points to: */
$location = $link->getAttribute('href');
if($location == ''){
/* There was no href attribute, or it is empty. the DOM will not return false for this
method, if there was no location specified, send to the index (relative)*/
$link->setAttribute('href', 'index.php');
}else{
/* We are going to send the user through the safe_redirect script to avoid sharing
the session id */
$link->setAttribute('href', 'safe_out.php?loc='.$link);
}
}



Read the documentation for this class, and you'll see it works in exactly the same way as the JS DOM. The example above changed all links on the page to move through the safe_out.php script, which could redirect a user to a page after stripping the phpsessid variable from the $_GET array, lessening the probablity for a Cross-site scripting attack...

Again, I don't have much to write on today, as I haven't really had time to do anything interesting. No cool new features, just fixing bugs in code...

Don't worry though, you non-existent audience (save you, of course mav3n), I'll soon start putting up some more interesting stuff.

-James

Thursday, September 08, 2005

 

AJAX in-page browser pt 2

So. I've been working with my AJAX browser, and I've come across a problem. I set up user authentication with a script that is executed with every page that loads on the server... It checks to see whether or not the encrypted cookie or the session variables for log-in are accurate, and will forward to the log in page if they are not. I have an exception page array, which contains a list of pages that are allowed to be viewed by users who are not logged in. This makes things very secure.

The AJAX browser I'm using in the form allows the user to browse through category information, specifying what category they would like to place their entry into. When the request is made to the script that loads the category information, the included file checks to see whether they are logged in or not and the log in page is displayed in the AJAX browser. The AJAX browser does not allow for the reading of the PHP session if it is in a cookie...

If such a system is in place, the easiest solution is to force the PHP session id into the GET array passed to the div browser...

Because of the authenticating include, you will also need to make sure that PHP sets the correct session id:


if(isset($_GET['PHPSESSID'])){
session_id($_GET['PHPSESSID']);
}
session_start();


Pretty easy... I guess you now know I couldn't think of anything to write today :)

Tuesday, September 06, 2005

 

AJAX in-page browser

Before you get into this post, if you don't know how to program with javascript and HTTPRequestObjects, you should look at my tutorial on PHPBuilder.com:

http://www.phpbuilder.com/columns/kassemi20050606.php3 (part 1)
http://www.phpbuilder.com/columns/kassemi20050613.php3 (part 2)

Yep. I wrote it. From what I gather, you either love it or hate it. It's been pretty popular (links to it show up when you google AJAX tutorial... :) )

So I needed to allow a user to select from a number of options while in page form. There are many such options available... The closest example I can think about are school codes. For every school there is an assigned school code. To find the one that applies to you, you need to be able to search through a number of schools. This information is not easily accessible from a dropdown box. The solution? Have you seen those pages that have a calendar icon you can click on to get a calendar next to the form input (I have one of these on the page, as well)? Why not offer a way to let users browse information next to the form, much in the same way they can browse through the months in the calendars? An iframe would do the trick, but in order to keep away from frames entirely, we'll use a div and some AJAX... Here's the PHP back-end to the whole thing. You can add security restrictions, as I have done:


span style="color: #000000">
<?php

/* PHP backend for AJAX browser */

    
$data = file_get_contents($_GET['to']);

    if(
stripos($data, '<body') !== true){


        
$start = stripos($data, '<body');

        
$end = stripos($data, '>', $start);


        
$data = substr($data, $end + 1);     

    }

    if(
stripos($data, '</body>') !== false){


        
$data = substr($data, 0, stripos($data, '</body>'));

    }


    echo
$_GET['div_id'].','.$data;

?>



All it does is return the data from a page (anything within the body element, if it exists), and the id that we pass to it... Here's the js... Everything is extremely simple:


/* (Copyright 2005 James Kassemi) */

function getHTTPObject() {
var xmlhttp;
/*@cc_on
@if (@_jscript_version >= 5)
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}

@else
xmlhttp = false;
@end @*/
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp = false;
}
}
return xmlhttp;
}
var http = getHTTPObject();

function request_o(http_object, method, url, capture_function, post_args){
http_object.abort();
http_object.open(method, url);
if(method=='post'){
http_object.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
http_object.onreadystatechange = eval(capture_function);
http_object.send(post_args);
}
if(method != 'post'){
http_object.onreadystatechange = eval(capture_function);
http_object.send(null);
}
}

function navigate(to, div_id){
request_o(http, 'GET', './div_browser.php?to=' + escape(to) + '&div_id=' + escape(div_id), 'handle_navigate');
}

function handle_navigate(){
if(http.readyState == 4){
/* This could be done using XML and certain procedures I've used before, but in this case this will work just fine... */
var response = http.responseText;
/* Instead of using split, we'll use our own procedure that should be a little faster. */
for(i=0;i<response.length;i++){
if(response.charAt(i) == ','){
var div_id = response.substring(0,i);
var content = response.substring(i+1);
break;
}
}
/* We now have the content for the div, and we have the div's id... Let's replace with content. */
document.getElementById(div_id).innerHTML = content;
/* Now we should convert the links inside to open in the same box... */
convert_links(div_id);
}
}

function convert_links(div){
/* Convert all anchor links to navigate() links... */
div_box = document.getElementById(div);
var links = div_box.getElementsByTagName('a');
for(i=0;i<links.length;i++){
var value = links.item(i).getAttribute('href');
if(value){
links.item(i).setAttribute('href', "javascript:navigate('" + escape(value) + "', '" + div + "');");
}
}
}


And that's pretty much the entire thing! A call to navigate(to, div_id) will replace the contents of div_id with the page, to. I added a few more options more specific to my site (including a little icon that can be clicked next to the form field, as I was talking about), and grabbed the obligatory slashdot.org screenshot:



I'm not saying this is a full solution for anything, but it could easily become one. You could add your own back, forward, and home buttons, and could even insert a navigation bar, where the person can enter whatever URL they want to have loaded.

One thing that would need some serious work, however, would be the convert_links function. It currently just takes anything that is in the href attribute of a link and adds the navigate event to it, so it will load in the current div... The problem with this is that it will not render relative links in functional format...

If you are going to expand this, be sure you're careful about security. Make certain no administrator-like page on your server or anything checks authenticity only by whether or not you're on localhost... There are quite a few things somebody could easily do with this technology if they wanted to. You may wish to consider adding a check that only loads pages that are on your own server, and further, only pages that you want accessed...

Until next time,
James

Saturday, September 03, 2005

 

Keeping my laptop cool

Last night as I was going to bed, I stared at the ceiling and wondered how I would keep my laptop free of dust. I've got an hp pavilion ze4420us (slackware-current and FULLY functional (including 3d acceleration, YAY), and I live in a very dirty room - as most males my age do. Since there's quite a bit of dust in here, the fan on this thing gets clogged regularly. About every day I squirt some compressed air into the fan intake, and every month I open the thing up completely to clean it out. Since I have no money - as most males my age don't - I decided I need something more affordable than compressed air. My roommate thinks it's necessary to do laundry every week (don't worry, I still smell fine), and she's got loads of dryer sheets. I wasn't too sure whether or not that would work, so today I started browsing the internet, and came across this:

http://www.afrotechmods.com/reallycheap/freshener/freshener.htm

What'd'ya know!? So I cut up a dryer sheet, and put it over the intake fan... My idle CPU temp jumped from 50 to 58 degrees, but if I don't have to worry about the dust, that's just fine. I'll take a look at the sheet in a week and see just what it catches. If it's got something interesting I'll find a way to get a photo of it up here (btw: will take your old digital camera :) ).

As for the AJAX syntax highlighter... Someone on sitepoint the other day was looking for some help making a guestbook for his daughter's web page, so I decided I'd help out and write one for him. It's pretty advanced, and I'll get you more information about that one when I'm done with it.

I'm also thinking of moving this blog. I don't like the way that blogger is set up. I can't upload files easily, categorize entries, etc. So once I find something better I'll try to export this to it.

Take it easy everybody!

Archives

August 2005   September 2005   October 2005   November 2005   December 2005   January 2006   February 2006   March 2006   April 2006   June 2006   July 2006   August 2006   September 2006   October 2006   November 2006  

This page is powered by Blogger. Isn't yours?