Coding Tips: April 2008 Archives
ProStores has a built in mail processor that it uses to send messages - like the Email a Friend feature for example. The cool part is, you can use the form mail processing that is built in to send your own forms - perhaps a "Contact Us" form or an "Ask a Question" form.
You can use the code below on any ProStores template to create a form that sends a message.
<form name="emailfriend" method="POST" action="Send.bok">
<p>FROM</p>
<p>Name <input type="text" name="$$email.senderName" value=" "></p>
<p>E-Mail <input type="text" name="$$email.senderEmail" value=" "></p>
<p>TO</p>
<p>Name <input type="text" name="$$email.recipientName" value=" "></p>
<p>E-Mail <input type="text" name="$$email.recipientEmail" value=" "></p>
<hr size="1"/>
<p>MESSAGE<br><textarea name="$$email.message" cols="40" rows="3" wrap="virtual"></textarea></p>
<p><input type="submit" value="Send"></p>
</form>
The ".bok" on the action may not be needed - it depends on the type of ProStores installation in which your store lives.
The documentation provided for the ProStores XTE (XML Transaction Engine) authentication scheme is pretty thorough, so I will assume that you are familiar with the variables, and how to receive them into your application. That being said, here is a way to create an XTE 3.0 token using PHP.
$entry_url = {$_GET variable};
$app_id = {$_GET variable or hardcoded};
$secret = {$_GET variable or hardcoded};
$timestamp = time();
$entry_url_pre_sig = "$secret&appid=$app_id&ts=$timestamp";
$entry_url_sig = md5($entry_url_pre_sig);
$complete_entry_url = "$entry_url/getInfo?appid=$app_id" . "&ts=$timestamp" . "&sig=$entry_url_sig";
$result = http_post_send($complete_entry_url, 80, '', 'text/xml', '');
$responseXML = str_replace('®', "", $result['body']);
$tree = GetXMLTree($responseXML);
$xml_api = $tree["XTE"][0]["RESPONSE"][0]["XMLAPI"][0]["VALUE"];
$rest_api_non_secure = $tree["XTE"][0]["RESPONSE"][0]["RESTAPINONSECURE"][0]["VALUE"];
$api_ticket = $_GET['ticket'];
$get_token_pre_sig = "$secret&appid=$app_id&ts=$timestamp&ticket=$api_ticket";
$get_token_sig = md5($get_token_pre_sig);
$complete_token_url = $rest_api_non_secure . "auth/getToken?appid=$app_id" . "&ts=$timestamp" . "&ticket=$api_ticket" . "&sig=$get_token_sig";
$token_result = http_post_send($complete_token_url, 80, '', 'text/xml', '');
$responseXML = str_replace('®', "", $token_result['body']);
$tree = GetXMLTree($responseXML);
$token = $tree["XTE"][0]["RESPONSE"][0]["TOKEN"][0]["VALUE"];
echo "Your sweet token = $token ";
/* These facilitate the transmission of data to the xte, and parsing the data into a nice array */
function http_post_send($url, $port, $body, $content_type, $cookie) {
$url = ereg_replace("^http://", "", $url);
$host = substr($url, 0, strpos($url, "/"));
$uri = strstr($url, "/");
$header = http_post_header($uri, $host, strlen($body), $content_type, $cookie);
$socket = fsockopen($host, $port, $errno, $errstr);
fputs($socket, $header.$body);
$ret = array("header" => array(), "body" => "");
$reading_header = true;
$status = array("unread_bytes" => 1);
while ($status["unread_bytes"] != 0){
$chunk = fgets($socket);
$status = socket_get_status($socket);
if($reading_header){
if ($chunk == "\r\n"){
$reading_header = false;
}
else{
$ret["header"][] = $chunk;
}
}
else{
$ret["body"] .= $chunk;
}
}
while ($more = fgets($socket)){
$ret["body"] .= $more;
}
fclose($socket);
return $ret;
}
function http_post_header($uri, $host, $content_length, $content_type, $cookie) {
$h = "POST $uri HTTP/1.0\n";
$h .= "Host: $host\n";
$h .= "User-Agent: Mozilla/4.0 [en] (Windows NT 5.0; U)\n";
$h .= "Accept: */*\n";
$h .= "Accept-Language: en-us\n";
$h .= "Accept-Encoding: gzip, deflate\n";
$h .= "Connection: Keep-Alive\n";
$h .= "Content-Type: $content_type\n";
$h .= "Content-Length: $content_length\n";
$h .= "\n";
return $h;
}
function GetXMLTree($data) {
$parser = xml_parser_create('ISO-8859-1');
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
xml_parse_into_struct($parser, $data, $vals, $index);
xml_parser_free($parser);
$tree = array();
$i = 0;
$tree[$vals[$i]['tag']][] = GetChildren($vals, $i);
return $tree;
}
function GetChildren($vals, &$i){
$children = array();
if(isset($vals[$i]['value'])){
$children['VALUE'] = $vals[$i]['value'];
}
while(++$i < count($vals)){
switch ($vals[$i]['type']){
case 'cdata':
if(isset($children['VALUE'])){
$children['VALUE'] .= $vals[$i]['value'];
}
else{
$children['VALUE'] = $vals[$i]['value'];
}
break;
case 'complete':
if(isset($vals[$i]['attributes'])) {
$children[$vals[$i]['tag']][]['ATTRIBUTES'] = $vals[$i]['attributes'];
$index = count($children[$vals[$i]['tag']])-1;
if(isset($vals[$i]['value'])){
$children[$vals[$i]['tag']][$index]['VALUE'] = $vals[$i]['value'];
}
else{
$children[$vals[$i]['tag']][$index]['VALUE'] = '';
}
}
else{
if(isset($vals[$i]['value'])){
$children[$vals[$i]['tag']][]['VALUE'] = $vals[$i]['value'];
}
else{
$children[$vals[$i]['tag']][]['VALUE'] = '';
}
}
break;
case 'open':
if(isset($vals[$i]['attributes'])){
$children[$vals[$i]['tag']][]['ATTRIBUTES'] = $vals[$i]['attributes'];
$index = count($children[$vals[$i]['tag']])-1;
$children[$vals[$i]['tag']][$index] = array_merge($children[$vals[$i]['tag']][$index],GetChildren($vals, $i));
}
else{
$children[$vals[$i]['tag']][] = GetChildren($vals, $i);
}
break;
case 'close':
return $children;
}
}
}
This post may stray from my usual uber-helpful code snippet. But, it could save you unbelievable amounts of time so pay very close attention...
The ampersand character is known around here as the devil symbol. Not the word "ampersand" mind you, but ---> & <---- this evil guy. Stay away from it unless you're using it to escape your HTML. The word 'and' is only two characters longer. In fact, in order to produce that symbol, you have to hold down the shift key, and press 7 which definitely takes more energy and concentration. So the next time your xml_parse_into_struct fails to push data into the array, check to see that your sweet & sour chicken is both sweet and sour.
P.S. all symbols are stupid. Stay away from them.
P.P.S. Don't ever use Word for web text. It's stupid, and has stupid characters.
Here is an example of the order confirmation code you receive from become.com - customized for use within your ProStores Order Confirmation template source code.
<!-- Become.com -->
<ss:set name="a1" value="https://partner.become.com/tracking/t.gif?merchantid=/*Your merchantID would go here*/&order_id="/>
<ss:set name="a2" value="$invoice.invoiceNumber"/>
<ss:set name="a3" value="&order_value="/>
<ss:set name="a4" value="$invoice.total" format="none"/>
<ss:set name="a5" value="&num_items="/>
<ss:set name="a6" value="$invoice.itemCount"/>
<ss:set name="aTotal" value="$string.concat($a1, $string.concat($a2, $string.concat($a3, $string.concat($a4, $string.concat($a5, $a6)))))"/>
<img src="$aTotal" id="become_t"/>
<script type="text/javascript" language="javascript" src="https://partner.become.com/tracking/conversion.js"> </script>
<!-- Become.com -->
Sometimes a secure XTE call is necessary based on the type of information you plan to extract from ProStores and use in your PHP application. I know the big one that I need is anything having to do with credit card details. So, whether you are looking to retrieve those details, or if you would like to know how to process http data via a secure channel here's some info.
One of the best functions I've found to process the proper http data is a built in function called fsockopen. You're basic URL call would look something like the following:
$socket = fsockopen("www.domain.com", 80);
// 80 = port that you want to post through
Now if you wanted to go secure, you would need to change it up a smidge.
$socket = pfsockopen("ssl://www.domain.com", 443);
// 443 = secure port
Also, you'll need to make sure your PHP has openssl installed and configured.
Subscribe to the feed for this blog