uc_cart_links.pages.inc 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <?php
  2. /**
  3. * @file
  4. * Cart Links menu items.
  5. */
  6. /**
  7. * Preprocesses a Cart Link, confirming with the user for destructive actions.
  8. *
  9. * @param string $cart_actions
  10. * A Cart Link URL is structured like "/cart/add/$cart_actions".
  11. *
  12. * @see uc_cart_links_form_submit()
  13. */
  14. function uc_cart_links_form($form, &$form_state, $cart_actions) {
  15. // Fail if the link is restricted.
  16. $data = variable_get('uc_cart_links_restrictions', '');
  17. if (!empty($data)) {
  18. $restrictions = explode("\n", variable_get('uc_cart_links_restrictions', ''));
  19. $restrictions = array_map('trim', $restrictions);
  20. if (!empty($restrictions) && !in_array($cart_actions, $restrictions)) {
  21. $url = variable_get('uc_cart_links_invalid_page', '');
  22. if (empty($url)) {
  23. $url = '<front>';
  24. }
  25. unset($_GET['destination']);
  26. drupal_goto($url);
  27. }
  28. }
  29. // Confirm with the user if the form contains a destructive action.
  30. $items = uc_cart_get_contents();
  31. if (variable_get('uc_cart_links_empty', TRUE) && !empty($items)) {
  32. $actions = explode('-', urldecode($cart_actions));
  33. foreach ($actions as $action) {
  34. $action = drupal_substr($action, 0, 1);
  35. if ($action == 'e' || $action == 'E') {
  36. return confirm_form(array(), t('The current contents of your shopping cart will be lost. Are you sure you want to continue?'), variable_get('uc_cart_links_invalid_page', ''));
  37. }
  38. }
  39. }
  40. // No destructive actions, so process the link immediately.
  41. uc_cart_links_process($cart_actions);
  42. }
  43. /**
  44. * Submit handler for uc_cart_links_form().
  45. *
  46. * @see uc_cart_links_form()
  47. */
  48. function uc_cart_links_form_submit($form, &$form_state) {
  49. uc_cart_links_process(arg(2));
  50. }
  51. /**
  52. * Processes a Cart Link to fiddle with the cart and redirect the user.
  53. *
  54. * @param string $cart_actions
  55. * A Cart Link URL is structured like "/cart/add/$cart_actions".
  56. */
  57. function uc_cart_links_process($cart_actions) {
  58. $actions = explode('-', urldecode($cart_actions));
  59. $rebuild_cart = FALSE;
  60. $messages = array();
  61. $id = t('(not specified)');
  62. foreach ($actions as $action) {
  63. switch (drupal_substr($action, 0, 1)) {
  64. // Set the ID of the Cart Link.
  65. case 'i':
  66. case 'I':
  67. $id = drupal_substr($action, 1, 32);
  68. break;
  69. // Add a product to the cart.
  70. case 'p':
  71. case 'P':
  72. // Set the default product variables.
  73. $p = array('nid' => 0, 'qty' => 1, 'data' => array());
  74. $msg = TRUE;
  75. // Parse the product action to adjust the product variables.
  76. $parts = explode('_', $action);
  77. foreach ($parts as $part) {
  78. switch (drupal_substr($part, 0, 1)) {
  79. // Set the product node ID: p23
  80. case 'p':
  81. case 'P':
  82. $p['nid'] = intval(drupal_substr($part, 1));
  83. break;
  84. // Set the quantity to add to cart: _q2
  85. case 'q':
  86. case 'Q':
  87. $p['qty'] = intval(drupal_substr($part, 1));
  88. break;
  89. // Set an attribute/option for the product: _a3o6
  90. case 'a':
  91. case 'A':
  92. $attribute = intval(drupal_substr($part, 1, stripos($part, 'o') - 1));
  93. $option = (string) drupal_substr($part, stripos($part, 'o') + 1);
  94. if (!isset($p['attributes'][$attribute])) {
  95. $p['attributes'][$attribute] = $option;
  96. }
  97. else {
  98. // Multiple options for this attribute implies checkbox
  99. // attribute, which we must store as an array
  100. if (is_array($p['attributes'][$attribute])) {
  101. // Already an array, just append this new option
  102. $p['attributes'][$attribute][$option] = $option;
  103. }
  104. else {
  105. // Set but not an array, means we already have at least one
  106. // option, so put that into an array with this new option
  107. $p['attributes'][$attribute] = array(
  108. $p['attributes'][$attribute] => $p['attributes'][$attribute],
  109. $option => $option,
  110. );
  111. }
  112. }
  113. break;
  114. // Suppress the add to cart message: _s
  115. case 's':
  116. case 'S':
  117. $msg = FALSE;
  118. break;
  119. }
  120. }
  121. // Add the item to the cart, suppressing the default redirect.
  122. if ($p['nid'] > 0 && $p['qty'] > 0) {
  123. // If it's a product kit, we need black magic to make everything work
  124. // right. In other words, we have to simulate FAPI's form values.
  125. $node = node_load($p['nid']);
  126. if ($node->status) {
  127. if (isset($node->products) && is_array($node->products)) {
  128. foreach ($node->products as $nid => $product) {
  129. $p['data']['products'][$nid] = array(
  130. 'nid' => $nid,
  131. 'qty' => $product->qty,
  132. );
  133. }
  134. }
  135. uc_cart_add_item($p['nid'], $p['qty'], $p['data'] + module_invoke_all('uc_add_to_cart_data', $p), NULL, $msg, FALSE, FALSE);
  136. $rebuild_cart = TRUE;
  137. }
  138. else {
  139. watchdog('uc_cart_link', 'Cart Link on %url tried to add an unpublished product to the cart.', array('%url' => $_SERVER['HTTP_REFERER']), WATCHDOG_ERROR);
  140. }
  141. }
  142. break;
  143. // Empty the shopping cart.
  144. case 'e':
  145. case 'E':
  146. if (variable_get('uc_cart_links_empty', TRUE)) {
  147. uc_cart_empty();
  148. }
  149. break;
  150. // Display a pre-configured message.
  151. case 'm':
  152. case 'M':
  153. // Load the messages if they haven't been loaded yet.
  154. if (empty($messages)) {
  155. $data = explode("\n", variable_get('uc_cart_links_messages', ''));
  156. foreach ($data as $message) {
  157. // Skip blank lines.
  158. if (preg_match('/^\s*$/', $message)) {
  159. continue;
  160. }
  161. list($mkey, $mdata) = explode('|', $message, 2);
  162. $messages[trim($mkey)] = trim($mdata);
  163. }
  164. }
  165. // Parse the message key and display it if it exists.
  166. $mkey = intval(drupal_substr($action, 1));
  167. if (!empty($messages[$mkey])) {
  168. drupal_set_message($messages[$mkey]);
  169. }
  170. break;
  171. }
  172. // Rebuild the cart cache if necessary.
  173. if ($rebuild_cart) {
  174. uc_cart_get_contents(NULL, 'rebuild');
  175. }
  176. }
  177. if (variable_get('uc_cart_links_track', TRUE)) {
  178. db_merge('uc_cart_link_clicks')
  179. ->key(array('cart_link_id' => (string) $id))
  180. ->fields(array(
  181. 'clicks' => 1,
  182. 'last_click' => REQUEST_TIME,
  183. ))
  184. ->expression('clicks', 'clicks + :i', array(':i' => 1))
  185. ->execute();
  186. }
  187. $_SESSION['uc_cart_last_url'] = $_SERVER['HTTP_REFERER'];
  188. drupal_goto();
  189. }