commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / sites / all / modules-new / civicrm / tools / extensions / org.civicrm.payment.googlecheckout / packages / Google / library / googlecart.php
1 <?php
2
3 /**
4 * Copyright (C) 2006 Google Inc.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 /* This class is used to create a Google Checkout shopping cart and post it
20 * to the Sandbox or Production environment
21 * A very useful function is the CheckoutButtonCode() which returns the HTML
22 * code to post the cart using the standard technique
23 * Refer demo/cartdemo.php for different use case scenarios for this code
24 */
25 class GoogleCart {
26 var $merchant_id;
27 var $merchant_key;
28 var $server_url;
29 var $schema_url;
30 var $base_url;
31 var $checkout_url;
32 var $checkout_diagnose_url;
33 var $request_url;
34 var $request_diagnose_url;
35
36 var $cart_expiration = "";
37 var $merchant_private_data = "";
38 var $edit_cart_url = "";
39 var $continue_shopping_url = "";
40 var $request_buyer_phone = "";
41 var $merchant_calculated = "";
42 var $merchant_calculations_url = "";
43 var $accept_merchant_coupons = "";
44 var $accept_gift_certificates = "";
45 var $default_tax_table;
46
47 var $item_arr;
48 var $shipping_arr;
49 var $alternate_tax_table_arr;
50 var $xml_data;
51
52 //The Constructor method which requires a merchant id, merchant key
53 //and the operation type(sandbox or checkout)
54 /**
55 * @param $id
56 * @param $key
57 * @param string $server_type
58 */
59 function GoogleCart($id, $key, $server_type = "checkout") {
60 $this->merchant_id = $id;
61 $this->merchant_key = $key;
62
63 if (strtolower($server_type) == "sandbox") {
64
65 $this->server_url = "https://sandbox.google.com/checkout/";
66 }
67 else $this->server_url = "https://checkout.google.com/";
68
69 $this->schema_url = "http://checkout.google.com/schema/2";
70 $this->base_url = $this->server_url . "cws/v2/Merchant/" . $this->merchant_id;
71 $this->checkout_url = $this->base_url . "/checkout";
72 $this->checkout_diagnose_url = $this->base_url . "/checkout/diagnose";
73 $this->request_url = $this->base_url . "/request";
74 $this->request_diagnose_url = $this->base_url . "/request/diagnose";
75
76 //The item, shipping and tax table arrays are initialized
77 $this->item_arr = array();
78 $this->shipping_arr = array();
79 $this->alternate_tax_table_arr = array();
80 }
81
82 /**
83 * @param $cart_expire
84 */
85 function SetCartExpiration($cart_expire) {
86 $this->cart_expiration = $cart_expire;
87 }
88
89 /**
90 * @param $data
91 */
92 function SetMerchantPrivateData($data) {
93 $this->merchant_private_data = $data;
94 }
95
96 /**
97 * @param $url
98 */
99 function SetEditCartUrl($url) {
100 $this->edit_cart_url = $url;
101 }
102
103 /**
104 * @param $url
105 */
106 function SetContinueShoppingUrl($url) {
107 $this->continue_shopping_url = $url;
108 }
109
110 /**
111 * @param $req
112 */
113 function SetRequestBuyerPhone($req) {
114 $this->_SetBooleanValue('request_buyer_phone', $req, "");
115 }
116
117 /**
118 * @param $url
119 * @param string $tax_option
120 * @param string $coupons
121 * @param string $gift_cert
122 */
123 function SetMerchantCalculations($url, $tax_option = "false",
124 $coupons = "false",
125 $gift_cert = "false"
126 ) {
127 $this->merchant_calculations_url = $url;
128 $this->_SetBooleanValue('merchant_calculated', $tax_option, "false");
129 $this->_SetBooleanValue('accept_merchant_coupons', $coupons, "false");
130 $this->_SetBooleanValue('accept_gift_certificates', $gift_cert, "false");
131 }
132
133 /**
134 * @param $google_item
135 */
136 function AddItem($google_item) {
137 $this->item_arr[] = $google_item;
138 }
139
140 /**
141 * @param $ship
142 */
143 function AddShipping($ship) {
144 $this->shipping_arr[] = $ship;
145 }
146
147 /**
148 * @param $tax
149 */
150 function AddTaxTables($tax) {
151 if ($tax->type == "default") {
152 $this->default_tax_table = $tax;
153 }
154 elseif ($tax->type == "alternate") {
155 $this->alternate_tax_table_arr[] = $tax;
156 }
157 }
158
159 /**
160 * @return string
161 */
162 function GetXML() {
163 require_once ('xml-processing/xmlbuilder.php');
164
165 $xml_data = new XmlBuilder();
166
167 $xml_data->Push('checkout-shopping-cart',
168 array('xmlns' => $this->schema_url)
169 );
170 $xml_data->Push('shopping-cart');
171
172 //Add cart expiration if set
173 if ($this->cart_expiration != "") {
174 $xml_data->Push('cart-expiration');
175 $xml_data->Element('good-until-date', $this->cart_expiration);
176 $xml_data->Pop('cart-expiration');
177 }
178
179 //Add XML data for each of the items
180 $xml_data->Push('items');
181 foreach ($this->item_arr as $item) {
182 $xml_data->Push('item');
183 $xml_data->Element('item-name', $item->item_name);
184 $xml_data->Element('item-description', $item->item_description);
185 $xml_data->Element('unit-price', $item->unit_price,
186 array('currency' => $item->currency)
187 );
188 $xml_data->Element('quantity', $item->quantity);
189 if ($item->merchant_private_data != '') $xml_data->Element('merchant-private-date',
190 $item->merchant_private_data
191 );
192 if ($item->tax_table_selector != '') {
193 $xml_data->Element('tax-table-selector', $item->tax_table_selector);
194 }
195 $xml_data->Pop('item');
196 }
197 $xml_data->Pop('items');
198
199 if ($this->merchant_private_data != '') $xml_data->Element('merchant-private-data',
200 $this->merchant_private_data
201 );
202
203 $xml_data->Pop('shopping-cart');
204
205 $xml_data->Push('checkout-flow-support');
206 $xml_data->Push('merchant-checkout-flow-support');
207 if ($this->edit_cart_url != '') {
208 $xml_data->Element('edit-cart-url', $this->edit_cart_url);
209 }
210 if ($this->continue_shopping_url != '') $xml_data->Element('continue-shopping-url',
211 $this->continue_shopping_url
212 );
213
214 if (count($this->shipping_arr) > 0) {
215
216 $xml_data->Push('shipping-methods');
217 }
218
219 //Add the shipping methods
220 foreach ($this->shipping_arr as $ship) {
221 //Pickup shipping handled in else part
222 if ($ship->type == "flat-rate" ||
223 $ship->type == "merchant-calculated"
224 ) {
225 $xml_data->Push($ship->type . '-shipping',
226 array('name' => $ship->name)
227 );
228 $xml_data->Element('price', $ship->price,
229 array('currency' => $ship->currency)
230 );
231
232 //Check if shipping restrictions have been specifd=ied
233 if ($ship->allowed_restrictions ||
234 $ship->excluded_restrictions
235 ) {
236 $xml_data->Push('shipping-restrictions');
237
238 //Check if allowed restrictions specified
239 if ($ship->allowed_restrictions) {
240 $xml_data->Push('allowed-areas');
241 if ($ship->allowed_country_area != "") $xml_data->Element('us-country-area', '',
242 array('country-area' =>
243 $ship->allowed_country_area,
244 )
245 );
246 foreach ($ship->allowed_state_areas_arr as $current) {
247 $xml_data->Push('us-state-area');
248 $xml_data->Element('state', $current);
249 $xml_data->Pop('us-state-area');
250 }
251 foreach ($ship->allowed_zip_patterns_arr as $current) {
252 $xml_data->Push('us-zip-area');
253 $xml_data->Element('zip-pattern', $current);
254 $xml_data->Pop('us-zip-area');
255 }
256 $xml_data->Pop('allowed-areas');
257 }
258
259 if ($ship->excluded_restrictions) {
260 $xml_data->Push('allowed-areas');
261 $xml_data->Pop('allowed-areas');
262 $xml_data->Push('excluded-areas');
263 if ($ship->excluded_country_area != "") $xml_data->Element('us-country-area', '',
264 array('country-area' =>
265 $ship->excluded_country_area,
266 )
267 );
268 foreach ($ship->excluded_state_areas_arr as $current) {
269 $xml_data->Push('us-state-area');
270 $xml_data->Element('state', $current);
271 $xml_data->Pop('us-state-area');
272 }
273 foreach ($ship->excluded_zip_patterns_arr as $current) {
274 $xml_data->Push('us-zip-area');
275 $xml_data->Element('zip-pattern', $current);
276 $xml_data->Pop('us-zip-area');
277 }
278 $xml_data->Pop('excluded-areas');
279 }
280 $xml_data->Pop('shipping-restrictions');
281 }
282 $xml_data->Pop($ship->type . '-shipping');
283 }
284 elseif ($ship->type == "pickup") {
285 $xml_data->Push('pickup', array('name' => $ship->name));
286 $xml_data->Element('price', $ship->price,
287 array('currency' => $ship->currency)
288 );
289 $xml_data->Pop('pickup');
290 }
291 }
292 if (count($this->shipping_arr) > 0) {
293 $xml_data->Pop('shipping-methods');
294 }
295
296 if ($this->request_buyer_phone != "") $xml_data->Element('request-buyer-phone-number',
297 $this->request_buyer_phone
298 );
299
300 if ($this->merchant_calculations_url != "") {
301 $xml_data->Push('merchant-calculations');
302 $xml_data->Element('merchant-calculations-url',
303 $this->merchant_calculations_url
304 );
305 if ($this->accept_merchant_coupons != "") $xml_data->Element('accept-merchant-coupons',
306 $this->accept_merchant_coupons
307 );
308 if ($this->accept_gift_certificates != "") $xml_data->Element('accept-gift-certificates',
309 $this->accept_gift_certificates
310 );
311 $xml_data->Pop('merchant-calculations');
312 }
313
314 //Set Default and Alternate tax tables
315 if ((count($this->alternate_tax_table_arr) != 0) || (isset($this->default_tax_table))) {
316 if ($this->merchant_calculated != "") {
317 $xml_data->Push('tax-tables', array('merchant-calculated' => $this->merchant_calculated));
318 }
319 else $xml_data->Push('tax-tables');
320
321 if (isset($this->default_tax_table)) {
322 $curr_table = $this->default_tax_table;
323 foreach ($curr_table->tax_rules_arr as $curr_rule) {
324
325
326 $xml_data->Push('default-tax-table');
327 $xml_data->Push('tax-rules');
328 foreach ($curr_rule->state_areas_arr as $current) {
329 $xml_data->Push('default-tax-rule');
330
331 $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
332 $xml_data->Element('rate', $curr_rule->tax_rate);
333 $xml_data->Push('tax-area');
334 if ($curr_rule->country_area != "") {
335 $xml_data->Element('us-country-area', '', array('country-area' => $curr_rule->country_area));
336 }
337 $xml_data->Push('us-state-area');
338 $xml_data->Element('state', $current);
339 $xml_data->Pop('us-state-area');
340
341 $xml_data->Pop('tax-area');
342 $xml_data->Pop('default-tax-rule');
343 }
344 foreach ($curr_rule->zip_patterns_arr as $current) {
345 $xml_data->Push('default-tax-rule');
346
347 $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
348 $xml_data->Element('rate', $curr_rule->tax_rate);
349 $xml_data->Push('tax-area');
350
351 if ($curr_rule->country_area != "") {
352
353 $xml_data->Element('us-country-area', '', array('country-area' => $curr_rule->country_area));
354 }
355 $xml_data->Push('us-zip-area');
356 $xml_data->Element('zip-pattern', $current);
357 $xml_data->Pop('us-zip-area');
358 $xml_data->Pop('tax-area');
359 $xml_data->Pop('default-tax-rule');
360 }
361 $xml_data->Pop('tax-rules');
362 $xml_data->Pop('default-tax-table');
363 }
364 }
365
366 if (count($this->alternate_tax_table_arr) != 0) {
367 $xml_data->Push('alternate-tax-tables');
368 foreach ($this->alternate_tax_table_arr as $curr_table) {
369 foreach ($curr_table->tax_rules_arr as $curr_rule) {
370 $xml_data->Push('alternate-tax-table', array('standalone' => $curr_table->standalone, 'name' => $curr_table->name));
371 $xml_data->Push('alternate-tax-rules');
372 foreach ($curr_rule->state_areas_arr as $current) {
373 $xml_data->Push('alternate-tax-rule');
374
375 $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
376 $xml_data->Element('rate', $curr_rule->tax_rate);
377 $xml_data->Push('tax-area');
378 if ($curr_rule->country_area != "") {
379 $xml_data->Element('us-country-area', '', array('country-area' => $curr_rule->country_area));
380 }
381 $xml_data->Push('us-state-area');
382 $xml_data->Element('state', $current);
383 $xml_data->Pop('us-state-area');
384
385 $xml_data->Pop('tax-area');
386 $xml_data->Pop('alternate-tax-rule');
387 }
388 foreach ($curr_rule->zip_patterns_arr as $current) {
389 $xml_data->Push('alternate-tax-rule');
390
391 $xml_data->Element('shipping-taxed', $curr_rule->shipping_taxed);
392 $xml_data->Element('rate', $curr_rule->tax_rate);
393 $xml_data->Push('tax-area');
394
395 if ($curr_rule->country_area != "") {
396
397 $xml_data->Element('us-country-area', '', array('country-area' => $curr_rule->country_area));
398 }
399 $xml_data->Push('us-zip-area');
400 $xml_data->Element('zip-pattern', $current);
401 $xml_data->Pop('us-zip-area');
402 $xml_data->Pop('tax-area');
403 $xml_data->Pop('alternate-tax-rule');
404 }
405 $xml_data->Pop('alternate-tax-rules');
406 $xml_data->Pop('alternate-tax-table');
407 }
408 }
409 $xml_data->Pop('alternate-tax-tables');
410 }
411 $xml_data->Pop('tax-tables');
412 }
413 $xml_data->Pop('merchant-checkout-flow-support');
414 $xml_data->Pop('checkout-flow-support');
415 $xml_data->Pop('checkout-shopping-cart');
416
417 return $xml_data->GetXML();
418 }
419
420 //Code for generating Checkout button
421 /**
422 * @param string $size
423 * @param string $style
424 * @param string $variant
425 * @param string $loc
426 *
427 * @return string
428 */
429 function CheckoutButtonCode($size = "large", $style = "white",
430 $variant = "text", $loc = "en_US"
431 ) {
432
433 switch ($size) {
434 case "large":
435 $width = "180";
436 $height = "46";
437 break;
438
439 case "medium":
440 $width = "168";
441 $height = "44";
442 break;
443
444 case "small":
445 $width = "160";
446 $height = "43";
447 break;
448
449 default:
450 break;
451 }
452
453 if ($variant == "text") {
454 $data = "<p><form method=\"POST\" action=\"" . $this->checkout_url . "\">
455 <input type=\"hidden\" name=\"cart\" value=\"" . base64_encode($this->GetXML()) . "\">
456 <input type=\"hidden\" name=\"signature\" value=\"" . base64_encode($this->CalcHmacSha1($this->GetXML())) . "\">
457 <input type=\"image\" name=\"Checkout\" alt=\"Checkout\"
458 src=\"" . $this->server_url . "buttons/checkout.gif?merchant_id=" . $this->merchant_id . "&w=" . $width . "&h=" . $height . "&style=" . $style . "&variant=" . $variant . "&loc=" . $loc . "\"
459 height=\"" . $height . "\" width=\"" . $width . "\" />
460 </form></p>";
461 }
462 elseif ($variant == "disabled") {
463 $data = "<p><img alt=\"Checkout\"
464 src=\"" . $this->server_url . "buttons/checkout.gif?merchant_id=" . $this->merchant_id . "&w=" . $width . "&h=" . $height . "&style=" . $style . "&variant=" . $variant . "&loc=" . $loc . "\"
465 height=\"" . $height . "\" width=\"" . $width . "\" /></p>";
466 }
467 return $data;
468 }
469
470 //Method which returns the encrypted google cart to make sure that the carts are not tampered with
471 /**
472 * @param $data
473 *
474 * @return string
475 */
476 function CalcHmacSha1($data) {
477 $key = $this->merchant_key;
478 $blocksize = 64;
479 $hashfunc = 'sha1';
480 if (strlen($key) > $blocksize) {
481 $key = pack('H*', $hashfunc($key));
482 }
483 $key = str_pad($key, $blocksize, chr(0x00));
484 $ipad = str_repeat(chr(0x36), $blocksize);
485 $opad = str_repeat(chr(0x5c), $blocksize);
486 $hmac = pack(
487 'H*', $hashfunc(
488 ($key ^ $opad) . pack(
489 'H*', $hashfunc(
490 ($key ^ $ipad) . $data
491 )
492 )
493 )
494 );
495 return $hmac;
496 }
497
498 //Method used internally to set true/false cart variables
499 /**
500 * @param $string
501 * @param $value
502 * @param $default
503 */
504 function _SetBooleanValue($string, $value, $default) {
505 $value = strtolower($value);
506 if ($value == "true" || $value == "false")eval('$this->' . $string . '="' . $value . '";');
507 else eval('$this->' . $string . '="' . $default . '";');
508 }
509 }
510