PageRenderTime 1142ms CodeModel.GetById 23ms RepoModel.GetById 92ms app.codeStats 0ms

/easyshop_class.php

https://github.com/nlstart/easyshop
PHP | 916 lines | 711 code | 55 blank | 150 comment | 159 complexity | 7accc8d4c3c64cce31f84d916fdf3ea4 MD5 | raw file
  1. <?php
  2. /*
  3. +------------------------------------------------------------------------------+
  4. | EasyShop - an easy e107 web shop | adapted by nlstart
  5. | formerly known as
  6. | jbShop - by Jesse Burns aka jburns131 aka Jakle
  7. | Plugin Support Site: e107.webstartinternet.com
  8. |
  9. | For the e107 website system visit http://e107.org
  10. |
  11. | Released under the terms and conditions of the
  12. | GNU General Public License (http://gnu.org).
  13. +------------------------------------------------------------------------------+
  14. */
  15. class ShopMail
  16. {
  17. function easyshop_sendemail($send_to, $subject, $message, $headers2, $attachment_name) {
  18. $domain_name = General::parseUrl(e_SELF); // Parse the current url
  19. $domain_name = $domain_name[host]; // Retrieve the host name from the parsed array
  20. require_once(e_HANDLER.'mail.php');
  21. // $bcc_mail = "yourmailaccount@yourdomain.tld";
  22. if (!sendemail($send_to, $subject, $message, $to_name, "no-reply@".$domain_name, "EasyShop", $attachment_name, "", $bcc_mail)) {
  23. return FALSE;
  24. } else { // E-mail was send succesfully
  25. return TRUE;
  26. }
  27. }
  28. function easyshop_senddownloads($array, $to_email)
  29. {
  30. $address = $to_email;
  31. // Loop throught the basket to detect dowloadable products
  32. foreach($array as $id => $item) {
  33. $sql = new db;
  34. $sql -> db_Select(DB_TABLE_SHOP_ITEMS, "*", "item_id=$item[db_id]");
  35. if ($row = $sql-> db_Fetch()){
  36. $download_product = $row['download_product'];
  37. $download_filename = $row['download_filename'];
  38. // Check if this is a downloadable product with valid download filename
  39. if ($download_product == 2 && strlen($download_filename) > 0) {
  40. $scrambled_name = intval($item[db_id]).$download_filename;
  41. $attachment_name_scrambled = "downloads/".MD5($scrambled_name);
  42. $attachment_name = "downloads/".$download_filename;
  43. // Create temporary original file to download with unscrambled name
  44. if (!copy($attachment_name_scrambled, $attachment_name)) {
  45. $message = EASYSHOP_CLASS_02." $attachment_name_scrambled...\n";
  46. }
  47. $subject = EASYSHOP_CLASS_03." ".$item[item_name]." ".date("Y-m-d");
  48. $message = EASYSHOP_CLASS_04.": ".$download_filename."\n";
  49. // $message .= "Download filename scrambled: ".$attachment_name_scrambled."\n"; // debug info
  50. // $message .= "Download filename: ".$attachment_name; // debug info
  51. if(!ShopMail::easyshop_sendemail($address, $subject, $message, $header, $attachment_name)) {
  52. $message = EASYSHOP_CLASS_05; // Sending downloadable product failed
  53. }
  54. // Delete the temporary download file
  55. unlink($attachment_name);
  56. } // End of the if downloadable product with valid download filename
  57. } // End of the if product fetch
  58. // Make sure the variables are empty before going into the while loop again
  59. $download_product = "";
  60. $download_filename = "";
  61. }
  62. }
  63. function easyshop_sendalert($product_id, $newstock, $minimum_level, $alert_type)
  64. // Send alerts to shop owner
  65. // Parameters:
  66. // $product_id = the item_id that the alert is send for
  67. // $newstock = actual number of product in stock including this purchase
  68. // $minimum_level = minimum number of product that should be in stock
  69. // $alert_type = 1 : mimimum stock level alert
  70. // 2 : customer paid for more products than in stock
  71. // 3 : product is out of stock
  72. {
  73. // Determine admin e-mail address from e107 preferences
  74. global $pref;
  75. $to_email = (!(isset($pref['siteadminemail']) && strlen($pref['siteadminemail'])==0)?$pref['replyto_email']:$pref['siteadminemail']); // Keep 0.7.8 compatible
  76. // Retrieve product data
  77. $product_id = intval($product_id);
  78. $sql = new db;
  79. $sql -> db_Select(DB_TABLE_SHOP_ITEMS, "*", "item_id=$product_id");
  80. if ($row = $sql-> db_Fetch()){
  81. // Set subject and message for each alert type
  82. if ($alert_type == "1") { // Alert 1: stock is below minimum level of this product
  83. $subject = EASYSHOP_CLASS_06." ".$row['item_name'];
  84. $message = EASYSHOP_CLASS_08." <a href='".SITEURL.e_PLUGIN."easyshop/easyshop.php?prod.".$product_id."'>".$row['item_name']."</a>!<br /><br />
  85. ".EASYSHOP_CLASS_09.": $minimum_level<br />
  86. ".EASYSHOP_CLASS_10.": $newstock";
  87. }
  88. if ($alert_type == "2") { // Alert 2: last buyer purchased more of this product than actual in stock
  89. $subject = EASYSHOP_CLASS_07." ".$row['item_name'];
  90. $message = EASYSHOP_CLASS_11." <a href='".SITEURL.e_PLUGIN."easyshop/easyshop.php?prod.".$product_id."'>".$row['item_name']."</a>!<br /><br />
  91. ".EASYSHOP_CLASS_09.": $minimum_level<br />
  92. ".EASYSHOP_CLASS_10.": $newstock";
  93. }
  94. if ($alert_type == "3") { // Alert 3: product is out of stock
  95. $subject = EASYSHOP_CLASS_12." ".$row['item_name'];
  96. $message = EASYSHOP_CLASS_13." <a href='".SITEURL.e_PLUGIN."easyshop/easyshop.php?prod.".$product_id."'>".$row['item_name']."</a>!<br />";
  97. }
  98. // Send alert
  99. ShopMail::easyshop_sendemail($to_email, $subject, $message, $header, $attachment_name);
  100. }
  101. }
  102. }
  103. class Security
  104. {
  105. function get_session_id()
  106. {
  107. static $session_id;
  108. if ( $session_id == "" ) // 1.31 fix: setting static already sets the variable; thanks KVN
  109. {
  110. $session_id = session_id();
  111. }
  112. return $session_id;
  113. }
  114. }
  115. class General
  116. {
  117. function multiple_paging($total_pages,$items_per_page,$action,$action_id,$page_id,$page_devider)
  118. // Parameters: $total_pages = the total pages that must be paginated
  119. // $items_per_page = the number of items represented per page
  120. // $action = action from url, e.g. catpage or prodpage
  121. // $action_id = action_id from url
  122. // $page_devider is the page devide character
  123. {
  124. if (trim($page_id) <> "" or $page_id > 0) {
  125. $f_action_id = $page_id; // For prodpage or catpage the $page_id is the page indicator
  126. } else {
  127. $f_action_id = $action_id; // For mcatpage the $action_id is the page indicator
  128. }
  129. if ($action == "mcatpage" || $action == "catpage") {
  130. $f_action_id = $action_id; // For mcatpage and catpage the $action_id is the page indicator
  131. }
  132. $last_page = intval(($total_pages + $items_per_page - 1) / $items_per_page); // Rounded last page number
  133. if ($last_page > 1 ) { // Suppress page indication if there is only one page
  134. $page_count = 1;
  135. if ($f_action_id == "" or $f_action_id < 1 or $f_action_id == null) {
  136. $f_action_id = 1; // Set initial page if no page parameter or illegal parameter is given
  137. }
  138. while ($page_count <= $last_page) { // For each page counter display a page
  139. if ( $page_count == $f_action_id ) { // If it is the page itself, no link
  140. //if ( $page_count == $last_page) { // If it is the page itself, no link
  141. $page_text .= " ".EASYSHOP_SHOP_05." ".$page_count." ".$page_devider;
  142. } else { // This is a different page than the current one, provide a link
  143. //$offset = $items_per_page * ($page_count - 1);
  144. if ($action == "catpage" or $action == "allcat") {
  145. $page_text .= " <a href='".e_SELF."?catpage.".$page_count."'>".EASYSHOP_SHOP_05." ".$page_count."</a> ".$page_devider;
  146. }
  147. if ($action == "cat" or $action == "prodpage") {
  148. $page_text .= " <a href='".e_SELF."?prodpage.".$action_id.".".$page_count."'>".EASYSHOP_SHOP_05." ".$page_count."</a> ".$page_devider;
  149. }
  150. if ($action == "blanks") {
  151. $page_text .= " <a href='".e_SELF."?blanks.".$page_count."'>".EASYSHOP_SHOP_05." ".$page_count."</a> ".$page_devider;
  152. }
  153. if ($action == "mcat") {
  154. $page_text .= " <a href='".e_SELF."?mcat.".$action_id.".".$page_count."'>".EASYSHOP_SHOP_05." ".$page_count."</a> ".$page_devider;
  155. }
  156. if ($action == "" or $action == "mcatpage") {
  157. $page_text .= " <a href='".e_SELF."?mcatpage.".$page_count."'>".EASYSHOP_SHOP_05." ".$page_count."</a> ".$page_devider;
  158. }
  159. }
  160. // Some debug info
  161. //$page_text .= " lastpage: $last_page, items per page: $items_per_page, page_count: $page_count, total_pages: $total_pages <br /> ";
  162. //$page_text .= " f_action_id: $f_action_id page_id: $page_id <br /> ";
  163. $page_count++;
  164. }
  165. $page_text = substr($page_text, 0, -(strlen($page_devider))); // Remove length of last divider character from page string
  166. }
  167. return $page_text;
  168. }
  169. function determine_offset($f_action,$f_action_id,$f_items_per_page)
  170. // Parameters: $action = action from url, e.g. catpage or prodpage
  171. // $action_id = action_id from url
  172. // $items_per_page = the number of items represented per page
  173. {
  174. if ($f_action == null ) {
  175. $f_offset = 0;
  176. } else {
  177. if ($f_action_id == null or $f_action_id <= 0 or $f_action_id == "") {
  178. $f_offset = 0;
  179. } else {
  180. $f_offset = $f_items_per_page * ($f_action_id - 1);
  181. }
  182. }
  183. return $f_offset;
  184. }
  185. function validateDecimal($f_value) {
  186. // Parameter: $f_value = value to be checked on maximum of 2 decimals
  187. if (!ereg("^[+-]?[0-9]*\.?[0-9]{0,2}$", $f_value)) {
  188. // Not a decimal;
  189. return false;
  190. }
  191. return true;
  192. }
  193. function getCommentTotal($pluginid, $id) {
  194. // Get number of comments for an item.
  195. // This method returns the number of comments for the supplied plugin/item id.
  196. // @param string a unique ID for this plugin, maximum of 10 character
  197. // @param int id of the item comments are allowed for
  198. // @return int number of comments for the supplied parameters
  199. global $pref, $e107cache, $tp;
  200. $query = "where comment_item_id='$id' AND comment_type='$pluginid'";
  201. $mysql = new db();
  202. return $mysql->db_Count("comments", "(*)", $query);
  203. }
  204. function getCurrentVersion(){
  205. $current_version = strtolower(trim(file_get_contents('http://e107.webstartinternet.com/files/downloads/easyshop_ver.php')));
  206. return $current_version;
  207. }
  208. function getEasyShopDownloadDir() {
  209. $download_dir = "http://e107.webstartinternet.com/download.php?list.5";
  210. return $download_dir;
  211. }
  212. function Array_Clean($str,&$array) {
  213. // Cleans a given string from an array
  214. // @param string the string that you want to delete from an array
  215. // @param array the name of the array you want to apply the clean function
  216. if (in_array($str,$array)==true) {
  217. foreach ($array as $key=>$value) {
  218. if ($value==$str) unset($array[$key]);
  219. }
  220. }
  221. }
  222. function CreateRandomDiscountCode() {
  223. // Letter O (uppercase o) is not included; can be confused with zero (0)
  224. // The letter l (lowercase L), and the number 1 have been removed, as they can be easily mixed up
  225. $chars = "AaBbCcDdEeFfGgHhIiJjKkLMmNnoPpQqRrSsTtUuVvWwXxYyZz023456789,.;:#$%*=+[]";
  226. srand((double)microtime()*1000000);
  227. $i = 0;
  228. $random_discount_code = '' ;
  229. while ($i <= 5) { // Create a 6 character random code
  230. $num = rand() % 69;
  231. $tmp = substr($chars, $num, 1);
  232. $random_discount_code = $random_discount_code . $tmp;
  233. $i++;
  234. }
  235. return htmlspecialchars($random_discount_code);
  236. }
  237. function parseUrl($url) {
  238. $r = "^(?:(?P<scheme>\w+)://)?";
  239. $r .= "(?:(?P<login>\w+):(?P<pass>\w+)@)?";
  240. $r .= "(?P<host>(?:(?P<subdomain>[-\w\.]+)\.)?" . "(?P<domain>[-\w]+\.(?P<extension>\w+)))";
  241. $r .= "(?::(?P<port>\d+))?";
  242. $r .= "(?P<path>[\w/]*/(?P<file>\w+(?:\.\w+)?)?)?";
  243. $r .= "(?:\?(?P<arg>[\w=&]+))?";
  244. $r .= "(?:#(?P<anchor>\w+))?";
  245. $r = "!$r!"; // Delimiters
  246. preg_match ( $r, $url, $out );
  247. return $out;
  248. }
  249. function easyshop_theme_head() {
  250. return "<link rel='stylesheet' href='".e_PLUGIN."easyshop/tabs.css' />\n";
  251. }
  252. } // End of class General
  253. class Shop
  254. {
  255. function switch_columns($p_num_item_columns) {
  256. // Returns column width percentage variable $column_width
  257. // @param integer the number of item columns from the settings
  258. switch ($p_num_item_columns) {
  259. case 1:
  260. $column_width = '100%';
  261. break;
  262. case 2:
  263. $column_width = '50%';
  264. break;
  265. case 3:
  266. $column_width = '33%';
  267. break;
  268. case 4:
  269. $column_width = '25%';
  270. break;
  271. case 5:
  272. $column_width = '20%';
  273. break;
  274. }
  275. return $column_width;
  276. }
  277. function show_checkout($p_session_id, $p_special_instr_text) {
  278. // Default checkout method with PayPal (IPN)
  279. // Parameter $p_session_id is used to check the users' current session ID to prevent XSS vulnarabilities
  280. // Parameter $p_special_instr_text is used to pass e-mail special instructions for seller
  281. //if ($p_session_id != session_id()) { // Get out of here: incoming session id is not equal than current session id
  282. // header("Location: ".e_BASE); // Redirect to the home page
  283. // exit();
  284. //}
  285. // Check query
  286. if(e_QUERY){
  287. $tmp = explode(".", e_QUERY);
  288. $action = $tmp[0];
  289. unset($tmp);
  290. }
  291. $sql2 = new db;
  292. $sql2 -> db_Select(DB_TABLE_SHOP_PREFERENCES, "*", "store_id=1");
  293. if ($row2 = $sql2-> db_Fetch()){
  294. $sandbox = $row2['sandbox'];
  295. $paypal_email = $row2['paypal_email'];
  296. $payment_page_style = $row2['payment_page_style'];
  297. $paypal_currency_code = $row2['paypal_currency_code'];
  298. $set_currency_behind = $row2['set_currency_behind'];
  299. $minimum_amount = intval($row2['minimum_amount']);
  300. $always_show_checkout = $row2['always_show_checkout'];
  301. $email_order = $row2['email_order'];
  302. $show_shopping_bag = $row2['show_shopping_bag'];
  303. $print_special_instr = $row2['print_special_instr'];
  304. $enable_ipn = $row2['enable_ipn']; // IPN addition
  305. }
  306. $sql3 = new db;
  307. $sql3 -> db_Select(DB_TABLE_SHOP_CURRENCY, "*", "currency_active=2");
  308. if ($row3 = $sql3-> db_Fetch()){
  309. $unicode_character = $row3['unicode_character'];
  310. $paypal_currency_code = $row3['paypal_currency_code'];
  311. }
  312. // Determine currency before or after amount
  313. if ($set_currency_behind == 1) {
  314. // Print currency after amount
  315. $unicode_character_before = "";
  316. $unicode_character_after = "&nbsp;".$unicode_character;
  317. }
  318. else {
  319. $unicode_character_before = "&nbsp;".$unicode_character."&nbsp;";
  320. $unicode_character_after = "";
  321. // Print currency before amount in all other cases
  322. }
  323. if ($email_order == 1) {
  324. $actionDomain = e_SELF;
  325. } else {
  326. if ($sandbox == 2) {
  327. $actionDomain = "https://www.sandbox.paypal.com/cgi-bin/webscr";
  328. } else {
  329. $actionDomain = "https://www.paypal.com/cgi-bin/webscr";
  330. }
  331. }
  332. // Display check out button
  333. $f_text = ""; // initialise
  334. if(($enable_ipn == 2) && ($_SESSION['sc_total']['items'] > 0) && $email_order <> 1){ // IPN addition if IPN_enabled - use AJAX
  335. $f_text .= "
  336. <form action='track_checkout.php' method='POST'>
  337. <!-- <span id='checkoutbutton'> -->
  338. <div>
  339. <input type='hidden' name='phpsessionid' value='".session_id()."'/>
  340. <input type='hidden' name='source_url' value='".urlencode(e_SELF.(e_QUERY ? "?".e_QUERY : ""))."'/>
  341. <input class='button' type='submit' value='".EASYSHOP_CLASS_01."'/>
  342. </div>
  343. <!-- </span> -->
  344. </form>";
  345. } else {
  346. $f_text = ""; // Initialize variable
  347. // <form target='_blank' action='$paypalDomain/cgi-bin/webscr' method='post'> leads to XHTML incompatibility caused by target
  348. $f_text .= "
  349. <form action='$actionDomain' method='post'>
  350. <input type='hidden' name='cmd' value='_cart'/>
  351. <input type='hidden' name='upload' value='1'/>
  352. <input type='hidden' name='business' value='$paypal_email'/>
  353. <input type='hidden' name='page_style' value='$payment_page_style'/>";
  354. // Fill the Cart with products from the basket
  355. $count_items = count($_SESSION['shopping_cart']); // Count number of different products in basket
  356. $array = $_SESSION['shopping_cart'];
  357. $cart_count = 1; // PayPal requires to pass multiple products in a sequence starting at 1
  358. // For each product in the shopping cart array write PayPal details
  359. foreach($array as $id => $item) {
  360. $f_text .= "
  361. <input type='hidden' name='item_name_".$cart_count."' value='".$item['item_name']."'/>
  362. <input type='hidden' name='item_number_".$cart_count."' value='".$item['sku_number']."'/>
  363. <input type='hidden' name='amount_".$cart_count."' value='".$item['item_price']."'/>
  364. <input type='hidden' name='quantity_".$cart_count."' value='".$item['quantity']."'/>
  365. <input type='hidden' name='shipping_".$cart_count."' value='".$item['shipping']."'/>
  366. <input type='hidden' name='shipping2_".$cart_count."' value='".$item['shipping2']."'/>
  367. <input type='hidden' name='handling_".$cart_count."' value='".$item['handling']."'/>
  368. <input type='hidden' name='db_id_".$cart_count."' value='".$item['db_id']."' />";
  369. $cart_count++;
  370. }
  371. $thanks_page = str_replace('easyshop.php', 'thank_you.php', e_SELF); // Set thanks page to correct value
  372. $f_text .= "
  373. <input type='hidden' name='currency_code' value='$paypal_currency_code'/>
  374. <input type='hidden' name='no_note' value='1'/>
  375. <input type='hidden' name='lc' value='US'/>
  376. <input type='hidden' name='bn' value='PP-ShopCartBF'/>
  377. <input type='hidden' name='rm' value='1'/>
  378. <input type='hidden' name='return' value='".$thanks_page."'/>";
  379. }
  380. if((!$enable_ipn == 2 || $email_order == 1) && ($_SESSION['sc_total']['items'] > 0)){ // nlstart fix: here too! :) ### IPN addition if IPN_enabled - use AJAX
  381. // in case setting always show checkout button is off
  382. if ($always_show_checkout == 0) {
  383. // When there are items in the shopping cart, display 'Go to checkout' button
  384. if ($_SESSION['sc_total']['items'] > 0) {
  385. // Only show 'Go to checkout' if total amount is above minimum amount
  386. if ($_SESSION['sc_total']['sum'] > $minimum_amount) {
  387. if ($email_order == 1) {
  388. // Only show enter special instructions if setting is 'On'
  389. if ($print_special_instr == 1) {
  390. // Only show special instruction text form in basket edit mode
  391. if ($action == "edit" && $_SESSION['easyshop_menu'] == false) {
  392. $f_text .= "
  393. <table border='0' class='tborder' cellspacing='5'>
  394. <tr>
  395. <td class='tborder' style='width: 200px' valign='top'>
  396. <span class='smalltext' style='font-weight: bold'>
  397. ".EASYSHOP_SHOP_82."
  398. </span>
  399. <br />
  400. ".EASYSHOP_SHOP_83."
  401. </td>
  402. <td class='tborder' style='width: 200px'>
  403. <textarea class='tbox' cols='50' rows='2' name='special_instr_text'>$p_special_instr_text</textarea>
  404. </td>
  405. </tr>
  406. </table>";
  407. } else { // In the easyshop_menu, main cat, cat and product level display a link
  408. $f_text .= "
  409. <div style='text-align:center;'>
  410. <a href='".e_PLUGIN_ABS."easyshop/easyshop.php?edit'>".EASYSHOP_SHOP_82."</a><br /><br />
  411. </div>";
  412. }
  413. }
  414. $f_text .= "
  415. <input type='hidden' name='email_order' value='1'/>
  416. <input class='button' type='submit' value='".EASYSHOP_SHOP_09."'/>";
  417. }
  418. if ($enable_ipn == 0 && $email_order <> 1) { // Enable standard checkout button
  419. $f_text .= "
  420. <input class='button' type='submit' value='".EASYSHOP_SHOP_09."'/>";
  421. }
  422. } else { // Minimum amount has not been reached; inform the shopper
  423. $f_text .=
  424. EASYSHOP_SHOP_36." : ".$unicode_character_before.number_format($minimum_amount, 2, '.', '').$unicode_character_after." <br />
  425. ".EASYSHOP_SHOP_37." : ".$unicode_character_before.number_format(($minimum_amount - $_SESSION['sc_total']['sum']), 2, '.', '').$unicode_character_after;
  426. }
  427. }
  428. }
  429. // in case setting always display checkout button is on
  430. if ($always_show_checkout == 1) {
  431. $f_text .= "
  432. <input class='button' type='submit' value='".EASYSHOP_SHOP_09."'/>";
  433. }
  434. }
  435. $f_text .= "
  436. </form>
  437. <br />"; // Finally fix the form close issues once and for all v1.54 ;-)
  438. // Show 'Manage your basket link'
  439. if ($_SESSION['sc_total']['items'] > 0 AND $action != "edit") {
  440. $f_text .= "
  441. <div style='text-align:center;'>
  442. <a href='".e_PLUGIN_ABS."easyshop/easyshop.php?edit'>".EASYSHOP_SHOP_35."</a>";
  443. // Conditionally show cart icon (dependent on show shopping bag flag)
  444. if ($show_shopping_bag == '1') {
  445. $f_text .= "
  446. &nbsp;<a href='".e_PLUGIN_ABS."easyshop/easyshop.php?edit'><img style='border:0;' src='".e_PLUGIN_ABS."easyshop/images/cart.gif' alt='".EASYSHOP_SHOP_35."'/></a>";
  447. }
  448. $f_text .= "
  449. </div>";
  450. }
  451. /* // Some debug info
  452. print_r($_SESSION['shopping_cart']);
  453. print ("<br />");
  454. print_r($_SESSION['sc_total']);
  455. print ("<br />");
  456. print_r($_SESSION['sc_total']['shipping']);
  457. print ("<br />");
  458. print_r($_SESSION['sc_total']['shipping2']);
  459. print ("<br />");
  460. print_r($_SESSION['sc_total']['handling']);
  461. print ("<br />");
  462. */
  463. return $f_text;
  464. }
  465. function show_ipn_checkout($p_session_id) {
  466. // Parameter $p_session_id is used to check the users' current session ID to prevent XSS vulnarabilities
  467. //if ($p_session_id != session_id()) { // Get out of here: incoming session id is not equal than current session id
  468. // header("Location: ".e_BASE); // Redirect to the home page
  469. // exit();
  470. //}
  471. // Check query
  472. if(e_QUERY){
  473. $tmp = explode(".", e_QUERY);
  474. $action = $tmp[0];
  475. unset($tmp);
  476. }
  477. $sql2 = new db;
  478. $sql2 -> db_Select(DB_TABLE_SHOP_PREFERENCES, "*", "store_id=1");
  479. while($row2 = $sql2-> db_Fetch()){
  480. $sandbox = $row2['sandbox'];
  481. $paypal_email = $row2['paypal_email'];
  482. $payment_page_style = $row2['payment_page_style'];
  483. $paypal_currency_code = $row2['paypal_currency_code'];
  484. $set_currency_behind = $row2['set_currency_behind'];
  485. $minimum_amount = intval($row2['minimum_amount']);
  486. $always_show_checkout = $row2['always_show_checkout'];
  487. $email_order = $row2['email_order'];
  488. }
  489. $sql3 = new db;
  490. $sql3 -> db_Select(DB_TABLE_SHOP_CURRENCY, "*", "currency_active=2");
  491. while($row3 = $sql3-> db_Fetch()){
  492. $unicode_character = $row3['unicode_character'];
  493. $paypal_currency_code = $row3['paypal_currency_code'];
  494. }
  495. // Determine currency before or after amount
  496. if ($set_currency_behind == 1) {
  497. // Print currency after amount
  498. $unicode_character_before = "";
  499. $unicode_character_after = "&nbsp;".$unicode_character;
  500. }
  501. else {
  502. $unicode_character_before = "&nbsp;".$unicode_character."&nbsp;";
  503. $unicode_character_after = "";
  504. // Print currency before amount in all other cases
  505. }
  506. if ($sandbox == 2) {
  507. $paypalDomain = "https://www.sandbox.paypal.com";
  508. } else {
  509. $paypalDomain = "https://www.paypal.com";
  510. }
  511. // Display check out button
  512. // <form target='_blank' action='$paypalDomain/cgi-bin/webscr' method='post'> leads to XHTML incompatible caused by target
  513. $f_text .= "
  514. <form action='$paypalDomain/cgi-bin/webscr' method='post'>
  515. <div>
  516. <input type='hidden' name='cmd' value='_xclick' />
  517. <input type='hidden' name='upload' value='1' />
  518. <input type='hidden' name='business' value='$paypal_email' />
  519. <input type='hidden' name='page_style' value='$payment_page_style' />";
  520. // Fill the Cart with products from the basket
  521. $count_items = count($_SESSION['shopping_cart']); // Count number of different products in basket
  522. $array = $_SESSION['shopping_cart'];
  523. // PayPal requires to pass multiple products in a sequence starting at 1
  524. $cart_count = 1;
  525. // Set thanks page to correct value
  526. $thanks_page = str_replace('easyshop.php', 'thank_you.php', e_SELF);
  527. $cancel_page = str_replace('easyshop.php', 'cancelled.php', e_SELF);
  528. $ipn_notify_page = str_replace('easyshop.php', 'ipn_notify.php', e_SELF);
  529. // For each product in the shopping cart array write PayPal details
  530. foreach($array as $id => $item) {
  531. $f_text .= "
  532. <input type='hidden' name='item_name_".$cart_count."' value='".$item['item_name']."' />
  533. <input type='hidden' name='item_number_".$cart_count."' value='".$item['sku_number']."' />
  534. <input type='hidden' name='amount_".$cart_count."' value='".$item['item_price']."' />
  535. <input type='hidden' name='quantity_".$cart_count."' value='".$item['quantity']."' />
  536. <input type='hidden' name='shipping_".$cart_count."' value='".$item['shipping']."' />
  537. <input type='hidden' name='shipping2_".$cart_count."' value='".$item['shipping2']."' />
  538. <input type='hidden' name='handling_".$cart_count."' value='".$item['handling']."' />
  539. <input type='hidden' name='db_id_".$cart_count."' value='".$item['db_id']."' />";
  540. $cart_count++;
  541. }
  542. $f_text .= "
  543. <input type='hidden' name='currency_code' value='$paypal_currency_code' />
  544. <input type='hidden' name='no_note' value='1' />
  545. <input type='hidden' name='lc' value='US' />
  546. <input type='hidden' name='bn' value='PP-ShopCartBF' />
  547. <input type='hidden' name='rm' value='1' />
  548. <input type='hidden' name='notify_url' value='$ipn_notify_page' />
  549. <input type='hidden' name='return' value='".$thanks_page."' />
  550. <input type='hidden' name='cancel_return' value='".$cancel_page."' />
  551. ";
  552. if (USER) { // If user is logged in we also include the user id
  553. $f_text .="<input type='hidden' name='custom' value='".USERID."' />";
  554. }
  555. if ($email_order == 0) {
  556. // in case setting always show checkout button is off
  557. if ($always_show_checkout == 0) {
  558. // When there are items in the shopping cart, display 'Go to checkout' button
  559. if ($_SESSION['sc_total']['items'] > 0) {
  560. // Only show 'Go to checkout' if total amount is above minimum amount
  561. if ($_SESSION['sc_total']['sum'] > $minimum_amount) {
  562. $f_text .= "
  563. <input class='button' type='submit' value='".EASYSHOP_SHOP_09."'/>
  564. </div>
  565. </form>
  566. <br />";
  567. } else { // Minimum amount has not been reached; inform the shopper
  568. $f_text .= EASYSHOP_SHOP_36." : ".$unicode_character_before.number_format($minimum_amount, 2, '.', '').$unicode_character_after." <br />
  569. ".EASYSHOP_SHOP_37." : ".$unicode_character_before.number_format(($minimum_amount - $_SESSION['sc_total']['sum']), 2, '.', '').$unicode_character_after." <br />";
  570. }
  571. }
  572. } else { // RC6 Fix for proper closing the form tag
  573. $f_text .= "</div></form><br />";
  574. }
  575. } else { // e-mail the order to admin
  576. $f_text .= "<a class='button' href='function MailOrder($array)'>".EASYSHOP_SHOP_79."</a></form><br />";
  577. }
  578. // in case setting always display checkout button is on
  579. //else
  580. if ($always_show_checkout == 1) {
  581. $f_text .= "
  582. <input class='button' type='submit' value='".EASYSHOP_SHOP_09."'/>
  583. </form>
  584. <br />";
  585. }
  586. // Show 'Manage your basket link'
  587. if ($_SESSION['sc_total']['items'] > 0 AND $action != "edit") {
  588. $f_text .= "
  589. <div style='text-align:center;'><a href='easyshop.php?edit'>".EASYSHOP_SHOP_35."</a></div>
  590. ";
  591. }
  592. else
  593. {
  594. $f_text .= "
  595. </div>
  596. </form>
  597. <br />";
  598. }
  599. /* // Some debug info
  600. print_r($_SESSION['shopping_cart']);
  601. print ("<br />");
  602. print_r($_SESSION['sc_total']);
  603. print ("<br />");
  604. print_r($_SESSION['sc_total']['shipping']);
  605. print ("<br />");
  606. print_r($_SESSION['sc_total']['shipping2']);
  607. print ("<br />");
  608. print_r($_SESSION['sc_total']['handling']);
  609. print ("<br />");
  610. */
  611. return $f_text;
  612. }
  613. function include_prop($prop1_list, $prop1_array, $prop1_prices,$prop1_name,
  614. $prop2_list, $prop2_array, $prop2_prices,$prop2_name,
  615. $prop3_list, $prop3_array, $prop3_prices,$prop3_name,
  616. $prop4_list, $prop4_array, $prop4_prices,$prop4_name,
  617. $prop5_list, $prop5_array, $prop5_prices,$prop5_name,
  618. $prop6_list, $prop6_array, $prop6_prices,$prop6_name,
  619. $unicode_character_before, $unicode_character_after, $item_price ) {
  620. // Function provides the property select boxes for category and product details and signals if property prices have been used
  621. for ($n = 1; $n < 6; $n++){
  622. if (${"prop".$n."_list"} <> "") {
  623. ${"prop".$n."_array"} = explode(",", ${"prop".$n."_list"});
  624. if (${"prop".$n."_prices"} <> "") {
  625. ${"price".$n."_array"} = explode(",", ${"prop".$n."_prices"});
  626. }
  627. $text .= "<b>".${"prop".$n."_name"}.":</b> "; // Name of property list
  628. $text .= "<select class='tbox' name='prod_prop_$n'>";
  629. // Add an empty value for the property list; check in easyshop_basket if value is selected
  630. $text .= "<option value=' ' selected='selected'>&nbsp;</option>";
  631. $arrayLength = count(${"prop".$n."_array"});
  632. for ($i = 0; $i < $arrayLength; $i++){
  633. $text .= "<option value='".${"prop".$n."_array"}[$i]."'>".${"prop".$n."_array"}[$i];
  634. // Display different price if corresponding price delta in properties is found
  635. if (${"price".$n."_array"}[$i] <> 0) {
  636. $text .= "&nbsp;".$unicode_character_before.number_format(($item_price+${"price".$n."_array"}[$i]), 2, '.', '')."&nbsp;".$unicode_character_after;
  637. $property_prices = 1; // There is at least one or more property price detected; use in discounts
  638. }
  639. $text .= "</option>";
  640. }
  641. $text .= "</select><br />";
  642. }
  643. }
  644. return array($text, $property_prices);
  645. }
  646. function include_disc ($discount_id, $discount_class, $discount_valid_from, $discount_valid_till,
  647. $discount_code, $item_price, $discount_flag, $discount_percentage, $discount_price,
  648. $property_prices, $unicode_character_before, $unicode_character_after, $print_discount_icons){
  649. // Function provides the discount handling for category and product details and returns discount price (when no discount code is applied)
  650. // Include selected discount in the product form
  651. if (isset($discount_id)) { // Include the product discount if it is filled in
  652. $text .= "<input type='hidden' name='discount_id' value='".$discount_id."'/>";
  653. // Determine if user class if applicable for this discount
  654. if (check_class($discount_class)) {
  655. // Determine if discount date is valid
  656. $today = time(); // Record the current date/time stamp
  657. if ($today > $discount_valid_from and $today < $discount_valid_till) { // This moment is between start and end date of discount
  658. if ($discount_code <> "") { // Ask the discount code to activate discount
  659. $text .= "<b>".EASYSHOP_SHOP_50.":</b><br /> <input class='tbox' size='25' type='text' name='discount_code' /><br />"; // Discount code
  660. } else { // Apply the discount straight away; no discount code needed
  661. // Adjust item price
  662. $old_item_price = number_format($item_price, 2, '.', '');
  663. if ($discount_flag == 1) { // Discount percentage
  664. $item_price = number_format($item_price - ( ( $discount_percentage / 100) * $item_price ), 2, '.', '');
  665. }
  666. else { // Discount amount
  667. $item_price = $item_price - $discount_price;
  668. }
  669. // Protection against a discount that makes the price negative
  670. if ($item_price < 0) {
  671. $item_price = 0;
  672. }
  673. if ($property_prices != 1) { // Without variable property prices we can indicate the new price
  674. // Display From For text
  675. $text .= EASYSHOP_SHOP_51." ".$unicode_character_before.$old_item_price.$unicode_character_after." ".EASYSHOP_SHOP_52." ".$unicode_character_before.number_format($item_price.$unicode_character_after, 2, '.', '')."<br />";
  676. } else { // Only able to tell there will be a discount due to unknown property selection with price delta
  677. $text .= EASYSHOP_SHOP_53." ";
  678. if ($discount_flag == 1) { // Discount percentage
  679. $text .= $discount_percentage."%<br />";
  680. }
  681. else { // Discount amount
  682. $text .= $unicode_character_before.number_format($discount_price, 2, '.', '').$unicode_character_after."<br />";
  683. }
  684. } // End else/if of property price indications
  685. } // End else/if of applying the discount immediately
  686. // Do something special for 'special' percentages when print_discount_icons flag is set
  687. if ($print_discount_icons == 1){
  688. $display_text = EASYSHOP_SHOP_53." ".(($discount_percentage>0)?$discount_percentage."%":$unicode_character_before.number_format($discount_price, 2, '.', '').$unicode_character_after);
  689. if ($discount_flag == 1 AND strstr("_5_10_20_50_", "_".$discount_percentage."_")) {
  690. $text .= "&nbsp;<img src='".e_PLUGIN_ABS."easyshop/images/offer_".$discount_percentage.".gif' style='height:22px' alt='$display_text' title='$display_text' />";
  691. } else {
  692. $text .= "&nbsp;<img src='".e_PLUGIN_ABS."easyshop/images/special_offer.gif' style='height:22px' alt='$display_text' title='$display_text' />";
  693. }
  694. } // End if print_discount_icons
  695. } // End if date is valid: don't calculate the discount if the date is invalid
  696. } // End if user class is valid: don't calculate the discount if the user class is invalid
  697. } // End if when discount_id is found
  698. return array($text,$item_price);
  699. } // End of function include_disc
  700. }
  701. class Tabs {
  702. var $name;
  703. var $tabs;
  704. var $active;
  705. var $current;
  706. function __construct($name){
  707. $this->name = $name;
  708. }
  709. function start($name){
  710. if (empty($this->active)){ $this->active = $name; }
  711. $this->current = $name;
  712. ob_start();
  713. }
  714. function end(){
  715. $this->tabs[$this->current] = ob_get_contents();
  716. ob_end_clean();
  717. }
  718. function run(){
  719. if (count($this->tabs) > 0){
  720. $text .= "<DIV CLASS='tabs'>\n";
  721. $jsClear = "";
  722. foreach($this->tabs as $tabname => $tabcontent){
  723. $tabid = "tab_".$this->name."_$tabname";
  724. $contentid = "tabcontent_".$this->name."_$tabname";
  725. $jsClear .= "\tdocument.getElementById('$tabid').className = 'tab_inactive';\n";
  726. $jsClear .= "\tdocument.getElementById('$contentid').style.display = 'none';\n";
  727. }
  728. $text .= "<script type=\"text/javascript\">\n";
  729. $text .= "function tab_".$this->name."(id){\n";
  730. $text .= "$jsClear";
  731. $text .= "\tdocument.getElementById('tab_".$this->name."_'+id).className = 'tab_active';\n";
  732. $text .= "\tdocument.getElementById('tabcontent_".$this->name."_'+id).style.display = '';\n";
  733. $text .= "}\n";
  734. $text .= "</script>\n";
  735. foreach($this->tabs as $tabname => $tabcontent){
  736. $tabid = "tab_".$this->name."_$tabname";
  737. $contentid = "tabcontent_".$this->name."_$tabname";
  738. $text .= "<DIV CLASS='";
  739. if ($this->active == $tabname){ $text .= "tab_active"; }else{ $text .= "tab_inactive"; }
  740. $text .= "' ID='$tabid' ";
  741. $text .= "onClick=\"tab_".$this->name."('$tabname');\">$tabname</DIV>\n";
  742. }
  743. $text .= "<DIV STYLE='float: left; clear:both;'></DIV>\n";
  744. foreach($this->tabs as $tabname => $tabcontent){
  745. $contentid = "tabcontent_".$this->name."_$tabname";
  746. $text .= "<DIV ID = '$contentid' CLASS='tab_content' STYLE='display: ";
  747. if ($this->active == $tabname){ $text .= "block"; }else{ $text .= "none"; }
  748. $text .= ";'>$tabcontent</DIV>\n";
  749. }
  750. $text .= "</DIV>\n";
  751. $text .= "<DIV STYLE='clear: both;'></DIV>\n";
  752. return $text;
  753. }
  754. }
  755. } // End of class Tabs
  756. class Forms
  757. {
  758. function add_to_cart_form($prop1_list, $prop1_array, $prop1_prices,$prop1_name,
  759. $prop2_list, $prop2_array, $prop2_prices,$prop2_name,
  760. $prop3_list, $prop3_array, $prop3_prices,$prop3_name,
  761. $prop4_list, $prop4_array, $prop4_prices,$prop4_name,
  762. $prop5_list, $prop5_array, $prop5_prices,$prop5_name,
  763. $prop6_list, $prop6_array, $prop6_prices,$prop6_name,
  764. $unicode_character_before, $unicode_character_after, $item_price,
  765. $discount_id, $discount_class, $discount_valid_from, $discount_valid_till,
  766. $discount_code, $discount_flag, $discount_percentage, $discount_price,
  767. $property_prices, $unicode_character_before, $unicode_character_after, $print_discount_icons,
  768. $item_id, $item_name, $sku_number, $shipping_first_item, $shipping_additional_item, $handling_override,
  769. $category_id, $item_instock, $item_track_stock, $enable_ipn, $db_id,
  770. $category_order_class, $enable_number_input, $fill_basket)
  771. {
  772. $text .= "
  773. <br />
  774. <form method='post' action='easyshop_basket.php'>
  775. <div>";
  776. // Include selected properties in the product form
  777. // Function include_prop returns an array! [0] is for $text and [1] is for $property_prices!
  778. $temp_array = Shop::include_prop($prop1_list, $prop1_array, $prop1_prices,$prop1_name,
  779. $prop2_list, $prop2_array, $prop2_prices,$prop2_name,
  780. $prop3_list, $prop3_array, $prop3_prices,$prop3_name,
  781. $prop4_list, $prop4_array, $prop4_prices,$prop4_name,
  782. $prop5_list, $prop5_array, $prop5_prices,$prop5_name,
  783. $prop6_list, $prop6_array, $prop6_prices,$prop6_name,
  784. $unicode_character_before, $unicode_character_after, $item_price);
  785. $text .= $temp_array[0];
  786. $property_prices = $temp_array[1];
  787. unset($temp_array);
  788. // Include selected discount in the product form
  789. // Function include_disc returns an array! [0] is for $text and [1] is for $item_price!
  790. $temp_array = Shop::include_disc($discount_id, $discount_class, $discount_valid_from, $discount_valid_till,
  791. $discount_code, $item_price, $discount_flag, $discount_percentage, $discount_price,
  792. $property_prices, $unicode_character_before, $unicode_character_after, $print_discount_icons);
  793. $text .= $temp_array[0];
  794. // $item_price = $temp_array[1]; // Bugfix #75
  795. unset($temp_array);
  796. // Include also currency sign to send it to the basket
  797. // Send the product data to the basket
  798. $text .= "
  799. <input type='hidden' name='unicode_character_before' value='".$unicode_character_before."'/>
  800. <input type='hidden' name='unicode_character_after' value='".$unicode_character_after."'/>
  801. <input type='hidden' name='item_id' value='".$item_id."'/>
  802. <input type='hidden' name='item_name' value='".$item_name."'/>
  803. <input type='hidden' name='sku_number' value='".$sku_number."'/>
  804. <input type='hidden' name='item_price' value='".number_format($item_price, 2, '.', '')."'/>
  805. <input type='hidden' name='shipping' value='".number_format($shipping_first_item, 2, '.', '')."'/>
  806. <input type='hidden' name='shipping2' value='".number_format($shipping_additional_item, 2, '.', '')."'/>
  807. <input type='hidden' name='handling' value='".number_format($handling_override, 2, '.', '')."'/>
  808. <input type='hidden' name='category_id' value='".$category_id."'/>";
  809. // IPN addition to include stock tracking option
  810. if ($item_track_stock== 2 && $enable_ipn == 2)
  811. {
  812. $text .= "
  813. <input type='hidden' name='item_instock' value='".$item_instock."'>
  814. <input type='hidden' name='item_track_stock' value='".$item_track_stock."'>";
  815. }
  816. // IPN addition to include Item's database ID into session variable
  817. $text .= "
  818. <input type='hidden' name='db_id' value='".$db_id."'>
  819. <input type='hidden' name='fill_basket' value='".$fill_basket."'/>";
  820. // Include properties lists hidden in the form
  821. for ($n = 1; $n < 6; $n++)
  822. {
  823. $propname = "prop".$n."_name";
  824. $proplist = "prop".$n."_list";
  825. $propprices = "prop".$n."_prices";
  826. $text .= "
  827. <input type='hidden' name='$propname' value='".${"prop".$n."_name"}."'/>
  828. <input type='hidden' name='$proplist' value='".${"prop".$n."_list"}."'/>
  829. <input type='hidden' name='$propprices' value='".${"prop".$n."_prices"}."'/>";
  830. }
  831. // Include user id if user is logged in
  832. if(USER)
  833. {
  834. $text .= "
  835. <input type='hidden' name='custom' value='".USERID."'/>";
  836. }
  837. if(check_class($category_order_class))
  838. { // Only display number and checkout button if user is member of order_class
  839. if ($enable_number_input == '1')
  840. { // Shop visitor can specify number of products
  841. $text .= "
  842. <div class='easyshop_nr_of_prod'>
  843. ".EASYSHOP_SHOP_80.":&nbsp;<input name='item_qty' type='text' value='1' size='2' />
  844. </div>";
  845. }
  846. else
  847. { // Shop adds one product at each click on add button
  848. $text .= "
  849. <input type='hidden' name='item_qty' value='1' />";
  850. }
  851. $text .= "
  852. <input type='hidden' name='return_url' value='".e_SELF.(e_QUERY ? '?'.e_QUERY : '')."'/>
  853. <input class='button' type='submit' value='".EASYSHOP_SHOP_08."'/>";
  854. }
  855. $text .= "
  856. </div>
  857. </form>";
  858. return $text;
  859. }
  860. } // End of class Forms
  861. ?>