1<?php
2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
3//
4// All Rights Reserved. See copyright.txt for details and a complete list of authors.
5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
6// $Id$
7
8// NB, all PayPal supported "HTML Variables" will be passed on to the button, even if not mentioned here
9
10function wikiplugin_paypal_info()
11{
12
13	global $prefs;
14
15	return [
16		'name' => tra('PayPal Button'),
17		'documentation' => 'Payment',
18		'description' => tra('Embed a PayPal button'),
19		'introduced' => 11,
20		'prefs' => ['wikiplugin_paypal'],		// not dependent on 'payment_feature', would be annoying if you just want one donate button for instance
21		'iconname' => 'paypal',
22		'format' => 'html',
23		'extraparams' => true,
24		'validate' => 'all',
25		'params' => [
26			'cmd' => [
27				'required' => false,
28				'name' => tra('Type'),
29				'description' => tra('Type of PayPal button'),
30				'since' => '11.0',
31				'filter' => 'word',
32				'options' => [
33					['text' => '', 'value' => ''],
34					['text' => tra('Shopping cart'), 'value' => '_cart'],
35					['text' => tra('Buy Now'), 'value' => '_xclick'],
36					['text' => tra('Donations'), 'value' => 'donations'],
37//					array('text' => tra('Gift vouchers'), 'value' => 'gift_certs'),	TODO?
38//					array('text' => tra('Subscriptions'), 'value' => 'subscriptions'),
39//					array('text' => tra('Automatic Billing'), 'value' => 'auto_billing'),
40//					array('text' => tra('Instalment Plan'), 'value' => 'payment_plan'),
41				],
42				'default' => '_cart',
43			],
44			'cart_action' => [
45				'required' => false,
46				'name' => tra('Cart Action'),
47				'description' => tra('Action if Shopping Cart selected for type'),
48				'since' => '11.0',
49				'filter' => 'word',
50				'options' => [
51					['text' => '', 'value' => ''],
52					['text' => tra('Add to Cart'), 'value' => 'add'],
53					['text' => tra('View Cart'), 'value' => 'display'],
54					//array('text' => tra('Cart Upload'), 'value' => 'upload'),	// N/A
55				],
56				'default' => 'add',
57			],
58			'item_name' => [
59				'required' => false,
60				'name' => tra('Item Name'),
61				'description' => tra('Item name or description. Required for Shopping cart'),
62				'since' => '11.0',
63				'filter' => 'text',
64				'default' => '',
65			],
66			'amount' => [
67				'required' => false,
68				'name' => tra('Price'),
69				'description' => tra('Item price'),
70				'since' => '11.0',
71				'filter' => 'text',
72				'default' => '',
73			],
74			'paypal_button' => [
75				'required' => false,
76				'name' => tra('PayPal Button'),
77				'description' => tra('Button appearance'),
78				'since' => '11.0',
79				'filter' => 'text',
80				'options' => [
81					['text' => tra('Normal'), 'value' => ''],
82					['text' => tra('Smaller'), 'value' => 'small_button'],
83					['text' => tra('Custom'), 'value' => 'custom'],
84				],
85				'default' => '',
86			],
87			'custom_image_url' => [
88				'required' => false,
89				'name' => tra('Custom Button'),
90				'description' => tra('Custom button image URL'),
91				'since' => '11.0',
92				'filter' => 'url',
93				'default' => '',
94			],
95			'item_number' => [
96				'required' => false,
97				'name' => tra('Product ID'),
98				'description' => tra('Optional item identifier, often a tracker itemId'),
99				'since' => '11.0',
100				'filter' => 'text',
101				'default' => '',
102			],
103			'quantity' => [
104				'required' => false,
105				'name' => tra('Quantity'),
106				'description' => tra('Number of items, empty or 0 to have an input the user can fill in'),
107				'since' => '11.0',
108				'filter' => 'text',
109				'default' => '',
110			],
111			'shipping' => [
112				'required' => false,
113				'name' => tra('Shipping Cost'),
114				'description' => tra('The cost of shipping this item'),
115				'since' => '11.0',
116				'filter' => 'text',
117				'default' => '',
118				'advanced' => true,
119			],
120			'shipping2' => [
121				'required' => false,
122				'name' => tra('Additional Shipping Cost'),
123				'description' => tra('The cost of shipping each additional unit of this item'),
124				'since' => '11.0',
125				'filter' => 'text',
126				'default' => '',
127				'advanced' => true,
128			],
129			'weight' => [
130				'required' => false,
131				'name' => tra('Weight'),
132				'description' => tra('Weight of item'),
133				'since' => '11.0',
134				'filter' => 'text',
135				'default' => '',
136				'advanced' => true,
137			],
138			'weight_unit' => [
139				'required' => false,
140				'name' => tra('Weight Unit'),
141				'description' => tra('The unit of measure if weight is specified'),
142				'since' => '11.0',
143				'filter' => 'word',
144				'options' => [
145					['text' => '', 'value' => ''],
146					['text' => tra('Kilos'), 'value' => 'kgs'],
147					['text' => tra('Pounds'), 'value' => 'lbs'],
148				],
149				'default' => 'kgs',
150				'advanced' => true,
151			],
152			'business' => [
153				'required' => false,
154				'name' => tra('Business ID'),
155				'description' => tra('PayPal business name/ID') . ' ' . tra('(Uses value in admin/payment if not set here)'),
156				'since' => '11.0',
157				'filter' => 'text',
158				'default' => $prefs['payment_paypal_business'],
159				'advanced' => ! empty($prefs['payment_paypal_business']),	// if set in prefs shouldn't need to change it here
160			],
161			'minicart' => [
162				'required' => false,
163				'name' => tra('Use MiniCart'),
164				'description' => tra('See https://github.com/jeffharrell/MiniCart'),
165				'since' => '11.0',
166				'filter' => 'alpha',
167				'options' => [
168					['text' => '', 'value' => ''],
169					['text' => tra('Yes'), 'value' => 'y'],
170					['text' => tra('No'), 'value' => 'n'],
171				],
172				'default' => 'y',
173				'advanced' => true,
174			],
175			'no_shipping' => [
176				'required' => false,
177				'name' => tra('Shipping Address Prompt'),
178				'description' => tra('Indicate whether to prompt for and require an address'),
179				'since' => '11.0',
180				'filter' => 'digits',
181				'options' => [
182					['text' => '', 'value' => ''],
183					['text' => tra('Prompt for address'), 'value' => 0],
184					['text' => tra('Do not prompt for address'), 'value' => 1],
185					['text' => tra('Prompt for and require address'), 'value' => 2],
186				],
187				'default' => 2,
188				'advanced' => true,
189			],
190			'return' => [
191				'required' => false,
192				'name' => tra('Completed payment return URL'),
193				'description' => tr('Empty for current page, %0n%1 to disable', '<code>', '</code>'),
194				'since' => '11.0',
195				'filter' => 'text',
196				'default' => '',
197				'advanced' => true,
198			],
199			'shopping_url' => [
200				'required' => false,
201				'name' => tra('Continue Shopping URL'),
202				'description' => tr('Empty for current page, %0n%1 to disable', '<code>', '</code>'),
203				'since' => '11.0',
204				'filter' => 'text',
205				'default' => '',
206				'advanced' => true,
207			],
208			'cancel_return' => [
209				'required' => false,
210				'name' => tra('Cancel payment URL'),
211				'description' => tr('Empty for current page, %0n%1 to disable', '<code>', '</code>'),
212				'since' => '11.0',
213				'filter' => 'text',
214				'default' => '',
215				'advanced' => true,
216			],
217			'title' => [
218				'required' => false,
219				'name' => tra('Form title'),
220				'description' => tra('Tooltip for the form and alt attribute for the image'),
221				'since' => '11.0',
222				'filter' => 'text',
223				'default' => tra('PayPalThe safer, easier way to pay online.'),
224				'advanced' => true,
225			],
226			'stringButton' => [
227				'required' => false,
228				'name' => tra('Button text'),
229				'description' => tra('The checkout button text'),
230				'since' => '11.0',
231				'filter' => 'text',
232				'default' => 'Checkout',
233				'advanced' => true,
234			],
235			'stringSubtotal' => [
236				'required' => false,
237				'name' => tra('Subtotal text'),
238				'description' => tra('The subtotal text'),
239				'since' => '11.0',
240				'filter' => 'text',
241				'default' => 'Subtotal: ',
242				'advanced' => true,
243			],
244			'stringDiscount' => [
245				'required' => false,
246				'name' => tra('Discount text'),
247				'description' => tra('The discount text'),
248				'since' => '11.0',
249				'filter' => 'text',
250				'default' => 'Discount: ',
251				'advanced' => true,
252			],
253			'stringShipping' => [
254				'required' => false,
255				'name' => tra('Shipping text'),
256				'description' => tra('The shipping text'),
257				'since' => '11.0',
258				'filter' => 'text',
259				'default' => 'does not include shipping &amp; tax',
260				'advanced' => true,
261			],
262			'stringProcessing' => [
263				'required' => false,
264				'name' => tra('Processing text'),
265				'description' => tra('The processing text'),
266				'since' => '11.0',
267				'filter' => 'text',
268				'default' => 'Processing...',
269				'advanced' => true,
270			],
271		],
272	];
273}
274
275function wikiplugin_paypal($data, $params)
276{
277	global $prefs, $language, $base_uri, $base_host;
278	static $id = 0;
279
280	$unique = 'wppaypal-' . ++$id;
281	$smarty = TikiLib::lib('smarty');
282
283	// process default
284	$plugininfo = wikiplugin_paypal_info();
285	foreach ($plugininfo['params'] as $key => $p) {
286		$default[$key] = $p['default'];
287	}
288	$params = array_merge($default, $params);
289
290	// check required params
291	if (empty($params['business'])) {
292		$access = TikiLib::lib('access');
293		$access->check_feature('payment_paypal_business');
294	}
295
296	if ($params['cmd'] === '_cart') {
297		if (empty($params['item_name'])) {
298			return '<span class="alert-warning">' . tra('PayPal button:') . ' ' . tra('Item name (item_name) required') . '</span>';
299		}
300		if (empty($params['amount'])) {
301			return '<span class="alert-warning">' . tra('PayPal button:') . ' ' . tra('Price (amount) required') . '</span>';
302		}
303
304		$params[$params['cart_action']] = 1;
305		unset($params['cart_action']);
306	}
307
308	// process others
309	if ($prefs['payment_feature'] === 'y' && ! empty($prefs['payment_currency'])) {
310		$params['currency_code'] = $prefs['payment_currency'];
311	}
312
313	if (empty($params['weight'])) {
314		unset($params['weight_unit']);
315	}
316
317	// logic handled in the tpl
318	$smarty->assign('wppaypal_quantity', $params['quantity']);
319	unset($params['quantity']);
320	$smarty->assign('wppaypal_title', $params['title']);
321	unset($params['title']);
322
323	global $paypallib;
324	include_once('lib/payment/paypallib.php');
325	$locale = $paypallib->localeMap($language);		// 'lc' locale param TODO maybe
326
327	// button image
328	if (! empty($params['custom_image_url']) && $params['paypal_button'] === 'custom') {
329		$button_url = $params['custom_image_url'];
330	} else {
331		switch ($params['cmd']) {
332			case '_cart':
333				if (isset($params['add'])) {
334					$button_type = 'cart';
335				} elseif (isset($params['display'])) {
336					$button_type = 'viewcart';
337				}
338				break;
339			case '_xclick':
340				$button_type = 'buynow';
341				break;
342			case 'donations':
343				$button_type = 'donate';
344				break;
345			default:
346				$button_type = 'paynow';
347		}
348		$size = $params['paypal_button'] === 'small_button' ? 'SM' : 'LG';
349		$button_url = "https://www.paypalobjects.com/{$locale}/i/btn/btn_{$button_type}_{$size}.gif";
350	}
351	$pixel_url = "https://www.paypalobjects.com/{$locale}/i/scr/pixel.gif";
352
353	$smarty->assign('wppaypal_button', $button_url);
354	$smarty->assign('wppaypal_pixel', $pixel_url);
355	unset($params['custom_image_url']);
356	unset($params['paypal_button']);
357
358	// return params
359	if (! empty($_SERVER['REQUEST_URI'])) {
360		$returnUrl = $base_host . $_SERVER['REQUEST_URI'];
361	} else {
362		$returnUrl = $base_uri;
363	}
364	if (strpos($returnUrl, 'tiki-ajax_services.php') !== false ||
365			(isset($_REQUEST['controller']) && $_REQUEST['controller'] === 'search_customsearch')) {
366		$csearchEvent = 'pageSearchReady';
367		if (! empty($_SERVER['HTTP_REFERER'])) {
368			$returnUrl = $_SERVER['HTTP_REFERER'];
369		}
370		$csearchInit = 'paypal = {}; $("#PPMiniCart").fadeOut().remove();';
371	} else {
372		$csearchEvent = 'ready';
373		$csearchInit = '';
374	}
375	foreach (['return', 'shopping_url', 'cancel_return'] as $ret) {
376		if (empty($params[$ret])) {
377			$params[$ret] = $returnUrl;
378		} elseif ($params[$ret] === 'n') {
379			unset($params[$ret]);
380		}
381	}
382
383	// just add javascript?
384	$jsfile = 'vendor_bundled/vendor/jquery/minicart/dist/minicart' . ($prefs['tiki_minify_javascript'] === 'y' ? '.min' : '') . '.js';
385	if ($params['minicart'] === 'y' && file_exists($jsfile)) {
386		// it appears currently if you set any of these all must be set
387		$miniParams = ['strings' => []];
388		$miniParams['strings']['button']     = tra($params['stringButton']);
389		$miniParams['strings']['subtotal']   = tra($params['stringSubtotal']);
390		$miniParams['strings']['discount']   = tra($params['stringDiscount']);
391		$miniParams['strings']['shipping']   = tra($params['stringShipping']);
392		$miniParams['strings']['processing'] = tra($params['stringProcessing']);
393		// this seems to be the only secure URL for these assets, minicart.com uses github's SSL certificate
394		$miniParams['assetURL'] = 'https://github.com/jeffharrell/minicart/raw/3.0.6/';
395		$miniParamStr = json_encode($miniParams);
396
397		TikiLib::lib('header')->add_js(
398			'
399$(document).on("' . $csearchEvent . '", function () {
400	' . $csearchInit . ' $.getScript("' . $jsfile . '", function() {
401			paypal.minicart.render(' . $miniParamStr . ');
402		});
403});'
404		)->add_css('#PPMiniCart {z-index: 1040;}');	// make sure it clears the fixed page-header
405	}
406	unset($params['minicart']);
407
408
409	//$params['item_name'] = htmlentities($params['item_name']);	// FIXME encoding problems!
410
411	// all remaining non-empty params get turned into hidden form inputs
412	$params = array_filter($params);
413	$smarty->assign_by_ref('wppaypal_hiddens', $params);
414
415	return $smarty->fetch('wiki-plugins/wikiplugin_paypal.tpl');
416}
417